mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] IDEA-307630 Constant values: remove warning at the beginning of |= and &= series
GitOrigin-RevId: 3841398346bfc13b26cd6bed05e51e762e2f78e1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
604f30df53
commit
c4fee89a6e
+17
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.DefUseUtil;
|
||||
import com.intellij.psi.impl.source.PsiFieldImpl;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -429,6 +430,10 @@ public class ConstantValueInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
|
||||
if (PsiUtil.skipParenthesizedExprUp(psiAnchor.getParent()) instanceof PsiAssignmentExpression assignment &&
|
||||
PsiTreeUtil.isAncestor(assignment.getLExpression(), psiAnchor, false)) {
|
||||
IElementType tokenType = assignment.getOperationTokenType();
|
||||
if (tokenType.equals(JavaTokenType.ANDEQ) || tokenType.equals(JavaTokenType.OREQ)) {
|
||||
if (isFlagSetChain(assignment.getLExpression(), tokenType.equals(JavaTokenType.ANDEQ))) return;
|
||||
}
|
||||
reporter.registerProblem(
|
||||
psiAnchor,
|
||||
JavaAnalysisBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
|
||||
@@ -456,6 +461,18 @@ public class ConstantValueInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
reporter.registerProblem(psiAnchor, message, fixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
|
||||
private static boolean isFlagSetChain(@NotNull PsiExpression expression, boolean isAnd) {
|
||||
PsiLocalVariable local = ExpressionUtils.resolveLocalVariable(expression);
|
||||
if (local == null) return false;
|
||||
PsiExpression initializer = local.getInitializer();
|
||||
if (!ExpressionUtils.isLiteral(initializer, isAnd)) return false;
|
||||
if (!(PsiUtil.getVariableCodeBlock(local, null) instanceof PsiCodeBlock block)) return false;
|
||||
PsiElement[] defs = DefUseUtil.getDefs(block, local, expression.getParent());
|
||||
// boolean x = false; x|=something;
|
||||
return defs.length == 1 && defs[0] == local &&
|
||||
VariableAccessUtils.getVariableReferences(local, block).stream().filter(PsiUtil::isAccessedForWriting).limit(2).count() > 1;
|
||||
}
|
||||
|
||||
private static @Nullable LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
|
||||
LocalQuickFixOnPsiElement fix = createSimplifyBooleanFix(element, value);
|
||||
if (fix == null) return null;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Test {
|
||||
public void foo(boolean x, boolean y, boolean z) {
|
||||
boolean r = true;
|
||||
<warning descr="Condition 'r' at the left side of assignment expression is always 'true'. Can be simplified">r</warning> &= x;
|
||||
r &= x;
|
||||
r &= y;
|
||||
r &= z;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// IDEA-304296
|
||||
class BooleanOrEquals {
|
||||
boolean test() {
|
||||
boolean result = false;
|
||||
result |= check1();
|
||||
result |= check2();
|
||||
result |= check3();
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean testWrong() {
|
||||
boolean result = true;
|
||||
<warning descr="Condition 'result' at the left side of assignment expression is always 'true'. Can be simplified">result</warning> |= check1();
|
||||
<warning descr="Condition 'result' at the left side of assignment expression is always 'true'. Can be simplified">result</warning> |= check2();
|
||||
<warning descr="Condition 'result' at the left side of assignment expression is always 'true'. Can be simplified">result</warning> |= check3();
|
||||
return result;
|
||||
}
|
||||
|
||||
native boolean check1();
|
||||
native boolean check2();
|
||||
native boolean check3();
|
||||
}
|
||||
@@ -722,4 +722,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
public void testSuppression() { doTest(); }
|
||||
public void testRewiringSubclassMethod() { doTest(); }
|
||||
public void testTryWithResourcesCloseThrows() { doTest(); }
|
||||
public void testBooleanOrEquals() { doTest(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user