Properly lower ImplicitClassReceiver
This commit is contained in:
committed by
Dmitry Petrov
parent
a93f929615
commit
20c4f47253
+12
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
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.callResolverUtil.getSuperCallExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
@@ -42,8 +43,17 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R
|
|||||||
}
|
}
|
||||||
|
|
||||||
val receiverExpression = when (receiver) {
|
val receiverExpression = when (receiver) {
|
||||||
is ImplicitClassReceiver ->
|
is ImplicitClassReceiver -> {
|
||||||
IrGetValueImpl(ktDefaultElement.startOffset, ktDefaultElement.startOffset, receiver.classDescriptor.thisAsReceiverParameter)
|
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 ->
|
is ThisClassReceiver ->
|
||||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||||
is SuperCallReceiverValue ->
|
is SuperCallReceiverValue ->
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class Z {
|
||||||
|
|
||||||
|
fun test2() {
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun test() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
enum class Z {
|
||||||
|
ENTRY {
|
||||||
|
fun test() {}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun test2() {
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<Z>
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUES
|
||||||
|
FUN ENUM_CLASS_SPECIAL_MEMBER public final fun valueOf(value: kotlin.String): Z
|
||||||
|
SYNTHETIC_BODY kind=ENUM_VALUEOF
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
object Z {
|
||||||
|
|
||||||
|
fun test() {}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun test2() {
|
||||||
|
test()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -766,4 +766,31 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user