made PseudocodeVariableDataCollector know about variables

(not about abstract data)
This commit is contained in:
Svetlana Isakova
2014-02-24 14:16:53 +04:00
parent b79df51dab
commit 4a4e237539
2 changed files with 41 additions and 47 deletions
@@ -23,12 +23,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.Instruction;
import org.jetbrains.jet.lang.cfg.pseudocode.LocalFunctionDeclarationInstruction;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
public class PseudocodeVariableDataCollector extends PseudocodeTraverser {
private final BindingContext bindingContext;
@@ -37,39 +35,37 @@ public class PseudocodeVariableDataCollector extends PseudocodeTraverser {
bindingContext = context;
}
public <D> Map<Instruction, Edges<D>> collectData(
public <D> Map<Instruction, Edges<Map<VariableDescriptor, D>>> collectData(
@NotNull Pseudocode pseudocode,
@NotNull TraversalOrder traversalOrder,
@NotNull LookInsideStrategy lookInside,
@NotNull D initialDataValue,
@NotNull D initialDataValueForEnterInstruction,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy
@NotNull InstructionDataMergeStrategy<Map<VariableDescriptor, D>> instructionDataMergeStrategy
) {
Map<Instruction, Edges<D>> edgesMap = Maps.newLinkedHashMap();
initializeEdgesMap(pseudocode, lookInside, edgesMap, initialDataValue);
edgesMap.put(getStartInstruction(pseudocode, traversalOrder), Edges.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
Map<VariableDescriptor, D> initialDataValue = Collections.emptyMap();
Map<Instruction, Edges<Map<VariableDescriptor, D>>> edgesMap = Maps.newLinkedHashMap();
initializeEdgesMap(pseudocode, edgesMap, initialDataValue);
edgesMap.put(getStartInstruction(pseudocode, traversalOrder), Edges.create(initialDataValue, initialDataValue));
boolean[] changed = new boolean[1];
changed[0] = true;
while (changed[0]) {
changed[0] = false;
collectDataFromSubgraph(pseudocode, traversalOrder, lookInside, edgesMap, instructionDataMergeStrategy,
Collections.<Instruction>emptyList(), changed, false);
collectDataFromSubgraph(pseudocode, traversalOrder, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS, edgesMap,
instructionDataMergeStrategy, Collections.<Instruction>emptyList(), changed, false);
}
return edgesMap;
}
private <D> void initializeEdgesMap(
@NotNull Pseudocode pseudocode, LookInsideStrategy lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull D initialDataValue) {
private static <M> void initializeEdgesMap(
@NotNull Pseudocode pseudocode,
@NotNull Map<Instruction, Edges<M>> edgesMap,
@NotNull M initialDataValue
) {
List<Instruction> instructions = pseudocode.getInstructions();
Edges<D> initialEdge = Edges.create(initialDataValue, initialDataValue);
Edges<M> initialEdge = Edges.create(initialDataValue, initialDataValue);
for (Instruction instruction : instructions) {
edgesMap.put(instruction, initialEdge);
if (shouldLookInside(instruction, lookInside)) {
initializeEdgesMap(((LocalFunctionDeclarationInstruction) instruction).getBody(), lookInside, edgesMap, initialDataValue);
if (shouldLookInside(instruction, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS)) {
initializeEdgesMap(((LocalFunctionDeclarationInstruction) instruction).getBody(), edgesMap, initialDataValue);
}
}
}
@@ -78,8 +74,8 @@ public class PseudocodeVariableDataCollector extends PseudocodeTraverser {
@NotNull Pseudocode pseudocode,
@NotNull TraversalOrder traversalOrder,
@NotNull LookInsideStrategy lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy,
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, D>>> edgesMap,
@NotNull InstructionDataMergeStrategy<Map<VariableDescriptor, D>> instructionDataMergeStrategy,
@NotNull Collection<Instruction> previousSubGraphInstructions,
boolean[] changed,
boolean isLocal
@@ -109,25 +105,25 @@ public class PseudocodeVariableDataCollector extends PseudocodeTraverser {
previousInstructions,
changed, true);
Instruction lastInstruction = getLastInstruction(subroutinePseudocode, traversalOrder);
Edges<D> previousValue = edgesMap.get(instruction);
Edges<D> newValue = edgesMap.get(lastInstruction);
Edges<Map<VariableDescriptor, D>> previousValue = edgesMap.get(instruction);
Edges<Map<VariableDescriptor, D>> newValue = edgesMap.get(lastInstruction);
if (!previousValue.equals(newValue)) {
changed[0] = true;
edgesMap.put(instruction, newValue);
}
continue;
}
Edges<D> previousDataValue = edgesMap.get(instruction);
Edges<Map<VariableDescriptor, D>> previousDataValue = edgesMap.get(instruction);
Collection<D> incomingEdgesData = Sets.newHashSet();
Collection<Map<VariableDescriptor, D>> incomingEdgesData = Sets.newHashSet();
for (Instruction previousInstruction : allPreviousInstructions) {
Edges<D> previousData = edgesMap.get(previousInstruction);
Edges<Map<VariableDescriptor, D>> previousData = edgesMap.get(previousInstruction);
if (previousData != null) {
incomingEdgesData.add(previousData.out);
}
}
Edges<D> mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData);
Edges<Map<VariableDescriptor, D>> mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData);
if (!mergedData.equals(previousDataValue)) {
changed[0] = true;
edgesMap.put(instruction, mergedData);
@@ -20,16 +20,21 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.Edges;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.InstructionAnalyzeStrategy;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.InstructionDataMergeStrategy;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.BACKWARD;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.FORWARD;
@@ -129,9 +134,9 @@ public class PseudocodeVariablesData {
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers(@NotNull Pseudocode pseudocode) {
final Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode, true);
Map<VariableDescriptor, VariableInitState> initialMap = Collections.emptyMap();
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>> instructionDataMergeStrategy =
return new PseudocodeVariableDataCollector(bindingContext).collectData(
pseudocode, FORWARD,
new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
@Override
public Edges<Map<VariableDescriptor, VariableInitState>> execute(
@@ -145,11 +150,7 @@ public class PseudocodeVariablesData {
addVariableInitStateFromCurrentInstructionIfAny(instruction, enterInstructionData, declaredVariables);
return Edges.create(enterInstructionData, exitInstructionData);
}
};
return new PseudocodeVariableDataCollector(bindingContext).collectData(
pseudocode, FORWARD, ANALYSE_LOCAL_DECLARATIONS,
initialMap, initialMap, instructionDataMergeStrategy);
});
}
public static VariableInitState getDefaultValueForInitializers(
@@ -228,8 +229,8 @@ public class PseudocodeVariablesData {
@NotNull
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() {
Map<VariableDescriptor, VariableUseState> sinkInstructionData = Maps.newHashMap();
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>> collectVariableUseStatusStrategy =
return new PseudocodeVariableDataCollector(bindingContext).collectData(
pseudocode, BACKWARD,
new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() {
@Override
public Edges<Map<VariableDescriptor, VariableUseState>> execute(
@@ -272,10 +273,7 @@ public class PseudocodeVariablesData {
}
return Edges.create(enterResult, exitResult);
}
};
return new PseudocodeVariableDataCollector(bindingContext).collectData(
pseudocode, BACKWARD, ANALYSE_LOCAL_DECLARATIONS, Collections.<VariableDescriptor, VariableUseState>emptyMap(),
sinkInstructionData, collectVariableUseStatusStrategy);
});
}
public static class VariableInitState {