[FIR2IR] Get rid of IrSymbol.owner usages in generation of delegated bodies in DelegatedMemberGenerator
^KT-60924
This commit is contained in:
committed by
Space Team
parent
4164c0f7ef
commit
3a9567ad45
+80
-29
@@ -17,15 +17,15 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
|
|
||||||
import org.jetbrains.kotlin.fir.types.resolvedType
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
|
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
@@ -56,27 +56,37 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
private val bodiesInfo = mutableListOf<DeclarationBodyInfo>()
|
||||||
|
|
||||||
fun generateBodies() {
|
fun generateBodies() {
|
||||||
for ((declaration, irField, delegateToSymbol, delegateToLookupTag) in bodiesInfo) {
|
for ((declaration, irField, delegateToFirSymbol, delegateToLookupTag) in bodiesInfo) {
|
||||||
val callTypeCanBeNullable = Fir2IrImplicitCastInserter.typeCanBeEnhancedOrFlexibleNullable(delegateToSymbol.fir.returnTypeRef.coneType.fullyExpandedType(session))
|
val delegatedDeclarationType = delegateToFirSymbol.fir.returnTypeRef.coneType.fullyExpandedType(session)
|
||||||
|
val callTypeCanBeNullable = Fir2IrImplicitCastInserter.typeCanBeEnhancedOrFlexibleNullable(delegatedDeclarationType)
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is IrSimpleFunction -> {
|
is IrSimpleFunction -> {
|
||||||
@OptIn(IrSymbolInternals::class)
|
val delegateToIrFunctionSymbol = declarationStorage.getIrFunctionSymbol(
|
||||||
val member = declarationStorage.getIrFunctionSymbol(
|
delegateToFirSymbol as FirNamedFunctionSymbol, delegateToLookupTag
|
||||||
delegateToSymbol as FirNamedFunctionSymbol, delegateToLookupTag
|
) as? IrSimpleFunctionSymbol ?: continue
|
||||||
).owner as? IrSimpleFunction ?: continue
|
val body = createDelegateBody(
|
||||||
val body = createDelegateBody(irField, declaration, member, callTypeCanBeNullable)
|
irField, declaration, delegateToFirSymbol.fir, delegateToIrFunctionSymbol,
|
||||||
|
callTypeCanBeNullable, isSetter = false
|
||||||
|
)
|
||||||
declaration.body = body
|
declaration.body = body
|
||||||
}
|
}
|
||||||
is IrProperty -> {
|
is IrProperty -> {
|
||||||
@OptIn(IrSymbolInternals::class)
|
val delegateToIrPropertySymbol = declarationStorage.getIrPropertySymbol(
|
||||||
val member = declarationStorage.getIrPropertySymbol(
|
delegateToFirSymbol as FirPropertySymbol, delegateToLookupTag
|
||||||
delegateToSymbol as FirPropertySymbol, delegateToLookupTag
|
) as? IrPropertySymbol ?: continue
|
||||||
).owner as? IrProperty ?: continue
|
val delegateToGetterSymbol = declarationStorage.findGetterOfProperty(delegateToIrPropertySymbol)!!
|
||||||
val getter = declaration.getter!!
|
val getter = declaration.getter!!
|
||||||
getter.body = createDelegateBody(irField, getter, member.getter!!, callTypeCanBeNullable)
|
getter.body = createDelegateBody(
|
||||||
|
irField, getter, delegateToFirSymbol.fir, delegateToGetterSymbol,
|
||||||
|
callTypeCanBeNullable, isSetter = false
|
||||||
|
)
|
||||||
if (declaration.isVar) {
|
if (declaration.isVar) {
|
||||||
|
val delegateToSetterSymbol = declarationStorage.findSetterOfProperty(delegateToIrPropertySymbol)!!
|
||||||
val setter = declaration.setter!!
|
val setter = declaration.setter!!
|
||||||
setter.body = createDelegateBody(irField, setter, member.setter!!, false)
|
setter.body = createDelegateBody(
|
||||||
|
irField, setter, delegateToFirSymbol.fir, delegateToSetterSymbol,
|
||||||
|
callTypeCanBeNullable = false, isSetter = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,22 +232,51 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
return delegateFunction
|
return delegateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interface Base {
|
||||||
|
* fun foo(): String
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* class Impl : Base {
|
||||||
|
* override fun foo(): String { <-------------- [originalFirFunction], [originalFunctionSymbol]
|
||||||
|
* return "OK"
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* class Delegated(impl: Impl) : Base by impl {
|
||||||
|
* private field delegate_xxx: Impl = impl <-------------- [irField]
|
||||||
|
* generated override fun foo(): String <-------------- [delegateFunction]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
private fun createDelegateBody(
|
private fun createDelegateBody(
|
||||||
irField: IrField,
|
irField: IrField,
|
||||||
delegateFunction: IrSimpleFunction,
|
delegateFunction: IrSimpleFunction,
|
||||||
superFunction: IrSimpleFunction,
|
originalFirDeclaration: FirCallableDeclaration,
|
||||||
callTypeCanBeNullable: Boolean
|
originalFunctionSymbol: IrSimpleFunctionSymbol,
|
||||||
|
callTypeCanBeNullable: Boolean,
|
||||||
|
isSetter: Boolean
|
||||||
): IrBlockBody {
|
): IrBlockBody {
|
||||||
val startOffset = SYNTHETIC_OFFSET
|
val startOffset = SYNTHETIC_OFFSET
|
||||||
val endOffset = SYNTHETIC_OFFSET
|
val endOffset = SYNTHETIC_OFFSET
|
||||||
val body = irFactory.createBlockBody(startOffset, endOffset)
|
val body = irFactory.createBlockBody(startOffset, endOffset)
|
||||||
|
val typeOrigin = when {
|
||||||
|
originalFirDeclaration is FirPropertyAccessor && originalFirDeclaration.isSetter -> ConversionTypeOrigin.SETTER
|
||||||
|
else -> ConversionTypeOrigin.DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
|
val callReturnType = when (isSetter) {
|
||||||
|
false -> originalFirDeclaration.returnTypeRef.toIrType(typeOrigin)
|
||||||
|
true -> irBuiltIns.unitType
|
||||||
|
}
|
||||||
|
|
||||||
val irCall = IrCallImpl(
|
val irCall = IrCallImpl(
|
||||||
startOffset,
|
startOffset,
|
||||||
endOffset,
|
endOffset,
|
||||||
superFunction.returnType,
|
callReturnType,
|
||||||
superFunction.symbol,
|
originalFunctionSymbol,
|
||||||
superFunction.typeParameters.size,
|
originalFirDeclaration.typeParameters.size,
|
||||||
superFunction.valueParameters.size
|
originalFirDeclaration.numberOfIrValueParameters(isSetter)
|
||||||
).apply {
|
).apply {
|
||||||
val getField = IrGetFieldImpl(
|
val getField = IrGetFieldImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
@@ -252,11 +291,13 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
|
|
||||||
// When the delegation expression has an intersection type, it is not guaranteed that the field will have the same type as the
|
// When the delegation expression has an intersection type, it is not guaranteed that the field will have the same type as the
|
||||||
// dispatch receiver of the target method. Therefore, we need to check if a cast must be inserted.
|
// dispatch receiver of the target method. Therefore, we need to check if a cast must be inserted.
|
||||||
val superFunctionParent = superFunction.parent as? IrClass
|
val superFunctionDispatchReceiverType = originalFirDeclaration.dispatchReceiverType
|
||||||
dispatchReceiver = if (superFunctionParent == null || irField.type.isSubtypeOfClass(superFunctionParent.symbol)) {
|
val superFunctionDispatchReceiverLookupTag = (superFunctionDispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||||
|
val superFunctionParentSymbol = superFunctionDispatchReceiverLookupTag?.let { classifierStorage.findIrClass(it)?.symbol }
|
||||||
|
dispatchReceiver = if (superFunctionParentSymbol == null || irField.type.isSubtypeOfClass(superFunctionParentSymbol)) {
|
||||||
getField
|
getField
|
||||||
} else {
|
} else {
|
||||||
Fir2IrImplicitCastInserter.implicitCastOrExpression(getField, superFunction.dispatchReceiverParameter!!.type)
|
Fir2IrImplicitCastInserter.implicitCastOrExpression(getField, superFunctionDispatchReceiverType.toIrType())
|
||||||
}
|
}
|
||||||
|
|
||||||
extensionReceiver =
|
extensionReceiver =
|
||||||
@@ -266,10 +307,10 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
delegateFunction.valueParameters.forEach {
|
delegateFunction.valueParameters.forEach {
|
||||||
putValueArgument(it.index, IrGetValueImpl(startOffset, endOffset, it.type, it.symbol))
|
putValueArgument(it.index, IrGetValueImpl(startOffset, endOffset, it.type, it.symbol))
|
||||||
}
|
}
|
||||||
superFunction.typeParameters.forEach {
|
for (index in originalFirDeclaration.typeParameters.indices) {
|
||||||
putTypeArgument(
|
putTypeArgument(
|
||||||
it.index, IrSimpleTypeImpl(
|
index, IrSimpleTypeImpl(
|
||||||
delegateFunction.typeParameters[it.index].symbol,
|
delegateFunction.typeParameters[index].symbol,
|
||||||
hasQuestionMark = false,
|
hasQuestionMark = false,
|
||||||
arguments = emptyList(),
|
arguments = emptyList(),
|
||||||
annotations = emptyList()
|
annotations = emptyList()
|
||||||
@@ -282,7 +323,8 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
val irCastOrCall =
|
val irCastOrCall =
|
||||||
if (callTypeCanBeNullable && !resultType.isNullable()) Fir2IrImplicitCastInserter.implicitNotNullCast(irCall)
|
if (callTypeCanBeNullable && !resultType.isNullable()) Fir2IrImplicitCastInserter.implicitNotNullCast(irCall)
|
||||||
else irCall
|
else irCall
|
||||||
if (superFunction.returnType.isUnit() || superFunction.returnType.isNothing()) {
|
val originalDeclarationReturnType = originalFirDeclaration.returnTypeRef.coneType
|
||||||
|
if (isSetter || originalDeclarationReturnType.isUnit || originalDeclarationReturnType.isNothing) {
|
||||||
body.statements.add(irCastOrCall)
|
body.statements.add(irCastOrCall)
|
||||||
} else {
|
} else {
|
||||||
val irReturn = IrReturnImpl(startOffset, endOffset, irBuiltIns.nothingType, delegateFunction.symbol, irCastOrCall)
|
val irReturn = IrReturnImpl(startOffset, endOffset, irBuiltIns.nothingType, delegateFunction.symbol, irCastOrCall)
|
||||||
@@ -291,6 +333,15 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirCallableDeclaration.numberOfIrValueParameters(isSetter: Boolean): Int {
|
||||||
|
var result = contextReceivers.size
|
||||||
|
when {
|
||||||
|
this is FirFunction -> result += valueParameters.size
|
||||||
|
this is FirProperty && isSetter -> result += 1
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateDelegatedProperty(
|
private fun generateDelegatedProperty(
|
||||||
subClass: IrClass,
|
subClass: IrClass,
|
||||||
firSubClass: FirClass,
|
firSubClass: FirClass,
|
||||||
|
|||||||
Reference in New Issue
Block a user