001    /*
002     * Copyright 2010-2016 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.resolve.calls;
018    
019    import com.intellij.psi.PsiElement;
020    import kotlin.Pair;
021    import kotlin.jvm.functions.Function0;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.annotations.Nullable;
024    import org.jetbrains.kotlin.builtins.FunctionTypesKt;
025    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
026    import org.jetbrains.kotlin.config.LanguageVersionSettings;
027    import org.jetbrains.kotlin.descriptors.*;
028    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
029    import org.jetbrains.kotlin.name.Name;
030    import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
031    import org.jetbrains.kotlin.psi.*;
032    import org.jetbrains.kotlin.resolve.*;
033    import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
034    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
035    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode;
036    import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
037    import org.jetbrains.kotlin.resolve.calls.context.*;
038    import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceUtilKt;
039    import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
040    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
041    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
042    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
043    import org.jetbrains.kotlin.resolve.calls.tasks.*;
044    import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference;
045    import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
046    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
047    import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
048    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
049    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
050    import org.jetbrains.kotlin.types.KotlinType;
051    import org.jetbrains.kotlin.types.TypeSubstitutor;
052    import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
053    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
054    import org.jetbrains.kotlin.types.expressions.ExpressionTypingVisitorDispatcher;
055    import org.jetbrains.kotlin.util.OperatorNameConventions;
056    import org.jetbrains.kotlin.util.PerformanceCounter;
057    
058    import javax.inject.Inject;
059    import java.util.*;
060    
061    import static org.jetbrains.kotlin.diagnostics.Errors.*;
062    import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
063    import static org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE;
064    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
065    
066    @SuppressWarnings("RedundantTypeArguments")
067    public class CallResolver {
068        private ExpressionTypingServices expressionTypingServices;
069        private TypeResolver typeResolver;
070        private ArgumentTypeResolver argumentTypeResolver;
071        private GenericCandidateResolver genericCandidateResolver;
072        private CallCompleter callCompleter;
073        private NewResolutionOldInference newCallResolver;
074        private final KotlinBuiltIns builtIns;
075        private final LanguageVersionSettings languageVersionSettings;
076    
077        private static final PerformanceCounter callResolvePerfCounter = PerformanceCounter.Companion.create("Call resolve", ExpressionTypingVisitorDispatcher.typeInfoPerfCounter);
078    
079        public CallResolver(
080                @NotNull KotlinBuiltIns builtIns,
081                @NotNull LanguageVersionSettings languageVersionSettings
082        ) {
083            this.builtIns = builtIns;
084            this.languageVersionSettings = languageVersionSettings;
085        }
086    
087        // component dependency cycle
088        @Inject
089        public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
090            this.expressionTypingServices = expressionTypingServices;
091        }
092    
093        // component dependency cycle
094        @Inject
095        public void setTypeResolver(@NotNull TypeResolver typeResolver) {
096            this.typeResolver = typeResolver;
097        }
098    
099        // component dependency cycle
100        @Inject
101        public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) {
102            this.argumentTypeResolver = argumentTypeResolver;
103        }
104    
105        // component dependency cycle
106        @Inject
107        public void setGenericCandidateResolver(GenericCandidateResolver genericCandidateResolver) {
108            this.genericCandidateResolver = genericCandidateResolver;
109        }
110    
111        // component dependency cycle
112        @Inject
113        public void setCallCompleter(@NotNull CallCompleter callCompleter) {
114            this.callCompleter = callCompleter;
115        }
116    
117        // component dependency cycle
118        @Inject
119        public void setCallCompleter(@NotNull NewResolutionOldInference newCallResolver) {
120            this.newCallResolver = newCallResolver;
121        }
122    
123        @NotNull
124        public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(@NotNull BasicCallResolutionContext context) {
125            KtExpression calleeExpression = context.call.getCalleeExpression();
126            assert calleeExpression instanceof KtSimpleNameExpression;
127            KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) calleeExpression;
128            Name referencedName = nameExpression.getReferencedNameAsName();
129            return computeTasksAndResolveCall(
130                    context, referencedName, nameExpression,
131                    NewResolutionOldInference.ResolutionKind.Variable.INSTANCE);
132        }
133    
134        @NotNull
135        public OverloadResolutionResults<CallableDescriptor> resolveCallForMember(
136                @NotNull KtSimpleNameExpression nameExpression,
137                @NotNull BasicCallResolutionContext context
138        ) {
139            return computeTasksAndResolveCall(
140                    context, nameExpression.getReferencedNameAsName(), nameExpression,
141                    NewResolutionOldInference.ResolutionKind.CallableReference.INSTANCE);
142        }
143    
144        @NotNull
145        public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
146                @NotNull ResolutionContext<?> context,
147                @NotNull Call call,
148                @NotNull KtReferenceExpression functionReference,
149                @NotNull Name name
150        ) {
151            BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
152            return computeTasksAndResolveCall(
153                    callResolutionContext, name, functionReference,
154                    NewResolutionOldInference.ResolutionKind.Function.INSTANCE);
155        }
156    
157        @NotNull
158        private OverloadResolutionResults<FunctionDescriptor> resolveCallForInvoke(
159                @NotNull BasicCallResolutionContext context,
160                @NotNull TracingStrategy tracing
161        ) {
162            return computeTasksAndResolveCall(
163                    context, OperatorNameConventions.INVOKE, tracing,
164                    NewResolutionOldInference.ResolutionKind.Invoke.INSTANCE);
165        }
166    
167        @NotNull
168        private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
169                @NotNull BasicCallResolutionContext context,
170                @NotNull Name name,
171                @NotNull KtReferenceExpression referenceExpression,
172                @NotNull NewResolutionOldInference.ResolutionKind<D> kind
173        ) {
174            TracingStrategy tracing = TracingStrategyImpl.create(referenceExpression, context.call);
175            return computeTasksAndResolveCall(context, name, tracing, kind);
176        }
177    
178        @NotNull
179        private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
180                @NotNull final BasicCallResolutionContext context,
181                @NotNull final Name name,
182                @NotNull final TracingStrategy tracing,
183                @NotNull final NewResolutionOldInference.ResolutionKind<D> kind
184        ) {
185            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<D>>() {
186                @Override
187                public OverloadResolutionResults<D> invoke() {
188                    ResolutionTask<D> resolutionTask = new ResolutionTask<D>(
189                            kind, name, null
190                    );
191                    return doResolveCallOrGetCachedResults(context, resolutionTask, tracing);
192                }
193            });
194        }
195    
196        @NotNull
197        private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksFromCandidatesAndResolvedCall(
198                @NotNull BasicCallResolutionContext context,
199                @NotNull KtReferenceExpression referenceExpression,
200                @NotNull Collection<ResolutionCandidate<D>> candidates
201        ) {
202            return computeTasksFromCandidatesAndResolvedCall(context, candidates,
203                                                             TracingStrategyImpl.create(referenceExpression, context.call));
204        }
205    
206        @NotNull
207        private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksFromCandidatesAndResolvedCall(
208                @NotNull final BasicCallResolutionContext context,
209                @NotNull final Collection<ResolutionCandidate<D>> candidates,
210                @NotNull final TracingStrategy tracing
211        ) {
212            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<D>>() {
213                @Override
214                public OverloadResolutionResults<D> invoke() {
215                    ResolutionTask<D> resolutionTask = new ResolutionTask<D>(
216                            new NewResolutionOldInference.ResolutionKind.GivenCandidates<D>(), null, candidates
217                    );
218                    return doResolveCallOrGetCachedResults(context, resolutionTask, tracing);
219                }
220            });
221        }
222    
223        @NotNull
224        public OverloadResolutionResults<FunctionDescriptor> resolveBinaryCall(
225                ExpressionTypingContext context,
226                ExpressionReceiver receiver,
227                KtBinaryExpression binaryExpression,
228                Name name
229        ) {
230            return resolveCallWithGivenName(
231                    context,
232                    CallMaker.makeCall(receiver, binaryExpression),
233                    binaryExpression.getOperationReference(),
234                    name
235            );
236        }
237    
238        @NotNull
239        public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
240                @NotNull BindingTrace trace,
241                @NotNull LexicalScope scope,
242                @NotNull Call call,
243                @NotNull KotlinType expectedType,
244                @NotNull DataFlowInfo dataFlowInfo,
245                boolean isAnnotationContext
246        ) {
247            return resolveFunctionCall(
248                    BasicCallResolutionContext.create(
249                            trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
250                            isAnnotationContext
251                    )
252            );
253        }
254    
255        @NotNull
256        public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(@NotNull BasicCallResolutionContext context) {
257            ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
258    
259            Call.CallType callType = context.call.getCallType();
260            if (callType == Call.CallType.ARRAY_GET_METHOD || callType == Call.CallType.ARRAY_SET_METHOD) {
261                Name name = callType == Call.CallType.ARRAY_GET_METHOD ? OperatorNameConventions.GET : OperatorNameConventions.SET;
262                KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) context.call.getCallElement();
263                return computeTasksAndResolveCall(
264                        context, name, arrayAccessExpression,
265                        NewResolutionOldInference.ResolutionKind.Function.INSTANCE);
266            }
267    
268            KtExpression calleeExpression = context.call.getCalleeExpression();
269            if (calleeExpression instanceof KtSimpleNameExpression) {
270                KtSimpleNameExpression expression = (KtSimpleNameExpression) calleeExpression;
271                return computeTasksAndResolveCall(
272                        context, expression.getReferencedNameAsName(), expression,
273                        NewResolutionOldInference.ResolutionKind.Function.INSTANCE);
274            }
275            else if (calleeExpression instanceof KtConstructorCalleeExpression) {
276                return (OverloadResolutionResults) resolveCallForConstructor(context, (KtConstructorCalleeExpression) calleeExpression);
277            }
278            else if (calleeExpression instanceof KtConstructorDelegationReferenceExpression) {
279                KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement();
280                DeclarationDescriptor container = context.scope.getOwnerDescriptor();
281                assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container;
282                return (OverloadResolutionResults) resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression,
283                                                        (ClassConstructorDescriptor) container);
284            }
285            else if (calleeExpression == null) {
286                return checkArgumentTypesAndFail(context);
287            }
288    
289            // Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2)
290            KotlinType expectedType = NO_EXPECTED_TYPE;
291            if (calleeExpression instanceof KtLambdaExpression) {
292                int parameterNumber = ((KtLambdaExpression) calleeExpression).getValueParameters().size();
293                List<KotlinType> parameterTypes = new ArrayList<KotlinType>(parameterNumber);
294                for (int i = 0; i < parameterNumber; i++) {
295                    parameterTypes.add(NO_EXPECTED_TYPE);
296                }
297                expectedType = FunctionTypesKt.createFunctionType(
298                        builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, null, context.expectedType
299                );
300            }
301            KotlinType calleeType = expressionTypingServices.safeGetType(
302                    context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
303            ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
304    
305            Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call,
306                                                                  false);
307            TracingStrategyForInvoke tracingForInvoke = new TracingStrategyForInvoke(calleeExpression, call, calleeType);
308            return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke);
309        }
310    
311        private OverloadResolutionResults<ConstructorDescriptor> resolveCallForConstructor(
312                @NotNull BasicCallResolutionContext context,
313                @NotNull KtConstructorCalleeExpression expression
314        ) {
315            assert context.call.getExplicitReceiver() == null :
316                    "Constructor can't be invoked with explicit receiver: " + context.call.getCallElement().getText();
317    
318            context.trace.record(BindingContext.LEXICAL_SCOPE, context.call.getCallElement(), context.scope);
319    
320            KtReferenceExpression functionReference = expression.getConstructorReferenceExpression();
321            KtTypeReference typeReference = expression.getTypeReference();
322            if (functionReference == null || typeReference == null) {
323                return checkArgumentTypesAndFail(context); // No type there
324            }
325            KotlinType constructedType = typeResolver.resolveType(context.scope, typeReference, context.trace, true);
326            if (constructedType.isError()) {
327                return checkArgumentTypesAndFail(context);
328            }
329    
330            DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
331            if (!(declarationDescriptor instanceof ClassDescriptor)) {
332                context.trace.report(NOT_A_CLASS.on(expression));
333                return checkArgumentTypesAndFail(context);
334            }
335    
336            ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
337    
338            Collection<ClassConstructorDescriptor> constructors = classDescriptor.getConstructors();
339            if (constructors.isEmpty()) {
340                context.trace.report(NO_CONSTRUCTOR.on(CallUtilKt.getValueArgumentListOrElement(context.call)));
341                return checkArgumentTypesAndFail(context);
342            }
343    
344            Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
345                    prepareCandidatesAndContextForConstructorCall(constructedType, context);
346    
347            Collection<ResolutionCandidate<ConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
348            context = candidatesAndContext.getSecond();
349    
350            return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates);
351        }
352    
353        @Nullable
354        public OverloadResolutionResults<ConstructorDescriptor> resolveConstructorDelegationCall(
355                @NotNull BindingTrace trace, @NotNull LexicalScope scope, @NotNull DataFlowInfo dataFlowInfo,
356                @NotNull ClassConstructorDescriptor constructorDescriptor,
357                @NotNull KtConstructorDelegationCall call
358        ) {
359            // Method returns `null` when there is nothing to resolve in trivial cases like `null` call expression or
360            // when super call should be conventional enum constructor and super call should be empty
361    
362            BasicCallResolutionContext context = BasicCallResolutionContext.create(
363                    trace, scope,
364                    CallMaker.makeCall(null, null, call),
365                    NO_EXPECTED_TYPE,
366                    dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
367                    false);
368    
369            if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
370    
371            if (constructorDescriptor.getConstructedClass().getKind() == ClassKind.ENUM_CLASS && call.isImplicit()) {
372                return null;
373            }
374    
375            return resolveConstructorDelegationCall(
376                    context,
377                    call,
378                    call.getCalleeExpression(),
379                    constructorDescriptor
380            );
381        }
382    
383        @NotNull
384        private OverloadResolutionResults<ConstructorDescriptor> resolveConstructorDelegationCall(
385                @NotNull BasicCallResolutionContext context,
386                @NotNull KtConstructorDelegationCall call,
387                @NotNull KtConstructorDelegationReferenceExpression calleeExpression,
388                @NotNull ClassConstructorDescriptor calleeConstructor
389        ) {
390            context.trace.record(BindingContext.LEXICAL_SCOPE, call, context.scope);
391    
392            ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration();
393    
394            boolean isThisCall = calleeExpression.isThis();
395            if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) {
396                context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(calleeExpression));
397                return checkArgumentTypesAndFail(context);
398            }
399    
400            ClassDescriptor delegateClassDescriptor = isThisCall ? currentClassDescriptor :
401                                                      DescriptorUtilsKt.getSuperClassOrAny(currentClassDescriptor);
402            Collection<ClassConstructorDescriptor> constructors = delegateClassDescriptor.getConstructors();
403    
404            if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
405                if (DescriptorUtils.canHaveDeclaredConstructors(currentClassDescriptor)) {
406                    // Diagnostic is meaningless when reporting on interfaces and object
407                    context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
408                            (KtConstructorDelegationCall) calleeExpression.getParent()
409                    ));
410                }
411                if (call.isImplicit()) return OverloadResolutionResultsImpl.nameNotFound();
412            }
413    
414            if (constructors.isEmpty()) {
415                context.trace.report(NO_CONSTRUCTOR.on(CallUtilKt.getValueArgumentListOrElement(context.call)));
416                return checkArgumentTypesAndFail(context);
417            }
418    
419    
420            KotlinType superType = isThisCall ?
421                                      calleeConstructor.getContainingDeclaration().getDefaultType() :
422                                      DescriptorUtils.getSuperClassType(currentClassDescriptor);
423    
424            Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
425                    prepareCandidatesAndContextForConstructorCall(superType, context);
426            Collection<ResolutionCandidate<ConstructorDescriptor>> candidates = candidatesAndContext.getFirst();
427            context = candidatesAndContext.getSecond();
428    
429            TracingStrategy tracing = call.isImplicit() ?
430                                      new TracingStrategyForImplicitConstructorDelegationCall(call, context.call) :
431                                      TracingStrategyImpl.create(calleeExpression, context.call);
432    
433            PsiElement reportOn = call.isImplicit() ? call : calleeExpression;
434    
435            if (delegateClassDescriptor.isInner()
436                    && !DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, reportOn,
437                                                                      (ClassDescriptor) delegateClassDescriptor.getContainingDeclaration())) {
438                return checkArgumentTypesAndFail(context);
439            }
440    
441            return computeTasksFromCandidatesAndResolvedCall(context, candidates, tracing);
442        }
443    
444        @NotNull
445        private static Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall(
446                @NotNull KotlinType superType,
447                @NotNull BasicCallResolutionContext context
448        ) {
449            if (!(superType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
450                return new Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext>(
451                        Collections.<ResolutionCandidate<ConstructorDescriptor>>emptyList(), context);
452            }
453    
454            // If any constructor has type parameter (currently it only can be true for ones from Java), try to infer arguments for them
455            // Otherwise use NO_EXPECTED_TYPE and knownTypeParametersSubstitutor
456            boolean anyConstructorHasDeclaredTypeParameters =
457                    anyConstructorHasDeclaredTypeParameters(superType.getConstructor().getDeclarationDescriptor());
458    
459            TypeSubstitutor knownTypeParametersSubstitutor = anyConstructorHasDeclaredTypeParameters ? null : TypeSubstitutor.create(superType);
460            if (anyConstructorHasDeclaredTypeParameters) {
461                context = context.replaceExpectedType(superType);
462            }
463    
464            Collection<ResolutionCandidate<ConstructorDescriptor>> candidates =
465                    CallResolverUtilKt.createResolutionCandidatesForConstructors(context.scope, context.call, superType, knownTypeParametersSubstitutor);
466    
467            return new Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext>(candidates, context);
468        }
469    
470        private static boolean anyConstructorHasDeclaredTypeParameters(@Nullable ClassifierDescriptor classDescriptor) {
471            if (!(classDescriptor instanceof ClassDescriptor)) return false;
472            for (ConstructorDescriptor constructor : ((ClassDescriptor) classDescriptor).getConstructors()) {
473                if (constructor.getTypeParameters().size() > constructor.getContainingDeclaration().getDeclaredTypeParameters().size()) return true;
474            }
475    
476            return false;
477        }
478    
479        public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate(
480                @NotNull final Call call,
481                @NotNull final TracingStrategy tracing,
482                @NotNull final ResolutionContext<?> context,
483                @NotNull final ResolutionCandidate<FunctionDescriptor> candidate,
484                @Nullable final MutableDataFlowInfoForArguments dataFlowInfoForArguments
485        ) {
486            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<FunctionDescriptor>>() {
487                @Override
488                public OverloadResolutionResults<FunctionDescriptor> invoke() {
489                    BasicCallResolutionContext basicCallResolutionContext =
490                            BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, dataFlowInfoForArguments);
491    
492                    Set<ResolutionCandidate<FunctionDescriptor>> candidates = Collections.singleton(candidate);
493    
494                    ResolutionTask<FunctionDescriptor> resolutionTask =
495                            new ResolutionTask<FunctionDescriptor>(
496                                    new NewResolutionOldInference.ResolutionKind.GivenCandidates<FunctionDescriptor>(), null, candidates
497                            );
498    
499    
500                    return doResolveCallOrGetCachedResults(basicCallResolutionContext, resolutionTask, tracing);
501                }
502            });
503        }
504    
505        private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> doResolveCallOrGetCachedResults(
506                @NotNull BasicCallResolutionContext context,
507                @NotNull ResolutionTask<D> resolutionTask,
508                @NotNull TracingStrategy tracing
509        ) {
510            Call call = context.call;
511            tracing.bindCall(context.trace, call);
512    
513            TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", call);
514            BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall);
515    
516            BindingContextUtilsKt.recordScope(newContext.trace, newContext.scope, newContext.call.getCalleeExpression());
517            BindingContextUtilsKt.recordDataFlowInfo(newContext, newContext.call.getCalleeExpression());
518    
519            OverloadResolutionResultsImpl<D> results = doResolveCall(newContext, resolutionTask, tracing);
520    
521            // this is necessary because we already run CallCompleter for such calls
522            if (CoroutineInferenceUtilKt.isResultWithCoroutineInference(results)) {
523                traceToResolveCall.commit();
524                return results;
525            }
526    
527            DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
528            if (deltasTraceForTypeInference != null) {
529                deltasTraceForTypeInference.addOwnDataTo(traceToResolveCall);
530            }
531            completeTypeInferenceDependentOnFunctionLiterals(newContext, results, tracing);
532            if (context.contextDependency == ContextDependency.DEPENDENT) {
533                cacheResults(context, results, traceToResolveCall, tracing);
534            }
535            traceToResolveCall.commit();
536    
537            if (context.contextDependency == ContextDependency.INDEPENDENT) {
538                results = callCompleter.completeCall(context, results, tracing);
539            }
540    
541            return results;
542        }
543    
544        private <D extends CallableDescriptor> void completeTypeInferenceDependentOnFunctionLiterals(
545                @NotNull BasicCallResolutionContext context,
546                @NotNull OverloadResolutionResultsImpl<D> results,
547                @NotNull TracingStrategy tracing
548        ) {
549            if (CallResolverUtilKt.isInvokeCallOnVariable(context.call)) return;
550            if (!results.isSingleResult()) {
551                if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
552                    argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
553                }
554                return;
555            }
556    
557            CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
558                    results.getResultingCall(), context, tracing);
559            genericCandidateResolver.completeTypeInferenceDependentOnFunctionArgumentsForCall(candidateContext);
560        }
561    
562        private static <F extends CallableDescriptor> void cacheResults(
563                @NotNull BasicCallResolutionContext context,
564                @NotNull OverloadResolutionResultsImpl<F> results,
565                @NotNull DelegatingBindingTrace traceToResolveCall,
566                @NotNull TracingStrategy tracing
567        ) {
568            Call call = context.call;
569            if (CallResolverUtilKt.isInvokeCallOnVariable(call)) return;
570    
571            DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
572                    BindingContext.EMPTY, "delta trace for caching resolve of", context.call, BindingTraceFilter.Companion.getACCEPT_ALL());
573            traceToResolveCall.addOwnDataTo(deltasTraceToCacheResolve);
574    
575            context.resolutionResultsCache.record(call, results, context, tracing, deltasTraceToCacheResolve);
576        }
577    
578        private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> checkArgumentTypesAndFail(BasicCallResolutionContext context) {
579            argumentTypeResolver.checkTypesWithNoCallee(context, ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS);
580            return OverloadResolutionResultsImpl.nameNotFound();
581        }
582    
583        @NotNull
584        private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> doResolveCall(
585                @NotNull BasicCallResolutionContext context,
586                @NotNull ResolutionTask<D> resolutionTask,
587                @NotNull TracingStrategy tracing
588        ) {
589            if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
590                argumentTypeResolver.analyzeArgumentsAndRecordTypes(context, ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS);
591            }
592    
593            List<KtTypeProjection> typeArguments = context.call.getTypeArguments();
594            for (KtTypeProjection projection : typeArguments) {
595                if (projection.getProjectionKind() != KtProjectionKind.NONE) {
596                    context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
597                    ModifierCheckerCore.INSTANCE.check(projection, context.trace, null, languageVersionSettings);
598                }
599                KotlinType type = argumentTypeResolver.resolveTypeRefWithDefault(
600                        projection.getTypeReference(), context.scope, context.trace,
601                        null);
602                if (type != null) {
603                    ForceResolveUtil.forceResolveAllContents(type);
604                }
605            }
606    
607            if (!(resolutionTask.resolutionKind instanceof NewResolutionOldInference.ResolutionKind.GivenCandidates)) {
608                assert resolutionTask.name != null;
609                return newCallResolver.runResolution(context, resolutionTask.name, resolutionTask.resolutionKind, tracing);
610            }
611            else {
612                assert resolutionTask.givenCandidates != null;
613                return newCallResolver.runResolutionForGivenCandidates(context, tracing, resolutionTask.givenCandidates);
614            }
615        }
616    
617        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
618        private static class ResolutionTask<D extends CallableDescriptor> {
619    
620            @Nullable
621            final Name name;
622    
623            @Nullable
624            final Collection<ResolutionCandidate<D>> givenCandidates;
625    
626            @NotNull
627            final NewResolutionOldInference.ResolutionKind<D> resolutionKind;
628    
629            private ResolutionTask(
630                    @NotNull NewResolutionOldInference.ResolutionKind<D> kind,
631                    @Nullable Name name,
632                    @Nullable Collection<ResolutionCandidate<D>> candidates
633            ) {
634                this.name = name;
635                givenCandidates = candidates;
636                resolutionKind = kind;
637            }
638        }
639    
640    }