FIR: Reuse callables copying parts in FirClassSubstitutionScope

It changes the behavior in FirTypeIntersectionScope:
- now type parameters are also get copied
- value parameters are being copied unchanged
This commit is contained in:
Denis Zharkov
2020-09-14 13:06:53 +03:00
parent 0297be1fa8
commit 7c7c5336f9
2 changed files with 58 additions and 35 deletions
@@ -290,17 +290,41 @@ class FirClassSubstitutionScope(
newReturnType: ConeKotlinType? = null,
newParameterTypes: List<ConeKotlinType?>? = null,
newTypeParameters: List<FirTypeParameter>? = null,
isExpect: Boolean = baseFunction.isExpect
isExpect: Boolean = baseFunction.isExpect,
): FirSimpleFunction {
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
// As second alternative, we can invent some light-weight kind of FirRegularClass
return createCopyForFirFunction(
fakeOverrideSymbol,
baseFunction,
session,
FirDeclarationOrigin.FakeOverride,
isExpect,
newParameterTypes,
newTypeParameters,
newReceiverType,
newReturnType
)
}
fun createCopyForFirFunction(
newSymbol: FirFunctionSymbol<FirSimpleFunction>,
baseFunction: FirSimpleFunction,
session: FirSession,
origin: FirDeclarationOrigin,
isExpect: Boolean = baseFunction.isExpect,
newParameterTypes: List<ConeKotlinType?>? = null,
newTypeParameters: List<FirTypeParameter>? = null,
newReceiverType: ConeKotlinType? = null,
newReturnType: ConeKotlinType? = null
): FirSimpleFunction {
return buildSimpleFunction {
source = baseFunction.source
this.session = session
origin = FirDeclarationOrigin.FakeOverride
this.origin = origin
name = baseFunction.name
status = baseFunction.status.withExpect(isExpect)
symbol = fakeOverrideSymbol
symbol = newSymbol
resolvePhase = baseFunction.resolvePhase
typeParameters += configureAnnotationsTypeParametersAndSignature(
@@ -413,21 +437,39 @@ class FirClassSubstitutionScope(
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseProperty.name),
isFakeOverride = true, overriddenSymbol = baseSymbol
)
buildProperty {
createCopyForFirProperty(
symbol, baseProperty, session, isExpect,
newTypeParameters, newReceiverType, newReturnType
)
return symbol
}
fun createCopyForFirProperty(
newSymbol: FirPropertySymbol,
baseProperty: FirProperty,
session: FirSession,
isExpect: Boolean = baseProperty.isExpect,
newTypeParameters: List<FirTypeParameter>? = null,
newReceiverType: ConeKotlinType? = null,
newReturnType: ConeKotlinType? = null,
): FirProperty {
return buildProperty {
source = baseProperty.source
this.session = session
origin = FirDeclarationOrigin.FakeOverride
name = baseProperty.name
isVar = baseProperty.isVar
this.symbol = symbol
this.symbol = newSymbol
isLocal = false
status = baseProperty.status.withExpect(isExpect)
resolvePhase = baseProperty.resolvePhase
typeParameters += configureAnnotationsTypeParametersAndSignature(
baseProperty, newTypeParameters, newReceiverType, newReturnType
baseProperty,
newTypeParameters,
newReceiverType,
newReturnType
)
}
return symbol
}
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
import org.jetbrains.kotlin.fir.scopes.FirScope
@@ -145,36 +142,20 @@ class FirTypeIntersectionScope private constructor(
isIntersectionOverride = true
)
val mostSpecificFunction = mostSpecific.fir
createFunctionCopy(mostSpecific.fir, newSymbol).apply {
resolvePhase = mostSpecificFunction.resolvePhase
origin = FirDeclarationOrigin.IntersectionOverride
typeParameters += mostSpecificFunction.typeParameters
valueParameters += mostSpecificFunction.valueParameters.mapIndexed { index, mostSpecificParameter ->
val overriddenWithDefault =
extractedOverrides.firstOrNull {
it.member.fir.valueParameters.getOrNull(index)?.defaultValue != null
}?.member?.fir
if (overriddenWithDefault == null) {
mostSpecificParameter
} else {
val overriddenWithDefaultParameter = overriddenWithDefault.valueParameters[index]
createValueParameterCopy(mostSpecificParameter, null).apply {
annotations += mostSpecificParameter.annotations
}.build()
}
}
}.build()
FirClassSubstitutionScope.createCopyForFirFunction(
newSymbol,
mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride,
mostSpecificFunction.isExpect,
)
return newSymbol
}
private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol {
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
val mostSpecificProperty = mostSpecific.fir
createPropertyCopy(mostSpecific.fir, newSymbol).apply {
resolvePhase = mostSpecificProperty.resolvePhase
origin = FirDeclarationOrigin.IntersectionOverride
typeParameters += mostSpecificProperty.typeParameters
}.build()
FirClassSubstitutionScope.createCopyForFirProperty(
newSymbol, mostSpecificProperty, mostSpecificProperty.session
)
return newSymbol
}