From da003d48ff590abec55cbab1ac1bdb0f8398cc90 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Tue, 15 Aug 2017 16:34:58 +0300 Subject: [PATCH] Support isSuccessful in SuccessfulResultCollector Since now SuccessfulResultCollector do not run computation of resultingApplicability for error candidate before getFinalCandidates(). It is very useful because we can do not run all checks for error candidates if we have not-error candidate. --- .../resolve/calls/tower/TowerResolver.kt | 79 +++++++++++-------- 1 file changed, 45 insertions(+), 34 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 cf8fa35b7a4..b97fac2e46b 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 @@ -208,14 +208,7 @@ class TowerResolver { abstract fun getFinalCandidates(): Collection - fun pushCandidates(candidates: Collection) { - val filteredCandidates = candidates.filter { - it.resultingApplicability != ResolutionCandidateApplicability.HIDDEN - } - if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates) - } - - protected abstract fun addCandidates(candidates: Collection) + abstract fun pushCandidates(candidates: Collection) } class AllCandidatesCollector: ResultCollector() { @@ -225,33 +218,51 @@ class TowerResolver { override fun getFinalCandidates(): Collection = allCandidates - override fun addCandidates(candidates: Collection) { - allCandidates.addAll(candidates) - } - } - - class SuccessfulResultCollector: ResultCollector() { - private var currentCandidates: Collection = emptyList() - private var currentLevel: ResolutionCandidateApplicability? = null - - override fun getSuccessfulCandidates(): Collection? = getResolved() - - fun getResolved() = currentCandidates.takeIf { currentLevel == ResolutionCandidateApplicability.RESOLVED } - - fun getResolvedLowPriority() = currentCandidates.takeIf { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY } - - fun getErrors() = currentCandidates.takeIf { - currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY - } - - override fun getFinalCandidates() = getResolved() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList() - - override fun addCandidates(candidates: Collection) { - val minimalLevel = candidates.map { it.resultingApplicability }.min()!! - if (currentLevel == null || currentLevel!! > minimalLevel) { - currentLevel = minimalLevel - currentCandidates = candidates.filter { it.resultingApplicability == minimalLevel } + override fun pushCandidates(candidates: Collection) { + candidates.filterNotTo(allCandidates) { + it.resultingApplicability == ResolutionCandidateApplicability.HIDDEN } } } + + class SuccessfulResultCollector : ResultCollector() { + private var candidateGroups = arrayListOf>() + private var isSuccessful = false + + override fun getSuccessfulCandidates(): Collection? { + if (!isSuccessful) return null + val firstGroupWithResolved = candidateGroups.firstOrNull { + it.any { it.resultingApplicability == ResolutionCandidateApplicability.RESOLVED } + } ?: return null + + return firstGroupWithResolved.filter { it.resultingApplicability == ResolutionCandidateApplicability.RESOLVED } + } + + override fun pushCandidates(candidates: Collection) { + val thereIsSuccessful = candidates.any { it.isSuccessful } + if (!isSuccessful && !thereIsSuccessful) { + candidateGroups.add(candidates) + return + } + + if (!isSuccessful) { + candidateGroups.clear() + isSuccessful = true + } + if (thereIsSuccessful) { + candidateGroups.add(candidates.filter { it.isSuccessful }) + } + } + + override fun getFinalCandidates(): Collection { + val moreSuitableGroup = candidateGroups.minBy { it.groupApplicability } ?: return emptyList() + val groupApplicability = moreSuitableGroup.groupApplicability + if (groupApplicability == ResolutionCandidateApplicability.HIDDEN) return emptyList() + + return moreSuitableGroup.filter { it.resultingApplicability == groupApplicability } + } + + private val Collection.groupApplicability get() = + minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN + } }