mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
Java: When merging identical branches of 'switch' statement keep the default branch the last (IDEA-204134)
This commit is contained in:
+180
-44
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static com.siyeh.ig.migration.TryWithIdenticalCatchesInspection.collectCommentTexts;
|
||||
import static com.siyeh.ig.migration.TryWithIdenticalCatchesInspection.getCommentText;
|
||||
@@ -54,28 +55,39 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
int size = branches.size();
|
||||
if (size > 1) {
|
||||
boolean[] isDuplicate = new boolean[size];
|
||||
|
||||
int defaultIndex = ContainerUtil.indexOf(branches, Branch::isDefault);
|
||||
if (defaultIndex >= 0) {
|
||||
Branch defaultBranch = branches.get(defaultIndex);
|
||||
for (int index = 0; index < size; index++) {
|
||||
if (index != defaultIndex) {
|
||||
Branch branch = branches.get(index);
|
||||
if (areDuplicates(defaultBranch, branch)) {
|
||||
isDuplicate[index] = isDuplicate[defaultIndex] = true;
|
||||
highlightDefaultDuplicate(branch.myStatements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = 0; index < size - 1; index++) {
|
||||
if (isDuplicate[index]) continue;
|
||||
Branch branch = branches.get(index);
|
||||
|
||||
for (int otherIndex = index + 1; otherIndex < size; otherIndex++) {
|
||||
Branch branch = branches.get(index);
|
||||
if (isDuplicate[otherIndex]) continue;
|
||||
Branch otherBranch = branches.get(otherIndex);
|
||||
|
||||
if (areDuplicates(branch, otherBranch)) {
|
||||
isDuplicate[otherIndex] = true;
|
||||
registerProblem(otherBranch.myStatements, branch.getSwitchLabelText());
|
||||
|
||||
if (!isDuplicate[index]) {
|
||||
isDuplicate[index] = true;
|
||||
registerProblem(branch.myStatements, null);
|
||||
}
|
||||
highlightDuplicate(otherBranch.myStatements, branch.getSwitchLabelText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerProblem(@NotNull PsiStatement[] statements, String switchLabelText) {
|
||||
private void highlightDuplicate(@NotNull PsiStatement[] statements, String switchLabelText) {
|
||||
ProblemDescriptor descriptor = InspectionManager.getInstance(myHolder.getProject())
|
||||
.createProblemDescriptor(statements[0], statements[statements.length - 1],
|
||||
InspectionsBundle.message("inspection.duplicate.branches.in.switch.message"),
|
||||
@@ -83,6 +95,15 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
switchLabelText != null ? new MergeBranchesFix(switchLabelText) : null);
|
||||
myHolder.registerProblem(descriptor);
|
||||
}
|
||||
|
||||
private void highlightDefaultDuplicate(PsiStatement[] statements) {
|
||||
ProblemDescriptor descriptor = InspectionManager.getInstance(myHolder.getProject())
|
||||
.createProblemDescriptor(statements[0], statements[statements.length - 1],
|
||||
InspectionsBundle.message("inspection.duplicate.branches.in.switch.redundant.message"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, myHolder.isOnTheFly(),
|
||||
new DeleteRedundantBranchFix(), new MergeWithDefaultBranchFix());
|
||||
myHolder.registerProblem(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -171,7 +192,7 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
|
||||
@Contract("null -> false")
|
||||
private static boolean isBreakWithoutLabel(@Nullable PsiStatement statement) {
|
||||
return statement instanceof PsiBreakStatement && ((PsiBreakStatement)statement).getLabelIdentifier() == null;
|
||||
return statement instanceof PsiBreakStatement && ((PsiBreakStatement)statement).getLabelExpression() == null;
|
||||
}
|
||||
|
||||
private static class MergeBranchesFix implements LocalQuickFix {
|
||||
@@ -197,53 +218,120 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement startElement = descriptor.getStartElement();
|
||||
FixContext context = new FixContext();
|
||||
if (context.prepare(descriptor.getStartElement(), branch -> mySwitchLabelText.equals(branch.getSwitchLabelText()))) {
|
||||
context.moveBranchLabel();
|
||||
context.deleteRedundantComments();
|
||||
context.deleteStatements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MergeWithDefaultBranchFix implements LocalQuickFix {
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("inspection.duplicate.branches.in.switch.merge.with.default.fix.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
FixContext context = new FixContext();
|
||||
if (context.prepare(descriptor.getStartElement(), Branch::isDefault)) {
|
||||
context.moveBranchLabel();
|
||||
context.deleteRedundantComments();
|
||||
context.deleteStatements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteRedundantBranchFix implements LocalQuickFix {
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return InspectionsBundle.message("inspection.duplicate.branches.in.switch.redundant.fix.name");
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionsBundle.message("inspection.duplicate.branches.in.switch.redundant.fix.family.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
FixContext context = new FixContext();
|
||||
if (context.prepare(descriptor.getStartElement(), Branch::isDefault)) {
|
||||
context.deleteBranchLabel();
|
||||
context.deleteStatements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class FixContext {
|
||||
private Branch myBranchToDelete;
|
||||
private Branch myBranchToMergeWith;
|
||||
private List<PsiElement> myBranchPrefixToMove;
|
||||
private PsiSwitchLabelStatement myLabelToMergeWith;
|
||||
private Set<String> myCommentsToMergeWith;
|
||||
private PsiElement myNextFromLabelToMergeWith;
|
||||
|
||||
private boolean prepare(PsiElement startElement, Predicate<Branch> shouldMergeWith) {
|
||||
PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(startElement, PsiSwitchStatement.class);
|
||||
if (switchStatement == null) return;
|
||||
if (switchStatement == null) return false;
|
||||
|
||||
Branch branchToDelete = null;
|
||||
List<Branch> candidateBranches = null;
|
||||
for (List<Branch> branches : collectSameLengthBranches(switchStatement)) {
|
||||
branchToDelete = ContainerUtil.find(branches, branch -> branch.myStatements[0] == startElement);
|
||||
if (branchToDelete != null) {
|
||||
myBranchToDelete = ContainerUtil.find(branches, branch -> branch.myStatements[0] == startElement);
|
||||
if (myBranchToDelete != null) {
|
||||
candidateBranches = branches;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myBranchToDelete == null || candidateBranches == null) return false;
|
||||
|
||||
if (branchToDelete == null) return;
|
||||
|
||||
Branch branchToMergeWith = null;
|
||||
for (Branch branch : candidateBranches) {
|
||||
if (mySwitchLabelText.equals(branch.getSwitchLabelText()) && areDuplicates(branchToDelete, branch)) {
|
||||
branchToMergeWith = branch;
|
||||
if (shouldMergeWith.test(branch) && areDuplicates(myBranchToDelete, branch)) {
|
||||
myBranchToMergeWith = branch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (branchToMergeWith == null) return;
|
||||
if (myBranchToMergeWith == null) return false;
|
||||
|
||||
List<PsiElement> branchPrefixToMove = branchToDelete.getBranchPrefix();
|
||||
if (branchPrefixToMove.isEmpty()) return;
|
||||
myBranchPrefixToMove = myBranchToDelete.getBranchPrefix();
|
||||
if (myBranchPrefixToMove.isEmpty()) return false;
|
||||
|
||||
PsiSwitchLabelStatement labelToMergeWith =
|
||||
PsiTreeUtil.getPrevSiblingOfType(branchToMergeWith.myStatements[0], PsiSwitchLabelStatement.class);
|
||||
if (labelToMergeWith == null) return;
|
||||
myLabelToMergeWith = PsiTreeUtil.getPrevSiblingOfType(myBranchToMergeWith.myStatements[0], PsiSwitchLabelStatement.class);
|
||||
if (myLabelToMergeWith == null) return false;
|
||||
|
||||
PsiElement oldNextElement = PsiTreeUtil.skipWhitespacesForward(labelToMergeWith);
|
||||
myNextFromLabelToMergeWith = PsiTreeUtil.skipWhitespacesForward(myLabelToMergeWith);
|
||||
|
||||
PsiElement firstElementToMove = branchPrefixToMove.get(0);
|
||||
PsiElement lastElementToMove = branchPrefixToMove.get(branchPrefixToMove.size() - 1);
|
||||
labelToMergeWith.getParent().addRangeAfter(firstElementToMove, lastElementToMove, labelToMergeWith);
|
||||
myCommentsToMergeWith = ContainerUtil.set(myBranchToMergeWith.myCommentTexts);
|
||||
return true;
|
||||
}
|
||||
|
||||
void moveBranchLabel() {
|
||||
PsiElement firstElementToMove = myBranchPrefixToMove.get(0);
|
||||
PsiElement lastElementToMove = myBranchPrefixToMove.get(myBranchPrefixToMove.size() - 1);
|
||||
|
||||
PsiElement moveTarget = myLabelToMergeWith;
|
||||
if (myLabelToMergeWith.isDefaultCase()) {
|
||||
PsiElement prevElement = PsiTreeUtil.skipWhitespacesAndCommentsBackward(myLabelToMergeWith);
|
||||
if (prevElement != null) moveTarget = prevElement;
|
||||
}
|
||||
moveTarget.getParent().addRangeAfter(firstElementToMove, lastElementToMove, moveTarget);
|
||||
firstElementToMove.getParent().deleteChildRange(firstElementToMove, lastElementToMove);
|
||||
}
|
||||
|
||||
Set<String> commentsToMergeWith = ContainerUtil.set(branchToMergeWith.myCommentTexts);
|
||||
deleteRedundantComments(labelToMergeWith.getNextSibling(), oldNextElement, commentsToMergeWith);
|
||||
|
||||
void deleteStatements() {
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
PsiStatement[] statementsToDelete = branchToDelete.getStatementsToDelete();
|
||||
PsiStatement[] statementsToDelete = myBranchToDelete.getStatementsToDelete();
|
||||
for (PsiStatement statement : statementsToDelete) {
|
||||
PsiTreeUtil.processElements(statement, child -> {
|
||||
if (isRedundantComment(commentsToMergeWith, child)) {
|
||||
if (isRedundantComment(myCommentsToMergeWith, child)) {
|
||||
tracker.markUnchanged(child);
|
||||
}
|
||||
return true;
|
||||
@@ -255,13 +343,13 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
tracker.deleteAndRestoreComments(statementsToDelete[statementsToDelete.length - 1]);
|
||||
}
|
||||
|
||||
private static void deleteRedundantComments(@Nullable PsiElement startElement,
|
||||
@Nullable PsiElement stopElement,
|
||||
@NotNull Set<String> existingComments) {
|
||||
void deleteRedundantComments() {
|
||||
List<PsiElement> redundantComments = new ArrayList<>();
|
||||
for (PsiElement element = startElement; element != null && element != stopElement; element = element.getNextSibling()) {
|
||||
for (PsiElement element = myLabelToMergeWith.getNextSibling();
|
||||
element != null && element != myNextFromLabelToMergeWith;
|
||||
element = element.getNextSibling()) {
|
||||
PsiTreeUtil.processElements(element, child -> {
|
||||
if (isRedundantComment(existingComments, child)) {
|
||||
if (isRedundantComment(myCommentsToMergeWith, child)) {
|
||||
redundantComments.add(child);
|
||||
}
|
||||
return true;
|
||||
@@ -278,11 +366,37 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void deleteBranchLabel() {
|
||||
List<PsiElement> toDelete = new ArrayList<>();
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
|
||||
for (PsiElement element : myBranchPrefixToMove) {
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
continue;
|
||||
}
|
||||
toDelete.add(element);
|
||||
PsiTreeUtil.processElements(element, child -> {
|
||||
if (isRedundantComment(myCommentsToMergeWith, child)) {
|
||||
tracker.markUnchanged(child);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
int size = toDelete.size();
|
||||
if (size != 0) {
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
tracker.delete(toDelete.get(i));
|
||||
}
|
||||
tracker.deleteAndRestoreComments(toDelete.get(size - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Branch {
|
||||
private final PsiStatement[] myStatements;
|
||||
private final String[] myCommentTexts;
|
||||
private final boolean myIsDefault;
|
||||
private final boolean myIsSimpleExit;
|
||||
private final boolean myCanFallThrough;
|
||||
|
||||
@@ -298,6 +412,7 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
}
|
||||
myStatements = statementList.toArray(PsiStatement.EMPTY_ARRAY);
|
||||
myCommentTexts = commentTexts;
|
||||
myIsDefault = calculateIsDefault(statementList.get(0));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -317,6 +432,10 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
return myStatements.length;
|
||||
}
|
||||
|
||||
boolean isDefault() {
|
||||
return myIsDefault;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getSwitchLabelText() {
|
||||
PsiSwitchLabelStatement switchLabel = null;
|
||||
@@ -330,10 +449,12 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
if (switchLabel.isDefaultCase()) {
|
||||
return PsiKeyword.DEFAULT;
|
||||
}
|
||||
//todo support multi-value label
|
||||
PsiExpression value = switchLabel.getCaseValue();
|
||||
if (value != null) {
|
||||
return PsiKeyword.CASE + ' ' + value.getText();
|
||||
PsiExpressionList caseValues = switchLabel.getCaseValues();
|
||||
if (caseValues != null) {
|
||||
PsiExpression[] expressions = caseValues.getExpressions();
|
||||
if (expressions.length != 0) {
|
||||
return PsiKeyword.CASE + ' ' + expressions[0].getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -346,7 +467,7 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
List<PsiElement> getBranchPrefix() {
|
||||
List<PsiElement> result = new ArrayList<>();
|
||||
for (PsiElement element = myStatements[0].getPrevSibling();
|
||||
element != null && (element instanceof PsiSwitchLabelStatement || !(element instanceof PsiStatement));
|
||||
element != null && !isLeftBrace(element) && (element instanceof PsiSwitchLabelStatement || !(element instanceof PsiStatement));
|
||||
element = element.getPrevSibling()) {
|
||||
result.add(element);
|
||||
}
|
||||
@@ -354,6 +475,10 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isLeftBrace(PsiElement element) {
|
||||
return element instanceof PsiJavaToken && JavaTokenType.LBRACE.equals(((PsiJavaToken)element).getTokenType());
|
||||
}
|
||||
|
||||
PsiStatement[] getStatementsToDelete() {
|
||||
PsiStatement nextStatement = PsiTreeUtil.getNextSiblingOfType(myStatements[myStatements.length - 1], PsiStatement.class);
|
||||
if (isBreakWithoutLabel(nextStatement)) {
|
||||
@@ -405,6 +530,17 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean calculateIsDefault(PsiStatement statement) {
|
||||
for (PsiElement element = PsiTreeUtil.getPrevSiblingOfType(statement, PsiStatement.class);
|
||||
element instanceof PsiSwitchLabelStatement;
|
||||
element = PsiTreeUtil.getPrevSiblingOfType(element, PsiStatement.class)) {
|
||||
if (((PsiSwitchLabelStatement)element).isDefaultCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Comments {
|
||||
|
||||
+2
-2
@@ -2,11 +2,11 @@ class C {
|
||||
int foo(int n, boolean b) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">if(b) {
|
||||
if(b) {
|
||||
return bar("A");
|
||||
} else {
|
||||
break;
|
||||
}</weak_warning>
|
||||
}
|
||||
case 2:
|
||||
if(b) {
|
||||
return bar("B");
|
||||
|
||||
@@ -2,12 +2,12 @@ class C {
|
||||
void foo(int n, boolean b) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">if(b) {
|
||||
if(b) {
|
||||
bar("A");
|
||||
} else {
|
||||
bar("z");
|
||||
}
|
||||
bar("o");</weak_warning>
|
||||
bar("o");
|
||||
break;
|
||||
case 2:
|
||||
if(b) {
|
||||
|
||||
@@ -4,8 +4,8 @@ class C {
|
||||
for (int i = 0; i < n; i++) {
|
||||
switch (i % 4) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">s += i;
|
||||
continue;</weak_warning>
|
||||
s += i;
|
||||
continue;
|
||||
case 2:
|
||||
continue;
|
||||
case 3:
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
case 1:
|
||||
<weak_warning descr="Branch in 'switch' statement is a duplicate of the default branch">bar("A");</weak_warning>
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
bar("A");
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ enum T {
|
||||
int foo(T t) {
|
||||
switch (t) {
|
||||
case A:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">return t.ordinal(); // comment 1</weak_warning>
|
||||
return t.ordinal(); // comment 1
|
||||
|
||||
case B:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">return t.ordinal();</weak_warning>
|
||||
|
||||
@@ -2,7 +2,7 @@ class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
bar("A");
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
|
||||
@@ -2,7 +2,7 @@ class C {
|
||||
String foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">return "A";</weak_warning>
|
||||
return "A";
|
||||
case 2:
|
||||
return "B";
|
||||
case 3:
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ enum C {
|
||||
switch (c) {
|
||||
case ORIGINAL_CODE_WITH_COMMENT:
|
||||
/* comment 1 */
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">return "A";</weak_warning>
|
||||
return "A";
|
||||
case THE_SAME_CODE_WITH_DIFFERENT_COMMENT:
|
||||
/* comment 2 */
|
||||
return "A";
|
||||
|
||||
@@ -2,7 +2,7 @@ class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
bar("A");
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
|
||||
@@ -2,7 +2,7 @@ class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
bar("A");
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
@@ -10,7 +10,7 @@ class C {
|
||||
case 3:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
break;
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Branch in 'switch' statement is a duplicate of the default branch">bar("A");</weak_warning>
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 3:
|
||||
<weak_warning descr="Branch in 'switch' statement is a duplicate of the default branch">bar("A");</weak_warning>
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ class C {
|
||||
String foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">throw new IllegalArgumentException("A");</weak_warning>
|
||||
throw new IllegalArgumentException("A");
|
||||
case 2:
|
||||
throw new IllegalStateException("A");
|
||||
case 3:
|
||||
|
||||
@@ -3,7 +3,7 @@ class C {
|
||||
switch (n) {
|
||||
case 1:
|
||||
case 2:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
bar("A");
|
||||
break;
|
||||
case 3:
|
||||
<weak_warning descr="Duplicate branch in 'switch' statement">bar("A");</weak_warning>
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
/*comment 2*/
|
||||
bar("A");
|
||||
break;/*comment 1*/
|
||||
/*comment 3*/
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@ class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
default:
|
||||
case 4:
|
||||
bar("A");
|
||||
break;
|
||||
case 2:
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 3:
|
||||
bar("A");
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
/*comment 2*/
|
||||
bar("A");
|
||||
break;
|
||||
/*comment 1*/
|
||||
case 1:
|
||||
/*comment 2*/
|
||||
bar("A");<caret>
|
||||
/*comment 3*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Delete redundant 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ class C {
|
||||
case 3:
|
||||
bar("A");
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// "Merge with the default 'switch' branch" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
void foo(int n) {
|
||||
switch (n) {
|
||||
case 1:
|
||||
bar("A");<caret>
|
||||
break;
|
||||
case 2:
|
||||
bar("B");
|
||||
break;
|
||||
case 3:
|
||||
bar("A");
|
||||
break;
|
||||
default:
|
||||
bar("A");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void bar(String s){}
|
||||
}
|
||||
+2
@@ -28,6 +28,8 @@ class DuplicateBranchesInSwitchTest : LightCodeInsightFixtureTestCase() {
|
||||
fun testNoLastBreak() = doTest()
|
||||
fun testFallThroughToBreak() = doTest()
|
||||
fun testThreeDuplicates() = doTest()
|
||||
fun testThreeDuplicatesDefault() = doTest()
|
||||
fun testDuplicateAfterDefault() = doTest()
|
||||
fun testTwoCaseLabels() = doTest()
|
||||
fun testComplexBranches() = doTest()
|
||||
fun testBreakWithLabel() = doTest()
|
||||
|
||||
@@ -1043,6 +1043,10 @@ inspection.duplicate.branches.in.switch.display.name=Duplicate branches in 'swit
|
||||
inspection.duplicate.branches.in.switch.message=Duplicate branch in 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.fix.family.name=Merge duplicate branches of 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.fix.name=Merge with ''{0}:''
|
||||
inspection.duplicate.branches.in.switch.redundant.message=Branch in 'switch' statement is a duplicate of the default branch
|
||||
inspection.duplicate.branches.in.switch.redundant.fix.family.name=Delete redundant branches of 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.redundant.fix.name=Delete redundant 'switch' branch
|
||||
inspection.duplicate.branches.in.switch.merge.with.default.fix.name=Merge with the default 'switch' branch
|
||||
|
||||
inspection.switch.labeled.rule.can.be.code.block.display.name=Labeled switch rule can have code block
|
||||
inspection.switch.labeled.rule.can.be.code.block.expression.message=Labeled rule's result expression can be wrapped with code block
|
||||
|
||||
Reference in New Issue
Block a user