TraversalOrder enum instead of boolean flag
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user