From bbcc8ca24d02012d137207ab5bf1eafd20ca2ba8 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 1 Oct 2018 16:06:01 +0700 Subject: [PATCH] IDEA-199693 Unreachable switch statements are not highlighted after always reachable branch --- .../dataFlow/DataFlowInspectionBase.java | 13 +++++- .../fixture/AlwaysTrueSwitchLabel.java | 43 +++++++++++++++++++ .../DataFlowInspectionTest.java | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/dataFlow/fixture/AlwaysTrueSwitchLabel.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 54421e1bbd31..9d988642ec6b 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 @@ -43,7 +43,6 @@ import java.util.*; import static com.intellij.util.ObjectUtils.tryCast; -@SuppressWarnings("ConditionalExpressionWithIdenticalBranches") public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool { static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection"); @NonNls private static final String SHORT_NAME = "ConstantConditions"; @@ -692,6 +691,18 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool holder.registerProblem(psiAnchor, InspectionsBundle.message("dataflow.message.unreachable.switch.label"), new DeleteSwitchLabelFix((PsiSwitchLabelStatement)psiAnchor)); + } else if (trueSet.contains(instruction)) { + // If switch branch is always reachable, then all the subsequent branches are unreachable (thus weren't analyzed) + PsiSwitchLabelStatement current = (PsiSwitchLabelStatement)psiAnchor; + while(true) { + current = PsiTreeUtil.getNextSiblingOfType(current, PsiSwitchLabelStatement.class); + if (current == null) break; + if (!current.isDefaultCase()) { + holder.registerProblem(current, + InspectionsBundle.message("dataflow.message.unreachable.switch.label"), + new DeleteSwitchLabelFix((PsiSwitchLabelStatement)psiAnchor)); + } + } } } else if (psiAnchor != null && !isFlagCheck(psiAnchor)) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/AlwaysTrueSwitchLabel.java b/java/java-tests/testData/inspection/dataFlow/fixture/AlwaysTrueSwitchLabel.java new file mode 100644 index 000000000000..3f69d76d5e53 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/AlwaysTrueSwitchLabel.java @@ -0,0 +1,43 @@ +class Scratch { + public static void main(String[] args) { + switch("ping") { + case "ping": + System.out.println("ping"); + break; + case "pong": + System.out.println("pong"); + break; + case "simple": + System.out.println("simple"); + break; + default: + break; + } + switch("ping") { + case "pong": + System.out.println("pong"); + break; + case "ping": + System.out.println("ping"); + break; + case "simple": + System.out.println("simple"); + break; + default: + break; + } + switch("ping") { + case "pong": + System.out.println("pong"); + break; + case "simple": + System.out.println("simple"); + break; + case "ping": + System.out.println("ping"); + break; + default: + break; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java index 2751d3bc1424..8326120979a1 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTest.java @@ -657,4 +657,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase { assertEquals(1, intentions.stream().filter(i -> i.getText().equals("Remove 'if' statement")).count()); assertEquals(0, intentions.stream().filter(i -> i.getText().equals("Simplify 'expirationDay != other.expirationDay' to false")).count()); } + public void testAlwaysTrueSwitchLabel() { doTest(); } }