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