[FIR] Don't create member function for each when and try expression
Use one function (per session) instead
This commit is contained in:
@@ -26,8 +26,7 @@ interface SyntheticSymbol : ConeSymbol
|
|||||||
class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol
|
class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol
|
||||||
|
|
||||||
class FirSyntheticFunctionSymbol(
|
class FirSyntheticFunctionSymbol(
|
||||||
callableId: CallableId,
|
callableId: CallableId
|
||||||
val file: FirFile
|
|
||||||
) : FirNamedFunctionSymbol(callableId), SyntheticSymbol
|
) : FirNamedFunctionSymbol(callableId), SyntheticSymbol
|
||||||
|
|
||||||
class FirSyntheticPropertiesScope(
|
class FirSyntheticPropertiesScope(
|
||||||
|
|||||||
+31
-46
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
|||||||
import org.jetbrains.kotlin.fir.references.FirStubReference
|
import org.jetbrains.kotlin.fir.references.FirStubReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.SyntheticCallableId
|
import org.jetbrains.kotlin.fir.symbols.SyntheticCallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
@@ -31,14 +32,19 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransformer) : BodyResolveComponents by transformer {
|
class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransformer) : BodyResolveComponents by transformer {
|
||||||
|
private val whenSelectFunction: FirMemberFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.WHEN)
|
||||||
|
private val trySelectFunction: FirMemberFunctionImpl = generateSyntheticSelectFunction(SyntheticCallableId.TRY)
|
||||||
|
|
||||||
fun generateCalleeForWhenExpression(whenExpression: FirWhenExpression): FirWhenExpression? {
|
fun generateCalleeForWhenExpression(whenExpression: FirWhenExpression): FirWhenExpression? {
|
||||||
val stubReference = whenExpression.calleeReference
|
val stubReference = whenExpression.calleeReference
|
||||||
assert(stubReference is FirStubReference)
|
assert(stubReference is FirStubReference)
|
||||||
|
|
||||||
val function = generateWhenCallDeclaration()
|
|
||||||
|
|
||||||
val arguments = whenExpression.branches.map { it.result }
|
val arguments = whenExpression.branches.map { it.result }
|
||||||
val reference = generateCalleeReferenceWithCandidate(function, arguments, SyntheticCallableId.WHEN.callableName) ?: return null // TODO
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
whenSelectFunction,
|
||||||
|
arguments,
|
||||||
|
SyntheticCallableId.WHEN.callableName
|
||||||
|
) ?: return null // TODO
|
||||||
|
|
||||||
return whenExpression.copy(calleeReference = reference)
|
return whenExpression.copy(calleeReference = reference)
|
||||||
}
|
}
|
||||||
@@ -47,61 +53,24 @@ class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransform
|
|||||||
val stubReference = tryExpression.calleeReference
|
val stubReference = tryExpression.calleeReference
|
||||||
assert(stubReference is FirStubReference)
|
assert(stubReference is FirStubReference)
|
||||||
|
|
||||||
val function = generateTryCallDeclaration(tryExpression)
|
|
||||||
val arguments = mutableListOf<FirExpression>()
|
val arguments = mutableListOf<FirExpression>()
|
||||||
|
|
||||||
with(tryExpression) {
|
with(tryExpression) {
|
||||||
arguments += tryBlock
|
arguments += tryBlock
|
||||||
catches.map {
|
catches.forEach {
|
||||||
arguments += it.block
|
arguments += it.block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val reference = generateCalleeReferenceWithCandidate(function, arguments, SyntheticCallableId.TRY.callableName) ?: return null // TODO
|
val reference = generateCalleeReferenceWithCandidate(
|
||||||
|
trySelectFunction,
|
||||||
|
arguments,
|
||||||
|
SyntheticCallableId.TRY.callableName
|
||||||
|
) ?: return null // TODO
|
||||||
|
|
||||||
return tryExpression.copy(calleeReference = reference)
|
return tryExpression.copy(calleeReference = reference)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTryCallDeclaration(tryExpression: FirTryExpression): FirMemberFunctionImpl {
|
|
||||||
val functionSymbol = FirSyntheticFunctionSymbol(SyntheticCallableId.TRY, file)
|
|
||||||
val typeParameterSymbol = FirTypeParameterSymbol()
|
|
||||||
val typeParameter = FirTypeParameterImpl(session, null, typeParameterSymbol, Name.identifier("K"), Variance.INVARIANT, false)
|
|
||||||
|
|
||||||
val returnType = FirResolvedTypeRefImpl(null, ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false))
|
|
||||||
|
|
||||||
val tryType = FirResolvedTypeRefImpl(null, returnType.coneTypeUnsafe())
|
|
||||||
val catchTypes = tryExpression.catches.map {
|
|
||||||
FirResolvedTypeRefImpl(null, returnType.coneTypeUnsafe())
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeArgument = FirTypeProjectionWithVarianceImpl(null, Variance.INVARIANT, returnType)
|
|
||||||
|
|
||||||
return generateMemberFunction(session, functionSymbol, SyntheticCallableId.TRY.callableName, typeArgument.typeRef).apply {
|
|
||||||
typeParameters += typeParameter
|
|
||||||
|
|
||||||
valueParameters += tryType.toValueParameter(session, "tryBlock")
|
|
||||||
catchTypes.forEachIndexed { i, type ->
|
|
||||||
valueParameters += type.toValueParameter(session, "catchBlock_$i")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateWhenCallDeclaration(): FirMemberFunctionImpl {
|
|
||||||
val functionSymbol = FirSyntheticFunctionSymbol(SyntheticCallableId.WHEN, file)
|
|
||||||
val typeParameterSymbol = FirTypeParameterSymbol()
|
|
||||||
val typeParameter = FirTypeParameterImpl(session, null, typeParameterSymbol, Name.identifier("K"), Variance.INVARIANT, false)
|
|
||||||
|
|
||||||
val returnType = FirResolvedTypeRefImpl(null, ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false))
|
|
||||||
val branchType = FirResolvedTypeRefImpl(null, returnType.coneTypeUnsafe<ConeKotlinType>().createArrayOf(session))
|
|
||||||
|
|
||||||
val typeArgument = FirTypeProjectionWithVarianceImpl(null, Variance.INVARIANT, returnType)
|
|
||||||
|
|
||||||
return generateMemberFunction(session, functionSymbol, SyntheticCallableId.WHEN.callableName, typeArgument.typeRef).apply {
|
|
||||||
typeParameters += typeParameter
|
|
||||||
valueParameters += branchType.toValueParameter(session, "branches", true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateCalleeReferenceWithCandidate(
|
private fun generateCalleeReferenceWithCandidate(
|
||||||
function: FirMemberFunctionImpl,
|
function: FirMemberFunctionImpl,
|
||||||
arguments: List<FirExpression>,
|
arguments: List<FirExpression>,
|
||||||
@@ -136,6 +105,22 @@ class FirSyntheticCallGenerator(private val transformer: FirBodyResolveTransform
|
|||||||
container = container
|
container = container
|
||||||
) { it.resultType }
|
) { it.resultType }
|
||||||
|
|
||||||
|
private fun generateSyntheticSelectFunction(callableId: CallableId): FirMemberFunctionImpl {
|
||||||
|
val functionSymbol = FirSyntheticFunctionSymbol(callableId)
|
||||||
|
val typeParameterSymbol = FirTypeParameterSymbol()
|
||||||
|
val typeParameter = FirTypeParameterImpl(session, null, typeParameterSymbol, Name.identifier("K"), Variance.INVARIANT, false)
|
||||||
|
|
||||||
|
val returnType = FirResolvedTypeRefImpl(null, ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false))
|
||||||
|
|
||||||
|
val argumentType = FirResolvedTypeRefImpl(null, returnType.coneTypeUnsafe<ConeKotlinType>().createArrayOf(session))
|
||||||
|
val typeArgument = FirTypeProjectionWithVarianceImpl(null, Variance.INVARIANT, returnType)
|
||||||
|
|
||||||
|
return generateMemberFunction(session, functionSymbol, callableId.callableName, typeArgument.typeRef).apply {
|
||||||
|
typeParameters += typeParameter
|
||||||
|
valueParameters += argumentType.toValueParameter(session, "branches", isVararg = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateMemberFunction(session: FirSession, symbol: FirNamedFunctionSymbol, name: Name, returnType: FirTypeRef) =
|
private fun generateMemberFunction(session: FirSession, symbol: FirNamedFunctionSymbol, name: Name, returnType: FirTypeRef) =
|
||||||
FirMemberFunctionImpl(
|
FirMemberFunctionImpl(
|
||||||
session = session,
|
session = session,
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ fun <D> AbstractFirBasedSymbol<D>.phasedFir(
|
|||||||
if (availablePhase < requiredPhase) {
|
if (availablePhase < requiredPhase) {
|
||||||
val provider = FirProvider.getInstance(session)
|
val provider = FirProvider.getInstance(session)
|
||||||
val containingFile = when (this) {
|
val containingFile = when (this) {
|
||||||
is FirSyntheticFunctionSymbol -> file
|
|
||||||
is ConeCallableSymbol -> provider.getFirCallableContainerFile(this)
|
is ConeCallableSymbol -> provider.getFirCallableContainerFile(this)
|
||||||
is ConeClassLikeSymbol -> provider.getFirClassifierContainerFile(this)
|
is ConeClassLikeSymbol -> provider.getFirClassifierContainerFile(this)
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
Reference in New Issue
Block a user