[FIR] Reuse empty scopes

This commit is contained in:
Simon Ogorodnik
2021-01-18 18:07:32 +03:00
parent 67267518f0
commit e22711d17f
3 changed files with 33 additions and 22 deletions
@@ -47,6 +47,9 @@ internal class TowerDataElementsForName(
towerDataElement.implicitReceiver?.let { receiver -> IndexedValue(index, receiver) }
}
}
val emptyScopes = mutableSetOf<FirScope>()
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
}
internal abstract class FirBaseTowerResolveTask(
@@ -137,8 +140,7 @@ internal abstract class FirBaseTowerResolveTask(
towerLevel
)
if (collector.isSuccess()) onSuccessfulLevel(finalGroup)
return result == ProcessorAction.NONE
return result == ProcessResult.SCOPE_EMPTY
}
}
@@ -22,7 +22,7 @@ internal class CandidateFactoriesAndCollectors(
internal class TowerLevelHandler {
// Try to avoid adding additional state here
private var processResult = ProcessorAction.NONE
private var processResult = ProcessResult.SCOPE_EMPTY
fun handleLevel(
collector: CandidateCollector,
@@ -31,8 +31,8 @@ internal class TowerLevelHandler {
explicitReceiverKind: ExplicitReceiverKind,
group: TowerGroup,
towerLevel: SessionBasedTowerLevel
): ProcessorAction {
processResult = ProcessorAction.NONE
): ProcessResult {
processResult = ProcessResult.SCOPE_EMPTY
val processor =
TowerScopeLevelProcessor(
info,
@@ -29,6 +29,15 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.util.OperatorNameConventions
enum class ProcessResult {
FOUND, SCOPE_EMPTY;
operator fun plus(other: ProcessResult): ProcessResult {
if (this == FOUND || other == FOUND) return FOUND
return this
}
}
abstract class TowerScopeLevel {
sealed class Token<out T : AbstractFirBasedSymbol<*>> {
@@ -37,11 +46,11 @@ abstract class TowerScopeLevel {
object Objects : Token<AbstractFirBasedSymbol<*>>()
}
abstract fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>): ProcessorAction
abstract fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>): ProcessResult
abstract fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>): ProcessorAction
abstract fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>): ProcessResult
abstract fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>): ProcessorAction
abstract fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>): ProcessResult
interface TowerScopeLevelProcessor<in T : AbstractFirBasedSymbol<*>> {
fun consumeCandidate(
@@ -79,9 +88,9 @@ class MemberScopeTowerLevel(
private fun <T : AbstractFirBasedSymbol<*>> processMembers(
output: TowerScopeLevelProcessor<T>,
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
): ProcessorAction {
): ProcessResult {
var empty = true
val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessorAction.NONE
val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessResult.SCOPE_EMPTY
scope.processScopeMembers { candidate ->
empty = false
if (candidate is FirCallableSymbol<*> &&
@@ -118,16 +127,16 @@ class MemberScopeTowerLevel(
output.consumeCandidate(symbol, dispatchReceiverValue, null, scope)
}
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
}
override fun processFunctionsByName(
name: Name,
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessorAction {
): ProcessResult {
val isInvoke = name == OperatorNameConventions.INVOKE
if (implicitExtensionInvokeMode && !isInvoke) {
return ProcessorAction.NEXT
return ProcessResult.FOUND
}
return processMembers(processor) { consumer ->
this.processFunctionsAndConstructorsByName(
@@ -145,7 +154,7 @@ class MemberScopeTowerLevel(
override fun processPropertiesByName(
name: Name,
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessorAction {
): ProcessResult {
return processMembers(processor) { consumer ->
this.processPropertiesByName(name) {
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@@ -158,8 +167,8 @@ class MemberScopeTowerLevel(
override fun processObjectsByName(
name: Name,
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
): ProcessorAction {
return ProcessorAction.NEXT
): ProcessResult {
return ProcessResult.FOUND
}
override fun replaceReceiverValue(receiverValue: ReceiverValue): SessionBasedTowerLevel {
@@ -262,7 +271,7 @@ class ScopeTowerLevel(
override fun processFunctionsByName(
name: Name,
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessorAction {
): ProcessResult {
var empty = true
scope.processFunctionsAndConstructorsByName(
name,
@@ -273,25 +282,25 @@ class ScopeTowerLevel(
empty = false
consumeCallableCandidate(candidate, processor)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
}
override fun processPropertiesByName(
name: Name,
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessorAction {
): ProcessResult {
var empty = true
scope.processPropertiesByName(name) { candidate ->
empty = false
consumeCallableCandidate(candidate, processor)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
}
override fun processObjectsByName(
name: Name,
processor: TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
): ProcessorAction {
): ProcessResult {
var empty = true
scope.processClassifiersByName(name) {
empty = false
@@ -301,7 +310,7 @@ class ScopeTowerLevel(
scope = scope
)
}
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
}
}