reuse control flow with exact parameters only (IDEA-127338)

This commit is contained in:
Anna Kozlova
2014-08-22 15:35:30 +04:00
parent 3f3255fe5e
commit fcac68054e
2 changed files with 22 additions and 9 deletions
@@ -204,7 +204,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
ProgressIndicatorProvider.checkCanceled();
ControlFlowSubRange subRange = entry.getValue();
PsiElement element = entry.getKey();
myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfCondition, myPolicy);
myControlFlowFactory.registerSubRange(element, subRange, myEvaluateConstantIfCondition, myEnabledShortCircuit, myPolicy);
}
}
@@ -62,19 +62,29 @@ public class ControlFlowFactory {
cachedFlows.clear();
}
@Deprecated
public void registerSubRange(final PsiElement codeFragment, final ControlFlowSubRange flow, final boolean evaluateConstantIfConfition,
final ControlFlowPolicy policy) {
registerControlFlow(codeFragment, flow, evaluateConstantIfConfition, policy);
registerSubRange(codeFragment, flow, evaluateConstantIfConfition, true, policy);
}
public void registerSubRange(final PsiElement codeFragment,
final ControlFlowSubRange flow,
final boolean evaluateConstantIfConfition,
boolean enableShortCircuit, final ControlFlowPolicy policy) {
registerControlFlow(codeFragment, flow, evaluateConstantIfConfition, enableShortCircuit, policy);
}
private static class ControlFlowContext {
private final ControlFlowPolicy policy;
private final boolean evaluateConstantIfCondition;
private final boolean enableShortCircuit;
private final long modificationCount;
private final ControlFlow controlFlow;
private ControlFlowContext(boolean evaluateConstantIfCondition, @NotNull ControlFlowPolicy policy, long modificationCount, @NotNull ControlFlow controlFlow) {
private ControlFlowContext(boolean evaluateConstantIfCondition, boolean enableShortCircuit, @NotNull ControlFlowPolicy policy, long modificationCount, @NotNull ControlFlow controlFlow) {
this.evaluateConstantIfCondition = evaluateConstantIfCondition;
this.enableShortCircuit = enableShortCircuit;
this.policy = policy;
this.modificationCount = modificationCount;
this.controlFlow = controlFlow;
@@ -96,9 +106,10 @@ public class ControlFlowFactory {
return result;
}
public boolean isFor(@NotNull ControlFlowPolicy policy, final boolean evaluateConstantIfCondition, long modificationCount) {
public boolean isFor(@NotNull ControlFlowPolicy policy, final boolean evaluateConstantIfCondition, final boolean enableShortCircuit, long modificationCount) {
if (modificationCount != this.modificationCount) return false;
if (!policy.equals(this.policy)) return false;
if (enableShortCircuit != this.enableShortCircuit) return false;
// optimization: when no constant condition were computed, both control flows are the same
if (!controlFlow.isConstantConditionOccurred()) return true;
@@ -107,7 +118,7 @@ public class ControlFlowFactory {
}
private boolean isFor(@NotNull ControlFlowContext that) {
return isFor(that.policy, that.evaluateConstantIfCondition, that.modificationCount);
return isFor(that.policy, that.evaluateConstantIfCondition, that.enableShortCircuit, that.modificationCount);
}
}
@@ -129,28 +140,30 @@ public class ControlFlowFactory {
final long modificationCount = element.getManager().getModificationTracker().getModificationCount();
ConcurrentList<ControlFlowContext> cached = getOrCreateCachedFlowsForElement(element);
for (ControlFlowContext context : cached) {
if (context.isFor(policy, evaluateConstantIfCondition,modificationCount)) return context.controlFlow;
if (context.isFor(policy, evaluateConstantIfCondition, enableShortCircuit, modificationCount)) return context.controlFlow;
}
ControlFlow controlFlow = new ControlFlowAnalyzer(element, policy, enableShortCircuit, evaluateConstantIfCondition).buildControlFlow();
ControlFlowContext context = createContext(evaluateConstantIfCondition, policy, controlFlow, modificationCount);
ControlFlowContext context = createContext(evaluateConstantIfCondition, enableShortCircuit, policy, controlFlow, modificationCount);
cached.addIfAbsent(context);
return controlFlow;
}
@NotNull
private static ControlFlowContext createContext(final boolean evaluateConstantIfCondition,
boolean enableShortCircuit,
@NotNull ControlFlowPolicy policy,
@NotNull ControlFlow controlFlow,
final long modificationCount) {
return new ControlFlowContext(evaluateConstantIfCondition, policy, modificationCount,controlFlow);
return new ControlFlowContext(evaluateConstantIfCondition, enableShortCircuit, policy, modificationCount,controlFlow);
}
private void registerControlFlow(@NotNull PsiElement element,
@NotNull ControlFlow flow,
boolean evaluateConstantIfCondition,
boolean enableShortCircuit,
@NotNull ControlFlowPolicy policy) {
final long modificationCount = element.getManager().getModificationTracker().getModificationCount();
ControlFlowContext controlFlowContext = createContext(evaluateConstantIfCondition, policy, flow, modificationCount);
ControlFlowContext controlFlowContext = createContext(evaluateConstantIfCondition, enableShortCircuit, policy, flow, modificationCount);
ConcurrentList<ControlFlowContext> cached = getOrCreateCachedFlowsForElement(element);
cached.addIfAbsent(controlFlowContext);