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 754b641da99..8b8042e77aa 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 @@ -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> - ) { - processElementsByNameAndStoreResult(TowerScopeLevel.Token.Properties, name, processor) - } - - private fun TowerScopeLevel.processFunctions( - name: Name, - processor: TowerScopeLevel.TowerScopeLevelProcessor> - ) { - processElementsByNameAndStoreResult(TowerScopeLevel.Token.Functions, name, processor) - } - - private fun TowerScopeLevel.processFunctionsAndProperties( - name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor> - ) { - processFunctions(name, processor) - processProperties(name, processor) - } - - private fun TowerScopeLevel.processObjectsAsVariables( - name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor> - ) { - // 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 > TowerScopeLevel.processElementsByNameAndStoreResult( - token: TowerScopeLevel.Token, - name: Name, - processor: TowerScopeLevel.TowerScopeLevelProcessor - ): ProcessorAction { - return processElementsByName(token, name, processor).also { - processResult += it - } - } } private class TowerScopeLevelProcessor( 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 e5e11b61a25..0cc7ded84cd 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 @@ -31,13 +31,13 @@ interface TowerScopeLevel { object Objects : Token>() } - fun > processElementsByName( - token: Token, - name: Name, - processor: TowerScopeLevelProcessor - ): ProcessorAction + fun processFunctionsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction - interface TowerScopeLevelProcessor> { + fun processPropertiesByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction + + fun processObjectsByName(name: Name, processor: TowerScopeLevelProcessor>): ProcessorAction + + interface TowerScopeLevelProcessor> { fun consumeCandidate( symbol: T, dispatchReceiverValue: ReceiverValue?, @@ -115,38 +115,47 @@ class MemberScopeTowerLevel( return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT } - override fun > processElementsByName( - token: TowerScopeLevel.Token, + override fun processFunctionsByName( name: Name, - processor: TowerScopeLevel.TowerScopeLevelProcessor + processor: TowerScopeLevel.TowerScopeLevelProcessor> ): 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> + ): 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> + ): 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 > processElementsByName( - token: TowerScopeLevel.Token, + override fun processFunctionsByName( name: Name, - processor: TowerScopeLevel.TowerScopeLevelProcessor + processor: TowerScopeLevel.TowerScopeLevelProcessor> ): 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> + ): 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> + ): 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 }