Filter out inapplicable member scopes in resolution
This commit is contained in:
@@ -87,6 +87,10 @@ internal class MemberScopeTowerLevel(
|
|||||||
|
|
||||||
private val syntheticScopes = scopeTower.syntheticScopes
|
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(
|
private fun collectMembers(
|
||||||
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
|
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
|
||||||
): Collection<CandidateWithBoundDispatchReceiver> {
|
): 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.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.coroutines.experimental.buildSequence
|
import kotlin.coroutines.experimental.buildSequence
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ class TowerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getImplicitReceiver(scope)?.let {
|
getImplicitReceiver(scope)?.let {
|
||||||
yield(MemberScopeTowerLevel(this@createNonLocalLevels, it))
|
yieldIfNotNull(MemberScopeTowerLevel(this@createNonLocalLevels, it).takeIf { it.mayFitForName(name) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (scope.mayFitForName(name, location)) {
|
else if (scope.mayFitForName(name, location)) {
|
||||||
@@ -156,7 +157,9 @@ class TowerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// members of implicit receiver or member extension for explicit receiver
|
// 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
|
// synthetic properties
|
||||||
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
|
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
|
||||||
@@ -193,6 +196,9 @@ class TowerResolver {
|
|||||||
return resultCollector.getFinalCandidates()
|
return resultCollector.getFinalCandidates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MemberScopeTowerLevel.mayFitForName(name: Name) =
|
||||||
|
!definitelyDoesNotContainName(name) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE)
|
||||||
|
|
||||||
private fun ResolutionScope.mayFitForName(name: Name, location: LookupLocation) =
|
private fun ResolutionScope.mayFitForName(name: Name, location: LookupLocation) =
|
||||||
!definitelyDoesNotContainName(name, location) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE, location)
|
!definitelyDoesNotContainName(name, location) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE, location)
|
||||||
|
|
||||||
|
|||||||
+5
@@ -218,6 +218,11 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
|||||||
override fun getVariableNames() = propertyNamesLazy
|
override fun getVariableNames() = propertyNamesLazy
|
||||||
override fun getClassifierNames() = classNamesLazy
|
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> {
|
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
|
||||||
if (name !in getFunctionNames()) return emptyList()
|
if (name !in getFunctionNames()) return emptyList()
|
||||||
return functions(name)
|
return functions(name)
|
||||||
|
|||||||
+5
@@ -78,6 +78,11 @@ abstract class DeserializedMemberScope protected constructor(
|
|||||||
override fun getVariableNames() = variableNamesLazy
|
override fun getVariableNames() = variableNamesLazy
|
||||||
override fun getClassifierNames(): Set<Name>? = classNames + typeAliasNames
|
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(
|
private inline fun <M : MessageLite> Collection<M>.groupByName(
|
||||||
getNameIndex: (M) -> Int
|
getNameIndex: (M) -> Int
|
||||||
) = groupBy { c.nameResolver.getName(getNameIndex(it)) }
|
) = groupBy { c.nameResolver.getName(getNameIndex(it)) }
|
||||||
|
|||||||
Reference in New Issue
Block a user