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