diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index 78d973556f3..82f70443e78 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -189,15 +189,21 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen ): PropertyLValueBase { val superQualifierSymbol = superQualifier?.let { context.symbolTable.referenceClass(it) } - val getterSymbol = descriptor.getter?.let { context.symbolTable.referenceFunction(it) } - val setterSymbol = descriptor.setter?.let { context.symbolTable.referenceFunction(it) } + val getterDescriptor = descriptor.getter + val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } + + val setterDescriptor = descriptor.setter + val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } + return if (getterSymbol != null || setterSymbol != null) { AccessorPropertyLValue( scope, ktExpression.startOffset, ktExpression.endOffset, origin, descriptor.type, getterSymbol, + getterDescriptor, setterSymbol, + setterDescriptor, typeArguments, propertyReceiver, superQualifierSymbol diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index 0af859198b8..1939d18ea85 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -135,10 +135,11 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE val getterDescriptor = descriptor.getter if (getterDescriptor != null) { - val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor) + val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original) IrGetterCallImpl( startOffset, endOffset, getterSymbol, + getterDescriptor, getTypeArguments(call.original), dispatchReceiverValue?.load(), extensionReceiverValue?.load(), diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt index 4fb3d8633b0..3d43ca5401a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.expressions.IrExpression @@ -112,7 +113,9 @@ class AccessorPropertyLValue( origin: IrStatementOrigin?, type: KotlinType, val getter: IrFunctionSymbol?, + val getterDescriptor: FunctionDescriptor?, val setter: IrFunctionSymbol?, + val setterDescriptor: FunctionDescriptor?, val typeArguments: Map?, callReceiver: CallReceiver, superQualifier: IrClassSymbol? @@ -121,7 +124,7 @@ class AccessorPropertyLValue( callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> IrGetterCallImpl( startOffset, endOffset, - getter!!, + getter!!, getterDescriptor!!, typeArguments, dispatchReceiverValue?.load(), extensionReceiverValue?.load(), @@ -134,7 +137,7 @@ class AccessorPropertyLValue( callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> IrSetterCallImpl( startOffset, endOffset, - setter!!, + setter!!, setterDescriptor!!, typeArguments, dispatchReceiverValue?.load(), extensionReceiverValue?.load(), @@ -147,7 +150,7 @@ class AccessorPropertyLValue( override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase = AccessorPropertyLValue( scope, startOffset, endOffset, origin, - type, getter, setter, + type, getter, getterDescriptor, setter, setterDescriptor, typeArguments, SimpleCallReceiver(dispatchReceiver, extensionReceiver), superQualifier diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt index ed7857fbb06..e9ab258a8bd 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt @@ -135,7 +135,7 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) = arg1, arg2)) fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall = - IrGetterCallImpl(startOffset, endOffset, getterSymbol, null, receiver, null, IrStatementOrigin.GET_PROPERTY) + IrGetterCallImpl(startOffset, endOffset, getterSymbol, getterSymbol.descriptor, null, receiver, null, IrStatementOrigin.GET_PROPERTY) fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: KotlinType): IrCall = IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor, null) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt index f5478bdf02e..b0fe3f7d5a8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrCallImpl.kt @@ -16,9 +16,10 @@ package org.jetbrains.kotlin.ir.expressions.impl -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol @@ -63,7 +64,7 @@ class IrCallImpl( typeArguments: Map? = null, origin: IrStatementOrigin? = null, superQualifierSymbol: IrClassSymbol? = null - ) : this(startOffset, endOffset, symbol.descriptor.returnType!!, symbol, descriptor, typeArguments, origin, superQualifierSymbol) + ) : this(startOffset, endOffset, descriptor.returnType!!, symbol, descriptor, typeArguments, origin, superQualifierSymbol) constructor(startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol) : this(startOffset, endOffset, symbol, symbol.descriptor) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt index a9ad71c90d2..fd2a3749846 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt @@ -36,11 +36,11 @@ import java.lang.UnsupportedOperationException abstract class IrPropertyAccessorCallBase( startOffset: Int, endOffset: Int, override val symbol: IrFunctionSymbol, + override val descriptor: FunctionDescriptor, typeArguments: Map?, override val origin: IrStatementOrigin? = null, override val superQualifierSymbol: IrClassSymbol? = null -) : IrMemberAccessExpressionBase(startOffset, endOffset, symbol.descriptor.returnType!!, typeArguments), IrCall { - override val descriptor: FunctionDescriptor get() = symbol.descriptor +) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!, typeArguments), IrCall { override val superQualifier: ClassDescriptor? get() = superQualifierSymbol?.descriptor override fun accept(visitor: IrElementVisitor, data: D): R { @@ -55,18 +55,20 @@ abstract class IrPropertyAccessorCallBase( class IrGetterCallImpl( startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol, + descriptor: FunctionDescriptor, typeArguments: Map?, origin: IrStatementOrigin? = null, superQualifierSymbol: IrClassSymbol? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy { +) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy { constructor(startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol, + descriptor: FunctionDescriptor, typeArguments: Map?, dispatchReceiver: IrExpression?, extensionReceiver: IrExpression?, origin: IrStatementOrigin? = null, superQualifierSymbol: IrClassSymbol? = null - ) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) { + ) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) { this.dispatchReceiver = dispatchReceiver this.extensionReceiver = extensionReceiver } @@ -82,12 +84,15 @@ class IrGetterCallImpl( } override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall = - IrGetterCallImpl(startOffset, endOffset, newCallee, typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier) + IrGetterCallImpl(startOffset, endOffset, newCallee, + descriptor, // TODO substitute descriptor for new callee? + typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier) override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall = IrGetterCallImpl( startOffset, endOffset, createFunctionSymbol(newCallee), + newCallee, typeArguments, dispatchReceiver, extensionReceiver, newOrigin, createClassSymbolOrNull(newSuperQualifier) @@ -97,19 +102,21 @@ class IrGetterCallImpl( class IrSetterCallImpl( startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol, + descriptor: FunctionDescriptor, typeArguments: Map?, origin: IrStatementOrigin? = null, superQualifierSymbol: IrClassSymbol? = null -) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy { +) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy { constructor(startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol, + descriptor: FunctionDescriptor, typeArguments: Map?, dispatchReceiver: IrExpression?, extensionReceiver: IrExpression?, argument: IrExpression, origin: IrStatementOrigin? = null, superQualifierSymbol: IrClassSymbol? = null - ) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) { + ) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) { this.dispatchReceiver = dispatchReceiver this.extensionReceiver = extensionReceiver putValueArgument(SETTER_ARGUMENT_INDEX, argument) @@ -131,12 +138,15 @@ class IrSetterCallImpl( } override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall = - IrSetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier) + IrSetterCallImpl(startOffset, endOffset, newCallee, + descriptor, // TODO substitute newCallee.descriptor? + typeArguments, newOrigin, newSuperQualifier) override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall = IrSetterCallImpl( startOffset, endOffset, createFunctionSymbol(newCallee), + newCallee, typeArguments, newOrigin, createClassSymbolOrNull(newSuperQualifier) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrSymbolBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrSymbolBase.kt index 45a7d30efdf..d543a0bb7f6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrSymbolBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/impl/IrSymbolBase.kt @@ -24,6 +24,18 @@ abstract class IrSymbolBase(override val descript abstract class IrBindableSymbolBase(descriptor: D) : IrBindableSymbol, IrSymbolBase(descriptor) { + init { + assert(isOriginalDescriptor(descriptor)) { + "Substituted descriptor $descriptor for ${descriptor.original}" + } + } + + private fun isOriginalDescriptor(descriptor: DeclarationDescriptor): Boolean = + if (descriptor is ValueParameterDescriptor) + isOriginalDescriptor(descriptor.containingDeclaration) + else + descriptor == descriptor.original + private var _owner: B? = null override val owner: B get() = _owner ?: throw IllegalStateException("Symbol for $descriptor is unbound") diff --git a/compiler/testData/ir/irText/expressions/genericPropertyCall.kt b/compiler/testData/ir/irText/expressions/genericPropertyCall.kt new file mode 100644 index 00000000000..5c31b0f1772 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/genericPropertyCall.kt @@ -0,0 +1,3 @@ +val T.id get() = this + +val test = "abc".id \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/genericPropertyCall.txt b/compiler/testData/ir/irText/expressions/genericPropertyCall.txt new file mode 100644 index 00000000000..5b6a00f7346 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/genericPropertyCall.txt @@ -0,0 +1,16 @@ +FILE /genericPropertyCall.kt + PROPERTY public val T.id: T + FUN public fun T.(): T + $receiver: VALUE_PARAMETER + BLOCK_BODY + RETURN type=kotlin.Nothing from='() on T: T' + GET_VAR '' type=T origin=null + PROPERTY public val test: kotlin.String + FIELD PROPERTY_BACKING_FIELD public val test: kotlin.String + EXPRESSION_BODY + CALL '() on String: String' type=kotlin.String origin=GET_PROPERTY + $receiver: CONST String type=kotlin.String value='abc' + FUN DEFAULT_PROPERTY_ACCESSOR public fun (): kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): String' + GET_FIELD 'test: String' type=kotlin.String origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index e3bd2f8b14a..25736d52cdb 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -647,6 +647,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("genericPropertyCall.kt") + public void testGenericPropertyCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/genericPropertyCall.kt"); + doTest(fileName); + } + @TestMetadata("identity.kt") public void testIdentity() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/identity.kt");