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