From 38fc4d0f1f96191c8e58c22584001a21354069ea Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 6 May 2020 12:46:28 +0300 Subject: [PATCH] FIR: set & use dispatch receiver for q. access with super reference --- .../resolve/diagnostics/abstractSuperCall.txt | 20 +++++++-------- .../resolve/diagnostics/notASupertype.txt | 4 +-- ...ifiedSupertypeExtendedByOtherSupertype.txt | 24 +++++++++--------- .../superclassNotAccessibleFromInterface.txt | 2 +- .../resolve/expresssions/nestedVisibility.txt | 6 ++--- .../expresssions/protectedVisibility.txt | 2 +- .../testData/resolve/incorrectSuperCall.txt | 6 ++--- .../fir/backend/Fir2IrConversionScope.kt | 25 ------------------- .../generators/CallAndReferenceGenerator.kt | 21 +++++----------- .../FirExpressionsResolveTransformer.kt | 12 +++++---- .../inner/instantiateInDerivedLabeled.kt | 1 - .../box/super/innerClassLabeledSuper.kt | 1 - .../box/super/innerClassLabeledSuper2.kt | 1 - .../super/innerClassLabeledSuperProperty.kt | 1 - .../super/innerClassLabeledSuperProperty2.kt | 1 - 15 files changed, 45 insertions(+), 82 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.txt index 3820afc9ac4..6a5d76015f1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.txt @@ -25,8 +25,8 @@ FILE: abstractSuperCall.kt public abstract fun f(): R|kotlin/Unit| public final fun t(): R|kotlin/Unit| { - super.R|/C.h|() - super.R|/C.x| + this@R|/A|.super.R|/C.h|() + this@R|/A|.super.R|/C.x| } } @@ -39,10 +39,10 @@ FILE: abstractSuperCall.kt } public final fun g(): R|kotlin/Unit| { - super.R|/A.f|() - super.R|/A.t|() - super.R|/A.x| - super.R|/A.y| + this@R|/B|.super.R|/A.f|() + this@R|/B|.super.R|/A.t|() + this@R|/B|.super.R|/A.x| + this@R|/B|.super.R|/A.y| } } @@ -52,10 +52,10 @@ FILE: abstractSuperCall.kt } public final fun r(): R|kotlin/Unit| { - super.R|/A.f|() - super.R|/A.t|() - super.R|/A.x| - super.R|/A.y| + this@R|/J|.super.R|/A.f|() + this@R|/J|.super.R|/A.t|() + this@R|/J|.super.R|/A.x| + this@R|/J|.super.R|/A.y| } } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.txt index 5d41a0582e0..13bf31a9e9e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.txt @@ -14,8 +14,8 @@ FILE: notASupertype.kt } public final fun g(): R|kotlin/Unit| { - super.#() - super.R|/A.f|() + this@R|/B|.super.#() + this@R|/B|.super.R|/A.f|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.txt index 782edfa9c7e..a4c129af390 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.txt @@ -23,11 +23,11 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt } public final fun test(): R|kotlin/Unit| { - super.R|/IBase.foo|() - super.R|/IBase.bar|() - super.R|/IDerived.foo|() - super.R|/IBase.bar|() - super.R|/IDerived.qux|() + this@R|/Test|.super.R|/IBase.foo|() + this@R|/Test|.super.R|/IBase.bar|() + this@R|/Test|.super.R|/IDerived.foo|() + this@R|/Test|.super.R|/IBase.bar|() + this@R|/Test|.super.R|/IDerived.qux|() } } @@ -37,13 +37,13 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt } public final fun test(): R|kotlin/Unit| { - super.R|/IBase.foo|() - super.R|/IBase.bar|() - super.R|/IBase.foo|() - super.R|/IBase.bar|() - super.R|/IDerived.foo|() - super.R|/IBase.bar|() - super.R|/IDerived.qux|() + this@R|/Test2|.super.R|/IBase.foo|() + this@R|/Test2|.super.R|/IBase.bar|() + this@R|/Test2|.super.R|/IBase.foo|() + this@R|/Test2|.super.R|/IBase.bar|() + this@R|/Test2|.super.R|/IDerived.foo|() + this@R|/Test2|.super.R|/IBase.bar|() + this@R|/Test2|.super.R|/IDerived.qux|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.txt index 7d7157c95d9..06412dbc359 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/superclassNotAccessibleFromInterface.txt @@ -10,7 +10,7 @@ FILE: superclassNotAccessibleFromInterface.kt } public abstract interface ATrait : R|A| { public open override fun foo(): R|kotlin/Unit| { - super.R|/A.foo|() + this@R|/ATrait|.super.R|/A.foo|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt index 3c96308f742..81b2fb57feb 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/nestedVisibility.txt @@ -54,11 +54,11 @@ FILE: nestedVisibility.kt public final fun foo(): R|kotlin/Unit| { Q|Outer|.#() - super.#() + this@R|/Derived|.super.#() Q|Outer|.R|/Outer.ProtectedNested.ProtectedNested|() - super.R|/Outer.ProtectedInner.ProtectedInner|() + this@R|/Derived|.super.R|/Outer.ProtectedInner.ProtectedInner|() Q|Outer|.R|/Outer.PublicNested.PublicNested|() - super.R|/Outer.PublicInner.PublicInner|() + this@R|/Derived|.super.R|/Outer.PublicInner.PublicInner|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt index fc03a4b2fd2..d74b2d7669a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt @@ -101,7 +101,7 @@ FILE: protectedVisibility.kt } public final override fun foo(): R|kotlin/Int| { - ^foo super|>.R|FakeOverride|() + ^foo this@R|/DerivedGeneric|.super|>.R|FakeOverride|() } } diff --git a/compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.txt b/compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.txt index 1cf0d2252fd..57a44c195d0 100644 --- a/compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.txt +++ b/compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.txt @@ -27,9 +27,9 @@ FILE: incorrectSuperCall.kt } public final override fun foo(): R|kotlin/Unit| { - super.R|/B.foo|() - super.#() - super.R|/B.baz|() + this@R|/C|.super.R|/B.foo|() + this@R|/C|.super.#() + this@R|/C|.super.R|/B.baz|() this@R|/C|.R|/A.baz|() } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index 3c29ae3f866..393bc56eb23 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -96,31 +96,6 @@ class Fir2IrConversionScope { return irClass.thisReceiver } - fun dispatchReceiverParameter(label: String): IrValueParameter? { - for (function in functionStack.asReversed()) { - if (!function.name.isSpecial && function.name.identifier == label) { - function.dispatchReceiverParameter?.let { return it } - } - } - for (irClass in classStack.asReversed()) { - if (!irClass.name.isSpecial && irClass.name.identifier == label) { - return irClass.thisReceiver - } - } - return null - } - - fun lastDispatchReceiverParameter(): IrValueParameter? { - // Use the dispatch receiver of the containing/enclosing functions (from the last to the first) - for (function in functionStack.asReversed()) { - function.dispatchReceiverParameter?.let { return it } - } - - // Use the dispatch receiver of the containing class - val lastClass = classStack.lastOrNull() - return lastClass?.thisReceiver - } - fun lastClass(): IrClass? = classStack.lastOrNull() fun lastSubject(): IrVariable = subjectVariableStack.last() diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index a341e70bf00..1a521217f50 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -30,10 +30,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrNull -import org.jetbrains.kotlin.ir.types.makeNotNull -import org.jetbrains.kotlin.ir.types.makeNullable +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects @@ -165,21 +162,15 @@ internal class CallAndReferenceGenerator( conversionScope ) return typeRef.convertWithOffsets { startOffset, endOffset -> + val dispatchReceiver = qualifiedAccess.dispatchReceiver if (qualifiedAccess.calleeReference is FirSuperReference) { - val superReference = qualifiedAccess.calleeReference as FirSuperReference - if (typeRef !is FirComposedSuperTypeRef) { - val label = superReference.labelName - val dispatchReceiver = - if (label != null) conversionScope.dispatchReceiverParameter(label) - else conversionScope.lastDispatchReceiverParameter() - if (dispatchReceiver != null) { - return@convertWithOffsets IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol) - } + if (typeRef !is FirComposedSuperTypeRef && dispatchReceiver !is FirNoReceiverExpression) { + return@convertWithOffsets visitor.convertToIrExpression(dispatchReceiver) } } var superQualifierSymbol: IrClassSymbol? = null - if (qualifiedAccess.dispatchReceiver is FirQualifiedAccess) { - val dispatchReceiverReference = (qualifiedAccess.dispatchReceiver as FirQualifiedAccess).calleeReference + if (dispatchReceiver is FirQualifiedAccess) { + val dispatchReceiverReference = dispatchReceiver.calleeReference if (dispatchReceiverReference is FirSuperReference) { val coneSuperType = dispatchReceiverReference.superTypeRef.coneTypeSafe() (coneSuperType?.lookupTag?.toSymbol(session) as? FirClassSymbol<*>)?.let { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 7de7d7de330..63b83593784 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -35,7 +35,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.invoke import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.* -import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -81,6 +80,13 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : qualifiedAccessExpression } is FirSuperReference -> { + val labelName = callee.labelName + val implicitReceiver = + if (labelName != null) implicitReceiverStack[labelName] as? ImplicitDispatchReceiverValue + else implicitReceiverStack.lastDispatchReceiver() + implicitReceiver?.receiverExpression?.let { + qualifiedAccessExpression.transformDispatchReceiver(StoreReceiver, it) + } when (val superTypeRef = callee.superTypeRef) { is FirResolvedTypeRef -> { qualifiedAccessExpression.resultType = superTypeRef @@ -90,10 +96,6 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : qualifiedAccessExpression.resultType = callee.superTypeRef } else -> { - val labelName = callee.labelName - val implicitReceiver = - if (labelName != null) implicitReceiverStack[labelName] as? ImplicitDispatchReceiverValue - else implicitReceiverStack.lastDispatchReceiver() val superTypeRefs = implicitReceiver?.boundSymbol?.phasedFir?.superTypeRefs val resultType = when { superTypeRefs?.isNotEmpty() != true -> { diff --git a/compiler/testData/codegen/box/classes/inner/instantiateInDerivedLabeled.kt b/compiler/testData/codegen/box/classes/inner/instantiateInDerivedLabeled.kt index 30a36b1506a..34db2545d47 100644 --- a/compiler/testData/codegen/box/classes/inner/instantiateInDerivedLabeled.kt +++ b/compiler/testData/codegen/box/classes/inner/instantiateInDerivedLabeled.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR open class A(val value: String) { inner class B(val s: String) { val result = value + "_" + s diff --git a/compiler/testData/codegen/box/super/innerClassLabeledSuper.kt b/compiler/testData/codegen/box/super/innerClassLabeledSuper.kt index e48977e31c1..cbb0a875df9 100644 --- a/compiler/testData/codegen/box/super/innerClassLabeledSuper.kt +++ b/compiler/testData/codegen/box/super/innerClassLabeledSuper.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR interface BK { fun foo(): String fun bar(): String diff --git a/compiler/testData/codegen/box/super/innerClassLabeledSuper2.kt b/compiler/testData/codegen/box/super/innerClassLabeledSuper2.kt index 2de78ff0e27..1a0bca8c437 100644 --- a/compiler/testData/codegen/box/super/innerClassLabeledSuper2.kt +++ b/compiler/testData/codegen/box/super/innerClassLabeledSuper2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR //inspired by kt3492 interface BK { fun foo(): String diff --git a/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty.kt b/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty.kt index 4c1f0a54b75..bb8098564f6 100644 --- a/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty.kt +++ b/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR interface Base { val foo: String fun bar(): String diff --git a/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty2.kt b/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty2.kt index 0f6fbf2d06d..effc71e7925 100644 --- a/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty2.kt +++ b/compiler/testData/codegen/box/super/innerClassLabeledSuperProperty2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR //inspired by kt3492 interface Base { val foo: String