From 958ab9bc297c5a4973ffbd50a942a2e185b6d2d1 Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Fri, 30 Nov 2018 14:19:22 +0300 Subject: [PATCH] Java: Highlight redundant 'break' and braces as unused symbols (IDEA-202623) --- ...tLabeledSwitchRuleCodeBlockInspection.java | 64 +++++++++---------- .../RedundantLabeledSwitchRuleCodeBlock.html | 2 +- .../SwitchLabeledRuleCanBeCodeBlock.html | 2 +- .../InExpression.java | 6 +- .../InStatement.java | 6 +- .../afterCallInExpression.java | 2 +- .../afterCallInStatement.java | 4 +- .../afterConstInExpression.java | 4 +- .../afterThrowInExpression.java | 2 +- .../afterThrowInStatement.java | 4 +- .../beforeCallInExpression.java | 4 +- .../beforeCallInStatement.java | 4 +- .../beforeConstInExpression.java | 4 +- .../beforeThrowInExpression.java | 6 +- .../beforeThrowInStatement.java | 4 +- 15 files changed, 58 insertions(+), 60 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/RedundantLabeledSwitchRuleCodeBlockInspection.java b/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/RedundantLabeledSwitchRuleCodeBlockInspection.java index d7558e525a0d..385b5c7fb077 100644 --- a/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/RedundantLabeledSwitchRuleCodeBlockInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/enhancedSwitch/RedundantLabeledSwitchRuleCodeBlockInspection.java @@ -1,10 +1,7 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection.enhancedSwitch; -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.*; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -33,33 +30,41 @@ public class RedundantLabeledSwitchRuleCodeBlockInspection extends LocalInspecti public void visitSwitchLabeledRuleStatement(PsiSwitchLabeledRuleStatement statement) { super.visitSwitchLabeledRuleStatement(statement); - PsiStatement bodyStatement = unwrapSingleStatementCodeBlock(statement.getBody()); - if (bodyStatement instanceof PsiBreakStatement) { - if (((PsiBreakStatement)bodyStatement).getValueExpression() != null) { - registerProblem(statement); + PsiStatement body = statement.getBody(); + if (body instanceof PsiBlockStatement) { + PsiCodeBlock codeBlock = ((PsiBlockStatement)body).getCodeBlock(); + PsiStatement bodyStatement = unwrapSingleStatementCodeBlock(codeBlock); + + if (bodyStatement instanceof PsiBreakStatement) { + PsiBreakStatement breakStatement = (PsiBreakStatement)bodyStatement; + if (breakStatement.getValueExpression() != null) { + PsiKeyword breakKeyword = ObjectUtils.tryCast(breakStatement.getFirstChild(), PsiKeyword.class); + registerProblem(breakKeyword); + } + } + else if (bodyStatement instanceof PsiThrowStatement || bodyStatement instanceof PsiExpressionStatement) { + registerProblem(codeBlock.getLBrace()); + if (isOnTheFly) registerProblem(codeBlock.getRBrace()); } - } - else if (bodyStatement instanceof PsiThrowStatement || bodyStatement instanceof PsiExpressionStatement) { - registerProblem(statement); } } - public void registerProblem(PsiSwitchLabeledRuleStatement statement) { - holder.registerProblem(ObjectUtils.notNull(ObjectUtils.tryCast(statement.getFirstChild(), PsiKeyword.class), statement), - message("inspection.labeled.switch.rule.redundant.code.block.message"), - new UnwrapCodeBlockFix()); + private void registerProblem(@Nullable PsiElement element) { + if (element != null) { + holder.registerProblem(element, + message("inspection.labeled.switch.rule.redundant.code.block.message"), + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + new UnwrapCodeBlockFix()); + } } }; } @Nullable - private static PsiStatement unwrapSingleStatementCodeBlock(@Nullable PsiStatement statement) { - if (statement instanceof PsiBlockStatement) { - PsiCodeBlock block = ((PsiBlockStatement)statement).getCodeBlock(); - PsiStatement firstStatement = PsiTreeUtil.getNextSiblingOfType(block.getLBrace(), PsiStatement.class); - if (firstStatement != null && PsiTreeUtil.getNextSiblingOfType(firstStatement, PsiStatement.class) == null) { - return firstStatement; - } + private static PsiStatement unwrapSingleStatementCodeBlock(PsiCodeBlock block) { + PsiStatement firstStatement = PsiTreeUtil.getNextSiblingOfType(block.getLBrace(), PsiStatement.class); + if (firstStatement != null && PsiTreeUtil.getNextSiblingOfType(firstStatement, PsiStatement.class) == null) { + return firstStatement; } return null; } @@ -74,14 +79,9 @@ public class RedundantLabeledSwitchRuleCodeBlockInspection extends LocalInspecti @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiElement element = descriptor.getStartElement(); - if (element instanceof PsiKeyword) { - element = element.getParent(); - } - if (element instanceof PsiSwitchLabeledRuleStatement) { - PsiStatement body = ((PsiSwitchLabeledRuleStatement)element).getBody(); - - PsiStatement bodyStatement = unwrapSingleStatementCodeBlock(body); + PsiBlockStatement body = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiBlockStatement.class); + if (body != null && body.getParent() instanceof PsiSwitchLabeledRuleStatement) { + PsiStatement bodyStatement = unwrapSingleStatementCodeBlock(body.getCodeBlock()); if (bodyStatement instanceof PsiBreakStatement) { unwrapBreakValue(body, (PsiBreakStatement)bodyStatement); } @@ -95,14 +95,12 @@ public class RedundantLabeledSwitchRuleCodeBlockInspection extends LocalInspecti PsiExpression valueExpression = breakStatement.getValueExpression(); if (valueExpression != null) { CommentTracker tracker = new CommentTracker(); - tracker.markUnchanged(valueExpression); - tracker.replaceAndRestoreComments(body, valueExpression.getText() + ';'); + tracker.replaceAndRestoreComments(body, tracker.text(valueExpression) + ';'); } } private static void unwrap(PsiStatement body, PsiStatement bodyStatement) { CommentTracker tracker = new CommentTracker(); - tracker.markUnchanged(bodyStatement); tracker.replaceAndRestoreComments(body, bodyStatement); } } diff --git a/java/java-impl/src/inspectionDescriptions/RedundantLabeledSwitchRuleCodeBlock.html b/java/java-impl/src/inspectionDescriptions/RedundantLabeledSwitchRuleCodeBlock.html index e722f60ffe4a..43c174b885b7 100644 --- a/java/java-impl/src/inspectionDescriptions/RedundantLabeledSwitchRuleCodeBlock.html +++ b/java/java-impl/src/inspectionDescriptions/RedundantLabeledSwitchRuleCodeBlock.html @@ -1,7 +1,7 @@ Reports rules of switch expression or enhanced switch statement which have redundant code block.
-Available if the language level is at least Java 12 Preview +Available if the language level is at least Java 12 Preview.

New in 2019.1

diff --git a/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html b/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html index cec2dbbbc7b0..7f513635ccf5 100644 --- a/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html +++ b/java/java-impl/src/inspectionDescriptions/SwitchLabeledRuleCanBeCodeBlock.html @@ -1,7 +1,7 @@ Reports rules of switch expression or enhanced switch statement which can be converted to a code block.
-Available if the language level is at least Java 12 Preview +Available if the language level is at least Java 12 Preview.

New in 2019.1

diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InExpression.java index 6e46e8c4b5a8..e25733a56291 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InExpression.java @@ -2,10 +2,10 @@ class C { String foo(int n) { return switch (n) { case 1 -> Integer.toString(n); - case 2 -> { break Integer.toString(n); } + case 2 -> { break Integer.toString(n); } case 3 -> throw new RuntimeException(); - case 4 -> { throw new RuntimeException(); } - case 5 -> { break "a";} + case 4 -> { throw new RuntimeException(); } + case 5 -> { break "a";} default -> "b"; }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InStatement.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InStatement.java index 813f468689f1..b6d231f7c9ea 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InStatement.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlock/InStatement.java @@ -3,10 +3,10 @@ class C { String s; switch (n) { case 1 -> s = Integer.toString(n); - case 2 -> { s = Integer.toString(n); } + case 2 -> { s = Integer.toString(n); } case 3 -> throw new RuntimeException(); - case 4 -> { throw new RuntimeException(); } - case 5 -> { s = "a"; } + case 4 -> { throw new RuntimeException(); } + case 5 -> { s = "a"; } default -> s = "b"; }; return s; diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInExpression.java index 652017771b6e..0cd57f4074f3 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInExpression.java @@ -1,4 +1,4 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInStatement.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInStatement.java index 3c7cc94e783b..c527f8fb89b8 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInStatement.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterCallInStatement.java @@ -1,9 +1,9 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { void foo(int n) { String s; switch (n) { - case 1 -> System.out.println(n); + case 1 -> System.out.println(n); default -> System.out.println(); }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterConstInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterConstInExpression.java index 5d207d46ad1d..3fa486fe32f3 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterConstInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterConstInExpression.java @@ -1,8 +1,8 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { - case 1 -> /*1*/ /*2*/ /*3*/ "a"; /*4*/ + case 1 -> /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ "a"; /*6*/ default -> "b"; }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInExpression.java index 9960f9b01c40..72b890cb7d20 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInExpression.java @@ -1,4 +1,4 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInStatement.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInStatement.java index e0becd3ae5a2..d453062d5e13 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInStatement.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/afterThrowInStatement.java @@ -1,8 +1,8 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { switch (n) { - case 1 -> /*1*//*2*/throw /*3*/new RuntimeException(/*4*/); /*5*//*6*/ + case 1 -> /*1*//*2*/throw /*3*/new RuntimeException(/*4*/)/*5*/; /*6*//*7*/ default ->System.out.println(); }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInExpression.java index f332ab4f591b..ccc26886d186 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInExpression.java @@ -1,8 +1,8 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { - case 1 -> { break Integer.toString(n); } + case 1 -> { break Integer.toString(n); } default -> "b"; }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInStatement.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInStatement.java index 4126157dcff7..2df03f479191 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInStatement.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeCallInStatement.java @@ -1,9 +1,9 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { void foo(int n) { String s; switch (n) { - case 1 -> { System.out.println(n); } + case 1 -> { System.out.println(n); } default -> System.out.println(); }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeConstInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeConstInExpression.java index 2f2dccc8d0b6..15be60ee5c6f 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeConstInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeConstInExpression.java @@ -1,8 +1,8 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { - case 1 -> /*1*/ { break /*2*/"a"; /*3*/ } /*4*/ + case 1 -> /*1*/ { /*2*/break /*3*/"a"/*4*/; /*5*/ } /*6*/ default -> "b"; }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInExpression.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInExpression.java index eaaf4fd981a0..3f40027d1ecd 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInExpression.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInExpression.java @@ -1,10 +1,10 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { return switch (n) { - case 1 -> { + case 1 -> { throw new RuntimeException(); - } + } default -> "b"; }; } diff --git a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInStatement.java b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInStatement.java index 3360b37b8d46..cc1a2c6cc60c 100644 --- a/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInStatement.java +++ b/java/java-tests/testData/inspection/redundantLabeledSwitchRuleCodeBlockFix/beforeThrowInStatement.java @@ -1,8 +1,8 @@ -// "Unwrap code block of labeled rule" "GENERIC_ERROR_OR_WARNING" +// "Unwrap code block of labeled rule" "LIKE_UNUSED_SYMBOL" class C { String foo(int n) { switch (n) { - case 1 -> /*1*/{/*2*/throw /*3*/new RuntimeException(/*4*/); /*5*/}/*6*/ + case 1 -> /*1*/{/*2*/throw /*3*/new RuntimeException(/*4*/)/*5*/; /*6*/}/*7*/ default ->System.out.println(); }; }