001    /*
002     * Copyright 2010-2015 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.google.common.collect.Lists;
020    import com.intellij.openapi.util.Condition;
021    import com.intellij.psi.PsiElement;
022    import com.intellij.util.containers.ContainerUtil;
023    import kotlin.Unit;
024    import kotlin.jvm.functions.Function0;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
028    import org.jetbrains.kotlin.descriptors.*;
029    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
030    import org.jetbrains.kotlin.name.Name;
031    import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
032    import org.jetbrains.kotlin.psi.*;
033    import org.jetbrains.kotlin.resolve.*;
034    import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
035    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
036    import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode;
037    import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
038    import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
039    import org.jetbrains.kotlin.resolve.calls.context.*;
040    import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
041    import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
042    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
043    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
044    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
045    import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler;
046    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
047    import org.jetbrains.kotlin.resolve.calls.tasks.*;
048    import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors;
049    import org.jetbrains.kotlin.resolve.calls.tower.NewResolveOldInference;
050    import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
051    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
052    import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
053    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
054    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
055    import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
056    import org.jetbrains.kotlin.types.KotlinType;
057    import org.jetbrains.kotlin.types.TypeSubstitutor;
058    import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
059    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
060    import org.jetbrains.kotlin.types.expressions.ExpressionTypingVisitorDispatcher;
061    import org.jetbrains.kotlin.util.OperatorNameConventions;
062    import org.jetbrains.kotlin.util.PerformanceCounter;
063    
064    import javax.inject.Inject;
065    import java.util.*;
066    
067    import static org.jetbrains.kotlin.diagnostics.Errors.*;
068    import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
069    import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
070    import static org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode.EXIT_ON_FIRST_ERROR;
071    import static org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode.FULLY;
072    import static org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER;
073    import static org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE;
074    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
075    
076    @SuppressWarnings("RedundantTypeArguments")
077    public class CallResolver {
078        private ExpressionTypingServices expressionTypingServices;
079        private TypeResolver typeResolver;
080        private CandidateResolver candidateResolver;
081        private ArgumentTypeResolver argumentTypeResolver;
082        private GenericCandidateResolver genericCandidateResolver;
083        private CallCompleter callCompleter;
084        private NewResolveOldInference newCallResolver;
085        private final TaskPrioritizer taskPrioritizer;
086        private final ResolutionResultsHandler resolutionResultsHandler;
087        @NotNull private KotlinBuiltIns builtIns;
088    
089        private static final PerformanceCounter callResolvePerfCounter = PerformanceCounter.Companion.create("Call resolve", ExpressionTypingVisitorDispatcher.typeInfoPerfCounter);
090        private static final PerformanceCounter candidatePerfCounter = PerformanceCounter.Companion.create("Call resolve candidate analysis", true);
091    
092        public static boolean useNewResolve = !"false".equals(System.getProperty("kotlin.internal.new_resolve"));
093    
094        public CallResolver(
095                @NotNull TaskPrioritizer taskPrioritizer,
096                @NotNull ResolutionResultsHandler resolutionResultsHandler,
097                @NotNull KotlinBuiltIns builtIns
098        ) {
099            this.taskPrioritizer = taskPrioritizer;
100            this.resolutionResultsHandler = resolutionResultsHandler;
101            this.builtIns = builtIns;
102        }
103    
104        // component dependency cycle
105        @Inject
106        public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
107            this.expressionTypingServices = expressionTypingServices;
108        }
109    
110        // component dependency cycle
111        @Inject
112        public void setTypeResolver(@NotNull TypeResolver typeResolver) {
113            this.typeResolver = typeResolver;
114        }
115    
116        // component dependency cycle
117        @Inject
118        public void setCandidateResolver(@NotNull CandidateResolver candidateResolver) {
119            this.candidateResolver = candidateResolver;
120        }
121    
122        // component dependency cycle
123        @Inject
124        public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) {
125            this.argumentTypeResolver = argumentTypeResolver;
126        }
127    
128        // component dependency cycle
129        @Inject
130        public void setGenericCandidateResolver(GenericCandidateResolver genericCandidateResolver) {
131            this.genericCandidateResolver = genericCandidateResolver;
132        }
133    
134        // component dependency cycle
135        @Inject
136        public void setCallCompleter(@NotNull CallCompleter callCompleter) {
137            this.callCompleter = callCompleter;
138        }
139    
140        // component dependency cycle
141        @Inject
142        public void setCallCompleter(@NotNull NewResolveOldInference newCallResolver) {
143            this.newCallResolver = newCallResolver;
144        }
145    
146        @NotNull
147        public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(@NotNull BasicCallResolutionContext context) {
148            KtExpression calleeExpression = context.call.getCalleeExpression();
149            assert calleeExpression instanceof KtSimpleNameExpression;
150            KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) calleeExpression;
151            Name referencedName = nameExpression.getReferencedNameAsName();
152            CallableDescriptorCollectors<VariableDescriptor> callableDescriptorCollectors = CallableDescriptorCollectors.VARIABLES;
153            return computeTasksAndResolveCall(
154                    context, referencedName, nameExpression,
155                    callableDescriptorCollectors, CallTransformer.VARIABLE_CALL_TRANSFORMER, ResolveKind.VARIABLE);
156        }
157    
158        @NotNull
159        public OverloadResolutionResults<CallableDescriptor> resolveCallForMember(
160                @NotNull KtSimpleNameExpression nameExpression,
161                @NotNull BasicCallResolutionContext context
162        ) {
163            return computeTasksAndResolveCall(
164                    context, nameExpression.getReferencedNameAsName(), nameExpression,
165                    CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.MEMBER_CALL_TRANSFORMER, ResolveKind.CALLABLE_REFERENCE);
166        }
167    
168        @NotNull
169        public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
170                @NotNull ExpressionTypingContext context,
171                @NotNull Call call,
172                @NotNull KtReferenceExpression functionReference,
173                @NotNull Name name
174        ) {
175            BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
176            return computeTasksAndResolveCall(
177                    callResolutionContext, name, functionReference,
178                    CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER, ResolveKind.FUNCTION);
179        }
180    
181        @NotNull
182        public OverloadResolutionResults<FunctionDescriptor> resolveCallForInvoke(
183                @NotNull BasicCallResolutionContext context,
184                @NotNull TracingStrategy tracing
185        ) {
186            return computeTasksAndResolveCall(
187                    context, OperatorNameConventions.INVOKE, tracing,
188                    CallableDescriptorCollectors.FUNCTIONS, CallTransformer.FUNCTION_CALL_TRANSFORMER,
189                    ResolveKind.INVOKE);
190        }
191    
192        @NotNull
193        private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksAndResolveCall(
194                @NotNull BasicCallResolutionContext context,
195                @NotNull Name name,
196                @NotNull KtReferenceExpression referenceExpression,
197                @NotNull CallableDescriptorCollectors<D> collectors,
198                @NotNull CallTransformer<D, F> callTransformer,
199                @NotNull ResolveKind kind
200        ) {
201            TracingStrategy tracing = TracingStrategyImpl.create(referenceExpression, context.call);
202            return computeTasksAndResolveCall(context, name, tracing, collectors, callTransformer, kind);
203        }
204    
205        @NotNull
206        private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksAndResolveCall(
207                @NotNull final BasicCallResolutionContext context,
208                @NotNull final Name name,
209                @NotNull final TracingStrategy tracing,
210                @NotNull final CallableDescriptorCollectors<D> collectors,
211                @NotNull final CallTransformer<D, F> callTransformer,
212                @NotNull final ResolveKind kind
213        ) {
214            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<F>>() {
215                @Override
216                public OverloadResolutionResults<F> invoke() {
217                    TaskContextForMigration<D, F> contextForMigration = new TaskContextForMigration<D, F>(
218                            kind, callTransformer, name, null,
219                            new Function0<List<ResolutionTask<D, F>>>() {
220                                @Override
221                                public List<ResolutionTask<D, F>> invoke() {
222                                    return taskPrioritizer.<D, F>computePrioritizedTasks(context, name, tracing, collectors);
223                                }
224                            });
225                    return doResolveCallOrGetCachedResults(context, contextForMigration, tracing);
226                }
227            });
228        }
229    
230        @NotNull
231        private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksFromCandidatesAndResolvedCall(
232                @NotNull BasicCallResolutionContext context,
233                @NotNull KtReferenceExpression referenceExpression,
234                @NotNull Collection<ResolutionCandidate<D>> candidates,
235                @NotNull CallTransformer<D, F> callTransformer
236        ) {
237            return computeTasksFromCandidatesAndResolvedCall(context, candidates, callTransformer,
238                                                             TracingStrategyImpl.create(referenceExpression, context.call));
239        }
240    
241        @NotNull
242        private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksFromCandidatesAndResolvedCall(
243                @NotNull final BasicCallResolutionContext context,
244                @NotNull final Collection<ResolutionCandidate<D>> candidates,
245                @NotNull final CallTransformer<D, F> callTransformer,
246                @NotNull final TracingStrategy tracing
247        ) {
248            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<F>>() {
249                @Override
250                public OverloadResolutionResults<F> invoke() {
251                    TaskContextForMigration<D, F> contextForMigration = new TaskContextForMigration<D, F>(
252                            ResolveKind.GIVEN_CANDIDATES, callTransformer, null, candidates,
253                            new Function0<List<ResolutionTask<D, F>>>() {
254                                @Override
255                                public List<ResolutionTask<D, F>> invoke() {
256                                    return taskPrioritizer.<D, F>computePrioritizedTasksFromCandidates(
257                                            context, candidates, tracing);
258                                }
259                            });
260                    return doResolveCallOrGetCachedResults(context, contextForMigration, tracing);
261                }
262            });
263        }
264    
265        @NotNull
266        public OverloadResolutionResults<FunctionDescriptor> resolveBinaryCall(
267                ExpressionTypingContext context,
268                ExpressionReceiver receiver,
269                KtBinaryExpression binaryExpression,
270                Name name
271        ) {
272            return resolveCallWithGivenName(
273                    context,
274                    CallMaker.makeCall(receiver, binaryExpression),
275                    binaryExpression.getOperationReference(),
276                    name
277            );
278        }
279    
280        @NotNull
281        public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(
282                @NotNull BindingTrace trace,
283                @NotNull LexicalScope scope,
284                @NotNull Call call,
285                @NotNull KotlinType expectedType,
286                @NotNull DataFlowInfo dataFlowInfo,
287                boolean isAnnotationContext
288        ) {
289            return resolveFunctionCall(
290                    BasicCallResolutionContext.create(
291                            trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
292                            CallChecker.DoNothing.INSTANCE, isAnnotationContext
293                    )
294            );
295        }
296    
297        @NotNull
298        public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(@NotNull BasicCallResolutionContext context) {
299            ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
300    
301            Call.CallType callType = context.call.getCallType();
302            if (callType == Call.CallType.ARRAY_GET_METHOD || callType == Call.CallType.ARRAY_SET_METHOD) {
303                Name name = Name.identifier(callType == Call.CallType.ARRAY_GET_METHOD ? "get" : "set");
304                KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) context.call.getCallElement();
305                return computeTasksAndResolveCall(
306                        context, name, arrayAccessExpression,
307                        CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES,
308                        CallTransformer.FUNCTION_CALL_TRANSFORMER,
309                        ResolveKind.FUNCTION);
310            }
311    
312            KtExpression calleeExpression = context.call.getCalleeExpression();
313            if (calleeExpression instanceof KtSimpleNameExpression) {
314                KtSimpleNameExpression expression = (KtSimpleNameExpression) calleeExpression;
315                return computeTasksAndResolveCall(
316                        context, expression.getReferencedNameAsName(), expression,
317                        CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER, ResolveKind.FUNCTION);
318            }
319            else if (calleeExpression instanceof KtConstructorCalleeExpression) {
320                return resolveCallForConstructor(context, (KtConstructorCalleeExpression) calleeExpression);
321            }
322            else if (calleeExpression instanceof KtConstructorDelegationReferenceExpression) {
323                KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement();
324                DeclarationDescriptor container = context.scope.getOwnerDescriptor();
325                assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container;
326                return resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression,
327                                                        (ConstructorDescriptor) container);
328            }
329            else if (calleeExpression == null) {
330                return checkArgumentTypesAndFail(context);
331            }
332    
333            // Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2)
334            KotlinType expectedType = NO_EXPECTED_TYPE;
335            if (calleeExpression instanceof KtLambdaExpression) {
336                int parameterNumber = ((KtLambdaExpression) calleeExpression).getValueParameters().size();
337                List<KotlinType> parameterTypes = new ArrayList<KotlinType>(parameterNumber);
338                for (int i = 0; i < parameterNumber; i++) {
339                    parameterTypes.add(NO_EXPECTED_TYPE);
340                }
341                expectedType = builtIns.getFunctionType(Annotations.Companion.getEMPTY(), null, parameterTypes, context.expectedType);
342            }
343            KotlinType calleeType = expressionTypingServices.safeGetType(
344                    context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
345            ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
346    
347            Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call);
348            TracingStrategyForInvoke tracingForInvoke = new TracingStrategyForInvoke(calleeExpression, call, calleeType);
349            return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke);
350        }
351    
352        private OverloadResolutionResults<FunctionDescriptor> resolveCallForConstructor(
353                @NotNull BasicCallResolutionContext context,
354                @NotNull KtConstructorCalleeExpression expression
355        ) {
356            assert context.call.getExplicitReceiver() == null :
357                    "Constructor can't be invoked with explicit receiver: " + context.call.getCallElement().getText();
358    
359            context.trace.record(BindingContext.LEXICAL_SCOPE, context.call.getCallElement(), context.scope);
360    
361            KtReferenceExpression functionReference = expression.getConstructorReferenceExpression();
362            KtTypeReference typeReference = expression.getTypeReference();
363            if (functionReference == null || typeReference == null) {
364                return checkArgumentTypesAndFail(context); // No type there
365            }
366            KotlinType constructedType = typeResolver.resolveType(context.scope, typeReference, context.trace, true);
367            if (constructedType.isError()) {
368                return checkArgumentTypesAndFail(context);
369            }
370    
371            DeclarationDescriptor declarationDescriptor = constructedType.getConstructor().getDeclarationDescriptor();
372            if (!(declarationDescriptor instanceof ClassDescriptor)) {
373                context.trace.report(NOT_A_CLASS.on(expression));
374                return checkArgumentTypesAndFail(context);
375            }
376    
377            ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
378    
379            Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
380            if (constructors.isEmpty()) {
381                context.trace.report(NO_CONSTRUCTOR.on(CallUtilKt.getValueArgumentListOrElement(context.call)));
382                return checkArgumentTypesAndFail(context);
383            }
384            TypeSubstitutor knownSubstitutor = TypeSubstitutor.create(constructedType);
385            Collection<ResolutionCandidate<CallableDescriptor>> candidates =
386                    taskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(
387                            context.scope, constructors, context.call, knownSubstitutor);
388    
389            return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
390        }
391    
392        @Nullable
393        public OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
394                @NotNull BindingTrace trace, @NotNull LexicalScope scope, @NotNull DataFlowInfo dataFlowInfo,
395                @NotNull ConstructorDescriptor constructorDescriptor,
396                @NotNull KtConstructorDelegationCall call
397        ) {
398            // Method returns `null` when there is nothing to resolve in trivial cases like `null` call expression or
399            // when super call should be conventional enum constructor and super call should be empty
400    
401            BasicCallResolutionContext context = BasicCallResolutionContext.create(
402                    trace, scope,
403                    CallMaker.makeCall(null, null, call),
404                    NO_EXPECTED_TYPE,
405                    dataFlowInfo, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
406                    CallChecker.DoNothing.INSTANCE, false);
407    
408            if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
409    
410            if (constructorDescriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS && call.isImplicit()) {
411                return null;
412            }
413    
414            return resolveConstructorDelegationCall(
415                    context,
416                    call,
417                    call.getCalleeExpression(),
418                    constructorDescriptor
419            );
420        }
421    
422        @NotNull
423        private OverloadResolutionResults<FunctionDescriptor> resolveConstructorDelegationCall(
424                @NotNull BasicCallResolutionContext context,
425                @NotNull KtConstructorDelegationCall call,
426                @NotNull KtConstructorDelegationReferenceExpression calleeExpression,
427                @NotNull ConstructorDescriptor calleeConstructor
428        ) {
429            context.trace.record(BindingContext.LEXICAL_SCOPE, call, context.scope);
430    
431            ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration();
432    
433            boolean isThisCall = calleeExpression.isThis();
434            if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) {
435                context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(calleeExpression));
436                return checkArgumentTypesAndFail(context);
437            }
438    
439            ClassDescriptor delegateClassDescriptor = isThisCall ? currentClassDescriptor :
440                                                      DescriptorUtilsKt.getSuperClassOrAny(currentClassDescriptor);
441            Collection<ConstructorDescriptor> constructors = delegateClassDescriptor.getConstructors();
442    
443            if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
444                if (DescriptorUtils.canHaveDeclaredConstructors(currentClassDescriptor)) {
445                    // Diagnostic is meaningless when reporting on interfaces and object
446                    context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
447                            (KtConstructorDelegationCall) calleeExpression.getParent()
448                    ));
449                }
450                if (call.isImplicit()) return OverloadResolutionResultsImpl.nameNotFound();
451            }
452    
453            if (constructors.isEmpty()) {
454                context.trace.report(NO_CONSTRUCTOR.on(CallUtilKt.getValueArgumentListOrElement(context.call)));
455                return checkArgumentTypesAndFail(context);
456            }
457    
458    
459            KotlinType superType = isThisCall ?
460                                      calleeConstructor.getContainingDeclaration().getDefaultType() :
461                                      DescriptorUtils.getSuperClassType(currentClassDescriptor);
462    
463            TypeSubstitutor knownTypeParametersSubstitutor = TypeSubstitutor.create(superType);
464    
465            Collection<ResolutionCandidate<CallableDescriptor>> candidates =
466                    taskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(
467                            context.scope, constructors, context.call, knownTypeParametersSubstitutor);
468    
469            TracingStrategy tracing = call.isImplicit() ?
470                                      new TracingStrategyForImplicitConstructorDelegationCall(call, context.call) :
471                                      TracingStrategyImpl.create(calleeExpression, context.call);
472    
473            PsiElement reportOn = call.isImplicit() ? call : calleeExpression;
474    
475            if (delegateClassDescriptor.isInner()
476                    && !DescriptorResolver.checkHasOuterClassInstance(context.scope, context.trace, reportOn,
477                                                                      (ClassDescriptor) delegateClassDescriptor.getContainingDeclaration())) {
478                return checkArgumentTypesAndFail(context);
479            }
480    
481            return computeTasksFromCandidatesAndResolvedCall(context, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
482        }
483    
484        public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate(
485                @NotNull final Call call,
486                @NotNull final TracingStrategy tracing,
487                @NotNull final ResolutionContext<?> context,
488                @NotNull final ResolutionCandidate<CallableDescriptor> candidate,
489                @Nullable final MutableDataFlowInfoForArguments dataFlowInfoForArguments
490        ) {
491            return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<FunctionDescriptor>>() {
492                @Override
493                public OverloadResolutionResults<FunctionDescriptor> invoke() {
494                    final BasicCallResolutionContext basicCallResolutionContext =
495                            BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, dataFlowInfoForArguments);
496    
497                    final Set<ResolutionCandidate<CallableDescriptor>> candidates = Collections.singleton(candidate);
498    
499                    TaskContextForMigration<CallableDescriptor, FunctionDescriptor> contextForMigration =
500                            new TaskContextForMigration<CallableDescriptor, FunctionDescriptor>(
501                                    ResolveKind.GIVEN_CANDIDATES, CallTransformer.FUNCTION_CALL_TRANSFORMER, null, candidates,
502                                    new Function0<List<ResolutionTask<CallableDescriptor, FunctionDescriptor>>>() {
503                                        @Override
504                                        public List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> invoke() {
505    
506                                            return taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
507                                                    basicCallResolutionContext, candidates, tracing);
508                                        }
509                                    }
510                            );
511    
512    
513                    return doResolveCallOrGetCachedResults(basicCallResolutionContext, contextForMigration, tracing);
514                }
515            });
516        }
517    
518        private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCallOrGetCachedResults(
519                @NotNull BasicCallResolutionContext context,
520                @NotNull TaskContextForMigration<D, F> contextForMigration,
521                @NotNull TracingStrategy tracing
522        ) {
523            Call call = context.call;
524            tracing.bindCall(context.trace, call);
525    
526            TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", call);
527            BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall);
528    
529            BindingContextUtilsKt.recordScope(newContext.trace, newContext.scope, newContext.call.getCalleeExpression());
530            BindingContextUtilsKt.recordDataFlowInfo(newContext, newContext.call.getCalleeExpression());
531    
532            OverloadResolutionResultsImpl<F> results = doResolveCall(newContext, contextForMigration, tracing);
533            DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
534            if (deltasTraceForTypeInference != null) {
535                deltasTraceForTypeInference.addOwnDataTo(traceToResolveCall);
536            }
537            completeTypeInferenceDependentOnFunctionLiterals(newContext, results, tracing);
538            if (context.contextDependency == ContextDependency.DEPENDENT) {
539                cacheResults(context, results, traceToResolveCall, tracing);
540            }
541            traceToResolveCall.commit();
542    
543            if (context.contextDependency == ContextDependency.INDEPENDENT) {
544                results = callCompleter.completeCall(context, results, tracing);
545            }
546    
547            return results;
548        }
549    
550        private <D extends CallableDescriptor> void completeTypeInferenceDependentOnFunctionLiterals(
551                @NotNull BasicCallResolutionContext context,
552                @NotNull OverloadResolutionResultsImpl<D> results,
553                @NotNull TracingStrategy tracing
554        ) {
555            if (CallResolverUtilKt.isInvokeCallOnVariable(context.call)) return;
556            if (!results.isSingleResult()) {
557                if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
558                    argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
559                }
560                return;
561            }
562    
563            CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
564                    results.getResultingCall(), context, tracing);
565            genericCandidateResolver.completeTypeInferenceDependentOnFunctionArgumentsForCall(candidateContext);
566        }
567    
568        private static <F extends CallableDescriptor> void cacheResults(
569                @NotNull BasicCallResolutionContext context,
570                @NotNull OverloadResolutionResultsImpl<F> results,
571                @NotNull DelegatingBindingTrace traceToResolveCall,
572                @NotNull TracingStrategy tracing
573        ) {
574            Call call = context.call;
575            if (CallResolverUtilKt.isInvokeCallOnVariable(call)) return;
576    
577            DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
578                    BindingContext.EMPTY, "delta trace for caching resolve of", context.call);
579            traceToResolveCall.addOwnDataTo(deltasTraceToCacheResolve);
580    
581            context.resolutionResultsCache.record(call, results, context, tracing, deltasTraceToCacheResolve);
582        }
583    
584        private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> checkArgumentTypesAndFail(BasicCallResolutionContext context) {
585            argumentTypeResolver.checkTypesWithNoCallee(context, ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS);
586            return OverloadResolutionResultsImpl.nameNotFound();
587        }
588    
589        @NotNull
590        private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCall(
591                @NotNull BasicCallResolutionContext context,
592                @NotNull TaskContextForMigration<D, F> contextForMigration,
593                @NotNull TracingStrategy tracing
594        ) {
595            if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
596                argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
597            }
598    
599            List<KtTypeProjection> typeArguments = context.call.getTypeArguments();
600            for (KtTypeProjection projection : typeArguments) {
601                if (projection.getProjectionKind() != KtProjectionKind.NONE) {
602                    context.trace.report(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(projection));
603                    ModifierCheckerCore.INSTANCE.check(projection, context.trace, null);
604                }
605                KotlinType type = argumentTypeResolver.resolveTypeRefWithDefault(
606                        projection.getTypeReference(), context.scope, context.trace,
607                        null);
608                if (type != null) {
609                    ForceResolveUtil.forceResolveAllContents(type);
610                }
611            }
612    
613            if (contextForMigration.resolveKind != ResolveKind.GIVEN_CANDIDATES && useNewResolve) {
614                assert contextForMigration.name != null;
615                return (OverloadResolutionResultsImpl<F>)
616                        newCallResolver.runResolve(context, contextForMigration.name, contextForMigration.resolveKind, tracing);
617            }
618    
619            return doResolveCall(context, contextForMigration.lazyTasks.invoke(), contextForMigration.callTransformer, tracing);
620        }
621    
622        @NotNull
623        private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCall(
624                @NotNull BasicCallResolutionContext context,
625                @NotNull List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority
626                @NotNull CallTransformer<D, F> callTransformer,
627                @NotNull TracingStrategy tracing
628        ) {
629            Collection<ResolvedCall<F>> allCandidates = Lists.newArrayList();
630            OverloadResolutionResultsImpl<F> successfulResults = null;
631            TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
632            OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
633            for (ResolutionTask<D, F> task : prioritizedTasks) {
634                if (task.getCandidates().isEmpty()) continue;
635    
636                TemporaryBindingTrace taskTrace =
637                        TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.call.getCalleeExpression());
638                OverloadResolutionResultsImpl<F> results = performResolution(task.replaceBindingTrace(taskTrace), callTransformer);
639    
640    
641                allCandidates.addAll(task.getResolvedCalls());
642    
643                if (successfulResults != null) continue;
644    
645                if (results.isSuccess() || results.isAmbiguity()) {
646                    taskTrace.commit();
647                    successfulResults = results;
648                }
649                if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
650                    results.setTrace(taskTrace);
651                    successfulResults = results;
652                }
653                boolean updateResults = traceForFirstNonemptyCandidateSet == null
654                                        || (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER
655                                            && results.getResultCode() != CANDIDATES_WITH_WRONG_RECEIVER);
656                if (!task.getCandidates().isEmpty() && !results.isNothing() && updateResults) {
657                    traceForFirstNonemptyCandidateSet = taskTrace;
658                    resultsForFirstNonemptyCandidateSet = results;
659                }
660    
661                if (successfulResults != null && !context.collectAllCandidates) break;
662            }
663            OverloadResolutionResultsImpl<F> results;
664            if (successfulResults != null) {
665                results = successfulResults;
666            }
667            else if (traceForFirstNonemptyCandidateSet == null) {
668                tracing.unresolvedReference(context.trace);
669                argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS);
670                results = OverloadResolutionResultsImpl.<F>nameNotFound();
671            }
672            else {
673                traceForFirstNonemptyCandidateSet.commit();
674                results = resultsForFirstNonemptyCandidateSet;
675            }
676            results.setAllCandidates(context.collectAllCandidates ? allCandidates : null);
677            return results;
678        }
679    
680        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
681    
682        @NotNull
683        private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> performResolution(
684                @NotNull ResolutionTask<D, F> task,
685                @NotNull CallTransformer<D, F> callTransformer
686        ) {
687            CandidateResolveMode mode = task.collectAllCandidates ? FULLY : EXIT_ON_FIRST_ERROR;
688            List<CallCandidateResolutionContext<D>> contexts = collectCallCandidateContext(task, callTransformer, mode);
689            boolean isSuccess = ContainerUtil.exists(contexts, new Condition<CallCandidateResolutionContext<D>>() {
690                @Override
691                public boolean value(CallCandidateResolutionContext<D> context) {
692                    return context.candidateCall.getStatus().possibleTransformToSuccess();
693                }
694            });
695            if (!isSuccess && mode == EXIT_ON_FIRST_ERROR) {
696                contexts = collectCallCandidateContext(task, callTransformer, FULLY);
697            }
698    
699            for (CallCandidateResolutionContext<D> context : contexts) {
700                addResolvedCall(task, callTransformer, context);
701            }
702    
703            OverloadResolutionResultsImpl<F> results = resolutionResultsHandler.computeResultAndReportErrors(
704                    task, task.tracing, task.getResolvedCalls());
705            if (!results.isSingleResult() && !results.isIncomplete()) {
706                argumentTypeResolver.checkTypesWithNoCallee(task.toBasic());
707            }
708            return results;
709        }
710    
711        @NotNull
712        private <D extends CallableDescriptor, F extends D> List<CallCandidateResolutionContext<D>> collectCallCandidateContext(
713                @NotNull final ResolutionTask<D, F> task,
714                @NotNull final CallTransformer<D, F> callTransformer,
715                @NotNull final CandidateResolveMode candidateResolveMode
716        ) {
717            final List<CallCandidateResolutionContext<D>> candidateResolutionContexts = ContainerUtil.newArrayList();
718            for (final ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) {
719                if (DeprecationUtilKt.isHiddenInResolution(resolutionCandidate.getDescriptor())) continue;
720    
721                candidatePerfCounter.time(new Function0<Unit>() {
722                    @Override
723                    public Unit invoke() {
724                        TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create(
725                                task.trace, "trace to resolve candidate");
726                        Collection<CallCandidateResolutionContext<D>> contexts =
727                                callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace, candidateResolveMode);
728                        for (CallCandidateResolutionContext<D> context : contexts) {
729                            candidateResolver.performResolutionForCandidateCall(context, task.checkArguments);
730                            candidateResolutionContexts.add(context);
731                        }
732                        return Unit.INSTANCE;
733                    }
734                });
735            }
736            return candidateResolutionContexts;
737        }
738    
739        private <D extends CallableDescriptor, F extends D> void addResolvedCall(
740                @NotNull ResolutionTask<D, F> task,
741                @NotNull CallTransformer<D, F> callTransformer,
742                @NotNull CallCandidateResolutionContext<D> context) {
743            /* important for 'variable as function case': temporary bind reference to descriptor (will be rewritten)
744            to have a binding to variable while 'invoke' call resolve */
745            task.tracing.bindReference(context.candidateCall.getTrace(), context.candidateCall);
746    
747            Collection<MutableResolvedCall<F>> resolvedCalls = callTransformer.transformCall(context, this, task);
748    
749            for (MutableResolvedCall<F> resolvedCall : resolvedCalls) {
750                BindingTrace trace = resolvedCall.getTrace();
751                task.tracing.bindReference(trace, resolvedCall);
752                task.tracing.bindResolvedCall(trace, resolvedCall);
753                task.addResolvedCall(resolvedCall);
754            }
755        }
756    
757        private static class TaskContextForMigration<D extends CallableDescriptor, F extends D> {
758            @NotNull
759            final Function0<List<ResolutionTask<D, F>>> lazyTasks;
760    
761            @NotNull
762            final CallTransformer<D, F> callTransformer;
763    
764            @Nullable
765            final Name name;
766    
767            @Nullable
768            final Collection<ResolutionCandidate<D>> givenCandidates;
769    
770            @NotNull
771            final ResolveKind resolveKind;
772    
773            private TaskContextForMigration(
774                    @NotNull ResolveKind kind,
775                    @NotNull CallTransformer<D, F> transformer,
776                    @Nullable Name name,
777                    @Nullable Collection<ResolutionCandidate<D>> candidates, @NotNull Function0<List<ResolutionTask<D, F>>> tasks
778            ) {
779                lazyTasks = tasks;
780                callTransformer = transformer;
781                this.name = name;
782                givenCandidates = candidates;
783                resolveKind = kind;
784            }
785        }
786    
787        public enum ResolveKind {
788            FUNCTION,
789            INVOKE,
790            VARIABLE,
791            CALLABLE_REFERENCE,
792            GIVEN_CANDIDATES,
793        }
794    }