[FE] Report ambiguity in all possible cases
This commit is contained in:
committed by
TeamCityServer
parent
37495bcba0
commit
814777ba8c
@@ -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) {
|
||||
|
||||
+25
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user