[NI] Support AllCandidates mode for features in IDE

This commit is contained in:
Mikhail Zarechenskiy
2017-08-21 14:57:21 +03:00
parent 3f8a685ace
commit e666b87545
5 changed files with 65 additions and 12 deletions
@@ -38,7 +38,8 @@ class KotlinCallResolver(
resolutionCallbacks: KotlinResolutionCallbacks,
kotlinCall: KotlinCall,
expectedType: UnwrappedType?,
factoryProviderForInvoke: CandidateFactoryProviderForInvoke<KotlinResolutionCandidate>
factoryProviderForInvoke: CandidateFactoryProviderForInvoke<KotlinResolutionCandidate>,
collectAllCandidates: Boolean
): CallResolutionResult {
kotlinCall.checkCallInvariants()
@@ -53,6 +54,11 @@ class KotlinCallResolver(
KotlinCallKind.UNSUPPORTED -> throw UnsupportedOperationException()
}
if (collectAllCandidates) {
val allCandidates = towerResolver.collectAllCandidates(scopeTower, processor)
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
}
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED)
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
@@ -63,12 +69,21 @@ class KotlinCallResolver(
resolutionCallbacks: KotlinResolutionCallbacks,
kotlinCall: KotlinCall,
expectedType: UnwrappedType?,
givenCandidates: Collection<GivenCandidate>
givenCandidates: Collection<GivenCandidate>,
collectAllCandidates: Boolean
): CallResolutionResult {
kotlinCall.checkCallInvariants()
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
if (collectAllCandidates) {
val allCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
TowerResolver.AllCandidatesCollector(),
useOrder = false)
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
}
val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
TowerResolver.SuccessfulResultCollector(),
useOrder = true)
@@ -68,7 +68,25 @@ class KotlinCallCompleter(
else {
CallResolutionResult(CallResolutionResult.Type.PARTIAL, candidate.resolvedCall, diagnosticHolder.getDiagnostics(), constraintSystem.asReadOnlyStorage())
}
}
fun createAllCandidatesResult(
candidates: Collection<KotlinResolutionCandidate>,
expectedType: UnwrappedType?,
resolutionCallbacks: KotlinResolutionCallbacks
): CallResolutionResult {
val diagnosticsHolder = KotlinDiagnosticsHolder.SimpleHolder()
for (candidate in candidates) {
candidate.prepareForCompletion(expectedType)
runCompletion(
candidate.resolvedCall,
ConstraintSystemCompletionMode.FULL,
diagnosticsHolder,
candidate.getSystem(),
resolutionCallbacks,
skipPostponedArguments = true)
}
return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates)
}
private fun runCompletion(
@@ -76,11 +94,14 @@ class KotlinCallCompleter(
completionMode: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder,
constraintSystem: NewConstraintSystem,
resolutionCallbacks: KotlinResolutionCallbacks
resolutionCallbacks: KotlinResolutionCallbacks,
skipPostponedArguments: Boolean = false
) {
val returnType = resolvedCallAtom.freshReturnType ?: constraintSystem.builtIns.unitType
kotlinConstraintSystemCompleter.runCompletion(constraintSystem.asConstraintSystemCompleterContext(), completionMode, resolvedCallAtom, returnType) {
postponedArgumentsAnalyzer.analyze(constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it)
if (!skipPostponedArguments) {
postponedArgumentsAnalyzer.analyze(constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it)
}
}
constraintSystem.diagnostics.forEach(diagnosticsHolder::addDiagnostic)
@@ -150,14 +150,16 @@ class CallResolutionResult(
val type: Type,
val resultCallAtom: ResolvedCallAtom?,
diagnostics: List<KotlinCallDiagnostic>,
val constraintSystem: ConstraintStorage
val constraintSystem: ConstraintStorage,
val allCandidates: Collection<KotlinResolutionCandidate>? = null
) : ResolvedAtom() {
override val atom: ResolutionAtom? get() = null
enum class Type {
COMPLETED, // resultSubstitutor possible create use constraintSystem
PARTIAL,
ERROR // if resultCallAtom == null it means that there is errors NoneCandidates or ManyCandidates
ERROR, // if resultCallAtom == null it means that there is errors NoneCandidates or ManyCandidates
ALL_CANDIDATES // allCandidates != null
}
init {