[NI] Make CallResolutionResult more typed

This commit is contained in:
Mikhail Zarechenskiy
2018-03-15 13:01:57 +03:00
parent c8ef785010
commit ff10e97c28
9 changed files with 92 additions and 128 deletions
@@ -8,7 +8,6 @@ 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
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
@@ -41,7 +40,7 @@ class KotlinCallCompleter(
return if (resolutionCallbacks.inferenceSession.shouldFixTypeVariables())
candidate.runCompletion(completionType, diagnosticHolder, resolutionCallbacks)
else
candidate.asCallResolutionResult(CallResolutionResult.Type.PARTIAL, diagnosticHolder)
candidate.asCallResolutionResult(ConstraintSystemCompletionMode.PARTIAL, diagnosticHolder)
}
fun createAllCandidatesResult(
@@ -61,7 +60,7 @@ class KotlinCallCompleter(
collectAllCandidatesMode = true
)
}
return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates)
return AllCandidatesResolutionResult(candidates)
}
private fun KotlinResolutionCandidate.runCompletion(
@@ -71,17 +70,12 @@ class KotlinCallCompleter(
): CallResolutionResult {
if (ErrorUtils.isError(resolvedCall.candidateDescriptor) || csBuilder.hasContradiction) {
runCompletion(resolvedCall, ConstraintSystemCompletionMode.FULL, diagnosticHolder, getSystem(), resolutionCallbacks)
return asCallResolutionResult(CallResolutionResult.Type.ERROR, diagnosticHolder)
return asCallResolutionResult(completionType, diagnosticHolder, isError = true)
}
runCompletion(resolvedCall, completionType, diagnosticHolder, getSystem(), resolutionCallbacks)
val callResolutionType = if (completionType == ConstraintSystemCompletionMode.FULL)
CallResolutionResult.Type.COMPLETED
else
CallResolutionResult.Type.PARTIAL
return asCallResolutionResult(callResolutionType, diagnosticHolder)
return asCallResolutionResult(completionType, diagnosticHolder)
}
private fun runCompletion(
@@ -161,18 +155,22 @@ class KotlinCallCompleter(
return resolutionCallbacks.createReceiverWithSmartCastInfo(resolvedCall)?.stableType ?: returnType
}
private fun KotlinResolutionCandidate?.asCallResolutionResult(
type: CallResolutionResult.Type,
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder
private fun KotlinResolutionCandidate.asCallResolutionResult(
type: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder,
isError: Boolean = false
): CallResolutionResult {
val diagnosticsFromResolutionParts = this?.diagnosticsFromResolutionParts ?: emptyList<KotlinCallDiagnostic>()
val systemStorage = this?.getSystem()?.asReadOnlyStorage() ?: ConstraintStorage.Empty
val systemStorage = getSystem().asReadOnlyStorage()
val allDiagnostics = diagnosticsHolder.getDiagnostics() + this.diagnosticsFromResolutionParts
return CallResolutionResult(
type,
this?.resolvedCall,
diagnosticsHolder.getDiagnostics() + diagnosticsFromResolutionParts,
systemStorage
)
if (isError) {
return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
}
return if (type == ConstraintSystemCompletionMode.FULL) {
CompletedCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
} else {
PartialCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
}
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.calls.model
@@ -44,18 +33,6 @@ private fun SimpleKotlinCallArgument.checkReceiverInvariants() {
assert(argumentName == null) {
"Argument name should be null for receiver: $this, but it is $argumentName"
}
checkArgumentInvariants()
}
private fun KotlinCallArgument.checkArgumentInvariants() {
if (this is SubKotlinCallArgument) {
assert(callResult.type == CallResolutionResult.Type.PARTIAL) {
"SubCall should has type PARTIAL: $callResult"
}
assert(callResult.resultCallAtom != null) {
"SubCall should has resultCallAtom: $callResult"
}
}
}
fun KotlinCall.checkCallInvariants() {
@@ -65,8 +42,6 @@ fun KotlinCall.checkCallInvariants() {
explicitReceiver.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
dispatchReceiverForInvokeExtension.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
argumentsInParenthesis.forEach(KotlinCallArgument::checkArgumentInvariants)
externalArgument?.checkArgumentInvariants()
if (callKind != KotlinCallKind.FUNCTION) {
assert(externalArgument == null) {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.calls.model
@@ -55,7 +44,7 @@ interface SimpleKotlinCallArgument : KotlinCallArgument, ReceiverKotlinCallArgum
interface ExpressionKotlinCallArgument : SimpleKotlinCallArgument, ResolutionAtom
interface SubKotlinCallArgument : SimpleKotlinCallArgument {
val callResult: CallResolutionResult
val callResult: PartialCallResolutionResult
}
interface LambdaKotlinCallArgument : PostponableKotlinCallArgument {
@@ -148,29 +148,55 @@ class ResolvedCollectionLiteralAtom(
}
}
class CallResolutionResult(
val type: Type,
val resultCallAtom: ResolvedCallAtom?,
sealed class CallResolutionResult(
resultCallAtom: ResolvedCallAtom?,
val diagnostics: List<KotlinCallDiagnostic>,
val constraintSystem: ConstraintStorage,
val allCandidates: Collection<KotlinResolutionCandidate>? = null
val constraintSystem: ConstraintStorage
) : 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
ALL_CANDIDATES // allCandidates != null
}
init {
setAnalyzedResults(listOfNotNull(resultCallAtom))
}
override fun toString() = "$type, resultCallAtom = $resultCallAtom, (${diagnostics.joinToString()})"
final override fun setAnalyzedResults(subResolvedAtoms: List<ResolvedAtom>) {
super.setAnalyzedResults(subResolvedAtoms)
}
override val atom: ResolutionAtom? get() = null
override fun toString() = "diagnostics: (${diagnostics.joinToString()})"
}
open class SingleCallResolutionResult(
val resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage
) : CallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class PartialCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class CompletedCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class ErrorCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List<KotlinCallDiagnostic>,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class AllCandidatesResolutionResult(
val allCandidates: Collection<KotlinResolutionCandidate>
) : CallResolutionResult(null, emptyList(), ConstraintStorage.Empty)
fun CallResolutionResult.resultCallAtom(): ResolvedCallAtom? =
if (this is SingleCallResolutionResult) resultCallAtom else null
val ResolvedCallAtom.freshReturnType: UnwrappedType?
get() {
val returnType = candidateDescriptor.returnType ?: return null