mirror of
https://github.com/enso-org/enso.git
synced 2024-09-11 21:27:15 +03:00
Fix imports resolution (#1129)
Fix the ImportResolver issue when the module was compiled the second time and refactor the logic into tail-recursive function.
This commit is contained in:
parent
259302c229
commit
a2accd3444
@ -55,12 +55,22 @@ public class Module implements TruffleObject {
|
||||
/**
|
||||
* Checks whether the current compilation stage is at least as advanced as the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is at least as advanced as {@code stage}.
|
||||
*/
|
||||
public boolean isAtLeast(CompilationStage stage) {
|
||||
return ordinal >= stage.ordinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the current compilation stage is before the provided one.
|
||||
*
|
||||
* @param stage the stage to compare to.
|
||||
* @return whether or not {@code this} is before then {@code stage}.
|
||||
*/
|
||||
public boolean isBefore(CompilationStage stage) {
|
||||
return ordinal < stage.ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleScope scope;
|
||||
|
@ -6,7 +6,6 @@ import org.enso.compiler.data.BindingsMap
|
||||
import org.enso.compiler.pass.analyse.BindingAnalysis
|
||||
import org.enso.interpreter.runtime.Module
|
||||
|
||||
import util.control.Breaks._
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
@ -30,43 +29,54 @@ class ImportResolver(compiler: Compiler) {
|
||||
* the program.
|
||||
*/
|
||||
def mapImports(module: Module): List[Module] = {
|
||||
val seen: mutable.Set[Module] = mutable.Set()
|
||||
var stack: List[Module] = List(module)
|
||||
while (stack.nonEmpty) {
|
||||
val current = stack.head
|
||||
stack = stack.tail
|
||||
breakable {
|
||||
if (
|
||||
seen.contains(current) || current.getCompilationStage.isAtLeast(
|
||||
Module.CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
@scala.annotation.tailrec
|
||||
def go(
|
||||
stack: mutable.Stack[Module],
|
||||
seen: mutable.Set[Module]
|
||||
): List[Module] = {
|
||||
if (stack.isEmpty) {
|
||||
seen.toList
|
||||
} else {
|
||||
val current = stack.pop()
|
||||
if (seen.contains(current)) {
|
||||
go(stack, seen)
|
||||
} else {
|
||||
// get module metadata
|
||||
compiler.ensureParsed(current)
|
||||
val ir = current.getIr
|
||||
val currentLocal = ir.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Non-parsed module used in ImportResolver"
|
||||
)
|
||||
// put the list of resolved imports in the module metadata
|
||||
if (
|
||||
current.getCompilationStage
|
||||
.isBefore(Module.CompilationStage.AFTER_IMPORT_RESOLUTION)
|
||||
) {
|
||||
val importedModules = ir.imports.flatMap {
|
||||
case imp: IR.Module.Scope.Import.Module =>
|
||||
val impName = imp.name.name
|
||||
val exp = ir.exports.find(_.name.name == impName)
|
||||
compiler
|
||||
.getModule(impName)
|
||||
.map(BindingsMap.ResolvedImport(imp, exp, _))
|
||||
case _ => None
|
||||
}
|
||||
currentLocal.resolvedImports = importedModules
|
||||
current.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
)
|
||||
}
|
||||
// continue with updated stack
|
||||
go(
|
||||
stack.pushAll(currentLocal.resolvedImports.map(_.module)),
|
||||
seen += current
|
||||
)
|
||||
) {
|
||||
break()
|
||||
}
|
||||
compiler.ensureParsed(current)
|
||||
val ir = current.getIr
|
||||
val currentLocal = ir.unsafeGetMetadata(
|
||||
BindingAnalysis,
|
||||
"Non-parsed module used in ImportResolver"
|
||||
)
|
||||
val importedModules = ir.imports.flatMap {
|
||||
case imp: IR.Module.Scope.Import.Module =>
|
||||
val impName = imp.name.name
|
||||
val exp = ir.exports.find(_.name.name == impName)
|
||||
compiler
|
||||
.getModule(impName)
|
||||
.map(BindingsMap.ResolvedImport(imp, exp, _))
|
||||
case _ => None
|
||||
}
|
||||
|
||||
currentLocal.resolvedImports = importedModules
|
||||
current.unsafeSetCompilationStage(
|
||||
Module.CompilationStage.AFTER_IMPORT_RESOLUTION
|
||||
)
|
||||
stack = currentLocal.resolvedImports.map(_.module) ++ stack
|
||||
}
|
||||
seen += current
|
||||
}
|
||||
seen.toList
|
||||
|
||||
go(mutable.Stack(module), mutable.Set())
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user