[NI] Make CallResolutionResult more typed
This commit is contained in:
@@ -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;
|
||||
@@ -33,7 +22,7 @@ import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
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.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
@@ -128,7 +117,7 @@ public interface BindingContext {
|
||||
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<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<KtElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<>(DO_NOTHING);
|
||||
|
||||
+13
-7
@@ -73,9 +73,10 @@ class KotlinToResolvedCallTransformer(
|
||||
baseResolvedCall: CallResolutionResult,
|
||||
context: BasicCallResolutionContext
|
||||
): ResolvedCall<D> {
|
||||
val candidate = baseResolvedCall.resultCallAtom!!
|
||||
when (baseResolvedCall.type) {
|
||||
CallResolutionResult.Type.PARTIAL -> {
|
||||
return when (baseResolvedCall) {
|
||||
is PartialCallResolutionResult -> {
|
||||
val candidate = baseResolvedCall.resultCallAtom
|
||||
|
||||
val psiKotlinCall = candidate.atom.psiKotlinCall
|
||||
val psiCall = if (psiKotlinCall is PSIKotlinCallForInvoke)
|
||||
psiKotlinCall.baseCall.psiCall
|
||||
@@ -85,9 +86,12 @@ class KotlinToResolvedCallTransformer(
|
||||
context.trace.record(BindingContext.ONLY_RESOLVED_CALL, psiCall, 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 ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||
resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver,
|
||||
@@ -98,9 +102,11 @@ class KotlinToResolvedCallTransformer(
|
||||
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.
|
||||
*
|
||||
* 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.tower
|
||||
@@ -157,7 +146,7 @@ class SubKotlinCallArgumentImpl(
|
||||
override val dataFlowInfoBeforeThisArgument: DataFlowInfo,
|
||||
override val dataFlowInfoAfterThisArgument: DataFlowInfo,
|
||||
override val receiver: ReceiverValueWithSmartCastInfo,
|
||||
override val callResult: CallResolutionResult
|
||||
override val callResult: PartialCallResolutionResult
|
||||
) : SimplePSIKotlinCallArgument(), SubKotlinCallArgument {
|
||||
override val isSpread: Boolean get() = valueArgument.getSpreadElement() != null
|
||||
override val argumentName: Name? get() = valueArgument.getArgumentName()?.asName
|
||||
|
||||
@@ -174,13 +174,13 @@ class PSICallResolver(
|
||||
result: CallResolutionResult,
|
||||
tracingStrategy: TracingStrategy
|
||||
): OverloadResolutionResults<D> {
|
||||
if (result.type == CallResolutionResult.Type.ALL_CANDIDATES) {
|
||||
val resolvedCalls = result.allCandidates?.map {
|
||||
if (result is AllCandidatesResolutionResult) {
|
||||
val resolvedCalls = result.allCandidates.map {
|
||||
val resultingSubstitutor = it.getSystem().asReadOnlyStorage().buildResultingSubstitutor()
|
||||
kotlinToResolvedCallTransformer.transformToResolvedCall<D>(it.resolvedCall, null, resultingSubstitutor, result.diagnostics)
|
||||
}
|
||||
|
||||
return AllCandidates(resolvedCalls ?: emptyList())
|
||||
return AllCandidates(resolvedCalls)
|
||||
}
|
||||
|
||||
val trace = context.trace
|
||||
@@ -198,7 +198,7 @@ class PSICallResolver(
|
||||
getResultApplicability(result.diagnostics) == ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
|
||||
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 {
|
||||
tracingStrategy.unresolvedReferenceWrongReceiver(trace, listOf(it))
|
||||
}
|
||||
@@ -398,12 +398,8 @@ class PSICallResolver(
|
||||
|
||||
val psiKotlinCall = variable.resolvedCall.atom.psiKotlinCall
|
||||
|
||||
val variableResult = CallResolutionResult(
|
||||
CallResolutionResult.Type.PARTIAL,
|
||||
variable.resolvedCall,
|
||||
listOf(),
|
||||
variable.getSystem().asReadOnlyStorage()
|
||||
)
|
||||
val variableResult = PartialCallResolutionResult(variable.resolvedCall, listOf(), variable.getSystem().asReadOnlyStorage())
|
||||
|
||||
return SubKotlinCallArgumentImpl(
|
||||
CallMaker.makeExternalValueArgument((variableReceiver.receiverValue as ExpressionReceiver).expression),
|
||||
psiKotlinCall.resultDataFlowInfo, psiKotlinCall.resultDataFlowInfo, variableReceiver,
|
||||
|
||||
+1
-5
@@ -56,11 +56,7 @@ class ResolvedAtomCompleter(
|
||||
is ResolvedCallableReferenceAtom -> completeCallableReference(resolvedAtom)
|
||||
is ResolvedLambdaAtom -> completeLambda(resolvedAtom)
|
||||
is ResolvedCallAtom -> completeResolvedCall(resolvedAtom, emptyList())
|
||||
is CallResolutionResult -> {
|
||||
if (resolvedAtom.type == CallResolutionResult.Type.PARTIAL) {
|
||||
resolvedAtom.resultCallAtom?.let { completeResolvedCall(it, resolvedAtom.diagnostics) }
|
||||
}
|
||||
}
|
||||
is PartialCallResolutionResult -> completeResolvedCall(resolvedAtom.resultCallAtom, resolvedAtom.diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-21
@@ -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) {
|
||||
|
||||
+3
-14
@@ -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 {
|
||||
|
||||
+41
-15
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user