From d9d582b226d9d0c3b1d5a64ef0b840fbe1317a12 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 21 May 2019 20:02:25 +0300 Subject: [PATCH] FIR tower resolve: add level with implicit extension receiver --- .../kotlin/fir/resolve/calls/CallResolver.kt | 20 +++++++++++++++---- .../resolve/testData/resolve/extension.txt | 2 +- .../resolve/stdlib/arrayFirstOrNull.txt | 2 +- .../resolve/stdlib/topLevelResolve.txt | 4 ++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt index a269202996d..e05f427c9d4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt @@ -245,7 +245,8 @@ private fun ConeCallableSymbol.hasExtensionReceiver(): Boolean = (this as? FirCa // (if explicit receiver exists, it always *should* be an extension receiver) class ScopeTowerLevel( session: FirSession, - val scope: FirScope + val scope: FirScope, + val implicitExtensionReceiver: ReceiverValue? = null ) : SessionBasedTowerLevel(session) { override fun processElementsByName( token: TowerScopeLevel.Token, @@ -253,18 +254,21 @@ class ScopeTowerLevel( explicitReceiver: ExpressionReceiverValue?, processor: TowerScopeLevel.TowerScopeLevelProcessor ): ProcessorAction { + if (explicitReceiver != null && implicitExtensionReceiver != null) { + return ProcessorAction.NEXT + } + val extensionReceiver = explicitReceiver ?: implicitExtensionReceiver return when (token) { TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate -> - if (candidate.hasConsistentExtensionReceiver(explicitReceiver) && candidate.dispatchReceiverValue() == null) { + if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) { processor.consumeCandidate(candidate as T, dispatchReceiverValue = null) } else { ProcessorAction.NEXT } } TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name) { candidate -> - // TODO: fix implicit receiver - if (candidate.hasConsistentExtensionReceiver(explicitReceiver) && candidate.dispatchReceiverValue() == null) { + if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) { processor.consumeCandidate(candidate as T, dispatchReceiverValue = null) } else { ProcessorAction.NEXT @@ -606,6 +610,14 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf collector, group++ ) + for (scope in scopes!!) { + towerDataConsumer.consume( + TowerDataKind.TOWER_LEVEL, + ScopeTowerLevel(session, scope, implicitReceiverValue), + collector, group++ + ) + } + return group } diff --git a/compiler/fir/resolve/testData/resolve/extension.txt b/compiler/fir/resolve/testData/resolve/extension.txt index 409721f13b3..ac84313931a 100644 --- a/compiler/fir/resolve/testData/resolve/extension.txt +++ b/compiler/fir/resolve/testData/resolve/extension.txt @@ -2,5 +2,5 @@ FILE: extension.kt public final fun R|kotlin/String|.foo(): R|kotlin/Unit| { } public final fun R|kotlin/String|.bar(): R|kotlin/Unit| { - #() + R|/foo|() } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt b/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt index ab4289011ed..3935a93b881 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.txt @@ -9,7 +9,7 @@ FILE: arrayFirstOrNull.kt } public final fun R|kotlin/Array|.firstOrNullX(): R|T|? { ^firstOrNullX when () { - #() -> { + #() -> { Null(null) } else -> { diff --git a/compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt b/compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt index 544ae81e28b..367efa5a35a 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.txt @@ -36,7 +36,7 @@ FILE: topLevelResolve.kt } ) lval viaWith: R|kotlin/Nothing| = R|kotlin/with||, R|kotlin/Nothing|>(R|kotlin/collections/listOf|(Int(42)), = with@fun R|kotlin/collections/List|.(it: R|kotlin/collections/List|): R|kotlin/Function2, kotlin/collections/List, kotlin/Nothing>| { - #( = map@fun .(): { + #( = map@fun .(): { it#.times#(it#) } ) @@ -49,7 +49,7 @@ FILE: topLevelResolve.kt } ) lval indices: R|kotlin/Nothing| = R|kotlin/with|(String(), = with@fun R|kotlin/String|.(it: R|kotlin/String|): R|kotlin/Function2| { - # + # } ) lval indicesNoWith: R|kotlin/ranges/IntRange| = String().R|kotlin/text/indices|