[FE 1.0] Resolve this and super calls through the new type inference infra

^KT-48961 In progress
This commit is contained in:
Victor Petukhov
2021-11-02 11:43:50 +03:00
committed by teamcity
parent 3c0c477f06
commit bab8047bb3
11 changed files with 93 additions and 74 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext.*
@@ -290,7 +291,7 @@ class DelegatedPropertyResolver(
resolutionErrorFactory?.let {
val expectedFunction = renderCall(delegateOperatorCall, trace.bindingContext)
trace.report(it.on(delegateExpression, expectedFunction, delegateOperatorResults.resultingCalls))
trace.reportDiagnosticOnce(it.on(delegateExpression, expectedFunction, delegateOperatorResults.resultingCalls))
}
return resolutionErrorFactory != null
@@ -290,6 +290,21 @@ public class CallResolver {
callResolutionContext, resolutionCandidates, TracingStrategyImpl.create(expression, call));
}
@NotNull
public OverloadResolutionResults<ReceiverParameterDescriptor> resolveThisOrSuperCallWithGivenDescriptor(
@NotNull ExpressionTypingContext context,
@NotNull Call call,
@NotNull ReceiverParameterDescriptor descriptor
) {
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
return PSICallResolver.runResolutionAndInferenceForGivenDescriptors(
callResolutionContext,
Collections.singletonList(descriptor),
TracingStrategy.EMPTY
);
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
@NotNull BindingTrace trace,
@@ -605,7 +620,7 @@ public class CallResolver {
if (newInferenceEnabled && resolutionKind instanceof NewResolutionOldInference.ResolutionKind.GivenCandidates) {
assert resolutionTask.givenCandidates != null;
BindingContextUtilsKt.recordScope(context.trace, context.scope, context.call.getCalleeExpression());
return PSICallResolver.runResolutionAndInferenceForGivenCandidates(context, resolutionTask.givenCandidates, tracing);
return PSICallResolver.runResolutionAndInferenceForGivenOldCandidates(context, resolutionTask.givenCandidates, tracing);
}
TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", call);
@@ -143,8 +143,36 @@ class PSICallResolver(
}
}
fun <D : CallableDescriptor> runResolutionAndInferenceForGivenDescriptors(
context: BasicCallResolutionContext,
descriptors: Collection<CallableDescriptor>,
tracingStrategy: TracingStrategy
): OverloadResolutionResults<D> {
val isSpecialFunction = descriptors.any { it.name in SPECIAL_FUNCTION_NAMES }
val kotlinCall = toKotlinCall(
context, KotlinCallKind.FUNCTION, context.call, givenCandidatesName, tracingStrategy, isSpecialFunction, null
)
val scopeTower = ASTScopeTower(context)
val resolutionCallbacks = createResolutionCallbacks(context)
val givenCandidates = descriptors.map {
GivenCandidate(
it,
dispatchReceiver = null,
knownTypeParametersResultingSubstitutor = null
)
}
val result = kotlinCallResolver.resolveAndCompleteGivenCandidates(
scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates
)
return convertToOverloadResolutionResults<D>(context, result, tracingStrategy).also {
clearCacheForApproximationResults()
}
}
// actually, `D` is at least FunctionDescriptor, but right now because of CallResolver it isn't possible change upper bound for `D`
fun <D : CallableDescriptor> runResolutionAndInferenceForGivenCandidates(
fun <D : CallableDescriptor> runResolutionAndInferenceForGivenOldCandidates(
context: BasicCallResolutionContext,
resolutionCandidates: Collection<OldResolutionCandidate<D>>,
tracingStrategy: TracingStrategy
@@ -58,7 +58,6 @@ import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.calls.tasks.OldResolutionCandidate;
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy;
import org.jetbrains.kotlin.resolve.calls.tower.NewAbstractResolvedCall;
@@ -636,27 +635,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
) {
BindingTrace trace = context.trace;
Call call = CallMaker.makeCall(expression, null, null, expression, Collections.emptyList());
OldResolutionCandidate<ReceiverParameterDescriptor> resolutionCandidate =
OldResolutionCandidate.create(
call, descriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
OverloadResolutionResults<ReceiverParameterDescriptor> results =
components.callResolver.resolveThisOrSuperCallWithGivenDescriptor(context, call, descriptor);
ResolvedCallImpl<ReceiverParameterDescriptor> resolvedCall =
ResolvedCallImpl.create(resolutionCandidate,
TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"),
TracingStrategy.EMPTY,
new DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call));
resolvedCall.markCallAsCompleted();
ResolvedCall<?> resolvedCall = results.getResultingCall();
trace.record(RESOLVED_CALL, call, resolvedCall);
trace.record(CALL, expression, call);
if (context.trace.wantsDiagnostics()) {
CallCheckerContext callCheckerContext =
createCallCheckerContext(context);
for (CallChecker checker : components.callCheckers) {
checker.check(resolvedCall, expression, callCheckerContext);
}
}
}
private static boolean isDeclaredInClass(ReceiverParameterDescriptor receiver) {