[FIR] Move functions for fake override creating to separate objects
This commit is contained in:
+3
-3
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
|||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
|
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
|
||||||
@@ -84,7 +84,7 @@ class FakeOverrideGenerator(
|
|||||||
declarationStorage::getCachedIrFunction,
|
declarationStorage::getCachedIrFunction,
|
||||||
declarationStorage::createIrFunction,
|
declarationStorage::createIrFunction,
|
||||||
createFakeOverrideSymbol = { firFunction, callableSymbol ->
|
createFakeOverrideSymbol = { firFunction, callableSymbol ->
|
||||||
FirClassSubstitutionScope.createFakeOverrideFunction(
|
FirFakeOverrideGenerator.createFakeOverrideFunction(
|
||||||
session, firFunction, callableSymbol,
|
session, firFunction, callableSymbol,
|
||||||
derivedClassId = klass.symbol.classId,
|
derivedClassId = klass.symbol.classId,
|
||||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||||
@@ -107,7 +107,7 @@ class FakeOverrideGenerator(
|
|||||||
declarationStorage::getCachedIrProperty,
|
declarationStorage::getCachedIrProperty,
|
||||||
declarationStorage::createIrProperty,
|
declarationStorage::createIrProperty,
|
||||||
createFakeOverrideSymbol = { firProperty, callableSymbol ->
|
createFakeOverrideSymbol = { firProperty, callableSymbol ->
|
||||||
FirClassSubstitutionScope.createFakeOverrideProperty(
|
FirFakeOverrideGenerator.createFakeOverrideProperty(
|
||||||
session, firProperty, callableSymbol,
|
session, firProperty, callableSymbol,
|
||||||
derivedClassId = klass.symbol.classId,
|
derivedClassId = klass.symbol.classId,
|
||||||
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
isExpect = (klass as? FirRegularClass)?.isExpect == true
|
||||||
|
|||||||
+2
-2
@@ -16,7 +16,7 @@ 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.transformers.ensureResolved
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
|
||||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -122,7 +122,7 @@ private fun FirTypeAliasSymbol.findSAMConstructorForTypeAlias(
|
|||||||
type,
|
type,
|
||||||
session
|
session
|
||||||
) { newReturnType, newParameterTypes, newTypeParameters ->
|
) { newReturnType, newParameterTypes, newTypeParameters ->
|
||||||
FirClassSubstitutionScope.createFakeOverrideFunction(
|
FirFakeOverrideGenerator.createFakeOverrideFunction(
|
||||||
session, this, namedSymbol, null,
|
session, this, namedSymbol, null,
|
||||||
newReturnType, newParameterTypes, newTypeParameters
|
newReturnType, newParameterTypes, newTypeParameters
|
||||||
).fir
|
).fir
|
||||||
|
|||||||
+6
-410
@@ -5,26 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -149,7 +141,7 @@ class FirClassSubstitutionScope(
|
|||||||
* it's safe to cast newTypeParameters to List<FirTypeParameter>
|
* it's safe to cast newTypeParameters to List<FirTypeParameter>
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return createFakeOverrideFunction(
|
return FirFakeOverrideGenerator.createFakeOverrideFunction(
|
||||||
session,
|
session,
|
||||||
member,
|
member,
|
||||||
original,
|
original,
|
||||||
@@ -174,7 +166,7 @@ class FirClassSubstitutionScope(
|
|||||||
if (newReturnType == null && newParameterTypes.all { it == null } && newTypeParameters === constructor.typeParameters) {
|
if (newReturnType == null && newParameterTypes.all { it == null } && newTypeParameters === constructor.typeParameters) {
|
||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
return createFakeOverrideConstructor(
|
return FirFakeOverrideGenerator.createFakeOverrideConstructor(
|
||||||
FirConstructorSymbol(original.callableId, overriddenSymbol = original),
|
FirConstructorSymbol(original.callableId, overriddenSymbol = original),
|
||||||
session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect
|
session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect
|
||||||
).symbol
|
).symbol
|
||||||
@@ -193,7 +185,7 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return createFakeOverrideProperty(
|
return FirFakeOverrideGenerator.createFakeOverrideProperty(
|
||||||
session,
|
session,
|
||||||
member,
|
member,
|
||||||
original,
|
original,
|
||||||
@@ -213,7 +205,7 @@ class FirClassSubstitutionScope(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData {
|
private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData {
|
||||||
val (newTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
|
val (newTypeParameters, substitutor) = FirFakeOverrideGenerator.createNewTypeParametersAndSubstitutor(
|
||||||
member as FirTypeParameterRefsOwner,
|
member as FirTypeParameterRefsOwner,
|
||||||
substitutor,
|
substitutor,
|
||||||
forceTypeParametersRecreation = derivedClassId != null && derivedClassId != member.symbol.callableId.classId
|
forceTypeParametersRecreation = derivedClassId != null && derivedClassId != member.symbol.callableId.classId
|
||||||
@@ -235,7 +227,7 @@ class FirClassSubstitutionScope(
|
|||||||
val returnType = member.returnTypeRef.coneType
|
val returnType = member.returnTypeRef.coneType
|
||||||
val newReturnType = returnType.substitute() ?: return original
|
val newReturnType = returnType.substitute() ?: return original
|
||||||
|
|
||||||
return createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
|
return FirFakeOverrideGenerator.createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
|
private fun createFakeOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
|
||||||
@@ -254,403 +246,7 @@ class FirClassSubstitutionScope(
|
|||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFakeOverrideAccessor(session, member, original, newReturnType, newParameterTypes)
|
return FirFakeOverrideGenerator.createFakeOverrideAccessor(session, member, original, newReturnType, newParameterTypes)
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun createFakeOverrideFunction(
|
|
||||||
session: FirSession,
|
|
||||||
baseFunction: FirSimpleFunction,
|
|
||||||
baseSymbol: FirNamedFunctionSymbol,
|
|
||||||
newReceiverType: ConeKotlinType? = null,
|
|
||||||
newReturnType: ConeKotlinType? = null,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>? = null,
|
|
||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
|
||||||
derivedClassId: ClassId? = null,
|
|
||||||
isExpect: Boolean = baseFunction.isExpect
|
|
||||||
): FirNamedFunctionSymbol {
|
|
||||||
val symbol = FirNamedFunctionSymbol(
|
|
||||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseFunction.name),
|
|
||||||
isFakeOverride = true, overriddenSymbol = baseSymbol
|
|
||||||
)
|
|
||||||
createFakeOverrideFunction(
|
|
||||||
symbol, session, baseFunction, newReceiverType, newReturnType, newParameterTypes, newTypeParameters, isExpect
|
|
||||||
)
|
|
||||||
return symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createFakeOverrideFunction(
|
|
||||||
fakeOverrideSymbol: FirFunctionSymbol<FirSimpleFunction>,
|
|
||||||
session: FirSession,
|
|
||||||
baseFunction: FirSimpleFunction,
|
|
||||||
newReceiverType: ConeKotlinType?,
|
|
||||||
newReturnType: ConeKotlinType?,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
|
||||||
newTypeParameters: List<FirTypeParameter>?,
|
|
||||||
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,
|
|
||||||
newModality: Modality? = null,
|
|
||||||
newVisibility: Visibility? = null,
|
|
||||||
): FirSimpleFunction {
|
|
||||||
return buildSimpleFunction {
|
|
||||||
source = baseFunction.source
|
|
||||||
this.session = session
|
|
||||||
this.origin = origin
|
|
||||||
name = baseFunction.name
|
|
||||||
status = baseFunction.status.updatedStatus(isExpect, newModality, newVisibility)
|
|
||||||
symbol = newSymbol
|
|
||||||
resolvePhase = baseFunction.resolvePhase
|
|
||||||
|
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
|
||||||
session, baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType
|
|
||||||
).filterIsInstance<FirTypeParameter>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createFakeOverrideConstructor(
|
|
||||||
fakeOverrideSymbol: FirConstructorSymbol,
|
|
||||||
session: FirSession,
|
|
||||||
baseConstructor: FirConstructor,
|
|
||||||
newReturnType: ConeKotlinType?,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
|
||||||
newTypeParameters: List<FirTypeParameterRef>?,
|
|
||||||
isExpect: Boolean
|
|
||||||
): FirConstructor {
|
|
||||||
// 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 buildConstructor {
|
|
||||||
source = baseConstructor.source
|
|
||||||
this.session = session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
|
|
||||||
status = baseConstructor.status.updatedStatus(isExpect)
|
|
||||||
symbol = fakeOverrideSymbol
|
|
||||||
resolvePhase = baseConstructor.resolvePhase
|
|
||||||
|
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
|
||||||
session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature(
|
|
||||||
session: FirSession,
|
|
||||||
baseFunction: FirFunction<*>,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
|
||||||
newTypeParameters: List<FirTypeParameterRef>?,
|
|
||||||
newReceiverType: ConeKotlinType?,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
): List<FirTypeParameterRef> {
|
|
||||||
return when {
|
|
||||||
baseFunction.typeParameters.isEmpty() -> {
|
|
||||||
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
newTypeParameters == null -> {
|
|
||||||
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
|
|
||||||
baseFunction, ConeSubstitutor.Empty
|
|
||||||
)
|
|
||||||
val copiedParameterTypes = baseFunction.valueParameters.map {
|
|
||||||
substitutor.substituteOrNull(it.returnTypeRef.coneType)
|
|
||||||
}
|
|
||||||
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
|
|
||||||
baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor
|
|
||||||
)
|
|
||||||
configureAnnotationsAndSignature(session, baseFunction, copiedParameterTypes, copiedReceiverType, copiedReturnType)
|
|
||||||
copiedTypeParameters
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
|
||||||
newTypeParameters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirFunctionBuilder.configureAnnotationsAndSignature(
|
|
||||||
session: FirSession,
|
|
||||||
baseFunction: FirFunction<*>,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
|
||||||
newReceiverType: ConeKotlinType?,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
) {
|
|
||||||
annotations += baseFunction.annotations
|
|
||||||
returnTypeRef = replaceReturnTypeIfResolved(baseFunction, newReturnType)
|
|
||||||
|
|
||||||
if (this is FirSimpleFunctionBuilder) {
|
|
||||||
receiverTypeRef = baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
|
||||||
}
|
|
||||||
valueParameters += baseFunction.valueParameters.zip(
|
|
||||||
newParameterTypes ?: List(baseFunction.valueParameters.size) { null }
|
|
||||||
) { valueParameter, newType ->
|
|
||||||
buildValueParameterCopy(valueParameter) {
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
returnTypeRef = valueParameter.returnTypeRef.withReplacedConeType(newType)
|
|
||||||
symbol = FirVariableSymbol(valueParameter.symbol.callableId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun replaceReturnTypeIfResolved(
|
|
||||||
base: FirCallableDeclaration<*>,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
): FirTypeRef = if (base.returnTypeRef is FirResolvedTypeRef)
|
|
||||||
base.returnTypeRef.withReplacedConeType(newReturnType)
|
|
||||||
else
|
|
||||||
base.returnTypeRef
|
|
||||||
|
|
||||||
fun createFakeOverrideProperty(
|
|
||||||
session: FirSession,
|
|
||||||
baseProperty: FirProperty,
|
|
||||||
baseSymbol: FirPropertySymbol,
|
|
||||||
newReceiverType: ConeKotlinType? = null,
|
|
||||||
newReturnType: ConeKotlinType? = null,
|
|
||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
|
||||||
derivedClassId: ClassId? = null,
|
|
||||||
isExpect: Boolean = baseProperty.isExpect
|
|
||||||
): FirPropertySymbol {
|
|
||||||
val symbol = FirPropertySymbol(
|
|
||||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseProperty.name),
|
|
||||||
isFakeOverride = true, overriddenSymbol = baseSymbol
|
|
||||||
)
|
|
||||||
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,
|
|
||||||
newModality: Modality? = null,
|
|
||||||
newVisibility: Visibility? = null,
|
|
||||||
): FirProperty {
|
|
||||||
return buildProperty {
|
|
||||||
source = baseProperty.source
|
|
||||||
this.session = session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
name = baseProperty.name
|
|
||||||
isVar = baseProperty.isVar
|
|
||||||
this.symbol = newSymbol
|
|
||||||
isLocal = false
|
|
||||||
status = baseProperty.status.updatedStatus(isExpect, newModality, newVisibility)
|
|
||||||
|
|
||||||
resolvePhase = baseProperty.resolvePhase
|
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
|
||||||
baseProperty,
|
|
||||||
newTypeParameters,
|
|
||||||
newReceiverType,
|
|
||||||
newReturnType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
|
|
||||||
baseProperty: FirProperty,
|
|
||||||
newTypeParameters: List<FirTypeParameter>?,
|
|
||||||
newReceiverType: ConeKotlinType?,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
): 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?,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
) {
|
|
||||||
annotations += baseProperty.annotations
|
|
||||||
returnTypeRef = replaceReturnTypeIfResolved(baseProperty, newReturnType)
|
|
||||||
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createFakeOverrideField(
|
|
||||||
session: FirSession,
|
|
||||||
baseField: FirField,
|
|
||||||
baseSymbol: FirFieldSymbol,
|
|
||||||
newReturnType: ConeKotlinType?,
|
|
||||||
derivedClassId: ClassId?
|
|
||||||
): FirFieldSymbol {
|
|
||||||
val symbol = FirFieldSymbol(
|
|
||||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseField.name)
|
|
||||||
)
|
|
||||||
buildField {
|
|
||||||
source = baseField.source
|
|
||||||
this.session = session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
resolvePhase = baseField.resolvePhase
|
|
||||||
returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType)
|
|
||||||
name = baseField.name
|
|
||||||
this.symbol = symbol
|
|
||||||
isVar = baseField.isVar
|
|
||||||
status = baseField.status
|
|
||||||
resolvePhase = baseField.resolvePhase
|
|
||||||
annotations += baseField.annotations
|
|
||||||
}
|
|
||||||
return symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createFakeOverrideAccessor(
|
|
||||||
session: FirSession,
|
|
||||||
baseProperty: FirSyntheticProperty,
|
|
||||||
baseSymbol: FirAccessorSymbol,
|
|
||||||
newReturnType: ConeKotlinType?,
|
|
||||||
newParameterTypes: List<ConeKotlinType?>?
|
|
||||||
): FirAccessorSymbol {
|
|
||||||
val functionSymbol = FirNamedFunctionSymbol(baseSymbol.accessorId)
|
|
||||||
val function = createFakeOverrideFunction(
|
|
||||||
functionSymbol,
|
|
||||||
session,
|
|
||||||
baseProperty.getter.delegate,
|
|
||||||
newReceiverType = null,
|
|
||||||
newReturnType,
|
|
||||||
newParameterTypes,
|
|
||||||
newTypeParameters = null
|
|
||||||
)
|
|
||||||
return buildSyntheticProperty {
|
|
||||||
this.session = session
|
|
||||||
name = baseProperty.name
|
|
||||||
symbol = FirAccessorSymbol(baseSymbol.callableId, baseSymbol.accessorId)
|
|
||||||
delegateGetter = function
|
|
||||||
}.symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun FirDeclarationStatus.updatedStatus(
|
|
||||||
isExpect: Boolean,
|
|
||||||
newModality: Modality? = null,
|
|
||||||
newVisibility: Visibility? = null,
|
|
||||||
): FirDeclarationStatus {
|
|
||||||
return if (this.isExpect == isExpect && newModality == null && newVisibility == null) {
|
|
||||||
this
|
|
||||||
} else {
|
|
||||||
require(this is FirDeclarationStatusImpl) { "Unexpected class ${this::class}" }
|
|
||||||
this.resolved(newVisibility ?: visibility, newModality ?: modality!!).apply {
|
|
||||||
this.isExpect = isExpect
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a list of type parameters, and a substitutor that should be used for all other types
|
|
||||||
private fun createNewTypeParametersAndSubstitutor(
|
|
||||||
member: FirTypeParameterRefsOwner,
|
|
||||||
substitutor: ConeSubstitutor,
|
|
||||||
forceTypeParametersRecreation: Boolean = true
|
|
||||||
): Pair<List<FirTypeParameterRef>, ConeSubstitutor> {
|
|
||||||
if (member.typeParameters.isEmpty()) return Pair(member.typeParameters, substitutor)
|
|
||||||
val newTypeParameters = member.typeParameters.map { typeParameter ->
|
|
||||||
if (typeParameter !is FirTypeParameter) return@map null
|
|
||||||
FirTypeParameterBuilder().apply {
|
|
||||||
source = typeParameter.source
|
|
||||||
session = typeParameter.session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
name = typeParameter.name
|
|
||||||
symbol = FirTypeParameterSymbol()
|
|
||||||
variance = typeParameter.variance
|
|
||||||
isReified = typeParameter.isReified
|
|
||||||
annotations += typeParameter.annotations
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).mapNotNull { (original, new) ->
|
|
||||||
if (new != null)
|
|
||||||
Pair(original.symbol, ConeTypeParameterTypeImpl(new.symbol.toLookupTag(), isNullable = false))
|
|
||||||
else null
|
|
||||||
}.toMap()
|
|
||||||
|
|
||||||
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters)
|
|
||||||
|
|
||||||
var wereChangesInTypeParameters = forceTypeParametersRecreation
|
|
||||||
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
|
||||||
if (newTypeParameter == null) continue
|
|
||||||
val original = oldTypeParameter as FirTypeParameter
|
|
||||||
for (boundTypeRef in original.bounds) {
|
|
||||||
val typeForBound = boundTypeRef.coneType
|
|
||||||
val substitutedBound = substitutor.substituteOrNull(typeForBound)
|
|
||||||
if (substitutedBound != null) {
|
|
||||||
wereChangesInTypeParameters = true
|
|
||||||
}
|
|
||||||
newTypeParameter.bounds +=
|
|
||||||
buildResolvedTypeRef {
|
|
||||||
source = boundTypeRef.source
|
|
||||||
type = additionalSubstitutor.substituteOrSelf(substitutedBound ?: typeForBound)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wereChangesInTypeParameters) return Pair(member.typeParameters, substitutor)
|
|
||||||
return Pair(
|
|
||||||
newTypeParameters.mapIndexed { index, builder -> builder?.build() ?: member.typeParameters[index] },
|
|
||||||
ChainedSubstitutor(substitutor, additionalSubstitutor)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
|||||||
+2
-2
@@ -38,7 +38,7 @@ class FirDelegatedMemberScope(
|
|||||||
val newSymbol = FirNamedFunctionSymbol(
|
val newSymbol = FirNamedFunctionSymbol(
|
||||||
functionSymbol.callableId,
|
functionSymbol.callableId,
|
||||||
)
|
)
|
||||||
FirClassSubstitutionScope.createCopyForFirFunction(
|
FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||||
newSymbol,
|
newSymbol,
|
||||||
original,
|
original,
|
||||||
session,
|
session,
|
||||||
@@ -64,7 +64,7 @@ class FirDelegatedMemberScope(
|
|||||||
return@processor
|
return@processor
|
||||||
}
|
}
|
||||||
val delegatedSymbol = delegatedPropertyCache.getOrPut(propertySymbol) {
|
val delegatedSymbol = delegatedPropertyCache.getOrPut(propertySymbol) {
|
||||||
FirClassSubstitutionScope.createCopyForFirProperty(
|
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||||
FirPropertySymbol(
|
FirPropertySymbol(
|
||||||
propertySymbol.callableId,
|
propertySymbol.callableId,
|
||||||
overriddenSymbol = propertySymbol
|
overriddenSymbol = propertySymbol
|
||||||
|
|||||||
+420
@@ -0,0 +1,420 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
object FirFakeOverrideGenerator {
|
||||||
|
fun createFakeOverrideFunction(
|
||||||
|
session: FirSession,
|
||||||
|
baseFunction: FirSimpleFunction,
|
||||||
|
baseSymbol: FirNamedFunctionSymbol,
|
||||||
|
newReceiverType: ConeKotlinType? = null,
|
||||||
|
newReturnType: ConeKotlinType? = null,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>? = null,
|
||||||
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
|
derivedClassId: ClassId? = null,
|
||||||
|
isExpect: Boolean = baseFunction.isExpect
|
||||||
|
): FirNamedFunctionSymbol {
|
||||||
|
val symbol = FirNamedFunctionSymbol(
|
||||||
|
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseFunction.name),
|
||||||
|
isFakeOverride = true, overriddenSymbol = baseSymbol
|
||||||
|
)
|
||||||
|
createFakeOverrideFunction(
|
||||||
|
symbol, session, baseFunction, newReceiverType, newReturnType, newParameterTypes, newTypeParameters, isExpect
|
||||||
|
)
|
||||||
|
return symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFakeOverrideFunction(
|
||||||
|
fakeOverrideSymbol: FirFunctionSymbol<FirSimpleFunction>,
|
||||||
|
session: FirSession,
|
||||||
|
baseFunction: FirSimpleFunction,
|
||||||
|
newReceiverType: ConeKotlinType?,
|
||||||
|
newReturnType: ConeKotlinType?,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
|
newTypeParameters: List<FirTypeParameter>?,
|
||||||
|
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,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
|
): FirSimpleFunction {
|
||||||
|
return buildSimpleFunction {
|
||||||
|
source = baseFunction.source
|
||||||
|
this.session = session
|
||||||
|
this.origin = origin
|
||||||
|
name = baseFunction.name
|
||||||
|
status = baseFunction.status.updatedStatus(isExpect, newModality, newVisibility)
|
||||||
|
symbol = newSymbol
|
||||||
|
resolvePhase = baseFunction.resolvePhase
|
||||||
|
|
||||||
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
|
session, baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType
|
||||||
|
).filterIsInstance<FirTypeParameter>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFakeOverrideConstructor(
|
||||||
|
fakeOverrideSymbol: FirConstructorSymbol,
|
||||||
|
session: FirSession,
|
||||||
|
baseConstructor: FirConstructor,
|
||||||
|
newReturnType: ConeKotlinType?,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
|
newTypeParameters: List<FirTypeParameterRef>?,
|
||||||
|
isExpect: Boolean
|
||||||
|
): FirConstructor {
|
||||||
|
// 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 buildConstructor {
|
||||||
|
source = baseConstructor.source
|
||||||
|
this.session = session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
|
||||||
|
status = baseConstructor.status.updatedStatus(isExpect)
|
||||||
|
symbol = fakeOverrideSymbol
|
||||||
|
resolvePhase = baseConstructor.resolvePhase
|
||||||
|
|
||||||
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
|
session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirFunctionBuilder.configureAnnotationsTypeParametersAndSignature(
|
||||||
|
session: FirSession,
|
||||||
|
baseFunction: FirFunction<*>,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
|
newTypeParameters: List<FirTypeParameterRef>?,
|
||||||
|
newReceiverType: ConeKotlinType?,
|
||||||
|
newReturnType: ConeKotlinType?
|
||||||
|
): List<FirTypeParameterRef> {
|
||||||
|
return when {
|
||||||
|
baseFunction.typeParameters.isEmpty() -> {
|
||||||
|
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
newTypeParameters == null -> {
|
||||||
|
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
|
||||||
|
baseFunction, ConeSubstitutor.Empty
|
||||||
|
)
|
||||||
|
val copiedParameterTypes = baseFunction.valueParameters.map {
|
||||||
|
substitutor.substituteOrNull(it.returnTypeRef.coneType)
|
||||||
|
}
|
||||||
|
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
|
||||||
|
baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor
|
||||||
|
)
|
||||||
|
configureAnnotationsAndSignature(session, baseFunction, copiedParameterTypes, copiedReceiverType, copiedReturnType)
|
||||||
|
copiedTypeParameters
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
||||||
|
newTypeParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirFunctionBuilder.configureAnnotationsAndSignature(
|
||||||
|
session: FirSession,
|
||||||
|
baseFunction: FirFunction<*>,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
|
newReceiverType: ConeKotlinType?,
|
||||||
|
newReturnType: ConeKotlinType?
|
||||||
|
) {
|
||||||
|
annotations += baseFunction.annotations
|
||||||
|
returnTypeRef = replaceReturnTypeIfResolved(baseFunction, newReturnType)
|
||||||
|
|
||||||
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
|
receiverTypeRef = baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
||||||
|
}
|
||||||
|
valueParameters += baseFunction.valueParameters.zip(
|
||||||
|
newParameterTypes ?: List(baseFunction.valueParameters.size) { null }
|
||||||
|
) { valueParameter, newType ->
|
||||||
|
buildValueParameterCopy(valueParameter) {
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
returnTypeRef = valueParameter.returnTypeRef.withReplacedConeType(newType)
|
||||||
|
symbol = FirVariableSymbol(valueParameter.symbol.callableId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun replaceReturnTypeIfResolved(
|
||||||
|
base: FirCallableDeclaration<*>,
|
||||||
|
newReturnType: ConeKotlinType?
|
||||||
|
): FirTypeRef = if (base.returnTypeRef is FirResolvedTypeRef)
|
||||||
|
base.returnTypeRef.withReplacedConeType(newReturnType)
|
||||||
|
else
|
||||||
|
base.returnTypeRef
|
||||||
|
|
||||||
|
fun createFakeOverrideProperty(
|
||||||
|
session: FirSession,
|
||||||
|
baseProperty: FirProperty,
|
||||||
|
baseSymbol: FirPropertySymbol,
|
||||||
|
newReceiverType: ConeKotlinType? = null,
|
||||||
|
newReturnType: ConeKotlinType? = null,
|
||||||
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
|
derivedClassId: ClassId? = null,
|
||||||
|
isExpect: Boolean = baseProperty.isExpect
|
||||||
|
): FirPropertySymbol {
|
||||||
|
val symbol = FirPropertySymbol(
|
||||||
|
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseProperty.name),
|
||||||
|
isFakeOverride = true, overriddenSymbol = baseSymbol
|
||||||
|
)
|
||||||
|
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,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
|
): FirProperty {
|
||||||
|
return buildProperty {
|
||||||
|
source = baseProperty.source
|
||||||
|
this.session = session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
name = baseProperty.name
|
||||||
|
isVar = baseProperty.isVar
|
||||||
|
this.symbol = newSymbol
|
||||||
|
isLocal = false
|
||||||
|
status = baseProperty.status.updatedStatus(isExpect, newModality, newVisibility)
|
||||||
|
|
||||||
|
resolvePhase = baseProperty.resolvePhase
|
||||||
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
|
baseProperty,
|
||||||
|
newTypeParameters,
|
||||||
|
newReceiverType,
|
||||||
|
newReturnType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature(
|
||||||
|
baseProperty: FirProperty,
|
||||||
|
newTypeParameters: List<FirTypeParameter>?,
|
||||||
|
newReceiverType: ConeKotlinType?,
|
||||||
|
newReturnType: ConeKotlinType?
|
||||||
|
): 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?,
|
||||||
|
newReturnType: ConeKotlinType?
|
||||||
|
) {
|
||||||
|
annotations += baseProperty.annotations
|
||||||
|
returnTypeRef = replaceReturnTypeIfResolved(baseProperty, newReturnType)
|
||||||
|
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFakeOverrideField(
|
||||||
|
session: FirSession,
|
||||||
|
baseField: FirField,
|
||||||
|
baseSymbol: FirFieldSymbol,
|
||||||
|
newReturnType: ConeKotlinType?,
|
||||||
|
derivedClassId: ClassId?
|
||||||
|
): FirFieldSymbol {
|
||||||
|
val symbol = FirFieldSymbol(
|
||||||
|
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseField.name)
|
||||||
|
)
|
||||||
|
buildField {
|
||||||
|
source = baseField.source
|
||||||
|
this.session = session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
resolvePhase = baseField.resolvePhase
|
||||||
|
returnTypeRef = baseField.returnTypeRef.withReplacedConeType(newReturnType)
|
||||||
|
name = baseField.name
|
||||||
|
this.symbol = symbol
|
||||||
|
isVar = baseField.isVar
|
||||||
|
status = baseField.status
|
||||||
|
resolvePhase = baseField.resolvePhase
|
||||||
|
annotations += baseField.annotations
|
||||||
|
}
|
||||||
|
return symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFakeOverrideAccessor(
|
||||||
|
session: FirSession,
|
||||||
|
baseProperty: FirSyntheticProperty,
|
||||||
|
baseSymbol: FirAccessorSymbol,
|
||||||
|
newReturnType: ConeKotlinType?,
|
||||||
|
newParameterTypes: List<ConeKotlinType?>?
|
||||||
|
): FirAccessorSymbol {
|
||||||
|
val functionSymbol = FirNamedFunctionSymbol(baseSymbol.accessorId)
|
||||||
|
val function = createFakeOverrideFunction(
|
||||||
|
functionSymbol,
|
||||||
|
session,
|
||||||
|
baseProperty.getter.delegate,
|
||||||
|
newReceiverType = null,
|
||||||
|
newReturnType,
|
||||||
|
newParameterTypes,
|
||||||
|
newTypeParameters = null
|
||||||
|
)
|
||||||
|
return buildSyntheticProperty {
|
||||||
|
this.session = session
|
||||||
|
name = baseProperty.name
|
||||||
|
symbol = FirAccessorSymbol(baseSymbol.callableId, baseSymbol.accessorId)
|
||||||
|
delegateGetter = function
|
||||||
|
}.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirDeclarationStatus.updatedStatus(
|
||||||
|
isExpect: Boolean,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
|
): FirDeclarationStatus {
|
||||||
|
return if (this.isExpect == isExpect && newModality == null && newVisibility == null) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
require(this is FirDeclarationStatusImpl) { "Unexpected class ${this::class}" }
|
||||||
|
this.resolved(newVisibility ?: visibility, newModality ?: modality!!).apply {
|
||||||
|
this.isExpect = isExpect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a list of type parameters, and a substitutor that should be used for all other types
|
||||||
|
fun createNewTypeParametersAndSubstitutor(
|
||||||
|
member: FirTypeParameterRefsOwner,
|
||||||
|
substitutor: ConeSubstitutor,
|
||||||
|
forceTypeParametersRecreation: Boolean = true
|
||||||
|
): Pair<List<FirTypeParameterRef>, ConeSubstitutor> {
|
||||||
|
if (member.typeParameters.isEmpty()) return Pair(member.typeParameters, substitutor)
|
||||||
|
val newTypeParameters = member.typeParameters.map { typeParameter ->
|
||||||
|
if (typeParameter !is FirTypeParameter) return@map null
|
||||||
|
FirTypeParameterBuilder().apply {
|
||||||
|
source = typeParameter.source
|
||||||
|
session = typeParameter.session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
name = typeParameter.name
|
||||||
|
symbol = FirTypeParameterSymbol()
|
||||||
|
variance = typeParameter.variance
|
||||||
|
isReified = typeParameter.isReified
|
||||||
|
annotations += typeParameter.annotations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val substitutionMapForNewParameters = member.typeParameters.zip(newTypeParameters).mapNotNull { (original, new) ->
|
||||||
|
if (new != null)
|
||||||
|
Pair(original.symbol, ConeTypeParameterTypeImpl(new.symbol.toLookupTag(), isNullable = false))
|
||||||
|
else null
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
val additionalSubstitutor = substitutorByMap(substitutionMapForNewParameters)
|
||||||
|
|
||||||
|
var wereChangesInTypeParameters = forceTypeParametersRecreation
|
||||||
|
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
||||||
|
if (newTypeParameter == null) continue
|
||||||
|
val original = oldTypeParameter as FirTypeParameter
|
||||||
|
for (boundTypeRef in original.bounds) {
|
||||||
|
val typeForBound = boundTypeRef.coneType
|
||||||
|
val substitutedBound = substitutor.substituteOrNull(typeForBound)
|
||||||
|
if (substitutedBound != null) {
|
||||||
|
wereChangesInTypeParameters = true
|
||||||
|
}
|
||||||
|
newTypeParameter.bounds +=
|
||||||
|
buildResolvedTypeRef {
|
||||||
|
source = boundTypeRef.source
|
||||||
|
type = additionalSubstitutor.substituteOrSelf(substitutedBound ?: typeForBound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wereChangesInTypeParameters) return Pair(member.typeParameters, substitutor)
|
||||||
|
return Pair(
|
||||||
|
newTypeParameters.mapIndexed { index, builder -> builder?.build() ?: member.typeParameters[index] },
|
||||||
|
ChainedSubstitutor(substitutor, additionalSubstitutor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -269,7 +269,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
isIntersectionOverride = true
|
isIntersectionOverride = true
|
||||||
)
|
)
|
||||||
val mostSpecificFunction = mostSpecific.fir
|
val mostSpecificFunction = mostSpecific.fir
|
||||||
FirClassSubstitutionScope.createCopyForFirFunction(
|
FirFakeOverrideGenerator.createCopyForFirFunction(
|
||||||
newSymbol,
|
newSymbol,
|
||||||
mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride,
|
mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride,
|
||||||
mostSpecificFunction.isExpect,
|
mostSpecificFunction.isExpect,
|
||||||
@@ -286,7 +286,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
): FirPropertySymbol {
|
): FirPropertySymbol {
|
||||||
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
|
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
|
||||||
val mostSpecificProperty = mostSpecific.fir
|
val mostSpecificProperty = mostSpecific.fir
|
||||||
FirClassSubstitutionScope.createCopyForFirProperty(
|
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||||
newSymbol, mostSpecificProperty, mostSpecificProperty.session,
|
newSymbol, mostSpecificProperty, mostSpecificProperty.session,
|
||||||
newModality = newModality,
|
newModality = newModality,
|
||||||
newVisibility = newVisibility,
|
newVisibility = newVisibility,
|
||||||
|
|||||||
Reference in New Issue
Block a user