FIR: Simplify ConstructorProcessing relevant to type aliases
This commit is contained in:
+40
-113
@@ -8,12 +8,13 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypeParameterRef
|
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypeParameterRef
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructorCopy
|
import org.jetbrains.kotlin.fir.declarations.builder.buildConstructorCopy
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
@@ -118,21 +119,27 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias(
|
|||||||
|
|
||||||
val namedSymbol = samConstructorForClass.symbol as? FirNamedFunctionSymbol ?: return null
|
val namedSymbol = samConstructorForClass.symbol as? FirNamedFunctionSymbol ?: return null
|
||||||
|
|
||||||
val substitutor = prepareSubstitutorForTypeAliasConstructors<FirSimpleFunction>(
|
val substitutor = prepareSubstitutorForTypeAliasConstructors(
|
||||||
this,
|
|
||||||
type,
|
type,
|
||||||
session
|
session
|
||||||
) { newReturnType, newParameterTypes, newTypeParameters ->
|
) ?: return null
|
||||||
FirFakeOverrideGenerator.createFakeOverrideFunction(
|
|
||||||
session, this, namedSymbol,
|
|
||||||
newDispatchReceiverType = null,
|
|
||||||
newReceiverType = null,
|
|
||||||
newReturnType, newParameterTypes, newTypeParameters,
|
|
||||||
expansionRegularClass.classId,
|
|
||||||
).fir
|
|
||||||
} ?: return null
|
|
||||||
|
|
||||||
return substitutor.substitute(samConstructorForClass)
|
val typeParameters = this@findSAMConstructorForTypeAlias.fir.typeParameters
|
||||||
|
val newReturnType = samConstructorForClass.returnTypeRef.coneType.let(substitutor::substituteOrNull)
|
||||||
|
|
||||||
|
val newParameterTypes = samConstructorForClass.valueParameters.map { valueParameter ->
|
||||||
|
valueParameter.returnTypeRef.coneType.let(substitutor::substituteOrNull)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newReturnType == null && newParameterTypes.all { it == null }) return samConstructorForClass
|
||||||
|
|
||||||
|
return FirFakeOverrideGenerator.createFakeOverrideFunction(
|
||||||
|
session, samConstructorForClass, namedSymbol,
|
||||||
|
newDispatchReceiverType = null,
|
||||||
|
newReceiverType = null,
|
||||||
|
newReturnType, newParameterTypes, typeParameters,
|
||||||
|
expansionRegularClass.classId,
|
||||||
|
).fir
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processConstructors(
|
private fun processConstructors(
|
||||||
@@ -152,9 +159,10 @@ private fun processConstructors(
|
|||||||
val basicScope = type.scope(session, bodyResolveComponents.scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
val basicScope = type.scope(session, bodyResolveComponents.scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||||
|
|
||||||
if (basicScope != null && type.typeArguments.isNotEmpty()) {
|
if (basicScope != null && type.typeArguments.isNotEmpty()) {
|
||||||
prepareSubstitutingScopeForTypeAliasConstructors(
|
TypeAliasConstructorsSubstitutingScope(
|
||||||
matchedSymbol, session, basicScope
|
matchedSymbol,
|
||||||
) ?: return
|
basicScope
|
||||||
|
)
|
||||||
} else basicScope
|
} else basicScope
|
||||||
}
|
}
|
||||||
is FirClassSymbol ->
|
is FirClassSymbol ->
|
||||||
@@ -179,110 +187,31 @@ private fun processConstructors(
|
|||||||
|
|
||||||
private class TypeAliasConstructorsSubstitutingScope(
|
private class TypeAliasConstructorsSubstitutingScope(
|
||||||
private val typeAliasSymbol: FirTypeAliasSymbol,
|
private val typeAliasSymbol: FirTypeAliasSymbol,
|
||||||
private val copyFactory: ConstructorCopyFactory<FirConstructor>,
|
|
||||||
private val delegatingScope: FirScope
|
private val delegatingScope: FirScope
|
||||||
) : FirScope() {
|
) : FirScope() {
|
||||||
|
|
||||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
delegatingScope.processDeclaredConstructors {
|
delegatingScope.processDeclaredConstructors { originalConstructorSymbol ->
|
||||||
|
|
||||||
val typeParameters = typeAliasSymbol.fir.typeParameters
|
val typeParameters = typeAliasSymbol.fir.typeParameters
|
||||||
if (typeParameters.isEmpty()) processor(it)
|
if (typeParameters.isEmpty()) processor(originalConstructorSymbol)
|
||||||
else {
|
else {
|
||||||
processor(it.fir.copyFactory(
|
processor(
|
||||||
null,
|
buildConstructorCopy(originalConstructorSymbol.fir) {
|
||||||
null,
|
symbol = FirConstructorSymbol(originalConstructorSymbol.callableId, overriddenSymbol = originalConstructorSymbol)
|
||||||
typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
|
origin = FirDeclarationOrigin.SubstitutionOverride
|
||||||
).symbol)
|
this.typeParameters += typeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
|
||||||
|
}.symbol
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private typealias ConstructorCopyFactory2<F> =
|
private fun prepareSubstitutorForTypeAliasConstructors(
|
||||||
F.(newReturnType: ConeKotlinType?, newValueParameterTypes: List<ConeKotlinType?>?, newTypeParameters: List<FirTypeParameter>) -> F
|
|
||||||
|
|
||||||
private typealias ConstructorCopyFactory<F> =
|
|
||||||
F.(newReturnType: ConeKotlinType?, newValueParameterTypes: List<ConeKotlinType?>?, newTypeParameters: List<FirTypeParameterRef>) -> F
|
|
||||||
|
|
||||||
private class TypeAliasConstructorsSubstitutor<F : FirFunction<F>>(
|
|
||||||
private val typeAliasSymbol: FirTypeAliasSymbol,
|
|
||||||
private val substitutor: ConeSubstitutor,
|
|
||||||
private val copyFactory: ConstructorCopyFactory2<F>
|
|
||||||
) {
|
|
||||||
fun substitute(baseFunction: F): F {
|
|
||||||
val typeParameters = typeAliasSymbol.fir.typeParameters
|
|
||||||
val newReturnType = baseFunction.returnTypeRef.coneType.let(substitutor::substituteOrNull)
|
|
||||||
|
|
||||||
val newParameterTypes = baseFunction.valueParameters.map { valueParameter ->
|
|
||||||
valueParameter.returnTypeRef.coneType.let(substitutor::substituteOrNull)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newReturnType == null && newParameterTypes.all { it == null }) return baseFunction
|
|
||||||
|
|
||||||
return baseFunction.copyFactory(
|
|
||||||
newReturnType,
|
|
||||||
newParameterTypes,
|
|
||||||
typeParameters
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun prepareSubstitutingScopeForTypeAliasConstructors(
|
|
||||||
typeAliasSymbol: FirTypeAliasSymbol,
|
|
||||||
session: FirSession,
|
|
||||||
delegatingScope: FirScope
|
|
||||||
): FirScope {
|
|
||||||
val copyFactory2: ConstructorCopyFactory<FirConstructor> = factory@{ newReturnType, newParameterTypes, newTypeParameters ->
|
|
||||||
buildConstructor {
|
|
||||||
source = this@factory.source
|
|
||||||
this.session = session
|
|
||||||
origin = FirDeclarationOrigin.SubstitutionOverride
|
|
||||||
returnTypeRef = this@factory.returnTypeRef.withReplacedConeType(newReturnType)
|
|
||||||
receiverTypeRef = this@factory.receiverTypeRef
|
|
||||||
status = this@factory.status
|
|
||||||
symbol = FirConstructorSymbol(this@factory.symbol.callableId, overriddenSymbol = this@factory.symbol)
|
|
||||||
resolvePhase = this@factory.resolvePhase
|
|
||||||
if (newParameterTypes != null) {
|
|
||||||
valueParameters +=
|
|
||||||
this@factory.valueParameters.zip(
|
|
||||||
newParameterTypes
|
|
||||||
) { valueParameter, newParameterType ->
|
|
||||||
buildValueParameter {
|
|
||||||
source = valueParameter.source
|
|
||||||
this.session = session
|
|
||||||
resolvePhase = valueParameter.resolvePhase
|
|
||||||
origin = FirDeclarationOrigin.SubstitutionOverride
|
|
||||||
returnTypeRef = valueParameter.returnTypeRef.withReplacedConeType(newParameterType)
|
|
||||||
name = valueParameter.name
|
|
||||||
symbol = FirVariableSymbol(valueParameter.symbol.callableId)
|
|
||||||
defaultValue = valueParameter.defaultValue
|
|
||||||
isCrossinline = valueParameter.isCrossinline
|
|
||||||
isNoinline = valueParameter.isNoinline
|
|
||||||
isVararg = valueParameter.isVararg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
valueParameters += this@factory.valueParameters
|
|
||||||
}
|
|
||||||
this.typeParameters += newTypeParameters
|
|
||||||
this.attributes = this@factory.attributes.copy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeAliasConstructorsSubstitutingScope(
|
|
||||||
typeAliasSymbol,
|
|
||||||
copyFactory2,
|
|
||||||
delegatingScope
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <F : FirFunction<F>> prepareSubstitutorForTypeAliasConstructors(
|
|
||||||
typeAliasSymbol: FirTypeAliasSymbol,
|
|
||||||
expandedType: ConeClassLikeType,
|
expandedType: ConeClassLikeType,
|
||||||
session: FirSession,
|
session: FirSession
|
||||||
copyFactory: ConstructorCopyFactory2<F>
|
): ConeSubstitutor? {
|
||||||
): TypeAliasConstructorsSubstitutor<F>? {
|
|
||||||
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
val expandedClass = expandedType.lookupTag.toSymbol(session)?.fir as? FirRegularClass ?: return null
|
||||||
|
|
||||||
val resultingTypeArguments = expandedType.typeArguments.map {
|
val resultingTypeArguments = expandedType.typeArguments.map {
|
||||||
@@ -290,12 +219,9 @@ private fun <F : FirFunction<F>> prepareSubstitutorForTypeAliasConstructors(
|
|||||||
// typealias A = ArrayList<*>()
|
// typealias A = ArrayList<*>()
|
||||||
it as? ConeKotlinType ?: return null
|
it as? ConeKotlinType ?: return null
|
||||||
}
|
}
|
||||||
|
return substitutorByMap(
|
||||||
val substitutor = substitutorByMap(
|
|
||||||
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap()
|
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
return TypeAliasConstructorsSubstitutor(typeAliasSymbol, substitutor, copyFactory)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepareCopyConstructorForTypealiasNestedClass(
|
private fun prepareCopyConstructorForTypealiasNestedClass(
|
||||||
@@ -341,4 +267,5 @@ private fun prepareCopyConstructorForTypealiasNestedClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object TypeAliasConstructorKey : FirDeclarationDataKey()
|
private object TypeAliasConstructorKey : FirDeclarationDataKey()
|
||||||
|
|
||||||
var FirConstructor.originalConstructorIfTypeAlias: FirConstructor? by FirDeclarationDataRegistry.data(TypeAliasConstructorKey)
|
var FirConstructor.originalConstructorIfTypeAlias: FirConstructor? by FirDeclarationDataRegistry.data(TypeAliasConstructorKey)
|
||||||
|
|||||||
Reference in New Issue
Block a user