Collect all candidates for completion
This commit is contained in:
+7
@@ -89,6 +89,13 @@ class NewResolveOldInference(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.collectAllCandidates) {
|
||||||
|
val allCandidates = towerResolver.collectAllCandidates(baseContext, processor)
|
||||||
|
val result = OverloadResolutionResultsImpl.nameNotFound<CallableDescriptor>()
|
||||||
|
result.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall<CallableDescriptor> }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
val candidates = towerResolver.runResolve(baseContext, processor, useOrder = kind != CallResolver.ResolveKind.CALLABLE_REFERENCE)
|
val candidates = towerResolver.runResolve(baseContext, processor, useOrder = kind != CallResolver.ResolveKind.CALLABLE_REFERENCE)
|
||||||
return convertToOverloadResults(candidates, tracing, context)
|
return convertToOverloadResults(candidates, tracing, context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
interface TowerContext<C> {
|
interface TowerContext<C> {
|
||||||
val name: Name
|
val name: Name
|
||||||
@@ -60,9 +61,19 @@ class TowerResolver {
|
|||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
useOrder: Boolean = true
|
useOrder: Boolean = true
|
||||||
): Collection<C> {
|
): Collection<C> {
|
||||||
|
return run(context, processor, useOrder, SuccessfulResultCollector(context))
|
||||||
|
}
|
||||||
|
|
||||||
val resultCollector = ResultCollector<C> { context.getStatus(it) }
|
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C> {
|
||||||
|
return run(context, processor, false, AllCandidatesCollector(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <C> run(
|
||||||
|
context: TowerContext<C>,
|
||||||
|
processor: ScopeTowerProcessor<C>,
|
||||||
|
useOrder: Boolean,
|
||||||
|
resultCollector: ResultCollector<C>
|
||||||
|
): Collection<C> {
|
||||||
fun collectCandidates(data: TowerData): Collection<C>? {
|
fun collectCandidates(data: TowerData): Collection<C>? {
|
||||||
val candidatesGroups = if (useOrder) {
|
val candidatesGroups = if (useOrder) {
|
||||||
processor.process(data)
|
processor.process(data)
|
||||||
@@ -96,12 +107,39 @@ class TowerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//todo collect all candidates
|
internal abstract class ResultCollector<C>(val context: TowerContext<C>) {
|
||||||
internal class ResultCollector<C>(private val getStatus: (C) -> ResolutionCandidateStatus) {
|
abstract fun getResolved(): Collection<C>?
|
||||||
|
|
||||||
|
abstract fun getFinalCandidates(): Collection<C>
|
||||||
|
|
||||||
|
fun pushCandidates(candidates: Collection<C>) {
|
||||||
|
val filteredCandidates = candidates.filter {
|
||||||
|
context.getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||||
|
}
|
||||||
|
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun addCandidates(candidates: Collection<C>)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AllCandidatesCollector<C>(context: TowerContext<C>): ResultCollector<C>(context) {
|
||||||
|
private val allCandidates = ArrayList<C>()
|
||||||
|
|
||||||
|
override fun getResolved(): Collection<C>? = null
|
||||||
|
|
||||||
|
override fun getFinalCandidates(): Collection<C> = allCandidates
|
||||||
|
|
||||||
|
override fun addCandidates(candidates: Collection<C>) {
|
||||||
|
allCandidates.addAll(candidates)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SuccessfulResultCollector<C>(context: TowerContext<C>): ResultCollector<C>(context) {
|
||||||
private var currentCandidates: Collection<C> = emptyList()
|
private var currentCandidates: Collection<C> = emptyList()
|
||||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
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 }
|
fun getSyntheticResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED }
|
||||||
|
|
||||||
@@ -109,15 +147,13 @@ class TowerResolver {
|
|||||||
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED
|
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFinalCandidates() = getResolved() ?: getSyntheticResolved() ?: getErrors() ?: emptyList()
|
override fun getFinalCandidates() = getResolved() ?: getSyntheticResolved() ?: getErrors() ?: emptyList()
|
||||||
|
|
||||||
fun pushCandidates(candidates: Collection<C>) {
|
override fun addCandidates(candidates: Collection<C>) {
|
||||||
val filteredCandidates = candidates.filter { getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN }
|
val minimalLevel = candidates.map { context.getStatus(it).resultingApplicability }.min()!!
|
||||||
if (filteredCandidates.isEmpty()) return
|
|
||||||
val minimalLevel = filteredCandidates.map { getStatus(it).resultingApplicability }.min()!!
|
|
||||||
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
||||||
currentLevel = minimalLevel
|
currentLevel = minimalLevel
|
||||||
currentCandidates = filteredCandidates.filter { getStatus(it).resultingApplicability == minimalLevel }
|
currentCandidates = candidates.filter { context.getStatus(it).resultingApplicability == minimalLevel }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user