mirror of
https://github.com/enso-org/enso.git
synced 2024-11-27 17:32:12 +03:00
Make the BindingsMap
able to break links (#1980)
This commit is contained in:
parent
45c01da490
commit
7cced6a9de
@ -124,7 +124,7 @@ object LauncherApplication {
|
||||
"(error | warning | info | debug | trace)",
|
||||
"Sets logging verbosity for the engine. Defaults to info."
|
||||
)
|
||||
.withDefault(LogLevel.Info)
|
||||
.withDefault(LogLevel.Warning)
|
||||
}
|
||||
|
||||
private def runCommand: Command[Config => Int] =
|
||||
|
@ -649,7 +649,7 @@ object Main {
|
||||
|
||||
/** Default log level to use if the LOG_LEVEL option is not provided.
|
||||
*/
|
||||
val defaultLogLevel: LogLevel = LogLevel.Info
|
||||
val defaultLogLevel: LogLevel = LogLevel.Warning
|
||||
|
||||
/** Main entry point for the CLI program.
|
||||
*
|
||||
|
@ -35,10 +35,21 @@ trait PackageRepository {
|
||||
): Either[PackageRepository.Error, Unit]
|
||||
|
||||
/** Get a sequence of currently loaded packages. */
|
||||
def getLoadedPackages(): Seq[Package[TruffleFile]]
|
||||
def getLoadedPackages: Seq[Package[TruffleFile]]
|
||||
|
||||
/** Get a sequence of currently loaded modules. */
|
||||
def getLoadedModules(): Seq[Module]
|
||||
def getLoadedModules: Seq[Module]
|
||||
|
||||
/** Get the mapping from qualified module names (equivalent to
|
||||
* [[QualifiedName.toString]]) to modules.
|
||||
*
|
||||
* This map may be updated concurrently.
|
||||
*/
|
||||
def getModuleMap: PackageRepository.ModuleMap
|
||||
|
||||
/** Gets a frozen form of the module map that cannot be updated concurrently.
|
||||
*/
|
||||
def freezeModuleMap: PackageRepository.FrozenModuleMap
|
||||
|
||||
/** Get a loaded module by its qualified name. */
|
||||
def getLoadedModule(qualifiedName: String): Option[Module]
|
||||
@ -63,6 +74,9 @@ trait PackageRepository {
|
||||
|
||||
object PackageRepository {
|
||||
|
||||
type ModuleMap = collection.concurrent.Map[String, Module]
|
||||
type FrozenModuleMap = Map[String, Module]
|
||||
|
||||
/** A trait representing errors reported by this system */
|
||||
sealed trait Error
|
||||
|
||||
@ -130,10 +144,23 @@ object PackageRepository {
|
||||
collection.concurrent.TrieMap(builtinsName -> None)
|
||||
}
|
||||
|
||||
/** The mapping containing loaded modules. */
|
||||
/** The mapping containing loaded modules.
|
||||
*
|
||||
* We use [[String]] as the key as we often index into this map based on
|
||||
* qualified names that come from interop (via
|
||||
* [[org.enso.interpreter.runtime.scope.TopLevelScope]]). These arrive as
|
||||
* Strings, and constantly converting them into [[QualifiedName]]s would
|
||||
* add more overhead than is probably necessary.
|
||||
*/
|
||||
val loadedModules: collection.concurrent.Map[String, Module] =
|
||||
collection.concurrent.TrieMap(Builtins.MODULE_NAME -> builtins.getModule)
|
||||
|
||||
/** @inheritdoc */
|
||||
override def getModuleMap: ModuleMap = loadedModules
|
||||
|
||||
/** @inheritdoc */
|
||||
override def freezeModuleMap: FrozenModuleMap = loadedModules.toMap
|
||||
|
||||
/** @inheritdoc */
|
||||
override def registerMainProjectPackage(
|
||||
libraryName: LibraryName,
|
||||
@ -235,11 +262,11 @@ object PackageRepository {
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def getLoadedModules(): Seq[Module] =
|
||||
override def getLoadedModules: Seq[Module] =
|
||||
loadedModules.values.toSeq
|
||||
|
||||
/** @inheritdoc */
|
||||
override def getLoadedPackages(): Seq[Package[TruffleFile]] =
|
||||
override def getLoadedPackages: Seq[Package[TruffleFile]] =
|
||||
loadedPackages.values.toSeq.flatten
|
||||
|
||||
/** @inheritdoc */
|
||||
@ -352,7 +379,7 @@ object PackageRepository {
|
||||
languageHome = homeManager,
|
||||
edition = edition,
|
||||
preferLocalLibraries =
|
||||
projectPackage.map(_.config.preferLocalLibraries).getOrElse(false)
|
||||
projectPackage.exists(_.config.preferLocalLibraries)
|
||||
)
|
||||
new Default(
|
||||
resolvingLibraryProvider,
|
||||
|
@ -150,7 +150,9 @@ class IrToTruffle(
|
||||
"No binding analysis at the point of codegen."
|
||||
)
|
||||
.resolvedExports
|
||||
.foreach { exp => moduleScope.addExport(exp.module.getScope) }
|
||||
.foreach { exp =>
|
||||
moduleScope.addExport(exp.module.unsafeAsModule().getScope)
|
||||
}
|
||||
val imports = module.imports
|
||||
val atomDefs = module.bindings.collect {
|
||||
case atom: IR.Module.Scope.Definition.Atom => atom
|
||||
@ -230,9 +232,13 @@ class IrToTruffle(
|
||||
.map { res =>
|
||||
res.target match {
|
||||
case BindingsMap.ResolvedModule(module) =>
|
||||
module.getScope.getAssociatedType
|
||||
module.unsafeAsModule().getScope.getAssociatedType
|
||||
case BindingsMap.ResolvedConstructor(definitionModule, cons) =>
|
||||
definitionModule.getScope.getConstructors.get(cons.name)
|
||||
definitionModule
|
||||
.unsafeAsModule()
|
||||
.getScope
|
||||
.getConstructors
|
||||
.get(cons.name)
|
||||
case BindingsMap.ResolvedPolyglotSymbol(_, _) =>
|
||||
throw new CompilerError(
|
||||
"Impossible polyglot symbol, should be caught by MethodDefinitions pass."
|
||||
@ -379,11 +385,14 @@ class IrToTruffle(
|
||||
)
|
||||
bindingsMap.exportedSymbols.foreach {
|
||||
case (name, List(resolution)) =>
|
||||
if (resolution.module != moduleScope.getModule) {
|
||||
if (resolution.module.unsafeAsModule() != moduleScope.getModule) {
|
||||
resolution match {
|
||||
case BindingsMap.ResolvedConstructor(definitionModule, cons) =>
|
||||
val runtimeCons =
|
||||
definitionModule.getScope.getConstructors.get(cons.name)
|
||||
val runtimeCons = definitionModule
|
||||
.unsafeAsModule()
|
||||
.getScope
|
||||
.getConstructors
|
||||
.get(cons.name)
|
||||
val fun = mkConsGetter(runtimeCons)
|
||||
moduleScope.registerMethod(
|
||||
moduleScope.getAssociatedType,
|
||||
@ -392,7 +401,7 @@ class IrToTruffle(
|
||||
)
|
||||
case BindingsMap.ResolvedModule(module) =>
|
||||
val runtimeCons =
|
||||
module.getScope.getAssociatedType
|
||||
module.unsafeAsModule().getScope.getAssociatedType
|
||||
val fun = mkConsGetter(runtimeCons)
|
||||
moduleScope.registerMethod(
|
||||
moduleScope.getAssociatedType,
|
||||
@ -400,8 +409,9 @@ class IrToTruffle(
|
||||
fun
|
||||
)
|
||||
case BindingsMap.ResolvedMethod(module, method) =>
|
||||
val fun = module.getScope.getMethods
|
||||
.get(module.getScope.getAssociatedType)
|
||||
val actualModule = module.unsafeAsModule()
|
||||
val fun = actualModule.getScope.getMethods
|
||||
.get(actualModule.getScope.getAssociatedType)
|
||||
.get(method.name)
|
||||
moduleScope.registerMethod(
|
||||
moduleScope.getAssociatedType,
|
||||
@ -667,13 +677,15 @@ class IrToTruffle(
|
||||
case Some(
|
||||
BindingsMap.Resolution(BindingsMap.ResolvedModule(mod))
|
||||
) =>
|
||||
Right(mod.getScope.getAssociatedType)
|
||||
Right(mod.unsafeAsModule().getScope.getAssociatedType)
|
||||
case Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(mod, cons)
|
||||
)
|
||||
) =>
|
||||
Right(mod.getScope.getConstructors.get(cons.name))
|
||||
Right(
|
||||
mod.unsafeAsModule().getScope.getConstructors.get(cons.name)
|
||||
)
|
||||
case Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedPolyglotSymbol(_, _)
|
||||
@ -867,13 +879,23 @@ class IrToTruffle(
|
||||
resolution match {
|
||||
case BindingsMap.ResolvedConstructor(definitionModule, cons) =>
|
||||
ConstructorNode.build(
|
||||
definitionModule.getScope.getConstructors.get(cons.name)
|
||||
definitionModule
|
||||
.unsafeAsModule()
|
||||
.getScope
|
||||
.getConstructors
|
||||
.get(cons.name)
|
||||
)
|
||||
case BindingsMap.ResolvedModule(module) =>
|
||||
ConstructorNode.build(module.getScope.getAssociatedType)
|
||||
ConstructorNode.build(
|
||||
module.unsafeAsModule().getScope.getAssociatedType
|
||||
)
|
||||
case BindingsMap.ResolvedPolyglotSymbol(module, symbol) =>
|
||||
ConstantObjectNode.build(
|
||||
module.getScope.getPolyglotSymbols.get(symbol.name)
|
||||
module
|
||||
.unsafeAsModule()
|
||||
.getScope
|
||||
.getPolyglotSymbols
|
||||
.get(symbol.name)
|
||||
)
|
||||
case BindingsMap.ResolvedMethod(_, _) =>
|
||||
throw new CompilerError(
|
||||
|
@ -1,9 +1,14 @@
|
||||
package org.enso.compiler.data
|
||||
|
||||
import org.enso.compiler.PackageRepository
|
||||
import org.enso.compiler.PackageRepository.ModuleMap
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap.ModuleReference
|
||||
import org.enso.compiler.exception.CompilerError
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.interpreter.runtime.Module
|
||||
import org.enso.pkg.QualifiedName
|
||||
|
||||
/** A utility structure for resolving symbols in a given module.
|
||||
*
|
||||
@ -16,7 +21,7 @@ case class BindingsMap(
|
||||
types: List[BindingsMap.Cons],
|
||||
polyglotSymbols: List[BindingsMap.PolyglotSymbol],
|
||||
moduleMethods: List[BindingsMap.ModuleMethod],
|
||||
currentModule: Module
|
||||
currentModule: ModuleReference
|
||||
) extends IRPass.Metadata {
|
||||
import BindingsMap._
|
||||
|
||||
@ -28,10 +33,81 @@ case class BindingsMap(
|
||||
*/
|
||||
var resolvedImports: List[ResolvedImport] = List()
|
||||
|
||||
/** Modules exported by [[currentModule]].
|
||||
*/
|
||||
var resolvedExports: List[ExportedModule] = List()
|
||||
|
||||
/** Symbols exported by [[currentModule]].
|
||||
*/
|
||||
var exportedSymbols: Map[String, List[ResolvedName]] = Map()
|
||||
|
||||
/** Convert this [[BindingsMap]] instance to use abstract module references.
|
||||
*
|
||||
* @return `this` with module references converted to abstract
|
||||
*/
|
||||
def toAbstract: BindingsMap = {
|
||||
val copy = this.copy(currentModule = currentModule.toAbstract)
|
||||
copy.resolvedImports = this.resolvedImports.map(_.toAbstract)
|
||||
copy.resolvedExports = this.resolvedExports.map(_.toAbstract)
|
||||
copy.exportedSymbols = this.exportedSymbols.map { case (key, value) =>
|
||||
key -> value.map(name => name.toAbstract)
|
||||
}
|
||||
|
||||
copy
|
||||
}
|
||||
|
||||
/** Convert this [[BindingsMap]] instance to use concrete module references.
|
||||
*
|
||||
* @param moduleMap the mapping from qualified module names to module
|
||||
* instances
|
||||
* @return `this` with module references converted to concrete
|
||||
*/
|
||||
def toConcrete(moduleMap: ModuleMap): Option[BindingsMap] = {
|
||||
val newMap = this.currentModule.toConcrete(moduleMap).map { module =>
|
||||
this.copy(currentModule = module)
|
||||
}
|
||||
|
||||
val withImports: Option[BindingsMap] = newMap.flatMap { bindings =>
|
||||
val newImports = this.resolvedImports.map(_.toConcrete(moduleMap))
|
||||
if (newImports.exists(_.isEmpty)) {
|
||||
None
|
||||
} else {
|
||||
bindings.resolvedImports = newImports.map(_.get)
|
||||
Some(bindings)
|
||||
}
|
||||
}
|
||||
|
||||
val withExports: Option[BindingsMap] = withImports.flatMap { bindings =>
|
||||
val newExports = this.resolvedExports.map(_.toConcrete(moduleMap))
|
||||
if (newExports.exists(_.isEmpty)) {
|
||||
None
|
||||
} else {
|
||||
bindings.resolvedExports = newExports.map(_.get)
|
||||
Some(bindings)
|
||||
}
|
||||
}
|
||||
|
||||
val withSymbols: Option[BindingsMap] = withExports.flatMap { bindings =>
|
||||
val newSymbols = this.exportedSymbols.map { case (key, value) =>
|
||||
val newValue = value.map(_.toConcrete(moduleMap))
|
||||
if (newValue.exists(_.isEmpty)) {
|
||||
key -> None
|
||||
} else {
|
||||
key -> Some(newValue.map(_.get))
|
||||
}
|
||||
}
|
||||
|
||||
if (newSymbols.exists { case (_, v) => v.isEmpty }) {
|
||||
None
|
||||
} else {
|
||||
bindings.exportedSymbols = newSymbols.map { case (k, v) => k -> v.get }
|
||||
Some(bindings)
|
||||
}
|
||||
}
|
||||
|
||||
withSymbols
|
||||
}
|
||||
|
||||
private def findConstructorCandidates(
|
||||
name: String
|
||||
): List[ResolvedConstructor] = {
|
||||
@ -79,12 +155,19 @@ case class BindingsMap(
|
||||
resolvedImports
|
||||
.flatMap { imp =>
|
||||
if (imp.importDef.allowsAccess(name)) {
|
||||
imp.module.getIr
|
||||
imp.module match {
|
||||
case ModuleReference.Concrete(module) =>
|
||||
module.getIr
|
||||
.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Wrong pass ordering. Running resolution on an unparsed module."
|
||||
)
|
||||
.findExportedSymbolsFor(name)
|
||||
case ModuleReference.Abstract(name) =>
|
||||
throw new CompilerError(
|
||||
s"Cannot find export candidates for abstract module reference $name."
|
||||
)
|
||||
}
|
||||
} else { List() }
|
||||
}
|
||||
}
|
||||
@ -99,17 +182,24 @@ case class BindingsMap(
|
||||
}
|
||||
}
|
||||
|
||||
private def getBindingsFrom(module: Module): BindingsMap = {
|
||||
private def getBindingsFrom(module: ModuleReference): BindingsMap = {
|
||||
module match {
|
||||
case ModuleReference.Concrete(module) =>
|
||||
module.getIr.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"imported module has no binding map info"
|
||||
)
|
||||
case ModuleReference.Abstract(_) =>
|
||||
throw new CompilerError(
|
||||
"Bindings cannot be obtained from an abstract module reference."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolves a name in the context of current module.
|
||||
*
|
||||
* @param name the name to resolve.
|
||||
* @return a resolution for [[name]] or an error, if the name could not be
|
||||
* @return a resolution for `name` or an error, if the name could not be
|
||||
* resolved.
|
||||
*/
|
||||
def resolveUppercaseName(
|
||||
@ -430,10 +520,28 @@ object BindingsMap {
|
||||
* @param symbols any symbol restrictions connected to the export.
|
||||
*/
|
||||
case class ExportedModule(
|
||||
module: Module,
|
||||
module: ModuleReference,
|
||||
exportedAs: Option[String],
|
||||
symbols: SymbolRestriction
|
||||
)
|
||||
) {
|
||||
|
||||
/** Convert the internal [[ModuleReference]] to an abstract reference.
|
||||
*
|
||||
* @return `this` with its module reference made abstract
|
||||
*/
|
||||
def toAbstract: ExportedModule = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** Convert the internal [[ModuleReference]] to a concrete reference.
|
||||
*
|
||||
* @param moduleMap the mapping from qualified names to modules
|
||||
* @return `this` with its module reference made concrete
|
||||
*/
|
||||
def toConcrete(moduleMap: ModuleMap): Option[ExportedModule] = {
|
||||
module.toConcrete(moduleMap).map(x => this.copy(module = x))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of a resolved import statement.
|
||||
*
|
||||
@ -444,8 +552,26 @@ object BindingsMap {
|
||||
case class ResolvedImport(
|
||||
importDef: IR.Module.Scope.Import.Module,
|
||||
exports: Option[IR.Module.Scope.Export.Module],
|
||||
module: Module
|
||||
)
|
||||
module: ModuleReference
|
||||
) {
|
||||
|
||||
/** Convert the internal [[ModuleReference]] to an abstract reference.
|
||||
*
|
||||
* @return `this` with its module reference made abstract
|
||||
*/
|
||||
def toAbstract: ResolvedImport = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** Convert the internal [[ModuleReference]] to a concrete reference.
|
||||
*
|
||||
* @param moduleMap the mapping from qualified names to modules
|
||||
* @return `this` with its module reference made concrete
|
||||
*/
|
||||
def toConcrete(moduleMap: ModuleMap): Option[ResolvedImport] = {
|
||||
module.toConcrete(moduleMap).map(x => this.copy(module = x))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of a constructor.
|
||||
*
|
||||
@ -469,7 +595,20 @@ object BindingsMap {
|
||||
/** A result of successful name resolution.
|
||||
*/
|
||||
sealed trait ResolvedName {
|
||||
def module: Module
|
||||
def module: ModuleReference
|
||||
|
||||
/** Convert the resolved name to abstract form.
|
||||
*
|
||||
* @return `this`, converted to abstract form
|
||||
*/
|
||||
def toAbstract: ResolvedName
|
||||
|
||||
/** Convert the resolved name to concrete form.
|
||||
*
|
||||
* @param moduleMap the mapping from qualified names to modules
|
||||
* @return `this`, converted to concrete form
|
||||
*/
|
||||
def toConcrete(moduleMap: ModuleMap): Option[ResolvedName]
|
||||
}
|
||||
|
||||
/** A representation of a name being resolved to a constructor.
|
||||
@ -477,28 +616,83 @@ object BindingsMap {
|
||||
* @param module the module the constructor is defined in.
|
||||
* @param cons a representation of the constructor.
|
||||
*/
|
||||
case class ResolvedConstructor(module: Module, cons: Cons)
|
||||
extends ResolvedName
|
||||
case class ResolvedConstructor(module: ModuleReference, cons: Cons)
|
||||
extends ResolvedName {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toAbstract: ResolvedConstructor = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toConcrete(
|
||||
moduleMap: ModuleMap
|
||||
): Option[ResolvedConstructor] = {
|
||||
module.toConcrete(moduleMap).map(module => this.copy(module = module))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of a name being resolved to a module.
|
||||
*
|
||||
* @param module the module the name resolved to.
|
||||
*/
|
||||
case class ResolvedModule(module: Module) extends ResolvedName
|
||||
case class ResolvedModule(module: ModuleReference) extends ResolvedName {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toAbstract: ResolvedModule = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toConcrete(
|
||||
moduleMap: ModuleMap
|
||||
): Option[ResolvedModule] = {
|
||||
module.toConcrete(moduleMap).map(module => this.copy(module = module))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of a name being resolved to a method call.
|
||||
*
|
||||
* @param module the module defining the method.
|
||||
* @param method the method representation.
|
||||
*/
|
||||
case class ResolvedMethod(module: Module, method: ModuleMethod)
|
||||
extends ResolvedName
|
||||
case class ResolvedMethod(module: ModuleReference, method: ModuleMethod)
|
||||
extends ResolvedName {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toAbstract: ResolvedMethod = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toConcrete(
|
||||
moduleMap: ModuleMap
|
||||
): Option[ResolvedMethod] = {
|
||||
module.toConcrete(moduleMap).map(module => this.copy(module = module))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of a name being resolved to a polyglot symbol.
|
||||
*
|
||||
* @param symbol the imported symbol name.
|
||||
*/
|
||||
case class ResolvedPolyglotSymbol(module: Module, symbol: PolyglotSymbol)
|
||||
extends ResolvedName
|
||||
case class ResolvedPolyglotSymbol(
|
||||
module: ModuleReference,
|
||||
symbol: PolyglotSymbol
|
||||
) extends ResolvedName {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toAbstract: ResolvedPolyglotSymbol = {
|
||||
this.copy(module = module.toAbstract)
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toConcrete(
|
||||
moduleMap: ModuleMap
|
||||
): Option[ResolvedPolyglotSymbol] = {
|
||||
module.toConcrete(moduleMap).map(module => this.copy(module = module))
|
||||
}
|
||||
}
|
||||
|
||||
/** A representation of an error during name resolution.
|
||||
*/
|
||||
@ -532,4 +726,94 @@ object BindingsMap {
|
||||
*/
|
||||
override def duplicate(): Option[IRPass.Metadata] = Some(this)
|
||||
}
|
||||
|
||||
/** A reference to a module.
|
||||
*/
|
||||
sealed trait ModuleReference {
|
||||
|
||||
/** @return the qualified name of the module
|
||||
*/
|
||||
def getName: QualifiedName
|
||||
|
||||
/** Convert `this` into a concrete module reference.
|
||||
*
|
||||
* @param moduleMap the mapping from qualified names to concrete modules
|
||||
* @return the concrete module for this reference, if possible
|
||||
*/
|
||||
def toConcrete(
|
||||
moduleMap: PackageRepository.ModuleMap
|
||||
): Option[ModuleReference.Concrete]
|
||||
|
||||
/** Convert `this` into an abstract module reference.
|
||||
*
|
||||
* @return the abstract reference to the module represented by `this`
|
||||
*/
|
||||
def toAbstract: ModuleReference.Abstract
|
||||
|
||||
/** Unsafely coerces the module reference to a concrete one.
|
||||
*
|
||||
* @param message the message for if the coercion fails
|
||||
* @return the concrete version of this reference
|
||||
*/
|
||||
@throws[CompilerError]
|
||||
def unsafeAsModule(message: String = ""): Module
|
||||
}
|
||||
object ModuleReference {
|
||||
|
||||
/** A module reference that points to a concrete [[Module]] object.
|
||||
*
|
||||
* @param module the module being referenced
|
||||
*/
|
||||
case class Concrete(module: Module) extends ModuleReference {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def getName: QualifiedName = module.getName
|
||||
|
||||
/** Converts `this` into a concrete module reference (a no-op).
|
||||
*
|
||||
* @param moduleMap the mapping from qualified names to concrete modules
|
||||
* @return the concrete module for this reference, if possible
|
||||
*/
|
||||
override def toConcrete(moduleMap: ModuleMap): Option[Concrete] =
|
||||
Some(this)
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toAbstract: Abstract =
|
||||
ModuleReference.Abstract(module.getName)
|
||||
|
||||
/** @inheritdoc */
|
||||
override def unsafeAsModule(message: String = ""): Module = module
|
||||
}
|
||||
|
||||
/** A module reference that refers to a module by qualified name, without an
|
||||
* explicit link to the target.
|
||||
*
|
||||
* @param name the qualified name (including namespace) of the module
|
||||
* being referenced
|
||||
*/
|
||||
case class Abstract(name: QualifiedName) extends ModuleReference {
|
||||
|
||||
/** @inheritdoc */
|
||||
override def getName: QualifiedName = name
|
||||
|
||||
/** @inheritdoc */
|
||||
override def toConcrete(moduleMap: ModuleMap): Option[Concrete] = {
|
||||
moduleMap.get(name.toString).map(Concrete)
|
||||
}
|
||||
|
||||
/** Convert `this` into an abstract module reference (a no-op).
|
||||
*
|
||||
* @return the abstract reference to the module represented by `this`
|
||||
*/
|
||||
override def toAbstract: Abstract = this
|
||||
|
||||
/** @inheritdoc */
|
||||
override def unsafeAsModule(message: String = ""): Module = {
|
||||
val rest = if (message.isEmpty) "." else s": $message"
|
||||
val errMsg = s"Could not get concrete module from abstract module $name$rest"
|
||||
|
||||
throw new CompilerError(errMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import org.enso.compiler.context.{InlineContext, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.ir.MetadataStorage.ToPair
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.ModuleReference
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.desugar.{
|
||||
ComplexType,
|
||||
@ -81,7 +82,7 @@ case object BindingAnalysis extends IRPass {
|
||||
definedConstructors,
|
||||
importedPolyglot,
|
||||
methodsWithAutogen,
|
||||
moduleContext.module
|
||||
ModuleReference.Concrete(moduleContext.module)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package org.enso.compiler.pass.resolve
|
||||
import org.enso.compiler.context.{InlineContext, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.ResolvedModule
|
||||
import org.enso.compiler.data.BindingsMap.{ModuleReference, ResolvedModule}
|
||||
import org.enso.compiler.exception.CompilerError
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.analyse.AliasAnalysis
|
||||
@ -46,8 +46,9 @@ case object ModuleThisToHere extends IRPass {
|
||||
ir: IR.Module,
|
||||
moduleContext: ModuleContext
|
||||
): IR.Module = {
|
||||
val localResolution =
|
||||
BindingsMap.Resolution(ResolvedModule(moduleContext.module))
|
||||
val localResolution = BindingsMap.Resolution(
|
||||
ResolvedModule(ModuleReference.Concrete(moduleContext.module))
|
||||
)
|
||||
val newBindings = ir.bindings.map {
|
||||
case m: IR.Module.Scope.Definition.Method =>
|
||||
if (
|
||||
|
@ -251,7 +251,9 @@ case object UppercaseNames extends IRPass {
|
||||
): Option[BindingsMap.ResolvedConstructor] =
|
||||
thisResolution.target match {
|
||||
case BindingsMap.ResolvedModule(module) =>
|
||||
val resolution = module.getIr
|
||||
val resolution = module
|
||||
.unsafeAsModule()
|
||||
.getIr
|
||||
.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Imported module without bindings analysis results"
|
||||
|
@ -4,8 +4,10 @@ import org.enso.compiler.context.{InlineContext, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.ir.MetadataStorage.ToPair
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.ModuleReference
|
||||
import org.enso.compiler.pass.IRPass
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.interpreter.runtime.Module
|
||||
|
||||
case object VectorLiterals extends IRPass {
|
||||
|
||||
@ -21,6 +23,9 @@ case object VectorLiterals extends IRPass {
|
||||
/** The passes that are invalidated by running this pass. */
|
||||
override val invalidatedPasses: Seq[IRPass] = Seq()
|
||||
|
||||
/** The name of the module that contains the Enso stdlib vector definition. */
|
||||
val vectorModuleName: String = "Standard.Base.Data.Vector"
|
||||
|
||||
/** Executes the pass on the provided `ir`, and returns a possibly transformed
|
||||
* or annotated version of `ir`.
|
||||
*
|
||||
@ -64,17 +69,17 @@ case object VectorLiterals extends IRPass {
|
||||
}
|
||||
|
||||
private def vectorCons(bindings: BindingsMap): IR.Expression = {
|
||||
val module = bindings.resolvedImports
|
||||
.flatMap(imp =>
|
||||
imp.module :: imp.module.getIr
|
||||
val modules: List[Module] = bindings.resolvedImports.flatMap { imp =>
|
||||
val module = imp.module.unsafeAsModule()
|
||||
module :: module.getIr
|
||||
.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"no binding analyis on an imported module"
|
||||
"no binding analysis on an imported module"
|
||||
)
|
||||
.resolvedExports
|
||||
.map(_.module)
|
||||
)
|
||||
.find(_.getName.toString == "Standard.Base.Data.Vector")
|
||||
.map { export => export.module.unsafeAsModule() }
|
||||
}
|
||||
val module = modules.find(_.getName.toString == vectorModuleName)
|
||||
val name = IR.Name.Literal(
|
||||
"<Sequence Macro>",
|
||||
isReferent = true,
|
||||
@ -86,7 +91,10 @@ case object VectorLiterals extends IRPass {
|
||||
val withRes = name.updateMetadata(
|
||||
UppercaseNames -->> BindingsMap.Resolution(
|
||||
BindingsMap
|
||||
.ResolvedConstructor(module, BindingsMap.Cons("Vector", 1))
|
||||
.ResolvedConstructor(
|
||||
ModuleReference.Concrete(module),
|
||||
BindingsMap.Cons("Vector", 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
withRes
|
||||
|
@ -3,6 +3,7 @@ package org.enso.compiler.phase
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.{
|
||||
ExportedModule,
|
||||
ModuleReference,
|
||||
ResolvedConstructor,
|
||||
ResolvedMethod,
|
||||
ResolvedModule,
|
||||
@ -53,7 +54,7 @@ class ExportsResolution {
|
||||
val node = nodes(module)
|
||||
node.exports = exports.map {
|
||||
case ExportedModule(mod, rename, restriction) =>
|
||||
Edge(node, restriction, rename, nodes(mod))
|
||||
Edge(node, restriction, rename, nodes(mod.unsafeAsModule()))
|
||||
}
|
||||
node.exports.foreach { edge => edge.exportee.exportedBy ::= edge }
|
||||
}
|
||||
@ -122,12 +123,16 @@ class ExportsResolution {
|
||||
nodes.foreach { node =>
|
||||
val explicitlyExported =
|
||||
node.exports.map(edge =>
|
||||
ExportedModule(edge.exportee.module, edge.exportsAs, edge.symbols)
|
||||
ExportedModule(
|
||||
ModuleReference.Concrete(edge.exportee.module),
|
||||
edge.exportsAs,
|
||||
edge.symbols
|
||||
)
|
||||
)
|
||||
val transitivelyExported: List[ExportedModule] =
|
||||
explicitlyExported.flatMap {
|
||||
case ExportedModule(module, _, restriction) =>
|
||||
exports(module).map {
|
||||
exports(module.unsafeAsModule()).map {
|
||||
case ExportedModule(export, _, parentRestriction) =>
|
||||
ExportedModule(
|
||||
export,
|
||||
@ -160,22 +165,31 @@ class ExportsResolution {
|
||||
private def resolveExportedSymbols(modules: List[Module]): Unit = {
|
||||
modules.foreach { module =>
|
||||
val bindings = getBindings(module)
|
||||
val ownMethods = bindings.moduleMethods.map(method =>
|
||||
(method.name.toLowerCase, List(ResolvedMethod(module, method)))
|
||||
)
|
||||
val ownConstructors = bindings.types.map(tp =>
|
||||
(tp.name.toLowerCase, List(ResolvedConstructor(module, tp)))
|
||||
)
|
||||
val ownPolyglotBindings = bindings.polyglotSymbols.map(poly =>
|
||||
(poly.name.toLowerCase, List(ResolvedPolyglotSymbol(module, poly)))
|
||||
)
|
||||
val ownMethods = bindings.moduleMethods.map { method =>
|
||||
val name = method.name.toLowerCase
|
||||
val syms =
|
||||
List(ResolvedMethod(ModuleReference.Concrete(module), method))
|
||||
(name, syms)
|
||||
}
|
||||
val ownConstructors = bindings.types.map { tp =>
|
||||
val name = tp.name.toLowerCase
|
||||
val types =
|
||||
List(ResolvedConstructor(ModuleReference.Concrete(module), tp))
|
||||
(name, types)
|
||||
}
|
||||
val ownPolyglotBindings = bindings.polyglotSymbols.map { poly =>
|
||||
val name = poly.name.toLowerCase
|
||||
val syms =
|
||||
List(ResolvedPolyglotSymbol(ModuleReference.Concrete(module), poly))
|
||||
(name, syms)
|
||||
}
|
||||
val exportedModules = bindings.resolvedExports.collect {
|
||||
case ExportedModule(mod, Some(name), _) =>
|
||||
(name.toLowerCase, List(ResolvedModule(mod)))
|
||||
}
|
||||
val reExportedSymbols = bindings.resolvedExports.flatMap { export =>
|
||||
getBindings(export.module).exportedSymbols.toList.flatMap {
|
||||
case (sym, resolutions) =>
|
||||
getBindings(export.module.unsafeAsModule()).exportedSymbols.toList
|
||||
.flatMap { case (sym, resolutions) =>
|
||||
val allowedResolutions =
|
||||
resolutions.filter(res => export.symbols.canAccess(sym, res))
|
||||
if (allowedResolutions.isEmpty) None
|
||||
|
@ -3,6 +3,7 @@ package org.enso.compiler.phase
|
||||
import org.enso.compiler.Compiler
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.ModuleReference
|
||||
import org.enso.compiler.exception.CompilerError
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.editions.LibraryName
|
||||
@ -78,7 +79,13 @@ class ImportResolver(compiler: Compiler) {
|
||||
case Some(module) =>
|
||||
(
|
||||
imp,
|
||||
Some(BindingsMap.ResolvedImport(imp, exp, module))
|
||||
Some(
|
||||
BindingsMap.ResolvedImport(
|
||||
imp,
|
||||
exp,
|
||||
ModuleReference.Concrete(module)
|
||||
)
|
||||
)
|
||||
)
|
||||
case None =>
|
||||
(
|
||||
@ -112,7 +119,9 @@ class ImportResolver(compiler: Compiler) {
|
||||
}
|
||||
// continue with updated stack
|
||||
go(
|
||||
stack.pushAll(currentLocal.resolvedImports.map(_.module)),
|
||||
stack.pushAll(
|
||||
currentLocal.resolvedImports.map(_.module.unsafeAsModule())
|
||||
),
|
||||
seen += current
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,11 @@ package org.enso.compiler.phase
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.ir.MetadataStorage._
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.{ResolvedConstructor, ResolvedMethod}
|
||||
import org.enso.compiler.data.BindingsMap.{
|
||||
ModuleReference,
|
||||
ResolvedConstructor,
|
||||
ResolvedMethod
|
||||
}
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.interpreter.runtime.Module
|
||||
|
||||
@ -39,13 +43,18 @@ object StubIrBuilder {
|
||||
val polyglot = scope.getPolyglotSymbols.asScala.keys.toList
|
||||
.map(BindingsMap.PolyglotSymbol)
|
||||
val exportedBindings = definedConstructors.map(c =>
|
||||
(c.name.toLowerCase, List(ResolvedConstructor(module, c)))
|
||||
) ++ moduleMethods.map(m => (m.name, List(ResolvedMethod(module, m))))
|
||||
(
|
||||
c.name.toLowerCase,
|
||||
List(ResolvedConstructor(ModuleReference.Concrete(module), c))
|
||||
)
|
||||
) ++ moduleMethods.map(m =>
|
||||
(m.name, List(ResolvedMethod(ModuleReference.Concrete(module), m)))
|
||||
)
|
||||
val meta = BindingsMap(
|
||||
definedConstructors,
|
||||
polyglot,
|
||||
moduleMethods,
|
||||
module
|
||||
ModuleReference.Concrete(module)
|
||||
)
|
||||
meta.exportedSymbols = exportedBindings.toMap
|
||||
ir.updateMetadata(BindingAnalysis -->> meta)
|
||||
|
@ -3,7 +3,7 @@ package org.enso.compiler.test.pass.analyse
|
||||
import org.enso.compiler.Passes
|
||||
import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap.{Cons, ModuleMethod, PolyglotSymbol}
|
||||
import org.enso.compiler.data.BindingsMap.{Cons, ModuleMethod, ModuleReference, PolyglotSymbol}
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.compiler.pass.{PassConfiguration, PassGroup, PassManager}
|
||||
import org.enso.compiler.test.CompilerTest
|
||||
@ -37,7 +37,7 @@ class BindingAnalysisTest extends CompilerTest {
|
||||
* @param context the module context in which analysis takes place
|
||||
* @return [[ir]], with tail call analysis metadata attached
|
||||
*/
|
||||
def analyse(implicit context: ModuleContext) = {
|
||||
def analyse(implicit context: ModuleContext): IR.Module = {
|
||||
BindingAnalysis.runModule(ir, context)
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ class BindingAnalysisTest extends CompilerTest {
|
||||
ModuleMethod("enso_project"),
|
||||
ModuleMethod("foo")
|
||||
)
|
||||
metadata.currentModule shouldEqual ctx.module
|
||||
metadata.currentModule shouldEqual ModuleReference.Concrete(ctx.module)
|
||||
}
|
||||
|
||||
"properly assign module-level methods when a type with the same name as module is defined" in {
|
||||
|
@ -4,7 +4,7 @@ import org.enso.compiler.Passes
|
||||
import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.data.BindingsMap.Cons
|
||||
import org.enso.compiler.data.BindingsMap.{Cons, ModuleReference}
|
||||
import org.enso.compiler.pass.resolve.MethodDefinitions
|
||||
import org.enso.compiler.pass.{PassConfiguration, PassGroup, PassManager}
|
||||
import org.enso.compiler.test.CompilerTest
|
||||
@ -77,7 +77,7 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
.getMetadata(MethodDefinitions) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(
|
||||
ctx.module,
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Foo", 3)
|
||||
)
|
||||
)
|
||||
@ -88,7 +88,7 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
.typePointer
|
||||
.getMetadata(MethodDefinitions) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedModule(ctx.module)
|
||||
BindingsMap.ResolvedModule(ModuleReference.Concrete(ctx.module))
|
||||
)
|
||||
)
|
||||
ir.bindings(4)
|
||||
@ -97,7 +97,7 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
.typePointer
|
||||
.getMetadata(MethodDefinitions) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedModule(ctx.module)
|
||||
BindingsMap.ResolvedModule(ModuleReference.Concrete(ctx.module))
|
||||
)
|
||||
)
|
||||
ir.bindings(5)
|
||||
@ -112,12 +112,18 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
MethodDefinitions
|
||||
) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(ctx.module, Cons("Foo", 3))
|
||||
BindingsMap.ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Foo", 3)
|
||||
)
|
||||
)
|
||||
)
|
||||
conv1.sourceTypeName.getMetadata(MethodDefinitions) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(ctx.module, Cons("Bar", 0))
|
||||
BindingsMap.ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Bar", 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@ -128,7 +134,10 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
MethodDefinitions
|
||||
) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(ctx.module, Cons("Bar", 0))
|
||||
BindingsMap.ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Bar", 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
conv2.sourceTypeName shouldBe an[IR.Error.Resolution]
|
||||
@ -139,7 +148,10 @@ class MethodDefinitionsTest extends CompilerTest {
|
||||
conv3.methodReference.typePointer shouldBe an[IR.Error.Resolution]
|
||||
conv3.sourceTypeName.getMetadata(MethodDefinitions) shouldEqual Some(
|
||||
BindingsMap.Resolution(
|
||||
BindingsMap.ResolvedConstructor(ctx.module, Cons("Foo", 3))
|
||||
BindingsMap.ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Foo", 3)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap.{
|
||||
Cons,
|
||||
ModuleReference,
|
||||
Resolution,
|
||||
ResolvedConstructor
|
||||
}
|
||||
@ -85,7 +86,12 @@ class PatternsTest extends CompilerTest {
|
||||
.asInstanceOf[IR.Pattern.Constructor]
|
||||
.constructor
|
||||
.getMetadata(Patterns) shouldEqual Some(
|
||||
Resolution(ResolvedConstructor(ctx.module, Cons("Foo", 3)))
|
||||
Resolution(
|
||||
ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("Foo", 3)
|
||||
)
|
||||
)
|
||||
)
|
||||
patterns(1) shouldBe a[IR.Error.Pattern]
|
||||
patterns(2)
|
||||
|
@ -5,6 +5,7 @@ import org.enso.compiler.context.{FreshNameSupply, ModuleContext}
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.data.BindingsMap.{
|
||||
Cons,
|
||||
ModuleReference,
|
||||
Resolution,
|
||||
ResolvedConstructor,
|
||||
ResolvedModule
|
||||
@ -94,7 +95,12 @@ class UppercaseNamesTest extends CompilerTest {
|
||||
.asInstanceOf[IR.Application.Prefix]
|
||||
.function
|
||||
.getMetadata(UppercaseNames) shouldEqual Some(
|
||||
Resolution(ResolvedConstructor(ctx.module, Cons("My_Cons", 3)))
|
||||
Resolution(
|
||||
ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("My_Cons", 3)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -105,7 +111,7 @@ class UppercaseNamesTest extends CompilerTest {
|
||||
app.function.asInstanceOf[IR.Name.Literal].name shouldEqual "constant"
|
||||
app.arguments.length shouldEqual 1
|
||||
app.arguments(0).value.getMetadata(UppercaseNames) shouldEqual Some(
|
||||
Resolution(ResolvedModule(ctx.module))
|
||||
Resolution(ResolvedModule(ModuleReference.Concrete(ctx.module)))
|
||||
)
|
||||
}
|
||||
|
||||
@ -116,7 +122,7 @@ class UppercaseNamesTest extends CompilerTest {
|
||||
app.function.asInstanceOf[IR.Name.Literal].name shouldEqual "add_one"
|
||||
app.arguments.length shouldEqual 2
|
||||
app.arguments(0).value.getMetadata(UppercaseNames) shouldEqual Some(
|
||||
Resolution(ResolvedModule(ctx.module))
|
||||
Resolution(ResolvedModule(ModuleReference.Concrete(ctx.module)))
|
||||
)
|
||||
}
|
||||
|
||||
@ -124,7 +130,12 @@ class UppercaseNamesTest extends CompilerTest {
|
||||
val app = bodyExprs(3).asInstanceOf[IR.Application.Prefix]
|
||||
app.arguments.length shouldBe 3
|
||||
app.function.getMetadata(UppercaseNames) shouldEqual Some(
|
||||
Resolution(ResolvedConstructor(ctx.module, Cons("My_Cons", 3)))
|
||||
Resolution(
|
||||
ResolvedConstructor(
|
||||
ModuleReference.Concrete(ctx.module),
|
||||
Cons("My_Cons", 3)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.enso.interpreter.test.instrument
|
||||
|
||||
import org.enso.compiler.pass.resolve.VectorLiterals
|
||||
import org.enso.distribution.FileSystem
|
||||
import org.enso.distribution.locking.ThreadSafeFileLockManager
|
||||
import org.enso.interpreter.test.Metadata
|
||||
@ -204,7 +205,7 @@ class RuntimeStdlibTest
|
||||
)
|
||||
) if module.contains("Vector") =>
|
||||
(xs.nonEmpty || as.nonEmpty) shouldBe true
|
||||
xs.toVector.head.suggestion.module shouldEqual "Standard.Base.Data.Vector"
|
||||
xs.toVector.head.suggestion.module shouldEqual VectorLiterals.vectorModuleName
|
||||
}
|
||||
stdlibSuggestions.nonEmpty shouldBe true
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user