[NI] Introduce basic resolver for many candidates

This commit is contained in:
Mikhail Zarechenskiy
2018-03-15 14:15:27 +03:00
parent 3078e5a6ff
commit 0f60965595
7 changed files with 180 additions and 48 deletions
@@ -44,7 +44,7 @@ class KotlinCallResolver(
): CallResolutionResult {
kotlinCall.checkCallInvariants()
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall, resolutionCallbacks.inferenceSession)
val processor = when (kotlinCall.callKind) {
KotlinCallKind.VARIABLE -> {
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
@@ -85,7 +85,7 @@ class KotlinCallResolver(
collectAllCandidates: Boolean
): CallResolutionResult {
kotlinCall.checkCallInvariants()
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall, resolutionCallbacks.inferenceSession)
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
@@ -5,19 +5,31 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult
interface InferenceSession {
companion object {
val default = object : InferenceSession {
override fun prepareBeforeCompletion(commonSystem: NewConstraintSystem) {}
override fun shouldFixTypeVariables(): Boolean = false
override fun addPartiallyResolvedCall(call: CallResolutionResult) {}
override fun shouldFixTypeVariables(candidate: KotlinResolutionCandidate): Boolean = true
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
}
}
fun prepareBeforeCompletion(commonSystem: NewConstraintSystem)
fun shouldFixTypeVariables(): Boolean
fun addPartiallyResolvedCall(call: CallResolutionResult)
fun shouldFixTypeVariables(candidate: KotlinResolutionCandidate): Boolean
fun addPartialCallInfo(callInfo: PartialCallInfo)
fun addErrorCallInfo(callInfo: ErrorCallInfo)
fun currentConstraintSystem(): ConstraintStorage
}
interface PartialCallInfo {
val callResolutionResult: PartialCallResolutionResult
}
interface ErrorCallInfo {
val callResolutionResult: CallResolutionResult
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
@@ -37,7 +38,7 @@ class KotlinCallCompleter(
val candidate = prepareCandidateForCompletion(factory, candidates, resolutionCallbacks)
val completionType = candidate.prepareForCompletion(expectedType, resolutionCallbacks)
return if (resolutionCallbacks.inferenceSession.shouldFixTypeVariables())
return if (resolutionCallbacks.inferenceSession.shouldFixTypeVariables(candidate))
candidate.runCompletion(completionType, diagnosticHolder, resolutionCallbacks)
else
candidate.asCallResolutionResult(ConstraintSystemCompletionMode.PARTIAL, diagnosticHolder)
@@ -68,9 +69,9 @@ class KotlinCallCompleter(
diagnosticHolder: KotlinDiagnosticsHolder.SimpleHolder,
resolutionCallbacks: KotlinResolutionCallbacks
): CallResolutionResult {
if (ErrorUtils.isError(resolvedCall.candidateDescriptor) || csBuilder.hasContradiction) {
if (isErrorCandidate()) {
runCompletion(resolvedCall, ConstraintSystemCompletionMode.FULL, diagnosticHolder, getSystem(), resolutionCallbacks)
return asCallResolutionResult(completionType, diagnosticHolder, isError = true)
return asCallResolutionResult(completionType, diagnosticHolder)
}
runCompletion(resolvedCall, completionType, diagnosticHolder, getSystem(), resolutionCallbacks)
@@ -155,15 +156,14 @@ class KotlinCallCompleter(
return resolutionCallbacks.createReceiverWithSmartCastInfo(resolvedCall)?.stableType ?: returnType
}
private fun KotlinResolutionCandidate.asCallResolutionResult(
fun KotlinResolutionCandidate.asCallResolutionResult(
type: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder,
isError: Boolean = false
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder
): CallResolutionResult {
val systemStorage = getSystem().asReadOnlyStorage()
val allDiagnostics = diagnosticsHolder.getDiagnostics() + this.diagnosticsFromResolutionParts
if (isError) {
if (isErrorCandidate()) {
return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
}
@@ -173,4 +173,8 @@ class KotlinCallCompleter(
PartialCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
}
}
private fun KotlinResolutionCandidate.isErrorCandidate(): Boolean {
return ErrorUtils.isError(resolvedCall.candidateDescriptor) || hasContradiction
}
}
@@ -48,7 +48,8 @@ class KotlinCallComponents(
class SimpleCandidateFactory(
val callComponents: KotlinCallComponents,
val scopeTower: ImplicitScopeTower,
val kotlinCall: KotlinCall
val kotlinCall: KotlinCall,
val inferenceSession: InferenceSession
) : CandidateFactory<KotlinResolutionCandidate> {
val baseSystem: ConstraintStorage
@@ -61,6 +62,8 @@ class SimpleCandidateFactory(
}
baseSystem.addSubsystemFromArgument(kotlinCall.externalArgument)
baseSystem.addOtherSystem(inferenceSession.currentConstraintSystem())
this.baseSystem = baseSystem.asReadOnlyStorage()
}