FIR tower levels: inline processElementsByName[AndStoreResult]

This commit is contained in:
Mikhail Glukhikh
2020-12-09 22:01:51 +03:00
parent af4941b222
commit 34d7a7c184
2 changed files with 80 additions and 98 deletions
@@ -53,17 +53,18 @@ internal class TowerLevelHandler {
when (info.callKind) {
CallKind.VariableAccess -> {
towerLevel.processProperties(info.name, processor)
processResult += towerLevel.processPropertiesByName(info.name, processor)
if (!collector.isSuccess()) {
towerLevel.processObjectsAsVariables(info.name, processor)
if (!collector.isSuccess() && towerLevel is ScopeTowerLevel && towerLevel.extensionReceiver == null) {
processResult += towerLevel.processObjectsByName(info.name, processor)
}
}
CallKind.Function -> {
towerLevel.processFunctions(info.name, processor)
processResult += towerLevel.processFunctionsByName(info.name, processor)
}
CallKind.CallableReference -> {
towerLevel.processFunctionsAndProperties(info.name, processor)
processResult += towerLevel.processFunctionsByName(info.name, processor)
processResult += towerLevel.processPropertiesByName(info.name, processor)
}
else -> {
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
@@ -71,46 +72,6 @@ internal class TowerLevelHandler {
}
return processResult
}
private fun TowerScopeLevel.processProperties(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
) {
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Properties, name, processor)
}
private fun TowerScopeLevel.processFunctions(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
) {
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Functions, name, processor)
}
private fun TowerScopeLevel.processFunctionsAndProperties(
name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
) {
processFunctions(name, processor)
processProperties(name, processor)
}
private fun TowerScopeLevel.processObjectsAsVariables(
name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
) {
// Skipping objects when extension receiver is bound to the level
if (this is ScopeTowerLevel && this.extensionReceiver != null) return
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Objects, name, processor)
}
private fun <T : AbstractFirBasedSymbol<*>> TowerScopeLevel.processElementsByNameAndStoreResult(
token: TowerScopeLevel.Token<T>,
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction {
return processElementsByName(token, name, processor).also {
processResult += it
}
}
}
private class TowerScopeLevelProcessor(
@@ -31,13 +31,13 @@ interface TowerScopeLevel {
object Objects : Token<AbstractFirBasedSymbol<*>>()
}
fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: Token<T>,
name: Name,
processor: TowerScopeLevelProcessor<T>
): ProcessorAction
fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>): ProcessorAction
interface TowerScopeLevelProcessor<T : AbstractFirBasedSymbol<*>> {
fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>): ProcessorAction
fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>): ProcessorAction
interface TowerScopeLevelProcessor<in T : AbstractFirBasedSymbol<*>> {
fun consumeCandidate(
symbol: T,
dispatchReceiverValue: ReceiverValue?,
@@ -115,38 +115,47 @@ class MemberScopeTowerLevel(
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>,
override fun processFunctionsByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
processor: TowerScopeLevel.TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessorAction {
val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions
val isInvoke = name == OperatorNameConventions.INVOKE
if (implicitExtensionInvokeMode && !isInvoke) {
return ProcessorAction.NEXT
}
return when (token) {
is TowerScopeLevel.Token.Properties -> processMembers(processor) { consumer ->
this.processPropertiesByName(name) {
return processMembers(processor) { consumer ->
this.processFunctionsAndConstructorsByName(
name, session, bodyResolveComponents,
includeInnerConstructors = true,
processor = {
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@Suppress("UNCHECKED_CAST")
consumer(it as T)
consumer(it as FirFunctionSymbol<*>)
}
}
TowerScopeLevel.Token.Functions -> processMembers(processor) { consumer ->
this.processFunctionsAndConstructorsByName(
name, session, bodyResolveComponents,
includeInnerConstructors = true,
processor = {
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@Suppress("UNCHECKED_CAST")
consumer(it as T)
}
)
}
TowerScopeLevel.Token.Objects -> ProcessorAction.NEXT
)
}
}
override fun processPropertiesByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessorAction {
return processMembers(processor) { consumer ->
this.processPropertiesByName(name) {
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@Suppress("UNCHECKED_CAST")
consumer(it)
}
}
}
override fun processObjectsByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
): ProcessorAction {
return ProcessorAction.NEXT
}
override fun replaceReceiverValue(receiverValue: ReceiverValue): SessionBasedTowerLevel {
return MemberScopeTowerLevel(
session, bodyResolveComponents, receiverValue, extensionReceiver, implicitExtensionInvokeMode, scopeSession
@@ -222,35 +231,47 @@ class ScopeTowerLevel(
}
}
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>,
override fun processFunctionsByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
processor: TowerScopeLevel.TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessorAction {
var empty = true
@Suppress("UNCHECKED_CAST")
when (token) {
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate ->
empty = false
consumeCallableCandidate(candidate, processor)
}
TowerScopeLevel.Token.Functions -> scope.processFunctionsAndConstructorsByName(
name,
session,
bodyResolveComponents,
includeInnerConstructors = includeInnerConstructors
) { candidate ->
empty = false
consumeCallableCandidate(candidate, processor)
}
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
empty = false
processor.consumeCandidate(
it as T, dispatchReceiverValue = null,
extensionReceiverValue = null,
scope = scope
)
}
scope.processFunctionsAndConstructorsByName(
name,
session,
bodyResolveComponents,
includeInnerConstructors = includeInnerConstructors
) { candidate ->
empty = false
consumeCallableCandidate(candidate, processor)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}
override fun processPropertiesByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessorAction {
var empty = true
scope.processPropertiesByName(name) { candidate ->
empty = false
consumeCallableCandidate(candidate, processor)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}
override fun processObjectsByName(
name: Name,
processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
): ProcessorAction {
var empty = true
scope.processClassifiersByName(name) {
empty = false
processor.consumeCandidate(
it, dispatchReceiverValue = null,
extensionReceiverValue = null,
scope = scope
)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}