mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 03:32:23 +03:00
Fix Meta.get_qualified_type_name when run as single file (#11401)
`Meta.get_qualified_type_name` correctly returns fully qualified type name when running a single file from a project with `enso --run Proj/src/Main.enso`.
This commit is contained in:
parent
aad1107a8e
commit
536a49f35d
@ -1,5 +1,8 @@
|
||||
package org.enso.interpreter.caches;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -29,9 +32,13 @@ public class HelloWorldCacheTest {
|
||||
// the second run must read Hello_World from its .ir file!
|
||||
var secondMsgs = executeOnce(helloWorld);
|
||||
assertTrue("Contains hello world:\n" + secondMsgs, secondMsgs.contains("Hello World"));
|
||||
assertTrue(
|
||||
assertThat(
|
||||
"Properly deserialized:\n" + secondMsgs,
|
||||
secondMsgs.contains("Deserializing module Hello_World from IR file: true"));
|
||||
secondMsgs,
|
||||
allOf(
|
||||
containsString("Deserializing module"),
|
||||
containsString("Hello_World"),
|
||||
containsString("from IR file: true")));
|
||||
}
|
||||
|
||||
private static String executeOnce(File src) throws Exception {
|
||||
|
@ -0,0 +1,37 @@
|
||||
package org.enso.interpreter.test.meta;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.enso.test.utils.ProjectUtils;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class QualifiedNameTest {
|
||||
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
private static final String mainModSrc =
|
||||
"""
|
||||
from Standard.Base import all
|
||||
|
||||
type My_Type
|
||||
Value x
|
||||
|
||||
main =
|
||||
obj = My_Type.Value 42
|
||||
Meta.get_qualified_type_name obj
|
||||
""";
|
||||
|
||||
@Test
|
||||
public void qualifiedTypeNameWorks_WhenRunningSingleFile() throws IOException {
|
||||
var projDir = temporaryFolder.newFolder().toPath();
|
||||
ProjectUtils.createProject("Proj", mainModSrc, projDir);
|
||||
ProjectUtils.testProjectRun(
|
||||
projDir,
|
||||
(res) -> {
|
||||
assertThat(res.asString(), is("local.Proj.Main.My_Type"));
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -22,23 +22,19 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
|
||||
private val moduleName = QualifiedName.simpleName("Test")
|
||||
|
||||
implicit private class PreprocessModule(code: String) {
|
||||
|
||||
private val Module = QualifiedName(List("Unnamed"), "Test")
|
||||
|
||||
def preprocessModule(name: QualifiedName): Module = {
|
||||
def preprocessModule(): Module = {
|
||||
val module = new runtime.Module(
|
||||
name,
|
||||
moduleName,
|
||||
null,
|
||||
code.stripMargin.linesIterator.mkString("\n")
|
||||
)
|
||||
langCtx.getCompiler.run(module.asCompilerModule())
|
||||
module.getIr
|
||||
}
|
||||
|
||||
def preprocessModule: Module =
|
||||
preprocessModule(Module)
|
||||
|
||||
}
|
||||
|
||||
private def findUsagesOfLiteral(
|
||||
@ -86,7 +82,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule
|
||||
val module = code.preprocessModule()
|
||||
val operator1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfLiteral(module, operator1)
|
||||
|
||||
@ -111,7 +107,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule
|
||||
val module = code.preprocessModule()
|
||||
val operator1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfLiteral(module, operator1)
|
||||
|
||||
@ -136,7 +132,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule
|
||||
val module = code.preprocessModule()
|
||||
val operator1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfLiteral(module, operator1)
|
||||
|
||||
@ -148,8 +144,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
}
|
||||
|
||||
"find usages of a static method call in main body" in {
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val moduleName = QualifiedName(List("Unnamed"), "Test")
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val code =
|
||||
s"""function1 x = x + 1
|
||||
|
|
||||
@ -164,7 +159,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule(moduleName)
|
||||
val module = code.preprocessModule()
|
||||
val function1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfModuleMethod(moduleName, module, function1)
|
||||
|
||||
@ -176,8 +171,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
}
|
||||
|
||||
"find usages of a static call in lambda" in {
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val moduleName = QualifiedName(List("Unnamed"), "Test")
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val code =
|
||||
s"""function1 x = x
|
||||
|
|
||||
@ -192,7 +186,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule(moduleName)
|
||||
val module = code.preprocessModule()
|
||||
val function1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfModuleMethod(moduleName, module, function1)
|
||||
|
||||
@ -204,8 +198,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
}
|
||||
|
||||
"find usages of a static method call in presence of an instance method" in {
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val moduleName = QualifiedName(List("Unnamed"), "Test")
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val code =
|
||||
s"""function1 x = x
|
||||
|
|
||||
@ -220,7 +213,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule(moduleName)
|
||||
val module = code.preprocessModule()
|
||||
val function1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfModuleMethod(moduleName, module, function1)
|
||||
|
||||
@ -232,8 +225,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
}
|
||||
|
||||
"find usages of a static method call in presence of a type method" in {
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val moduleName = QualifiedName(List("Unnamed"), "Test")
|
||||
val uuid1 = new UUID(0, 1)
|
||||
val code =
|
||||
s"""function1 x = x
|
||||
|
|
||||
@ -251,7 +243,7 @@ class IRUtilsTest extends AnyWordSpecLike with Matchers with OptionValues {
|
||||
|[]
|
||||
|""".stripMargin
|
||||
|
||||
val module = code.preprocessModule(moduleName)
|
||||
val module = code.preprocessModule()
|
||||
val operator1 = IRUtils.findByExternalId(module, uuid1).get
|
||||
val usages = findUsagesOfModuleMethod(moduleName, module, operator1)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.enso.compiler.test.semantic
|
||||
|
||||
import com.oracle.truffle.api.TruffleFile
|
||||
import org.enso.compiler.core.Implicits.AsMetadata
|
||||
import org.enso.compiler.core.ir.{Module, ProcessingPass, Warning}
|
||||
import org.enso.compiler.core.ir.expression.errors
|
||||
@ -11,17 +12,18 @@ import org.enso.interpreter.runtime
|
||||
import org.enso.interpreter.runtime.EnsoContext
|
||||
import org.enso.persist.Persistance
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.pkg.Package
|
||||
import org.enso.common.LanguageInfo
|
||||
import org.enso.common.MethodNames
|
||||
import org.enso.compiler.phase.exports.Node
|
||||
import org.enso.common.RuntimeOptions
|
||||
import org.enso.test.utils.{ContextUtils, ProjectUtils}
|
||||
import org.graalvm.polyglot.{Context, Engine}
|
||||
import org.scalatest.BeforeAndAfter
|
||||
import org.scalatest.{BeforeAndAfter}
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpecLike
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.{Files, Path, Paths}
|
||||
import java.util.logging.Level
|
||||
import java.io.IOException
|
||||
|
||||
@ -35,12 +37,17 @@ class ImportExportTest
|
||||
with BeforeAndAfter {
|
||||
private val out = new ByteArrayOutputStream()
|
||||
|
||||
private val namespace = "local"
|
||||
private val packageName = "My_Package"
|
||||
private val packageQualifiedName =
|
||||
QualifiedName.fromString(namespace + "." + packageName)
|
||||
|
||||
private val engine = Engine
|
||||
.newBuilder("enso")
|
||||
.allowExperimentalOptions(true)
|
||||
.build()
|
||||
|
||||
private val ctx = Context
|
||||
private val ctxBldr = Context
|
||||
.newBuilder(LanguageInfo.ID)
|
||||
.engine(engine)
|
||||
.allowExperimentalOptions(true)
|
||||
@ -51,7 +58,7 @@ class ImportExportTest
|
||||
.option(RuntimeOptions.LOG_LEVEL, Level.WARNING.getName())
|
||||
.option(RuntimeOptions.DISABLE_IR_CACHES, "true")
|
||||
.option(RuntimeOptions.STRICT_ERRORS, "false")
|
||||
.logHandler(System.err)
|
||||
.logHandler(out)
|
||||
.option(
|
||||
RuntimeOptions.LANGUAGE_HOME_OVERRIDE,
|
||||
Paths
|
||||
@ -60,23 +67,34 @@ class ImportExportTest
|
||||
.getAbsolutePath
|
||||
)
|
||||
.option(RuntimeOptions.EDITION_OVERRIDE, "0.0.0-dev")
|
||||
.build()
|
||||
|
||||
private val langCtx: EnsoContext = ctx
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
private var ctx: Context = _
|
||||
private var langCtx: EnsoContext = _
|
||||
private var tmpDir: Path = _
|
||||
private var pkg: Package[TruffleFile] = _
|
||||
|
||||
private val namespace = "my_pkg"
|
||||
private val packageName = "My_Package"
|
||||
private val packageQualifiedName =
|
||||
QualifiedName.fromString(namespace + "." + packageName)
|
||||
before {
|
||||
// Create temp dir with skeleton project structure. In the tests, we will create
|
||||
// synthetic modules that will be part of this project.
|
||||
tmpDir = Files.createTempDirectory("enso-test")
|
||||
ProjectUtils.createProject(packageName, "main = 42", tmpDir)
|
||||
ctxBldr.option(RuntimeOptions.PROJECT_ROOT, tmpDir.toAbsolutePath.toString)
|
||||
ctx = ctxBldr.build()
|
||||
langCtx = ContextUtils.leakContext(ctx)
|
||||
langCtx.getPackageRepository.getMainProjectPackage shouldBe defined
|
||||
pkg = langCtx.getPackageRepository.getMainProjectPackage.get
|
||||
ctx.enter()
|
||||
}
|
||||
|
||||
langCtx.getPackageRepository.registerSyntheticPackage(namespace, packageName)
|
||||
after {
|
||||
ctx.leave()
|
||||
out.reset()
|
||||
ProjectUtils.deleteRecursively(tmpDir)
|
||||
}
|
||||
|
||||
implicit private class CreateModule(moduleCode: String) {
|
||||
def createModule(moduleName: QualifiedName): runtime.Module = {
|
||||
val module = new runtime.Module(moduleName, null, moduleCode)
|
||||
val module = new runtime.Module(moduleName, pkg, moduleCode)
|
||||
langCtx.getPackageRepository.registerModuleCreatedInRuntime(
|
||||
module.asCompilerModule()
|
||||
)
|
||||
@ -114,15 +132,6 @@ class ImportExportTest
|
||||
)
|
||||
}
|
||||
|
||||
before {
|
||||
ctx.enter()
|
||||
}
|
||||
|
||||
after {
|
||||
ctx.leave()
|
||||
out.reset()
|
||||
}
|
||||
|
||||
"Import resolution with just two modules" should {
|
||||
"resolve one import symbol from a module" in {
|
||||
val moduleCode =
|
||||
|
@ -6,15 +6,21 @@ import org.enso.compiler.core.ir
|
||||
import org.enso.compiler.core.ir.module.scope.definition
|
||||
import org.enso.compiler.core.ir.`type`
|
||||
import org.enso.compiler.pass.resolve.{TypeNames, TypeSignatures}
|
||||
import org.enso.interpreter.runtime
|
||||
import org.enso.interpreter.runtime.EnsoContext
|
||||
import org.enso.interpreter.test.InterpreterContext
|
||||
import org.enso.pkg.QualifiedName
|
||||
import org.enso.common.{LanguageInfo, MethodNames}
|
||||
import org.enso.common.{LanguageInfo, MethodNames, RuntimeOptions}
|
||||
import org.enso.editions.LibraryName
|
||||
import org.enso.test.utils.{ProjectUtils, SourceModule}
|
||||
import org.enso.testkit.WithTemporaryDirectory
|
||||
import org.scalatest.BeforeAndAfterAll
|
||||
import org.scalatest.matchers.{MatchResult, Matcher}
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpecLike
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import scala.jdk.CollectionConverters.SetHasAsJava
|
||||
|
||||
trait TypeMatchers {
|
||||
sealed trait Sig {
|
||||
def ->:(that: Sig): Sig = this match {
|
||||
@ -127,36 +133,67 @@ trait TypeMatchers {
|
||||
class TypeSignaturesTest
|
||||
extends AnyWordSpecLike
|
||||
with Matchers
|
||||
with TypeMatchers {
|
||||
with TypeMatchers
|
||||
with WithTemporaryDirectory
|
||||
with BeforeAndAfterAll {
|
||||
|
||||
private val ctx = new InterpreterContext()
|
||||
private val langCtx = ctx
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
private var ctx: InterpreterContext = _
|
||||
private var langCtx: EnsoContext = _
|
||||
private var devNull: ByteArrayOutputStream = new ByteArrayOutputStream()
|
||||
|
||||
private val Module = QualifiedName.fromString("Unnamed.Test")
|
||||
override def afterAll(): Unit = {
|
||||
ctx.close()
|
||||
devNull.close()
|
||||
devNull = null
|
||||
ctx = null
|
||||
langCtx = null
|
||||
}
|
||||
|
||||
langCtx.getPackageRepository.registerSyntheticPackage("my_pkg", "My_Lib")
|
||||
langCtx.getTopScope.createModule(
|
||||
QualifiedName.fromString("my_pkg.My_Lib.Util"),
|
||||
null,
|
||||
s"""
|
||||
|type Util_1
|
||||
|type Util_2
|
||||
|
|
||||
|type Util_Sum
|
||||
| Util_Sum_1
|
||||
| Util_Sum_2
|
||||
|""".stripMargin
|
||||
)
|
||||
private val libName: LibraryName = LibraryName("local", "My_Lib")
|
||||
|
||||
implicit private class PreprocessModule(code: String) {
|
||||
def preprocessModule: Module = {
|
||||
val module = new runtime.Module(Module, null, code)
|
||||
langCtx.getCompiler.run(module.asCompilerModule())
|
||||
module.getIr
|
||||
val utilMod = new SourceModule(
|
||||
QualifiedName.simpleName("Util"),
|
||||
"""
|
||||
|type Util_1
|
||||
|type Util_2
|
||||
|
|
||||
|type Util_Sum
|
||||
| Util_Sum_1
|
||||
| Util_Sum_2
|
||||
|""".stripMargin
|
||||
)
|
||||
val testMod = new SourceModule(QualifiedName.simpleName("Test"), code)
|
||||
ProjectUtils.createProject(
|
||||
libName.name,
|
||||
Set(utilMod, testMod).asJava,
|
||||
getTestDirectory
|
||||
)
|
||||
ctx = new InterpreterContext(bldr =>
|
||||
bldr
|
||||
.option(
|
||||
RuntimeOptions.PROJECT_ROOT,
|
||||
getTestDirectory.toFile.getAbsolutePath
|
||||
)
|
||||
.logHandler(devNull)
|
||||
)
|
||||
langCtx = ctx
|
||||
.ctx()
|
||||
.getBindings(LanguageInfo.ID)
|
||||
.invokeMember(MethodNames.TopScope.LEAK_CONTEXT)
|
||||
.asHostObject[EnsoContext]()
|
||||
val pkgWasLoaded =
|
||||
langCtx.getPackageRepository.ensurePackageIsLoaded(libName)
|
||||
pkgWasLoaded.isRight shouldBe true
|
||||
|
||||
val testModName = QualifiedName.fromString(libName.toString + ".Test")
|
||||
val module =
|
||||
langCtx.getPackageRepository.getLoadedModule(testModName.toString)
|
||||
module shouldBe defined
|
||||
val compilerRes = langCtx.getCompiler.run(module.get)
|
||||
compilerRes.compiledModules.isEmpty shouldBe false
|
||||
module.get.getIr
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,41 +239,41 @@ class TypeSignaturesTest
|
||||
|foo a = 42""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
getSignature(module, "foo") should typeAs(
|
||||
"Unnamed.Test.A" ->: "Unnamed.Test.B" ->: "Unnamed.Test.C" ->: "Unnamed.Test.C" ->: "Unnamed.Test.A"
|
||||
"local.My_Lib.Test.A" ->: "local.My_Lib.Test.B" ->: "local.My_Lib.Test.C" ->: "local.My_Lib.Test.C" ->: "local.My_Lib.Test.A"
|
||||
)
|
||||
}
|
||||
|
||||
"resolve imported names" in {
|
||||
"XX resolve imported names" in {
|
||||
val code =
|
||||
"""
|
||||
|from my_pkg.My_Lib.Util import all
|
||||
|from project.Util import all
|
||||
|
|
||||
|foo : Util_1 -> Util_2
|
||||
|foo a = 23
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
getSignature(module, "foo") should typeAs(
|
||||
"my_pkg.My_Lib.Util.Util_1" ->: "my_pkg.My_Lib.Util.Util_2"
|
||||
"local.My_Lib.Util.Util_1" ->: "local.My_Lib.Util.Util_2"
|
||||
)
|
||||
}
|
||||
|
||||
"resolve imported union type names" in {
|
||||
val code =
|
||||
"""
|
||||
|from my_pkg.My_Lib.Util import all
|
||||
|from project.Util import all
|
||||
|
|
||||
|foo : Util_Sum -> Util_2
|
||||
|foo a = 23
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
getSignature(module, "foo") should typeAs(
|
||||
"my_pkg.My_Lib.Util.Util_Sum" ->: "my_pkg.My_Lib.Util.Util_2"
|
||||
"local.My_Lib.Util.Util_Sum" ->: "local.My_Lib.Util.Util_2"
|
||||
)
|
||||
}
|
||||
|
||||
"resolve anonymous sum types" in {
|
||||
val code =
|
||||
"""from my_pkg.My_Lib.Util import all
|
||||
"""from project.Util import all
|
||||
|
|
||||
|type Foo
|
||||
|
|
||||
@ -245,7 +282,7 @@ class TypeSignaturesTest
|
||||
|""".stripMargin
|
||||
val module = code.preprocessModule
|
||||
getSignature(module, "baz") should typeAs(
|
||||
("Unnamed.Test.Foo" | "my_pkg.My_Lib.Util.Util_2" | "my_pkg.My_Lib.Util.Util_Sum") ->: "Unnamed.Test.Foo"
|
||||
("local.My_Lib.Test.Foo" | "local.My_Lib.Util.Util_2" | "local.My_Lib.Util.Util_Sum") ->: "local.My_Lib.Test.Foo"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -52,14 +52,21 @@ public class ProgramRootNode extends RootNode {
|
||||
public Object execute(VirtualFrame frame) {
|
||||
if (module == null) {
|
||||
CompilerDirectives.transferToInterpreterAndInvalidate();
|
||||
QualifiedName name = QualifiedName.simpleName(canonicalizeName(sourceCode.getName()));
|
||||
QualifiedName simpleName = QualifiedName.simpleName(canonicalizeName(sourceCode.getName()));
|
||||
EnsoContext ctx = EnsoContext.get(this);
|
||||
if (sourceCode.getPath() != null) {
|
||||
TruffleFile src = ctx.getTruffleFile(new File(sourceCode.getPath()));
|
||||
Package<TruffleFile> pkg = ctx.getPackageOf(src).orElse(null);
|
||||
module = new Module(name, pkg, src);
|
||||
QualifiedName qualifiedName;
|
||||
if (pkg != null) {
|
||||
qualifiedName =
|
||||
QualifiedName.fromString(pkg.libraryName().toString() + "." + simpleName.item());
|
||||
} else {
|
||||
qualifiedName = simpleName;
|
||||
}
|
||||
module = new Module(qualifiedName, pkg, src);
|
||||
} else {
|
||||
module = new Module(name, null, sourceCode.getCharacters().toString());
|
||||
module = new Module(simpleName, null, sourceCode.getCharacters().toString());
|
||||
}
|
||||
ctx.getPackageRepository().registerModuleCreatedInRuntime(module.asCompilerModule());
|
||||
if (ctx.isStrictErrors()) {
|
||||
|
@ -87,6 +87,7 @@ public final class Module implements EnsoObject {
|
||||
* @param sourceFile the module's source file.
|
||||
*/
|
||||
public Module(QualifiedName name, Package<TruffleFile> pkg, TruffleFile sourceFile) {
|
||||
ensureConsistentName(name, pkg);
|
||||
this.sources = ModuleSources.NONE.newWith(sourceFile);
|
||||
this.name = name;
|
||||
this.scopeBuilder = new ModuleScope.Builder(this);
|
||||
@ -105,6 +106,7 @@ public final class Module implements EnsoObject {
|
||||
* @param literalSource the module's source.
|
||||
*/
|
||||
public Module(QualifiedName name, Package<TruffleFile> pkg, String literalSource) {
|
||||
ensureConsistentName(name, pkg);
|
||||
this.sources = ModuleSources.NONE.newWith(Rope.apply(literalSource));
|
||||
this.name = name;
|
||||
this.scopeBuilder = new ModuleScope.Builder(this);
|
||||
@ -124,6 +126,7 @@ public final class Module implements EnsoObject {
|
||||
* @param literalSource the module's source.
|
||||
*/
|
||||
public Module(QualifiedName name, Package<TruffleFile> pkg, Rope literalSource) {
|
||||
ensureConsistentName(name, pkg);
|
||||
this.sources = ModuleSources.NONE.newWith(literalSource);
|
||||
this.name = name;
|
||||
this.scopeBuilder = new ModuleScope.Builder(this);
|
||||
@ -143,6 +146,7 @@ public final class Module implements EnsoObject {
|
||||
*/
|
||||
private Module(
|
||||
QualifiedName name, Package<TruffleFile> pkg, boolean synthetic, Rope literalSource) {
|
||||
ensureConsistentName(name, pkg);
|
||||
this.sources =
|
||||
literalSource == null ? ModuleSources.NONE : ModuleSources.NONE.newWith(literalSource);
|
||||
this.name = name;
|
||||
@ -159,6 +163,27 @@ public final class Module implements EnsoObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureConsistentName(QualifiedName name, Package<TruffleFile> pkg) {
|
||||
if (name.toString().equals(Builtins.MODULE_NAME)) {
|
||||
return;
|
||||
}
|
||||
if (pkg != null && name.isSimple()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Simple module name must not be in a package, i.e., trying to initialize a module in a"
|
||||
+ " package '"
|
||||
+ pkg.libraryName().toString()
|
||||
+ "' with a simple name '"
|
||||
+ name
|
||||
+ "'");
|
||||
} else if (pkg == null && !name.isSimple()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Qualified module name must be in a package, i.e., trying to initialize "
|
||||
+ "a module with a qualified name '"
|
||||
+ name
|
||||
+ "' without a package");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps runtime module from compiler module.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import org.enso.common.MethodNames;
|
||||
import org.enso.compiler.PackageRepository;
|
||||
import org.enso.editions.LibraryName;
|
||||
import org.enso.interpreter.EnsoLanguage;
|
||||
import org.enso.interpreter.runtime.EnsoContext;
|
||||
import org.enso.interpreter.runtime.Module;
|
||||
@ -151,7 +152,15 @@ public final class TopLevelScope implements EnsoObject {
|
||||
Types.extractArguments(arguments, String.class, String.class);
|
||||
QualifiedName qualName = QualifiedName.fromString(args.getFirst());
|
||||
File location = new File(args.getSecond());
|
||||
Module module = new Module(qualName, null, context.getTruffleFile(location));
|
||||
var libName = LibraryName.fromModuleName(qualName.toString());
|
||||
Package<TruffleFile> pkg = null;
|
||||
if (libName.isDefined()) {
|
||||
var pkgOpt = context.getPackageRepository().getPackageForLibraryJava(libName.get());
|
||||
if (pkgOpt.isPresent()) {
|
||||
pkg = pkgOpt.get();
|
||||
}
|
||||
}
|
||||
Module module = new Module(qualName, pkg, context.getTruffleFile(location));
|
||||
scope.packageRepository.registerModuleCreatedInRuntime(module.asCompilerModule());
|
||||
return module;
|
||||
}
|
||||
|
@ -49,6 +49,12 @@ case class QualifiedName(path: List[String], item: String) {
|
||||
path.asJava
|
||||
}
|
||||
|
||||
/** Returns true if this a simple name, not a fully qualified name.
|
||||
*/
|
||||
def isSimple(): Boolean = {
|
||||
path.isEmpty
|
||||
}
|
||||
|
||||
def fullPath(): List[String] = path :+ item
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ add_specs suite_builder = suite_builder.group "Meta-Value Inspection" group_buil
|
||||
y = My_Type.Value 1 2 3
|
||||
Meta.get_qualified_type_name x . should_equal "Standard.Base.Data.Numbers.Integer"
|
||||
Meta.get_simple_type_name x . should_equal "Integer"
|
||||
Meta.get_qualified_type_name y . should_end_with "Meta_Location_Spec.My_Type"
|
||||
Meta.get_qualified_type_name y . should_equal "enso_dev.Base_Tests.Semantic.Meta_Location_Spec.My_Type"
|
||||
Meta.get_simple_type_name y . should_equal "My_Type"
|
||||
|
||||
group_builder.specify "should allow access to package names" <|
|
||||
|
Loading…
Reference in New Issue
Block a user