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