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