From 1f9d08861db0463f5d1c9d68f16eddd123e36543 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 23 Oct 2012 15:45:17 +0400 Subject: [PATCH] cache resolve results for incomplete type inference --- .../jet/lang/resolve/calls/CallResolver.java | 87 ++++++++++--------- .../calls/OverloadResolutionResultsImpl.java | 7 +- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 174e431ff80..86b39d5afe8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -274,43 +274,37 @@ public class CallResolver { @NotNull CallTransformer callTransformer, @NotNull final JetReferenceExpression reference) { PsiElement element = context.call.getCallElement(); + OverloadResolutionResults results = null; + TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call); if (element instanceof JetExpression) { - OverloadResolutionResults cachedResults = context.trace.get(resolutionResultsSlice, CallKey.create(context.call.getCallType(), (JetExpression) element)); + CallKey key = CallKey.create(context.call.getCallType(), (JetExpression) element); + OverloadResolutionResults cachedResults = context.trace.get(resolutionResultsSlice, key); if (cachedResults != null) { - DelegatingBindingTrace delegatingTrace = context.trace.get(TRACE_DELTAS_CACHE, (JetExpression) element); - assert delegatingTrace != null; - delegatingTrace.addAllMyDataTo(context.trace); - return cachedResults; + DelegatingBindingTrace deltasTraceForResolve = context.trace.get(TRACE_DELTAS_CACHE, (JetExpression) element); + assert deltasTraceForResolve != null; + deltasTraceForResolve.addAllMyDataTo(traceToResolveCall); + results = cachedResults; } } - TemporaryBindingTrace delegatingBindingTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call); - BasicResolutionContext newContext = context.replaceTrace(delegatingBindingTrace); - OverloadResolutionResults results = doResolveCall(newContext, - prioritizedTasks, - callTransformer, reference); - DelegatingBindingTrace cloneDelta = new DelegatingBindingTrace( - new BindingTraceContext().getBindingContext(), "delta trace for caching resolve of", context.call); - delegatingBindingTrace.addAllMyDataTo(cloneDelta); - cacheResults(resolutionResultsSlice, context, results, cloneDelta); + if (results == null) { + results = doResolveCall(context.replaceTrace(traceToResolveCall), prioritizedTasks, callTransformer, reference); + if (results instanceof OverloadResolutionResultsImpl) { + DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace(); + if (deltasTraceForTypeInference != null) { + deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); + } + } + cacheResults(resolutionResultsSlice, context, results, traceToResolveCall); + } if (prioritizedTasks.isEmpty()) { - delegatingBindingTrace.commit(); + traceToResolveCall.commit(); 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; - OverloadResolutionResults completeResults = completeTypeInferenceDependentOnExpectedType(newContext, results, tracing); - if (temporaryBindingTrace != null) { - temporaryBindingTrace.commit(); - } - delegatingBindingTrace.commit(); + OverloadResolutionResults completeResults = completeTypeInferenceDependentOnExpectedType( + context.replaceTrace(traceToResolveCall), results, tracing); + traceToResolveCall.commit(); return completeResults; } @@ -319,12 +313,13 @@ public class CallResolver { @NotNull OverloadResolutionResults resultsWithIncompleteTypeInference, @NotNull TracingStrategy tracing ) { - if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return resultsWithIncompleteTypeInference; + if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) + return resultsWithIncompleteTypeInference; Set> successful = Sets.newLinkedHashSet(); Set> failed = Sets.newLinkedHashSet(); for (ResolvedCall call : resultsWithIncompleteTypeInference.getResultingCalls()) { if (!(call instanceof ResolvedCallImpl)) continue; - ResolvedCallImpl resolvedCall = (ResolvedCallImpl) call; + ResolvedCallImpl resolvedCall = ((ResolvedCallImpl) call).copy(context); if (!resolvedCall.hasUnknownTypeParameters()) { if (resolvedCall.getStatus().isSuccess()) { successful.add(resolvedCall); @@ -388,9 +383,10 @@ public class CallResolver { List argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes; JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; context.tracing.typeInferenceFailed(resolvedCall.getTrace(), - InferenceErrorData - .create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType), - constraintSystemWithoutExpectedTypeConstraint); + InferenceErrorData + .create(descriptor, constraintSystem, argumentTypes, receiverType, + context.expectedType), + constraintSystemWithoutExpectedTypeConstraint); resolvedCall.addStatus(ResolutionStatus.TYPE_INFERENCE_ERROR); failed.add(resolvedCall); return; @@ -426,19 +422,24 @@ public class CallResolver { private void cacheResults(@NotNull WritableSlice> resolutionResultsSlice, @NotNull BasicResolutionContext context, @NotNull OverloadResolutionResults results, - @NotNull DelegatingBindingTrace delegatingBindingTrace) { - boolean canBeCached = true; - for (ResolvedCall call : results.getResultingCalls()) { - if (!call.getCandidateDescriptor().getTypeParameters().isEmpty()) { - canBeCached = false; - } - } - if (!canBeCached) return; + @NotNull DelegatingBindingTrace traceToResolveCall) { + //boolean canBeCached = true; + //for (ResolvedCall call : results.getResultingCalls()) { + // if (!call.getCandidateDescriptor().getTypeParameters().isEmpty()) { + // canBeCached = false; + // } + //} + //if (!canBeCached) return; PsiElement callElement = context.call.getCallElement(); 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(TRACE_DELTAS_CACHE, (JetExpression) callElement, delegatingBindingTrace); + context.trace.record(TRACE_DELTAS_CACHE, (JetExpression) callElement, deltasTraceToCacheResolve); } private OverloadResolutionResults checkArgumentTypesAndFail(BasicResolutionContext context) { @@ -557,7 +558,7 @@ public class CallResolver { for (ResolutionCandidate resolutionCandidate : task.getCandidates()) { TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create( - task.trace, "trace to resolve candidate", resolutionCandidate); + task.trace, "trace to resolve candidate"); Collection> contexts = callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace); for (CallResolutionContext context : contexts) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java index 34dfc0c87d7..50a15ac7fea 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.calls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import java.util.Collection; @@ -68,7 +69,7 @@ import java.util.Collections; private final Collection> results; private final Code resultCode; - private TemporaryBindingTrace trace; + private DelegatingBindingTrace trace; private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection> results) { this.results = results; @@ -130,11 +131,11 @@ import java.util.Collections; // return new OverloadResolutionResultsImpl(resultCode, functionDescriptors); // } - public TemporaryBindingTrace getTrace() { + public DelegatingBindingTrace getTrace() { return trace; } - public OverloadResolutionResultsImpl setTrace(TemporaryBindingTrace trace) { + public OverloadResolutionResultsImpl setTrace(DelegatingBindingTrace trace) { this.trace = trace; return this; }