All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.aya.concrete.resolve.context.Context Maven / Gradle / Ivy
// Copyright (c) 2020-2021 Yinsen (Tesla) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.concrete.resolve.context;
import kala.collection.Seq;
import kala.collection.immutable.ImmutableSeq;
import kala.collection.mutable.DynamicSeq;
import kala.collection.mutable.MutableMap;
import org.aya.api.error.Problem;
import org.aya.api.error.Reporter;
import org.aya.api.ref.LocalVar;
import org.aya.api.ref.Var;
import org.aya.api.util.InterruptException;
import org.aya.concrete.resolve.error.QualifiedNameNotFoundError;
import org.aya.concrete.resolve.error.ShadowingWarn;
import org.aya.concrete.resolve.error.UnqualifiedNameNotFoundError;
import org.aya.concrete.stmt.QualifiedID;
import org.aya.generic.Constants;
import org.aya.util.error.SourcePos;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* @author re-xyr
*/
public interface Context {
ImmutableSeq TOP_LEVEL_MOD_NAME = ImmutableSeq.empty();
@Nullable Context parent();
@NotNull Reporter reporter();
@NotNull Path underlyingFile();
default @Nullable T iterate(@NotNull Function<@NotNull Context, @Nullable T> f) {
var p = this;
while (p != null) {
var result = f.apply(p);
if (result != null) return result;
p = p.parent();
}
return null;
}
default @NotNull ImmutableSeq moduleName() {
var p = parent();
if (p == null) return ImmutableSeq.empty();
else return p.moduleName();
}
@Contract("_->fail") default @NotNull T reportAndThrow(@NotNull Problem problem) {
reporter().report(problem);
throw new ResolvingInterruptedException();
}
default @NotNull Var get(@NotNull QualifiedID name) {
var isUnqualified = name.isUnqualified();
return isUnqualified
? getUnqualified(name.justName(), name.sourcePos())
: getQualified(name, name.sourcePos());
}
default DynamicSeq collect(@NotNull DynamicSeq container) {
return container;
}
@Nullable Var getUnqualifiedLocalMaybe(@NotNull String name, @NotNull SourcePos sourcePos);
default @Nullable Var getUnqualifiedMaybe(@NotNull String name, @NotNull SourcePos sourcePos) {
return iterate(c -> c.getUnqualifiedLocalMaybe(name, sourcePos));
}
default @NotNull Var getUnqualified(@NotNull String name, @NotNull SourcePos sourcePos) {
var result = getUnqualifiedMaybe(name, sourcePos);
if (result == null) reportAndThrow(new UnqualifiedNameNotFoundError(name, sourcePos));
return result;
}
@Nullable Var getQualifiedLocalMaybe(@NotNull ImmutableSeq<@NotNull String> modName, @NotNull String name, @NotNull SourcePos sourcePos);
default @Nullable Var getQualifiedMaybe(@NotNull ImmutableSeq<@NotNull String> modName, @NotNull String name, @NotNull SourcePos sourcePos) {
return iterate(c -> c.getQualifiedLocalMaybe(modName, name, sourcePos));
}
default @NotNull Var getQualified(@NotNull ImmutableSeq<@NotNull String> modName, @NotNull String name, @NotNull SourcePos sourcePos) {
var result = getQualifiedMaybe(modName, name, sourcePos);
if (result == null) reportAndThrow(new QualifiedNameNotFoundError(modName, name, sourcePos));
return result;
}
default @NotNull Var getQualified(@NotNull QualifiedID qualifiedID, @NotNull SourcePos sourcePos) {
var view = qualifiedID.ids().view();
return getQualified(view.dropLast(1).toImmutableSeq(), view.last(), sourcePos);
}
@Nullable MutableMap getModuleLocalMaybe(@NotNull ImmutableSeq modName);
default @Nullable MutableMap getModuleMaybe(@NotNull ImmutableSeq modName) {
return iterate(c -> c.getModuleLocalMaybe(modName));
}
default @NotNull BindContext bind(
@NotNull LocalVar ref,
@NotNull SourcePos sourcePos,
@NotNull Predicate<@Nullable Var> toWarn
) {
return bind(ref.name(), ref, sourcePos, toWarn);
}
default @NotNull BindContext bind(@NotNull LocalVar ref, @NotNull SourcePos sourcePos) {
return bind(ref.name(), ref, sourcePos, var -> var instanceof LocalVar);
}
default @NotNull BindContext bind(
@NotNull String name,
@NotNull LocalVar ref,
@NotNull SourcePos sourcePos,
@NotNull Predicate<@Nullable Var> toWarn
) {
if (toWarn.test(getUnqualifiedMaybe(name, sourcePos)) && !name.startsWith(Constants.ANONYMOUS_PREFIX)) {
reporter().report(new ShadowingWarn(name, sourcePos));
}
return new BindContext(this, name, ref);
}
default @NotNull PhysicalModuleContext derive(@NotNull String extraName) {
return new PhysicalModuleContext(this, this.moduleName().appended(extraName));
}
default @NotNull PhysicalModuleContext derive(@NotNull Seq<@NotNull String> extraName) {
return new PhysicalModuleContext(this, this.moduleName().concat(extraName));
}
class ResolvingInterruptedException extends InterruptException {
@Override public InterruptStage stage() {
return InterruptStage.Resolving;
}
}
}