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