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