From ef8485a2326942706228f31f92e47fdfff3dc6ab Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 22 Jan 2020 16:37:05 +0300 Subject: [PATCH] FIR2IR: change receiver handling in case it's an outer object Before this commit, FIR2IR expected that FIR will have no receiver in this case. However, now FIR *has* receiver, so we have to convert it to object correctly --- .../kotlin/fir/backend/Fir2IrVisitor.kt | 13 ++++++++++++ ...classCallsProtectedInheritedByCompanion.kt | 1 - .../expressions/objectReference.fir.txt | 8 ++++---- .../expressions/propertyReferences.fir.txt | 20 +++++++++---------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index aad1c464d07..73e6ccd62b5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -873,6 +873,19 @@ class Fir2IrVisitor( override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: Any?): IrElement { val calleeReference = thisReceiverExpression.calleeReference if (calleeReference.labelName == null && calleeReference.boundSymbol is FirRegularClassSymbol) { + // Object case + val firObject = (calleeReference.boundSymbol?.fir as? FirClass)?.takeIf { + it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT + } + if (firObject != null) { + val irObject = declarationStorage.getIrClass(firObject, setParent = false) + if (irObject != classStack.lastOrNull()) { + return thisReceiverExpression.convertWithOffsets { startOffset, endOffset -> + IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol) + } + } + } + val dispatchReceiver = this.functionStack.lastOrNull()?.dispatchReceiverParameter if (dispatchReceiver != null) { // Use the dispatch receiver of the containing function diff --git a/compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt b/compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt index 102025bfe39..454a3815e24 100644 --- a/compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt +++ b/compiler/testData/codegen/box/objects/classCallsProtectedInheritedByCompanion.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR open class A { protected fun foo() = "OK" } diff --git a/compiler/testData/ir/irText/expressions/objectReference.fir.txt b/compiler/testData/ir/irText/expressions/objectReference.fir.txt index 7a0ad2446d6..efd53bd1350 100644 --- a/compiler/testData/ir/irText/expressions/objectReference.fir.txt +++ b/compiler/testData/ir/irText/expressions/objectReference.fir.txt @@ -121,10 +121,10 @@ FILE fqName: fileName:/objectReference.kt ANONYMOUS_INITIALIZER isStatic=false BLOCK_BODY SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null - receiver: GET_VAR ': .Z declared in .Z' type=.Z origin=null + receiver: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z value: CONST Int type=kotlin.Int value=1 CALL 'public final fun foo (): kotlin.Unit declared in .Z' type=kotlin.Unit origin=null - $this: GET_VAR ': .Z declared in .Z' type=.Z origin=null + $this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null receiver: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z value: CONST Int type=kotlin.Int value=1 @@ -134,10 +134,10 @@ FILE fqName: fileName:/objectReference.kt $this: VALUE_PARAMETER name: type:.Z.anObject. BLOCK_BODY SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null - receiver: GET_VAR ': .Z.anObject. declared in .Z.anObject..test' type=.Z.anObject. origin=null + receiver: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z value: CONST Int type=kotlin.Int value=1 CALL 'public final fun foo (): kotlin.Unit declared in .Z' type=kotlin.Unit origin=null - $this: GET_VAR ': .Z.anObject. declared in .Z.anObject..test' type=.Z.anObject. origin=null + $this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:private' type=kotlin.Unit origin=null receiver: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.Z value: CONST Int type=kotlin.Int value=1 diff --git a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt index 66db339b185..9995fc74d03 100644 --- a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt +++ b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt @@ -250,23 +250,23 @@ FILE fqName: fileName:/propertyReferences.kt RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KProperty0 declared in ' GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_constVal type:kotlin.reflect.KProperty0 visibility:private [final,static]' type=kotlin.reflect.KProperty0 origin=null PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty1<.J, kotlin.Int> visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty0 visibility:private [final,static] EXPRESSION_BODY - ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.CONST|' type=kotlin.reflect.KProperty1<.J, kotlin.Int> - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty1<.J, kotlin.Int> + ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.CONST|' type=kotlin.reflect.KProperty0 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty0 correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KProperty1<.J, kotlin.Int> declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty1<.J, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KProperty1<.J, kotlin.Int> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KProperty0 declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty0 visibility:private [final,static]' type=kotlin.reflect.KProperty0 origin=null PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty1<.J, kotlin.Int> visibility:private [final,static] + FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty0 visibility:private [final,static] EXPRESSION_BODY - ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.nonConst|' type=kotlin.reflect.KMutableProperty1<.J, kotlin.Int> - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty1<.J, kotlin.Int> + ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.nonConst|' type=kotlin.reflect.KMutableProperty0 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty0 correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KMutableProperty1<.J, kotlin.Int> declared in ' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty1<.J, kotlin.Int> visibility:private [final,static]' type=kotlin.reflect.KMutableProperty1<.J, kotlin.Int> origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.reflect.KMutableProperty0 declared in ' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty0 visibility:private [final,static]' type=kotlin.reflect.KMutableProperty0 origin=null PROPERTY name:test_varWithPrivateSet visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:kotlin.reflect.KMutableProperty1<.C, kotlin.Int> visibility:private [final,static] EXPRESSION_BODY