From c308f0b8c0f97ca52b5c66061d15f700cc3e80a7 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 23 Mar 2020 09:30:44 +0700 Subject: [PATCH] IDEA-143315 Suppress zero test extracted; suppress method call result if all args are constants Review ID: IDEA-CR-60202 GitOrigin-RevId: 278d64a98d03fb9f9f2456e8cf8212b969c7d4de --- .../dataFlow/DataFlowInspectionBase.java | 36 +++++++++++++------ .../dataFlow/fixture/LongRangeBasics.java | 12 ------- .../dataFlow/fixture/SuppressZeroReport.java | 29 +++++++++++++++ .../DataFlowRangeAnalysisTest.java | 1 + 4 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/SuppressZeroReport.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 9cec119aa828..9d3d25fb3071 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -40,6 +40,7 @@ import javax.swing.*; import java.text.MessageFormat; import java.util.*; import java.util.function.Consumer; +import java.util.stream.Stream; import static com.intellij.util.ObjectUtils.tryCast; @@ -454,23 +455,36 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec } private static boolean shouldReportZero(PsiExpression ref) { - boolean reportZeroValue = ref instanceof PsiPolyadicExpression && !PsiUtil.isConstantExpression(ref) || - ref instanceof PsiMethodCallExpression; - if (!reportZeroValue) return false; + if (ref instanceof PsiPolyadicExpression) { + if (PsiUtil.isConstantExpression(ref)) return false; + PsiPolyadicExpression polyadic = (PsiPolyadicExpression)ref; + IElementType tokenType = polyadic.getOperationTokenType(); + if (tokenType.equals(JavaTokenType.ASTERISK)) { + PsiMethod method = PsiTreeUtil.getParentOfType(ref, PsiMethod.class, true, PsiLambdaExpression.class, PsiClass.class); + if (MethodUtils.isHashCode(method)) { + // Standard hashCode template generates int result = 0; result = result * 31 + ...; + // so annoying warnings might be produced there + return false; + } + } + } + else if (ref instanceof PsiMethodCallExpression) { + PsiMethodCallExpression call = (PsiMethodCallExpression)ref; + PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); + if (PsiUtil.isConstantExpression(qualifier) && + Stream.of(call.getArgumentList().getExpressions()).allMatch(PsiUtil::isConstantExpression)) { + return false; + } + } + else { + return false; + } PsiElement parent = PsiUtil.skipParenthesizedExprUp(ref.getParent()); PsiBinaryExpression binOp = tryCast(parent, PsiBinaryExpression.class); if (binOp != null && ComparisonUtils.isEqualityComparison(binOp) && (ExpressionUtils.isZero(binOp.getLOperand()) || ExpressionUtils.isZero(binOp.getROperand()))) { return false; } - PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class, true, PsiLambdaExpression.class, PsiClass.class); - if (MethodUtils.isHashCode(method)) { - // Standard hashCode template generates int result = 0; result = result * 31 + ...; - // so annoying warnings might be produced there - if (ref instanceof PsiPolyadicExpression && ((PsiPolyadicExpression)ref).getOperationTokenType().equals(JavaTokenType.ASTERISK)) { - return false; - } - } return true; } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeBasics.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeBasics.java index 20301adb048b..57994ccc5c98 100644 --- a/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeBasics.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongRangeBasics.java @@ -229,16 +229,4 @@ public class LongRangeBasics { System.out.println(); } } - - class HashCode { - Object a, b, c; - - public int hashCode() { - int result = 0; - result = result * 31 + a.hashCode(); - result = result * 31 + b.hashCode(); - result = result * 31 + c.hashCode(); - return result; - } - } } diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/SuppressZeroReport.java b/java/java-tests/testData/inspection/dataFlow/fixture/SuppressZeroReport.java new file mode 100644 index 000000000000..a2a48e24d369 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/SuppressZeroReport.java @@ -0,0 +1,29 @@ +class HashCode { + Object a, b, c; + + public int hashCode() { + int result = 0; + result = result * 31 + a.hashCode(); + result = result * 31 + b.hashCode(); + result = result * 31 + c.hashCode(); + return result; + } + + public int hashCode2() { + int result = 0; + result = result * 31 + a.hashCode(); + result = result * 31 + b.hashCode(); + result = result * 31 + c.hashCode(); + return result; + } + + static final String STRING = "123456"; + static final String PREFIX = "123"; + + void testIndexOf(String s) { + int pos = STRING.indexOf(PREFIX); + if (s.equals(PREFIX)) { + int pos2 = s.indexOf(PREFIX); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java index f5dee776422a..dafdfbf4137c 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowRangeAnalysisTest.java @@ -70,4 +70,5 @@ public class DataFlowRangeAnalysisTest extends DataFlowInspectionTestCase { public void testWidenPlusInLoop() { doTest(); } public void testWidenMulInLoop() { doTest(); } public void testReduceBinOpOnCast() { doTest(); } + public void testSuppressZeroReport() { doTest(); } }