FIR tower resolve: add level with implicit extension receiver

This commit is contained in:
Mikhail Glukhikh
2019-05-21 20:02:25 +03:00
parent 45b0f5a0ca
commit d9d582b226
4 changed files with 20 additions and 8 deletions
@@ -245,7 +245,8 @@ private fun ConeCallableSymbol.hasExtensionReceiver(): Boolean = (this as? FirCa
// (if explicit receiver exists, it always *should* be an extension receiver) // (if explicit receiver exists, it always *should* be an extension receiver)
class ScopeTowerLevel( class ScopeTowerLevel(
session: FirSession, session: FirSession,
val scope: FirScope val scope: FirScope,
val implicitExtensionReceiver: ReceiverValue? = null
) : SessionBasedTowerLevel(session) { ) : SessionBasedTowerLevel(session) {
override fun <T : ConeSymbol> processElementsByName( override fun <T : ConeSymbol> processElementsByName(
token: TowerScopeLevel.Token<T>, token: TowerScopeLevel.Token<T>,
@@ -253,18 +254,21 @@ class ScopeTowerLevel(
explicitReceiver: ExpressionReceiverValue?, explicitReceiver: ExpressionReceiverValue?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T> processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction { ): ProcessorAction {
if (explicitReceiver != null && implicitExtensionReceiver != null) {
return ProcessorAction.NEXT
}
val extensionReceiver = explicitReceiver ?: implicitExtensionReceiver
return when (token) { return when (token) {
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate -> 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) processor.consumeCandidate(candidate as T, dispatchReceiverValue = null)
} else { } else {
ProcessorAction.NEXT ProcessorAction.NEXT
} }
} }
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name) { candidate -> TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name) { candidate ->
// TODO: fix implicit receiver if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) {
if (candidate.hasConsistentExtensionReceiver(explicitReceiver) && candidate.dispatchReceiverValue() == null) {
processor.consumeCandidate(candidate as T, dispatchReceiverValue = null) processor.consumeCandidate(candidate as T, dispatchReceiverValue = null)
} else { } else {
ProcessorAction.NEXT ProcessorAction.NEXT
@@ -606,6 +610,14 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
collector, group++ collector, group++
) )
for (scope in scopes!!) {
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
ScopeTowerLevel(session, scope, implicitReceiverValue),
collector, group++
)
}
return group return group
} }
+1 -1
View File
@@ -2,5 +2,5 @@ FILE: extension.kt
public final fun R|kotlin/String|.foo(): R|kotlin/Unit| { public final fun R|kotlin/String|.foo(): R|kotlin/Unit| {
} }
public final fun R|kotlin/String|.bar(): R|kotlin/Unit| { public final fun R|kotlin/String|.bar(): R|kotlin/Unit| {
<Unresolved name: foo>#() R|/foo|()
} }
@@ -9,7 +9,7 @@ FILE: arrayFirstOrNull.kt
} }
public final fun <T> R|kotlin/Array<out T>|.firstOrNullX(): R|T|? { public final fun <T> R|kotlin/Array<out T>|.firstOrNullX(): R|T|? {
^firstOrNullX when () { ^firstOrNullX when () {
<Unresolved name: isEmpty>#() -> { <Ambiguity: isEmpty, [kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/collections/isEmpty, kotlin/text/isEmpty]>#() -> {
Null(null) Null(null)
} }
else -> { else -> {
@@ -36,7 +36,7 @@ FILE: topLevelResolve.kt
} }
) )
lval viaWith: R|kotlin/Nothing| = R|kotlin/with|<R|kotlin/collections/List<kotlin/Int>|, R|kotlin/Nothing|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(42)), <L> = with@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(it: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Function2<kotlin/collections/List<kotlin/Int>, kotlin/collections/List<kotlin/Int>, kotlin/Nothing>| { lval viaWith: R|kotlin/Nothing| = R|kotlin/with|<R|kotlin/collections/List<kotlin/Int>|, R|kotlin/Nothing|>(R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(42)), <L> = with@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(it: R|kotlin/collections/List<kotlin/Int>|): R|kotlin/Function2<kotlin/collections/List<kotlin/Int>, kotlin/collections/List<kotlin/Int>, kotlin/Nothing>| {
<Unresolved name: map>#(<L> = map@fun <implicit>.<anonymous>(): <implicit> { <Ambiguity: map, [kotlin/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/collections/map, kotlin/sequences/map, kotlin/text/map]>#(<L> = map@fun <implicit>.<anonymous>(): <implicit> {
it#.times#(it#) it#.times#(it#)
} }
) )
@@ -49,7 +49,7 @@ FILE: topLevelResolve.kt
} }
) )
lval indices: R|kotlin/Nothing| = R|kotlin/with|<R|kotlin/String|, R|kotlin/Nothing|>(String(), <L> = with@fun R|kotlin/String|.<anonymous>(it: R|kotlin/String|): R|kotlin/Function2<kotlin/String, kotlin/String, kotlin/Nothing>| { lval indices: R|kotlin/Nothing| = R|kotlin/with|<R|kotlin/String|, R|kotlin/Nothing|>(String(), <L> = with@fun R|kotlin/String|.<anonymous>(it: R|kotlin/String|): R|kotlin/Function2<kotlin/String, kotlin/String, kotlin/Nothing>| {
<Unresolved name: indices># <Ambiguity: indices, [kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/collections/indices, kotlin/text/indices]>#
} }
) )
lval indicesNoWith: R|kotlin/ranges/IntRange| = String().R|kotlin/text/indices| lval indicesNoWith: R|kotlin/ranges/IntRange| = String().R|kotlin/text/indices|