FIR: Avoid redundant substitution when type parameters don't change
This commit is contained in:
+33
-32
@@ -95,26 +95,7 @@ class FirClassSubstitutionScope(
|
|||||||
else -> throw AssertionError("Should not be here")
|
else -> throw AssertionError("Should not be here")
|
||||||
}
|
}
|
||||||
|
|
||||||
val newTypeParameters = member.typeParameters.map { originalParameter ->
|
val (newTypeParameters, newSubstitutor) = createNewTypeParametersAndSubstitutor(member)
|
||||||
FirTypeParameterImpl(
|
|
||||||
originalParameter.source, originalParameter.session, originalParameter.name,
|
|
||||||
FirTypeParameterSymbol(), originalParameter.variance, originalParameter.isReified
|
|
||||||
).apply {
|
|
||||||
annotations += originalParameter.annotations
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val newSubstitutor =
|
|
||||||
if (member.typeParameters.isEmpty())
|
|
||||||
substitutor
|
|
||||||
else {
|
|
||||||
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).map {
|
|
||||||
Pair(it.first.symbol, ConeTypeParameterTypeImpl(it.second.symbol.toLookupTag(), isNullable = false))
|
|
||||||
}.toMap()
|
|
||||||
ChainedSubstitutor(substitutor, substitutorByMap(substitutionMapForNewParameters))
|
|
||||||
}
|
|
||||||
|
|
||||||
val wereChangesInTypeParameters = fillBoundsForTypeParameters(newTypeParameters, member, newSubstitutor)
|
|
||||||
|
|
||||||
val receiverType = member.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
val receiverType = member.receiverTypeRef?.coneTypeUnsafe<ConeKotlinType>()
|
||||||
val newReceiverType = receiverType?.substitute(newSubstitutor)
|
val newReceiverType = receiverType?.substitute(newSubstitutor)
|
||||||
@@ -126,7 +107,8 @@ class FirClassSubstitutionScope(
|
|||||||
it.returnTypeRef.coneTypeUnsafe<ConeKotlinType>().substitute(newSubstitutor)
|
it.returnTypeRef.coneTypeUnsafe<ConeKotlinType>().substitute(newSubstitutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } && !wereChangesInTypeParameters) {
|
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } &&
|
||||||
|
newTypeParameters === member.typeParameters) {
|
||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,26 +117,45 @@ class FirClassSubstitutionScope(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fillBoundsForTypeParameters(
|
// Returns a list of type parameters, and a substitutor that should be used for all other types
|
||||||
newTypeParameters: List<FirTypeParameterImpl>,
|
private fun createNewTypeParametersAndSubstitutor(
|
||||||
member: FirSimpleFunction,
|
member: FirSimpleFunction
|
||||||
newSubstitutor: ConeSubstitutor
|
): Pair<List<FirTypeParameter>, ConeSubstitutor> {
|
||||||
): Boolean {
|
if (member.typeParameters.isEmpty()) return Pair(member.typeParameters, substitutor)
|
||||||
|
val newTypeParameters = member.typeParameters.map { originalParameter ->
|
||||||
|
FirTypeParameterImpl(
|
||||||
|
originalParameter.source, originalParameter.session, originalParameter.name,
|
||||||
|
FirTypeParameterSymbol(), originalParameter.variance, originalParameter.isReified
|
||||||
|
).apply {
|
||||||
|
annotations += originalParameter.annotations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).map {
|
||||||
|
Pair(it.first.symbol, ConeTypeParameterTypeImpl(it.second.symbol.toLookupTag(), isNullable = false))
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters)
|
||||||
|
|
||||||
var wereChangesInTypeParameters = false
|
var wereChangesInTypeParameters = false
|
||||||
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
||||||
for (boundTypeRef in oldTypeParameter.bounds) {
|
for (boundTypeRef in oldTypeParameter.bounds) {
|
||||||
val typeForBound = boundTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
val typeForBound = boundTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||||
val substitutedBound = typeForBound.substitute(newSubstitutor)
|
val substitutedBound = typeForBound.substitute()
|
||||||
if (substitutedBound == null) {
|
if (substitutedBound != null) {
|
||||||
newTypeParameter.bounds += boundTypeRef
|
|
||||||
} else {
|
|
||||||
newTypeParameter.bounds += FirResolvedTypeRefImpl(boundTypeRef.source, substitutedBound)
|
|
||||||
wereChangesInTypeParameters = true
|
wereChangesInTypeParameters = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newTypeParameter.bounds +=
|
||||||
|
FirResolvedTypeRefImpl(
|
||||||
|
boundTypeRef.source, additionalSubstitutor.substituteOrSelf(substitutedBound ?: typeForBound)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wereChangesInTypeParameters
|
if (!wereChangesInTypeParameters) return Pair(member.typeParameters, substitutor)
|
||||||
|
|
||||||
|
return Pair(newTypeParameters, ChainedSubstitutor(substitutor, additionalSubstitutor))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
private fun createFakeOverrideProperty(original: FirPropertySymbol): FirPropertySymbol {
|
||||||
|
|||||||
Reference in New Issue
Block a user