diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java index 48ad2cc6a58a..abffef643418 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java @@ -283,7 +283,7 @@ public class DataFlowInspection extends BaseLocalInspectionTool { createSimplifyToAssignmentFix() ); } - else if (shouldReportConditionAlwaysTrueOrFalse(psiAnchor, evaluatesToTrue) && !visitor.silenceConstantCondition(psiAnchor)) { + else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) { final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue); String message = InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.when.reached" : @@ -294,6 +294,11 @@ public class DataFlowInspection extends BaseLocalInspectionTool { } } + private boolean skipReportingConstantCondition(StandardInstructionVisitor visitor, PsiElement psiAnchor, boolean evaluatesToTrue) { + return DONT_REPORT_TRUE_ASSERT_STATEMENTS && isAssertionEffectively(psiAnchor, evaluatesToTrue) || + visitor.silenceConstantCondition(psiAnchor); + } + private static void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder) { Set exprs = runner.getNullableArguments(); for (PsiExpression expr : exprs) { @@ -339,11 +344,24 @@ public class DataFlowInspection extends BaseLocalInspectionTool { } } - private boolean shouldReportConditionAlwaysTrueOrFalse(PsiElement psiAnchor, boolean evaluatesToTrue) { - if (psiAnchor.getParent() instanceof PsiAssertStatement && DONT_REPORT_TRUE_ASSERT_STATEMENTS && evaluatesToTrue) { - return false; + private static boolean isAssertionEffectively(PsiElement psiAnchor, boolean evaluatesToTrue) { + PsiElement parent = psiAnchor.getParent(); + if (parent instanceof PsiAssertStatement) { + return evaluatesToTrue; } - return true; + if (parent instanceof PsiIfStatement && psiAnchor == ((PsiIfStatement)parent).getCondition()) { + PsiStatement thenBranch = ((PsiIfStatement)parent).getThenBranch(); + if (thenBranch instanceof PsiThrowStatement) { + return !evaluatesToTrue; + } + if (thenBranch instanceof PsiBlockStatement) { + PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements(); + if (statements.length == 1 && statements[0] instanceof PsiThrowStatement) { + return !evaluatesToTrue; + } + } + } + return false; } private static boolean isAtRHSOfBooleanAnd(PsiElement expr) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/SkipAssertions.java b/java/java-tests/testData/inspection/dataFlow/fixture/SkipAssertions.java new file mode 100644 index 000000000000..486fdcb5ad4e --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/SkipAssertions.java @@ -0,0 +1,21 @@ +import org.jetbrains.annotations.NotNull; + +class Test { + private static void test(@NotNull Object foo) { + assert foo != null; + } + + private static void test2(@NotNull Object foo) { + if (foo == null) { + throw new IllegalArgumentException(); + } + } + private static void test3(@NotNull Object foo) { + if (foo == null) throw new IllegalArgumentException(); + } + + private static void test4(@NotNull Object foo) { + if (foo != null) throw new IllegalArgumentException(); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java index 282aae37c8f9..6d963c22e705 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionFixtureTest.java @@ -36,7 +36,7 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/"; } - private void doTest() throws Throwable { + private void doTest() { final DataFlowInspection inspection = new DataFlowInspection(); inspection.SUGGEST_NULLABLE_ANNOTATIONS = true; myFixture.enableInspections(inspection); @@ -119,4 +119,11 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas } } + public void testSkipAssertions() { + final DataFlowInspection inspection = new DataFlowInspection(); + inspection.DONT_REPORT_TRUE_ASSERT_STATEMENTS = true; + myFixture.enableInspections(inspection); + myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); + } + } diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index e759d727be9c..6e88899071d3 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -46,7 +46,7 @@ inspection.annotate.method.quickfix.name=Annotate method as ''@{0}'' #dataflow inspection.data.flow.display.name=Constant conditions \\& exceptions inspection.data.flow.nullable.quickfix.option=Suggest @Nullable annotation for methods that may possibly return null and
report nullable values passed to non-annotated parameters -inspection.data.flow.true.asserts.option=Don't report assert statements with condition statically proven to be always true +inspection.data.flow.true.asserts.option=Don't report assertions with condition statically proven to be always true inspection.data.flow.redundant.instanceof.quickfix=Replace with != null inspection.data.flow.simplify.boolean.expression.quickfix=Simplify Boolean Expression inspection.data.flow.simplify.to.assignment.quickfix.name=Simplify to normal assignment