[JS IR] Fix name clash between class members defined on prototype

- Fixes [KT-33327]
This commit is contained in:
Roman Artemev
2019-11-21 11:20:50 +03:00
committed by romanart
parent 987c6ab3ee
commit 9946feb66c
7 changed files with 53 additions and 11 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.ir.util.isPropertyAccessor import org.jetbrains.kotlin.ir.util.isPropertyAccessor
import org.jetbrains.kotlin.ir.util.isPropertyField import org.jetbrains.kotlin.ir.util.isPropertyField
@@ -35,8 +36,10 @@ class StableNamesCollector : IrElementVisitorVoid {
if (declaration !is IrDeclarationWithName) if (declaration !is IrDeclarationWithName)
return return
val isStatic = declaration.hasStaticDispatch()
val scope = val scope =
if (declaration.hasStaticDispatch()) if (isStatic)
staticNames staticNames
else else
memberNames memberNames
@@ -45,13 +48,22 @@ class StableNamesCollector : IrElementVisitorVoid {
if (declaration.isEffectivelyExternal()) if (declaration.isEffectivelyExternal())
stableNameForExternalDeclaration(declaration) stableNameForExternalDeclaration(declaration)
else else
stableNameForNonExternalDeclaration(declaration) stableNameForNonExternalDeclaration(declaration, isStatic)
scope.addIfNotNull(stableName) scope.addIfNotNull(stableName)
} }
private fun stableNameForNonExternalDeclaration(declaration: IrDeclarationWithName): String? = private fun stableNameForNonExternalDeclaration(declaration: IrDeclarationWithName, isStatic: Boolean): String? =
declaration.getJsName() declaration.getJsName() ?: run {
// TODO: since following code affects local variable naming some weird behaviour of js("..") is possible
// Remove check once 1. `js` function is re-designed and re-implemented, 2. JsExport is properly implemented
if (!isStatic) {
// Make sure property defined on prototype has stable name
val simpleFunction = declaration as? IrSimpleFunction
val property = simpleFunction?.correspondingPropertySymbol?.owner
property?.getJsNameOrKotlinName()?.identifier
} else null
}
private fun stableNameForExternalDeclaration(declaration: IrDeclarationWithName): String? { private fun stableNameForExternalDeclaration(declaration: IrDeclarationWithName): String? {
if (declaration.isPropertyAccessor || if (declaration.isPropertyAccessor ||
-2
View File
@@ -1,6 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// Name clashes
// IGNORE_BACKEND: JS_IR
class A (val p: String, p1: String, p2: String) { class A (val p: String, p1: String, p2: String) {
-2
View File
@@ -1,6 +1,4 @@
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// Name clashes
// IGNORE_BACKEND: JS_IR
class A (val p: String, p1: String, p2: String) { class A (val p: String, p1: String, p2: String) {
@@ -6514,6 +6514,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/propertyAccess/propertyAssignment.kt"); runTest("js/js.translator/testData/box/propertyAccess/propertyAssignment.kt");
} }
@TestMetadata("publicNameClash.kt")
public void testPublicNameClash() throws Exception {
runTest("js/js.translator/testData/box/propertyAccess/publicNameClash.kt");
}
@TestMetadata("setter.kt") @TestMetadata("setter.kt")
public void testSetter() throws Exception { public void testSetter() throws Exception {
runTest("js/js.translator/testData/box/propertyAccess/setter.kt"); runTest("js/js.translator/testData/box/propertyAccess/setter.kt");
@@ -6544,6 +6544,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/propertyAccess/propertyAssignment.kt"); runTest("js/js.translator/testData/box/propertyAccess/propertyAssignment.kt");
} }
@TestMetadata("publicNameClash.kt")
public void testPublicNameClash() throws Exception {
runTest("js/js.translator/testData/box/propertyAccess/publicNameClash.kt");
}
@TestMetadata("setter.kt") @TestMetadata("setter.kt")
public void testSetter() throws Exception { public void testSetter() throws Exception {
runTest("js/js.translator/testData/box/propertyAccess/setter.kt"); runTest("js/js.translator/testData/box/propertyAccess/setter.kt");
@@ -1,6 +1,3 @@
// Name clashes
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1295 // EXPECTED_REACHABLE_NODES: 1295
package foo package foo
@@ -0,0 +1,27 @@
// EXPECTED_REACHABLE_NODES: 1284
// KT-33327
class C {
var foo: String = "FAIL1"
fun foo(foo: String): C {
this.foo = foo
return this
}
@JsName("_bar")
var bar: String = "FAIL2"
fun bar(bar: String): C {
this.bar = bar
return this
}
}
fun box(): String {
val c = C()
c.foo("O").bar("K")
return c.foo + c.bar
}