diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt index f3f765ab45a..24b9e468dae 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt @@ -47,6 +47,9 @@ internal class TowerDataElementsForName( towerDataElement.implicitReceiver?.let { receiver -> IndexedValue(index, receiver) } } } + + val emptyScopes = mutableSetOf() + val implicitReceiverValuesWithEmptyScopes = mutableSetOf>() } 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 } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 6c17c315da7..5e8ecf8814e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -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, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 37fbc428bad..73e60d9c20b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -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> { @@ -37,11 +46,11 @@ abstract class TowerScopeLevel { object Objects : Token>() } - abstract fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction + abstract fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessResult - abstract fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction + abstract fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessResult - abstract fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction + abstract fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessResult interface TowerScopeLevelProcessor> { fun consumeCandidate( @@ -79,9 +88,9 @@ class MemberScopeTowerLevel( private fun > processMembers( output: TowerScopeLevelProcessor, 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> - ): 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> - ): 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> - ): 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> - ): 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> - ): 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> - ): 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 } }