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