Filter out inapplicable member scopes in resolution

This commit is contained in:
Denis Zharkov
2017-08-16 15:49:02 +07:00
parent d0bf0f5fb3
commit 860951748f
4 changed files with 22 additions and 2 deletions
@@ -87,6 +87,10 @@ internal class MemberScopeTowerLevel(
private val syntheticScopes = scopeTower.syntheticScopes
fun definitelyDoesNotContainName(name: Name) =
(dispatchReceiver.possibleTypes + dispatchReceiver.receiverValue.type)
.all { !it.isDynamic() && it.memberScope.definitelyDoesNotContainName(name, location) }
private fun collectMembers(
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
): Collection<CandidateWithBoundDispatchReceiver> {
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.yieldIfNotNull
import java.util.*
import kotlin.coroutines.experimental.buildSequence
@@ -99,7 +100,7 @@ class TowerResolver {
}
getImplicitReceiver(scope)?.let {
yield(MemberScopeTowerLevel(this@createNonLocalLevels, it))
yieldIfNotNull(MemberScopeTowerLevel(this@createNonLocalLevels, it).takeIf { it.mayFitForName(name) })
}
}
else if (scope.mayFitForName(name, location)) {
@@ -156,7 +157,9 @@ class TowerResolver {
}
// members of implicit receiver or member extension for explicit receiver
TowerData.TowerLevel(MemberScopeTowerLevel(this, implicitReceiver)).process()?.let { return it }
MemberScopeTowerLevel(this, implicitReceiver).takeIf { it.mayFitForName(name) }?.let {
TowerData.TowerLevel(it).process()?.let { return it }
}
// synthetic properties
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
@@ -193,6 +196,9 @@ class TowerResolver {
return resultCollector.getFinalCandidates()
}
private fun MemberScopeTowerLevel.mayFitForName(name: Name) =
!definitelyDoesNotContainName(name) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE)
private fun ResolutionScope.mayFitForName(name: Name, location: LookupLocation) =
!definitelyDoesNotContainName(name, location) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE, location)
@@ -218,6 +218,11 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
override fun getVariableNames() = propertyNamesLazy
override fun getClassifierNames() = classNamesLazy
override fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean {
recordLookup(name, location)
return name !in functionNamesLazy && name !in propertyNamesLazy && name !in classNamesLazy
}
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
if (name !in getFunctionNames()) return emptyList()
return functions(name)
@@ -78,6 +78,11 @@ abstract class DeserializedMemberScope protected constructor(
override fun getVariableNames() = variableNamesLazy
override fun getClassifierNames(): Set<Name>? = classNames + typeAliasNames
override fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean {
recordLookup(name, location)
return name !in functionNamesLazy && name !in variableNamesLazy && name !in classNames && name !in typeAliasNames
}
private inline fun <M : MessageLite> Collection<M>.groupByName(
getNameIndex: (M) -> Int
) = groupBy { c.nameResolver.getName(getNameIndex(it)) }