[FE] Report ambiguity in all possible cases

This commit is contained in:
Anastasiya Shadrina
2021-06-20 06:27:14 +07:00
committed by TeamCityServer
parent 37495bcba0
commit 814777ba8c
18 changed files with 111 additions and 104 deletions
@@ -112,6 +112,12 @@ abstract class ResolutionDiagnostic(candidateApplicability: CandidateApplicabili
}
}
class ContextReceiverAmbiguity : ResolutionDiagnostic(RESOLVED_WITH_ERROR) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this)
}
}
// todo error for this access from nested class
class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility) : ResolutionDiagnostic(RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) {
@@ -153,6 +153,31 @@ private class NoExplicitReceiverScopeTowerProcessor<C : Candidate>(
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
data.implicitReceiver
)
is TowerData.BothTowerLevelAndContextReceiversGroup -> {
val collected = mutableListOf<CandidateWithBoundDispatchReceiver>()
val receiversWithCandidates = mutableMapOf<ReceiverValueWithSmartCastInfo, List<CandidateWithBoundDispatchReceiver>>()
for (contextReceiver in data.contextReceiversGroup) {
val collectedFromReceiver = data.level.collectCandidates(contextReceiver).toMutableList()
collectedFromReceiver.removeIf { collectedCandidate ->
val duplicate = collected.find { it.descriptor == collectedCandidate.descriptor }
if (duplicate != null) {
duplicate.diagnostics.add(ContextReceiverAmbiguity())
true
} else {
false
}
}
collected.addAll(collectedFromReceiver)
receiversWithCandidates[contextReceiver] = collectedFromReceiver
}
receiversWithCandidates.flatMap {
createCandidates(
it.value,
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
it.key
)
}
}
else -> emptyList()
}
@@ -67,6 +67,10 @@ sealed class TowerData {
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData()
class TowerLevel(val level: ScopeTowerLevel) : TowerData()
class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData()
class BothTowerLevelAndContextReceiversGroup(
val level: ScopeTowerLevel,
val contextReceiversGroup: List<ReceiverValueWithSmartCastInfo>
) : TowerData()
// Has the same meaning as BothTowerLevelAndImplicitReceiver, but it's only used for names lookup, so it doesn't need implicit receiver
class ForLookupForNoExplicitReceiver(val level: ScopeTowerLevel) : TowerData()
}
@@ -222,9 +226,16 @@ class TowerResolver {
}
is ScopeResolutionStep.ContextReceiversGroupsResolution -> if (scope is LexicalScope) {
val contextReceiversGroup = implicitScopeTower.getContextReceivers(scope)
if (contextReceiversGroup.isNotEmpty()) {
TowerData.TowerLevel(ContextReceiversGroupScopeTowerLevel(implicitScopeTower, contextReceiversGroup))
.process()?.let { return it }
TowerData.BothTowerLevelAndContextReceiversGroup(syntheticLevel, contextReceiversGroup).process()
?.let { return it }
for (nonLocalLevel in nonLocalLevels) {
TowerData.BothTowerLevelAndContextReceiversGroup(nonLocalLevel, contextReceiversGroup).process()
?.let { return it }
}
}
}
is ScopeResolutionStep.ImportingScopesResolution -> if (scope is ImportingScope) {