[FIR2IR] Generate property extension receiver references properly
This commit is contained in:
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
@@ -92,7 +93,8 @@ fun FirClassifierSymbol<*>.toSymbol(
|
||||
fun FirReference.toSymbol(
|
||||
session: FirSession,
|
||||
classifierStorage: Fir2IrClassifierStorage,
|
||||
declarationStorage: Fir2IrDeclarationStorage
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
conversionScope: Fir2IrConversionScope
|
||||
): IrSymbol? {
|
||||
return when (this) {
|
||||
is FirResolvedNamedReference -> {
|
||||
@@ -114,6 +116,10 @@ fun FirReference.toSymbol(
|
||||
when (val boundSymbol = boundSymbol) {
|
||||
is FirClassSymbol<*> -> classifierStorage.getIrClassSymbol(boundSymbol).owner.thisReceiver?.symbol
|
||||
is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner.extensionReceiverParameter?.symbol
|
||||
is FirPropertySymbol -> {
|
||||
val property = declarationStorage.getIrPropertyOrFieldSymbol(boundSymbol).owner as? IrProperty
|
||||
property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) }?.symbol
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,16 @@ class Fir2IrConversionScope {
|
||||
|
||||
fun parentFromStack(): IrDeclarationParent = parentStack.last()
|
||||
|
||||
fun parentAccessorOfPropertyFromStack(property: IrProperty): IrSimpleFunction? {
|
||||
for (parent in parentStack.asReversed()) {
|
||||
when (parent) {
|
||||
property.getter -> return property.getter
|
||||
property.setter -> return property.setter
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun <T : IrDeclaration> applyParentFromStackTo(declaration: T): T {
|
||||
declaration.parent = parentStack.last()
|
||||
return declaration
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.resolve.isIteratorNext
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
@@ -32,10 +33,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
@@ -286,22 +284,32 @@ class Fir2IrVisitor(
|
||||
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: Any?): IrElement {
|
||||
val calleeReference = thisReceiverExpression.calleeReference
|
||||
val boundSymbol = calleeReference.boundSymbol
|
||||
if (calleeReference.labelName == null && boundSymbol is FirClassSymbol) {
|
||||
// Object case
|
||||
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, irClass.defaultType, irClass.symbol)
|
||||
if (calleeReference.labelName == null) {
|
||||
if (boundSymbol is FirClassSymbol) {
|
||||
// Object case
|
||||
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, irClass.defaultType, irClass.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
|
||||
if (dispatchReceiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
|
||||
if (dispatchReceiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||
}
|
||||
}
|
||||
} else if (boundSymbol is FirCallableSymbol) {
|
||||
val receiverSymbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope)
|
||||
val receiver = (receiverSymbol?.owner as? IrSimpleFunction)?.extensionReceiverParameter
|
||||
if (receiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -51,7 +51,7 @@ internal class CallAndReferenceGenerator(
|
||||
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
fun convertToIrCallableReference(callableReferenceAccess: FirCallableReferenceAccess): IrExpression {
|
||||
val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage)
|
||||
val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope)
|
||||
val type = callableReferenceAccess.typeRef.toIrType()
|
||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||
when (symbol) {
|
||||
@@ -147,7 +147,8 @@ internal class CallAndReferenceGenerator(
|
||||
val symbol = qualifiedAccess.calleeReference.toSymbol(
|
||||
session,
|
||||
classifierStorage,
|
||||
declarationStorage
|
||||
declarationStorage,
|
||||
conversionScope
|
||||
)
|
||||
return typeRef.convertWithOffsets { startOffset, endOffset ->
|
||||
if (qualifiedAccess.calleeReference is FirSuperReference) {
|
||||
@@ -192,7 +193,7 @@ internal class CallAndReferenceGenerator(
|
||||
fun convertToIrSetCall(variableAssignment: FirVariableAssignment): IrExpression {
|
||||
val type = irBuiltIns.unitType
|
||||
val calleeReference = variableAssignment.calleeReference
|
||||
val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage)
|
||||
val symbol = calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope)
|
||||
val origin = IrStatementOrigin.EQ
|
||||
return variableAssignment.convertWithOffsets { startOffset, endOffset ->
|
||||
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
||||
|
||||
Reference in New Issue
Block a user