Fix delegate property name clash in JS BE
See KT-19542
This commit is contained in:
@@ -1106,6 +1106,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("clashingNameInSubclass.kt")
|
||||
public void testClashingNameInSubclass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/delegateProperty/clashingNameInSubclass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegateByExtensionProperty.kt")
|
||||
public void testDelegateByExtensionProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/delegateProperty/delegateByExtensionProperty.kt");
|
||||
|
||||
@@ -159,16 +159,6 @@ public final class Namer {
|
||||
return DELEGATE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getDelegateName(@NotNull String propertyName) {
|
||||
return propertyName + DELEGATE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsNameRef getDelegateNameRef(String propertyName) {
|
||||
return new JsNameRef(getDelegateName(propertyName), new JsThisRef());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
|
||||
return pureFqn(CALL_FUNCTION, functionExpression);
|
||||
|
||||
@@ -116,7 +116,7 @@ public final class StaticContext {
|
||||
private final Map<DeclarationDescriptor, JsName> nameCache = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
private final Map<PropertyDescriptor, JsName> backingFieldNameCache = new HashMap<>();
|
||||
private final Map<VariableDescriptorWithAccessors, JsName> backingFieldNameCache = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
private final Map<DeclarationDescriptor, JsExpression> fqnCache = new HashMap<>();
|
||||
@@ -353,7 +353,7 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsName getNameForBackingField(@NotNull PropertyDescriptor property) {
|
||||
public JsName getNameForBackingField(@NotNull VariableDescriptorWithAccessors property) {
|
||||
JsName name = backingFieldNameCache.get(property);
|
||||
|
||||
if (name == null) {
|
||||
|
||||
+1
-1
@@ -407,7 +407,7 @@ public class TranslationContext {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsName getNameForBackingField(@NotNull PropertyDescriptor property) {
|
||||
public JsName getNameForBackingField(@NotNull VariableDescriptorWithAccessors property) {
|
||||
return staticContext.getNameForBackingField(property);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -412,7 +412,7 @@ class ClassTranslator private constructor(
|
||||
function.parameters.add(i, JsParameter(name))
|
||||
if (fieldName != null && constructor == primaryConstructor) {
|
||||
val source = (constructor.descriptor as? DeclarationDescriptorWithSource)?.source
|
||||
additionalStatements += JsAstUtils.defineSimpleProperty(fieldName.ident, name.makeRef(), source)
|
||||
additionalStatements += JsAstUtils.defineSimpleProperty(fieldName, name.makeRef(), source)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -170,7 +170,6 @@ class DeclarationBodyVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getBackingFieldReference(descriptor: PropertyDescriptor): JsExpression {
|
||||
return Namer.getDelegateNameRef(descriptor.name.asString())
|
||||
}
|
||||
override fun getBackingFieldReference(descriptor: PropertyDescriptor): JsExpression =
|
||||
JsNameRef(context.getNameForBackingField(descriptor), JsThisRef())
|
||||
}
|
||||
|
||||
+2
-3
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer.getDelegateNameRef
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer.getReceiverParameterName
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.expression.translateAndAliasParameters
|
||||
@@ -225,7 +224,7 @@ private class PropertyTranslator(
|
||||
private fun generateDefaultGetter(): JsPropertyInitializer {
|
||||
val getterDescriptor = descriptor.getter ?: throw IllegalStateException("Getter descriptor should not be null")
|
||||
val defaultFunction = createFunction(getterDescriptor).apply {
|
||||
val delegateRef = getDelegateNameRef(descriptor.name.asString())
|
||||
val delegateRef = JsNameRef(context().getNameForBackingField(descriptor), JsThisRef())
|
||||
DefaultPropertyTranslator(descriptor, context(), delegateRef).generateDefaultGetterFunction(getterDescriptor, this)
|
||||
}
|
||||
return generateDefaultAccessor(getterDescriptor, defaultFunction)
|
||||
@@ -234,7 +233,7 @@ private class PropertyTranslator(
|
||||
private fun generateDefaultSetter(): JsPropertyInitializer {
|
||||
val setterDescriptor = descriptor.setter ?: throw IllegalStateException("Setter descriptor should not be null")
|
||||
val defaultFunction = createFunction(setterDescriptor).apply {
|
||||
val delegateRef = getDelegateNameRef(descriptor.name.asString())
|
||||
val delegateRef = JsNameRef(context().getNameForBackingField(descriptor), JsThisRef())
|
||||
DefaultPropertyTranslator(descriptor, context(), delegateRef).generateDefaultSetterFunction(setterDescriptor, this)
|
||||
}
|
||||
return generateDefaultAccessor(setterDescriptor, defaultFunction)
|
||||
|
||||
+3
-3
@@ -43,12 +43,12 @@ public final class InitializerUtils {
|
||||
return assignment.makeStmt();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public static JsStatement generateInitializerForDelegate(
|
||||
@NotNull TranslationContext context,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull JsExpression value
|
||||
) {
|
||||
String name = descriptor.getName().asString();
|
||||
return JsAstUtils.defineSimpleProperty(Namer.getDelegateName(name), value, descriptor.getSource());
|
||||
return JsAstUtils.defineSimpleProperty(context.getNameForBackingField(descriptor), value, descriptor.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ public final class InitializerVisitor extends TranslatorVisitor<Void> {
|
||||
}
|
||||
else if (delegate != null) {
|
||||
assert value != null;
|
||||
statement = generateInitializerForDelegate(descriptor, value);
|
||||
statement = generateInitializerForDelegate(context, descriptor, value);
|
||||
}
|
||||
else if (Boolean.TRUE.equals(context.bindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||
JsNameRef backingFieldReference = TranslationUtils.backingFieldReference(context, descriptor);
|
||||
|
||||
@@ -444,7 +444,7 @@ public final class JsAstUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsStatement defineSimpleProperty(@NotNull String name, @NotNull JsExpression value, @Nullable SourceElement source) {
|
||||
public static JsStatement defineSimpleProperty(@NotNull JsName name, @NotNull JsExpression value, @Nullable SourceElement source) {
|
||||
JsExpression assignment = assignment(new JsNameRef(name, new JsThisRef()), value);
|
||||
if (source != null) {
|
||||
assignment.setSource(KotlinSourceElementKt.getPsi(source));
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1043
|
||||
fun box(): String {
|
||||
val b = B()
|
||||
|
||||
var r = b.getFooA()
|
||||
if (r != "A.foo") return "fail1: $r"
|
||||
|
||||
r = b.getFooB()
|
||||
if (r != "B.foo") return "fail2: $r"
|
||||
|
||||
r = b.getBarA()
|
||||
if (r != "A.bar") return "fail3: $r"
|
||||
|
||||
r = b.getBarB()
|
||||
if (r != "B.bar") return "fail4: $r"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
open class A {
|
||||
open val foo by lazy {
|
||||
"A.foo"
|
||||
}
|
||||
|
||||
private val bar by lazy {
|
||||
"A.bar"
|
||||
}
|
||||
|
||||
fun getBarA() = bar
|
||||
}
|
||||
|
||||
class B : A() {
|
||||
override val foo by lazy {
|
||||
"B.foo"
|
||||
}
|
||||
|
||||
private val bar by lazy {
|
||||
"B.bar"
|
||||
}
|
||||
|
||||
fun getFooB() = foo
|
||||
fun getFooA() = super.foo
|
||||
fun getBarB() = bar
|
||||
}
|
||||
Reference in New Issue
Block a user