FIR: Introduce FirScope.processOverriddenFunctions
^KT-35495 In Progress
This commit is contained in:
@@ -45,4 +45,12 @@ abstract class FirIterableScope : FirScope() {
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
return processComposite(FirScope::processPropertiesByName, name, processor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processOverriddenFunctions(functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
for (scope in scopes) {
|
||||
if (!scope.processOverriddenFunctions(functionSymbol, processor)) return ProcessorAction.STOP
|
||||
}
|
||||
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,46 @@ abstract class FirScope {
|
||||
) {}
|
||||
|
||||
open fun mayContainName(name: Name) = true
|
||||
|
||||
// Currently, this function has very weak guarantees
|
||||
// - 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 doesn't guarantee any specific order in which overridden tree will be traversed
|
||||
// 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
|
||||
// TODO: Consider extracting this function to a separate abstract class/interface, so only limited types of scopes would be supporing it
|
||||
// on interface level
|
||||
open fun processOverriddenFunctions(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction = ProcessorAction.NONE
|
||||
|
||||
// This is just a helper for a common implementation
|
||||
protected fun doProcessOverriddenFunctions(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
||||
directOverriddenMap: Map<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>,
|
||||
baseScope: FirScope
|
||||
): ProcessorAction {
|
||||
val directOverridden =
|
||||
directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctions(functionSymbol, processor)
|
||||
|
||||
for (overridden in directOverridden) {
|
||||
if (!processor(overridden)) return ProcessorAction.STOP
|
||||
if (!baseScope.processOverriddenFunctions(overridden, processor)) return ProcessorAction.STOP
|
||||
}
|
||||
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
fun FirScope.processOverriddenFunctionsAndSelf(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
if (!processor(functionSymbol)) return ProcessorAction.STOP
|
||||
|
||||
return processOverriddenFunctions(functionSymbol, processor)
|
||||
}
|
||||
|
||||
enum class ProcessorAction {
|
||||
|
||||
@@ -15,3 +15,9 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration<D>> : AbstractFirBas
|
||||
open val overriddenSymbol: FirCallableSymbol<D>?
|
||||
get() = null
|
||||
}
|
||||
|
||||
inline fun <reified E : FirCallableSymbol<*>> E.unwrapOverriddenOnce(): E {
|
||||
overriddenSymbol?.let { return it as E }
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user