From 502c51ccff4265d503a31b718f0bb70894fda8b0 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 7 Sep 2017 11:52:08 +0300 Subject: [PATCH] Sanitize names for backing fields and private declarations in JS BE See KT-1816 --- .../kotlin/js/naming/NameSuggestion.kt | 5 +++- .../js/test/semantics/BoxJsTestGenerated.java | 12 +++++++++ .../box/delegateProperty/peculiarName.kt | 25 +++++++++++++++++++ .../identifierClash/privateDeclarations.kt | 17 +++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/box/delegateProperty/peculiarName.kt create mode 100644 js/js.translator/testData/box/expression/identifierClash/privateDeclarations.kt diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt index 870fa579f81..bc75baada29 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt @@ -322,7 +322,10 @@ class NameSuggestion { @JvmStatic fun getPrivateMangledName(baseName: String, descriptor: CallableDescriptor): String { val ownerName = descriptor.containingDeclaration.fqNameUnsafe.asString() - return getStableMangledName(baseName, ownerName + ":" + encodeSignature(descriptor)) + + // Base name presents here since name part gets sanitized, so we have to produce different suffixes to distinguish + // between, say `.` and `;`. + return getStableMangledName(sanitizeName(baseName), ownerName + "." + baseName + ":" + encodeSignature(descriptor)) } fun getInternalMangledName(suggestedName: String, forCalculateId: String): String { 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 918842c90f4..9adecf0ce3f 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 @@ -1166,6 +1166,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("peculiarName.kt") + public void testPeculiarName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/delegateProperty/peculiarName.kt"); + doTest(fileName); + } + @TestMetadata("propertyMetadata.kt") public void testPropertyMetadata() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/delegateProperty/propertyMetadata.kt"); @@ -2536,6 +2542,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("privateDeclarations.kt") + public void testPrivateDeclarations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/identifierClash/privateDeclarations.kt"); + doTest(fileName); + } + @TestMetadata("useVariableOfNameOfFunction.kt") public void testUseVariableOfNameOfFunction() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/identifierClash/useVariableOfNameOfFunction.kt"); diff --git a/js/js.translator/testData/box/delegateProperty/peculiarName.kt b/js/js.translator/testData/box/delegateProperty/peculiarName.kt new file mode 100644 index 00000000000..5d7f076efe7 --- /dev/null +++ b/js/js.translator/testData/box/delegateProperty/peculiarName.kt @@ -0,0 +1,25 @@ +// EXPECTED_REACHABLE_NODES: 1006 +class X(private val x: String) { + operator fun getValue(thisRef: Any?, property: Any): String = x +} + +class C { + @JsName("a") val `;`: String by X("foo") + + private val `.`: String by X("bar") + + private val `@`: String by X("baz") + + fun bar(): String = `.` + + fun baz(): String = `@` +} + +fun box(): String { + val c = C() + if (c.`;` != "foo") return "fail1: ${c.`;`}" + if (c.bar() != "bar") return "fail2: ${c.bar()}" + if (c.baz() != "baz") return "fail3: ${c.baz()}" + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/expression/identifierClash/privateDeclarations.kt b/js/js.translator/testData/box/expression/identifierClash/privateDeclarations.kt new file mode 100644 index 00000000000..95d2c1041e3 --- /dev/null +++ b/js/js.translator/testData/box/expression/identifierClash/privateDeclarations.kt @@ -0,0 +1,17 @@ +// EXPECTED_REACHABLE_NODES: 1000 +open class A { + private val `.` = "A" + private val `;` = "B" + + private fun `@`() = "C" + private fun `#`() = "D" + + fun foo() = `.` + `;` + `@`() + `#`() +} + +fun box(): String { + val x = A().foo() + if (x != "ABCD") return "fail: $x" + + return "OK" +} \ No newline at end of file