[FIR2IR] Correct 'this' conversion when it points to non-closest class
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
|
||||
class Fir2IrConversionScope {
|
||||
private val parentStack = mutableListOf<IrDeclarationParent>()
|
||||
@@ -76,6 +77,15 @@ class Fir2IrConversionScope {
|
||||
|
||||
fun parent(): IrDeclarationParent? = parentStack.lastOrNull()
|
||||
|
||||
fun dispatchReceiverParameter(irClass: IrClass): IrValueParameter? {
|
||||
for (function in functionStack.asReversed()) {
|
||||
if (function.parentClassOrNull == irClass) {
|
||||
function.dispatchReceiverParameter?.let { return it }
|
||||
}
|
||||
}
|
||||
return irClass.thisReceiver
|
||||
}
|
||||
|
||||
fun lastDispatchReceiverParameter(): IrValueParameter? {
|
||||
// Use the dispatch receiver of the containing/enclosing functions (from the last to the first)
|
||||
for (function in functionStack.asReversed()) {
|
||||
|
||||
@@ -285,21 +285,20 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: Any?): IrElement {
|
||||
val calleeReference = thisReceiverExpression.calleeReference
|
||||
if (calleeReference.labelName == null && calleeReference.boundSymbol is FirClassSymbol) {
|
||||
val boundSymbol = calleeReference.boundSymbol
|
||||
if (calleeReference.labelName == null && boundSymbol is FirClassSymbol) {
|
||||
// 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 = classifierStorage.getCachedIrClass(firObject)!!
|
||||
if (irObject != conversionScope.lastClass()) {
|
||||
val firClass = boundSymbol.fir as FirClass
|
||||
val irClass = classifierStorage.getCachedIrClass(firClass)!!
|
||||
if (firClass is FirAnonymousObject || firClass is FirRegularClass && firClass.classKind == ClassKind.OBJECT) {
|
||||
if (irClass != conversionScope.lastClass()) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol)
|
||||
IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dispatchReceiver = conversionScope.lastDispatchReceiverParameter()
|
||||
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
|
||||
if (dispatchReceiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||
|
||||
Reference in New Issue
Block a user