Clean internal data for 'invoke' calls.

This commit is contained in:
svtk
2013-10-30 19:30:37 +04:00
parent 0f56559823
commit 3c04b87f1a
5 changed files with 52 additions and 6 deletions
@@ -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.MutableDataFlowInfoForArguments;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; 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.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.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
@@ -335,6 +336,8 @@ public class CallResolver {
} }
return; return;
} }
//call for 'invoke' was completed earlier
if (results.getResultingCall() instanceof VariableAsFunctionResolvedCall) return;
CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( CallCandidateResolutionContext<D> candidateContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing); results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing);
candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext); candidateResolver.completeTypeInferenceDependentOnFunctionLiteralsForCall(candidateContext);
@@ -390,9 +393,10 @@ public class CallResolver {
context.resolutionResultsCache.recordResolutionTrace(callKey, deltasTraceToCacheResolve); context.resolutionResultsCache.recordResolutionTrace(callKey, deltasTraceToCacheResolve);
if (results.isSingleResult()) { if (results.isSingleResult()) {
ResolvedCallWithTrace<F> resultingCall = results.getResultingCall();
CallCandidateResolutionContext<F> callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed( CallCandidateResolutionContext<F> callCandidateResolutionContext = CallCandidateResolutionContext.createForCallBeingAnalyzed(
results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing); results.getResultingCall().getCallToCompleteTypeArgumentInference(), context, tracing);
context.resolutionResultsCache.recordDeferredComputationForCall(callKey, callCandidateResolutionContext); context.resolutionResultsCache.recordDeferredComputationForCall(callKey, resultingCall, callCandidateResolutionContext);
} }
} }
@@ -371,6 +371,12 @@ public class CandidateResolver {
type, expression, context.trace, isFairSafeCallExpression(expression, context.trace)); type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
contextForArgument.candidateCall.cleanInternalData(); contextForArgument.candidateCall.cleanInternalData();
// clean data for "invoke" calls
ResolvedCallWithTrace<? extends CallableDescriptor> 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); DataFlowUtils.checkType(result, expression, contextForArgument);
} }
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.CallKey;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; 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.lang.resolve.calls.results.OverloadResolutionResultsImpl;
public interface ResolutionResultsCache { public interface ResolutionResultsCache {
@@ -55,9 +56,13 @@ public interface ResolutionResultsCache {
<D extends CallableDescriptor> void recordDeferredComputationForCall( <D extends CallableDescriptor> void recordDeferredComputationForCall(
@NotNull CallKey callKey, @NotNull CallKey callKey,
@NotNull ResolvedCallWithTrace<D> resolvedCall,
@NotNull CallCandidateResolutionContext<D> deferredComputation @NotNull CallCandidateResolutionContext<D> deferredComputation
); );
@Nullable @Nullable
CallCandidateResolutionContext<? extends CallableDescriptor> getDeferredComputation(@Nullable JetExpression expression); CallCandidateResolutionContext<? extends CallableDescriptor> getDeferredComputation(@Nullable JetExpression expression);
@Nullable
ResolvedCallWithTrace<? extends CallableDescriptor> getCallForArgument(@Nullable JetExpression expression);
} }
@@ -22,22 +22,26 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; 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.CallKey;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; 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.lang.resolve.calls.results.OverloadResolutionResultsImpl;
import org.jetbrains.jet.util.slicedmap.BasicWritableSlice; import org.jetbrains.jet.util.slicedmap.BasicWritableSlice;
import org.jetbrains.jet.util.slicedmap.Slices; import org.jetbrains.jet.util.slicedmap.Slices;
import org.jetbrains.jet.util.slicedmap.WritableSlice; 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 class ResolutionResultsCacheImpl implements ResolutionResultsCache {
public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<FunctionDescriptor>> public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<FunctionDescriptor>>
RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice(); RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice();
public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice(); public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
public static final WritableSlice<CallKey, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice(); public static final WritableSlice<CallKey, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice();
public static final WritableSlice<CallKey, CallCandidateResolutionContext<? extends CallableDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice(); public static final WritableSlice<CallKey, CallCandidateResolutionContext<? extends CallableDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice();
public static final WritableSlice<CallKey, ResolvedCallWithTrace<? extends CallableDescriptor>> RESOLVED_CALL_FOR_ARGUMENT = Slices.createSimpleSlice();
static { static {
BasicWritableSlice.initSliceDebugNames(ResolutionResultsCacheImpl.class); BasicWritableSlice.initSliceDebugNames(ResolutionResultsCacheImpl.class);
@@ -78,19 +82,28 @@ public class ResolutionResultsCacheImpl implements ResolutionResultsCache {
@Override @Override
public <D extends CallableDescriptor> void recordDeferredComputationForCall( public <D extends CallableDescriptor> void recordDeferredComputationForCall(
@NotNull CallKey callKey, @NotNull CallKey callKey,
@NotNull ResolvedCallWithTrace<D> resolvedCall,
@NotNull CallCandidateResolutionContext<D> deferredComputation @NotNull CallCandidateResolutionContext<D> deferredComputation
) { ) {
trace.record(DEFERRED_COMPUTATION_FOR_CALL, callKey, deferredComputation); trace.record(DEFERRED_COMPUTATION_FOR_CALL, callKey, deferredComputation);
trace.record(RESOLVED_CALL_FOR_ARGUMENT, callKey, resolvedCall);
} }
@Override @Override
@Nullable @Nullable
public CallCandidateResolutionContext<? extends CallableDescriptor> getDeferredComputation(@Nullable JetExpression expression) { public CallCandidateResolutionContext<? extends CallableDescriptor> getDeferredComputation(@Nullable JetExpression expression) {
return getValueTryingAllCallTypes(expression, DEFERRED_COMPUTATION_FOR_CALL);
}
@Nullable
private <T> T getValueTryingAllCallTypes(
@Nullable JetExpression expression,
@NotNull WritableSlice<CallKey, T> slice
) {
if (expression == null) return null; if (expression == null) return null;
for (Call.CallType callType : Lists for (CallType callType : Lists.newArrayList(DEFAULT, ARRAY_GET_METHOD, ARRAY_SET_METHOD)) {
.newArrayList(Call.CallType.DEFAULT, Call.CallType.ARRAY_GET_METHOD, Call.CallType.ARRAY_SET_METHOD)) {
CallKey callKey = CallKey.create(callType, expression); CallKey callKey = CallKey.create(callType, expression);
CallCandidateResolutionContext<? extends CallableDescriptor> context = trace.get(DEFERRED_COMPUTATION_FOR_CALL, callKey); T context = trace.get(slice, callKey);
if (context != null) { if (context != null) {
return context; return context;
} }
@@ -98,6 +111,12 @@ public class ResolutionResultsCacheImpl implements ResolutionResultsCache {
return null; return null;
} }
@Nullable
@Override
public ResolvedCallWithTrace<? extends CallableDescriptor> getCallForArgument(@Nullable JetExpression expression) {
return getValueTryingAllCallTypes(expression, RESOLVED_CALL_FOR_ARGUMENT);
}
@NotNull @NotNull
public static ResolutionResultsCache create() { public static ResolutionResultsCache create() {
return new ResolutionResultsCacheImpl(); return new ResolutionResultsCacheImpl();
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.CallKey;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; 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.lang.resolve.calls.results.OverloadResolutionResultsImpl;
public class TemporaryResolutionResultsCache implements ResolutionResultsCache { public class TemporaryResolutionResultsCache implements ResolutionResultsCache {
@@ -76,9 +77,10 @@ public class TemporaryResolutionResultsCache implements ResolutionResultsCache {
@Override @Override
public <D extends CallableDescriptor> void recordDeferredComputationForCall( public <D extends CallableDescriptor> void recordDeferredComputationForCall(
@NotNull CallKey callKey, @NotNull CallKey callKey,
@NotNull ResolvedCallWithTrace<D> resolvedCall,
@NotNull CallCandidateResolutionContext<D> deferredComputation @NotNull CallCandidateResolutionContext<D> deferredComputation
) { ) {
innerCache.recordDeferredComputationForCall(callKey, deferredComputation); innerCache.recordDeferredComputationForCall(callKey, resolvedCall, deferredComputation);
} }
@Nullable @Nullable
@@ -91,6 +93,16 @@ public class TemporaryResolutionResultsCache implements ResolutionResultsCache {
return parentCache.getDeferredComputation(expression); return parentCache.getDeferredComputation(expression);
} }
@Nullable
@Override
public ResolvedCallWithTrace<? extends CallableDescriptor> getCallForArgument(@Nullable JetExpression expression) {
ResolvedCallWithTrace<? extends CallableDescriptor> resolvedCall = innerCache.getCallForArgument(expression);
if (resolvedCall != null) {
return resolvedCall;
}
return parentCache.getCallForArgument(expression);
}
public void commit() { public void commit() {
if (parentCache instanceof ResolutionResultsCacheImpl) { if (parentCache instanceof ResolutionResultsCacheImpl) {
((ResolutionResultsCacheImpl) parentCache).addData(innerCache); ((ResolutionResultsCacheImpl) parentCache).addData(innerCache);