From b09b2673bf8b48405cb61fee577c5762823e4282 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 4 Feb 2020 12:39:30 +0300 Subject: [PATCH] FIR2IR: handle non-ambiguous super references properly --- .../org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt | 10 ++++++++++ .../codegen/box/mangling/internalOverrideSuperCall.kt | 1 + .../codegen/box/mangling/publicOverrideSuperCall.kt | 1 + .../testData/codegen/box/super/interfaceHashCode.kt | 1 - .../ir/irText/classes/enumWithMultipleCtors.fir.txt | 2 +- .../implicitNotNullOnDelegatedImplementation.fir.txt | 7 +++---- .../ir/irText/classes/qualifiedSuperCalls.fir.txt | 8 ++++---- 7 files changed, 20 insertions(+), 10 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 34e9de90e50..49078978c9c 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 @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope @@ -705,6 +706,15 @@ class Fir2IrVisitor( val type = typeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage) val symbol = calleeReference.toSymbol(declarationStorage) return typeRef.convertWithOffsets { startOffset, endOffset -> + if (calleeReference is FirSuperReference) { + if (typeRef !is FirComposedSuperTypeRef) { + val dispatchReceiver = functionStack.lastOrNull()?.dispatchReceiverParameter + if (dispatchReceiver != null) { + // Use the dispatch receiver of the containing function + return@convertWithOffsets IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol) + } + } + } when { symbol is IrConstructorSymbol -> IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, type, symbol) symbol is IrSimpleFunctionSymbol -> IrCallImpl( diff --git a/compiler/testData/codegen/box/mangling/internalOverrideSuperCall.kt b/compiler/testData/codegen/box/mangling/internalOverrideSuperCall.kt index 64424c1dd80..e5530d5d9e3 100644 --- a/compiler/testData/codegen/box/mangling/internalOverrideSuperCall.kt +++ b/compiler/testData/codegen/box/mangling/internalOverrideSuperCall.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR open class A { internal open val field = "F" diff --git a/compiler/testData/codegen/box/mangling/publicOverrideSuperCall.kt b/compiler/testData/codegen/box/mangling/publicOverrideSuperCall.kt index 422f510101e..40bcb6b6077 100644 --- a/compiler/testData/codegen/box/mangling/publicOverrideSuperCall.kt +++ b/compiler/testData/codegen/box/mangling/publicOverrideSuperCall.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR open class A { internal open val field = "F" diff --git a/compiler/testData/codegen/box/super/interfaceHashCode.kt b/compiler/testData/codegen/box/super/interfaceHashCode.kt index 7a6aeff7fa3..c88e69af2cf 100644 --- a/compiler/testData/codegen/box/super/interfaceHashCode.kt +++ b/compiler/testData/codegen/box/super/interfaceHashCode.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR interface I class C : I { fun foo() = super.hashCode() } diff --git a/compiler/testData/ir/irText/classes/enumWithMultipleCtors.fir.txt b/compiler/testData/ir/irText/classes/enumWithMultipleCtors.fir.txt index 7c28536f8a1..974556fb5aa 100644 --- a/compiler/testData/ir/irText/classes/enumWithMultipleCtors.fir.txt +++ b/compiler/testData/ir/irText/classes/enumWithMultipleCtors.fir.txt @@ -22,7 +22,7 @@ FILE fqName: fileName:/enumWithMultipleCtors.kt RETURN type=kotlin.Nothing from='public final fun f (): kotlin.String declared in .A.Y' CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=null $this: CALL 'public open fun f (): kotlin.String declared in .A' type=kotlin.String origin=null - $this: GET_VAR ': . declared in .' type=. origin=null + $this: GET_VAR ': .A.Y declared in .A.Y.f' type=.A.Y origin=null other: CONST String type=kotlin.String value="#Y" ENUM_ENTRY name:Z class: CLASS ENUM_ENTRY name:Z modality:FINAL visibility:local superTypes:[.A] diff --git a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt index 1466fdc0237..24eeeaf43f5 100644 --- a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt +++ b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt @@ -93,12 +93,11 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in .JUnrelatedFoo' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:K4 modality:FINAL visibility:public superTypes:[.JUnrelatedFoo; .IFoo]' - FUN name:foo visibility:public modality:FINAL <> ($this:.K4) returnType:kotlin.String + FUN name:foo visibility:public modality:FINAL <> ($this:.K4) returnType:IrErrorType $this: VALUE_PARAMETER name: type:.K4 BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String declared in .K4' - CALL 'public abstract fun foo (): kotlin.String declared in .IFoo' type=kotlin.String origin=null - $this: GET_VAR ': .K4 declared in .K4.foo' type=.K4 origin=null + RETURN type=kotlin.Nothing from='public final fun foo (): IrErrorType declared in .K4' + ERROR_CALL 'Unresolved reference: #' type=IrErrorType FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/classes/qualifiedSuperCalls.fir.txt b/compiler/testData/ir/irText/classes/qualifiedSuperCalls.fir.txt index f6f16da98dc..41363583194 100644 --- a/compiler/testData/ir/irText/classes/qualifiedSuperCalls.fir.txt +++ b/compiler/testData/ir/irText/classes/qualifiedSuperCalls.fir.txt @@ -59,9 +59,9 @@ FILE fqName: fileName:/qualifiedSuperCalls.kt $this: VALUE_PARAMETER name: type:.CBoth BLOCK_BODY CALL 'public open fun foo (): kotlin.Unit declared in .ILeft' type=kotlin.Unit origin=null - $this: ERROR_CALL 'Unresolved reference: super' type=.ILeft + $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.CBoth origin=null CALL 'public open fun foo (): kotlin.Unit declared in .IRight' type=kotlin.Unit origin=null - $this: ERROR_CALL 'Unresolved reference: super' type=.IRight + $this: GET_VAR ': .CBoth declared in .CBoth.foo' type=.CBoth origin=null PROPERTY name:bar visibility:public modality:FINAL [val] FUN name: visibility:public modality:FINAL <> ($this:.CBoth) returnType:kotlin.Int correspondingProperty: PROPERTY name:bar visibility:public modality:FINAL [val] @@ -70,9 +70,9 @@ FILE fqName: fileName:/qualifiedSuperCalls.kt RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .CBoth' CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public open fun (): kotlin.Int declared in .ILeft' type=kotlin.Int origin=null - $this: ERROR_CALL 'Unresolved reference: super' type=.ILeft + $this: GET_VAR ': .CBoth declared in .CBoth.' type=.CBoth origin=null other: CALL 'public open fun (): kotlin.Int declared in .IRight' type=kotlin.Int origin=null - $this: ERROR_CALL 'Unresolved reference: super' type=.IRight + $this: GET_VAR ': .CBoth declared in .CBoth.' type=.CBoth origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any