From d0bf0f5fb340cb5d441abcc5d27d33878455c20b Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 16 Aug 2017 13:01:53 +0700 Subject: [PATCH] Filter out inapplicable non-local levels for implicit receivers --- .../resolve/calls/tower/TowerResolver.kt | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index 49f74d3ac5d..a9c24775fc4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastI import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf import org.jetbrains.kotlin.util.OperatorNameConventions import java.util.* +import kotlin.coroutines.experimental.buildSequence interface Candidate { // this operation should be very fast @@ -90,21 +91,21 @@ class TowerResolver { ): Collection = scopeTower.run(processor, AllCandidatesCollector(), false, name) - private fun ImplicitScopeTower.createNonLocalLevels(): List { - val result = ArrayList() - + private fun ImplicitScopeTower.createNonLocalLevels(name: Name): Sequence = buildSequence { lexicalScope.parentsWithSelf.forEach { scope -> if (scope is LexicalScope) { - if (!scope.kind.withLocalDescriptors) result.add(ScopeBasedTowerLevel(this, scope)) + if (!scope.kind.withLocalDescriptors && scope.mayFitForName(name, location)) { + yield(ScopeBasedTowerLevel(this@createNonLocalLevels, scope)) + } - getImplicitReceiver(scope)?.let { result.add(MemberScopeTowerLevel(this, it)) } + getImplicitReceiver(scope)?.let { + yield(MemberScopeTowerLevel(this@createNonLocalLevels, it)) + } } - else { - result.add(ImportingScopeBasedTowerLevel(this, scope as ImportingScope)) + else if (scope.mayFitForName(name, location)) { + yield(ImportingScopeBasedTowerLevel(this@createNonLocalLevels, scope as ImportingScope)) } } - - return result } private fun ImplicitScopeTower.run( @@ -170,11 +171,16 @@ class TowerResolver { // extension for implicit receiver if (nonLocalLevels == null) { - nonLocalLevels = createNonLocalLevels() + nonLocalLevels = arrayListOf() + for (nonLocalLevel in createNonLocalLevels(name)) { + TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it } + nonLocalLevels.add(nonLocalLevel) + } } - - for (nonLocalLevel in nonLocalLevels) { - TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it } + else { + for (nonLocalLevel in nonLocalLevels) { + TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it } + } } } }