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 }