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