correspondence between CallableDescriptorCollector and CallTransformer (special treatment only for function invocations)
This commit is contained in:
@@ -102,16 +102,16 @@ public class CallResolver {
|
||||
if (referencedName == null) {
|
||||
return OverloadResolutionResultsImpl.nameNotFound();
|
||||
}
|
||||
List<MemberPrioritizer<VariableDescriptor>> memberPrioritizers = Lists.newArrayList();
|
||||
List<CallableDescriptorCollector<? extends VariableDescriptor>> callableDescriptorCollectors = Lists.newArrayList();
|
||||
if (nameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
||||
referencedName = referencedName.substring(1);
|
||||
memberPrioritizers.add(MemberPrioritizers.PROPERTY_TASK_PRIORITIZER);
|
||||
callableDescriptorCollectors.add(CallableDescriptorCollectors.PROPERTIES);
|
||||
}
|
||||
else {
|
||||
memberPrioritizers.add(MemberPrioritizers.VARIABLE_TASK_PRIORITIZER);
|
||||
callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES);
|
||||
}
|
||||
List<ResolutionTask<VariableDescriptor>> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, memberPrioritizers);
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.PROPERTY_CALL_TRANSFORMATION_STRATEGY, nameExpression);
|
||||
List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, callableDescriptorCollectors);
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -119,9 +119,8 @@ public class CallResolver {
|
||||
@NotNull BasicResolutionContext context,
|
||||
@NotNull final JetReferenceExpression functionReference,
|
||||
@NotNull String name) {
|
||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizer.computePrioritizedTasks(
|
||||
context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
|
||||
return doResolveCall(context, tasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
|
||||
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
|
||||
return doResolveCall(context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -131,7 +130,7 @@ public class CallResolver {
|
||||
|
||||
@NotNull
|
||||
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(@NotNull BasicResolutionContext context) {
|
||||
List<ResolutionTask<FunctionDescriptor>> prioritizedTasks;
|
||||
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> prioritizedTasks;
|
||||
|
||||
JetExpression calleeExpression = context.call.getCalleeExpression();
|
||||
final JetReferenceExpression functionReference;
|
||||
@@ -142,7 +141,7 @@ public class CallResolver {
|
||||
String name = expression.getReferencedName();
|
||||
if (name == null) return checkArgumentTypesAndFail(context);
|
||||
|
||||
prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, Collections.singletonList(MemberPrioritizers.FUNCTION_TASK_PRIORITIZER));
|
||||
prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
|
||||
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
|
||||
@Override
|
||||
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
|
||||
@@ -184,8 +183,8 @@ public class CallResolver {
|
||||
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
Collection<ResolutionCandidate<FunctionDescriptor>> candidates = TaskPrioritizer.<FunctionDescriptor>convertWithImpliedThis(context.scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors);
|
||||
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
Collection<ResolutionCandidate<CallableDescriptor>> candidates = TaskPrioritizer.<CallableDescriptor>convertWithImpliedThis(context.scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors);
|
||||
prioritizedTasks.add(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
}
|
||||
else {
|
||||
context.trace.report(NOT_A_CLASS.on(calleeExpression));
|
||||
@@ -206,8 +205,8 @@ public class CallResolver {
|
||||
context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
List<ResolutionCandidate<FunctionDescriptor>> candidates = ResolutionCandidate.<FunctionDescriptor>convertCollection(constructors);
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
List<ResolutionCandidate<CallableDescriptor>> candidates = ResolutionCandidate.<CallableDescriptor>convertCollection(constructors);
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
|
||||
}
|
||||
else if (calleeExpression != null) {
|
||||
// Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2)
|
||||
@@ -223,7 +222,7 @@ public class CallResolver {
|
||||
|
||||
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]");
|
||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER);
|
||||
ResolutionCandidate<FunctionDescriptor> resolutionCandidate = ResolutionCandidate.<FunctionDescriptor>create(functionDescriptor);
|
||||
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(functionDescriptor);
|
||||
resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver());
|
||||
|
||||
// strictly speaking, this is a hack:
|
||||
@@ -231,7 +230,7 @@ public class CallResolver {
|
||||
// so we wrap what we have into a fake reference and pass it on (unwrap on the other end)
|
||||
functionReference = new JetFakeReference(calleeExpression);
|
||||
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(Collections.singleton(resolutionCandidate), functionReference, context));
|
||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(Collections.singleton(resolutionCandidate), functionReference, context));
|
||||
}
|
||||
else {
|
||||
// checkTypesWithNoCallee(trace, scope, call);
|
||||
@@ -239,7 +238,7 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformationStrategy.FUNCTION_CALL_TRANSFORMATION_STRATEGY, functionReference);
|
||||
return doResolveCall(context, prioritizedTasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference);
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
||||
@@ -248,10 +247,10 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> doResolveCall(
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> doResolveCall(
|
||||
@NotNull final BasicResolutionContext context,
|
||||
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy,
|
||||
@NotNull final List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority
|
||||
@NotNull CallTransformer<D, F> callTransformer,
|
||||
@NotNull final JetReferenceExpression reference) {
|
||||
|
||||
ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create();
|
||||
@@ -265,10 +264,11 @@ public class CallResolver {
|
||||
debugInfo.set(ResolutionDebugInfo.TASKS, prioritizedTasks);
|
||||
|
||||
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
||||
OverloadResolutionResultsImpl<D> resultsForFirstNonemptyCandidateSet = null;
|
||||
for (ResolutionTask<D> task : prioritizedTasks) {
|
||||
OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
|
||||
for (ResolutionTask<D, F> task : prioritizedTasks) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
|
||||
OverloadResolutionResultsImpl<D> results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace), callTransformationStrategy);
|
||||
OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments(task.withTrace(temporaryTrace),
|
||||
callTransformer);
|
||||
if (results.isSuccess() || results.isAmbiguity()) {
|
||||
temporaryTrace.commit();
|
||||
|
||||
@@ -294,15 +294,15 @@ public class CallResolver {
|
||||
context.trace.report(UNRESOLVED_REFERENCE.on(reference));
|
||||
checkTypesWithNoCallee(context);
|
||||
}
|
||||
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<D>nameNotFound();
|
||||
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolutionGuardedForExtraFunctionLiteralArguments(@NotNull ResolutionTask<D> task,
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy) {
|
||||
OverloadResolutionResultsImpl<D> results = performResolution(task, callTransformationStrategy);
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> performResolutionGuardedForExtraFunctionLiteralArguments(@NotNull ResolutionTask<D, F> task,
|
||||
@NotNull CallTransformer<D, F> callTransformer) {
|
||||
OverloadResolutionResultsImpl<F> results = performResolution(task, callTransformer);
|
||||
|
||||
// If resolution fails, we should check for some of the following situations:
|
||||
// class A {
|
||||
@@ -329,14 +329,14 @@ public class CallResolver {
|
||||
for (ResolutionCandidate<D> candidate : task.getCandidates()) {
|
||||
newCandidates.add(ResolutionCandidate.create(candidate.getDescriptor()));
|
||||
}
|
||||
ResolutionTask<D> newContext = new ResolutionTask<D>(newCandidates, task.reference, TemporaryBindingTrace.create(task.trace), task.scope, new DelegatingCall(task.call) {
|
||||
ResolutionTask<D, F> newContext = new ResolutionTask<D, F>(newCandidates, task.reference, TemporaryBindingTrace.create(task.trace), task.scope, new DelegatingCall(task.call) {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}, task.expectedType, task.dataFlowInfo);
|
||||
OverloadResolutionResultsImpl<D> resultsWithFunctionLiteralsStripped = performResolution(newContext, callTransformationStrategy);
|
||||
OverloadResolutionResultsImpl<F> resultsWithFunctionLiteralsStripped = performResolution(newContext, callTransformer);
|
||||
if (resultsWithFunctionLiteralsStripped.isSuccess() || resultsWithFunctionLiteralsStripped.isAmbiguity()) {
|
||||
task.tracing.danglingFunctionLiteralArgumentSuspected(task.trace, task.call.getFunctionLiteralArguments());
|
||||
}
|
||||
@@ -346,23 +346,28 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolution(@NotNull ResolutionTask<D> task,
|
||||
@NotNull CallTransformationStrategy<D, D> callTransformationStrategy) {
|
||||
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 temporaryTrace = TemporaryBindingTrace.create(task.trace);
|
||||
CallResolutionContext<D> context = callTransformationStrategy.createCallContext(resolutionCandidate, task, temporaryTrace, task.tracing);
|
||||
performResolutionForCandidateCall(context, task, temporaryTrace);
|
||||
Collection<CallResolutionContext<D, F>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, temporaryTrace);
|
||||
Collection<ResolvedCallWithTrace<F>> calls = Lists.newArrayList();
|
||||
for (CallResolutionContext<D, F> context : contexts) {
|
||||
|
||||
Collection<ResolvedCallImpl<D>> calls = callTransformationStrategy.transformResultCall(context, this, task);
|
||||
for (ResolvedCallImpl<D> call : calls) {
|
||||
task.getResolvedCallMap().put(resolutionCandidate, call);
|
||||
performResolutionForCandidateCall(context, task);
|
||||
calls.addAll(callTransformer.transformCall(context, this, task));
|
||||
}
|
||||
for (ResolvedCallWithTrace<F> call : calls) {
|
||||
|
||||
task.tracing.bindResolvedCall(call.getTrace(), call);
|
||||
task.getResolvedCalls().add(call);
|
||||
}
|
||||
}
|
||||
|
||||
Set<ResolvedCallImpl<D>> successfulCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallImpl<D>> failedCandidates = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallImpl<D> candidateCall : task.getResolvedCallMap().values()) {
|
||||
Set<ResolvedCallWithTrace<F>> successfulCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<F>> failedCandidates = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallWithTrace<F> candidateCall : task.getResolvedCalls()) {
|
||||
ResolutionStatus status = candidateCall.getStatus();
|
||||
if (status.isSuccess()) {
|
||||
successfulCandidates.add(candidateCall);
|
||||
@@ -373,23 +378,19 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
|
||||
OverloadResolutionResultsImpl<F> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
|
||||
if (!results.isSingleResult()) {
|
||||
checkTypesWithNoCallee(task.toBasic());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> void performResolutionForCandidateCall(@NotNull CallResolutionContext<D> context,
|
||||
@NotNull ResolutionTask<D> task,
|
||||
@NotNull TemporaryBindingTrace temporaryTrace) {
|
||||
private <D extends CallableDescriptor, F extends D> void performResolutionForCandidateCall(@NotNull CallResolutionContext<D, F> context,
|
||||
@NotNull ResolutionTask<D, F> task) {
|
||||
|
||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||
|
||||
candidateCall.setTrace(temporaryTrace);
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
|
||||
context.tracing.bindReference(context.trace, candidateCall);
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
candidateCall.addStatus(SUCCESS);
|
||||
checkTypesWithNoCallee(context.toBasic());
|
||||
@@ -477,7 +478,7 @@ public class CallResolver {
|
||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus inferTypeArguments(CallResolutionContext<D> context) {
|
||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus inferTypeArguments(CallResolutionContext<D, F> context) {
|
||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
|
||||
@@ -624,7 +625,7 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkAllValueArguments(CallResolutionContext<D> context) {
|
||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus checkAllValueArguments(CallResolutionContext<D, F> context) {
|
||||
ResolutionStatus result = checkValueArgumentTypes(context);
|
||||
ResolvedCall candidateCall = context.candidateCall;
|
||||
result = result.combine(checkReceiver(context, candidateCall.getResultingDescriptor().getReceiverParameter(), candidateCall.getReceiverArgument()));
|
||||
@@ -632,7 +633,7 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(CallResolutionContext<D> context, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument) {
|
||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus checkReceiver(CallResolutionContext<D, F> context, ReceiverDescriptor receiverParameter, ReceiverDescriptor receiverArgument) {
|
||||
ResolutionStatus result = SUCCESS;
|
||||
if (receiverParameter.exists() && receiverArgument.exists()) {
|
||||
ASTNode callOperationNode = context.call.getCallOperationNode();
|
||||
@@ -660,7 +661,7 @@ public class CallResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkValueArgumentTypes(CallResolutionContext<D> context) {
|
||||
private <D extends CallableDescriptor, F extends D> ResolutionStatus checkValueArgumentTypes(CallResolutionContext<D, F> context) {
|
||||
ResolutionStatus result = SUCCESS;
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : context.candidateCall.getValueArguments().entrySet()) {
|
||||
ValueParameterDescriptor parameterDescriptor = entry.getKey();
|
||||
@@ -734,8 +735,8 @@ public class CallResolver {
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> computeResultAndReportErrors(
|
||||
BindingTrace trace,
|
||||
TracingStrategy tracing,
|
||||
Set<ResolvedCallImpl<D>> successfulCandidates,
|
||||
Set<ResolvedCallImpl<D>> failedCandidates) {
|
||||
Set<ResolvedCallWithTrace<D>> successfulCandidates,
|
||||
Set<ResolvedCallWithTrace<D>> failedCandidates) {
|
||||
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
||||
|
||||
if (successfulCandidates.size() > 0) {
|
||||
@@ -756,8 +757,8 @@ public class CallResolver {
|
||||
// and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable"
|
||||
// Used to be: weak errors. Generalized for future extensions
|
||||
for (EnumSet<ResolutionStatus> severityLevel : SEVERITY_LEVELS) {
|
||||
Set<ResolvedCallImpl<D>> thisLevel = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallImpl<D> candidate : failedCandidates) {
|
||||
Set<ResolvedCallWithTrace<D>> thisLevel = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallWithTrace<D> candidate : failedCandidates) {
|
||||
if (severityLevel.contains(candidate.getStatus())) {
|
||||
thisLevel.add(candidate);
|
||||
}
|
||||
@@ -777,7 +778,7 @@ public class CallResolver {
|
||||
|
||||
assert false : "Should not be reachable, cause every status must belong to some level";
|
||||
|
||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
||||
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
||||
if (noOverrides.size() != 1) {
|
||||
tracing.noneApplicable(trace, noOverrides);
|
||||
tracing.recordAmbiguity(trace, noOverrides);
|
||||
@@ -787,7 +788,7 @@ public class CallResolver {
|
||||
failedCandidates = noOverrides;
|
||||
}
|
||||
|
||||
ResolvedCallImpl<D> failed = failedCandidates.iterator().next();
|
||||
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
|
||||
failed.getTrace().commit();
|
||||
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
|
||||
}
|
||||
@@ -797,18 +798,18 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||
for (ResolvedCallImpl<D> result : results) {
|
||||
private static <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallWithTrace<D>> results) {
|
||||
for (ResolvedCallWithTrace<D> result : results) {
|
||||
if (result.isDirty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallImpl<D>> candidates, boolean discriminateGenerics) {
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) {
|
||||
if (candidates.size() != 1) {
|
||||
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||
ResolvedCallImpl<D> candidate = iterator.next();
|
||||
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||
ResolvedCallWithTrace<D> candidate = iterator.next();
|
||||
if (candidate.isDirty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -817,27 +818,31 @@ public class CallResolver {
|
||||
if (cleanCandidates.isEmpty()) {
|
||||
cleanCandidates = candidates;
|
||||
}
|
||||
ResolvedCallImpl<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
|
||||
ResolvedCallWithTrace<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
|
||||
if (maximallySpecific != null) {
|
||||
return OverloadResolutionResultsImpl.success(maximallySpecific);
|
||||
}
|
||||
|
||||
if (discriminateGenerics) {
|
||||
ResolvedCallImpl<D> maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
|
||||
ResolvedCallWithTrace<D> maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
|
||||
if (maximallySpecificGenericsDiscriminated != null) {
|
||||
return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated);
|
||||
}
|
||||
}
|
||||
|
||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||
|
||||
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
|
||||
}
|
||||
else {
|
||||
ResolvedCallImpl<D> result = candidates.iterator().next();
|
||||
ResolvedCallWithTrace<D> result = candidates.iterator().next();
|
||||
|
||||
TemporaryBindingTrace temporaryTrace = result.getTrace();
|
||||
temporaryTrace.commit();
|
||||
|
||||
if (result instanceof VariableAsFunctionResolvedCall) {
|
||||
((VariableAsFunctionResolvedCall)result).getVariableCall().getTrace().commit();
|
||||
}
|
||||
return OverloadResolutionResultsImpl.success(result);
|
||||
}
|
||||
}
|
||||
@@ -868,13 +873,12 @@ public class CallResolver {
|
||||
|
||||
BindingTraceContext trace = new BindingTraceContext();
|
||||
TemporaryBindingTrace temporaryBindingTrace = TemporaryBindingTrace.create(trace);
|
||||
Set<ResolvedCallImpl<FunctionDescriptor>> calls = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<FunctionDescriptor>> calls = Sets.newLinkedHashSet();
|
||||
for (ResolutionCandidate<FunctionDescriptor> candidate : candidates) {
|
||||
ResolvedCallImpl<FunctionDescriptor> call = ResolvedCallImpl.create(candidate);
|
||||
call.setTrace(temporaryBindingTrace);
|
||||
ResolvedCallImpl<FunctionDescriptor> call = ResolvedCallImpl.create(candidate, temporaryBindingTrace);
|
||||
calls.add(call);
|
||||
}
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, calls, Collections.<ResolvedCallImpl<FunctionDescriptor>>emptySet());
|
||||
return computeResultAndReportErrors(trace, TracingStrategy.EMPTY, calls, Collections.<ResolvedCallWithTrace<FunctionDescriptor>>emptySet());
|
||||
}
|
||||
|
||||
private List<ResolutionCandidate<FunctionDescriptor>> findCandidatesByExactSignature(JetScope scope, ReceiverDescriptor receiver,
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Map;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ResolutionDebugInfo {
|
||||
public static final WritableSlice<One, List<? extends ResolutionTask<? extends CallableDescriptor>>> TASKS = Slices.createSimpleSlice();
|
||||
public static final WritableSlice<One, List<? extends ResolutionTask<? extends CallableDescriptor, ?>>> TASKS = Slices.createSimpleSlice();
|
||||
public static final WritableSlice<One, ResolvedCall<? extends CallableDescriptor>> RESULT = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ResolvedCall<? extends CallableDescriptor>, StringBuilder> ERRORS = Slices.createSimpleSlice();
|
||||
|
||||
+4
-4
@@ -31,7 +31,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
|
||||
private final JetReferenceExpression reference;
|
||||
private final BasicResolutionContext basicResolutionContext;
|
||||
private final Predicate<ResolutionCandidate<D>> visibleStrategy;
|
||||
@@ -40,7 +40,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
private final Collection<Collection<ResolutionCandidate<D>>> members = Sets.newLinkedHashSet();
|
||||
private final Collection<Collection<ResolutionCandidate<D>>> nonLocalExtensions = Sets.newLinkedHashSet();
|
||||
|
||||
private List<ResolutionTask<D>> tasks = null;
|
||||
private List<ResolutionTask<D, F>> tasks = null;
|
||||
|
||||
public ResolutionTaskHolder(@NotNull JetReferenceExpression reference,
|
||||
@NotNull BasicResolutionContext basicResolutionContext,
|
||||
@@ -68,7 +68,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
}
|
||||
}
|
||||
|
||||
public List<ResolutionTask<D>> getTasks() {
|
||||
public List<ResolutionTask<D, F>> getTasks() {
|
||||
if (tasks == null) {
|
||||
tasks = Lists.newArrayList();
|
||||
List<Collection<ResolutionCandidate<D>>> candidateList = Lists.newArrayList();
|
||||
@@ -89,7 +89,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor> {
|
||||
for (Collection<ResolutionCandidate<D>> candidates : candidateList) {
|
||||
Collection<ResolutionCandidate<D>> filteredCandidates = Collections2.filter(candidates, visibilityStrategy);
|
||||
if (!filteredCandidates.isEmpty()) {
|
||||
tasks.add(new ResolutionTask<D>(filteredCandidates, reference, basicResolutionContext));
|
||||
tasks.add(new ResolutionTask<D, F>(filteredCandidates, reference, basicResolutionContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user