DFA: ignore boolean fields initializer if it's true or false literal

Often it's used as a knob to switch program behavior, so it's reasonable to analyze both alternatives
This commit is contained in:
Tagir Valeev
2017-12-29 18:35:29 +07:00
parent f688f2edd9
commit c78e018f81
6 changed files with 17 additions and 5 deletions
@@ -310,6 +310,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
private void initializeVariable(PsiVariable variable, PsiExpression initializer) {
if (DfaUtil.ignoreInitializer(variable)) return;
DfaVariableValue dfaVariable = myFactory.getVarFactory().createVariableValue(variable, false);
addInstruction(new PushInstruction(dfaVariable, initializer, true));
initializer.accept(this);
@@ -303,7 +303,7 @@ public class DataFlowRunner {
private static DfaValue makeInitialValue(DfaVariableValue var, PsiElement block) {
if(var.getQualifier() != null) return null;
PsiField field = ObjectUtils.tryCast(var.getPsiVariable(), PsiField.class);
if (field == null || DfaUtil.hasInitializationHacks(field)) return null;
if (field == null || DfaUtil.ignoreInitializer(field) || DfaUtil.hasInitializationHacks(field)) return null;
return DfaUtil.getPossiblyNonInitializedValue(var.getFactory(), field, block);
}
@@ -273,6 +273,17 @@ public class DfaUtil {
return containingClass != null && System.class.getName().equals(containingClass.getQualifiedName());
}
public static boolean ignoreInitializer(PsiVariable variable) {
// Skip boolean constant fields as they usually used as control knobs to modify program logic
// it's better to analyze both true and false values even if it's predefined
PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(variable.getInitializer());
return initializer != null &&
variable instanceof PsiField &&
variable.hasModifierProperty(PsiModifier.FINAL) &&
variable.getType().equals(PsiType.BOOLEAN) &&
(ExpressionUtils.isLiteral(initializer, Boolean.TRUE) || ExpressionUtils.isLiteral(initializer, Boolean.FALSE));
}
static boolean isInsideConstructorOrInitializer(PsiElement element) {
while (element != null) {
if (element instanceof PsiClass) return true;
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.codeInspection.dataFlow.DfaUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -56,6 +57,7 @@ public class DfaConstValue extends DfaValue {
@Nullable
public DfaValue create(PsiVariable variable) {
if (DfaUtil.ignoreInitializer(variable)) return null;
Object value = variable.computeConstantValue();
PsiType type = variable.getType();
if (value == null) {
@@ -1,8 +1,7 @@
// "Unwrap 'if' statement" "true"
class X {
private final boolean field = true;
String m() {
boolean field = true;
return "one";
}
}
@@ -1,8 +1,7 @@
// "Unwrap 'if' statement" "true"
class X {
private final boolean field = true;
String m() {
boolean field = true;
if (fiel<caret>d) return "one";
return "two";
}