cache resolve results for incomplete type inference
This commit is contained in:
@@ -274,43 +274,37 @@ public class CallResolver {
|
|||||||
@NotNull CallTransformer<D, F> callTransformer,
|
@NotNull CallTransformer<D, F> callTransformer,
|
||||||
@NotNull final JetReferenceExpression reference) {
|
@NotNull final JetReferenceExpression reference) {
|
||||||
PsiElement element = context.call.getCallElement();
|
PsiElement element = context.call.getCallElement();
|
||||||
|
OverloadResolutionResults<F> results = null;
|
||||||
|
TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call);
|
||||||
if (element instanceof JetExpression) {
|
if (element instanceof JetExpression) {
|
||||||
OverloadResolutionResults<F> cachedResults = context.trace.get(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression) element));
|
CallKey key = CallKey.create(context.call.getCallType(), (JetExpression) element);
|
||||||
|
OverloadResolutionResults<F> cachedResults = context.trace.get(resolutionResultsSlice, key);
|
||||||
if (cachedResults != null) {
|
if (cachedResults != null) {
|
||||||
DelegatingBindingTrace delegatingTrace = context.trace.get(TRACE_DELTAS_CACHE, (JetExpression) element);
|
DelegatingBindingTrace deltasTraceForResolve = context.trace.get(TRACE_DELTAS_CACHE, (JetExpression) element);
|
||||||
assert delegatingTrace != null;
|
assert deltasTraceForResolve != null;
|
||||||
delegatingTrace.addAllMyDataTo(context.trace);
|
deltasTraceForResolve.addAllMyDataTo(traceToResolveCall);
|
||||||
return cachedResults;
|
results = cachedResults;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TemporaryBindingTrace delegatingBindingTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call);
|
if (results == null) {
|
||||||
BasicResolutionContext newContext = context.replaceTrace(delegatingBindingTrace);
|
results = doResolveCall(context.replaceTrace(traceToResolveCall), prioritizedTasks, callTransformer, reference);
|
||||||
OverloadResolutionResults<F> results = doResolveCall(newContext,
|
if (results instanceof OverloadResolutionResultsImpl) {
|
||||||
prioritizedTasks,
|
DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
|
||||||
callTransformer, reference);
|
if (deltasTraceForTypeInference != null) {
|
||||||
DelegatingBindingTrace cloneDelta = new DelegatingBindingTrace(
|
deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall);
|
||||||
new BindingTraceContext().getBindingContext(), "delta trace for caching resolve of", context.call);
|
}
|
||||||
delegatingBindingTrace.addAllMyDataTo(cloneDelta);
|
}
|
||||||
cacheResults(resolutionResultsSlice, context, results, cloneDelta);
|
cacheResults(resolutionResultsSlice, context, results, traceToResolveCall);
|
||||||
|
}
|
||||||
|
|
||||||
if (prioritizedTasks.isEmpty()) {
|
if (prioritizedTasks.isEmpty()) {
|
||||||
delegatingBindingTrace.commit();
|
traceToResolveCall.commit();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
TemporaryBindingTrace temporaryBindingTrace = null;
|
|
||||||
if (results instanceof OverloadResolutionResultsImpl) {
|
|
||||||
temporaryBindingTrace = ((OverloadResolutionResultsImpl) results).getTrace();
|
|
||||||
if (temporaryBindingTrace != null) {
|
|
||||||
newContext = newContext.replaceTrace(temporaryBindingTrace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TracingStrategy tracing = prioritizedTasks.iterator().next().tracing;
|
TracingStrategy tracing = prioritizedTasks.iterator().next().tracing;
|
||||||
OverloadResolutionResults<F> completeResults = completeTypeInferenceDependentOnExpectedType(newContext, results, tracing);
|
OverloadResolutionResults<F> completeResults = completeTypeInferenceDependentOnExpectedType(
|
||||||
if (temporaryBindingTrace != null) {
|
context.replaceTrace(traceToResolveCall), results, tracing);
|
||||||
temporaryBindingTrace.commit();
|
traceToResolveCall.commit();
|
||||||
}
|
|
||||||
delegatingBindingTrace.commit();
|
|
||||||
return completeResults;
|
return completeResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,12 +313,13 @@ public class CallResolver {
|
|||||||
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference,
|
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference,
|
||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return resultsWithIncompleteTypeInference;
|
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE)
|
||||||
|
return resultsWithIncompleteTypeInference;
|
||||||
Set<ResolvedCallWithTrace<D>> successful = Sets.newLinkedHashSet();
|
Set<ResolvedCallWithTrace<D>> successful = Sets.newLinkedHashSet();
|
||||||
Set<ResolvedCallWithTrace<D>> failed = Sets.newLinkedHashSet();
|
Set<ResolvedCallWithTrace<D>> failed = Sets.newLinkedHashSet();
|
||||||
for (ResolvedCall<? extends D> call : resultsWithIncompleteTypeInference.getResultingCalls()) {
|
for (ResolvedCall<? extends D> call : resultsWithIncompleteTypeInference.getResultingCalls()) {
|
||||||
if (!(call instanceof ResolvedCallImpl)) continue;
|
if (!(call instanceof ResolvedCallImpl)) continue;
|
||||||
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) call;
|
ResolvedCallImpl<D> resolvedCall = ((ResolvedCallImpl<D>) call).copy(context);
|
||||||
if (!resolvedCall.hasUnknownTypeParameters()) {
|
if (!resolvedCall.hasUnknownTypeParameters()) {
|
||||||
if (resolvedCall.getStatus().isSuccess()) {
|
if (resolvedCall.getStatus().isSuccess()) {
|
||||||
successful.add(resolvedCall);
|
successful.add(resolvedCall);
|
||||||
@@ -388,9 +383,10 @@ public class CallResolver {
|
|||||||
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
|
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
|
||||||
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
|
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
|
||||||
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
context.tracing.typeInferenceFailed(resolvedCall.getTrace(),
|
||||||
InferenceErrorData
|
InferenceErrorData
|
||||||
.create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType),
|
.create(descriptor, constraintSystem, argumentTypes, receiverType,
|
||||||
constraintSystemWithoutExpectedTypeConstraint);
|
context.expectedType),
|
||||||
|
constraintSystemWithoutExpectedTypeConstraint);
|
||||||
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
|
resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR);
|
||||||
failed.add(resolvedCall);
|
failed.add(resolvedCall);
|
||||||
return;
|
return;
|
||||||
@@ -426,19 +422,24 @@ public class CallResolver {
|
|||||||
|
|
||||||
private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice,
|
private <F extends CallableDescriptor> void cacheResults(@NotNull WritableSlice<CallKey, OverloadResolutionResults<F>> resolutionResultsSlice,
|
||||||
@NotNull BasicResolutionContext context, @NotNull OverloadResolutionResults<F> results,
|
@NotNull BasicResolutionContext context, @NotNull OverloadResolutionResults<F> results,
|
||||||
@NotNull DelegatingBindingTrace delegatingBindingTrace) {
|
@NotNull DelegatingBindingTrace traceToResolveCall) {
|
||||||
boolean canBeCached = true;
|
//boolean canBeCached = true;
|
||||||
for (ResolvedCall<? extends CallableDescriptor> call : results.getResultingCalls()) {
|
//for (ResolvedCall<? extends CallableDescriptor> call : results.getResultingCalls()) {
|
||||||
if (!call.getCandidateDescriptor().getTypeParameters().isEmpty()) {
|
// if (!call.getCandidateDescriptor().getTypeParameters().isEmpty()) {
|
||||||
canBeCached = false;
|
// canBeCached = false;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
if (!canBeCached) return;
|
//if (!canBeCached) return;
|
||||||
PsiElement callElement = context.call.getCallElement();
|
PsiElement callElement = context.call.getCallElement();
|
||||||
if (!(callElement instanceof JetExpression)) return;
|
if (!(callElement instanceof JetExpression)) return;
|
||||||
|
|
||||||
|
DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
|
||||||
|
new BindingTraceContext().getBindingContext(), "delta trace for caching resolve of", context.call);
|
||||||
|
traceToResolveCall.addAllMyDataTo(deltasTraceToCacheResolve);
|
||||||
|
|
||||||
|
|
||||||
context.trace.record(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression)callElement), results);
|
context.trace.record(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression)callElement), results);
|
||||||
context.trace.record(TRACE_DELTAS_CACHE, (JetExpression) callElement, delegatingBindingTrace);
|
context.trace.record(TRACE_DELTAS_CACHE, (JetExpression) callElement, deltasTraceToCacheResolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BasicResolutionContext context) {
|
||||||
@@ -557,7 +558,7 @@ public class CallResolver {
|
|||||||
|
|
||||||
for (ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) {
|
for (ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) {
|
||||||
TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create(
|
TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create(
|
||||||
task.trace, "trace to resolve candidate", resolutionCandidate);
|
task.trace, "trace to resolve candidate");
|
||||||
Collection<CallResolutionContext<D, F>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace);
|
Collection<CallResolutionContext<D, F>> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace);
|
||||||
for (CallResolutionContext<D, F> context : contexts) {
|
for (CallResolutionContext<D, F> context : contexts) {
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.calls;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -68,7 +69,7 @@ import java.util.Collections;
|
|||||||
|
|
||||||
private final Collection<ResolvedCallWithTrace<D>> results;
|
private final Collection<ResolvedCallWithTrace<D>> results;
|
||||||
private final Code resultCode;
|
private final Code resultCode;
|
||||||
private TemporaryBindingTrace trace;
|
private DelegatingBindingTrace trace;
|
||||||
|
|
||||||
private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection<ResolvedCallWithTrace<D>> results) {
|
private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection<ResolvedCallWithTrace<D>> results) {
|
||||||
this.results = results;
|
this.results = results;
|
||||||
@@ -130,11 +131,11 @@ import java.util.Collections;
|
|||||||
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
|
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public TemporaryBindingTrace getTrace() {
|
public DelegatingBindingTrace getTrace() {
|
||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OverloadResolutionResultsImpl<D> setTrace(TemporaryBindingTrace trace) {
|
public OverloadResolutionResultsImpl<D> setTrace(DelegatingBindingTrace trace) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user