diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 11193c5aaf4..de1ee92fcbb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -529,8 +529,15 @@ public abstract class StackValue { } ReceiverValue callExtensionReceiver = resolvedCall.getExtensionReceiver(); + + boolean isImportedObjectMember = false; + if (descriptor instanceof ImportedFromObjectCallableDescriptor) { + isImportedObjectMember = true; + descriptor = ((ImportedFromObjectCallableDescriptor) descriptor).getCallableFromObject(); + } + if (callDispatchReceiver != null || callExtensionReceiver != null - || isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) { + || isLocalFunCall(callableMethod) || isImportedObjectMember) { ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter(); ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter(); @@ -540,10 +547,10 @@ public abstract class StackValue { boolean hasExtensionReceiver = callExtensionReceiver != null; StackValue dispatchReceiver = platformStaticCallIfPresent( - genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false), + genReceiver(hasExtensionReceiver ? none() : receiver, codegen, descriptor, callableMethod, callDispatchReceiver, false), descriptor ); - StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, callExtensionReceiver, true); + StackValue extensionReceiver = genReceiver(receiver, codegen, descriptor, callableMethod, callExtensionReceiver, true); return CallReceiver.generateCallReceiver( resolvedCall, codegen, callableMethod, dispatchReceiverParameter, dispatchReceiver, @@ -556,22 +563,24 @@ public abstract class StackValue { private static StackValue genReceiver( @NotNull StackValue receiver, @NotNull ExpressionCodegen codegen, - @NotNull ResolvedCall resolvedCall, + @NotNull CallableDescriptor descriptor, @Nullable Callable callableMethod, @Nullable ReceiverValue receiverValue, boolean isExtension ) { + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (receiver == none()) { if (receiverValue != null) { return codegen.generateReceiverValue(receiverValue, false); } else if (isLocalFunCall(callableMethod) && !isExtension) { - StackValue value = codegen.findLocalOrCapturedValue(resolvedCall.getResultingDescriptor().getOriginal()); - assert value != null : "Local fun should be found in locals or in captured params: " + resolvedCall; + StackValue value = codegen.findLocalOrCapturedValue(descriptor.getOriginal()); + assert value != null : "Local fun should be found in locals or in captured params: " + descriptor; return value; } - else if (isCallToMemberObjectImportedByName(resolvedCall)) { - return singleton(((ImportedFromObjectCallableDescriptor) resolvedCall.getResultingDescriptor()).getContainingObject(), codegen.typeMapper); + else if (!isExtension && DescriptorUtils.isObject(containingDeclaration)) { + // Object member could be imported by name, in which case it has no explicit dispatch receiver + return singleton((ClassDescriptor) containingDeclaration, codegen.typeMapper); } } else if (receiverValue != null) { @@ -580,10 +589,6 @@ public abstract class StackValue { return none(); } - private static boolean isCallToMemberObjectImportedByName(@NotNull ResolvedCall resolvedCall) { - return resolvedCall.getResultingDescriptor() instanceof ImportedFromObjectCallableDescriptor; - } - private static StackValue platformStaticCallIfPresent(@NotNull StackValue resultReceiver, @NotNull CallableDescriptor descriptor) { if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) { if (resultReceiver.canHaveSideEffects()) { diff --git a/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt b/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt new file mode 100644 index 00000000000..358a1b9ddfd --- /dev/null +++ b/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +import Host.x + +object A { + var xx = intArrayOf(0) +} + +object Host { + val A.x get() = A.xx +} + +fun box(): String { + A.x[0] += 1 + if (A.x[0] != 1) return "Fail 1: ${A.x[0]}" + + A.x[0]++ + if (A.x[0] != 2) return "Fail 2: ${A.x[0]}" + + ++A.x[0] + if (A.x[0] != 3) return "Fail 3: ${A.x[0]}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt b/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt new file mode 100644 index 00000000000..bfe33afdeaa --- /dev/null +++ b/compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +import Host.x + +object Host { + val x = intArrayOf(0) +} + +fun box(): String { + x[0] += 1 + if (x[0] != 1) return "Fail 1: ${x[0]}" + + x[0]++ + if (x[0] != 2) return "Fail 2: ${x[0]}" + + ++x[0] + if (x[0] != 3) return "Fail 3: ${x[0]}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt b/compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt new file mode 100644 index 00000000000..593c7d6242f --- /dev/null +++ b/compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt @@ -0,0 +1,24 @@ +import Host.x + +object A { + var xx = 0 +} + +object Host { + var A.x + get() = A.xx + set(v) { A.xx = v } +} + +fun box(): String { + A.x += 1 + if (A.x != 1) return "Fail 1: ${A.x}" + + A.x++ + if (A.x != 2) return "Fail 2: ${A.x}" + + ++A.x + if (A.x != 3) return "Fail 3: ${A.x}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt b/compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt new file mode 100644 index 00000000000..db7d276732c --- /dev/null +++ b/compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt @@ -0,0 +1,18 @@ +import Host.x + +object Host { + var x = 0 +} + +fun box(): String { + x += 1 + if (x != 1) return "Fail 1: $x" + + x++ + if (x != 2) return "Fail 2: $x" + + ++x + if (x != 3) return "Fail 3: $x" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 17e7815e58d..b12933c8744 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12452,6 +12452,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt"); + doTest(fileName); + } + @TestMetadata("flist.kt") public void testFlist() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/flist.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 1db20d31e53..6a46a529d30 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12452,6 +12452,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt"); + doTest(fileName); + } + @TestMetadata("flist.kt") public void testFlist() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/flist.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index a7d1e64913a..a2902489207 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12452,6 +12452,30 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt"); + doTest(fileName); + } + @TestMetadata("flist.kt") public void testFlist() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/flist.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 5958ea4e180..6b2b64f0890 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -13514,6 +13514,30 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToArrayAccessToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToArrayAccessToPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToExtensionPropertyImportedFromObject.kt") + public void testCompoundAssignmentToExtensionPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToExtensionPropertyImportedFromObject.kt"); + doTest(fileName); + } + + @TestMetadata("compoundAssignmentToPropertyImportedFromObject.kt") + public void testCompoundAssignmentToPropertyImportedFromObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/compoundAssignmentToPropertyImportedFromObject.kt"); + doTest(fileName); + } + @TestMetadata("flist.kt") public void testFlist() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/objects/flist.kt");