From fdb4de355c206321aa813d14e7ead51e244a69c7 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 4 May 2017 12:43:31 +0300 Subject: [PATCH] Use original descriptors to create symbols for callable references --- .../generators/LocalFunctionGenerator.kt | 4 +- .../ReflectionReferencesGenerator.kt | 12 ++--- .../impl/IrFunctionReferenceImpl.kt | 5 +-- .../kotlin/ir/util/DeepCopyIrTree.kt | 10 ++--- .../ir/util/DeepCopyIrTreeWithSymbols.kt | 1 + .../expressions/callableRefToGenericMember.kt | 7 +++ .../callableRefToGenericMember.txt | 44 +++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 6 +++ 8 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/callableRefToGenericMember.kt create mode 100644 compiler/testData/ir/irText/expressions/callableRefToGenericMember.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LocalFunctionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LocalFunctionGenerator.kt index 2544e6cd8bd..c557d6e7f4c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LocalFunctionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LocalFunctionGenerator.kt @@ -37,7 +37,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement irBlock.statements.add( IrFunctionReferenceImpl( ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, - irLambdaFunction.symbol, + irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, null, IrStatementOrigin.LAMBDA ) ) @@ -59,7 +59,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement irBlock.statements.add( IrFunctionReferenceImpl( ktFun.startOffset, ktFun.endOffset, funExpressionType, - irFun.symbol, + irFun.symbol, irFun.symbol.descriptor, null, IrStatementOrigin.ANONYMOUS_FUNCTION ) ) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index a24628b8365..11a45bcd186 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -42,7 +42,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St } else { val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor - val typeClass = typeConstructorDeclaration as? ClassifierDescriptor ?: + val typeClass = typeConstructorDeclaration ?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration") IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, context.symbolTable.referenceClassifier(typeClass)) @@ -83,7 +83,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St is FunctionDescriptor -> generateFunctionReference( startOffset, endOffset, type, - context.symbolTable.referenceFunction(callableDescriptor), + context.symbolTable.referenceFunction(callableDescriptor.original), + callableDescriptor, typeArguments, origin ) @@ -128,8 +129,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St val setterDescriptor = propertyDescriptor.setter val fieldSymbol = if (getterDescriptor == null) context.symbolTable.referenceField(propertyDescriptor) else null - val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it) } - val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) } + val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } + val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } return IrPropertyReferenceImpl( startOffset, endOffset, type, @@ -145,12 +146,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St endOffset: Int, type: KotlinType, symbol: IrFunctionSymbol, + descriptor: FunctionDescriptor, typeArguments: Map?, origin: IrStatementOrigin? ): IrFunctionReference = IrFunctionReferenceImpl( startOffset, endOffset, type, - symbol, + symbol, descriptor, typeArguments, origin ) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt index c9819f813d3..eccf31b7d36 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrFunctionReferenceImpl.kt @@ -30,6 +30,7 @@ class IrFunctionReferenceImpl( endOffset: Int, type: KotlinType, override val symbol: IrFunctionSymbol, + override val descriptor: FunctionDescriptor, typeArguments: Map?, origin: IrStatementOrigin? = null ) : IrFunctionReference, @@ -48,9 +49,7 @@ class IrFunctionReferenceImpl( descriptor: FunctionDescriptor, typeArguments: Map?, origin: IrStatementOrigin? = null - ) : this(startOffset, endOffset, type, createFunctionSymbol(descriptor), typeArguments, origin) - - override val descriptor: FunctionDescriptor get() = symbol.descriptor + ) : this(startOffset, endOffset, type, createFunctionSymbol(descriptor.original), descriptor, typeArguments, origin) override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitFunctionReference(this, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt index abf4cab4f4b..40263f42060 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt @@ -409,7 +409,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { return IrFunctionReferenceImpl( expression.startOffset, expression.endOffset, expression.type, - newCallee, + newCallee.original, expression.transformTypeArguments(newCallee), mapStatementOrigin(expression.origin) ).transformValueArguments(expression) @@ -418,8 +418,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { override fun visitPropertyReference(expression: IrPropertyReference): IrExpression { val newProperty = mapPropertyReference(expression.descriptor) val newFieldSymbol = if (newProperty.getter == null) IrFieldSymbolImpl(newProperty) else null - val newGetterSymbol = newProperty.getter?.let { IrSimpleFunctionSymbolImpl(it) } - val newSetterSymbol = newProperty.setter?.let { IrSimpleFunctionSymbolImpl(it) } + val newGetterSymbol = newProperty.getter?.let { IrSimpleFunctionSymbolImpl(it.original) } + val newSetterSymbol = newProperty.setter?.let { IrSimpleFunctionSymbolImpl(it.original) } return IrPropertyReferenceImpl( expression.startOffset, expression.endOffset, expression.type, newProperty, newFieldSymbol, newGetterSymbol, newSetterSymbol, @@ -432,8 +432,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { val newLocalDelegatedProperty = mapLocalPropertyReference(expression.descriptor) val newDelegateDescriptor = mapVariableReference(expression.delegate.descriptor) val newDelegateSymbol = IrVariableSymbolImpl(newDelegateDescriptor) - val newGetterSymbol = newLocalDelegatedProperty.getter!!.let { IrSimpleFunctionSymbolImpl(it) } - val newSetterSymbol = newLocalDelegatedProperty.setter?.let { IrSimpleFunctionSymbolImpl(it) } + val newGetterSymbol = newLocalDelegatedProperty.getter!!.let { IrSimpleFunctionSymbolImpl(it.original) } + val newSetterSymbol = newLocalDelegatedProperty.setter?.let { IrSimpleFunctionSymbolImpl(it.original) } return IrLocalDelegatedPropertyReferenceImpl( expression.startOffset, expression.endOffset, expression.type, newLocalDelegatedProperty, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt index 9856b9a1729..5351129c0a1 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt @@ -378,6 +378,7 @@ class DeepCopyIrTreeWithSymbols(private val symbolsRemapper: DeepCopySymbolsRema expression.startOffset, expression.endOffset, expression.type, symbolsRemapper.getReferencedFunction(expression.symbol), + expression.descriptor, // TODO substitute referenced descriptor expression.getTypeArgumentsMap(), mapStatementOrigin(expression.origin) ).transformValueArguments(expression) diff --git a/compiler/testData/ir/irText/expressions/callableRefToGenericMember.kt b/compiler/testData/ir/irText/expressions/callableRefToGenericMember.kt new file mode 100644 index 00000000000..791d303ff9b --- /dev/null +++ b/compiler/testData/ir/irText/expressions/callableRefToGenericMember.kt @@ -0,0 +1,7 @@ +class A { + fun foo() {} + val bar = 42 +} + +val test1 = A::foo +val test2 = A::bar \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/callableRefToGenericMember.txt b/compiler/testData/ir/irText/expressions/callableRefToGenericMember.txt new file mode 100644 index 00000000000..0d8fff215a3 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/callableRefToGenericMember.txt @@ -0,0 +1,44 @@ +FILE /callableRefToGenericMember.kt + CLASS CLASS A + $this: VALUE_PARAMETER this@A: A + TYPE_PARAMETER + CONSTRUCTOR public constructor A() + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='A' + FUN public final fun foo(): kotlin.Unit + $this: VALUE_PARAMETER this@A: A + BLOCK_BODY + PROPERTY public final val bar: kotlin.Int = 42 + FIELD PROPERTY_BACKING_FIELD public final val bar: kotlin.Int = 42 + EXPRESSION_BODY + CONST Int type=kotlin.Int value='42' + FUN DEFAULT_PROPERTY_ACCESSOR public final fun (): kotlin.Int + $this: VALUE_PARAMETER this@A: A + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): Int' + GET_FIELD 'bar: Int' type=kotlin.Int origin=null + receiver: GET_VAR 'this@A: A' type=A origin=null + FUN FAKE_OVERRIDE public open override fun equals(other: kotlin.Any?): kotlin.Boolean + $this: VALUE_PARAMETER this@Any: Any + VALUE_PARAMETER value-parameter other: kotlin.Any? + FUN FAKE_OVERRIDE public open override fun hashCode(): kotlin.Int + $this: VALUE_PARAMETER this@Any: Any + FUN FAKE_OVERRIDE public open override fun toString(): kotlin.String + $this: VALUE_PARAMETER this@Any: Any + PROPERTY public val test1: kotlin.reflect.KFunction1, kotlin.Unit> + FIELD PROPERTY_BACKING_FIELD public val test1: kotlin.reflect.KFunction1, kotlin.Unit> + EXPRESSION_BODY + FUNCTION_REFERENCE 'foo(): Unit' type=kotlin.reflect.KFunction1, kotlin.Unit> origin=null + FUN DEFAULT_PROPERTY_ACCESSOR public fun (): kotlin.reflect.KFunction1, kotlin.Unit> + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): KFunction1, Unit>' + GET_FIELD 'test1: KFunction1, Unit>' type=kotlin.reflect.KFunction1, kotlin.Unit> origin=null + PROPERTY public val test2: kotlin.reflect.KProperty1, kotlin.Int> + FIELD PROPERTY_BACKING_FIELD public val test2: kotlin.reflect.KProperty1, kotlin.Int> + EXPRESSION_BODY + PROPERTY_REFERENCE 'bar: Int' field=null getter='(): Int' setter=null type=kotlin.reflect.KProperty1, kotlin.Int> origin=null + FUN DEFAULT_PROPERTY_ACCESSOR public fun (): kotlin.reflect.KProperty1, kotlin.Int> + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): KProperty1, Int>' + GET_FIELD 'test2: KProperty1, Int>' type=kotlin.reflect.KProperty1, kotlin.Int> origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index cb9afd83e44..82628b67c3b 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -545,6 +545,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("callableRefToGenericMember.kt") + public void testCallableRefToGenericMember() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/callableRefToGenericMember.kt"); + doTest(fileName); + } + @TestMetadata("calls.kt") public void testCalls() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/calls.kt");