From 6ea33986fa0034ce3699cf406272f2beb25d5044 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 11 Jul 2019 13:01:58 +0300 Subject: [PATCH] psi2ir: Provide substituted descriptor for property references --- .../kotlin/fir/Fir2IrTextTestGenerated.java | 5 ++ .../ReflectionReferencesGenerator.kt | 1 + .../impl/IrPropertyReferenceImpl.kt | 20 ++++- .../genericPropertyReferenceType.fir.txt | 66 +++++++++++++++ .../types/genericPropertyReferenceType.kt | 20 +++++ .../types/genericPropertyReferenceType.txt | 81 +++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 5 ++ 7 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt create mode 100644 compiler/testData/ir/irText/types/genericPropertyReferenceType.kt create mode 100644 compiler/testData/ir/irText/types/genericPropertyReferenceType.txt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 2db4d3ce71c..b508eeaaba8 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1616,6 +1616,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); } + @TestMetadata("genericPropertyReferenceType.kt") + public void testGenericPropertyReferenceType() throws Exception { + runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt"); + } + @TestMetadata("intersectionType1_NI.kt") public void testIntersectionType1_NI() throws Exception { runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt"); 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 73a1e879816..46ca1bd6376 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 @@ -143,6 +143,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St return IrPropertyReferenceImpl( startOffset, endOffset, type.toIrType(), context.symbolTable.referenceProperty(originalProperty), + propertyDescriptor, propertyDescriptor.typeParametersCount, getFieldForPropertyReference(originalProperty), originalGetter?.let { context.symbolTable.referenceSimpleFunction(it) }, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt index a9d5af76fe5..17cb397c7f4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyReferenceImpl.kt @@ -31,6 +31,7 @@ class IrPropertyReferenceImpl( endOffset: Int, type: IrType, override val symbol: IrPropertySymbol, + override val descriptor: PropertyDescriptor, typeArgumentsCount: Int, override val field: IrFieldSymbol?, override val getter: IrSimpleFunctionSymbol?, @@ -40,6 +41,22 @@ class IrPropertyReferenceImpl( IrNoArgumentsCallableReferenceBase(startOffset, endOffset, type, typeArgumentsCount, origin), IrPropertyReference { + constructor( + startOffset: Int, + endOffset: Int, + type: IrType, + symbol: IrPropertySymbol, + typeArgumentsCount: Int, + field: IrFieldSymbol?, + getter: IrSimpleFunctionSymbol?, + setter: IrSimpleFunctionSymbol?, + origin: IrStatementOrigin? = null + ) : this( + startOffset, endOffset, type, + symbol, symbol.descriptor, + typeArgumentsCount, field, getter, setter, origin + ) + @Deprecated(message = "Don't use descriptor-based API for IrPropertyReference", level = DeprecationLevel.WARNING) constructor( startOffset: Int, @@ -57,9 +74,6 @@ class IrPropertyReferenceImpl( typeArgumentsCount, field, getter, setter, origin ) - override val descriptor: PropertyDescriptor - get() = symbol.descriptor - override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitPropertyReference(this, data) } \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt new file mode 100644 index 00000000000..e7db1cd1524 --- /dev/null +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.txt @@ -0,0 +1,66 @@ +FILE fqName: fileName:/genericPropertyReferenceType.kt + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + TYPE_PARAMETER name:T index:0 variance: superTypes:[] + CONSTRUCTOR visibility:public <> (x:T of ) returnType:.C> [primary] + VALUE_PARAMETER name:x index:0 type:T of + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public + EXPRESSION_BODY + GET_VAR 'x: T of declared in .C.' type=T of origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C) returnType:T of .C + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.C + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T of .C declared in .C' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public ' type=T of .C origin=null + receiver: GET_VAR ': .C declared in .C.' type=.C origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C, :T of .C) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.C + VALUE_PARAMETER name: index:0 type:T of .C + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public ' type=kotlin.Unit origin=null + receiver: GET_VAR ': .C declared in .C.' type=.C origin=null + value: GET_VAR ': T of .C declared in .C.' type=T of .C origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + PROPERTY name:y visibility:public modality:FINAL [var] + FUN name: visibility:public modality:FINAL <> () returnType:IrErrorType + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): IrErrorType declared in ' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + FUN name: visibility:public modality:FINAL <> (v:IrErrorType) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] + VALUE_PARAMETER name:v index:0 type:IrErrorType + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=IrErrorType + FUN name:use visibility:public modality:FINAL <> (p:kotlin.reflect.KMutableProperty) returnType:kotlin.Unit + VALUE_PARAMETER name:p index:0 type:kotlin.reflect.KMutableProperty + BLOCK_BODY + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null + p: CALL 'public final fun (): IrErrorType declared in ' type=IrErrorType origin=null + FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=.C origin=CAST typeOperand=.C + GET_VAR 'a: kotlin.Any declared in .test2' type=kotlin.Any origin=null + CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null + p: ERROR_CALL 'Unresolved reference: #' type=IrErrorType diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt new file mode 100644 index 00000000000..0a6b18c7682 --- /dev/null +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KMutableProperty + +class C(var x: T) + +var C.y + get() = x + set(v) { + x = v + } + +fun use(p: KMutableProperty) {} + +fun test1() { + use(C("abc")::y) +} + +fun test2(a: Any) { + a as C + use(a::y) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.txt new file mode 100644 index 00000000000..798acb09036 --- /dev/null +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.txt @@ -0,0 +1,81 @@ +FILE fqName: fileName:/genericPropertyReferenceType.kt + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C.C> + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> (x:T of .C) returnType:.C.C> [primary] + VALUE_PARAMETER name:x index:0 type:T of .C + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:x visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public + EXPRESSION_BODY + GET_VAR 'x: T of .C declared in .C.' type=T of .C origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C.C>) returnType:T of .C + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.C.C> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T of .C declared in .C' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public ' type=T of .C origin=null + receiver: GET_VAR ': .C.C> declared in .C.' type=.C.C> origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C.C>, :T of .C) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.C.C> + VALUE_PARAMETER name: index:0 type:T of .C + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:public ' type=kotlin.Unit origin=null + receiver: GET_VAR ': .C.C> declared in .C.' type=.C.C> origin=null + value: GET_VAR ': T of .C declared in .C.' type=T of .C origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + PROPERTY name:y visibility:public modality:FINAL [var] + FUN name: visibility:public modality:FINAL ($receiver:.C.>) returnType:T of . + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + $receiver: VALUE_PARAMETER name: type:.C.> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): T of . declared in ' + CALL 'public final fun (): T of .C declared in .C' type=T of . origin=GET_PROPERTY + $this: GET_VAR ': .C.> declared in .' type=.C.> origin=null + FUN name: visibility:public modality:FINAL ($receiver:.C.>, v:T of .) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + $receiver: VALUE_PARAMETER name: type:.C.> + VALUE_PARAMETER name:v index:0 type:T of . + BLOCK_BODY + CALL 'public final fun (: T of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=EQ + $this: GET_VAR ': .C.> declared in .' type=.C.> origin=null + : GET_VAR 'v: T of . declared in .' type=T of . origin=null + FUN name:use visibility:public modality:FINAL <> (p:kotlin.reflect.KMutableProperty) returnType:kotlin.Unit + VALUE_PARAMETER name:p index:0 type:kotlin.reflect.KMutableProperty + BLOCK_BODY + FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null + p: PROPERTY_REFERENCE 'public final y: T of . [var]' field=null getter='public final fun (): T of . declared in ' setter='public final fun (v: T of .): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty0 origin=null + <1>: kotlin.String + $receiver: CONSTRUCTOR_CALL 'public constructor (x: T of .C) [primary] declared in .C' type=.C origin=null + : kotlin.String + x: CONST String type=kotlin.String value="abc" + FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:a index:0 type:kotlin.Any + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + TYPE_OP type=.C origin=CAST typeOperand=.C + GET_VAR 'a: kotlin.Any declared in .test2' type=kotlin.Any origin=null + CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null + p: PROPERTY_REFERENCE 'public final y: T of . [var]' field=null getter='public final fun (): T of . declared in ' setter='public final fun (v: T of .): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty0 origin=null + <1>: kotlin.String + $receiver: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C + GET_VAR 'a: kotlin.Any declared in .test2' type=kotlin.Any origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 29ee1f62c05..30603c5575e 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1616,6 +1616,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/types/explicitEqualsAndCompareToCallsOnPlatformTypeReceiver.kt"); } + @TestMetadata("genericPropertyReferenceType.kt") + public void testGenericPropertyReferenceType() throws Exception { + runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt"); + } + @TestMetadata("intersectionType1_NI.kt") public void testIntersectionType1_NI() throws Exception { runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt");