JS: fix translation of augmented assignment in class initializer. See KT-15569
This commit is contained in:
+45
@@ -0,0 +1,45 @@
|
||||
abstract class A {
|
||||
val b = B("O")
|
||||
|
||||
open val c: B
|
||||
|
||||
val d: B
|
||||
get() = field
|
||||
|
||||
var e: String
|
||||
get() = field
|
||||
|
||||
init {
|
||||
c = B("O")
|
||||
d = B("O")
|
||||
e = "O"
|
||||
|
||||
b += ","
|
||||
c += "."
|
||||
d += ";"
|
||||
e += "|"
|
||||
}
|
||||
}
|
||||
|
||||
class B(var value: String) {
|
||||
operator fun plusAssign(o: String) {
|
||||
value += o
|
||||
}
|
||||
}
|
||||
|
||||
class C : A() {
|
||||
init {
|
||||
b += "K"
|
||||
c += "K"
|
||||
d += "K"
|
||||
e += "K"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = C()
|
||||
val result = "${c.b.value} ${c.c.value} ${c.d.value} ${c.e}"
|
||||
if (result != "O,K O.K O;K O|K") return "fail: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class A {
|
||||
private final @org.jetbrains.annotations.NotNull field b: B
|
||||
private final @org.jetbrains.annotations.NotNull field c: B
|
||||
private final @org.jetbrains.annotations.NotNull field d: B
|
||||
private @org.jetbrains.annotations.NotNull field e: java.lang.String
|
||||
public method <init>(): void
|
||||
public final @org.jetbrains.annotations.NotNull method getB(): B
|
||||
public @org.jetbrains.annotations.NotNull method getC(): B
|
||||
public final @org.jetbrains.annotations.NotNull method getD(): B
|
||||
public final @org.jetbrains.annotations.NotNull method getE(): java.lang.String
|
||||
public final method setE(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class AugmentedAssignmentInInitializerKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class B {
|
||||
private @org.jetbrains.annotations.NotNull field value: java.lang.String
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final @org.jetbrains.annotations.NotNull method getValue(): java.lang.String
|
||||
public final method plusAssign(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final method setValue(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class C {
|
||||
public method <init>(): void
|
||||
}
|
||||
+6
@@ -10655,6 +10655,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentInInitializer.kt")
|
||||
public void testAugmentedAssignmentInInitializer() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentInInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentWithArrayLHS.kt")
|
||||
public void testAugmentedAssignmentWithArrayLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||
|
||||
@@ -10655,6 +10655,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentInInitializer.kt")
|
||||
public void testAugmentedAssignmentInInitializer() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentInInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentWithArrayLHS.kt")
|
||||
public void testAugmentedAssignmentWithArrayLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||
|
||||
@@ -10655,6 +10655,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentInInitializer.kt")
|
||||
public void testAugmentedAssignmentInInitializer() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentInInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentWithArrayLHS.kt")
|
||||
public void testAugmentedAssignmentWithArrayLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||
|
||||
@@ -12450,6 +12450,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentInInitializer.kt")
|
||||
public void testAugmentedAssignmentInInitializer() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentInInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("augmentedAssignmentWithArrayLHS.kt")
|
||||
public void testAugmentedAssignmentWithArrayLHS() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/augmentedAssignmentWithArrayLHS.kt");
|
||||
|
||||
+12
-18
@@ -16,12 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.operation;
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.reference.AccessTranslationUtils;
|
||||
@@ -44,8 +44,7 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public static JsExpression translate(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
if (hasCorrespondingFunctionIntrinsic(context, expression)) {
|
||||
return IntrinsicAssignmentTranslator.doTranslate(expression, context);
|
||||
}
|
||||
@@ -56,8 +55,7 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
protected final KtBinaryExpression expression;
|
||||
protected final boolean isVariableReassignment;
|
||||
|
||||
protected AssignmentTranslator(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
protected AssignmentTranslator(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
|
||||
@@ -65,12 +63,13 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
assert left != null : "No left-hand side: " + expression.getText();
|
||||
}
|
||||
|
||||
protected final AccessTranslator createAccessTranslator(KtExpression left, boolean forceOrderOfEvaluation) {
|
||||
protected final AccessTranslator createAccessTranslator(@NotNull KtExpression left, boolean forceOrderOfEvaluation) {
|
||||
if (isReferenceToBackingFieldFromConstructor(left, context())) {
|
||||
KtSimpleNameExpression simpleName = getSimpleName(left);
|
||||
assert simpleName != null;
|
||||
return BackingFieldAccessTranslator.newInstance(simpleName, context());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return AccessTranslationUtils.getAccessTranslator(left, context(), forceOrderOfEvaluation);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +86,8 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
else if (expression instanceof KtDotQualifiedExpression) {
|
||||
KtDotQualifiedExpression qualifiedExpression = (KtDotQualifiedExpression) expression;
|
||||
if (qualifiedExpression.getReceiverExpression() instanceof KtThisExpression &&
|
||||
qualifiedExpression.getSelectorExpression() instanceof KtSimpleNameExpression) {
|
||||
qualifiedExpression.getSelectorExpression() instanceof KtSimpleNameExpression
|
||||
) {
|
||||
KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) qualifiedExpression.getSelectorExpression();
|
||||
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression(context.bindingContext(), nameExpression);
|
||||
return isReferenceToBackingFieldFromConstructor(descriptor, context);
|
||||
@@ -100,19 +100,13 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
@Nullable DeclarationDescriptor descriptor,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
if (!(descriptor instanceof PropertyDescriptor)) return false;
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
if (!(context.getDeclarationDescriptor() instanceof ClassDescriptor)) return false;
|
||||
|
||||
if (!(context.getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) context.getDeclarationDescriptor();
|
||||
|
||||
if (classDescriptor != propertyDescriptor.getContainingDeclaration()) {
|
||||
return false;
|
||||
}
|
||||
if (classDescriptor != propertyDescriptor.getContainingDeclaration()) return false;
|
||||
|
||||
return !propertyDescriptor.isVar();
|
||||
}
|
||||
|
||||
+6
-5
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.reference.AccessTranslator;
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken;
|
||||
import org.jetbrains.kotlin.lexer.KtToken;
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
|
||||
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken;
|
||||
@@ -40,18 +41,18 @@ public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
|
||||
private final JsBlock rightBlock = new JsBlock();
|
||||
|
||||
@NotNull
|
||||
public static JsExpression doTranslate(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public static JsExpression doTranslate(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
return (new IntrinsicAssignmentTranslator(expression, context)).translate();
|
||||
}
|
||||
|
||||
private IntrinsicAssignmentTranslator(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
private IntrinsicAssignmentTranslator(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
|
||||
right = translateRightExpression(context, expression, rightBlock);
|
||||
rightExpressionTrivial = rightBlock.isEmpty();
|
||||
accessTranslator = createAccessTranslator(expression.getLeft(), !rightExpressionTrivial);
|
||||
KtExpression left = expression.getLeft();
|
||||
assert left != null;
|
||||
accessTranslator = createAccessTranslator(left, !rightExpressionTrivial);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+11
-8
@@ -16,13 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.operation;
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock;
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||
import org.jetbrains.kotlin.js.translate.reference.AccessTranslationUtils;
|
||||
import org.jetbrains.kotlin.js.translate.reference.AccessTranslator;
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
@@ -34,16 +35,14 @@ import java.util.Map;
|
||||
|
||||
public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
@NotNull
|
||||
public static JsExpression doTranslate(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public static JsExpression doTranslate(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
return (new OverloadedAssignmentTranslator(expression, context)).translate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final ResolvedCall<? extends FunctionDescriptor> resolvedCall;
|
||||
|
||||
private OverloadedAssignmentTranslator(@NotNull KtBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
private OverloadedAssignmentTranslator(@NotNull KtBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
resolvedCall = CallUtilKt.getFunctionResolvedCallWithAssert(expression, context.bindingContext());
|
||||
}
|
||||
@@ -53,12 +52,16 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
if (isVariableReassignment) {
|
||||
return reassignment();
|
||||
}
|
||||
return overloadedMethodInvocation(createAccessTranslator(expression.getLeft(), false));
|
||||
KtExpression left = expression.getLeft();
|
||||
assert left != null;
|
||||
return overloadedMethodInvocation(AccessTranslationUtils.getAccessTranslator(left, context()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression reassignment() {
|
||||
AccessTranslator accessTranslator = createAccessTranslator(expression.getLeft(), false).getCached();
|
||||
KtExpression left = expression.getLeft();
|
||||
assert left != null;
|
||||
AccessTranslator accessTranslator = AccessTranslationUtils.getAccessTranslator(left, context()).getCached();
|
||||
JsExpression newValue = overloadedMethodInvocation(accessTranslator);
|
||||
return accessTranslator.translateAsSet(newValue);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user