@NotNull private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> performResolution( @NotNull ResolutionTask<D, F> task, @NotNull CallTransformer<D, F> callTransformer) { for (ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) { TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create(task.trace, "trace to resolve candidate"); Collection<CallCandidateResolutionContext<D>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace); for (CallCandidateResolutionContext<D> context : contexts) { candidateResolver.performResolutionForCandidateCall(context, task); /* important for 'variable as function case': temporary bind reference to descriptor (will be rewritten) to have a binding to variable while 'invoke' call resolve */ task.tracing.bindReference(context.candidateCall.getTrace(), context.candidateCall); Collection<ResolvedCallWithTrace<F>> calls = callTransformer.transformCall(context, this, task); for (ResolvedCallWithTrace<F> call : calls) { task.tracing.bindReference(call.getTrace(), call); task.tracing.bindResolvedCall(call.getTrace(), call); task.getResolvedCalls().add(call); } } } OverloadResolutionResultsImpl<F> results = ResolutionResultsHandler.INSTANCE.computeResultAndReportErrors( task.trace, task.tracing, task.getResolvedCalls()); if (!results.isSingleResult() && !results.isIncomplete()) { argumentTypeResolver.checkTypesWithNoCallee(task.toBasic()); } return results; }
@NotNull private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCall( @NotNull BasicCallResolutionContext context, @NotNull List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority @NotNull CallTransformer<D, F> callTransformer, @NotNull JetReferenceExpression reference) { ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create(); context.trace.record( ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement(), debugInfo); context.trace.record(RESOLUTION_SCOPE, context.call.getCalleeExpression(), context.scope); if (context.dataFlowInfo.hasTypeInfoConstraints()) { context.trace.record( NON_DEFAULT_EXPRESSION_DATA_FLOW, context.call.getCalleeExpression(), context.dataFlowInfo); } debugInfo.set(ResolutionDebugInfo.TASKS, prioritizedTasks); if (context.checkArguments == CheckValueArgumentsMode.ENABLED) { argumentTypeResolver.analyzeArgumentsAndRecordTypes(context); } TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null; for (ResolutionTask<D, F> task : prioritizedTasks) { TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create( context.trace, "trace to resolve a task for", task.reference); OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments( task.replaceBindingTrace(taskTrace), callTransformer); if (results.isSuccess() || results.isAmbiguity()) { taskTrace.commit(); if (results.isSuccess()) { debugInfo.set(ResolutionDebugInfo.RESULT, results.getResultingCall()); } resolveFunctionArguments(context, results); return results; } if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) { results.setTrace(taskTrace); return results; } boolean updateResults = traceForFirstNonemptyCandidateSet == null || (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER && results.getResultCode() != CANDIDATES_WITH_WRONG_RECEIVER); if (!task.getCandidates().isEmpty() && !results.isNothing() && updateResults) { traceForFirstNonemptyCandidateSet = taskTrace; resultsForFirstNonemptyCandidateSet = results; } } if (traceForFirstNonemptyCandidateSet != null) { traceForFirstNonemptyCandidateSet.commit(); if (resultsForFirstNonemptyCandidateSet.isSingleResult()) { debugInfo.set( ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall()); } resolveFunctionArguments(context, resultsForFirstNonemptyCandidateSet); } else { context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS); } return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound(); }