[FIR] Introduce & use processOverriddenPropertiesWithDepth

This commit is contained in:
Mikhail Glukhikh
2020-07-15 12:20:03 +03:00
committed by Mikhail Glukhikh
parent 13ef97e51e
commit 80022cccd9
13 changed files with 235 additions and 46 deletions
@@ -550,7 +550,7 @@ class Fir2IrDeclarationStorage(
if (irParent != null) { if (irParent != null) {
parent = irParent parent = irParent
} }
if (!isFakeOverride && thisReceiverOwner != null) { if (correspondingProperty is Fir2IrLazyProperty && !isFakeOverride && thisReceiverOwner != null) {
populateOverriddenSymbols(thisReceiverOwner) populateOverriddenSymbols(thisReceiverOwner)
} }
} }
@@ -264,7 +264,7 @@ class Fir2IrVisitor(
if (property.isLocal) return visitLocalVariable(property) if (property.isLocal) return visitLocalVariable(property)
val irProperty = declarationStorage.getCachedIrProperty(property)!! val irProperty = declarationStorage.getCachedIrProperty(property)!!
return conversionScope.withProperty(irProperty) { return conversionScope.withProperty(irProperty) {
memberGenerator.convertPropertyContent(irProperty, property) memberGenerator.convertPropertyContent(irProperty, property, containingClass = conversionScope.containerFirClass())
} }
} }
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -188,17 +189,23 @@ internal class ClassMemberGenerator(
return irFunction return irFunction
} }
fun convertPropertyContent(irProperty: IrProperty, property: FirProperty): IrProperty { fun convertPropertyContent(irProperty: IrProperty, property: FirProperty, containingClass: FirClass<*>?): IrProperty {
val initializer = property.initializer val initializer = property.initializer
val delegate = property.delegate val delegate = property.delegate
val propertyType = property.returnTypeRef.toIrType() val propertyType = property.returnTypeRef.toIrType()
irProperty.initializeBackingField(property, initializerExpression = initializer ?: delegate) irProperty.initializeBackingField(property, initializerExpression = initializer ?: delegate)
irProperty.getter?.setPropertyAccessorContent( irProperty.getter?.setPropertyAccessorContent(
property, property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter property, property.getter, irProperty, propertyType,
property.getter is FirDefaultPropertyGetter,
isGetter = true,
containingClass = containingClass
) )
if (property.isVar) { if (property.isVar) {
irProperty.setter?.setPropertyAccessorContent( irProperty.setter?.setPropertyAccessorContent(
property, property.setter, irProperty, propertyType, property.setter is FirDefaultPropertySetter property, property.setter, irProperty, propertyType,
property.setter is FirDefaultPropertySetter,
isGetter = false,
containingClass = containingClass
) )
} }
annotationGenerator.generate(irProperty, property) annotationGenerator.generate(irProperty, property)
@@ -221,12 +228,14 @@ internal class ClassMemberGenerator(
annotationGenerator.generate(irField, property) annotationGenerator.generate(irField, property)
} }
private fun IrFunction.setPropertyAccessorContent( private fun IrSimpleFunction.setPropertyAccessorContent(
property: FirProperty, property: FirProperty,
propertyAccessor: FirPropertyAccessor?, propertyAccessor: FirPropertyAccessor?,
correspondingProperty: IrProperty, correspondingProperty: IrProperty,
propertyType: IrType, propertyType: IrType,
isDefault: Boolean isDefault: Boolean,
isGetter: Boolean,
containingClass: FirClass<*>?
) { ) {
conversionScope.withFunction(this) { conversionScope.withFunction(this) {
applyParentFromStackTo(this) applyParentFromStackTo(this)
@@ -258,6 +267,28 @@ internal class ClassMemberGenerator(
declarationStorage.leaveScope(this) declarationStorage.leaveScope(this)
} }
} }
if (containingClass != null) {
val scope = containingClass.unsubstitutedScope(session, scopeSession)
scope.processPropertiesByName(property.name) {}
val overriddenSet = mutableSetOf<IrSimpleFunctionSymbol>()
scope.processDirectlyOverriddenProperties(property.symbol) {
if (it.fir.visibility == Visibilities.PRIVATE) {
return@processDirectlyOverriddenProperties ProcessorAction.NEXT
}
val overridden = declarationStorage.getIrPropertyOrFieldSymbol(it)
if (overridden is IrPropertySymbol) {
val accessorSymbol =
if (isGetter) overridden.owner.getter?.symbol
else overridden.owner.setter?.symbol
if (accessorSymbol != null) {
overriddenSet += accessorSymbol
}
}
ProcessorAction.NEXT
}
this.overriddenSymbols = overriddenSet.toList()
}
} }
annotationGenerator.generate(this, property) annotationGenerator.generate(this, property)
} }
@@ -21,15 +21,26 @@ class JavaClassMembersEnhancementScope(
private val useSiteMemberScope: JavaClassUseSiteMemberScope, private val useSiteMemberScope: JavaClassUseSiteMemberScope,
) : FirTypeScope() { ) : FirTypeScope() {
private val overriddenFunctions = mutableMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>() private val overriddenFunctions = mutableMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>()
private val overriddenProperties = mutableMapOf<FirPropertySymbol, Collection<FirPropertySymbol>>()
private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableSymbol<*>>>>() private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableSymbol<*>>>>()
private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) { private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) {
overriddenMembers() overriddenMembers(name)
} }
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
useSiteMemberScope.processPropertiesByName(name) process@{ original -> useSiteMemberScope.processPropertiesByName(name) process@{ original ->
processor(signatureEnhancement.enhancedProperty(original, name)) val enhancedPropertySymbol = signatureEnhancement.enhancedProperty(original, name)
if (enhancedPropertySymbol is FirPropertySymbol) {
val enhancedProperty = enhancedPropertySymbol.fir
overriddenProperties[enhancedPropertySymbol] =
enhancedProperty
.overriddenMembers(enhancedProperty.name)
.mapNotNull { it.symbol as? FirPropertySymbol }
}
processor(enhancedPropertySymbol)
} }
return super.processPropertiesByName(name, processor) return super.processPropertiesByName(name, processor)
@@ -37,23 +48,24 @@ class JavaClassMembersEnhancementScope(
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
useSiteMemberScope.processFunctionsByName(name) process@{ original -> useSiteMemberScope.processFunctionsByName(name) process@{ original ->
val enhancedFunction = signatureEnhancement.enhancedFunction(original, name) val enhancedFunctionSymbol = signatureEnhancement.enhancedFunction(original, name)
val enhancedFunction = enhancedFunctionSymbol.fir as? FirSimpleFunction
overriddenFunctions[enhancedFunction] = overriddenFunctions[enhancedFunctionSymbol] =
(enhancedFunction.fir as? FirSimpleFunction) enhancedFunction
?.overriddenMembers() ?.overriddenMembers(enhancedFunction.name)
?.mapNotNull { it.symbol as? FirFunctionSymbol<*> } ?.mapNotNull { it.symbol as? FirFunctionSymbol<*> }
.orEmpty() .orEmpty()
processor(enhancedFunction) processor(enhancedFunctionSymbol)
} }
return super.processFunctionsByName(name, processor) return super.processFunctionsByName(name, processor)
} }
private fun FirSimpleFunction.overriddenMembers(): List<FirCallableMemberDeclaration<*>> { private fun FirCallableMemberDeclaration<*>.overriddenMembers(name: Name): List<FirCallableMemberDeclaration<*>> {
val backMap = overrideBindCache.getOrPut(this.name) { val backMap = overrideBindCache.getOrPut(name) {
useSiteMemberScope.bindOverrides(this.name) useSiteMemberScope.bindOverrides(name)
useSiteMemberScope useSiteMemberScope
.overrideByBase .overrideByBase
.toList() .toList()
@@ -76,5 +88,16 @@ class JavaClassMembersEnhancementScope(
override fun processOverriddenFunctionsWithDepth( override fun processOverriddenFunctionsWithDepth(
functionSymbol: FirFunctionSymbol<*>, functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, overriddenFunctions, useSiteMemberScope) ): ProcessorAction = doProcessOverriddenCallables(
functionSymbol, processor, overriddenFunctions, useSiteMemberScope,
FirTypeScope::processOverriddenFunctionsWithDepth
)
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = doProcessOverriddenCallables(
propertySymbol, processor, overriddenProperties, useSiteMemberScope,
FirTypeScope::processOverriddenPropertiesWithDepth
)
} }
@@ -109,6 +109,9 @@ class JavaClassUseSiteMemberScope(
when (val overriddenBy = it.getOverridden(overrideCandidates)) { when (val overriddenBy = it.getOverridden(overrideCandidates)) {
null -> processor(it) null -> processor(it)
is FirAccessorSymbol -> processor(overriddenBy) is FirAccessorSymbol -> processor(overriddenBy)
is FirPropertySymbol -> if (it is FirPropertySymbol) {
directOverriddenProperties.getOrPut(overriddenBy) { mutableListOf() }.add(it)
}
} }
} }
} }
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class JvmMappedScope( class JvmMappedScope(
@@ -70,6 +67,11 @@ class JvmMappedScope(
declaredMemberScope.processPropertiesByName(name, processor) declaredMemberScope.processPropertiesByName(name, processor)
} }
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NONE
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor) declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
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.FirPropertyBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
abstract class AbstractFirOverrideScope( abstract class AbstractFirOverrideScope(
@@ -92,4 +94,23 @@ abstract class AbstractFirOverrideScope(
isVararg = parameter.isVararg isVararg = parameter.isVararg
} }
protected open fun createPropertyCopy(
firProperty: FirProperty,
newSymbol: FirPropertySymbol
): FirPropertyBuilder =
FirPropertyBuilder().apply {
source = firProperty.source
session = firProperty.session
origin = FirDeclarationOrigin.FakeOverride
returnTypeRef = firProperty.returnTypeRef
receiverTypeRef = firProperty.receiverTypeRef
isVar = firProperty.isVar
isLocal = firProperty.isLocal
getter = firProperty.getter
setter = firProperty.setter
name = firProperty.name
status = firProperty.status
symbol = newSymbol
}
} }
@@ -24,7 +24,8 @@ abstract class AbstractFirUseSiteMemberScope(
) : AbstractFirOverrideScope(session, overrideChecker) { ) : AbstractFirOverrideScope(session, overrideChecker) {
private val functions = hashMapOf<Name, Collection<FirFunctionSymbol<*>>>() private val functions = hashMapOf<Name, Collection<FirFunctionSymbol<*>>>()
private val directOverridden = hashMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>() private val directOverriddenFunctions = hashMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>()
protected val directOverriddenProperties = hashMapOf<FirPropertySymbol, MutableList<FirPropertySymbol>>()
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
functions.getOrPut(name) { functions.getOrPut(name) {
@@ -41,7 +42,7 @@ abstract class AbstractFirUseSiteMemberScope(
declaredMemberScope.processFunctionsByName(name) { declaredMemberScope.processFunctionsByName(name) {
if (it.isStatic) return@processFunctionsByName if (it.isStatic) return@processFunctionsByName
val directOverridden = computeDirectOverridden(it) val directOverridden = computeDirectOverridden(it)
this@AbstractFirUseSiteMemberScope.directOverridden[it] = directOverridden this@AbstractFirUseSiteMemberScope.directOverriddenFunctions[it] = directOverridden
val symbol = processInheritedDefaultParameters(it, directOverridden) val symbol = processInheritedDefaultParameters(it, directOverridden)
overrideCandidates += symbol overrideCandidates += symbol
add(symbol) add(symbol)
@@ -106,7 +107,20 @@ abstract class AbstractFirUseSiteMemberScope(
override fun processOverriddenFunctionsWithDepth( override fun processOverriddenFunctionsWithDepth(
functionSymbol: FirFunctionSymbol<*>, functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, directOverridden, superTypesScope) ): ProcessorAction =
doProcessOverriddenCallables(
functionSymbol, processor, directOverriddenFunctions, superTypesScope,
FirTypeScope::processOverriddenFunctionsWithDepth
)
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction =
doProcessOverriddenCallables(
propertySymbol, processor, directOverriddenProperties, superTypesScope,
FirTypeScope::processOverriddenPropertiesWithDepth
)
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor) declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
@@ -102,6 +102,22 @@ class FirClassSubstitutionScope(
} }
} }
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction {
if (!useSiteMemberScope.processOverriddenPropertiesWithDepth(propertySymbol, processor)) {
return ProcessorAction.STOP
}
val unwrapped = propertySymbol.overriddenSymbol ?: return ProcessorAction.NEXT
if (!processor(unwrapped, 1)) {
return ProcessorAction.STOP
}
return useSiteMemberScope.processOverriddenPropertiesWithDepth(unwrapped) { symbol, depth ->
processor(symbol, depth + 1)
}
}
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
useSiteMemberScope.processClassifiersByNameWithSubstitution(name) { symbol, substitutor -> useSiteMemberScope.processClassifiersByNameWithSubstitution(name) { symbol, substitutor ->
processor(symbol, substitutor.chain(this.substitutor)) processor(symbol, substitutor.chain(this.substitutor))
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.isStatic import org.jetbrains.kotlin.fir.symbols.impl.isStatic
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -30,6 +31,8 @@ class FirClassUseSiteMemberScope(
val overriddenBy = it.getOverridden(seen) val overriddenBy = it.getOverridden(seen)
if (overriddenBy == null) { if (overriddenBy == null) {
processor(it) processor(it)
} else if (overriddenBy is FirPropertySymbol && it is FirPropertySymbol) {
directOverriddenProperties.getOrPut(overriddenBy) { mutableListOf() }.add(it)
} }
} }
} }
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl
@@ -100,6 +101,11 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned
functionSymbol: FirFunctionSymbol<*>, functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT ): ProcessorAction = ProcessorAction.NEXT
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT
} }
@OptIn(FirImplementationDetail::class) @OptIn(FirImplementationDetail::class)
@@ -38,7 +38,7 @@ class FirTypeIntersectionScope private constructor(
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<FirCallableSymbol<*>>> = mutableMapOf() private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<FirCallableSymbol<*>>> = mutableMapOf()
private val intersectionOverrides: MutableMap<FirNamedFunctionSymbol, FirNamedFunctionSymbol> = mutableMapOf() private val intersectionOverrides: MutableMap<FirCallableSymbol<*>, FirCallableSymbol<*>> = mutableMapOf()
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
if (!processCallablesByName(name, processor, absentFunctions, FirScope::processFunctionsByName)) { if (!processCallablesByName(name, processor, absentFunctions, FirScope::processFunctionsByName)) {
@@ -94,11 +94,20 @@ class FirTypeIntersectionScope private constructor(
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers) val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers)
val mostSpecific = selectMostSpecificMember(extractedOverrides) val mostSpecific = selectMostSpecificMember(extractedOverrides)
if (extractedOverrides.size > 1 && mostSpecific is FirNamedFunctionSymbol) { if (extractedOverrides.size > 1) {
// TODO: same code for properties
val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) { val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
createIntersectionOverride(mostSpecific, extractedOverrides as Collection<FirNamedFunctionSymbol>) when (mostSpecific) {
is FirNamedFunctionSymbol -> {
createIntersectionOverride(mostSpecific, extractedOverrides as Collection<FirNamedFunctionSymbol>)
}
is FirPropertySymbol -> {
createIntersectionOverride(mostSpecific)
}
else -> {
throw IllegalStateException("Should not be here")
}
}
} }
overriddenSymbols[intersectionOverride] = extractedOverrides overriddenSymbols[intersectionOverride] = extractedOverrides
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -140,6 +149,17 @@ class FirTypeIntersectionScope private constructor(
return newSymbol return newSymbol
} }
private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol {
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific)
val mostSpecificProperty = mostSpecific.fir
createPropertyCopy(mostSpecific.fir, newSymbol).apply {
resolvePhase = mostSpecificProperty.resolvePhase
origin = FirDeclarationOrigin.IntersectionOverride
typeParameters += mostSpecificProperty.typeParameters
}.build()
return newSymbol
}
private fun <D : FirCallableSymbol<*>> selectMostSpecificMember(overridables: Collection<D>): D { private fun <D : FirCallableSymbol<*>> selectMostSpecificMember(overridables: Collection<D>): D {
require(overridables.isNotEmpty()) { "Should have at least one overridable symbol" } require(overridables.isNotEmpty()) { "Should have at least one overridable symbol" }
if (overridables.size == 1) { if (overridables.size == 1) {
@@ -275,8 +295,8 @@ class FirTypeIntersectionScope private constructor(
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun getDirectOverriddenSymbols(functionSymbol: FirFunctionSymbol<*>): Collection<FirFunctionSymbol<*>> = private fun <S : FirCallableSymbol<*>> getDirectOverriddenSymbols(symbol: S): Collection<S> =
overriddenSymbols[functionSymbol].orEmpty() as Collection<FirFunctionSymbol<*>> overriddenSymbols[symbol].orEmpty() as Collection<S>
override fun processOverriddenFunctionsWithDepth( override fun processOverriddenFunctionsWithDepth(
functionSymbol: FirFunctionSymbol<*>, functionSymbol: FirFunctionSymbol<*>,
@@ -297,6 +317,25 @@ class FirTypeIntersectionScope private constructor(
return ProcessorAction.NEXT return ProcessorAction.NEXT
} }
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction {
for (overridden in getDirectOverriddenSymbols(propertySymbol)) {
val overriddenDepth = if (overridden.overriddenSymbol != null) 0 else 1
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
// TODO: Preserve the scope where directOverridden came from
for (scope in scopes) {
if (!scope.processOverriddenPropertiesWithDepth(overridden) { symbol, depth ->
processor(symbol, depth + overriddenDepth)
}
) return ProcessorAction.STOP
}
}
return ProcessorAction.NEXT
}
companion object { companion object {
fun prepareIntersectionScope( fun prepareIntersectionScope(
session: FirSession, session: FirSession,
@@ -5,11 +5,12 @@
package org.jetbrains.kotlin.fir.scopes package org.jetbrains.kotlin.fir.scopes
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
abstract class FirTypeScope : FirScope() { abstract class FirTypeScope : FirScope() {
// Currently, this function has very weak guarantees // Currently, this function and its property brother both have very weak guarantees
// - It may silently do nothing on symbols originated from different scope instance // - It may silently do nothing on symbols originated from different scope instance
// - It may return the same overridden symbols more then once in case of substitution // - It may return the same overridden symbols more then once in case of substitution
// - It doesn't guarantee any specific order in which overridden tree will be traversed // - It doesn't guarantee any specific order in which overridden tree will be traversed
@@ -38,26 +39,51 @@ abstract class FirTypeScope : FirScope() {
} }
} }
// This is just a helper for a common implementation // ------------------------------------------------------------------------------------
protected fun doProcessOverriddenFunctions(
functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction,
directOverriddenMap: Map<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>,
baseScope: FirTypeScope
): ProcessorAction {
val directOverridden =
directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor)
for (overridden in directOverridden) { abstract fun processOverriddenPropertiesWithDepth(
val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.overriddenSymbol != null) 0 else 1 propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction
inline fun processOverriddenProperties(
propertySymbol: FirPropertySymbol,
crossinline processor: (FirPropertySymbol) -> ProcessorAction
): ProcessorAction = processOverriddenPropertiesWithDepth(propertySymbol) { symbol, _ ->
processor(symbol)
}
inline fun processDirectlyOverriddenProperties(
propertySymbol: FirPropertySymbol,
crossinline processor: (FirPropertySymbol) -> ProcessorAction
): ProcessorAction = processOverriddenPropertiesWithDepth(propertySymbol) { symbol, depth ->
if (depth == 1) {
processor(symbol)
} else {
ProcessorAction.NEXT
}
}
// ------------------------------------------------------------------------------------
// This is just a helper for a common implementation
protected fun <S : FirCallableSymbol<*>> doProcessOverriddenCallables(
callableSymbol: S,
processor: (S, Int) -> ProcessorAction,
directOverriddenMap: Map<S, Collection<S>>,
baseScope: FirTypeScope,
processOverriddenCallablesWithDepth: FirTypeScope.(S, (S, Int) -> ProcessorAction) -> ProcessorAction
): ProcessorAction {
for (overridden in directOverriddenMap[callableSymbol].orEmpty()) {
val overriddenDepth = if (overridden.overriddenSymbol != null) 0 else 1
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
if (!baseScope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth -> if (!baseScope.processOverriddenCallablesWithDepth(overridden) { symbol, depth ->
processor(symbol, depth + overriddenDepth) processor(symbol, depth + overriddenDepth)
} }
) return ProcessorAction.STOP ) return ProcessorAction.STOP
} }
return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor) return baseScope.processOverriddenCallablesWithDepth(callableSymbol, processor)
} }
object Empty : FirTypeScope() { object Empty : FirTypeScope() {
@@ -65,5 +91,10 @@ abstract class FirTypeScope : FirScope() {
functionSymbol: FirFunctionSymbol<*>, functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT ): ProcessorAction = ProcessorAction.NEXT
override fun processOverriddenPropertiesWithDepth(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, Int) -> ProcessorAction
): ProcessorAction = ProcessorAction.NEXT
} }
} }