diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt index d946f3ae211..08d09eb2d9e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ClassGenerator.kt @@ -23,10 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl +import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.mapValueParameters import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry @@ -40,6 +37,7 @@ import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import java.lang.AssertionError import java.util.* @@ -143,14 +141,17 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator private fun generateDelegatedProperty(irClass: IrClassImpl, irDelegate: IrFieldImpl, delegated: PropertyDescriptor, overridden: PropertyDescriptor) { - val irProperty = IrPropertyImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, false, delegated) + val startOffset = irDelegate.startOffset + val endOffset = irDelegate.endOffset - val irGetter = IrFunctionImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.getter!!) + val irProperty = IrPropertyImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, false, delegated) + + val irGetter = IrFunctionImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.getter!!) irGetter.body = generateDelegateFunctionBody(irDelegate, delegated.getter!!, overridden.getter!!) irProperty.getter = irGetter if (delegated.isVar) { - val irSetter = IrFunctionImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.setter!!) + val irSetter = IrFunctionImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.setter!!) irSetter.body = generateDelegateFunctionBody(irDelegate, delegated.setter!!, overridden.setter!!) irProperty.setter = irSetter } @@ -165,22 +166,28 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator } private fun generateDelegateFunctionBody(irDelegate: IrFieldImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl { - val irBlockBody = IrBlockBodyImpl(irDelegate.startOffset, irDelegate.endOffset) + val startOffset = irDelegate.startOffset + val endOffset = irDelegate.endOffset + val classOwner = delegated.containingDeclaration.assertedCast { "Class member expected: $delegated" } + + val irBlockBody = IrBlockBodyImpl(startOffset, endOffset) val returnType = overridden.returnType!! - val irCall = IrCallImpl(irDelegate.startOffset, irDelegate.endOffset, returnType, overridden, null) - irCall.dispatchReceiver = IrGetValueImpl(irDelegate.startOffset, irDelegate.endOffset, irDelegate.descriptor) + val irCall = IrCallImpl(startOffset, endOffset, returnType, overridden, null) + irCall.dispatchReceiver = IrGetFieldImpl(startOffset, endOffset, irDelegate.descriptor, + IrGetValueImpl(startOffset, endOffset, classOwner.thisAsReceiverParameter) + ) irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver -> - IrGetValueImpl(irDelegate.startOffset, irDelegate.endOffset, extensionReceiver) + IrGetValueImpl(startOffset, endOffset, extensionReceiver) } irCall.mapValueParameters { overriddenValueParameter -> val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index] - IrGetValueImpl(irDelegate.startOffset, irDelegate.endOffset, delegatedValueParameter) + IrGetValueImpl(startOffset, endOffset, delegatedValueParameter) } if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) { irBlockBody.statements.add(irCall) } else { - val irReturn = IrReturnImpl(irDelegate.startOffset, irDelegate.endOffset, context.builtIns.nothingType, delegated, irCall) + val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, delegated, irCall) irBlockBody.statements.add(irReturn) } return irBlockBody diff --git a/compiler/testData/ir/irText/classes/delegatedImplementation.txt b/compiler/testData/ir/irText/classes/delegatedImplementation.txt index 1d9b1f5814d..499c3471eca 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementation.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementation.txt @@ -108,17 +108,20 @@ FILE /delegatedImplementation.kt BLOCK_BODY RETURN type=kotlin.Nothing from='bar(): Int' CALL 'bar(): Int' type=kotlin.Int origin=null - $this: GET_VAR '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test1 origin=null FUN DELEGATED_MEMBER public open override fun foo(x: kotlin.Int, s: kotlin.String): kotlin.Unit BLOCK_BODY CALL 'foo(Int, String): Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test1 origin=null x: GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=null s: GET_VAR 'value-parameter s: String' type=kotlin.String origin=null FUN DELEGATED_MEMBER public open override fun kotlin.String.qux(): kotlin.Unit BLOCK_BODY CALL 'qux() on String: Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test1$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test1 origin=null $receiver: GET_VAR '' type=kotlin.String origin=null CLASS CLASS Test2 CONSTRUCTOR public constructor Test2() @@ -132,17 +135,20 @@ FILE /delegatedImplementation.kt BLOCK_BODY RETURN type=kotlin.Nothing from='bar(): Int' CALL 'bar(): Int' type=kotlin.Int origin=null - $this: GET_VAR '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test2 origin=null FUN DELEGATED_MEMBER public open override fun foo(x: kotlin.Int, s: kotlin.String): kotlin.Unit BLOCK_BODY CALL 'foo(Int, String): Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test2 origin=null x: GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=null s: GET_VAR 'value-parameter s: String' type=kotlin.String origin=null FUN DELEGATED_MEMBER public open override fun kotlin.String.qux(): kotlin.Unit BLOCK_BODY CALL 'qux() on String: Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + $this: GET_FIELD '`Test2$IBase$delegate`: BaseImpl' type=BaseImpl origin=null + receiver: GET_VAR '' type=Test2 origin=null $receiver: GET_VAR '' type=kotlin.String origin=null FIELD DELEGATE val `Test2$IOther$delegate`: IOther EXPRESSION_BODY @@ -154,25 +160,29 @@ FILE /delegatedImplementation.kt BLOCK_BODY RETURN type=kotlin.Nothing from='() on Byte: Int' CALL '() on Byte: Int' type=kotlin.Int origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null $receiver: GET_VAR '' type=kotlin.Byte origin=null PROPERTY DELEGATED_MEMBER public open override val x: kotlin.String FUN DELEGATED_MEMBER public open override fun (): kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from='(): String' CALL '(): String' type=kotlin.String origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null PROPERTY DELEGATED_MEMBER public open override var kotlin.Byte.z2: kotlin.Int FUN DELEGATED_MEMBER public open override fun kotlin.Byte.(): kotlin.Int BLOCK_BODY RETURN type=kotlin.Nothing from='() on Byte: Int' CALL '() on Byte: Int' type=kotlin.Int origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null $receiver: GET_VAR '' type=kotlin.Byte origin=null FUN DELEGATED_MEMBER public open override fun kotlin.Byte.(: kotlin.Int): kotlin.Unit BLOCK_BODY CALL '(Int) on Byte: Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null $receiver: GET_VAR '' type=kotlin.Byte origin=null : GET_VAR 'value-parameter : Int' type=kotlin.Int origin=null PROPERTY DELEGATED_MEMBER public open override var y: kotlin.Int @@ -180,9 +190,11 @@ FILE /delegatedImplementation.kt BLOCK_BODY RETURN type=kotlin.Nothing from='(): Int' CALL '(): Int' type=kotlin.Int origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null FUN DELEGATED_MEMBER public open override fun (: kotlin.Int): kotlin.Unit BLOCK_BODY CALL '(Int): Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`Test2$IOther$delegate`: IOther' type=IOther origin=null + $this: GET_FIELD '`Test2$IOther$delegate`: IOther' type=IOther origin=null + receiver: GET_VAR '' type=Test2 origin=null : GET_VAR 'value-parameter : Int' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.txt b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.txt index 8800c5c171c..b59b3363b9d 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.txt @@ -22,6 +22,7 @@ FILE /delegatedImplementationWithExplicitOverride.kt FUN DELEGATED_MEMBER public open override fun foo(): kotlin.Unit BLOCK_BODY CALL 'foo(): Unit' type=kotlin.Unit origin=null - $this: GET_VAR '`C$IFooBar$delegate`: FooBarImpl' type=FooBarImpl origin=null + $this: GET_FIELD '`C$IFooBar$delegate`: FooBarImpl' type=FooBarImpl origin=null + receiver: GET_VAR '' type=C origin=null FUN public open override fun bar(): kotlin.Unit BLOCK_BODY