Don't enter twice local scopes w/out particular name in FIR tower resolver

This commit is contained in:
Mikhail Glukhikh
2019-10-01 13:02:31 +03:00
parent e48428d39d
commit e276e8d9f3
6 changed files with 46 additions and 32 deletions
@@ -7,8 +7,11 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.calls.TowerDataKind.EMPTY
import org.jetbrains.kotlin.fir.resolve.calls.TowerDataKind.TOWER_LEVEL
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
enum class TowerDataKind {
@@ -29,6 +32,7 @@ class CallResolver(
private fun processImplicitReceiver(
towerDataConsumer: TowerDataConsumer,
implicitReceiverValue: ImplicitReceiverValue<*>,
nonEmptyLocalScopes: List<FirLocalScope>,
oldGroup: Int
): Int {
var group = oldGroup
@@ -39,7 +43,7 @@ class CallResolver(
// fun test(b: Bar) { b.baz() }
// }
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
MemberScopeTowerLevel(session, implicitReceiverValue, scopeSession = components.scopeSession),
group++
)
@@ -50,7 +54,7 @@ class CallResolver(
// fun test() { bar() }
// }
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
MemberScopeTowerLevel(session, implicitReceiverValue, implicitReceiverValue, components.scopeSession),
group++
)
@@ -62,9 +66,9 @@ class CallResolver(
// bar()
// }
// }
for (scope in localScopes) {
for (scope in nonEmptyLocalScopes) {
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
ScopeTowerLevel(session, components, scope, implicitExtensionReceiver = implicitReceiverValue),
group++
)
@@ -83,7 +87,7 @@ class CallResolver(
// }
// }
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
ScopeTowerLevel(session, components, implicitScope, implicitExtensionReceiver = implicitReceiverValue),
group++
)
@@ -97,7 +101,7 @@ class CallResolver(
// fun test() { foo() }
// }
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
ScopeTowerLevel(session, components, implicitCompanionScope, implicitExtensionReceiver = implicitReceiverValue),
group++
)
@@ -119,7 +123,7 @@ class CallResolver(
// with(a) { with(b) { foo() } }
// }
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
MemberScopeTowerLevel(
session, scopeSession = components.scopeSession,
dispatchReceiver = implicitDispatchReceiverValue,
@@ -137,7 +141,7 @@ class CallResolver(
// }
for (scope in topLevelScopes) {
towerDataConsumer.consume(
TowerDataKind.TOWER_LEVEL,
TOWER_LEVEL,
ScopeTowerLevel(session, components, scope, implicitExtensionReceiver = implicitReceiverValue),
group++
)
@@ -147,7 +151,7 @@ class CallResolver(
}
val collector by lazy { CandidateCollector(components, resolutionStageRunner) }
lateinit var towerDataConsumer: TowerDataConsumer
private lateinit var towerDataConsumer: TowerDataConsumer
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue<*>>
fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue<*>>): CandidateCollector {
@@ -158,12 +162,15 @@ class CallResolver(
// Member of explicit receiver' type (this stage does nothing without explicit receiver)
// class Foo(val x: Int)
// fun test(f: Foo) { f.x }
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, group++)
towerDataConsumer.consume(EMPTY, TowerScopeLevel.Empty, group++)
// Member of local scope
// fun test(x: Int) = x
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
for (scope in localScopes) {
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++)
if (towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++) != NONE) {
nonEmptyLocalScopes += scope
}
}
var blockDispatchReceivers = false
@@ -172,7 +179,7 @@ class CallResolver(
for (implicitReceiverValue in implicitReceiverValues) {
if (!blockDispatchReceivers || implicitReceiverValue !is ImplicitDispatchReceiverValue) {
// Direct use of implicit receiver (see inside)
group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, group)
group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, nonEmptyLocalScopes, group)
}
val implicitScope = implicitReceiverValue.implicitScope
if (implicitScope != null) {
@@ -181,7 +188,7 @@ class CallResolver(
// val x = 0
// class Nested { val y = x }
// }
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++)
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++)
}
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
val implicitCompanionScope = implicitReceiverValue.implicitCompanionScope
@@ -191,7 +198,7 @@ class CallResolver(
// companion object { val x = 0 }
// class Nested { val y = x }
// }
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, components, implicitCompanionScope), group++)
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitCompanionScope), group++)
}
if (!implicitReceiverValue.boundSymbol.fir.isInner) {
blockDispatchReceivers = true
@@ -203,7 +210,7 @@ class CallResolver(
// val x = 0
// fun test() { x }
for (scope in topLevelScopes) {
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++)
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++)
}
return collector
@@ -92,13 +92,15 @@ class PrioritizedTowerDataConsumer(
group: Int
): ProcessorAction {
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
var empty = true
for ((index, consumer) in consumers.withIndex()) {
val action = consumer.consume(kind, towerScopeLevel, group * consumers.size + index)
if (action.stop()) {
return ProcessorAction.STOP
when (action) {
ProcessorAction.STOP -> return action
ProcessorAction.NEXT -> empty = false
}
}
return ProcessorAction.NEXT
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}
}
@@ -123,16 +125,18 @@ class AccumulatingTowerDataConsumer(
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
accumulatedTowerData += TowerData(kind, towerScopeLevel, group)
if (initialConsumer.consume(kind, towerScopeLevel, group).stop()) {
return ProcessorAction.STOP
var empty = true
when (val action = initialConsumer.consume(kind, towerScopeLevel, group)) {
ProcessorAction.STOP -> return action
ProcessorAction.NEXT -> empty = false
}
for (consumer in additionalConsumers) {
val action = consumer.consume(kind, towerScopeLevel, group)
if (action.stop()) {
return ProcessorAction.STOP
when (val action = consumer.consume(kind, towerScopeLevel, group)) {
ProcessorAction.STOP -> return action
ProcessorAction.NEXT -> empty = false
}
}
return ProcessorAction.NEXT
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
}
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction {
@@ -50,10 +50,8 @@ abstract class FirAbstractSimpleImportingScope(
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> ProcessorAction
): ProcessorAction {
val imports = simpleImports[name] ?: return ProcessorAction.NEXT
if (imports.isEmpty()) return ProcessorAction.NEXT
val imports = simpleImports[name] ?: return ProcessorAction.NONE
if (imports.isEmpty()) return ProcessorAction.NONE
for (import in imports) {
if (processCallables(import, import.importedName!!, token, processor).stop()) {
@@ -50,6 +50,9 @@ abstract class FirAbstractStarImportingScope(
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> ProcessorAction
): ProcessorAction {
if (starImports.isEmpty()) {
return ProcessorAction.NONE
}
for (import in starImports) {
if (processCallables(import, name, token, processor).stop()) {
return ProcessorAction.STOP
@@ -39,7 +39,7 @@ class FirLocalScope : FirScope() {
if (prop != null) {
return processor(prop)
}
return ProcessorAction.NEXT
return ProcessorAction.NONE
}
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
@@ -47,6 +47,6 @@ class FirLocalScope : FirScope() {
if (prop != null) {
return processor(prop)
}
return ProcessorAction.NEXT
return ProcessorAction.NONE
}
}
@@ -54,15 +54,17 @@ enum class FirPosition(val allowTypeParameters: Boolean = true) {
enum class ProcessorAction {
STOP,
NEXT;
NEXT,
NONE;
operator fun not(): Boolean {
return when (this) {
STOP -> true
NEXT -> false
NONE -> false
}
}
fun stop() = this == STOP
fun next() = this == NEXT
fun next() = this != STOP
}