FIR: set & use dispatch receiver for q. access with super reference
This commit is contained in:
+10
-10
@@ -25,8 +25,8 @@ FILE: abstractSuperCall.kt
|
||||
public abstract fun f(): R|kotlin/Unit|
|
||||
|
||||
public final fun t(): R|kotlin/Unit| {
|
||||
super<R|C|>.R|/C.h|()
|
||||
super<R|C|>.R|/C.x|
|
||||
this@R|/A|.super<R|C|>.R|/C.h|()
|
||||
this@R|/A|.super<R|C|>.R|/C.x|
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,10 +39,10 @@ FILE: abstractSuperCall.kt
|
||||
}
|
||||
|
||||
public final fun g(): R|kotlin/Unit| {
|
||||
super<R|A|>.R|/A.f|()
|
||||
super<R|A|>.R|/A.t|()
|
||||
super<R|A|>.R|/A.x|
|
||||
super<R|A|>.R|/A.y|
|
||||
this@R|/B|.super<R|A|>.R|/A.f|()
|
||||
this@R|/B|.super<R|A|>.R|/A.t|()
|
||||
this@R|/B|.super<R|A|>.R|/A.x|
|
||||
this@R|/B|.super<R|A|>.R|/A.y|
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,10 +52,10 @@ FILE: abstractSuperCall.kt
|
||||
}
|
||||
|
||||
public final fun r(): R|kotlin/Unit| {
|
||||
super<R|A|>.R|/A.f|()
|
||||
super<R|A|>.R|/A.t|()
|
||||
super<R|A|>.R|/A.x|
|
||||
super<R|A|>.R|/A.y|
|
||||
this@R|/J|.super<R|A|>.R|/A.f|()
|
||||
this@R|/J|.super<R|A|>.R|/A.t|()
|
||||
this@R|/J|.super<R|A|>.R|/A.x|
|
||||
this@R|/J|.super<R|A|>.R|/A.y|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ FILE: notASupertype.kt
|
||||
}
|
||||
|
||||
public final fun g(): R|kotlin/Unit| {
|
||||
super<R|kotlin/String|>.<Unresolved name: f>#()
|
||||
super<R|A|>.R|/A.f|()
|
||||
this@R|/B|.super<R|kotlin/String|>.<Unresolved name: f>#()
|
||||
this@R|/B|.super<R|A|>.R|/A.f|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-12
@@ -23,11 +23,11 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
|
||||
}
|
||||
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
super<R|IBase|>.R|/IBase.foo|()
|
||||
super<R|IBase|>.R|/IBase.bar|()
|
||||
super<R|IDerived|>.R|/IDerived.foo|()
|
||||
super<R|IDerived|>.R|/IBase.bar|()
|
||||
super<R|IDerived|>.R|/IDerived.qux|()
|
||||
this@R|/Test|.super<R|IBase|>.R|/IBase.foo|()
|
||||
this@R|/Test|.super<R|IBase|>.R|/IBase.bar|()
|
||||
this@R|/Test|.super<R|IDerived|>.R|/IDerived.foo|()
|
||||
this@R|/Test|.super<R|IDerived|>.R|/IBase.bar|()
|
||||
this@R|/Test|.super<R|IDerived|>.R|/IDerived.qux|()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,13 +37,13 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
|
||||
}
|
||||
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
super<R|IBase|>.R|/IBase.foo|()
|
||||
super<R|IBase|>.R|/IBase.bar|()
|
||||
super<R|AliasedIBase|>.R|/IBase.foo|()
|
||||
super<R|AliasedIBase|>.R|/IBase.bar|()
|
||||
super<R|IDerived|>.R|/IDerived.foo|()
|
||||
super<R|IDerived|>.R|/IBase.bar|()
|
||||
super<R|IDerived|>.R|/IDerived.qux|()
|
||||
this@R|/Test2|.super<R|IBase|>.R|/IBase.foo|()
|
||||
this@R|/Test2|.super<R|IBase|>.R|/IBase.bar|()
|
||||
this@R|/Test2|.super<R|AliasedIBase|>.R|/IBase.foo|()
|
||||
this@R|/Test2|.super<R|AliasedIBase|>.R|/IBase.bar|()
|
||||
this@R|/Test2|.super<R|IDerived|>.R|/IDerived.foo|()
|
||||
this@R|/Test2|.super<R|IDerived|>.R|/IBase.bar|()
|
||||
this@R|/Test2|.super<R|IDerived|>.R|/IDerived.qux|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ FILE: superclassNotAccessibleFromInterface.kt
|
||||
}
|
||||
public abstract interface ATrait : R|A| {
|
||||
public open override fun foo(): R|kotlin/Unit| {
|
||||
super<R|A|>.R|/A.foo|()
|
||||
this@R|/ATrait|.super<R|A|>.R|/A.foo|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -54,11 +54,11 @@ FILE: nestedVisibility.kt
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
Q|Outer|.<Inapplicable(HIDDEN): [/Outer.PrivateNested.PrivateNested]>#()
|
||||
super<R|Outer|>.<Inapplicable(HIDDEN): [/Outer.PrivateInner.PrivateInner]>#()
|
||||
this@R|/Derived|.super<R|Outer|>.<Inapplicable(HIDDEN): [/Outer.PrivateInner.PrivateInner]>#()
|
||||
Q|Outer|.R|/Outer.ProtectedNested.ProtectedNested|()
|
||||
super<R|Outer|>.R|/Outer.ProtectedInner.ProtectedInner|()
|
||||
this@R|/Derived|.super<R|Outer|>.R|/Outer.ProtectedInner.ProtectedInner|()
|
||||
Q|Outer|.R|/Outer.PublicNested.PublicNested|()
|
||||
super<R|Outer|>.R|/Outer.PublicInner.PublicInner|()
|
||||
this@R|/Derived|.super<R|Outer|>.R|/Outer.PublicInner.PublicInner|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ FILE: protectedVisibility.kt
|
||||
}
|
||||
|
||||
public final override fun foo(): R|kotlin/Int| {
|
||||
^foo super<R|Generic<kotlin/Int>|>.R|FakeOverride</Generic.foo: R|kotlin/Int|>|()
|
||||
^foo this@R|/DerivedGeneric|.super<R|Generic<kotlin/Int>|>.R|FakeOverride</Generic.foo: R|kotlin/Int|>|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ FILE: incorrectSuperCall.kt
|
||||
}
|
||||
|
||||
public final override fun foo(): R|kotlin/Unit| {
|
||||
super<R|A|R|B|>.R|/B.foo|()
|
||||
super<R|A|R|B|>.<Ambiguity: bar, [/A.bar, /B.bar]>#()
|
||||
super<R|A|R|B|>.R|/B.baz|()
|
||||
this@R|/C|.super<R|A|R|B|>.R|/B.foo|()
|
||||
this@R|/C|.super<R|A|R|B|>.<Ambiguity: bar, [/A.bar, /B.bar]>#()
|
||||
this@R|/C|.super<R|A|R|B|>.R|/B.baz|()
|
||||
this@R|/C|.R|/A.baz|()
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
+6
-15
@@ -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<ConeClassLikeType>()
|
||||
(coneSuperType?.lookupTag?.toSymbol(session) as? FirClassSymbol<*>)?.let {
|
||||
|
||||
+7
-5
@@ -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 -> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface BK {
|
||||
fun foo(): String
|
||||
fun bar(): String
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
//inspired by kt3492
|
||||
interface BK {
|
||||
fun foo(): String
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
interface Base {
|
||||
val foo: String
|
||||
fun bar(): String
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
//inspired by kt3492
|
||||
interface Base {
|
||||
val foo: String
|
||||
|
||||
Reference in New Issue
Block a user