[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
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.resolve; package org.jetbrains.kotlin.resolve;
@@ -33,7 +22,7 @@ import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter; import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult; import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
@@ -128,7 +117,7 @@ public interface BindingContext {
new BasicWritableSlice<>(DO_NOTHING); new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<Call, ResolvedCall<?>> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING); WritableSlice<Call, ResolvedCall<?>> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<Call, CallResolutionResult> ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING); WritableSlice<Call, PartialCallResolutionResult> ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<KtExpression, Call> DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING); WritableSlice<KtExpression, Call> DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice(); WritableSlice<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
WritableSlice<KtElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<>(DO_NOTHING); WritableSlice<KtElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<>(DO_NOTHING);
@@ -73,9 +73,10 @@ class KotlinToResolvedCallTransformer(
baseResolvedCall: CallResolutionResult, baseResolvedCall: CallResolutionResult,
context: BasicCallResolutionContext context: BasicCallResolutionContext
): ResolvedCall<D> { ): ResolvedCall<D> {
val candidate = baseResolvedCall.resultCallAtom!! return when (baseResolvedCall) {
when (baseResolvedCall.type) { is PartialCallResolutionResult -> {
CallResolutionResult.Type.PARTIAL -> { val candidate = baseResolvedCall.resultCallAtom
val psiKotlinCall = candidate.atom.psiKotlinCall val psiKotlinCall = candidate.atom.psiKotlinCall
val psiCall = if (psiKotlinCall is PSIKotlinCallForInvoke) val psiCall = if (psiKotlinCall is PSIKotlinCallForInvoke)
psiKotlinCall.baseCall.psiCall psiKotlinCall.baseCall.psiCall
@@ -85,9 +86,12 @@ class KotlinToResolvedCallTransformer(
context.trace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, baseResolvedCall) context.trace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, baseResolvedCall)
context.inferenceSession.addPartiallyResolvedCall(baseResolvedCall) context.inferenceSession.addPartiallyResolvedCall(baseResolvedCall)
return createStubResolvedCallAndWriteItToTrace(candidate, context.trace, baseResolvedCall.diagnostics) createStubResolvedCallAndWriteItToTrace(candidate, context.trace, baseResolvedCall.diagnostics)
} }
CallResolutionResult.Type.ERROR, CallResolutionResult.Type.COMPLETED -> {
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
val candidate = (baseResolvedCall as SingleCallResolutionResult).resultCallAtom
val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor() val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor()
val ktPrimitiveCompleter = ResolvedAtomCompleter( val ktPrimitiveCompleter = ResolvedAtomCompleter(
resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver, resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver,
@@ -98,9 +102,11 @@ class KotlinToResolvedCallTransformer(
ktPrimitiveCompleter.completeAll(subKtPrimitive) ktPrimitiveCompleter.completeAll(subKtPrimitive)
} }
return ktPrimitiveCompleter.completeResolvedCall(candidate, baseResolvedCall.diagnostics) as ResolvedCall<D> ktPrimitiveCompleter.completeResolvedCall(candidate, baseResolvedCall.diagnostics) as ResolvedCall<D>
} }
CallResolutionResult.Type.ALL_CANDIDATES -> error("Cannot transform result for ALL_CANDIDATES mode")
is SingleCallResolutionResult -> error("Call resolution result for one candidate didn't transformed: $baseResolvedCall")
is AllCandidatesResolutionResult -> error("Cannot transform result for ALL_CANDIDATES mode")
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.resolve.calls.tower package org.jetbrains.kotlin.resolve.calls.tower
@@ -157,7 +146,7 @@ class SubKotlinCallArgumentImpl(
override val dataFlowInfoBeforeThisArgument: DataFlowInfo, override val dataFlowInfoBeforeThisArgument: DataFlowInfo,
override val dataFlowInfoAfterThisArgument: DataFlowInfo, override val dataFlowInfoAfterThisArgument: DataFlowInfo,
override val receiver: ReceiverValueWithSmartCastInfo, override val receiver: ReceiverValueWithSmartCastInfo,
override val callResult: CallResolutionResult override val callResult: PartialCallResolutionResult
) : SimplePSIKotlinCallArgument(), SubKotlinCallArgument { ) : SimplePSIKotlinCallArgument(), SubKotlinCallArgument {
override val isSpread: Boolean get() = valueArgument.getSpreadElement() != null override val isSpread: Boolean get() = valueArgument.getSpreadElement() != null
override val argumentName: Name? get() = valueArgument.getArgumentName()?.asName override val argumentName: Name? get() = valueArgument.getArgumentName()?.asName
@@ -174,13 +174,13 @@ class PSICallResolver(
result: CallResolutionResult, result: CallResolutionResult,
tracingStrategy: TracingStrategy tracingStrategy: TracingStrategy
): OverloadResolutionResults<D> { ): OverloadResolutionResults<D> {
if (result.type == CallResolutionResult.Type.ALL_CANDIDATES) { if (result is AllCandidatesResolutionResult) {
val resolvedCalls = result.allCandidates?.map { val resolvedCalls = result.allCandidates.map {
val resultingSubstitutor = it.getSystem().asReadOnlyStorage().buildResultingSubstitutor() val resultingSubstitutor = it.getSystem().asReadOnlyStorage().buildResultingSubstitutor()
kotlinToResolvedCallTransformer.transformToResolvedCall<D>(it.resolvedCall, null, resultingSubstitutor, result.diagnostics) kotlinToResolvedCallTransformer.transformToResolvedCall<D>(it.resolvedCall, null, resultingSubstitutor, result.diagnostics)
} }
return AllCandidates(resolvedCalls ?: emptyList()) return AllCandidates(resolvedCalls)
} }
val trace = context.trace val trace = context.trace
@@ -198,7 +198,7 @@ class PSICallResolver(
getResultApplicability(result.diagnostics) == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER getResultApplicability(result.diagnostics) == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
val resolvedCall = if (isInapplicableReceiver) { val resolvedCall = if (isInapplicableReceiver) {
val singleCandidate = result.resultCallAtom ?: error("Should be not null for result: $result") val singleCandidate = result.resultCallAtom() ?: error("Should be not null for result: $result")
kotlinToResolvedCallTransformer.onlyTransform<D>(singleCandidate, result.diagnostics).also { kotlinToResolvedCallTransformer.onlyTransform<D>(singleCandidate, result.diagnostics).also {
tracingStrategy.unresolvedReferenceWrongReceiver(trace, listOf(it)) tracingStrategy.unresolvedReferenceWrongReceiver(trace, listOf(it))
} }
@@ -398,12 +398,8 @@ class PSICallResolver(
val psiKotlinCall = variable.resolvedCall.atom.psiKotlinCall val psiKotlinCall = variable.resolvedCall.atom.psiKotlinCall
val variableResult = CallResolutionResult( val variableResult = PartialCallResolutionResult(variable.resolvedCall, listOf(), variable.getSystem().asReadOnlyStorage())
CallResolutionResult.Type.PARTIAL,
variable.resolvedCall,
listOf(),
variable.getSystem().asReadOnlyStorage()
)
return SubKotlinCallArgumentImpl( return SubKotlinCallArgumentImpl(
CallMaker.makeExternalValueArgument((variableReceiver.receiverValue as ExpressionReceiver).expression), CallMaker.makeExternalValueArgument((variableReceiver.receiverValue as ExpressionReceiver).expression),
psiKotlinCall.resultDataFlowInfo, psiKotlinCall.resultDataFlowInfo, variableReceiver, psiKotlinCall.resultDataFlowInfo, psiKotlinCall.resultDataFlowInfo, variableReceiver,
@@ -56,11 +56,7 @@ class ResolvedAtomCompleter(
is ResolvedCallableReferenceAtom -> completeCallableReference(resolvedAtom) is ResolvedCallableReferenceAtom -> completeCallableReference(resolvedAtom)
is ResolvedLambdaAtom -> completeLambda(resolvedAtom) is ResolvedLambdaAtom -> completeLambda(resolvedAtom)
is ResolvedCallAtom -> completeResolvedCall(resolvedAtom, emptyList()) is ResolvedCallAtom -> completeResolvedCall(resolvedAtom, emptyList())
is CallResolutionResult -> { is PartialCallResolutionResult -> completeResolvedCall(resolvedAtom.resultCallAtom, resolvedAtom.diagnostics)
if (resolvedAtom.type == CallResolutionResult.Type.PARTIAL) {
resolvedAtom.resultCallAtom?.let { completeResolvedCall(it, resolvedAtom.diagnostics) }
}
}
} }
} }
@@ -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.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter 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.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.inference.model.ExpectedTypeConstraintPosition
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
@@ -41,7 +40,7 @@ class KotlinCallCompleter(
return if (resolutionCallbacks.inferenceSession.shouldFixTypeVariables()) return if (resolutionCallbacks.inferenceSession.shouldFixTypeVariables())
candidate.runCompletion(completionType, diagnosticHolder, resolutionCallbacks) candidate.runCompletion(completionType, diagnosticHolder, resolutionCallbacks)
else else
candidate.asCallResolutionResult(CallResolutionResult.Type.PARTIAL, diagnosticHolder) candidate.asCallResolutionResult(ConstraintSystemCompletionMode.PARTIAL, diagnosticHolder)
} }
fun createAllCandidatesResult( fun createAllCandidatesResult(
@@ -61,7 +60,7 @@ class KotlinCallCompleter(
collectAllCandidatesMode = true collectAllCandidatesMode = true
) )
} }
return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates) return AllCandidatesResolutionResult(candidates)
} }
private fun KotlinResolutionCandidate.runCompletion( private fun KotlinResolutionCandidate.runCompletion(
@@ -71,17 +70,12 @@ class KotlinCallCompleter(
): CallResolutionResult { ): CallResolutionResult {
if (ErrorUtils.isError(resolvedCall.candidateDescriptor) || csBuilder.hasContradiction) { if (ErrorUtils.isError(resolvedCall.candidateDescriptor) || csBuilder.hasContradiction) {
runCompletion(resolvedCall, ConstraintSystemCompletionMode.FULL, diagnosticHolder, getSystem(), resolutionCallbacks) 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) runCompletion(resolvedCall, completionType, diagnosticHolder, getSystem(), resolutionCallbacks)
val callResolutionType = if (completionType == ConstraintSystemCompletionMode.FULL) return asCallResolutionResult(completionType, diagnosticHolder)
CallResolutionResult.Type.COMPLETED
else
CallResolutionResult.Type.PARTIAL
return asCallResolutionResult(callResolutionType, diagnosticHolder)
} }
private fun runCompletion( private fun runCompletion(
@@ -161,18 +155,22 @@ class KotlinCallCompleter(
return resolutionCallbacks.createReceiverWithSmartCastInfo(resolvedCall)?.stableType ?: returnType return resolutionCallbacks.createReceiverWithSmartCastInfo(resolvedCall)?.stableType ?: returnType
} }
private fun KotlinResolutionCandidate?.asCallResolutionResult( private fun KotlinResolutionCandidate.asCallResolutionResult(
type: CallResolutionResult.Type, type: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder diagnosticsHolder: KotlinDiagnosticsHolder.SimpleHolder,
isError: Boolean = false
): CallResolutionResult { ): CallResolutionResult {
val diagnosticsFromResolutionParts = this?.diagnosticsFromResolutionParts ?: emptyList<KotlinCallDiagnostic>() val systemStorage = getSystem().asReadOnlyStorage()
val systemStorage = this?.getSystem()?.asReadOnlyStorage() ?: ConstraintStorage.Empty val allDiagnostics = diagnosticsHolder.getDiagnostics() + this.diagnosticsFromResolutionParts
return CallResolutionResult( if (isError) {
type, return ErrorCallResolutionResult(resolvedCall, allDiagnostics, systemStorage)
this?.resolvedCall, }
diagnosticsHolder.getDiagnostics() + diagnosticsFromResolutionParts,
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. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.resolve.calls.model package org.jetbrains.kotlin.resolve.calls.model
@@ -44,18 +33,6 @@ private fun SimpleKotlinCallArgument.checkReceiverInvariants() {
assert(argumentName == null) { assert(argumentName == null) {
"Argument name should be null for receiver: $this, but it is $argumentName" "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() { fun KotlinCall.checkCallInvariants() {
@@ -65,8 +42,6 @@ fun KotlinCall.checkCallInvariants() {
explicitReceiver.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants() explicitReceiver.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
dispatchReceiverForInvokeExtension.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants() dispatchReceiverForInvokeExtension.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
argumentsInParenthesis.forEach(KotlinCallArgument::checkArgumentInvariants)
externalArgument?.checkArgumentInvariants()
if (callKind != KotlinCallKind.FUNCTION) { if (callKind != KotlinCallKind.FUNCTION) {
assert(externalArgument == null) { assert(externalArgument == null) {
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.resolve.calls.model package org.jetbrains.kotlin.resolve.calls.model
@@ -55,7 +44,7 @@ interface SimpleKotlinCallArgument : KotlinCallArgument, ReceiverKotlinCallArgum
interface ExpressionKotlinCallArgument : SimpleKotlinCallArgument, ResolutionAtom interface ExpressionKotlinCallArgument : SimpleKotlinCallArgument, ResolutionAtom
interface SubKotlinCallArgument : SimpleKotlinCallArgument { interface SubKotlinCallArgument : SimpleKotlinCallArgument {
val callResult: CallResolutionResult val callResult: PartialCallResolutionResult
} }
interface LambdaKotlinCallArgument : PostponableKotlinCallArgument { interface LambdaKotlinCallArgument : PostponableKotlinCallArgument {
@@ -148,29 +148,55 @@ class ResolvedCollectionLiteralAtom(
} }
} }
class CallResolutionResult( sealed class CallResolutionResult(
val type: Type, resultCallAtom: ResolvedCallAtom?,
val resultCallAtom: ResolvedCallAtom?,
val diagnostics: List<KotlinCallDiagnostic>, val diagnostics: List<KotlinCallDiagnostic>,
val constraintSystem: ConstraintStorage, val constraintSystem: ConstraintStorage
val allCandidates: Collection<KotlinResolutionCandidate>? = null
) : ResolvedAtom() { ) : 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 { init {
setAnalyzedResults(listOfNotNull(resultCallAtom)) 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? val ResolvedCallAtom.freshReturnType: UnwrappedType?
get() { get() {
val returnType = candidateDescriptor.returnType ?: return null val returnType = candidateDescriptor.returnType ?: return null