removed initial map for start instruction

This commit is contained in:
Svetlana Isakova
2014-02-23 13:25:26 +04:00
parent b1a12608b8
commit c2b10dc274
2 changed files with 55 additions and 69 deletions
@@ -268,7 +268,7 @@ public class JetFlowInformationProvider {
@Nullable Map<VariableDescriptor, VariableInitState> in, @Nullable Map<VariableDescriptor, VariableInitState> in,
@Nullable Map<VariableDescriptor, VariableInitState> out) { @Nullable Map<VariableDescriptor, VariableInitState> out) {
assert in != null && out != null; assert in != null && out != null;
VariableInitContext ctxt = new VariableInitContext(instruction, reportedDiagnosticMap, in, out); VariableInitContext ctxt = new VariableInitContext(instruction, reportedDiagnosticMap, in, out, declaredVariables);
if (ctxt.variableDescriptor == null) return; if (ctxt.variableDescriptor == null) return;
if (instruction instanceof ReadValueInstruction) { if (instruction instanceof ReadValueInstruction) {
JetElement element = ((ReadValueInstruction) instruction).getElement(); JetElement element = ((ReadValueInstruction) instruction).getElement();
@@ -843,11 +843,23 @@ public class JetFlowInformationProvider {
@NotNull Instruction instruction, @NotNull Instruction instruction,
@NotNull Map<Instruction, DiagnosticFactory> map, @NotNull Map<Instruction, DiagnosticFactory> map,
@NotNull Map<VariableDescriptor, VariableInitState> in, @NotNull Map<VariableDescriptor, VariableInitState> in,
@NotNull Map<VariableDescriptor, VariableInitState> out @NotNull Map<VariableDescriptor, VariableInitState> out,
@NotNull Set<VariableDescriptor> declaredVariables
) { ) {
super(instruction, map); super(instruction, map);
enterInitState = variableDescriptor != null ? in.get(variableDescriptor) : null; enterInitState = initialize(variableDescriptor, declaredVariables, in);
exitInitState = variableDescriptor != null ? out.get(variableDescriptor) : null; exitInitState = initialize(variableDescriptor, declaredVariables, out);
}
private VariableInitState initialize(
VariableDescriptor variableDescriptor,
Set<VariableDescriptor> declaredVariables,
Map<VariableDescriptor, VariableInitState> map
) {
if (variableDescriptor == null) return null;
VariableInitState state = map.get(variableDescriptor);
if (state != null) return state;
return PseudocodeVariablesData.getDefaultValueForInitializers(declaredVariables, variableDescriptor);
} }
} }
@@ -22,19 +22,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*; import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
import org.jetbrains.jet.lang.cfg.pseudocode.*; import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.Collection; import java.util.*;
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.LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.LookInsideStrategy.SKIP_LOCAL_DECLARATIONS;
import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.TraversalOrder.BACKWARD; 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.PseudocodeTraverser.TraversalOrder.FORWARD;
@@ -133,66 +128,43 @@ public class PseudocodeVariablesData {
@NotNull @NotNull
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers(@NotNull Pseudocode pseudocode) { private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers(@NotNull Pseudocode pseudocode) {
Set<VariableDescriptor> usedVariables = getUsedVariables(pseudocode); final Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode, true);
Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode, false);
Map<VariableDescriptor, VariableInitState> initialMap = Collections.emptyMap(); Map<VariableDescriptor, VariableInitState> initialMap = Collections.emptyMap();
Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = prepareInitializersMapForStartInstruction(
usedVariables, declaredVariables);
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap = PseudocodeTraverser.collectData( InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>> instructionDataMergeStrategy =
pseudocode, FORWARD, SKIP_LOCAL_DECLARATIONS, new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
initialMap, initialMapForStartInstruction, new PseudocodeTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() { @Override
@Override public Edges<Map<VariableDescriptor, VariableInitState>> execute(
public Edges<Map<VariableDescriptor, VariableInitState>> execute( @NotNull Instruction instruction,
@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) { @NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData
) {
Map<VariableDescriptor, VariableInitState> enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData); Map<VariableDescriptor, VariableInitState> enterInstructionData =
Map<VariableDescriptor, VariableInitState> exitInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData);
addVariableInitStateFromCurrentInstructionIfAny(instruction, enterInstructionData); Map<VariableDescriptor, VariableInitState> exitInstructionData =
return Edges.create(enterInstructionData, exitInstructionData); addVariableInitStateFromCurrentInstructionIfAny(instruction, enterInstructionData, declaredVariables);
} return Edges.create(enterInstructionData, exitInstructionData);
}); }
};
return PseudocodeTraverser.collectData(
for (LocalFunctionDeclarationInstruction localFunctionDeclarationInstruction : pseudocode.getLocalDeclarations()) { pseudocode, FORWARD, ANALYSE_LOCAL_DECLARATIONS,
Pseudocode localPseudocode = localFunctionDeclarationInstruction.getBody(); initialMap, initialMap, instructionDataMergeStrategy);
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> initializersForLocalDeclaration = getVariableInitializers(localPseudocode);
for (Instruction instruction : initializersForLocalDeclaration.keySet()) {
//todo
if (!variableInitializersMap.containsKey(instruction)) {
variableInitializersMap.put(instruction, initializersForLocalDeclaration.get(instruction));
}
}
variableInitializersMap.putAll(initializersForLocalDeclaration);
}
return variableInitializersMap;
} }
@NotNull public static VariableInitState getDefaultValueForInitializers(
private static Map<VariableDescriptor, VariableInitState> prepareInitializersMapForStartInstruction( @NotNull Set<VariableDescriptor> declaredVariables,
@NotNull Collection<VariableDescriptor> usedVariables, @NotNull VariableDescriptor variable
@NotNull Collection<VariableDescriptor> declaredVariables) { ) {
//todo: think of replacing it with "MapWithDefaultValue"
Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = Maps.newHashMap(); boolean isInitialized = !declaredVariables.contains(variable);
VariableInitState initializedForExternalVariable = VariableInitState.create(true); return VariableInitState.create(isInitialized);
VariableInitState notInitializedForDeclaredVariable = VariableInitState.create(false);
for (VariableDescriptor variable : usedVariables) {
if (declaredVariables.contains(variable)) {
initialMapForStartInstruction.put(variable, notInitializedForDeclaredVariable);
}
else {
initialMapForStartInstruction.put(variable, initializedForExternalVariable);
}
}
return initialMapForStartInstruction;
} }
@NotNull @NotNull
private static Map<VariableDescriptor, VariableInitState> mergeIncomingEdgesDataForInitializers( private static Map<VariableDescriptor, VariableInitState> mergeIncomingEdgesDataForInitializers(
@NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) { @NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData
) {
Set<VariableDescriptor> variablesInScope = Sets.newHashSet(); Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) { for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
variablesInScope.addAll(edgeData.keySet()); variablesInScope.addAll(edgeData.keySet());
@@ -220,8 +192,10 @@ public class PseudocodeVariablesData {
@NotNull @NotNull
private Map<VariableDescriptor, VariableInitState> addVariableInitStateFromCurrentInstructionIfAny( private Map<VariableDescriptor, VariableInitState> addVariableInitStateFromCurrentInstructionIfAny(
@NotNull Instruction instruction, @NotNull Map<VariableDescriptor, VariableInitState> enterInstructionData) { @NotNull Instruction instruction,
@NotNull Map<VariableDescriptor, VariableInitState> enterInstructionData,
@NotNull Set<VariableDescriptor> declaredVariables
) {
if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) { if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) {
return enterInstructionData; return enterInstructionData;
} }
@@ -238,6 +212,9 @@ public class PseudocodeVariablesData {
} }
else { // instruction instanceof VariableDeclarationInstruction else { // instruction instanceof VariableDeclarationInstruction
VariableInitState enterInitState = enterInstructionData.get(variable); VariableInitState enterInitState = enterInstructionData.get(variable);
if (enterInitState == null) {
enterInitState = getDefaultValueForInitializers(declaredVariables, variable);
}
if (enterInitState == null || !enterInitState.isInitialized || !enterInitState.isDeclared) { if (enterInitState == null || !enterInitState.isInitialized || !enterInitState.isDeclared) {
boolean isInitialized = enterInitState != null && enterInitState.isInitialized; boolean isInitialized = enterInitState != null && enterInitState.isInitialized;
VariableInitState variableDeclarationInfo = VariableInitState.create(isInitialized, true); VariableInitState variableDeclarationInfo = VariableInitState.create(isInitialized, true);
@@ -252,9 +229,6 @@ public class PseudocodeVariablesData {
@NotNull @NotNull
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() { public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() {
Map<VariableDescriptor, VariableUseState> sinkInstructionData = Maps.newHashMap(); Map<VariableDescriptor, VariableUseState> sinkInstructionData = Maps.newHashMap();
for (VariableDescriptor usedVariable : getUsedVariables(pseudocode)) {
sinkInstructionData.put(usedVariable, VariableUseState.UNUSED);
}
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>> collectVariableUseStatusStrategy = InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>> collectVariableUseStatusStrategy =
new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() { new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() {
@Override @Override
@@ -299,9 +273,9 @@ public class PseudocodeVariablesData {
return Edges.create(enterResult, exitResult); return Edges.create(enterResult, exitResult);
} }
}; };
return PseudocodeTraverser.collectData(pseudocode, BACKWARD, ANALYSE_LOCAL_DECLARATIONS, return PseudocodeTraverser.collectData(
Collections.<VariableDescriptor, VariableUseState>emptyMap(), pseudocode, BACKWARD, ANALYSE_LOCAL_DECLARATIONS, Collections.<VariableDescriptor, VariableUseState>emptyMap(),
sinkInstructionData, collectVariableUseStatusStrategy); sinkInstructionData, collectVariableUseStatusStrategy);
} }
public static class VariableInitState { public static class VariableInitState {