mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-dfa] IDEA-307660 Avoid double reporting between "Constant values" and "Pointless boolean expression"
GitOrigin-RevId: 97cf073bd5bcd69b8903e5cf2e915fb2a4261b6b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1a4b34963b
commit
e0f8104e43
+6
@@ -32,6 +32,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.bugs.EqualsWithItselfInspection;
|
||||
import com.siyeh.ig.controlflow.PointlessBooleanExpressionInspection;
|
||||
import com.siyeh.ig.fixes.EqualsToEqualityFix;
|
||||
import com.siyeh.ig.numeric.ComparisonToNaNInspection;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
@@ -325,6 +326,11 @@ public class ConstantValueInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
if (method == null || !JavaMethodContractUtil.isPure(method)) return true;
|
||||
}
|
||||
}
|
||||
if (new PointlessBooleanExpressionInspection().getExpressionKind(expression) !=
|
||||
PointlessBooleanExpressionInspection.BooleanExpressionKind.UNKNOWN) {
|
||||
// avoid double reporting
|
||||
return true;
|
||||
}
|
||||
while (expression != null && BoolUtils.isNegation(expression)) {
|
||||
expression = BoolUtils.getNegated(expression);
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// IDEA-304296
|
||||
class BooleanOrEquals {
|
||||
void foo(boolean a, boolean b) {
|
||||
boolean c = !(b && false);
|
||||
boolean d = a ^ b ^ true;
|
||||
boolean x = a ^ !true ^ b;
|
||||
|
||||
boolean y = false || <warning descr="Condition 'c' is always 'true' when reached">c</warning>;
|
||||
boolean z = b != true;
|
||||
}
|
||||
|
||||
static int i = 1;
|
||||
public static void main(String[] args) {
|
||||
boolean b = false;
|
||||
if (i == 1 && (b |= true))
|
||||
System.out.println("i == 1");
|
||||
if (i == 1 && (<warning descr="Condition 'b' at the left side of assignment expression is always 'true'. Can be simplified">b</warning> |= false))
|
||||
System.out.println("i == 1");
|
||||
if (<warning descr="Variable update does nothing">b</warning> |= false)
|
||||
System.out.println("i == 1");
|
||||
if (b |= true)
|
||||
System.out.println("i == 1");
|
||||
if (<warning descr="Variable is already assigned to this value">b</warning> = true)
|
||||
System.out.println("i == 1");
|
||||
System.out.println(b);
|
||||
|
||||
if (i == 1 && (<warning descr="Condition 'b' at the left side of assignment expression is always 'true'. Can be simplified">b</warning> &= true)) { }
|
||||
if (<warning descr="Condition 'i == 1 && (b &= false)' is always 'false'">i == 1 && (<warning descr="Condition 'b' at the left side of assignment expression is always 'true'. Can be simplified">b</warning> &= false)</warning>) { }
|
||||
if (<warning descr="Variable update does nothing">b</warning> &= true) {}
|
||||
if (b &= false) {}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -723,4 +723,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
public void testRewiringSubclassMethod() { doTest(); }
|
||||
public void testTryWithResourcesCloseThrows() { doTest(); }
|
||||
public void testBooleanOrEquals() { doTest(); }
|
||||
public void testDuplicatedByPointlessBooleanInspection() { doTest(); }
|
||||
}
|
||||
|
||||
+47
-40
@@ -41,7 +41,7 @@ import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PointlessBooleanExpressionInspection extends BaseInspection implements CleanupLocalInspectionTool {
|
||||
private enum BooleanExpressionKind {
|
||||
public enum BooleanExpressionKind {
|
||||
USELESS, USELESS_WITH_SIDE_EFFECTS, UNKNOWN
|
||||
}
|
||||
|
||||
@@ -441,9 +441,6 @@ public class PointlessBooleanExpressionInspection extends BaseInspection impleme
|
||||
if (parent instanceof PsiExpression && getExpressionKind((PsiExpression)parent) != BooleanExpressionKind.UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
if (containsEscapingPatternVariable(expression)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String replacement = buildSimplifiedExpression(expression, new StringBuilder(), new CommentTracker()).toString();
|
||||
final Supplier<PsiElement> newBodySupplier =
|
||||
@@ -457,52 +454,62 @@ public class PointlessBooleanExpressionInspection extends BaseInspection impleme
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private BooleanExpressionKind getExpressionKind(PsiExpression expression) {
|
||||
public BooleanExpressionKind getExpressionKind(PsiExpression expression) {
|
||||
if ((expression instanceof PsiPrefixExpression || expression instanceof PsiPolyadicExpression)
|
||||
&& containsEscapingPatternVariable(expression)) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
if (expression instanceof PsiPrefixExpression || expression instanceof PsiAssignmentExpression) {
|
||||
return evaluate(expression) != null ? BooleanExpressionKind.USELESS : BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
if (expression instanceof PsiPolyadicExpression polyadicExpression) {
|
||||
final IElementType sign = polyadicExpression.getOperationTokenType();
|
||||
if (!booleanTokens.contains(sign)) {
|
||||
return getPolyadicKind(polyadicExpression);
|
||||
}
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private BooleanExpressionKind getPolyadicKind(PsiPolyadicExpression expression) {
|
||||
final IElementType sign = expression.getOperationTokenType();
|
||||
if (!booleanTokens.contains(sign)) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
final PsiExpression[] operands = expression.getOperands();
|
||||
boolean containsConstant = false;
|
||||
boolean stopCheckingSideEffects = false;
|
||||
boolean sideEffectMayBeRemoved = false;
|
||||
boolean reducedToConstant = false;
|
||||
for (PsiExpression operand : operands) {
|
||||
if (operand == null) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
final PsiExpression[] operands = polyadicExpression.getOperands();
|
||||
boolean containsConstant = false;
|
||||
boolean stopCheckingSideEffects = false;
|
||||
boolean sideEffectMayBeRemoved = false;
|
||||
boolean reducedToConstant = false;
|
||||
for (PsiExpression operand : operands) {
|
||||
if (operand == null) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
final PsiType type = operand.getType();
|
||||
if (type == null || !type.equals(PsiType.BOOLEAN) && !type.equalsToText(CommonClassNames.JAVA_LANG_BOOLEAN)) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
if (!stopCheckingSideEffects && SideEffectChecker.mayHaveSideEffects(operand)) {
|
||||
sideEffectMayBeRemoved = true;
|
||||
continue;
|
||||
}
|
||||
Boolean value = evaluate(operand);
|
||||
if (value != null) {
|
||||
containsConstant = true;
|
||||
if ((JavaTokenType.ANDAND.equals(sign) && !value) || (JavaTokenType.OROR.equals(sign) && value)) {
|
||||
stopCheckingSideEffects = true;
|
||||
reducedToConstant = true;
|
||||
}
|
||||
final PsiType type = operand.getType();
|
||||
if (type == null || !type.equals(PsiType.BOOLEAN) && !type.equalsToText(CommonClassNames.JAVA_LANG_BOOLEAN)) {
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
if (!stopCheckingSideEffects && SideEffectChecker.mayHaveSideEffects(operand)) {
|
||||
sideEffectMayBeRemoved = true;
|
||||
continue;
|
||||
}
|
||||
Boolean value = evaluate(operand);
|
||||
if (value != null) {
|
||||
containsConstant = true;
|
||||
if ((JavaTokenType.ANDAND.equals(sign) && !value) || (JavaTokenType.OROR.equals(sign) && value)) {
|
||||
stopCheckingSideEffects = true;
|
||||
reducedToConstant = true;
|
||||
}
|
||||
if ((JavaTokenType.AND.equals(sign) && !value) || (JavaTokenType.OR.equals(sign) && value)) {
|
||||
reducedToConstant = true;
|
||||
}
|
||||
if ((JavaTokenType.AND.equals(sign) && !value) || (JavaTokenType.OR.equals(sign) && value)) {
|
||||
reducedToConstant = true;
|
||||
}
|
||||
}
|
||||
if (containsConstant) {
|
||||
if (sideEffectMayBeRemoved && reducedToConstant) {
|
||||
return CodeBlockSurrounder.canSurround(expression)
|
||||
? BooleanExpressionKind.USELESS_WITH_SIDE_EFFECTS
|
||||
: BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
return BooleanExpressionKind.USELESS;
|
||||
}
|
||||
if (containsConstant) {
|
||||
if (sideEffectMayBeRemoved && reducedToConstant) {
|
||||
return CodeBlockSurrounder.canSurround(expression)
|
||||
? BooleanExpressionKind.USELESS_WITH_SIDE_EFFECTS
|
||||
: BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
return BooleanExpressionKind.USELESS;
|
||||
}
|
||||
return BooleanExpressionKind.UNKNOWN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user