From 7949ac10807194f040b520044e10c9d55caa636f Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 25 Sep 2018 15:23:55 +0300 Subject: [PATCH] Use common instance receiver generation logic for 'this' expression Otherwise it would skip private companion object accessor generation. --- .../kotlin/codegen/ExpressionCodegen.java | 56 +++++++++++-------- .../objects/companionObjectAccess/kt27117.kt | 17 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++ .../IrJsCodegenBoxTestGenerated.java | 5 ++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++ 7 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index c0ea35b177d..7a619714998 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2673,28 +2673,8 @@ public class ExpressionCodegen extends KtVisitor impleme public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) { if (receiverValue instanceof ImplicitClassReceiver) { ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor(); - if (DescriptorUtils.isCompanionObject(receiverDescriptor)) { - CallableMemberDescriptor contextDescriptor = context.getContextDescriptor(); - if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) { - return StackValue.LOCAL_0; - } - else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) { - return generateThisOrOuterFromContext(receiverDescriptor, false, false); - } - else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) { - return StackValue.singleton(receiverDescriptor, typeMapper); - } - else { - return generateAccessorCallForCompanionObject(receiverDescriptor); - } - } - else if (receiverDescriptor instanceof ScriptDescriptor) { - return generateScriptReceiver((ScriptDescriptor) receiverDescriptor); - } - else { - return StackValue.thisOrOuter(this, receiverDescriptor, isSuper, - receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor)); - } + return generateInstanceReceiver(receiverDescriptor, isSuper, + receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor)); } else if (receiverValue instanceof ExtensionReceiver) { return generateExtensionReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor()); @@ -2714,6 +2694,35 @@ public class ExpressionCodegen extends KtVisitor impleme } } + private StackValue generateInstanceReceiver( + @NotNull ClassDescriptor receiverDescriptor, + boolean isSuper, + boolean castReceiver + + ) { + if (DescriptorUtils.isCompanionObject(receiverDescriptor)) { + CallableMemberDescriptor contextDescriptor = context.getContextDescriptor(); + if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) { + return StackValue.LOCAL_0; + } + else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) { + return generateThisOrOuterFromContext(receiverDescriptor, false, false); + } + else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) { + return StackValue.singleton(receiverDescriptor, typeMapper); + } + else { + return generateAccessorCallForCompanionObject(receiverDescriptor); + } + } + else if (receiverDescriptor instanceof ScriptDescriptor) { + return generateScriptReceiver((ScriptDescriptor) receiverDescriptor); + } + else { + return StackValue.thisOrOuter(this, receiverDescriptor, isSuper, castReceiver); + } + } + @NotNull private StackValue generateAccessorCallForCompanionObject(@NotNull ClassDescriptor companionObjectDescriptor) { DeclarationDescriptor hostClassDescriptor = companionObjectDescriptor.getContainingDeclaration(); @@ -4408,8 +4417,9 @@ public class ExpressionCodegen extends KtVisitor impleme public StackValue visitThisExpression(@NotNull KtThisExpression expression, StackValue receiver) { DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference()); if (descriptor instanceof ClassDescriptor) { + return generateInstanceReceiver((ClassDescriptor) descriptor, false, true); //TODO rewrite with context.lookupInContext() - return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true); + //return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true); } if (descriptor instanceof CallableDescriptor) { return generateExtensionReceiver((CallableDescriptor) descriptor); diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt new file mode 100644 index 00000000000..9e91d0ae2af --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField +// IGNORE_BACKEND: JS, JS_IR, JVM_IR + +inline fun on(body: () -> Any) = body().toString() + +class A { + fun test() = foo() + + private companion object { + private fun foo() = on { this } + + override fun toString() = "OK" + } +} + + +fun box() = A().test() \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 600afc5433f..1dab25ad1d0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -15118,6 +15118,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("kt27117.kt") + public void testKt27117() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); + } + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 00a260ba5ce..12a26348210 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -15118,6 +15118,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("kt27117.kt") + public void testKt27117() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); + } + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7e58f69a42d..5a4785ef02a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -15123,6 +15123,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("kt27117.kt") + public void testKt27117() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); + } + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index 2fd87df463a..fb982cbc167 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -13303,6 +13303,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); } + @TestMetadata("kt27117.kt") + public void testKt27117() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); + } + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.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 c87f3a0a221..057bb6c5c09 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 @@ -14348,6 +14348,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("kt27117.kt") + public void testKt27117() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); + } + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");