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