FIR: Rework overridden members processing in FirTypeScope
Now, FirTypeScope returns only direct overridden and a base scope where a client might look for deeper overridden It's necessary to make the API fast and simple when only direct overridden are needed At the same time, while this API looks a bit complicated for most of the clients there are simple extension helpers that obtain just the direct or all overridden
This commit is contained in:
@@ -17,8 +17,8 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
||||||
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.scopes.processOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.processDirectlyOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
|
||||||
@@ -39,7 +40,6 @@ import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassPublicSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassPublicSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||||
@@ -306,7 +306,7 @@ internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(
|
|||||||
if ((it.fir as FirSimpleFunction).visibility == Visibilities.PRIVATE) {
|
if ((it.fir as FirSimpleFunction).visibility == Visibilities.PRIVATE) {
|
||||||
return@processDirectlyOverriddenFunctions ProcessorAction.NEXT
|
return@processDirectlyOverriddenFunctions ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
val overridden = declarationStorage.getIrFunctionSymbol(it)
|
val overridden = declarationStorage.getIrFunctionSymbol(it.unwrapSubstitutionOverrides())
|
||||||
overriddenSet += overridden as IrSimpleFunctionSymbol
|
overriddenSet += overridden as IrSimpleFunctionSymbol
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -16,8 +16,10 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
|||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.processDirectlyOverriddenProperties
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.unwrapSubstitutionOverrides
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
@@ -269,7 +271,7 @@ internal class ClassMemberGenerator(
|
|||||||
if (it.fir.visibility == Visibilities.PRIVATE) {
|
if (it.fir.visibility == Visibilities.PRIVATE) {
|
||||||
return@processDirectlyOverriddenProperties ProcessorAction.NEXT
|
return@processDirectlyOverriddenProperties ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
val overridden = declarationStorage.getIrPropertyOrFieldSymbol(it)
|
val overridden = declarationStorage.getIrPropertyOrFieldSymbol(it.unwrapSubstitutionOverrides())
|
||||||
if (overridden is IrPropertySymbol) {
|
if (overridden is IrPropertySymbol) {
|
||||||
val accessorSymbol =
|
val accessorSymbol =
|
||||||
if (isGetter) overridden.owner.getter?.symbol
|
if (isGetter) overridden.owner.getter?.symbol
|
||||||
|
|||||||
+11
-10
@@ -85,20 +85,21 @@ class JavaClassMembersEnhancementScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = doProcessOverriddenCallables(
|
): ProcessorAction =
|
||||||
functionSymbol, processor, overriddenFunctions, useSiteMemberScope,
|
doProcessDirectOverriddenCallables(
|
||||||
FirTypeScope::processOverriddenFunctionsWithDepth
|
functionSymbol, processor, overriddenFunctions, useSiteMemberScope,
|
||||||
)
|
FirTypeScope::processDirectOverriddenFunctionsWithBaseScope
|
||||||
|
)
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = doProcessOverriddenCallables(
|
): ProcessorAction = doProcessDirectOverriddenCallables(
|
||||||
propertySymbol, processor, overriddenProperties, useSiteMemberScope,
|
propertySymbol, processor, overriddenProperties, useSiteMemberScope,
|
||||||
FirTypeScope::processOverriddenPropertiesWithDepth
|
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getCallableNames(): Set<Name> {
|
override fun getCallableNames(): Set<Name> {
|
||||||
|
|||||||
@@ -34,12 +34,9 @@ class JvmMappedScope(
|
|||||||
declaredMemberScope.processFunctionsByName(name, processor)
|
declaredMemberScope.processFunctionsByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JvmMappedScope is basically used as declaration scope but it's being wrapped into substitution scopes where
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
// a use-site (FirOverrideAwareScope) is expected
|
|
||||||
// So, we put here a stub implementation
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
) = ProcessorAction.NONE
|
) = ProcessorAction.NONE
|
||||||
|
|
||||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
@@ -65,9 +62,9 @@ class JvmMappedScope(
|
|||||||
declaredMemberScope.processPropertiesByName(name, processor)
|
declaredMemberScope.processPropertiesByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = ProcessorAction.NONE
|
): ProcessorAction = ProcessorAction.NONE
|
||||||
|
|
||||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
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.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||||
|
|||||||
+8
-8
@@ -101,22 +101,22 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
return newSymbol
|
return newSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction =
|
): ProcessorAction =
|
||||||
doProcessOverriddenCallables(
|
doProcessDirectOverriddenCallables(
|
||||||
functionSymbol, processor, directOverriddenFunctions, superTypesScope,
|
functionSymbol, processor, directOverriddenFunctions, superTypesScope,
|
||||||
FirTypeScope::processOverriddenFunctionsWithDepth
|
FirTypeScope::processDirectOverriddenFunctionsWithBaseScope
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction =
|
): ProcessorAction =
|
||||||
doProcessOverriddenCallables(
|
doProcessDirectOverriddenCallables(
|
||||||
propertySymbol, processor, directOverriddenProperties, superTypesScope,
|
propertySymbol, processor, directOverriddenProperties, superTypesScope,
|
||||||
FirTypeScope::processOverriddenPropertiesWithDepth
|
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||||
|
|||||||
+29
-33
@@ -26,7 +26,6 @@ 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.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.fakeElement
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -42,9 +41,7 @@ class FirClassSubstitutionScope(
|
|||||||
|
|
||||||
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
|
||||||
private val fakeOverrideConstructors = mutableMapOf<FirConstructorSymbol, FirConstructorSymbol>()
|
private val fakeOverrideConstructors = mutableMapOf<FirConstructorSymbol, FirConstructorSymbol>()
|
||||||
private val fakeOverrideProperties = mutableMapOf<FirPropertySymbol, FirPropertySymbol>()
|
private val fakeOverrideVariables = mutableMapOf<FirVariableSymbol<*>, FirVariableSymbol<*>>()
|
||||||
private val fakeOverrideFields = mutableMapOf<FirFieldSymbol, FirFieldSymbol>()
|
|
||||||
private val fakeOverrideAccessors = mutableMapOf<FirAccessorSymbol, FirAccessorSymbol>()
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
session: FirSession, useSiteMemberScope: FirTypeScope, scopeSession: ScopeSession,
|
session: FirSession, useSiteMemberScope: FirTypeScope, scopeSession: ScopeSession,
|
||||||
@@ -61,35 +58,41 @@ class FirClassSubstitutionScope(
|
|||||||
return super.processFunctionsByName(name, processor)
|
return super.processFunctionsByName(name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
|
): ProcessorAction =
|
||||||
|
processDirectOverriddenWithBaseScope(
|
||||||
|
functionSymbol, processor, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, fakeOverrideFunctions
|
||||||
|
)
|
||||||
|
|
||||||
|
private inline fun <reified D : FirCallableSymbol<*>> processDirectOverriddenWithBaseScope(
|
||||||
|
callableSymbol: D,
|
||||||
|
noinline processor: (D, FirTypeScope) -> ProcessorAction,
|
||||||
|
processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(D, ((D, FirTypeScope) -> ProcessorAction)) -> ProcessorAction,
|
||||||
|
fakeOverridesMap: Map<out FirCallableSymbol<*>, FirCallableSymbol<*>>
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
if (!useSiteMemberScope.processOverriddenFunctionsWithDepth(functionSymbol, processor)) {
|
val original = (callableSymbol.overriddenSymbol as? D)?.takeIf { it in fakeOverridesMap }
|
||||||
return ProcessorAction.STOP
|
?: return useSiteMemberScope.processDirectOverriddenCallablesWithBaseScope(callableSymbol, processor)
|
||||||
}
|
|
||||||
val unwrapped = functionSymbol.overriddenSymbol as FirFunctionSymbol<*>? ?: return ProcessorAction.NEXT
|
if (!processor(original, useSiteMemberScope)) return ProcessorAction.STOP
|
||||||
if (!processor(unwrapped, 1)) {
|
|
||||||
return ProcessorAction.STOP
|
return useSiteMemberScope.processDirectOverriddenCallablesWithBaseScope(original, processor)
|
||||||
}
|
|
||||||
return useSiteMemberScope.processOverriddenFunctionsWithDepth(unwrapped) { symbol, depth ->
|
|
||||||
processor(symbol, depth + 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
return useSiteMemberScope.processPropertiesByName(name) process@{ original ->
|
return useSiteMemberScope.processPropertiesByName(name) process@{ original ->
|
||||||
when (original) {
|
when (original) {
|
||||||
is FirPropertySymbol -> {
|
is FirPropertySymbol -> {
|
||||||
val property = fakeOverrideProperties.getOrPut(original) { createFakeOverrideProperty(original) }
|
val property = fakeOverrideVariables.getOrPut(original) { createFakeOverrideProperty(original) }
|
||||||
processor(property)
|
processor(property)
|
||||||
}
|
}
|
||||||
is FirFieldSymbol -> {
|
is FirFieldSymbol -> {
|
||||||
val field = fakeOverrideFields.getOrPut(original) { createFakeOverrideField(original) }
|
val field = fakeOverrideVariables.getOrPut(original) { createFakeOverrideField(original) }
|
||||||
processor(field)
|
processor(field)
|
||||||
}
|
}
|
||||||
is FirAccessorSymbol -> {
|
is FirAccessorSymbol -> {
|
||||||
val accessor = fakeOverrideAccessors.getOrPut(original) { createFakeOverrideAccessor(original) }
|
val accessor = fakeOverrideVariables.getOrPut(original) { createFakeOverrideAccessor(original) }
|
||||||
processor(accessor)
|
processor(accessor)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -99,21 +102,14 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction =
|
||||||
if (!useSiteMemberScope.processOverriddenPropertiesWithDepth(propertySymbol, processor)) {
|
processDirectOverriddenWithBaseScope(
|
||||||
return ProcessorAction.STOP
|
propertySymbol, processor, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope,
|
||||||
}
|
fakeOverrideVariables
|
||||||
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 ->
|
||||||
|
|||||||
+4
-4
@@ -97,14 +97,14 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned
|
|||||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = ProcessorAction.NEXT
|
): ProcessorAction = ProcessorAction.NEXT
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = ProcessorAction.NEXT
|
): ProcessorAction = ProcessorAction.NEXT
|
||||||
|
|
||||||
override fun getCallableNames(): Set<Name> = ALL_OPERATORS.keys
|
override fun getCallableNames(): Set<Name> = ALL_OPERATORS.keys
|
||||||
|
|||||||
+88
-68
@@ -17,11 +17,13 @@ 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.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
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.ConeFlexibleType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
@@ -36,9 +38,9 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
|
|
||||||
private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
||||||
|
|
||||||
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<FirCallableSymbol<*>>> = mutableMapOf()
|
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> = mutableMapOf()
|
||||||
|
|
||||||
private val intersectionOverrides: MutableMap<FirCallableSymbol<*>, FirCallableSymbol<*>> = mutableMapOf()
|
private val intersectionOverrides: MutableMap<FirCallableSymbol<*>, MemberWithBaseScope<out 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)) {
|
||||||
@@ -70,7 +72,9 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultForScope.takeIf { it.isNotEmpty() }
|
resultForScope.takeIf { it.isNotEmpty() }?.let {
|
||||||
|
scope to it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (membersByScope.isEmpty()) {
|
if (membersByScope.isEmpty()) {
|
||||||
@@ -78,28 +82,33 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
membersByScope.singleOrNull()?.let { members ->
|
membersByScope.singleOrNull()?.let { (scope, members) ->
|
||||||
for (member in members) {
|
for (member in members) {
|
||||||
overriddenSymbols[member] = listOf(member)
|
overriddenSymbols[member] = listOf(MemberWithBaseScope(member, scope))
|
||||||
processor(member)
|
processor(member)
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val allMembers = membersByScope.flattenTo(LinkedList())
|
val allMembersWithScope = membersByScope.flatMapTo(mutableListOf()) { (scope, members) ->
|
||||||
|
members.map { MemberWithBaseScope(it, scope) }
|
||||||
|
}
|
||||||
|
|
||||||
while (allMembers.isNotEmpty()) {
|
while (allMembersWithScope.isNotEmpty()) {
|
||||||
val maxByVisibility = findMemberWithMaxVisibility(allMembers)
|
val maxByVisibility = findMemberWithMaxVisibility(allMembersWithScope)
|
||||||
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers)
|
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembersWithScope)
|
||||||
|
|
||||||
val mostSpecific = selectMostSpecificMember(extractedOverrides)
|
val (mostSpecific, scopeForMostSpecific) = selectMostSpecificMember(extractedOverrides)
|
||||||
if (extractedOverrides.size > 1) {
|
if (extractedOverrides.size > 1) {
|
||||||
val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) {
|
val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
when (mostSpecific) {
|
when (mostSpecific) {
|
||||||
is FirNamedFunctionSymbol -> {
|
is FirNamedFunctionSymbol -> {
|
||||||
createIntersectionOverride(mostSpecific, extractedOverrides as Collection<FirNamedFunctionSymbol>)
|
createIntersectionOverride(
|
||||||
|
mostSpecific,
|
||||||
|
extractedOverrides as Collection<MemberWithBaseScope<FirNamedFunctionSymbol>>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is FirPropertySymbol -> {
|
is FirPropertySymbol -> {
|
||||||
createIntersectionOverride(mostSpecific)
|
createIntersectionOverride(mostSpecific)
|
||||||
@@ -107,11 +116,11 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException("Should not be here")
|
throw IllegalStateException("Should not be here")
|
||||||
}
|
}
|
||||||
}
|
}.withScope(scopeForMostSpecific)
|
||||||
}
|
}
|
||||||
overriddenSymbols[intersectionOverride] = extractedOverrides
|
overriddenSymbols[intersectionOverride.member] = extractedOverrides
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
processor(intersectionOverride as D)
|
processor(intersectionOverride.member as D)
|
||||||
} else {
|
} else {
|
||||||
overriddenSymbols[mostSpecific] = extractedOverrides
|
overriddenSymbols[mostSpecific] = extractedOverrides
|
||||||
processor(mostSpecific)
|
processor(mostSpecific)
|
||||||
@@ -123,9 +132,15 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
|
|
||||||
private fun createIntersectionOverride(
|
private fun createIntersectionOverride(
|
||||||
mostSpecific: FirNamedFunctionSymbol,
|
mostSpecific: FirNamedFunctionSymbol,
|
||||||
extractedOverrides: Collection<FirNamedFunctionSymbol>
|
extractedOverrides: Collection<MemberWithBaseScope<FirNamedFunctionSymbol>>
|
||||||
): FirNamedFunctionSymbol {
|
): FirNamedFunctionSymbol {
|
||||||
val newSymbol = FirNamedFunctionSymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific)
|
val newSymbol =
|
||||||
|
FirNamedFunctionSymbol(
|
||||||
|
mostSpecific.callableId,
|
||||||
|
mostSpecific.isFakeOverride,
|
||||||
|
mostSpecific,
|
||||||
|
isIntersectionOverride = true
|
||||||
|
)
|
||||||
val mostSpecificFunction = mostSpecific.fir
|
val mostSpecificFunction = mostSpecific.fir
|
||||||
createFunctionCopy(mostSpecific.fir, newSymbol).apply {
|
createFunctionCopy(mostSpecific.fir, newSymbol).apply {
|
||||||
resolvePhase = mostSpecificFunction.resolvePhase
|
resolvePhase = mostSpecificFunction.resolvePhase
|
||||||
@@ -134,8 +149,8 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
valueParameters += mostSpecificFunction.valueParameters.mapIndexed { index, mostSpecificParameter ->
|
valueParameters += mostSpecificFunction.valueParameters.mapIndexed { index, mostSpecificParameter ->
|
||||||
val overriddenWithDefault =
|
val overriddenWithDefault =
|
||||||
extractedOverrides.firstOrNull {
|
extractedOverrides.firstOrNull {
|
||||||
it.fir.valueParameters.getOrNull(index)?.defaultValue != null
|
it.member.fir.valueParameters.getOrNull(index)?.defaultValue != null
|
||||||
}?.fir
|
}?.member?.fir
|
||||||
if (overriddenWithDefault == null) {
|
if (overriddenWithDefault == null) {
|
||||||
mostSpecificParameter
|
mostSpecificParameter
|
||||||
} else {
|
} else {
|
||||||
@@ -150,7 +165,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol {
|
private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol {
|
||||||
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific)
|
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
|
||||||
val mostSpecificProperty = mostSpecific.fir
|
val mostSpecificProperty = mostSpecific.fir
|
||||||
createPropertyCopy(mostSpecific.fir, newSymbol).apply {
|
createPropertyCopy(mostSpecific.fir, newSymbol).apply {
|
||||||
resolvePhase = mostSpecificProperty.resolvePhase
|
resolvePhase = mostSpecificProperty.resolvePhase
|
||||||
@@ -160,21 +175,23 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
return newSymbol
|
return newSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : FirCallableSymbol<*>> selectMostSpecificMember(overridables: Collection<D>): D {
|
private fun <D : FirCallableSymbol<*>> selectMostSpecificMember(overridables: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<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) {
|
||||||
return overridables.first()
|
return overridables.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
val candidates: MutableCollection<D> = ArrayList(2)
|
val candidates: MutableCollection<MemberWithBaseScope<D>> = ArrayList(2)
|
||||||
var transitivelyMostSpecific: D = overridables.first()
|
var transitivelyMostSpecific: MemberWithBaseScope<D> = overridables.first()
|
||||||
|
|
||||||
for (candidate in overridables) {
|
for (candidate in overridables) {
|
||||||
if (overridables.all { isMoreSpecific(candidate, it) }) {
|
if (overridables.all { isMoreSpecific(candidate.member, it.member) }) {
|
||||||
candidates.add(candidate)
|
candidates.add(candidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMoreSpecific(candidate, transitivelyMostSpecific) && !isMoreSpecific(transitivelyMostSpecific, candidate)) {
|
if (isMoreSpecific(candidate.member, transitivelyMostSpecific.member) &&
|
||||||
|
!isMoreSpecific(transitivelyMostSpecific.member, candidate.member)
|
||||||
|
) {
|
||||||
transitivelyMostSpecific = candidate
|
transitivelyMostSpecific = candidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +201,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
candidates.size == 1 -> candidates.first()
|
candidates.size == 1 -> candidates.first()
|
||||||
else -> {
|
else -> {
|
||||||
candidates.firstOrNull {
|
candidates.firstOrNull {
|
||||||
val type = it.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
val type = it.member.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
type != null && type !is ConeFlexibleType
|
type != null && type !is ConeFlexibleType
|
||||||
}?.let { return it }
|
}?.let { return it }
|
||||||
candidates.first()
|
candidates.first()
|
||||||
@@ -224,10 +241,10 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
||||||
AbstractTypeChecker.isSubtypeOf(typeContext as AbstractTypeCheckerContext, a, b)
|
AbstractTypeChecker.isSubtypeOf(typeContext as AbstractTypeCheckerContext, a, b)
|
||||||
|
|
||||||
private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<D>): D {
|
private fun <D : FirCallableSymbol<*>> findMemberWithMaxVisibility(members: Collection<MemberWithBaseScope<D>>): MemberWithBaseScope<D> {
|
||||||
assert(members.isNotEmpty())
|
assert(members.isNotEmpty())
|
||||||
|
|
||||||
var member: D? = null
|
var member: MemberWithBaseScope<D>? = null
|
||||||
for (candidate in members) {
|
for (candidate in members) {
|
||||||
if (member == null) {
|
if (member == null) {
|
||||||
member = candidate
|
member = candidate
|
||||||
@@ -235,8 +252,8 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val result = Visibilities.compare(
|
val result = Visibilities.compare(
|
||||||
(member.fir as FirCallableMemberDeclaration<*>).status.visibility,
|
(member.member.fir as FirCallableMemberDeclaration<*>).status.visibility,
|
||||||
(candidate.fir as FirCallableMemberDeclaration<*>).status.visibility
|
(candidate.member.fir as FirCallableMemberDeclaration<*>).status.visibility
|
||||||
)
|
)
|
||||||
if (result != null && result < 0) {
|
if (result != null && result < 0) {
|
||||||
member = candidate
|
member = candidate
|
||||||
@@ -246,14 +263,14 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : FirCallableSymbol<*>> extractBothWaysOverridable(
|
private fun <D : FirCallableSymbol<*>> extractBothWaysOverridable(
|
||||||
overrider: D,
|
overrider: MemberWithBaseScope<D>,
|
||||||
members: MutableCollection<D>
|
members: MutableCollection<MemberWithBaseScope<D>>
|
||||||
): Collection<D> {
|
): Collection<MemberWithBaseScope<D>> {
|
||||||
val result = mutableListOf<D>().apply { add(overrider) }
|
val result = mutableListOf<MemberWithBaseScope<D>>().apply { add(overrider) }
|
||||||
|
|
||||||
val iterator = members.iterator()
|
val iterator = members.iterator()
|
||||||
|
|
||||||
val overrideCandidate = overrider.fir as FirCallableMemberDeclaration<*>
|
val overrideCandidate = overrider.member.fir as FirCallableMemberDeclaration<*>
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val next = iterator.next()
|
val next = iterator.next()
|
||||||
if (next == overrider) {
|
if (next == overrider) {
|
||||||
@@ -261,7 +278,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (similarFunctionsOrBothProperties(overrideCandidate, next.fir as FirCallableMemberDeclaration<*>)) {
|
if (similarFunctionsOrBothProperties(overrideCandidate, next.member.fir as FirCallableMemberDeclaration<*>)) {
|
||||||
result.add(next)
|
result.add(next)
|
||||||
iterator.remove()
|
iterator.remove()
|
||||||
}
|
}
|
||||||
@@ -295,46 +312,42 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun <S : FirCallableSymbol<*>> getDirectOverriddenSymbols(symbol: S): Collection<S> {
|
private fun <S : FirCallableSymbol<*>> getDirectOverriddenSymbols(symbol: S): Collection<MemberWithBaseScope<S>> {
|
||||||
val intersectionOverride = intersectionOverrides[symbol]
|
val intersectionOverride = intersectionOverrides[symbol]
|
||||||
val allDirectOverridden = overriddenSymbols[symbol].orEmpty() + intersectionOverride?.let {
|
val allDirectOverridden = overriddenSymbols[symbol].orEmpty() + intersectionOverride?.let {
|
||||||
overriddenSymbols[it]
|
overriddenSymbols[it.member]
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
return allDirectOverridden as Collection<S>
|
return allDirectOverridden as Collection<MemberWithBaseScope<S>>
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction =
|
||||||
for (overridden in getDirectOverriddenSymbols(functionSymbol)) {
|
processDirectOverriddenCallablesCallablesWithBaseScope(
|
||||||
val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.overriddenSymbol != null) 0 else 1
|
functionSymbol, processor,
|
||||||
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
|
FirTypeScope::processDirectOverriddenFunctionsWithBaseScope
|
||||||
// TODO: Preserve the scope where directOverridden came from
|
)
|
||||||
for (scope in scopes) {
|
|
||||||
if (!scope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
|
|
||||||
processor(symbol, depth + overriddenDepth)
|
|
||||||
}
|
|
||||||
) return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ProcessorAction.NEXT
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
}
|
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
|
): ProcessorAction =
|
||||||
|
processDirectOverriddenCallablesCallablesWithBaseScope(
|
||||||
|
propertySymbol, processor,
|
||||||
|
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun <D : FirCallableSymbol<*>> processDirectOverriddenCallablesCallablesWithBaseScope(
|
||||||
|
callableSymbol: D,
|
||||||
|
processor: (D, FirTypeScope) -> ProcessorAction,
|
||||||
|
processDirectOverriddenInBaseScope: FirTypeScope.(D, ((D, FirTypeScope) -> ProcessorAction)) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
for (overridden in getDirectOverriddenSymbols(propertySymbol)) {
|
for ((overridden, baseScope) in getDirectOverriddenSymbols(callableSymbol)) {
|
||||||
val overriddenDepth = if (overridden.overriddenSymbol != null) 0 else 1
|
if (overridden === callableSymbol) {
|
||||||
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
|
if (!baseScope.processDirectOverriddenInBaseScope(callableSymbol, processor)) return ProcessorAction.STOP
|
||||||
// TODO: Preserve the scope where directOverridden came from
|
} else {
|
||||||
for (scope in scopes) {
|
if (!processor(overridden, baseScope)) return ProcessorAction.STOP
|
||||||
if (!scope.processOverriddenPropertiesWithDepth(overridden) { symbol, depth ->
|
|
||||||
processor(symbol, depth + overriddenDepth)
|
|
||||||
}
|
|
||||||
) return ProcessorAction.STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,3 +373,10 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class MemberWithBaseScope<D : FirCallableSymbol<*>>(val member: D, private val baseScope: FirTypeScope) {
|
||||||
|
operator fun component1() = member
|
||||||
|
operator fun component2() = baseScope
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <D : FirCallableSymbol<*>> D.withScope(baseScope: FirTypeScope) = MemberWithBaseScope(this, baseScope)
|
||||||
|
|||||||
@@ -11,95 +11,121 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
abstract class FirTypeScope : FirScope(), FirContainingNamesAwareScope {
|
abstract class FirTypeScope : FirScope(), FirContainingNamesAwareScope {
|
||||||
|
// If the scope instance is the same as the one from which the symbol was originated, this function supplies
|
||||||
|
// all direct overridden members (each of them comes a base scope where grand-parents [overridden of this overridden] may be obtained from)
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// interface A { fun foo() }
|
||||||
|
// interface B : A { override fun foo() }
|
||||||
|
// interface C : B { override fun foo() }
|
||||||
|
//
|
||||||
|
// Here, for override C::foo from a scope of C, processor will receiver B::foo and scope for B
|
||||||
|
// Then, for B::foo from scope for B one may receive override A::foo and scope for A
|
||||||
|
//
|
||||||
// Currently, this function and its property brother both have 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
|
abstract fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
// But if the scope instance is the same as the one from which the symbol was originated, this function will enumarate all members
|
|
||||||
// of the overridden tree
|
|
||||||
abstract fun processOverriddenFunctionsWithDepth(
|
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction
|
): ProcessorAction
|
||||||
|
|
||||||
inline fun processOverriddenFunctions(
|
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
|
||||||
crossinline processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
|
||||||
): ProcessorAction = processOverriddenFunctionsWithDepth(functionSymbol) { symbol, _ ->
|
|
||||||
processor(symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun processDirectlyOverriddenFunctions(
|
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
|
||||||
crossinline processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
|
||||||
): ProcessorAction = processOverriddenFunctionsWithDepth(functionSymbol) { symbol, depth ->
|
|
||||||
if (depth == 1) {
|
|
||||||
processor(symbol)
|
|
||||||
} else {
|
|
||||||
ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
abstract fun processOverriddenPropertiesWithDepth(
|
abstract fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): 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 (!baseScope.processOverriddenCallablesWithDepth(overridden) { symbol, depth ->
|
|
||||||
processor(symbol, depth + overriddenDepth)
|
|
||||||
}
|
|
||||||
) return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseScope.processOverriddenCallablesWithDepth(callableSymbol, processor)
|
|
||||||
}
|
|
||||||
|
|
||||||
object Empty : FirTypeScope() {
|
object Empty : FirTypeScope() {
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = ProcessorAction.NEXT
|
): ProcessorAction = ProcessorAction.NEXT
|
||||||
|
|
||||||
override fun processOverriddenPropertiesWithDepth(
|
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||||
propertySymbol: FirPropertySymbol,
|
propertySymbol: FirPropertySymbol,
|
||||||
processor: (FirPropertySymbol, Int) -> ProcessorAction
|
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||||
): ProcessorAction = ProcessorAction.NEXT
|
): ProcessorAction = ProcessorAction.NEXT
|
||||||
|
|
||||||
override fun getCallableNames(): Set<Name> = emptySet()
|
override fun getCallableNames(): Set<Name> = emptySet()
|
||||||
|
|
||||||
override fun getClassifierNames(): Set<Name> = emptySet()
|
override fun getClassifierNames(): Set<Name> = emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected companion object {
|
||||||
|
fun <S : FirCallableSymbol<*>> doProcessDirectOverriddenCallables(
|
||||||
|
callableSymbol: S,
|
||||||
|
processor: (S, FirTypeScope) -> ProcessorAction,
|
||||||
|
directOverriddenMap: Map<S, Collection<S>>,
|
||||||
|
baseScope: FirTypeScope,
|
||||||
|
processDirectOverriddenCallables: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction
|
||||||
|
): ProcessorAction {
|
||||||
|
val directOverridden = directOverriddenMap[callableSymbol]?.takeIf { it.isNotEmpty() }
|
||||||
|
?: return baseScope.processDirectOverriddenCallables(callableSymbol, processor)
|
||||||
|
|
||||||
|
for (overridden in directOverridden) {
|
||||||
|
if (overridden.isIntersectionOverride) {
|
||||||
|
if (!baseScope.processDirectOverriddenCallables(overridden, processor)) return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
if (!processor(overridden, baseScope)) return ProcessorAction.STOP
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessorAction.NONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirTypeScope.processOverriddenFunctions(
|
||||||
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
|
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||||
|
): ProcessorAction =
|
||||||
|
doProcessAllOverriddenCallables(
|
||||||
|
functionSymbol,
|
||||||
|
processor,
|
||||||
|
FirTypeScope::processDirectOverriddenFunctionsWithBaseScope,
|
||||||
|
mutableSetOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun FirTypeScope.processOverriddenProperties(
|
||||||
|
propertySymbol: FirPropertySymbol,
|
||||||
|
processor: (FirPropertySymbol) -> ProcessorAction
|
||||||
|
): ProcessorAction =
|
||||||
|
doProcessAllOverriddenCallables(
|
||||||
|
propertySymbol,
|
||||||
|
processor,
|
||||||
|
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope,
|
||||||
|
mutableSetOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private fun <S : FirCallableSymbol<*>> FirTypeScope.doProcessAllOverriddenCallables(
|
||||||
|
callableSymbol: S,
|
||||||
|
processor: (S) -> ProcessorAction,
|
||||||
|
processDirectOverriddenCallablesWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
|
||||||
|
visited: MutableSet<S>
|
||||||
|
): ProcessorAction {
|
||||||
|
if (!visited.add(callableSymbol)) return ProcessorAction.NONE
|
||||||
|
return processDirectOverriddenCallablesWithBaseScope(callableSymbol) { overridden, baseScope ->
|
||||||
|
if (!processor(overridden)) return@processDirectOverriddenCallablesWithBaseScope ProcessorAction.STOP
|
||||||
|
|
||||||
|
baseScope.doProcessAllOverriddenCallables(overridden, processor, processDirectOverriddenCallablesWithBaseScope, visited)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun FirTypeScope.processDirectlyOverriddenFunctions(
|
||||||
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
|
crossinline processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||||
|
): ProcessorAction = processDirectOverriddenFunctionsWithBaseScope(functionSymbol) { overridden, _ ->
|
||||||
|
processor(overridden)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun FirTypeScope.processDirectlyOverriddenProperties(
|
||||||
|
propertySymbol: FirPropertySymbol,
|
||||||
|
crossinline processor: (FirPropertySymbol) -> ProcessorAction
|
||||||
|
): ProcessorAction = processDirectOverriddenPropertiesWithBaseScope(propertySymbol) { overridden, _ ->
|
||||||
|
processor(overridden)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration<D>> : AbstractFirBas
|
|||||||
|
|
||||||
open val overriddenSymbol: FirCallableSymbol<D>?
|
open val overriddenSymbol: FirCallableSymbol<D>?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
|
open val isIntersectionOverride: Boolean get() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirCallableSymbol<*>.isStatic: Boolean get() = (fir as? FirMemberDeclaration)?.status?.isStatic == true
|
val FirCallableSymbol<*>.isStatic: Boolean get() = (fir as? FirMemberDeclaration)?.status?.isStatic == true
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ open class FirNamedFunctionSymbol(
|
|||||||
callableId: CallableId,
|
callableId: CallableId,
|
||||||
override val isFakeOverride: Boolean = false,
|
override val isFakeOverride: Boolean = false,
|
||||||
// Actual for fake override only
|
// Actual for fake override only
|
||||||
override val overriddenSymbol: FirNamedFunctionSymbol? = null
|
override val overriddenSymbol: FirNamedFunctionSymbol? = null,
|
||||||
|
override val isIntersectionOverride: Boolean = false,
|
||||||
) : FirFunctionSymbol<FirSimpleFunction>(callableId), PossiblyFirFakeOverrideSymbol<FirSimpleFunction, FirNamedFunctionSymbol>
|
) : FirFunctionSymbol<FirSimpleFunction>(callableId), PossiblyFirFakeOverrideSymbol<FirSimpleFunction, FirNamedFunctionSymbol>
|
||||||
|
|
||||||
class FirConstructorSymbol(
|
class FirConstructorSymbol(
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ open class FirPropertySymbol(
|
|||||||
callableId: CallableId,
|
callableId: CallableId,
|
||||||
override val isFakeOverride: Boolean = false,
|
override val isFakeOverride: Boolean = false,
|
||||||
// Actual for fake override only
|
// Actual for fake override only
|
||||||
override val overriddenSymbol: FirPropertySymbol? = null
|
override val overriddenSymbol: FirPropertySymbol? = null,
|
||||||
|
override val isIntersectionOverride: Boolean = false,
|
||||||
) : FirVariableSymbol<FirProperty>(callableId), PossiblyFirFakeOverrideSymbol<FirProperty, FirPropertySymbol> {
|
) : FirVariableSymbol<FirProperty>(callableId), PossiblyFirFakeOverrideSymbol<FirProperty, FirPropertySymbol> {
|
||||||
// TODO: should we use this constructor for local variables?
|
// TODO: should we use this constructor for local variables?
|
||||||
constructor(name: Name) : this(CallableId(name))
|
constructor(name: Name) : this(CallableId(name))
|
||||||
|
|||||||
Reference in New Issue
Block a user