separated addition of constraints for function literals(*) and for expected type
* = which argument types are known call with these function literal constraints is cached
This commit is contained in:
@@ -276,13 +276,15 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
if (results == null) {
|
||||
results = doResolveCall(context.replaceBindingTrace(traceToResolveCall), prioritizedTasks, callTransformer, reference);
|
||||
if (results instanceof OverloadResolutionResultsImpl) {
|
||||
DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
|
||||
BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall);
|
||||
OverloadResolutionResults<F> resultsWithFixedResolve = doResolveCall(newContext, prioritizedTasks, callTransformer, reference);
|
||||
if (resultsWithFixedResolve instanceof OverloadResolutionResultsImpl) {
|
||||
DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) resultsWithFixedResolve).getTrace();
|
||||
if (deltasTraceForTypeInference != null) {
|
||||
deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall);
|
||||
}
|
||||
}
|
||||
results = completeTypeInferenceDependentOnFunctionLiterals(newContext, resultsWithFixedResolve, TracingStrategy.EMPTY);
|
||||
cacheResults(resolutionResultsSlice, context, results, traceToResolveCall);
|
||||
}
|
||||
|
||||
@@ -297,6 +299,35 @@ public class CallResolver {
|
||||
return completeResults;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnFunctionLiterals(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference,
|
||||
@NotNull TracingStrategy tracing
|
||||
) {
|
||||
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
|
||||
return resultsWithIncompleteTypeInference;
|
||||
}
|
||||
|
||||
Set<ResolvedCallWithTrace<D>> candidates = Sets.newLinkedHashSet(
|
||||
(Collection<? extends ResolvedCallWithTrace<D>>) resultsWithIncompleteTypeInference.getResultingCalls());
|
||||
ResolvedCallWithTrace<D> maximallySpecific = OverloadingConflictResolver.INSTANCE.findMaximallySpecific(candidates, false);
|
||||
if (maximallySpecific != null && maximallySpecific instanceof ResolvedCallImpl) {
|
||||
candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(
|
||||
CallCandidateResolutionContext.createForCallBeingAnalyzed((ResolvedCallImpl<D>) maximallySpecific, context, tracing));
|
||||
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : candidates) {
|
||||
if (callWithUnknownTypeParameters != maximallySpecific) {
|
||||
((ResolvedCallImpl<D>) callWithUnknownTypeParameters).addStatus(ResolutionStatus.OTHER_ERROR);
|
||||
}
|
||||
}
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(Collections.singleton(maximallySpecific));
|
||||
}
|
||||
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : candidates) {
|
||||
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) callWithUnknownTypeParameters;
|
||||
resolvedCall.addStatus(ResolutionStatus.INCOMPLETE_TYPE_INFERENCE);
|
||||
}
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(candidates);
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnExpectedType(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference,
|
||||
@@ -306,38 +337,21 @@ public class CallResolver {
|
||||
return resultsWithIncompleteTypeInference;
|
||||
}
|
||||
|
||||
Set<ResolvedCallWithTrace<D>> candidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<D>> incompleteCalls = Sets.newLinkedHashSet();
|
||||
for (ResolvedCall<? extends D> cachedCall : resultsWithIncompleteTypeInference.getResultingCalls()) {
|
||||
if (cachedCall instanceof ResolvedCallImpl) {
|
||||
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) cachedCall;
|
||||
if (resolvedCall.hasUnknownTypeParameters()) {
|
||||
ResolvedCallImpl<D> copy = CallResolverUtil.copy(resolvedCall, context);
|
||||
incompleteCalls.add(copy);
|
||||
candidates.add(copy);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
candidates.add((ResolvedCallWithTrace<D>) cachedCall);
|
||||
}
|
||||
ResolvedCallWithTrace<D> maximallySpecific = OverloadingConflictResolver.INSTANCE.findMaximallySpecific(incompleteCalls, false);
|
||||
if (maximallySpecific != null) {
|
||||
candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
CallCandidateResolutionContext.create(context, tracing, (ResolvedCallImpl<D>) maximallySpecific));
|
||||
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : incompleteCalls) {
|
||||
if (callWithUnknownTypeParameters != maximallySpecific) {
|
||||
((ResolvedCallImpl<D>) callWithUnknownTypeParameters).addStatus(ResolutionStatus.OTHER_ERROR);
|
||||
}
|
||||
Set<ResolvedCallWithTrace<D>> resultingCalls = null;
|
||||
if (resultsWithIncompleteTypeInference.isSingleResult()) {
|
||||
ResolvedCallWithTrace<D> resolvedCall = (ResolvedCallWithTrace<D>) resultsWithIncompleteTypeInference.getResultingCall();
|
||||
if (resolvedCall.hasUnknownTypeParameters() && resolvedCall instanceof ResolvedCallImpl) {
|
||||
ResolvedCallImpl<D> copy = CallResolverUtil.copy((ResolvedCallImpl<D>) resolvedCall, context);
|
||||
candidateResolver.completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
CallCandidateResolutionContext.createForCallBeingAnalyzed(copy, context, tracing));
|
||||
resultingCalls = Collections.<ResolvedCallWithTrace<D>>singleton(copy);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (ResolvedCallWithTrace<D> callWithUnknownTypeParameters : incompleteCalls) {
|
||||
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) callWithUnknownTypeParameters;
|
||||
resolvedCall.addStatus(ResolutionStatus.INCOMPLETE_TYPE_INFERENCE);
|
||||
}
|
||||
if (resultingCalls == null) {
|
||||
resultingCalls = (Set<ResolvedCallWithTrace<D>>) resultsWithIncompleteTypeInference.getResultingCalls();
|
||||
}
|
||||
OverloadResolutionResultsImpl<D> results = ResolutionResultsHandler.INSTANCE.computeResultAndReportErrors(
|
||||
context.trace, tracing, candidates);
|
||||
context.trace, tracing, resultingCalls);
|
||||
if (!results.isSingleResult()) {
|
||||
argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public class CallResolverUtil {
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : call.getValueArguments().entrySet()) {
|
||||
copy.recordValueArgument(entry.getKey(), entry.getValue());
|
||||
}
|
||||
copy.setInitialDataFlowInfo(call.getDataFlowInfo());
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ public class CandidateResolver {
|
||||
return descriptor instanceof ClassDescriptor ? (ClassDescriptor) descriptor : null;
|
||||
}
|
||||
|
||||
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnFunctionLiteralsForCall(
|
||||
CallCandidateResolutionContext<D, D> context
|
||||
) {
|
||||
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
||||
@@ -206,6 +206,16 @@ public class CandidateResolver {
|
||||
addConstraintForFunctionLiteral(valueArgument, valueParameterDescriptor, constraintSystem, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(
|
||||
CallCandidateResolutionContext<D, D> context
|
||||
) {
|
||||
ResolvedCallImpl<D> resolvedCall = context.candidateCall;
|
||||
assert resolvedCall.hasUnknownTypeParameters();
|
||||
D descriptor = resolvedCall.getCandidateDescriptor();
|
||||
ConstraintSystem constraintSystem = resolvedCall.getConstraintSystem();
|
||||
assert constraintSystem != null;
|
||||
|
||||
ConstraintSystem constraintSystemWithoutExpectedTypeConstraint = constraintSystem.copy();
|
||||
constraintSystem.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(),
|
||||
|
||||
+4
-4
@@ -65,11 +65,11 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor,
|
||||
return create(candidateCall, task, trace, tracing, task.call);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> CallCandidateResolutionContext<D, D> create(
|
||||
@NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing,
|
||||
@NotNull ResolvedCallImpl<D> candidateCall) {
|
||||
public static <D extends CallableDescriptor> CallCandidateResolutionContext<D, D> createForCallBeingAnalyzed(
|
||||
@NotNull ResolvedCallImpl<D> candidateCall, @NotNull BasicCallResolutionContext context, @NotNull TracingStrategy tracing
|
||||
) {
|
||||
return new CallCandidateResolutionContext<D, D>(candidateCall, tracing, context.trace, context.scope, context.call,
|
||||
context.expectedType, context.dataFlowInfo, context.namespacesAllowed, true);
|
||||
context.expectedType, context.dataFlowInfo, context.namespacesAllowed, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user