[JS IR] Fix name clash between class members defined on prototype
- Fixes [KT-33327]
This commit is contained in:
+16
-4
@@ -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 ||
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|
||||||
|
|||||||
+5
@@ -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");
|
||||||
|
|||||||
+5
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user