[FIR] Substitute copied type parameters in fake override properties

This commit is contained in:
Mikhail Glukhikh
2020-08-28 13:33:33 +03:00
parent dc9306367a
commit db815c96c5
2 changed files with 63 additions and 17 deletions
@@ -352,16 +352,9 @@ class FirClassSubstitutionScope(
val copiedParameterTypes = baseFunction.valueParameters.map {
substitutor.substituteOrNull(it.returnTypeRef.coneType)
}
val copiedReceiverType = newReceiverType?.let {
substitutor.substituteOrNull(it)
} ?: baseFunction.receiverTypeRef?.let {
substitutor.substituteOrNull(it.coneType)
}
val copiedReturnType = newReturnType?.let {
substitutor.substituteOrNull(it)
} ?: baseFunction.returnTypeRef.let {
substitutor.substituteOrNull(it.coneType)
}
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor
)
configureAnnotationsAndSignature(session, baseFunction, copiedParameterTypes, copiedReceiverType, copiedReturnType)
copiedTypeParameters
}
@@ -421,22 +414,74 @@ class FirClassSubstitutionScope(
source = baseProperty.source
this.session = session
origin = FirDeclarationOrigin.FakeOverride
returnTypeRef = baseProperty.returnTypeRef.withReplacedReturnType(newReturnType)
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
name = baseProperty.name
isVar = baseProperty.isVar
this.symbol = symbol
isLocal = false
status = baseProperty.status.withExpect(isExpect)
resolvePhase = baseProperty.resolvePhase
annotations += baseProperty.annotations
if (newTypeParameters != null) {
typeParameters += newTypeParameters
}
typeParameters += configureAnnotationsTypeParametersAndSignature(baseProperty, newTypeParameters, newReceiverType, newReturnType)
}
return symbol
}
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
baseProperty: FirProperty,
newTypeParameters: List<FirTypeParameter>?,
newReceiverType: ConeKotlinType? = null,
newReturnType: ConeKotlinType? = null
): List<FirTypeParameter> {
return when {
baseProperty.typeParameters.isEmpty() -> {
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType)
emptyList()
}
newTypeParameters == null -> {
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
baseProperty, ConeSubstitutor.Empty
)
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
baseProperty, newReceiverType, newReturnType, substitutor
)
configureAnnotationsAndSignature(baseProperty, copiedReceiverType, copiedReturnType)
copiedTypeParameters.filterIsInstance<FirTypeParameter>()
}
else -> {
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType)
newTypeParameters
}
}
}
private fun substituteReceiverAndReturnType(
baseCallable: FirCallableMemberDeclaration<*>,
newReceiverType: ConeKotlinType?,
newReturnType: ConeKotlinType?,
substitutor: ConeSubstitutor
): Pair<ConeKotlinType?, ConeKotlinType?> {
val copiedReceiverType = newReceiverType?.let {
substitutor.substituteOrNull(it)
} ?: baseCallable.receiverTypeRef?.let {
substitutor.substituteOrNull(it.coneType)
}
val copiedReturnType = newReturnType?.let {
substitutor.substituteOrNull(it)
} ?: baseCallable.returnTypeRef.let {
substitutor.substituteOrNull(it.coneType)
}
return copiedReceiverType to copiedReturnType
}
private fun FirPropertyBuilder.configureAnnotationsAndSignature(
baseProperty: FirProperty,
newReceiverType: ConeKotlinType? = null,
newReturnType: ConeKotlinType? = null
) {
annotations += baseProperty.annotations
returnTypeRef = baseProperty.returnTypeRef.withReplacedConeType(newReturnType)
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
}
fun createFakeOverrideField(
session: FirSession,
baseField: FirField,
@@ -124,10 +124,11 @@ FILE fqName:<root> fileName:/useImportedMember.kt
RETURN type=kotlin.Nothing from='public final fun <get-g2> <T> (): T of <root>.C.<get-g2> declared in <root>.C'
GET_VAR '<this>: T of <root>.C.<get-g2> declared in <root>.C.<get-g2>' type=T of <root>.C.<get-g2> origin=null
PROPERTY FAKE_OVERRIDE name:fromClass visibility:public modality:FINAL [fake_override,val]
FUN FAKE_OVERRIDE name:<get-fromClass> visibility:public modality:FINAL <> ($this:<root>.BaseClass) returnType:T of <root>.BaseClass.<get-fromClass> [fake_override]
FUN FAKE_OVERRIDE name:<get-fromClass> visibility:public modality:FINAL <T> ($this:<root>.BaseClass) returnType:T of <root>.C.<get-fromClass> [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:fromClass visibility:public modality:FINAL [fake_override,val]
overridden:
public final fun <get-fromClass> <T> (): T of <root>.BaseClass.<get-fromClass> declared in <root>.BaseClass
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
$this: VALUE_PARAMETER name:<this> type:<root>.BaseClass
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden: