From 3c04b87f1a80b0a59f38da23cbe45744f4becc67 Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 30 Oct 2013 19:30:37 +0400 Subject: [PATCH] Clean internal data for 'invoke' calls. --- .../jet/lang/resolve/calls/CallResolver.java | 6 ++++- .../lang/resolve/calls/CandidateResolver.java | 6 +++++ .../calls/context/ResolutionResultsCache.java | 5 ++++ .../context/ResolutionResultsCacheImpl.java | 27 ++++++++++++++++--- .../TemporaryResolutionResultsCache.java | 14 +++++++++- 5 files changed, 52 insertions(+), 6 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 15033992632..1a1f0c3098c 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 @@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; +import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; @@ -335,6 +336,8 @@ public class CallResolver { } return; } + //call for 'invoke' was completed earlier + if (results.getResultingCall() instanceof VariableAsFunctionResolvedCall) return; CallCandidateResolutionContext candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing); candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext); @@ -390,9 +393,10 @@ public class CallResolver { context.resolutionResultsCache.recordResolutionTrace(callKey, deltasTraceToCacheResolve); if (results.isSingleResult()) { + ResolvedCallWithTrace resultingCall = results.getResultingCall(); CallCandidateResolutionContext callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing); - context.resolutionResultsCache.recordDeferredComputationForCall(callKey, callCandidateResolutionContext); + context.resolutionResultsCache.recordDeferredComputationForCall(callKey, resultingCall, callCandidateResolutionContext); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 86c8783e424..e42ae267aaa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -371,6 +371,12 @@ public class CandidateResolver { type, expression, context.trace, isFairSafeCallExpression(expression, context.trace)); contextForArgument.candidateCall.cleanInternalData(); + + // clean data for "invoke" calls + ResolvedCallWithTrace resolvedCall = context.resolutionResultsCache.getCallForArgument(keyExpression); + assert resolvedCall != null : "Resolved call for '" + keyExpression + "' is not stored, but CallCandidateResolutionContext is."; + resolvedCall.cleanInternalData(); + DataFlowUtils.checkType(result, expression, contextForArgument); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCache.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCache.java index e761d29303b..8a6d182ac9c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCache.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCache.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; public interface ResolutionResultsCache { @@ -55,9 +56,13 @@ public interface ResolutionResultsCache { void recordDeferredComputationForCall( @NotNull CallKey callKey, + @NotNull ResolvedCallWithTrace resolvedCall, @NotNull CallCandidateResolutionContext deferredComputation ); @Nullable CallCandidateResolutionContext getDeferredComputation(@Nullable JetExpression expression); + + @Nullable + ResolvedCallWithTrace getCallForArgument(@Nullable JetExpression expression); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCacheImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCacheImpl.java index 401dd992955..4519671cf3c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCacheImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/ResolutionResultsCacheImpl.java @@ -22,22 +22,26 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.util.slicedmap.BasicWritableSlice; import org.jetbrains.jet.util.slicedmap.Slices; import org.jetbrains.jet.util.slicedmap.WritableSlice; +import static org.jetbrains.jet.lang.psi.Call.CallType; +import static org.jetbrains.jet.lang.psi.Call.CallType.*; + public class ResolutionResultsCacheImpl implements ResolutionResultsCache { public static final WritableSlice> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice(); public static final WritableSlice> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice(); public static final WritableSlice TRACE_DELTAS_CACHE = Slices.createSimpleSlice(); public static final WritableSlice> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice(); + public static final WritableSlice> RESOLVED_CALL_FOR_ARGUMENT = Slices.createSimpleSlice(); static { BasicWritableSlice.initSliceDebugNames(ResolutionResultsCacheImpl.class); @@ -78,19 +82,28 @@ public class ResolutionResultsCacheImpl implements ResolutionResultsCache { @Override public void recordDeferredComputationForCall( @NotNull CallKey callKey, + @NotNull ResolvedCallWithTrace resolvedCall, @NotNull CallCandidateResolutionContext deferredComputation ) { trace.record(DEFERRED_COMPUTATION_FOR_CALL, callKey, deferredComputation); + trace.record(RESOLVED_CALL_FOR_ARGUMENT, callKey, resolvedCall); } @Override @Nullable public CallCandidateResolutionContext getDeferredComputation(@Nullable JetExpression expression) { + return getValueTryingAllCallTypes(expression, DEFERRED_COMPUTATION_FOR_CALL); + } + + @Nullable + private T getValueTryingAllCallTypes( + @Nullable JetExpression expression, + @NotNull WritableSlice slice + ) { if (expression == null) return null; - for (Call.CallType callType : Lists - .newArrayList(Call.CallType.DEFAULT, Call.CallType.ARRAY_GET_METHOD, Call.CallType.ARRAY_SET_METHOD)) { + for (CallType callType : Lists.newArrayList(DEFAULT, ARRAY_GET_METHOD, ARRAY_SET_METHOD)) { CallKey callKey = CallKey.create(callType, expression); - CallCandidateResolutionContext context = trace.get(DEFERRED_COMPUTATION_FOR_CALL, callKey); + T context = trace.get(slice, callKey); if (context != null) { return context; } @@ -98,6 +111,12 @@ public class ResolutionResultsCacheImpl implements ResolutionResultsCache { return null; } + @Nullable + @Override + public ResolvedCallWithTrace getCallForArgument(@Nullable JetExpression expression) { + return getValueTryingAllCallTypes(expression, RESOLVED_CALL_FOR_ARGUMENT); + } + @NotNull public static ResolutionResultsCache create() { return new ResolutionResultsCacheImpl(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TemporaryResolutionResultsCache.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TemporaryResolutionResultsCache.java index 193d26fc9d3..d5198c3e9dd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TemporaryResolutionResultsCache.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/context/TemporaryResolutionResultsCache.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; public class TemporaryResolutionResultsCache implements ResolutionResultsCache { @@ -76,9 +77,10 @@ public class TemporaryResolutionResultsCache implements ResolutionResultsCache { @Override public void recordDeferredComputationForCall( @NotNull CallKey callKey, + @NotNull ResolvedCallWithTrace resolvedCall, @NotNull CallCandidateResolutionContext deferredComputation ) { - innerCache.recordDeferredComputationForCall(callKey, deferredComputation); + innerCache.recordDeferredComputationForCall(callKey, resolvedCall, deferredComputation); } @Nullable @@ -91,6 +93,16 @@ public class TemporaryResolutionResultsCache implements ResolutionResultsCache { return parentCache.getDeferredComputation(expression); } + @Nullable + @Override + public ResolvedCallWithTrace getCallForArgument(@Nullable JetExpression expression) { + ResolvedCallWithTrace resolvedCall = innerCache.getCallForArgument(expression); + if (resolvedCall != null) { + return resolvedCall; + } + return parentCache.getCallForArgument(expression); + } + public void commit() { if (parentCache instanceof ResolutionResultsCacheImpl) { ((ResolutionResultsCacheImpl) parentCache).addData(innerCache);