From 20c4f472532ec8830fdb58c4a388697013d09e9a Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Thu, 13 Oct 2016 10:21:14 +0300 Subject: [PATCH] Properly lower ImplicitClassReceiver --- .../generators/ArgumentsGenerationUtils.kt | 14 ++++++++-- .../ir/irText/singletons/companion.kt | 11 ++++++++ .../ir/irText/singletons/companion.txt | 17 +++++++++++ .../ir/irText/singletons/enumEntry.kt | 11 ++++++++ .../ir/irText/singletons/enumEntry.txt | 28 +++++++++++++++++++ .../testData/ir/irText/singletons/object.kt | 10 +++++++ .../testData/ir/irText/singletons/object.txt | 17 +++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 27 ++++++++++++++++++ 8 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/ir/irText/singletons/companion.kt create mode 100644 compiler/testData/ir/irText/singletons/companion.txt create mode 100644 compiler/testData/ir/irText/singletons/enumEntry.kt create mode 100644 compiler/testData/ir/irText/singletons/enumEntry.txt create mode 100644 compiler/testData/ir/irText/singletons/object.kt create mode 100644 compiler/testData/ir/irText/singletons/object.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 9d72351a27e..323daa92585 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi2ir.intermediate.* import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall import org.jetbrains.kotlin.resolve.calls.model.* @@ -42,8 +43,17 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R } val receiverExpression = when (receiver) { - is ImplicitClassReceiver -> - IrGetValueImpl(ktDefaultElement.startOffset, ktDefaultElement.startOffset, receiver.classDescriptor.thisAsReceiverParameter) + is ImplicitClassReceiver -> { + if (receiver.classDescriptor.kind.isSingleton && + this.scopeOwner != receiver.classDescriptor && //For anonymous initializers + this.scopeOwner.containingDeclaration != receiver.classDescriptor) { + IrGetObjectValueImpl(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver.type, + receiver.classDescriptor) + } + else { + IrGetValueImpl(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver.classDescriptor.thisAsReceiverParameter) + } + } is ThisClassReceiver -> generateThisOrSuperReceiver(receiver, receiver.classDescriptor) is SuperCallReceiverValue -> diff --git a/compiler/testData/ir/irText/singletons/companion.kt b/compiler/testData/ir/irText/singletons/companion.kt new file mode 100644 index 00000000000..40ddd570948 --- /dev/null +++ b/compiler/testData/ir/irText/singletons/companion.kt @@ -0,0 +1,11 @@ +class Z { + + fun test2() { + test() + } + + + companion object { + fun test() {} + } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/singletons/companion.txt b/compiler/testData/ir/irText/singletons/companion.txt new file mode 100644 index 00000000000..312e8b4f635 --- /dev/null +++ b/compiler/testData/ir/irText/singletons/companion.txt @@ -0,0 +1,17 @@ +FILE /companion.kt + CLASS CLASS Z + CONSTRUCTOR public constructor Z() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='Z' + FUN public final fun test2(): kotlin.Unit + BLOCK_BODY + CALL 'test(): Unit' type=kotlin.Unit origin=null + $this: GET_OBJECT 'companion object of Z' type=Z.Companion + CLASS OBJECT companion object of Z + CONSTRUCTOR private constructor Companion() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='companion object of Z' + FUN public final fun test(): kotlin.Unit + BLOCK_BODY diff --git a/compiler/testData/ir/irText/singletons/enumEntry.kt b/compiler/testData/ir/irText/singletons/enumEntry.kt new file mode 100644 index 00000000000..d057809601c --- /dev/null +++ b/compiler/testData/ir/irText/singletons/enumEntry.kt @@ -0,0 +1,11 @@ +enum class Z { + ENTRY { + fun test() {} + + class A { + fun test2() { + test() + } + } + } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/singletons/enumEntry.txt b/compiler/testData/ir/irText/singletons/enumEntry.txt new file mode 100644 index 00000000000..47c4458069b --- /dev/null +++ b/compiler/testData/ir/irText/singletons/enumEntry.txt @@ -0,0 +1,28 @@ +FILE /enumEntry.kt + CLASS ENUM_CLASS Z + CONSTRUCTOR private constructor Z() + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)' + INSTANCE_INITIALIZER_CALL classDescriptor='Z' + ENUM_ENTRY enum entry ENTRY + init: ENUM_CONSTRUCTOR_CALL 'constructor ENTRY()' + class: CLASS ENUM_ENTRY ENTRY + CONSTRUCTOR private constructor ENTRY() + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'constructor Z()' + INSTANCE_INITIALIZER_CALL classDescriptor='ENTRY' + FUN public final fun test(): kotlin.Unit + BLOCK_BODY + CLASS CLASS A + CONSTRUCTOR public constructor A() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='A' + FUN public final fun test2(): kotlin.Unit + BLOCK_BODY + CALL 'test(): Unit' type=kotlin.Unit origin=null + $this: GET_OBJECT 'ENTRY' type=Z.ENTRY + FUN ENUM_CLASS_SPECIAL_MEMBER public final fun values(): kotlin.Array + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Z + SYNTHETIC_BODY kind=ENUM_VALUEOF diff --git a/compiler/testData/ir/irText/singletons/object.kt b/compiler/testData/ir/irText/singletons/object.kt new file mode 100644 index 00000000000..299cee993d2 --- /dev/null +++ b/compiler/testData/ir/irText/singletons/object.kt @@ -0,0 +1,10 @@ +object Z { + + fun test() {} + + class A { + fun test2() { + test() + } + } +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/singletons/object.txt b/compiler/testData/ir/irText/singletons/object.txt new file mode 100644 index 00000000000..1169c137545 --- /dev/null +++ b/compiler/testData/ir/irText/singletons/object.txt @@ -0,0 +1,17 @@ +FILE /object.kt + CLASS OBJECT Z + CONSTRUCTOR private constructor Z() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='Z' + FUN public final fun test(): kotlin.Unit + BLOCK_BODY + CLASS CLASS A + CONSTRUCTOR public constructor A() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='A' + FUN public final fun test2(): kotlin.Unit + BLOCK_BODY + CALL 'test(): Unit' type=kotlin.Unit origin=null + $this: GET_OBJECT 'Z' type=Z diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 33dd216478c..03b75523dcd 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -766,4 +766,31 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } } + + @TestMetadata("compiler/testData/ir/irText/singletons") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Singletons extends AbstractIrTextTestCase { + public void testAllFilesPresentInSingletons() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/singletons"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("companion.kt") + public void testCompanion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/singletons/companion.kt"); + doTest(fileName); + } + + @TestMetadata("enumEntry.kt") + public void testEnumEntry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/singletons/enumEntry.kt"); + doTest(fileName); + } + + @TestMetadata("object.kt") + public void testObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/singletons/object.kt"); + doTest(fileName); + } + } }