From 846fb397c444b86a8421e02b4de6ec76e104d4a6 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Fri, 27 Nov 2015 18:33:55 +0300 Subject: [PATCH] Collect all candidates for completion --- .../calls/tower/NewResolveOldInference.kt | 7 +++ .../resolve/calls/tower/TowerResolver.kt | 56 +++++++++++++++---- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolveOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolveOldInference.kt index 043c0cb82a7..7008a7ffd65 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolveOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolveOldInference.kt @@ -89,6 +89,13 @@ class NewResolveOldInference( } } + if (context.collectAllCandidates) { + val allCandidates = towerResolver.collectAllCandidates(baseContext, processor) + val result = OverloadResolutionResultsImpl.nameNotFound() + result.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall } + return result + } + val candidates = towerResolver.runResolve(baseContext, processor, useOrder = kind != CallResolver.ResolveKind.CALLABLE_REFERENCE) return convertToOverloadResults(candidates, tracing, context) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index 95bb6c40342..90525040ff5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.utils.addToStdlib.check +import java.util.* interface TowerContext { val name: Name @@ -60,9 +61,19 @@ class TowerResolver { processor: ScopeTowerProcessor, useOrder: Boolean = true ): Collection { + return run(context, processor, useOrder, SuccessfulResultCollector(context)) + } - val resultCollector = ResultCollector { context.getStatus(it) } + internal fun collectAllCandidates(context: TowerContext, processor: ScopeTowerProcessor): Collection { + return run(context, processor, false, AllCandidatesCollector(context)) + } + private fun run( + context: TowerContext, + processor: ScopeTowerProcessor, + useOrder: Boolean, + resultCollector: ResultCollector + ): Collection { fun collectCandidates(data: TowerData): Collection? { val candidatesGroups = if (useOrder) { processor.process(data) @@ -96,12 +107,39 @@ class TowerResolver { } - //todo collect all candidates - internal class ResultCollector(private val getStatus: (C) -> ResolutionCandidateStatus) { + internal abstract class ResultCollector(val context: TowerContext) { + abstract fun getResolved(): Collection? + + abstract fun getFinalCandidates(): Collection + + fun pushCandidates(candidates: Collection) { + val filteredCandidates = candidates.filter { + context.getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN + } + if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates) + } + + protected abstract fun addCandidates(candidates: Collection) + } + + internal class AllCandidatesCollector(context: TowerContext): ResultCollector(context) { + private val allCandidates = ArrayList() + + override fun getResolved(): Collection? = null + + override fun getFinalCandidates(): Collection = allCandidates + + override fun addCandidates(candidates: Collection) { + allCandidates.addAll(candidates) + } + + } + + internal class SuccessfulResultCollector(context: TowerContext): ResultCollector(context) { private var currentCandidates: Collection = emptyList() private var currentLevel: ResolutionCandidateApplicability? = null - fun getResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED } + override fun getResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED } fun getSyntheticResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED } @@ -109,15 +147,13 @@ class TowerResolver { currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED } - fun getFinalCandidates() = getResolved() ?: getSyntheticResolved() ?: getErrors() ?: emptyList() + override fun getFinalCandidates() = getResolved() ?: getSyntheticResolved() ?: getErrors() ?: emptyList() - fun pushCandidates(candidates: Collection) { - val filteredCandidates = candidates.filter { getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN } - if (filteredCandidates.isEmpty()) return - val minimalLevel = filteredCandidates.map { getStatus(it).resultingApplicability }.min()!! + override fun addCandidates(candidates: Collection) { + val minimalLevel = candidates.map { context.getStatus(it).resultingApplicability }.min()!! if (currentLevel == null || currentLevel!! > minimalLevel) { currentLevel = minimalLevel - currentCandidates = filteredCandidates.filter { getStatus(it).resultingApplicability == minimalLevel } + currentCandidates = candidates.filter { context.getStatus(it).resultingApplicability == minimalLevel } } } }