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(); }
}