From 20842dcc44bcf307cbe6aa2d5139874d99677f9e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 26 Jun 2017 12:06:23 +0300 Subject: [PATCH] Add module name as a prefix to declaration keys in JS translator This is necessary due to different modules can have same package declarations. When importing declarations from these packages, we should distinguish from which module we are importing it. See KT-18652 --- .../js/test/semantics/BoxJsTestGenerated.java | 6 +++ .../js/translate/utils/signatureUtils.kt | 5 +- .../box/multiModule/samePackageNames.kt | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/box/multiModule/samePackageNames.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 3831fb96d85..6883235fcf3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -5618,6 +5618,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("samePackageNames.kt") + public void testSamePackageNames() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/samePackageNames.kt"); + doTest(fileName); + } + @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/useElementsFromDefaultPackageInAnotherModule.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/signatureUtils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/signatureUtils.kt index 7a7fc465792..70aa0a7dead 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/signatureUtils.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/signatureUtils.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.utils import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.js.naming.encodeSignature import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.module // Unfortunately, our descriptor serializer can't serialize references to descriptors. // We have to serialize entire class or package to serialize function or property. @@ -50,7 +51,9 @@ fun generateSignature(descriptor: DeclarationDescriptor): String? { parent + separator + escape(descriptor.name.asString()) + "|" + encodeSignature(descriptor) } is PackageFragmentDescriptor -> { - if (descriptor.fqName.isRoot) "" else escape(descriptor.fqName.pathSegments().map { escape(it.identifier) }.joinToString(".")) + val module = descriptor.module.name.asString() + val parts = sequenceOf(module) + descriptor.fqName.pathSegments().map { it.identifier } + parts.joinToString(".") { escape(it) } } is ClassDescriptor -> { val parent = generateSignature(descriptor.containingDeclaration) ?: return null diff --git a/js/js.translator/testData/box/multiModule/samePackageNames.kt b/js/js.translator/testData/box/multiModule/samePackageNames.kt new file mode 100644 index 00000000000..6ea7e962ad9 --- /dev/null +++ b/js/js.translator/testData/box/multiModule/samePackageNames.kt @@ -0,0 +1,54 @@ +// EXPECTED_REACHABLE_NODES: 511 +// MODULE: lib1 +// FILE: lib1.kt +package pkg + +object O { + fun f() = "O.f" +} + +fun foo() = "foo" + +class A { + fun f() = "A.f" +} + +// MODULE: lib2 +// FILE: lib2.kt +package pkg + +object P { + fun f() = "P.f" +} + +fun bar() = "bar" + +class B { + fun f() = "B.f" +} + +// MODULE: main(lib1, lib2) +// FILE: main.kt +import pkg.* + +fun box(): String { + var r = O.f() + if (r != "O.f") return "fail1: $r" + + r = foo() + if (r != "foo") return "fail2: $r" + + r = A().f() + if (r != "A.f") return "fail3: $r" + + r = P.f() + if (r != "P.f") return "fail4: $r" + + r = bar() + if (r != "bar") return "fail5: $r" + + r = B().f() + if (r != "B.f") return "fail6: $r" + + return "OK" +} \ No newline at end of file