package scotch.compiler.syntax.definition;
import static lombok.AccessLevel.PACKAGE;
import static scotch.compiler.syntax.builder.BuilderUtil.require;
import static scotch.symbol.Symbol.qualified;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import scotch.compiler.syntax.builder.SyntaxBuilder;
import scotch.compiler.text.SourceLocation;
import scotch.symbol.Symbol;
import scotch.symbol.SymbolEntry;
import scotch.symbol.SymbolResolver;
import scotch.compiler.syntax.type.Type;
@AllArgsConstructor(access = PACKAGE)
@EqualsAndHashCode(callSuper = false)
@ToString(exclude = "sourceLocation")
public final class ModuleImport extends Import {
public static Builder builder() {
return new Builder();
}
private final SourceLocation sourceLocation;
private final String moduleName;
@Override
public Set<Symbol> getContext(Type type, SymbolResolver resolver) {
return getContext_(moduleName, type, resolver);
}
@Override
public boolean isFrom(String moduleName) {
return Objects.equals(this.moduleName, moduleName);
}
@Override
public Optional<Symbol> qualify(String name, SymbolResolver resolver) {
return resolver.getEntry(qualified(moduleName, name)).map(SymbolEntry::getSymbol);
}
@Override
public ModuleImport withSourceLocation(SourceLocation sourceLocation) {
return new ModuleImport(sourceLocation, moduleName);
}
public static class Builder implements SyntaxBuilder<ModuleImport> {
private Optional<SourceLocation> sourceLocation = Optional.empty();
private Optional<String> moduleName = Optional.empty();
private Builder() {
// intentionally empty
}
@Override
public ModuleImport build() {
return moduleImport(
require(sourceLocation, "Source location"),
require(moduleName, "Module name")
);
}
public Builder withModuleName(String moduleName) {
this.moduleName = Optional.of(moduleName);
return this;
}
@Override
public Builder withSourceLocation(SourceLocation sourceLocation) {
this.sourceLocation = Optional.of(sourceLocation);
return this;
}
}
}