FIR2IR: Fix case of using context receivers in property initializers

This commit is contained in:
Denis.Zharkov
2022-05-05 11:24:50 +03:00
committed by teamcity
parent b87412c5af
commit e632689d90
17 changed files with 52 additions and 23 deletions
@@ -123,12 +123,6 @@ internal class ClassMemberGenerator(
}
body.statements += irDelegatingConstructorCall
}
if (delegatedConstructor?.isThis == false) {
val instanceInitializerCall = IrInstanceInitializerCallImpl(
startOffset, endOffset, irClass.symbol, irFunction.constructedClassType
)
body.statements += instanceInitializerCall
}
if (containingClass is FirRegularClass && containingClass.contextReceivers.isNotEmpty()) {
val contextReceiverFields =
@@ -158,6 +152,13 @@ internal class ClassMemberGenerator(
}
}
if (delegatedConstructor?.isThis == false) {
val instanceInitializerCall = IrInstanceInitializerCallImpl(
startOffset, endOffset, irClass.symbol, irFunction.constructedClassType
)
body.statements += instanceInitializerCall
}
val regularBody = firFunction.body?.let { visitor.convertToIrBlockBody(it) }
if (regularBody != null) {
body.statements += regularBody.statements
@@ -16788,6 +16788,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/unaryOperators.kt");
}
@Test
@TestMetadata("useContextReceiverInPropertyInitializer.kt")
public void testUseContextReceiverInPropertyInitializer() throws Exception {
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/useContextReceiverInPropertyInitializer.kt");
}
@Test
@TestMetadata("useFromAnotherModule.kt")
public void testUseFromAnotherModule() throws Exception {
@@ -1,6 +1,5 @@
// !LANGUAGE: +ContextReceivers
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// FIR status: context receivers aren't yet supported
class O(val o: String)
@@ -15,4 +14,4 @@ fun box(): String {
val ok = OK("K")
ok.result
}
}
}
@@ -1,6 +1,5 @@
// !LANGUAGE: +ContextReceivers
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// FIR status: context receivers aren't yet supported
class A {
@@ -15,4 +14,4 @@ class B {
typealias C = B
fun box(): String =
with(A()) { C().result }
with(A()) { C().result }
@@ -1,6 +1,5 @@
// !LANGUAGE: +ContextReceivers
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
// FIR status: context receivers aren't yet supported
// MODULE: lib
@@ -0,0 +1,19 @@
// !LANGUAGE: +ContextReceivers
// TARGET_BACKEND: JVM_IR
class Components(val x: String)
context(Components)
abstract class A(val y: String) {
val w: String = x
fun foo(): String = w + y
}
context(Components)
class B(y: String) : A(y)
fun box(): String {
return with(Components("O")) {
B("K").foo()
}
}
@@ -37,10 +37,10 @@ FILE fqName:<root> fileName:/class.kt
VALUE_PARAMETER name:arg index:1 type:kotlin.Any
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public superTypes:[kotlin.Any]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:<root>.Outer visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.Inner declared in <root>.Inner' type=<root>.Inner origin=null
value: GET_VAR '_context_receiver_0: <root>.Outer declared in <root>.Inner.<init>' type=<root>.Outer origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Inner modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN name:bar visibility:public modality:FINAL <> ($this:<root>.Inner) returnType:kotlin.Int
$this: VALUE_PARAMETER name:<this> type:<root>.Inner
BLOCK_BODY
@@ -15,9 +15,9 @@ class Inner {
private /* final field */ val contextReceiverField0: Outer
constructor(_context_receiver_0: Outer, arg: Any) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
fun bar(): Int {
@@ -38,10 +38,10 @@ FILE fqName:<root> fileName:/contextualPrimaryConstructorWithParams.kt
VALUE_PARAMETER name:k index:1 type:kotlin.String
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:OK modality:FINAL visibility:public superTypes:[kotlin.Any]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:<root>.O visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.OK declared in <root>.OK' type=<root>.OK origin=null
value: GET_VAR '_context_receiver_0: <root>.O declared in <root>.OK.<init>' type=<root>.O origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:OK modality:FINAL visibility:public superTypes:[kotlin.Any]'
PROPERTY name:k visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:k type:kotlin.String visibility:private [final]
EXPRESSION_BODY
@@ -15,9 +15,9 @@ class OK {
private /* final field */ val contextReceiverField0: O
constructor(_context_receiver_0: O, k: String) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
val k: String
@@ -88,10 +88,10 @@ FILE fqName:<root> fileName:/delegatedPropertiesOperators.kt
VALUE_PARAMETER name:_context_receiver_0 index:0 type:kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Result modality:FINAL visibility:public superTypes:[kotlin.Any]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:kotlin.Int visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.Result declared in <root>.Result' type=<root>.Result origin=null
value: GET_VAR '_context_receiver_0: kotlin.Int declared in <root>.Result.<init>' type=kotlin.Int origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Result modality:FINAL visibility:public superTypes:[kotlin.Any]'
PROPERTY name:s visibility:public modality:FINAL [delegated,var]
FIELD PROPERTY_DELEGATE name:s$delegate type:<root>.Delegate visibility:private [final]
EXPRESSION_BODY
@@ -31,9 +31,9 @@ class Result {
private /* final field */ val contextReceiverField0: Int
constructor(_context_receiver_0: Int) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
var s: String /* by */
@@ -7,10 +7,10 @@ FILE fqName:<root> fileName:/genericOuterClass.kt
VALUE_PARAMETER name:_context_receiver_0 index:0 type:T of <root>.A
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:T of <root>.A visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.A<T of <root>.A> declared in <root>.A' type=<root>.A<T of <root>.A> origin=null
value: GET_VAR '_context_receiver_0: T of <root>.A declared in <root>.A.<init>' type=T of <root>.A origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
@@ -32,10 +32,10 @@ FILE fqName:<root> fileName:/genericOuterClass.kt
VALUE_PARAMETER name:_context_receiver_0 index:0 type:kotlin.collections.Collection<P of <root>.B>
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:B modality:FINAL visibility:public superTypes:[kotlin.Any]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:kotlin.collections.Collection<P of <root>.B> visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.B<P of <root>.B> declared in <root>.B' type=<root>.B<P of <root>.B> origin=null
value: GET_VAR '_context_receiver_0: kotlin.collections.Collection<P of <root>.B> declared in <root>.B.<init>' type=kotlin.collections.Collection<P of <root>.B> origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:B modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
@@ -2,9 +2,9 @@ class A<T : Any?> {
private /* final field */ val contextReceiverField0: T
constructor(_context_receiver_0: T) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
}
@@ -13,9 +13,9 @@ class B<P : Any?> {
private /* final field */ val contextReceiverField0: Collection<P>
constructor(_context_receiver_0: Collection<P>) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
}
@@ -197,10 +197,10 @@ FILE fqName:<root> fileName:/iteratorOperator.kt
VALUE_PARAMETER name:counter index:1 type:<root>.Counter
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:CounterIterator modality:FINAL visibility:public superTypes:[kotlin.collections.Iterator<kotlin.Int>]'
SET_FIELD 'FIELD FIELD_FOR_CLASS_CONTEXT_RECEIVER name:contextReceiverField0 type:<root>.CounterConfig visibility:private [final]' type=kotlin.Unit origin=null
receiver: GET_VAR '<this>: <root>.CounterIterator declared in <root>.CounterIterator' type=<root>.CounterIterator origin=null
value: GET_VAR '_context_receiver_0: <root>.CounterConfig declared in <root>.CounterIterator.<init>' type=<root>.CounterConfig origin=null
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:CounterIterator modality:FINAL visibility:public superTypes:[kotlin.collections.Iterator<kotlin.Int>]'
PROPERTY name:counter visibility:private modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:counter type:<root>.Counter visibility:private [final]
EXPRESSION_BODY
@@ -89,9 +89,9 @@ class CounterIterator : Iterator<Int> {
private /* final field */ val contextReceiverField0: CounterConfig
constructor(_context_receiver_0: CounterConfig, counter: Counter) /* primary */ {
super/*Any*/()
<this>.#contextReceiverField0 = _context_receiver_0
/* <init>() */
<this>.#contextReceiverField0 = _context_receiver_0
}
private val counter: Counter
@@ -16788,6 +16788,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/unaryOperators.kt");
}
@Test
@TestMetadata("useContextReceiverInPropertyInitializer.kt")
public void testUseContextReceiverInPropertyInitializer() throws Exception {
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/useContextReceiverInPropertyInitializer.kt");
}
@Test
@TestMetadata("useFromAnotherModule.kt")
public void testUseFromAnotherModule() throws Exception {