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 abstract fun f(): R|kotlin/Unit|
|
||||||
|
|
||||||
public final fun t(): R|kotlin/Unit| {
|
public final fun t(): R|kotlin/Unit| {
|
||||||
super<R|C|>.R|/C.h|()
|
this@R|/A|.super<R|C|>.R|/C.h|()
|
||||||
super<R|C|>.R|/C.x|
|
this@R|/A|.super<R|C|>.R|/C.x|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,10 @@ FILE: abstractSuperCall.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun g(): R|kotlin/Unit| {
|
public final fun g(): R|kotlin/Unit| {
|
||||||
super<R|A|>.R|/A.f|()
|
this@R|/B|.super<R|A|>.R|/A.f|()
|
||||||
super<R|A|>.R|/A.t|()
|
this@R|/B|.super<R|A|>.R|/A.t|()
|
||||||
super<R|A|>.R|/A.x|
|
this@R|/B|.super<R|A|>.R|/A.x|
|
||||||
super<R|A|>.R|/A.y|
|
this@R|/B|.super<R|A|>.R|/A.y|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -52,10 +52,10 @@ FILE: abstractSuperCall.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun r(): R|kotlin/Unit| {
|
public final fun r(): R|kotlin/Unit| {
|
||||||
super<R|A|>.R|/A.f|()
|
this@R|/J|.super<R|A|>.R|/A.f|()
|
||||||
super<R|A|>.R|/A.t|()
|
this@R|/J|.super<R|A|>.R|/A.t|()
|
||||||
super<R|A|>.R|/A.x|
|
this@R|/J|.super<R|A|>.R|/A.x|
|
||||||
super<R|A|>.R|/A.y|
|
this@R|/J|.super<R|A|>.R|/A.y|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ FILE: notASupertype.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun g(): R|kotlin/Unit| {
|
public final fun g(): R|kotlin/Unit| {
|
||||||
super<R|kotlin/String|>.<Unresolved name: f>#()
|
this@R|/B|.super<R|kotlin/String|>.<Unresolved name: f>#()
|
||||||
super<R|A|>.R|/A.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| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
super<R|IBase|>.R|/IBase.foo|()
|
this@R|/Test|.super<R|IBase|>.R|/IBase.foo|()
|
||||||
super<R|IBase|>.R|/IBase.bar|()
|
this@R|/Test|.super<R|IBase|>.R|/IBase.bar|()
|
||||||
super<R|IDerived|>.R|/IDerived.foo|()
|
this@R|/Test|.super<R|IDerived|>.R|/IDerived.foo|()
|
||||||
super<R|IDerived|>.R|/IBase.bar|()
|
this@R|/Test|.super<R|IDerived|>.R|/IBase.bar|()
|
||||||
super<R|IDerived|>.R|/IDerived.qux|()
|
this@R|/Test|.super<R|IDerived|>.R|/IDerived.qux|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -37,13 +37,13 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun test(): R|kotlin/Unit| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
super<R|IBase|>.R|/IBase.foo|()
|
this@R|/Test2|.super<R|IBase|>.R|/IBase.foo|()
|
||||||
super<R|IBase|>.R|/IBase.bar|()
|
this@R|/Test2|.super<R|IBase|>.R|/IBase.bar|()
|
||||||
super<R|AliasedIBase|>.R|/IBase.foo|()
|
this@R|/Test2|.super<R|AliasedIBase|>.R|/IBase.foo|()
|
||||||
super<R|AliasedIBase|>.R|/IBase.bar|()
|
this@R|/Test2|.super<R|AliasedIBase|>.R|/IBase.bar|()
|
||||||
super<R|IDerived|>.R|/IDerived.foo|()
|
this@R|/Test2|.super<R|IDerived|>.R|/IDerived.foo|()
|
||||||
super<R|IDerived|>.R|/IBase.bar|()
|
this@R|/Test2|.super<R|IDerived|>.R|/IBase.bar|()
|
||||||
super<R|IDerived|>.R|/IDerived.qux|()
|
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 abstract interface ATrait : R|A| {
|
||||||
public open override fun foo(): R|kotlin/Unit| {
|
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| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
Q|Outer|.<Inapplicable(HIDDEN): [/Outer.PrivateNested.PrivateNested]>#()
|
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|()
|
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|()
|
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| {
|
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| {
|
public final override fun foo(): R|kotlin/Unit| {
|
||||||
super<R|A|R|B|>.R|/B.foo|()
|
this@R|/C|.super<R|A|R|B|>.R|/B.foo|()
|
||||||
super<R|A|R|B|>.<Ambiguity: bar, [/A.bar, /B.bar]>#()
|
this@R|/C|.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.baz|()
|
||||||
this@R|/C|.R|/A.baz|()
|
this@R|/C|.R|/A.baz|()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,31 +96,6 @@ class Fir2IrConversionScope {
|
|||||||
return irClass.thisReceiver
|
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 lastClass(): IrClass? = classStack.lastOrNull()
|
||||||
|
|
||||||
fun lastSubject(): IrVariable = subjectVariableStack.last()
|
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.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
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.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
||||||
|
|
||||||
@@ -165,21 +162,15 @@ internal class CallAndReferenceGenerator(
|
|||||||
conversionScope
|
conversionScope
|
||||||
)
|
)
|
||||||
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
val dispatchReceiver = qualifiedAccess.dispatchReceiver
|
||||||
if (qualifiedAccess.calleeReference is FirSuperReference) {
|
if (qualifiedAccess.calleeReference is FirSuperReference) {
|
||||||
val superReference = qualifiedAccess.calleeReference as FirSuperReference
|
if (typeRef !is FirComposedSuperTypeRef && dispatchReceiver !is FirNoReceiverExpression) {
|
||||||
if (typeRef !is FirComposedSuperTypeRef) {
|
return@convertWithOffsets visitor.convertToIrExpression(dispatchReceiver)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var superQualifierSymbol: IrClassSymbol? = null
|
var superQualifierSymbol: IrClassSymbol? = null
|
||||||
if (qualifiedAccess.dispatchReceiver is FirQualifiedAccess) {
|
if (dispatchReceiver is FirQualifiedAccess) {
|
||||||
val dispatchReceiverReference = (qualifiedAccess.dispatchReceiver as FirQualifiedAccess).calleeReference
|
val dispatchReceiverReference = dispatchReceiver.calleeReference
|
||||||
if (dispatchReceiverReference is FirSuperReference) {
|
if (dispatchReceiverReference is FirSuperReference) {
|
||||||
val coneSuperType = dispatchReceiverReference.superTypeRef.coneTypeSafe<ConeClassLikeType>()
|
val coneSuperType = dispatchReceiverReference.superTypeRef.coneTypeSafe<ConeClassLikeType>()
|
||||||
(coneSuperType?.lookupTag?.toSymbol(session) as? FirClassSymbol<*>)?.let {
|
(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.symbols.invoke
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.*
|
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.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -81,6 +80,13 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
qualifiedAccessExpression
|
qualifiedAccessExpression
|
||||||
}
|
}
|
||||||
is FirSuperReference -> {
|
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) {
|
when (val superTypeRef = callee.superTypeRef) {
|
||||||
is FirResolvedTypeRef -> {
|
is FirResolvedTypeRef -> {
|
||||||
qualifiedAccessExpression.resultType = superTypeRef
|
qualifiedAccessExpression.resultType = superTypeRef
|
||||||
@@ -90,10 +96,6 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
qualifiedAccessExpression.resultType = callee.superTypeRef
|
qualifiedAccessExpression.resultType = callee.superTypeRef
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val labelName = callee.labelName
|
|
||||||
val implicitReceiver =
|
|
||||||
if (labelName != null) implicitReceiverStack[labelName] as? ImplicitDispatchReceiverValue
|
|
||||||
else implicitReceiverStack.lastDispatchReceiver()
|
|
||||||
val superTypeRefs = implicitReceiver?.boundSymbol?.phasedFir?.superTypeRefs
|
val superTypeRefs = implicitReceiver?.boundSymbol?.phasedFir?.superTypeRefs
|
||||||
val resultType = when {
|
val resultType = when {
|
||||||
superTypeRefs?.isNotEmpty() != true -> {
|
superTypeRefs?.isNotEmpty() != true -> {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
open class A(val value: String) {
|
open class A(val value: String) {
|
||||||
inner class B(val s: String) {
|
inner class B(val s: String) {
|
||||||
val result = value + "_" + s
|
val result = value + "_" + s
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
interface BK {
|
interface BK {
|
||||||
fun foo(): String
|
fun foo(): String
|
||||||
fun bar(): String
|
fun bar(): String
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
//inspired by kt3492
|
//inspired by kt3492
|
||||||
interface BK {
|
interface BK {
|
||||||
fun foo(): String
|
fun foo(): String
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
interface Base {
|
interface Base {
|
||||||
val foo: String
|
val foo: String
|
||||||
fun bar(): String
|
fun bar(): String
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
//inspired by kt3492
|
//inspired by kt3492
|
||||||
interface Base {
|
interface Base {
|
||||||
val foo: String
|
val foo: String
|
||||||
|
|||||||
Reference in New Issue
Block a user