From 2d17864fcbdda82d6cec519990b194b31c1b8a0e Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 12 Sep 2022 11:24:57 +0200 Subject: [PATCH] Revert "[FE 1.0] Get rid of `OldResolutionCandidate` and its usages" This reverts commit d89fa8dea9bb72516680d30f6b3c398df3987633. --- .../kotlin/resolve/calls/CallResolver.java | 10 +- .../resolve/calls/model/ResolvedCallImpl.java | 33 ++++++ .../calls/tasks/OldResolutionCandidate.java | 103 ++++++++++++++++++ .../resolve/calls/tower/PSICallResolver.kt | 33 ++++++ .../kotlin/checkers/LazyOperationsLog.kt | 2 + 5 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/OldResolutionCandidate.java diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 13732b55c5f..e495a8a1149 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -189,7 +189,7 @@ public class CallResolver { @NotNull NewResolutionOldInference.ResolutionKind kind ) { return callResolvePerfCounter.>time(() -> { - ResolutionTask resolutionTask = new ResolutionTask<>(kind, name); + ResolutionTask resolutionTask = new ResolutionTask<>(kind, name, null); return doResolveCallOrGetCachedResults(context, resolutionTask, tracing); }); } @@ -574,14 +574,20 @@ public class CallResolver { @Nullable final Name name; + + @Nullable + final Collection> givenCandidates; + @NotNull final NewResolutionOldInference.ResolutionKind resolutionKind; private ResolutionTask( @NotNull NewResolutionOldInference.ResolutionKind kind, - @Nullable Name name + @Nullable Name name, + @Nullable Collection> candidates ) { this.name = name; + givenCandidates = candidates; resolutionKind = kind; } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java index 26ba94830f6..c1d9d257c77 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallImpl.java @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallResolverUtilKt; import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem; import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus; 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.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.scopes.receivers.*; @@ -48,6 +49,17 @@ import static org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.UNKNOW public class ResolvedCallImpl implements MutableResolvedCall { private static final Logger LOG = Logger.getInstance(ResolvedCallImpl.class); + + @NotNull + public static ResolvedCallImpl create( + @NotNull OldResolutionCandidate candidate, + @NotNull DelegatingBindingTrace trace, + @NotNull TracingStrategy tracing, + @NotNull MutableDataFlowInfoForArguments dataFlowInfoForArguments + ) { + return new ResolvedCallImpl<>(candidate, trace, tracing, dataFlowInfoForArguments); + } + private final Call call; private final D candidateDescriptor; private D resultingDescriptor; // Probably substituted @@ -72,6 +84,27 @@ public class ResolvedCallImpl implements MutableRe private boolean completed = false; private KotlinType smartCastDispatchReceiverType = null; private Queue> remainingTasks = null; + + private ResolvedCallImpl( + @NotNull OldResolutionCandidate candidate, + @NotNull DelegatingBindingTrace trace, + @NotNull TracingStrategy tracing, + @NotNull MutableDataFlowInfoForArguments dataFlowInfoForArguments + ) { + this.call = candidate.getCall(); + this.candidateDescriptor = candidate.getDescriptor(); + this.dispatchReceiver = candidate.getDispatchReceiver(); + this.extensionReceiver = null; // ResolutionCandidate can have only dispatch receiver + this.explicitReceiverKind = candidate.getExplicitReceiverKind(); + this.knownTypeParametersSubstitutor = candidate.getKnownTypeParametersResultingSubstitutor(); + this.trace = trace; + this.tracing = tracing; + this.dataFlowInfoForArguments = dataFlowInfoForArguments; + this.typeArguments = createTypeArgumentsMap(candidateDescriptor); + this.valueArguments = createValueArgumentsMap(candidateDescriptor); + this.argumentToParameterMap = createArgumentsToParameterMap(candidateDescriptor); + } + public ResolvedCallImpl( @NotNull Call call, @NotNull D candidateDescriptor, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/OldResolutionCandidate.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/OldResolutionCandidate.java new file mode 100644 index 00000000000..4f536aef61c --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/OldResolutionCandidate.java @@ -0,0 +1,103 @@ +/* + * Copyright 2010-2016 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. + */ + +package org.jetbrains.kotlin.resolve.calls.tasks; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.descriptors.CallableDescriptor; +import org.jetbrains.kotlin.psi.Call; +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; +import org.jetbrains.kotlin.types.TypeSubstitutor; + +public class OldResolutionCandidate { + private final Call call; + private final D candidateDescriptor; + private final TypeSubstitutor knownTypeParametersResultingSubstitutor; + private ReceiverValue dispatchReceiver; // receiver object of a method + private ExplicitReceiverKind explicitReceiverKind; + + private OldResolutionCandidate( + @NotNull Call call, @NotNull D descriptor, @Nullable ReceiverValue dispatchReceiver, + @NotNull ExplicitReceiverKind explicitReceiverKind, + @Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor + ) { + this.call = call; + this.candidateDescriptor = descriptor; + this.dispatchReceiver = dispatchReceiver; + this.explicitReceiverKind = explicitReceiverKind; + this.knownTypeParametersResultingSubstitutor = knownTypeParametersResultingSubstitutor; + } + + public static OldResolutionCandidate create( + @NotNull Call call, @NotNull D descriptor + ) { + return new OldResolutionCandidate<>(call, descriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null); + } + + public static OldResolutionCandidate create( + @NotNull Call call, @NotNull D descriptor, @Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor + ) { + return new OldResolutionCandidate<>(call, descriptor, null, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, + knownTypeParametersResultingSubstitutor); + } + + public static OldResolutionCandidate create( + @NotNull Call call, @NotNull D descriptor, @Nullable ReceiverValue dispatchReceiver, + @NotNull ExplicitReceiverKind explicitReceiverKind, + @Nullable TypeSubstitutor knownTypeParametersResultingSubstitutor + ) { + return new OldResolutionCandidate<>(call, descriptor, dispatchReceiver, explicitReceiverKind, knownTypeParametersResultingSubstitutor); + } + + public void setDispatchReceiver(@Nullable ReceiverValue dispatchReceiver) { + this.dispatchReceiver = dispatchReceiver; + } + + public void setExplicitReceiverKind(@NotNull ExplicitReceiverKind explicitReceiverKind) { + this.explicitReceiverKind = explicitReceiverKind; + } + + @NotNull + public Call getCall() { + return call; + } + + @NotNull + public D getDescriptor() { + return candidateDescriptor; + } + + @Nullable + public ReceiverValue getDispatchReceiver() { + return dispatchReceiver; + } + + @NotNull + public ExplicitReceiverKind getExplicitReceiverKind() { + return explicitReceiverKind; + } + + @Nullable + public TypeSubstitutor getKnownTypeParametersResultingSubstitutor() { + return knownTypeParametersResultingSubstitutor; + } + + @Override + public String toString() { + return candidateDescriptor.toString(); + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 962337ab489..016a71e1a0b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors +import org.jetbrains.kotlin.resolve.calls.tasks.OldResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy import org.jetbrains.kotlin.resolve.calls.util.* import org.jetbrains.kotlin.resolve.checkers.PassingProgressionAsCollectionCallChecker @@ -173,6 +174,38 @@ class PSICallResolver( } } + // actually, `D` is at least FunctionDescriptor, but right now because of CallResolver it isn't possible change upper bound for `D` + fun runResolutionAndInferenceForGivenOldCandidates( + context: BasicCallResolutionContext, + resolutionCandidates: Collection>, + tracingStrategy: TracingStrategy + ): OverloadResolutionResults { + val dispatchReceiver = resolutionCandidates.firstNotNullOfOrNull { it.dispatchReceiver } + + val isSpecialFunction = resolutionCandidates.any { it.descriptor.name in SPECIAL_FUNCTION_NAMES } + val kotlinCall = toKotlinCall( + context, KotlinCallKind.FUNCTION, context.call, givenCandidatesName, tracingStrategy, isSpecialFunction, dispatchReceiver + ) + val scopeTower = ASTScopeTower(context) + val resolutionCallbacks = createResolutionCallbacks(context) + + val givenCandidates = resolutionCandidates.map { + GivenCandidate( + it.descriptor as FunctionDescriptor, + it.dispatchReceiver?.let { context.transformToReceiverWithSmartCastInfo(it) }, + it.knownTypeParametersResultingSubstitutor + ) + } + + val result = kotlinCallResolver.resolveAndCompleteGivenCandidates( + scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates + ) + val overloadResolutionResults = convertToOverloadResolutionResults(context, result, tracingStrategy) + return overloadResolutionResults.also { + clearCacheForApproximationResults() + } + } + private fun clearCacheForApproximationResults() { // Mostly, we approximate captured or some other internal types that don't live longer than resolve for a call, // so it's quite useless to preserve cache for longer time diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/LazyOperationsLog.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/LazyOperationsLog.kt index 1a5138f6995..99076b551e1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/LazyOperationsLog.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/LazyOperationsLog.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.tasks.OldResolutionCandidate import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext import org.jetbrains.kotlin.serialization.deserialization.TypeDeserializer @@ -184,6 +185,7 @@ class LazyOperationsLog( } }.appendQuoted() } + o is OldResolutionCandidate<*> -> DescriptorRenderer.COMPACT.render(o.descriptor).appendQuoted() } return sb.toString() }