Refactoring: VariableInitState --> VariableControlFlowState
This commit is contained in:
@@ -28,7 +28,7 @@ import kotlin.jvm.functions.Function3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableInitState;
|
||||
import org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableControlFlowState;
|
||||
import org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableUseState;
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue;
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode;
|
||||
@@ -302,7 +302,7 @@ public class JetFlowInformationProvider {
|
||||
final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
|
||||
|
||||
PseudocodeVariablesData pseudocodeVariablesData = getPseudocodeVariablesData();
|
||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> initializers =
|
||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> initializers =
|
||||
pseudocodeVariablesData.getVariableInitializers();
|
||||
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode, true);
|
||||
final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariablesData.getLexicalScopeVariableInfo();
|
||||
@@ -311,12 +311,12 @@ public class JetFlowInformationProvider {
|
||||
|
||||
PseudocodeTraverserPackage.traverse(
|
||||
pseudocode, FORWARD, initializers,
|
||||
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableInitState>>() {
|
||||
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableControlFlowState>>() {
|
||||
@Override
|
||||
public void execute(
|
||||
@NotNull Instruction instruction,
|
||||
@Nullable Map<VariableDescriptor, VariableInitState> in,
|
||||
@Nullable Map<VariableDescriptor, VariableInitState> out
|
||||
@Nullable Map<VariableDescriptor, VariableControlFlowState> in,
|
||||
@Nullable Map<VariableDescriptor, VariableControlFlowState> out
|
||||
) {
|
||||
assert in != null && out != null;
|
||||
VariableInitContext ctxt =
|
||||
@@ -356,7 +356,7 @@ public class JetFlowInformationProvider {
|
||||
public void recordInitializedVariables() {
|
||||
PseudocodeVariablesData pseudocodeVariablesData = getPseudocodeVariablesData();
|
||||
Pseudocode pseudocode = pseudocodeVariablesData.getPseudocode();
|
||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> initializers =
|
||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> initializers =
|
||||
pseudocodeVariablesData.getVariableInitializers();
|
||||
recordInitializedVariables(pseudocode, initializers);
|
||||
for (LocalFunctionDeclarationInstruction instruction : pseudocode.getLocalDeclarations()) {
|
||||
@@ -584,14 +584,14 @@ public class JetFlowInformationProvider {
|
||||
|
||||
private void recordInitializedVariables(
|
||||
@NotNull Pseudocode pseudocode,
|
||||
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState>>> initializersMap
|
||||
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> initializersMap
|
||||
) {
|
||||
Edges<Map<VariableDescriptor, VariableInitState>> initializers = initializersMap.get(pseudocode.getExitInstruction());
|
||||
Edges<Map<VariableDescriptor, VariableControlFlowState>> initializers = initializersMap.get(pseudocode.getExitInstruction());
|
||||
Set<VariableDescriptor> declaredVariables = getPseudocodeVariablesData().getDeclaredVariables(pseudocode, false);
|
||||
for (VariableDescriptor variable : declaredVariables) {
|
||||
if (variable instanceof PropertyDescriptor) {
|
||||
PseudocodeVariablesData.VariableInitState variableInitState = initializers.getIncoming().get(variable);
|
||||
if (variableInitState != null && variableInitState.definitelyInitialized()) continue;
|
||||
VariableControlFlowState variableControlFlowState = initializers.getIncoming().get(variable);
|
||||
if (variableControlFlowState != null && variableControlFlowState.definitelyInitialized()) continue;
|
||||
trace.record(BindingContext.IS_UNINITIALIZED, (PropertyDescriptor) variable);
|
||||
}
|
||||
}
|
||||
@@ -977,14 +977,14 @@ public class JetFlowInformationProvider {
|
||||
}
|
||||
|
||||
private class VariableInitContext extends VariableContext {
|
||||
final VariableInitState enterInitState;
|
||||
final VariableInitState exitInitState;
|
||||
final VariableControlFlowState enterInitState;
|
||||
final VariableControlFlowState exitInitState;
|
||||
|
||||
private VariableInitContext(
|
||||
@NotNull Instruction instruction,
|
||||
@NotNull Map<Instruction, DiagnosticFactory<?>> map,
|
||||
@NotNull Map<VariableDescriptor, VariableInitState> in,
|
||||
@NotNull Map<VariableDescriptor, VariableInitState> out,
|
||||
@NotNull Map<VariableDescriptor, VariableControlFlowState> in,
|
||||
@NotNull Map<VariableDescriptor, VariableControlFlowState> out,
|
||||
@NotNull LexicalScopeVariableInfo lexicalScopeVariableInfo
|
||||
) {
|
||||
super(instruction, map);
|
||||
@@ -992,13 +992,13 @@ public class JetFlowInformationProvider {
|
||||
exitInitState = initialize(variableDescriptor, lexicalScopeVariableInfo, out);
|
||||
}
|
||||
|
||||
private VariableInitState initialize(
|
||||
private VariableControlFlowState initialize(
|
||||
VariableDescriptor variableDescriptor,
|
||||
LexicalScopeVariableInfo lexicalScopeVariableInfo,
|
||||
Map<VariableDescriptor, VariableInitState> map
|
||||
Map<VariableDescriptor, VariableControlFlowState> map
|
||||
) {
|
||||
if (variableDescriptor == null) return null;
|
||||
VariableInitState state = map.get(variableDescriptor);
|
||||
VariableControlFlowState state = map.get(variableDescriptor);
|
||||
if (state != null) return state;
|
||||
return PseudocodeVariablesData.getDefaultValueForInitializers(variableDescriptor, instruction, lexicalScopeVariableInfo);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class PseudocodeVariablesData {
|
||||
|
||||
private final Map<Pseudocode, Set<VariableDescriptor>> declaredVariablesForDeclaration = Maps.newHashMap();
|
||||
|
||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializers;
|
||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> variableInitializers;
|
||||
|
||||
public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) {
|
||||
this.pseudocode = pseudocode;
|
||||
@@ -112,7 +112,7 @@ public class PseudocodeVariablesData {
|
||||
// variable initializers
|
||||
|
||||
@NotNull
|
||||
public Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers() {
|
||||
public Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> getVariableInitializers() {
|
||||
if (variableInitializers == null) {
|
||||
variableInitializers = computeVariableInitializers();
|
||||
}
|
||||
@@ -121,31 +121,31 @@ public class PseudocodeVariablesData {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> computeVariableInitializers() {
|
||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> computeVariableInitializers() {
|
||||
|
||||
final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariableDataCollector.getLexicalScopeVariableInfo();
|
||||
|
||||
return pseudocodeVariableDataCollector.collectData(
|
||||
FORWARD, /*mergeDataWithLocalDeclarations=*/ false,
|
||||
new InstructionDataMergeStrategy<VariableInitState>() {
|
||||
new InstructionDataMergeStrategy<VariableControlFlowState>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Edges<Map<VariableDescriptor, VariableInitState>> invoke(
|
||||
public Edges<Map<VariableDescriptor, VariableControlFlowState>> invoke(
|
||||
@NotNull Instruction instruction,
|
||||
@NotNull Collection<? extends Map<VariableDescriptor, VariableInitState>> incomingEdgesData
|
||||
@NotNull Collection<? extends Map<VariableDescriptor, VariableControlFlowState>> incomingEdgesData
|
||||
) {
|
||||
|
||||
Map<VariableDescriptor, VariableInitState> enterInstructionData =
|
||||
Map<VariableDescriptor, VariableControlFlowState> enterInstructionData =
|
||||
mergeIncomingEdgesDataForInitializers(incomingEdgesData);
|
||||
Map<VariableDescriptor, VariableInitState> exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
||||
Map<VariableDescriptor, VariableControlFlowState> exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
||||
instruction, enterInstructionData, lexicalScopeVariableInfo);
|
||||
return new Edges<Map<VariableDescriptor, VariableInitState>>(enterInstructionData, exitInstructionData);
|
||||
return new Edges<Map<VariableDescriptor, VariableControlFlowState>>(enterInstructionData, exitInstructionData);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static VariableInitState getDefaultValueForInitializers(
|
||||
public static VariableControlFlowState getDefaultValueForInitializers(
|
||||
@NotNull VariableDescriptor variable,
|
||||
@NotNull Instruction instruction,
|
||||
@NotNull LexicalScopeVariableInfo lexicalScopeVariableInfo
|
||||
@@ -155,24 +155,24 @@ public class PseudocodeVariablesData {
|
||||
boolean declaredOutsideThisDeclaration =
|
||||
declaredIn == null //declared outside this pseudocode
|
||||
|| declaredIn.getLexicalScopeForContainingDeclaration() != instruction.getLexicalScope().getLexicalScopeForContainingDeclaration();
|
||||
return VariableInitState.create(/*initState=*/declaredOutsideThisDeclaration);
|
||||
return VariableControlFlowState.create(/*initState=*/declaredOutsideThisDeclaration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<VariableDescriptor, VariableInitState> mergeIncomingEdgesDataForInitializers(
|
||||
@NotNull Collection<? extends Map<VariableDescriptor, VariableInitState>> incomingEdgesData
|
||||
private static Map<VariableDescriptor, VariableControlFlowState> mergeIncomingEdgesDataForInitializers(
|
||||
@NotNull Collection<? extends Map<VariableDescriptor, VariableControlFlowState>> incomingEdgesData
|
||||
) {
|
||||
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
|
||||
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
|
||||
for (Map<VariableDescriptor, VariableControlFlowState> edgeData : incomingEdgesData) {
|
||||
variablesInScope.addAll(edgeData.keySet());
|
||||
}
|
||||
|
||||
Map<VariableDescriptor, VariableInitState> enterInstructionData = Maps.newHashMap();
|
||||
Map<VariableDescriptor, VariableControlFlowState> enterInstructionData = Maps.newHashMap();
|
||||
for (VariableDescriptor variable : variablesInScope) {
|
||||
TriInitState initState = null;
|
||||
boolean isDeclared = true;
|
||||
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
|
||||
VariableInitState varControlFlowState = edgeData.get(variable);
|
||||
for (Map<VariableDescriptor, VariableControlFlowState> edgeData : incomingEdgesData) {
|
||||
VariableControlFlowState varControlFlowState = edgeData.get(variable);
|
||||
if (varControlFlowState != null) {
|
||||
initState = initState != null ? initState.merge(varControlFlowState.initState) : varControlFlowState.initState;
|
||||
if (!varControlFlowState.isDeclared) {
|
||||
@@ -183,15 +183,15 @@ public class PseudocodeVariablesData {
|
||||
if (initState == null) {
|
||||
throw new AssertionError("An empty set of incoming edges data");
|
||||
}
|
||||
enterInstructionData.put(variable, VariableInitState.create(initState, isDeclared));
|
||||
enterInstructionData.put(variable, VariableControlFlowState.create(initState, isDeclared));
|
||||
}
|
||||
return enterInstructionData;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<VariableDescriptor, VariableInitState> addVariableInitStateFromCurrentInstructionIfAny(
|
||||
private Map<VariableDescriptor, VariableControlFlowState> addVariableInitStateFromCurrentInstructionIfAny(
|
||||
@NotNull Instruction instruction,
|
||||
@NotNull Map<VariableDescriptor, VariableInitState> enterInstructionData,
|
||||
@NotNull Map<VariableDescriptor, VariableControlFlowState> enterInstructionData,
|
||||
@NotNull LexicalScopeVariableInfo lexicalScopeVariableInfo
|
||||
) {
|
||||
if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) {
|
||||
@@ -201,26 +201,27 @@ public class PseudocodeVariablesData {
|
||||
if (variable == null) {
|
||||
return enterInstructionData;
|
||||
}
|
||||
Map<VariableDescriptor, VariableInitState> exitInstructionData = Maps.newHashMap(enterInstructionData);
|
||||
Map<VariableDescriptor, VariableControlFlowState> exitInstructionData = Maps.newHashMap(enterInstructionData);
|
||||
if (instruction instanceof WriteValueInstruction) {
|
||||
// if writing to already initialized object
|
||||
if (!PseudocodeUtil.isThisOrNoDispatchReceiver((WriteValueInstruction) instruction, bindingContext)) {
|
||||
return enterInstructionData;
|
||||
}
|
||||
|
||||
VariableInitState enterInitState = enterInstructionData.get(variable);
|
||||
VariableInitState initializationAtThisElement =
|
||||
VariableInitState.create(((WriteValueInstruction) instruction).getElement() instanceof JetProperty, enterInitState);
|
||||
VariableControlFlowState enterInitState = enterInstructionData.get(variable);
|
||||
VariableControlFlowState initializationAtThisElement =
|
||||
VariableControlFlowState
|
||||
.create(((WriteValueInstruction) instruction).getElement() instanceof JetProperty, enterInitState);
|
||||
exitInstructionData.put(variable, initializationAtThisElement);
|
||||
}
|
||||
else { // instruction instanceof VariableDeclarationInstruction
|
||||
VariableInitState enterInitState = enterInstructionData.get(variable);
|
||||
VariableControlFlowState enterInitState = enterInstructionData.get(variable);
|
||||
if (enterInitState == null) {
|
||||
enterInitState = getDefaultValueForInitializers(variable, instruction, lexicalScopeVariableInfo);
|
||||
}
|
||||
if (enterInitState == null || !enterInitState.mayBeInitialized() || !enterInitState.isDeclared) {
|
||||
boolean isInitialized = enterInitState != null && enterInitState.mayBeInitialized();
|
||||
VariableInitState variableDeclarationInfo = VariableInitState.create(isInitialized, true);
|
||||
VariableControlFlowState variableDeclarationInfo = VariableControlFlowState.create(isInitialized, true);
|
||||
exitInstructionData.put(variable, variableDeclarationInfo);
|
||||
}
|
||||
}
|
||||
@@ -300,25 +301,25 @@ public class PseudocodeVariablesData {
|
||||
}
|
||||
}
|
||||
|
||||
public static class VariableInitState {
|
||||
public static class VariableControlFlowState {
|
||||
|
||||
public final TriInitState initState;
|
||||
public final boolean isDeclared;
|
||||
|
||||
private VariableInitState(TriInitState initState, boolean isDeclared) {
|
||||
private VariableControlFlowState(TriInitState initState, boolean isDeclared) {
|
||||
this.initState = initState;
|
||||
this.isDeclared = isDeclared;
|
||||
}
|
||||
|
||||
private static final VariableInitState VS_IT = new VariableInitState(TriInitState.INITIALIZED, true);
|
||||
private static final VariableInitState VS_IF = new VariableInitState(TriInitState.INITIALIZED, false);
|
||||
private static final VariableInitState VS_UT = new VariableInitState(TriInitState.UNKNOWN, true);
|
||||
private static final VariableInitState VS_UF = new VariableInitState(TriInitState.UNKNOWN, false);
|
||||
private static final VariableInitState VS_NT = new VariableInitState(TriInitState.NOT_INITIALIZED, true);
|
||||
private static final VariableInitState VS_NF = new VariableInitState(TriInitState.NOT_INITIALIZED, false);
|
||||
private static final VariableControlFlowState VS_IT = new VariableControlFlowState(TriInitState.INITIALIZED, true);
|
||||
private static final VariableControlFlowState VS_IF = new VariableControlFlowState(TriInitState.INITIALIZED, false);
|
||||
private static final VariableControlFlowState VS_UT = new VariableControlFlowState(TriInitState.UNKNOWN, true);
|
||||
private static final VariableControlFlowState VS_UF = new VariableControlFlowState(TriInitState.UNKNOWN, false);
|
||||
private static final VariableControlFlowState VS_NT = new VariableControlFlowState(TriInitState.NOT_INITIALIZED, true);
|
||||
private static final VariableControlFlowState VS_NF = new VariableControlFlowState(TriInitState.NOT_INITIALIZED, false);
|
||||
|
||||
|
||||
private static VariableInitState create(TriInitState initState, boolean isDeclared) {
|
||||
private static VariableControlFlowState create(TriInitState initState, boolean isDeclared) {
|
||||
switch (initState) {
|
||||
case INITIALIZED: return isDeclared ? VS_IT : VS_IF;
|
||||
case UNKNOWN: return isDeclared ? VS_UT : VS_UF;
|
||||
@@ -326,15 +327,15 @@ public class PseudocodeVariablesData {
|
||||
}
|
||||
}
|
||||
|
||||
private static VariableInitState create(boolean isInitialized, boolean isDeclared) {
|
||||
private static VariableControlFlowState create(boolean isInitialized, boolean isDeclared) {
|
||||
return create(isInitialized ? TriInitState.INITIALIZED : TriInitState.NOT_INITIALIZED, isDeclared);
|
||||
}
|
||||
|
||||
private static VariableInitState create(boolean isInitialized) {
|
||||
private static VariableControlFlowState create(boolean isInitialized) {
|
||||
return create(isInitialized, false);
|
||||
}
|
||||
|
||||
private static VariableInitState create(boolean isDeclaredHere, @Nullable VariableInitState mergedEdgesData) {
|
||||
private static VariableControlFlowState create(boolean isDeclaredHere, @Nullable VariableControlFlowState mergedEdgesData) {
|
||||
return create(true, isDeclaredHere || (mergedEdgesData != null && mergedEdgesData.isDeclared));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableInitState;
|
||||
import static org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableControlFlowState;
|
||||
import static org.jetbrains.kotlin.cfg.PseudocodeVariablesData.VariableUseState;
|
||||
|
||||
public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest {
|
||||
@@ -42,7 +42,7 @@ public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest {
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
PseudocodeVariablesData pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode.getRootPseudocode(), bindingContext);
|
||||
final Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializers =
|
||||
final Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> variableInitializers =
|
||||
pseudocodeVariablesData.getVariableInitializers();
|
||||
final Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> useStatusData =
|
||||
pseudocodeVariablesData.getVariableUseStatusData();
|
||||
@@ -54,8 +54,8 @@ public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest {
|
||||
@Override
|
||||
public String invoke(Instruction instruction, Instruction next, Instruction prev) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
Edges<Map<VariableDescriptor, VariableInitState>> initializersEdges = variableInitializers.get(instruction);
|
||||
Edges<Map<VariableDescriptor, VariableInitState>> previousInitializersEdges = variableInitializers.get(prev);
|
||||
Edges<Map<VariableDescriptor, VariableControlFlowState>> initializersEdges = variableInitializers.get(instruction);
|
||||
Edges<Map<VariableDescriptor, VariableControlFlowState>> previousInitializersEdges = variableInitializers.get(prev);
|
||||
String initializersData = "";
|
||||
if (initializersEdges != null && !initializersEdges.equals(previousInitializersEdges)) {
|
||||
initializersData = dumpEdgesData(initPrefix, initializersEdges);
|
||||
@@ -75,11 +75,11 @@ public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest {
|
||||
private static int countDataColumnWidth(
|
||||
@NotNull String prefix,
|
||||
@NotNull List<Instruction> instructions,
|
||||
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> data
|
||||
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, VariableControlFlowState>>> data
|
||||
) {
|
||||
int maxWidth = 0;
|
||||
for (Instruction instruction : instructions) {
|
||||
Edges<Map<VariableDescriptor, VariableInitState>> edges = data.get(instruction);
|
||||
Edges<Map<VariableDescriptor, VariableControlFlowState>> edges = data.get(instruction);
|
||||
if (edges == null) continue;
|
||||
int length = dumpEdgesData(prefix, edges).length();
|
||||
if (maxWidth < length) {
|
||||
|
||||
Reference in New Issue
Block a user