[java-inspections] DuplicateBranchesInSwitchInspection: don't suggest merging when there's guarded/parenthesized pattern

GitOrigin-RevId: c7eb1fdda31dd6a7c81a9d6002430a83849ca26b
This commit is contained in:
Andrey.Cherkasov
2021-08-05 12:37:53 +00:00
committed by intellij-monorepo-bot
parent cebacbf05f
commit ea7340d2ae
5 changed files with 24 additions and 38 deletions
@@ -126,10 +126,11 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
}
private static boolean isMergeCasesFixAvailable(@NotNull BranchBase duplicate, @NotNull BranchBase original) {
if (duplicate.myIsPattern != original.myIsPattern) {
if (duplicate.myIsGuardedOrParenthesizedPattern || original.myIsGuardedOrParenthesizedPattern) return false;
if (duplicate.myIsTypeTestPattern != original.myIsTypeTestPattern) {
return duplicate.myIsNull || original.myIsNull;
}
return !duplicate.myIsPattern;
return !duplicate.myIsTypeTestPattern;
}
@@ -477,7 +478,8 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
protected final PsiStatement @NotNull [] myStatements;
protected final String @NotNull [] myCommentTexts;
private final boolean myIsDefault;
private final boolean myIsPattern;
private final boolean myIsTypeTestPattern;
private final boolean myIsGuardedOrParenthesizedPattern;
private final boolean myIsNull;
private DuplicatesFinder myFinder;
@@ -489,28 +491,34 @@ public class DuplicateBranchesInSwitchInspection extends LocalInspectionTool {
myStatements = statements;
myCommentTexts = commentTexts;
myIsDefault = ContainerUtil.find(labels, PsiSwitchLabelStatementBase::isDefaultCase) != null;
myIsPattern = isPattern(labels);
myIsTypeTestPattern = isPatternBy(labels, PsiTypeTestPattern.class);
myIsGuardedOrParenthesizedPattern = isPatternBy(labels, PsiGuardedPattern.class, PsiParenthesizedPattern.class);
myIsNull = isNull(labels);
}
private boolean isPattern(T @NotNull [] labels) {
private boolean isPatternBy(T @NotNull [] labels, Class<? extends PsiPattern>... classes) {
return ContainerUtil.find(labels, label -> {
PsiSwitchLabelStatementBase labelStatementBase = ObjectUtils.tryCast(label, PsiSwitchLabelStatementBase.class);
if (labelStatementBase == null) return false;
return PsiTreeUtil.getChildOfType(labelStatementBase.getCaseLabelElementList(), PsiPattern.class) != null;
}) != null;
PsiCaseLabelElement[] labelElements = getCaseLabelElements(label);
if (labelElements == null) return false;
return ContainerUtil.exists(labelElements, labelElement -> PsiTreeUtil.instanceOf(labelElement, classes));
}) != null;
}
private boolean isNull(T @NotNull [] labels) {
if (labels.length != 1) return false;
PsiSwitchLabelStatementBase labelStatement = ObjectUtils.tryCast(labels[0], PsiSwitchLabelStatementBase.class);
if (labelStatement == null) return false;
PsiCaseLabelElementList labelElementList = labelStatement.getCaseLabelElementList();
if (labelElementList == null) return false;
PsiCaseLabelElement[] labelElements = labelElementList.getElements();
PsiCaseLabelElement[] labelElements = getCaseLabelElements(labels[0]);
if (labelElements == null) return false;
return labelElements.length == 1 && ExpressionUtils.isNullLiteral(ObjectUtils.tryCast(labelElements[0], PsiExpression.class));
}
private PsiCaseLabelElement[] getCaseLabelElements(T label) {
PsiSwitchLabelStatementBase labelStatementBase = ObjectUtils.tryCast(label, PsiSwitchLabelStatementBase.class);
if (labelStatementBase == null) return null;
PsiCaseLabelElementList labelElementList = labelStatementBase.getCaseLabelElementList();
if (labelElementList == null) return null;
return labelElementList.getElements();
}
boolean isDefault() {
return myIsDefault;
}
@@ -1,11 +0,0 @@
// "Merge with 'case null'" "GENERIC_ERROR_OR_WARNING"
class C {
void foo(Object o) {
switch (o) {
case null, Number n && n.intValue() == 42 -> bar("A");
case String s -> bar("B");
default -> bar("C");
}
}
void bar(String s){}
}
@@ -1,11 +0,0 @@
// "Merge with 'case Number n && n.intValue() == 42'" "GENERIC_ERROR_OR_WARNING"
class C {
void foo(Object o) {
switch (o) {
case Number n && n.intValue() == 42, null -> bar("A");
case String s -> bar("B");
default -> bar("C");
}
}
void bar(String s){}
}
@@ -1,4 +1,4 @@
// "Merge with 'case null'" "GENERIC_ERROR_OR_WARNING"
// "Merge with 'case null'" "false"
class C {
void foo(Object o) {
switch (o) {
@@ -1,4 +1,4 @@
// "Merge with 'case Number n && n.intValue() == 42'" "GENERIC_ERROR_OR_WARNING"
// "Merge with 'case Number n && n.intValue() == 42'" "false"
class C {
void foo(Object o) {
switch (o) {