TraversalOrder enum instead of boolean flag

This commit is contained in:
Svetlana Isakova
2012-12-13 17:58:00 +04:00
parent 7a03c85549
commit e91805a593
3 changed files with 62 additions and 54 deletions
@@ -44,6 +44,8 @@ import org.jetbrains.jet.plugin.JetMainDetector;
import java.util.*;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.BACKWARD;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.FORWARD;
import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
@@ -196,7 +198,7 @@ public class JetFlowInformationProvider {
final Map<Instruction, AbstractDiagnosticFactory> reportedDiagnosticMap = Maps.newHashMap();
PseudocodeTraverser.traverseForward(pseudocode, true, initializers, new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState>>() {
PseudocodeTraverser.traverse(pseudocode, FORWARD, true, initializers, new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState>>() {
@Override
public void execute(@NotNull Instruction instruction,
@Nullable Map<VariableDescriptor, VariableInitState> in,
@@ -251,7 +253,8 @@ public class JetFlowInformationProvider {
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(ctxt.variableDescriptor)) {
varWithUninitializedErrorGenerated.add(ctxt.variableDescriptor);
if (ctxt.variableDescriptor instanceof ValueParameterDescriptor) {
report(Errors.UNINITIALIZED_PARAMETER.on((JetSimpleNameExpression) element, (ValueParameterDescriptor) ctxt.variableDescriptor), ctxt);
report(Errors.UNINITIALIZED_PARAMETER.on((JetSimpleNameExpression) element,
(ValueParameterDescriptor) ctxt.variableDescriptor), ctxt);
}
else {
report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, ctxt.variableDescriptor), ctxt);
@@ -502,7 +505,7 @@ public class JetFlowInformationProvider {
}
}
};
PseudocodeTraverser.traverseBackward(pseudocode, true, variableStatusData, variableStatusAnalyzeStrategy);
PseudocodeTraverser.traverse(pseudocode, BACKWARD, true, variableStatusData, variableStatusAnalyzeStrategy);
}
////////////////////////////////////////////////////////////////////////////////
@@ -511,8 +514,8 @@ public class JetFlowInformationProvider {
public void markUnusedLiteralsInBlock() {
assert pseudocode != null;
final Map<Instruction, AbstractDiagnosticFactory> reportedDiagnosticMap = Maps.newHashMap();
PseudocodeTraverser.traverseForward(
pseudocode, new InstructionAnalyzeStrategy() {
PseudocodeTraverser.traverse(
pseudocode, FORWARD, new InstructionAnalyzeStrategy() {
@Override
public void execute(@NotNull Instruction instruction) {
if (!(instruction instanceof ReadValueInstruction)) return;
@@ -28,29 +28,57 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.FORWARD;
/**
* @author svtk
*/
public class PseudocodeTraverser {
public static enum TraversalOrder {
FORWARD,
BACKWARD;
}
@NotNull
private static Instruction getStartInstruction(@NotNull Pseudocode pseudocode, boolean directOrder) {
return directOrder ? pseudocode.getEnterInstruction() : pseudocode.getSinkInstruction();
private static Instruction getStartInstruction(@NotNull Pseudocode pseudocode, @NotNull TraversalOrder traversalOrder) {
return traversalOrder == FORWARD ? pseudocode.getEnterInstruction() : pseudocode.getSinkInstruction();
}
@NotNull
private static Instruction getLastInstruction(@NotNull Pseudocode pseudocode, @NotNull TraversalOrder traversalOrder) {
return traversalOrder == FORWARD ? pseudocode.getSinkInstruction() : pseudocode.getEnterInstruction();
}
@NotNull
private static List<Instruction> getInstructions(@NotNull Pseudocode pseudocode, @NotNull TraversalOrder traversalOrder) {
return traversalOrder == FORWARD ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
}
@NotNull
private static Collection<Instruction> getPreviousInstruction(@NotNull Instruction instruction, @NotNull TraversalOrder traversalOrder) {
return traversalOrder == FORWARD ? instruction.getPreviousInstructions() : instruction.getNextInstructions();
}
private static boolean isStartInstruction(@NotNull Instruction instruction, @NotNull TraversalOrder traversalOrder) {
return traversalOrder == FORWARD ? instruction instanceof SubroutineEnterInstruction
: instruction instanceof SubroutineSinkInstruction;
}
public static <D> Map<Instruction, Edges<D>> collectData(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
@NotNull Pseudocode pseudocode, TraversalOrder traversalOrder, boolean lookInside,
@NotNull D initialDataValue, @NotNull D initialDataValueForEnterInstruction,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy) {
Map<Instruction, Edges<D>> edgesMap = Maps.newLinkedHashMap();
initializeEdgesMap(pseudocode, lookInside, edgesMap, initialDataValue);
edgesMap.put(getStartInstruction(pseudocode, directOrder), Edges.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
edgesMap.put(getStartInstruction(pseudocode, traversalOrder), Edges.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
boolean[] changed = new boolean[1];
changed[0] = true;
while (changed[0]) {
changed[0] = false;
collectDataFromSubgraph(pseudocode, directOrder, lookInside, edgesMap, instructionDataMergeStrategy,
collectDataFromSubgraph(pseudocode, traversalOrder, lookInside, edgesMap, instructionDataMergeStrategy,
Collections.<Instruction>emptyList(), changed, false);
}
return edgesMap;
@@ -71,21 +99,21 @@ public class PseudocodeTraverser {
}
private static <D> void collectDataFromSubgraph(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
@NotNull Pseudocode pseudocode, TraversalOrder traversalOrder, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy,
@NotNull Collection<Instruction> previousSubGraphInstructions,
boolean[] changed, boolean isLocal) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
Instruction startInstruction = getStartInstruction(pseudocode, directOrder);
List<Instruction> instructions = getInstructions(pseudocode, traversalOrder);
Instruction startInstruction = getStartInstruction(pseudocode, traversalOrder);
for (Instruction instruction : instructions) {
boolean isStart = directOrder ? instruction instanceof SubroutineEnterInstruction : instruction instanceof SubroutineSinkInstruction;
boolean isStart = isStartInstruction(instruction, traversalOrder);
if (!isLocal && isStart) continue;
Collection<Instruction> allPreviousInstructions;
Collection<Instruction> previousInstructions = directOrder ? instruction.getPreviousInstructions() : instruction.getNextInstructions();
Collection<Instruction> previousInstructions = getPreviousInstruction(instruction, traversalOrder);
if (instruction == startInstruction && !previousSubGraphInstructions.isEmpty()) {
allPreviousInstructions = Lists.newArrayList(previousInstructions);
@@ -97,10 +125,10 @@ public class PseudocodeTraverser {
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
collectDataFromSubgraph(subroutinePseudocode, directOrder, lookInside, edgesMap, instructionDataMergeStrategy,
collectDataFromSubgraph(subroutinePseudocode, traversalOrder, lookInside, edgesMap, instructionDataMergeStrategy,
previousInstructions,
changed, true);
Instruction lastInstruction = directOrder ? subroutinePseudocode.getSinkInstruction() : subroutinePseudocode.getEnterInstruction();
Instruction lastInstruction = getLastInstruction(subroutinePseudocode, traversalOrder);
Edges<D> previousValue = edgesMap.get(instruction);
Edges<D> newValue = edgesMap.get(lastInstruction);
if (!previousValue.equals(newValue)) {
@@ -127,54 +155,28 @@ public class PseudocodeTraverser {
}
}
public static void traverseForward(
@NotNull Pseudocode pseudocode,
@NotNull InstructionAnalyzeStrategy instructionAnalyzeStrategy) {
traverse(pseudocode, true, instructionAnalyzeStrategy);
}
public static void traverseBackward(
@NotNull Pseudocode pseudocode,
@NotNull InstructionAnalyzeStrategy instructionAnalyzeStrategy) {
traverse(pseudocode, false, instructionAnalyzeStrategy);
}
private static void traverse(
@NotNull Pseudocode pseudocode, boolean directOrder,
public static void traverse(
@NotNull Pseudocode pseudocode, TraversalOrder traversalOrder,
InstructionAnalyzeStrategy instructionAnalyzeStrategy) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
List<Instruction> instructions = getInstructions(pseudocode, traversalOrder);
for (Instruction instruction : instructions) {
if (instruction instanceof LocalDeclarationInstruction) {
traverse(((LocalDeclarationInstruction) instruction).getBody(), directOrder, instructionAnalyzeStrategy);
traverse(((LocalDeclarationInstruction) instruction).getBody(), traversalOrder, instructionAnalyzeStrategy);
}
instructionAnalyzeStrategy.execute(instruction);
}
}
public static <D> void traverseForward(
@NotNull Pseudocode pseudocode, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
traverse(pseudocode, true, lookInside, edgesMap, instructionDataAnalyzeStrategy);
}
public static <D> void traverseBackward(
@NotNull Pseudocode pseudocode, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
traverse(pseudocode, false, lookInside, edgesMap, instructionDataAnalyzeStrategy);
}
private static <D> void traverse(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
public static <D> void traverse(
@NotNull Pseudocode pseudocode, TraversalOrder traversalOrder, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
List<Instruction> instructions = getInstructions(pseudocode, traversalOrder);
for (Instruction instruction : instructions) {
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
traverse(((LocalDeclarationInstruction) instruction).getBody(), directOrder, lookInside, edgesMap,
traverse(((LocalDeclarationInstruction) instruction).getBody(), traversalOrder, lookInside, edgesMap,
instructionDataAnalyzeStrategy);
}
Edges<D> edges = edgesMap.get(instruction);
@@ -33,6 +33,9 @@ import java.util.Collections;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.BACKWARD;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.FORWARD;
/**
* @author svtk
*/
@@ -61,7 +64,7 @@ public class PseudocodeVariablesData {
Set<VariableDescriptor> usedVariables = usedVariablesForDeclaration.get(pseudocode);
if (usedVariables == null) {
final Set<VariableDescriptor> result = Sets.newHashSet();
PseudocodeTraverser.traverseForward(pseudocode, new InstructionAnalyzeStrategy() {
PseudocodeTraverser.traverse(pseudocode, FORWARD, new InstructionAnalyzeStrategy() {
@Override
public void execute(@NotNull Instruction instruction) {
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, false,
@@ -138,7 +141,7 @@ public class PseudocodeVariablesData {
usedVariables, declaredVariables);
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap = PseudocodeTraverser.collectData(
pseudocode, /* directOrder = */ true, /* lookInside = */ false,
pseudocode, FORWARD, /* lookInside = */ false,
initialMap, initialMapForStartInstruction, new PseudocodeTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
@Override
public Edges<Map<VariableDescriptor, VariableInitState>> execute(
@@ -289,7 +292,7 @@ public class PseudocodeVariablesData {
return Edges.create(enterResult, exitResult);
}
};
variableStatusMap = PseudocodeTraverser.collectData(pseudocode, false, true,
variableStatusMap = PseudocodeTraverser.collectData(pseudocode, BACKWARD, true,
Collections.<VariableDescriptor, VariableUseState>emptyMap(),
sinkInstructionData, collectVariableUseStatusStrategy);
}