mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
IDEA-203119 Unwrap switch statement: support expressions
This commit is contained in:
@@ -316,9 +316,18 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
|
||||
PsiSwitchBlock statement = labelStatement.getEnclosingSwitchBlock();
|
||||
if (statement == null) continue;
|
||||
if (PsiTreeUtil.getChildrenOfTypeAsList(statement.getBody(), PsiSwitchLabelStatementBase.class).size() == 1 &&
|
||||
Objects.requireNonNull(labelStatement.getCaseValues()).getExpressionCount() == 1 &&
|
||||
(!(statement instanceof PsiSwitchStatement) || BreakConverter.from((PsiSwitchStatement)statement) == null)) {
|
||||
continue;
|
||||
Objects.requireNonNull(labelStatement.getCaseValues()).getExpressionCount() == 1) {
|
||||
boolean canUnwrap;
|
||||
if (statement instanceof PsiSwitchStatement) {
|
||||
canUnwrap = BreakConverter.from(statement) != null;
|
||||
}
|
||||
else {
|
||||
canUnwrap = labelStatement instanceof PsiSwitchLabeledRuleStatement &&
|
||||
((PsiSwitchLabeledRuleStatement)labelStatement).getBody() instanceof PsiExpressionStatement;
|
||||
}
|
||||
if (!canUnwrap) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!StreamEx.iterate(labelStatement, Objects::nonNull, l -> PsiTreeUtil.getPrevSiblingOfType(l, PsiSwitchLabelStatementBase.class))
|
||||
.skip(1).map(PsiSwitchLabelStatementBase::getCaseValues)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.BlockUtils;
|
||||
import com.intellij.codeInspection.CommonQuickFixBundle;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.dataFlow.fix.DeleteSwitchLabelFix;
|
||||
@@ -24,7 +23,7 @@ public class UnwrapSwitchLabelFix implements LocalQuickFix {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return CommonQuickFixBundle.message("fix.unwrap.statement", PsiKeyword.SWITCH);
|
||||
return "Remove unreachable branches";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,21 +32,39 @@ public class UnwrapSwitchLabelFix implements LocalQuickFix {
|
||||
if (label == null) return;
|
||||
PsiSwitchLabelStatementBase labelStatement = PsiImplUtil.getSwitchLabel(label);
|
||||
if (labelStatement == null) return;
|
||||
PsiSwitchStatement statement = labelStatement.getEnclosingSwitchStatement();
|
||||
if (statement == null) return;
|
||||
List<PsiSwitchLabelStatementBase> labels = PsiTreeUtil.getChildrenOfTypeAsList(statement.getBody(), PsiSwitchLabelStatementBase.class);
|
||||
PsiSwitchBlock block = labelStatement.getEnclosingSwitchBlock();
|
||||
if (block == null) return;
|
||||
List<PsiSwitchLabelStatementBase> labels = PsiTreeUtil.getChildrenOfTypeAsList(block.getBody(), PsiSwitchLabelStatementBase.class);
|
||||
for (PsiSwitchLabelStatementBase otherLabel : labels) {
|
||||
if (otherLabel != labelStatement) {
|
||||
DeleteSwitchLabelFix.deleteLabel(otherLabel);
|
||||
}
|
||||
}
|
||||
BreakConverter converter = BreakConverter.from(statement);
|
||||
if (converter == null) return;
|
||||
converter.process();
|
||||
unwrap(labelStatement, statement);
|
||||
for (PsiExpression expression : Objects.requireNonNull(labelStatement.getCaseValues()).getExpressions()) {
|
||||
if (expression != label) {
|
||||
new CommentTracker().deleteAndRestoreComments(expression);
|
||||
}
|
||||
}
|
||||
tryUnwrap(labelStatement, block);
|
||||
}
|
||||
|
||||
private static void unwrap(PsiSwitchLabelStatementBase labelStatement, PsiSwitchStatement statement) {
|
||||
public void tryUnwrap(PsiSwitchLabelStatementBase labelStatement, PsiSwitchBlock block) {
|
||||
if (block instanceof PsiSwitchStatement) {
|
||||
BreakConverter converter = BreakConverter.from(block);
|
||||
if (converter == null) return;
|
||||
converter.process();
|
||||
unwrapStatement(labelStatement, (PsiSwitchStatement)block);
|
||||
} else {
|
||||
if (labelStatement instanceof PsiSwitchLabeledRuleStatement) {
|
||||
PsiSwitchLabeledRuleStatement ruleStatement = (PsiSwitchLabeledRuleStatement)labelStatement;
|
||||
if (ruleStatement.getBody() instanceof PsiExpressionStatement) {
|
||||
new CommentTracker().replaceAndRestoreComments(block, ((PsiExpressionStatement)ruleStatement.getBody()).getExpression());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void unwrapStatement(PsiSwitchLabelStatementBase labelStatement, PsiSwitchStatement statement) {
|
||||
PsiCodeBlock block = statement.getBody();
|
||||
PsiStatement body =
|
||||
labelStatement instanceof PsiSwitchLabeledRuleStatement ? ((PsiSwitchLabeledRuleStatement)labelStatement).getBody() : null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff() {
|
||||
System.out.println("one");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
//1
|
||||
//2
|
||||
//3
|
||||
//4
|
||||
//5
|
||||
//6
|
||||
//7
|
||||
//other
|
||||
System.out.println("five-ten-fifteen");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
fff();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
System.out.println(switch (x) {
|
||||
//1
|
||||
//2
|
||||
//3
|
||||
//4
|
||||
case 5 -> {
|
||||
System.out.println("something");
|
||||
break "five-ten-fifteen"; //5
|
||||
}
|
||||
//6
|
||||
//7
|
||||
//other
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
fff();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff() {
|
||||
switch ("one") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
System.out.println(switch (x) {
|
||||
case 1 -> "one"; //1
|
||||
case 2 -> "two"; //2
|
||||
case 3 -> "three"; //3
|
||||
case 4 -> "four"; //4
|
||||
case 0, <caret>5, 10 -> "five-ten-fifteen"; //5
|
||||
case 6 -> "six"; //6
|
||||
case 7 -> "seven"; //7
|
||||
default -> "and more"; //other
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
fff();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
System.out.println(switch (x) {
|
||||
case 1 -> "one"; //1
|
||||
case 2 -> "two"; //2
|
||||
case 3 -> "three"; //3
|
||||
case 4 -> "four"; //4
|
||||
case 0, <caret>5, 10 -> {
|
||||
System.out.println("something");
|
||||
break "five-ten-fifteen"; //5
|
||||
}
|
||||
case 6 -> "six"; //6
|
||||
case 7 -> "seven"; //7
|
||||
default -> "and more"; //other
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
fff();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Unwrap 'switch' statement" "true"
|
||||
// "Remove unreachable branches" "true"
|
||||
class Main {
|
||||
static void fff(int x) {
|
||||
if (x == 5) {
|
||||
|
||||
@@ -15,10 +15,10 @@ import java.util.List;
|
||||
* is unwrapped.
|
||||
*/
|
||||
public class BreakConverter {
|
||||
private final PsiSwitchStatement mySwitchStatement;
|
||||
private final PsiSwitchBlock mySwitchStatement;
|
||||
private final String myReplacement;
|
||||
|
||||
public BreakConverter(PsiSwitchStatement switchStatement, String replacement) {
|
||||
public BreakConverter(PsiSwitchBlock switchStatement, String replacement) {
|
||||
mySwitchStatement = switchStatement;
|
||||
myReplacement = replacement;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class BreakConverter {
|
||||
@Override
|
||||
public void visitBreakStatement(PsiBreakStatement statement) {
|
||||
super.visitBreakStatement(statement);
|
||||
if (statement.findExitedStatement() == mySwitchStatement) {
|
||||
if (statement.findExitedElement() == mySwitchStatement) {
|
||||
breaks.add(statement);
|
||||
}
|
||||
}
|
||||
@@ -92,8 +92,15 @@ public class BreakConverter {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isRemovable(PsiSwitchStatement switchStatement, PsiStatement statement) {
|
||||
private static boolean isRemovable(PsiSwitchBlock switchStatement, PsiStatement statement) {
|
||||
if (switchStatement instanceof PsiSwitchExpression) {
|
||||
// any breaks inside switch expressions are not convertible
|
||||
return false;
|
||||
}
|
||||
PsiElement parent = statement.getParent();
|
||||
if (parent instanceof PsiSwitchLabeledRuleStatement) {
|
||||
return true;
|
||||
}
|
||||
if (parent instanceof PsiIfStatement || parent instanceof PsiLabeledStatement) {
|
||||
return isRemovable(switchStatement, (PsiStatement)parent);
|
||||
}
|
||||
@@ -106,18 +113,18 @@ public class BreakConverter {
|
||||
}
|
||||
}
|
||||
if (nextStatement instanceof PsiSwitchLabelStatement) {
|
||||
return (((PsiSwitchLabelStatement)nextStatement).getEnclosingSwitchStatement() == switchStatement &&
|
||||
return (((PsiSwitchLabelStatement)nextStatement).getEnclosingSwitchBlock() == switchStatement &&
|
||||
!ControlFlowUtils.statementMayCompleteNormally(statement));
|
||||
}
|
||||
if (nextStatement instanceof PsiBreakStatement) {
|
||||
return ((PsiBreakStatement)nextStatement).findExitedStatement() == switchStatement;
|
||||
return ((PsiBreakStatement)nextStatement).findExitedElement() == switchStatement;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BreakConverter from(PsiSwitchStatement switchStatement) {
|
||||
String replacement = getReplacement(switchStatement);
|
||||
public static BreakConverter from(PsiSwitchBlock switchStatement) {
|
||||
String replacement = switchStatement instanceof PsiSwitchStatement ? getReplacement((PsiStatement)switchStatement) : null;
|
||||
if (replacement == null) {
|
||||
class Visitor extends JavaRecursiveElementWalkingVisitor {
|
||||
boolean hasNonRemovableBreak;
|
||||
@@ -125,7 +132,7 @@ public class BreakConverter {
|
||||
@Override
|
||||
public void visitBreakStatement(PsiBreakStatement statement) {
|
||||
super.visitBreakStatement(statement);
|
||||
if (statement.findExitedStatement() == switchStatement && !isRemovable(switchStatement, statement)) {
|
||||
if (statement.findExitedElement() == switchStatement && !isRemovable(switchStatement, statement)) {
|
||||
hasNonRemovableBreak = true;
|
||||
stopWalking();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user