no need in possible local initializers
for each variable for each instruction rename
This commit is contained in:
@@ -25,8 +25,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||||
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
|
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
|
||||||
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitializers;
|
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitState;
|
||||||
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseStatus;
|
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
@@ -41,6 +41,7 @@ import org.jetbrains.jet.plugin.JetMainDetector;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState.*;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||||
@@ -187,38 +188,38 @@ public class JetFlowInformationProvider {
|
|||||||
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
|
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
|
||||||
final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
|
final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
|
||||||
|
|
||||||
Map<Instruction, Edges<Map<VariableDescriptor,VariableInitializers>>> initializers = pseudocodeVariablesData.getVariableInitializers();
|
Map<Instruction, Edges<Map<VariableDescriptor,VariableInitState>>> initializers = pseudocodeVariablesData.getVariableInitializers();
|
||||||
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
|
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
|
||||||
PseudocodeTraverser.traverse(pseudocode, true, true, initializers, new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableInitializers>>() {
|
PseudocodeTraverser.traverse(pseudocode, true, true, initializers, new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState>>() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(@NotNull Instruction instruction,
|
public void execute(@NotNull Instruction instruction,
|
||||||
@Nullable Map<VariableDescriptor, VariableInitializers> in,
|
@Nullable Map<VariableDescriptor, VariableInitState> in,
|
||||||
@Nullable Map<VariableDescriptor, VariableInitializers> out) {
|
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState> out) {
|
||||||
assert in != null && out != null;
|
assert in != null && out != null;
|
||||||
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true, trace.getBindingContext());
|
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true, trace.getBindingContext());
|
||||||
if (variableDescriptor == null) return;
|
if (variableDescriptor == null) return;
|
||||||
if (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction)) return;
|
if (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction)) return;
|
||||||
VariableInitializers outInitializers = out.get(variableDescriptor);
|
VariableInitState outInitState = out.get(variableDescriptor);
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||||
boolean error = checkBackingField(variableDescriptor, element);
|
boolean error = checkBackingField(variableDescriptor, element);
|
||||||
if (!error && declaredVariables.contains(variableDescriptor)) {
|
if (!error && declaredVariables.contains(variableDescriptor)) {
|
||||||
checkIsInitialized(variableDescriptor, element, outInitializers, varWithUninitializedErrorGenerated);
|
checkIsInitialized(variableDescriptor, element, outInitState, varWithUninitializedErrorGenerated);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JetElement element = ((WriteValueInstruction) instruction).getlValue();
|
JetElement element = ((WriteValueInstruction) instruction).getlValue();
|
||||||
boolean error = checkBackingField(variableDescriptor, element);
|
boolean error = checkBackingField(variableDescriptor, element);
|
||||||
if (!(element instanceof JetExpression)) return;
|
if (!(element instanceof JetExpression)) return;
|
||||||
VariableInitializers inInitializers = in.get(variableDescriptor);
|
PseudocodeVariablesData.VariableInitState inInitState = in.get(variableDescriptor);
|
||||||
if (!error && !processLocalDeclaration) { // error has been generated before, while processing outer function of this local declaration
|
if (!error && !processLocalDeclaration) { // error has been generated before, while processing outer function of this local declaration
|
||||||
error = checkValReassignment(variableDescriptor, (JetExpression) element, inInitializers, varWithValReassignErrorGenerated);
|
error = checkValReassignment(variableDescriptor, (JetExpression) element, inInitState, varWithValReassignErrorGenerated);
|
||||||
}
|
}
|
||||||
if (!error && processClassOrObject) {
|
if (!error && processClassOrObject) {
|
||||||
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, inInitializers, outInitializers);
|
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, inInitState, outInitState);
|
||||||
}
|
}
|
||||||
if (!error && processClassOrObject) {
|
if (!error && processClassOrObject) {
|
||||||
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, inInitializers, outInitializers);
|
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, inInitState, outInitState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -232,11 +233,11 @@ public class JetFlowInformationProvider {
|
|||||||
|
|
||||||
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
|
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
|
||||||
@NotNull JetElement element,
|
@NotNull JetElement element,
|
||||||
@NotNull VariableInitializers variableInitializers,
|
@NotNull PseudocodeVariablesData.VariableInitState variableInitState,
|
||||||
@NotNull Collection<VariableDescriptor> varWithUninitializedErrorGenerated) {
|
@NotNull Collection<VariableDescriptor> varWithUninitializedErrorGenerated) {
|
||||||
if (!(element instanceof JetSimpleNameExpression)) return;
|
if (!(element instanceof JetSimpleNameExpression)) return;
|
||||||
|
|
||||||
boolean isInitialized = variableInitializers.isInitialized();
|
boolean isInitialized = variableInitState.isInitialized;
|
||||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||||
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) {
|
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) {
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
@@ -256,15 +257,11 @@ public class JetFlowInformationProvider {
|
|||||||
|
|
||||||
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
|
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
|
||||||
@NotNull JetExpression expression,
|
@NotNull JetExpression expression,
|
||||||
@NotNull VariableInitializers enterInitializers,
|
@NotNull VariableInitState enterInitState,
|
||||||
@NotNull Collection<VariableDescriptor> varWithValReassignErrorGenerated) {
|
@NotNull Collection<VariableDescriptor> varWithValReassignErrorGenerated) {
|
||||||
boolean isInitializedNotHere = enterInitializers.isInitialized();
|
boolean isInitializedNotHere = enterInitState.isInitialized;
|
||||||
Set<JetElement> possibleLocalInitializers = enterInitializers.getPossibleLocalInitializers();
|
if (expression.getParent() instanceof JetProperty && ((JetProperty)expression).getInitializer() != null) {
|
||||||
if (possibleLocalInitializers.size() == 1) {
|
isInitializedNotHere = false;
|
||||||
JetElement initializer = possibleLocalInitializers.iterator().next();
|
|
||||||
if (initializer instanceof JetProperty && initializer == expression.getParent()) {
|
|
||||||
isInitializedNotHere = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
boolean hasBackingField = true;
|
boolean hasBackingField = true;
|
||||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||||
@@ -307,16 +304,16 @@ public class JetFlowInformationProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
|
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
|
||||||
if (!enterInitializers.isDeclared() && !exitInitializers.isDeclared() && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
|
if (!enterInitState.isDeclared && !exitInitState.isDeclared && !enterInitState.isInitialized && exitInitState.isInitialized) {
|
||||||
trace.report(Errors.INITIALIZATION_BEFORE_DECLARATION.on(expression, variableDescriptor));
|
trace.report(Errors.INITIALIZATION_BEFORE_DECLARATION.on(expression, variableDescriptor));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
|
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
|
||||||
if (variableDescriptor instanceof PropertyDescriptor && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
|
if (variableDescriptor instanceof PropertyDescriptor && !enterInitState.isInitialized && exitInitState.isInitialized) {
|
||||||
if (!variableDescriptor.isVar()) return false;
|
if (!variableDescriptor.isVar()) return false;
|
||||||
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) return false;
|
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) return false;
|
||||||
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
||||||
@@ -396,15 +393,15 @@ public class JetFlowInformationProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordInitializedVariables(@NotNull Pseudocode pseudocode, @NotNull Map<Instruction, Edges<Map<VariableDescriptor,VariableInitializers>>> initializersMap) {
|
private void recordInitializedVariables(@NotNull Pseudocode pseudocode, @NotNull Map<Instruction, Edges<Map<VariableDescriptor,PseudocodeVariablesData.VariableInitState>>> initializersMap) {
|
||||||
Edges<Map<VariableDescriptor, VariableInitializers>> initializers = initializersMap.get(pseudocode.getExitInstruction());
|
Edges<Map<VariableDescriptor, VariableInitState>> initializers = initializersMap.get(pseudocode.getExitInstruction());
|
||||||
Set<VariableDescriptor> usedVariables = pseudocodeVariablesData.getUsedVariables(pseudocode);
|
Set<VariableDescriptor> usedVariables = pseudocodeVariablesData.getUsedVariables(pseudocode);
|
||||||
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
|
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
|
||||||
for (VariableDescriptor variable : usedVariables) {
|
for (VariableDescriptor variable : usedVariables) {
|
||||||
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
|
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
|
||||||
VariableInitializers variableInitializers = initializers.in.get(variable);
|
PseudocodeVariablesData.VariableInitState variableInitState = initializers.in.get(variable);
|
||||||
if (variableInitializers == null) return;
|
if (variableInitState == null) return;
|
||||||
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, variableInitializers.isInitialized());
|
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, variableInitState.isInitialized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,13 +410,13 @@ public class JetFlowInformationProvider {
|
|||||||
// "Unused variable" & "unused value" analyses
|
// "Unused variable" & "unused value" analyses
|
||||||
|
|
||||||
public void markUnusedVariables() {
|
public void markUnusedVariables() {
|
||||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableUseStatus>>> variableStatusData = pseudocodeVariablesData.getVariableUseStatusData();
|
Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> variableStatusData = pseudocodeVariablesData.getVariableUseStatusData();
|
||||||
InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableUseStatus>> variableStatusAnalyzeStrategy =
|
InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableUseState>> variableStatusAnalyzeStrategy =
|
||||||
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableUseStatus>>() {
|
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState>>() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(@NotNull Instruction instruction,
|
public void execute(@NotNull Instruction instruction,
|
||||||
@Nullable Map<VariableDescriptor, VariableUseStatus> in,
|
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState> in,
|
||||||
@Nullable Map<VariableDescriptor, VariableUseStatus> out) {
|
@Nullable Map<VariableDescriptor, VariableUseState> out) {
|
||||||
|
|
||||||
assert in != null && out != null;
|
assert in != null && out != null;
|
||||||
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(instruction.getOwner());
|
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(instruction.getOwner());
|
||||||
@@ -427,11 +424,11 @@ public class JetFlowInformationProvider {
|
|||||||
trace.getBindingContext());
|
trace.getBindingContext());
|
||||||
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) ||
|
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) ||
|
||||||
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
|
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
|
||||||
VariableUseStatus variableUseStatus = in.get(variableDescriptor);
|
PseudocodeVariablesData.VariableUseState variableUseState = in.get(variableDescriptor);
|
||||||
if (instruction instanceof WriteValueInstruction) {
|
if (instruction instanceof WriteValueInstruction) {
|
||||||
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
|
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
|
||||||
JetElement element = ((WriteValueInstruction) instruction).getElement();
|
JetElement element = ((WriteValueInstruction) instruction).getElement();
|
||||||
if (variableUseStatus != VariableUseStatus.LAST_READ) {
|
if (variableUseState != LAST_READ) {
|
||||||
if (element instanceof JetBinaryExpression &&
|
if (element instanceof JetBinaryExpression &&
|
||||||
((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
|
((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
|
||||||
JetExpression right = ((JetBinaryExpression) element).getRight();
|
JetExpression right = ((JetBinaryExpression) element).getRight();
|
||||||
@@ -452,7 +449,7 @@ public class JetFlowInformationProvider {
|
|||||||
if (element instanceof JetNamedDeclaration) {
|
if (element instanceof JetNamedDeclaration) {
|
||||||
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
|
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
|
||||||
if (nameIdentifier == null) return;
|
if (nameIdentifier == null) return;
|
||||||
if (variableUseStatus == null || variableUseStatus == VariableUseStatus.UNUSED) {
|
if (variableUseState == null || variableUseState == UNUSED) {
|
||||||
if (element instanceof JetProperty) {
|
if (element instanceof JetProperty) {
|
||||||
trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, variableDescriptor));
|
trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, variableDescriptor));
|
||||||
}
|
}
|
||||||
@@ -470,10 +467,10 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (variableUseStatus == VariableUseStatus.ONLY_WRITTEN_NEVER_READ &&element instanceof JetProperty) {
|
else if (variableUseState == ONLY_WRITTEN_NEVER_READ &&element instanceof JetProperty) {
|
||||||
trace.report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on((JetNamedDeclaration) element, variableDescriptor));
|
trace.report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on((JetNamedDeclaration) element, variableDescriptor));
|
||||||
}
|
}
|
||||||
else if (variableUseStatus == VariableUseStatus.LAST_WRITTEN && element instanceof JetProperty) {
|
else if (variableUseState == LAST_WRITTEN && element instanceof JetProperty) {
|
||||||
JetExpression initializer = ((JetProperty) element).getInitializer();
|
JetExpression initializer = ((JetProperty) element).getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
trace.report(Errors.VARIABLE_WITH_REDUNDANT_INITIALIZER.on(initializer, variableDescriptor));
|
trace.report(Errors.VARIABLE_WITH_REDUNDANT_INITIALIZER.on(initializer, variableDescriptor));
|
||||||
|
|||||||
@@ -181,16 +181,6 @@ public class PseudocodeTraverser {
|
|||||||
return new Edges<T>(in, out);
|
return new Edges<T>(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public T getIn() {
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public T getOut() {
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ public class PseudocodeVariablesData {
|
|||||||
private final Map<Pseudocode, Set<VariableDescriptor>> declaredVariablesInEachDeclaration = Maps.newHashMap();
|
private final Map<Pseudocode, Set<VariableDescriptor>> declaredVariablesInEachDeclaration = Maps.newHashMap();
|
||||||
private final Map<Pseudocode, Set<VariableDescriptor>> usedVariablesInEachDeclaration = Maps.newHashMap();
|
private final Map<Pseudocode, Set<VariableDescriptor>> usedVariablesInEachDeclaration = Maps.newHashMap();
|
||||||
|
|
||||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitializers>>> variableInitializersMap;
|
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap;
|
||||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableUseStatus>>> variableStatusMap;
|
private Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> variableStatusMap;
|
||||||
|
|
||||||
public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) {
|
public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) {
|
||||||
this.pseudocode = pseudocode;
|
this.pseudocode = pseudocode;
|
||||||
@@ -102,7 +102,7 @@ public class PseudocodeVariablesData {
|
|||||||
// variable initializers
|
// variable initializers
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Map<Instruction, Edges<Map<VariableDescriptor, VariableInitializers>>> getVariableInitializers() {
|
public Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers() {
|
||||||
if (variableInitializersMap == null) {
|
if (variableInitializersMap == null) {
|
||||||
variableInitializersMap = getVariableInitializers(pseudocode);
|
variableInitializersMap = getVariableInitializers(pseudocode);
|
||||||
}
|
}
|
||||||
@@ -110,23 +110,23 @@ public class PseudocodeVariablesData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitializers>>> getVariableInitializers(@NotNull Pseudocode pseudocode) {
|
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers(@NotNull Pseudocode pseudocode) {
|
||||||
|
|
||||||
Set<VariableDescriptor> usedVariables = getUsedVariables(pseudocode);
|
Set<VariableDescriptor> usedVariables = getUsedVariables(pseudocode);
|
||||||
Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode);
|
Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode);
|
||||||
Map<VariableDescriptor, VariableInitializers> initialMap = Collections.emptyMap();
|
Map<VariableDescriptor, VariableInitState> initialMap = Collections.emptyMap();
|
||||||
final Map<VariableDescriptor, VariableInitializers> initialMapForStartInstruction = prepareInitializersMapForStartInstruction(
|
final Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = prepareInitializersMapForStartInstruction(
|
||||||
usedVariables, declaredVariables);
|
usedVariables, declaredVariables);
|
||||||
|
|
||||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitializers>>> variableInitializersMap = PseudocodeTraverser.collectData(
|
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap = PseudocodeTraverser.collectData(
|
||||||
pseudocode, /* directOrder = */ true, /* lookInside = */ false,
|
pseudocode, /* directOrder = */ true, /* lookInside = */ false,
|
||||||
initialMap, initialMapForStartInstruction, new PseudocodeTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitializers>>() {
|
initialMap, initialMapForStartInstruction, new PseudocodeTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
|
||||||
@Override
|
@Override
|
||||||
public Edges<Map<VariableDescriptor, VariableInitializers>> execute(
|
public Edges<Map<VariableDescriptor, VariableInitState>> execute(
|
||||||
@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableInitializers>> incomingEdgesData) {
|
@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) {
|
||||||
|
|
||||||
Map<VariableDescriptor, VariableInitializers> enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData);
|
Map<VariableDescriptor, VariableInitState> enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData);
|
||||||
Map<VariableDescriptor, VariableInitializers> exitInstructionData =
|
Map<VariableDescriptor, VariableInitState> exitInstructionData =
|
||||||
addVariableInitializerFromCurrentInstructionIfAny(instruction, enterInstructionData);
|
addVariableInitializerFromCurrentInstructionIfAny(instruction, enterInstructionData);
|
||||||
return Edges.create(enterInstructionData, exitInstructionData);
|
return Edges.create(enterInstructionData, exitInstructionData);
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ public class PseudocodeVariablesData {
|
|||||||
|
|
||||||
for (LocalDeclarationInstruction localDeclarationInstruction : pseudocode.getLocalDeclarations()) {
|
for (LocalDeclarationInstruction localDeclarationInstruction : pseudocode.getLocalDeclarations()) {
|
||||||
Pseudocode localPseudocode = localDeclarationInstruction.getBody();
|
Pseudocode localPseudocode = localDeclarationInstruction.getBody();
|
||||||
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitializers>>> initializersForLocalDeclaration = getVariableInitializers(localPseudocode);
|
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> initializersForLocalDeclaration = getVariableInitializers(localPseudocode);
|
||||||
|
|
||||||
for (Instruction instruction : initializersForLocalDeclaration.keySet()) {
|
for (Instruction instruction : initializersForLocalDeclaration.keySet()) {
|
||||||
//todo
|
//todo
|
||||||
@@ -149,51 +149,51 @@ public class PseudocodeVariablesData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<VariableDescriptor, VariableInitializers> prepareInitializersMapForStartInstruction(
|
private Map<VariableDescriptor, VariableInitState> prepareInitializersMapForStartInstruction(
|
||||||
@NotNull Collection<VariableDescriptor> usedVariables,
|
@NotNull Collection<VariableDescriptor> usedVariables,
|
||||||
@NotNull Collection<VariableDescriptor> declaredVariables) {
|
@NotNull Collection<VariableDescriptor> declaredVariables) {
|
||||||
|
|
||||||
Map<VariableDescriptor, VariableInitializers> initialMapForStartInstruction = Maps.newHashMap();
|
Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = Maps.newHashMap();
|
||||||
VariableInitializers isInitializedForExternalVariable = new VariableInitializers(true);
|
VariableInitState initializedForExternalVariable = new VariableInitState(true);
|
||||||
VariableInitializers isNotInitializedForDeclaredVariable = new VariableInitializers(false);
|
VariableInitState notInitializedForDeclaredVariable = new VariableInitState(false);
|
||||||
|
|
||||||
for (VariableDescriptor variable : usedVariables) {
|
for (VariableDescriptor variable : usedVariables) {
|
||||||
if (declaredVariables.contains(variable)) {
|
if (declaredVariables.contains(variable)) {
|
||||||
initialMapForStartInstruction.put(variable, isNotInitializedForDeclaredVariable);
|
initialMapForStartInstruction.put(variable, notInitializedForDeclaredVariable);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
initialMapForStartInstruction.put(variable, isInitializedForExternalVariable);
|
initialMapForStartInstruction.put(variable, initializedForExternalVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return initialMapForStartInstruction;
|
return initialMapForStartInstruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<VariableDescriptor, VariableInitializers> mergeIncomingEdgesDataForInitializers(
|
private Map<VariableDescriptor, VariableInitState> mergeIncomingEdgesDataForInitializers(
|
||||||
@NotNull Collection<Map<VariableDescriptor, VariableInitializers>> incomingEdgesData) {
|
@NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) {
|
||||||
|
|
||||||
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
|
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
|
||||||
for (Map<VariableDescriptor, VariableInitializers> edgeData : incomingEdgesData) {
|
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
|
||||||
variablesInScope.addAll(edgeData.keySet());
|
variablesInScope.addAll(edgeData.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<VariableDescriptor, VariableInitializers> enterInstructionData = Maps.newHashMap();
|
Map<VariableDescriptor, VariableInitState> enterInstructionData = Maps.newHashMap();
|
||||||
for (VariableDescriptor variable : variablesInScope) {
|
for (VariableDescriptor variable : variablesInScope) {
|
||||||
Set<VariableInitializers> edgesDataForVariable = Sets.newHashSet();
|
Set<VariableInitState> edgesDataForVariable = Sets.newHashSet();
|
||||||
for (Map<VariableDescriptor, VariableInitializers> edgeData : incomingEdgesData) {
|
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
|
||||||
VariableInitializers initializers = edgeData.get(variable);
|
VariableInitState initState = edgeData.get(variable);
|
||||||
if (initializers != null) {
|
if (initState != null) {
|
||||||
edgesDataForVariable.add(initializers);
|
edgesDataForVariable.add(initState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enterInstructionData.put(variable, new VariableInitializers(edgesDataForVariable));
|
enterInstructionData.put(variable, new VariableInitState(edgesDataForVariable));
|
||||||
}
|
}
|
||||||
return enterInstructionData;
|
return enterInstructionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Map<VariableDescriptor, VariableInitializers> addVariableInitializerFromCurrentInstructionIfAny(
|
private Map<VariableDescriptor, VariableInitState> addVariableInitializerFromCurrentInstructionIfAny(
|
||||||
@NotNull Instruction instruction, @NotNull Map<VariableDescriptor, VariableInitializers> enterInstructionData) {
|
@NotNull Instruction instruction, @NotNull Map<VariableDescriptor, VariableInitState> enterInstructionData) {
|
||||||
|
|
||||||
if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) {
|
if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) {
|
||||||
return enterInstructionData;
|
return enterInstructionData;
|
||||||
@@ -202,21 +202,22 @@ public class PseudocodeVariablesData {
|
|||||||
if (variable == null) {
|
if (variable == null) {
|
||||||
return enterInstructionData;
|
return enterInstructionData;
|
||||||
}
|
}
|
||||||
Map<VariableDescriptor, VariableInitializers> exitInstructionData = Maps.newHashMap(enterInstructionData);
|
Map<VariableDescriptor, VariableInitState> exitInstructionData = Maps.newHashMap(enterInstructionData);
|
||||||
if (instruction instanceof WriteValueInstruction) {
|
if (instruction instanceof WriteValueInstruction) {
|
||||||
VariableInitializers enterInitializers = enterInstructionData.get(variable);
|
VariableInitState enterInitState = enterInstructionData.get(variable);
|
||||||
VariableInitializers initializationAtThisElement = new VariableInitializers(((WriteValueInstruction) instruction).getElement(), enterInitializers);
|
VariableInitState initializationAtThisElement =
|
||||||
|
new VariableInitState(((WriteValueInstruction) instruction).getElement() instanceof JetProperty, enterInitState);
|
||||||
exitInstructionData.put(variable, initializationAtThisElement);
|
exitInstructionData.put(variable, initializationAtThisElement);
|
||||||
}
|
}
|
||||||
else {
|
else { // instruction instanceof VariableDeclarationInstruction
|
||||||
VariableInitializers enterInitializers = enterInstructionData.get(variable);
|
VariableInitState enterInitState = enterInstructionData.get(variable);
|
||||||
if (enterInitializers == null || !enterInitializers.isInitialized() || !enterInitializers.isDeclared()) {
|
if (enterInitState == null || !enterInitState.isInitialized || !enterInitState.isDeclared) {
|
||||||
JetElement element = ((VariableDeclarationInstruction) instruction).getElement();
|
JetElement element = ((VariableDeclarationInstruction) instruction).getElement();
|
||||||
if (element instanceof JetProperty) {
|
if (element instanceof JetProperty) {
|
||||||
JetProperty property = (JetProperty) element;
|
JetProperty property = (JetProperty) element;
|
||||||
if (property.getInitializer() == null) {
|
if (property.getInitializer() == null) {
|
||||||
boolean isInitialized = enterInitializers != null && enterInitializers.isInitialized();
|
boolean isInitialized = enterInitState != null && enterInitState.isInitialized;
|
||||||
VariableInitializers variableDeclarationInfo = new VariableInitializers(isInitialized, true);
|
VariableInitState variableDeclarationInfo = new VariableInitState(isInitialized, true);
|
||||||
exitInstructionData.put(variable, variableDeclarationInfo);
|
exitInstructionData.put(variable, variableDeclarationInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,23 +229,23 @@ public class PseudocodeVariablesData {
|
|||||||
// variable use
|
// variable use
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseStatus>>> getVariableUseStatusData() {
|
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() {
|
||||||
if (variableStatusMap == null) {
|
if (variableStatusMap == null) {
|
||||||
Map<VariableDescriptor, VariableUseStatus> sinkInstructionData = Maps.newHashMap();
|
Map<VariableDescriptor, VariableUseState> sinkInstructionData = Maps.newHashMap();
|
||||||
for (VariableDescriptor usedVariable : usedVariablesInEachDeclaration.get(pseudocode)) {
|
for (VariableDescriptor usedVariable : usedVariablesInEachDeclaration.get(pseudocode)) {
|
||||||
sinkInstructionData.put(usedVariable, VariableUseStatus.UNUSED);
|
sinkInstructionData.put(usedVariable, VariableUseState.UNUSED);
|
||||||
}
|
}
|
||||||
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseStatus>> collectVariableUseStatusStrategy = new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseStatus>>() {
|
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>> collectVariableUseStatusStrategy = new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() {
|
||||||
@Override
|
@Override
|
||||||
public Edges<Map<VariableDescriptor, VariableUseStatus>> execute(@NotNull Instruction instruction,
|
public Edges<Map<VariableDescriptor, VariableUseState>> execute(@NotNull Instruction instruction,
|
||||||
@NotNull Collection<Map<VariableDescriptor, VariableUseStatus>> incomingEdgesData) {
|
@NotNull Collection<Map<VariableDescriptor, VariableUseState>> incomingEdgesData) {
|
||||||
|
|
||||||
Map<VariableDescriptor, VariableUseStatus> enterResult = Maps.newHashMap();
|
Map<VariableDescriptor, VariableUseState> enterResult = Maps.newHashMap();
|
||||||
for (Map<VariableDescriptor, VariableUseStatus> edgeData : incomingEdgesData) {
|
for (Map<VariableDescriptor, VariableUseState> edgeData : incomingEdgesData) {
|
||||||
for (Map.Entry<VariableDescriptor, VariableUseStatus> entry : edgeData.entrySet()) {
|
for (Map.Entry<VariableDescriptor, VariableUseState> entry : edgeData.entrySet()) {
|
||||||
VariableDescriptor variableDescriptor = entry.getKey();
|
VariableDescriptor variableDescriptor = entry.getKey();
|
||||||
VariableUseStatus variableUseStatus = entry.getValue();
|
VariableUseState variableUseState = entry.getValue();
|
||||||
enterResult.put(variableDescriptor, variableUseStatus.merge(enterResult.get(variableDescriptor)));
|
enterResult.put(variableDescriptor, variableUseState.merge(enterResult.get(variableDescriptor)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true,
|
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true,
|
||||||
@@ -253,109 +254,90 @@ public class PseudocodeVariablesData {
|
|||||||
(!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction))) {
|
(!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction))) {
|
||||||
return Edges.create(enterResult, enterResult);
|
return Edges.create(enterResult, enterResult);
|
||||||
}
|
}
|
||||||
Map<VariableDescriptor, VariableUseStatus> exitResult = Maps.newHashMap(enterResult);
|
Map<VariableDescriptor, VariableUseState> exitResult = Maps.newHashMap(enterResult);
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
exitResult.put(variableDescriptor, VariableUseStatus.LAST_READ);
|
exitResult.put(variableDescriptor, VariableUseState.LAST_READ);
|
||||||
}
|
}
|
||||||
else {
|
else { //instruction instanceof WriteValueInstruction
|
||||||
VariableUseStatus variableUseStatus = enterResult.get(variableDescriptor);
|
VariableUseState variableUseState = enterResult.get(variableDescriptor);
|
||||||
if (variableUseStatus == null) {
|
if (variableUseState == null) {
|
||||||
variableUseStatus = VariableUseStatus.UNUSED;
|
variableUseState = VariableUseState.UNUSED;
|
||||||
}
|
}
|
||||||
switch (variableUseStatus) {
|
switch (variableUseState) {
|
||||||
case UNUSED:
|
case UNUSED:
|
||||||
case ONLY_WRITTEN_NEVER_READ:
|
case ONLY_WRITTEN_NEVER_READ:
|
||||||
exitResult.put(variableDescriptor, VariableUseStatus.ONLY_WRITTEN_NEVER_READ);
|
exitResult.put(variableDescriptor, VariableUseState.ONLY_WRITTEN_NEVER_READ);
|
||||||
break;
|
break;
|
||||||
case LAST_WRITTEN:
|
case LAST_WRITTEN:
|
||||||
case LAST_READ:
|
case LAST_READ:
|
||||||
exitResult.put(variableDescriptor, VariableUseStatus.LAST_WRITTEN);
|
exitResult.put(variableDescriptor, VariableUseState.LAST_WRITTEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Edges.create(enterResult, exitResult);
|
return Edges.create(enterResult, exitResult);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
variableStatusMap = PseudocodeTraverser.collectData(pseudocode, false, true,
|
variableStatusMap = PseudocodeTraverser.collectData(pseudocode, false, true,
|
||||||
Collections.<VariableDescriptor, VariableUseStatus>emptyMap(),
|
Collections.<VariableDescriptor, VariableUseState>emptyMap(),
|
||||||
sinkInstructionData, collectVariableUseStatusStrategy);
|
sinkInstructionData, collectVariableUseStatusStrategy);
|
||||||
}
|
}
|
||||||
return variableStatusMap;
|
return variableStatusMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class VariableInitializers {
|
public static class VariableInitState {
|
||||||
private final Set<JetElement> possibleLocalInitializers = Sets.newHashSet();
|
public final boolean isInitialized;
|
||||||
private boolean isInitialized;
|
public final boolean isDeclared;
|
||||||
private boolean isDeclared;
|
|
||||||
|
|
||||||
public VariableInitializers(boolean isInitialized) {
|
public VariableInitState(boolean isInitialized) {
|
||||||
this(isInitialized, false);
|
this(isInitialized, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableInitializers(boolean isInitialized, boolean isDeclared) {
|
public VariableInitState(boolean isInitialized, boolean isDeclared) {
|
||||||
this.isInitialized = isInitialized;
|
this.isInitialized = isInitialized;
|
||||||
this.isDeclared = isDeclared;
|
this.isDeclared = isDeclared;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableInitializers(JetElement element, @Nullable VariableInitializers previous) {
|
public VariableInitState(boolean isDeclaredHere, @Nullable VariableInitState mergedEdgesData) {
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
isDeclared = element instanceof JetProperty || (previous != null && previous.isDeclared());
|
isDeclared = isDeclaredHere || (mergedEdgesData != null && mergedEdgesData.isDeclared);
|
||||||
possibleLocalInitializers.add(element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableInitializers(Set<VariableInitializers> edgesData) {
|
public VariableInitState(@NotNull Set<VariableInitState> edgesData) {
|
||||||
isInitialized = true;
|
boolean isInitialized = true;
|
||||||
isDeclared = true;
|
boolean isDeclared = true;
|
||||||
for (VariableInitializers edgeData : edgesData) {
|
for (VariableInitState edgeData : edgesData) {
|
||||||
if (!edgeData.isInitialized) {
|
if (!edgeData.isInitialized) {
|
||||||
isInitialized = false;
|
isInitialized = false;
|
||||||
}
|
}
|
||||||
if (!edgeData.isDeclared) {
|
if (!edgeData.isDeclared) {
|
||||||
isDeclared = false;
|
isDeclared = false;
|
||||||
}
|
}
|
||||||
possibleLocalInitializers.addAll(edgeData.possibleLocalInitializers);
|
|
||||||
}
|
}
|
||||||
}
|
this.isInitialized = isInitialized;
|
||||||
|
this.isDeclared = isDeclared;
|
||||||
public Set<JetElement> getPossibleLocalInitializers() {
|
|
||||||
return possibleLocalInitializers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return isInitialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeclared() {
|
|
||||||
return isDeclared;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (!(o instanceof VariableInitializers)) return false;
|
if (!(o instanceof VariableInitState)) return false;
|
||||||
|
|
||||||
VariableInitializers that = (VariableInitializers) o;
|
VariableInitState that = (VariableInitState) o;
|
||||||
|
|
||||||
if (isDeclared != that.isDeclared) return false;
|
if (isDeclared != that.isDeclared) return false;
|
||||||
if (isInitialized != that.isInitialized) return false;
|
if (isInitialized != that.isInitialized) return false;
|
||||||
if (possibleLocalInitializers != null
|
|
||||||
? !possibleLocalInitializers.equals(that.possibleLocalInitializers)
|
|
||||||
: that.possibleLocalInitializers != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = possibleLocalInitializers != null ? possibleLocalInitializers.hashCode() : 0;
|
int result = (isInitialized ? 1 : 0);
|
||||||
result = 31 * result + (isInitialized ? 1 : 0);
|
|
||||||
result = 31 * result + (isDeclared ? 1 : 0);
|
result = 31 * result + (isDeclared ? 1 : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum VariableUseStatus {
|
public static enum VariableUseState {
|
||||||
LAST_READ(3),
|
LAST_READ(3),
|
||||||
LAST_WRITTEN(2),
|
LAST_WRITTEN(2),
|
||||||
ONLY_WRITTEN_NEVER_READ(1),
|
ONLY_WRITTEN_NEVER_READ(1),
|
||||||
@@ -363,13 +345,13 @@ public class PseudocodeVariablesData {
|
|||||||
|
|
||||||
private final int importance;
|
private final int importance;
|
||||||
|
|
||||||
VariableUseStatus(int importance) {
|
VariableUseState(int importance) {
|
||||||
this.importance = importance;
|
this.importance = importance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableUseStatus merge(@Nullable VariableUseStatus variableUseStatus) {
|
public VariableUseState merge(@Nullable VariableUseState variableUseState) {
|
||||||
if (variableUseStatus == null || importance > variableUseStatus.importance) return this;
|
if (variableUseState == null || importance > variableUseState.importance) return this;
|
||||||
return variableUseStatus;
|
return variableUseState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user