mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ConvertSwitchToIfIntention: support Java 12 switch statements (no expressions)
This commit is contained in:
+35
-44
@@ -24,12 +24,13 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
private final PsiSwitchStatement mySwitchExpression;
|
||||
private final PsiSwitchStatement mySwitchStatement;
|
||||
|
||||
public ConvertSwitchToIfIntention(@NotNull PsiSwitchStatement switchStatement) {
|
||||
mySwitchExpression = switchStatement;
|
||||
mySwitchStatement = switchStatement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -46,7 +47,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return isAvailable(mySwitchExpression);
|
||||
return isAvailable(mySwitchStatement);
|
||||
}
|
||||
|
||||
public static boolean isAvailable(PsiSwitchStatement switchStatement) {
|
||||
@@ -55,10 +56,10 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
}
|
||||
|
||||
private static boolean mayFallThroughNonTerminalDefaultCase(PsiCodeBlock body) {
|
||||
List<PsiSwitchLabelStatement> labels = PsiTreeUtil.getChildrenOfTypeAsList(body, PsiSwitchLabelStatement.class);
|
||||
List<PsiSwitchLabelStatementBase> labels = PsiTreeUtil.getChildrenOfTypeAsList(body, PsiSwitchLabelStatementBase.class);
|
||||
return StreamEx.of(labels).pairMap((prev, next) -> {
|
||||
if (prev.isDefaultCase()) {
|
||||
Set<PsiSwitchLabelStatement> targets = getFallThroughTargets(body);
|
||||
Set<PsiSwitchLabelStatementBase> targets = getFallThroughTargets(body);
|
||||
return targets.contains(prev) || targets.contains(next);
|
||||
}
|
||||
return false;
|
||||
@@ -67,13 +68,13 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
doProcessIntention(mySwitchExpression);
|
||||
doProcessIntention(mySwitchStatement);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getElementToMakeWritable(@NotNull PsiFile file) {
|
||||
return mySwitchExpression;
|
||||
return mySwitchStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,7 +104,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
return;
|
||||
}
|
||||
// Should execute getFallThroughTargets and statementMayCompleteNormally before converting breaks
|
||||
Set<PsiSwitchLabelStatement> fallThroughTargets = getFallThroughTargets(body);
|
||||
Set<PsiSwitchLabelStatementBase> fallThroughTargets = getFallThroughTargets(body);
|
||||
boolean mayCompleteNormally = ControlFlowUtils.statementMayCompleteNormally(switchStatement);
|
||||
BreakConverter converter = BreakConverter.from(switchStatement);
|
||||
if (converter == null) return;
|
||||
@@ -205,7 +206,7 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
@NotNull
|
||||
private static List<SwitchStatementBranch> extractBranches(CommentTracker commentTracker,
|
||||
PsiCodeBlock body,
|
||||
Set<PsiSwitchLabelStatement> fallThroughTargets) {
|
||||
Set<PsiSwitchLabelStatementBase> fallThroughTargets) {
|
||||
final List<SwitchStatementBranch> openBranches = new ArrayList<>();
|
||||
final Set<PsiElement> declaredElements = new HashSet<>();
|
||||
final List<SwitchStatementBranch> allBranches = new ArrayList<>();
|
||||
@@ -232,17 +233,29 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
openBranches.add(currentBranch);
|
||||
}
|
||||
if (label.isDefaultCase()) {
|
||||
currentBranch.setDefault();
|
||||
currentBranch.setAlwaysExecuted(defaultAlwaysExecuted);
|
||||
if (defaultAlwaysExecuted) {
|
||||
openBranches.retainAll(Collections.singleton(currentBranch));
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiExpression value = label.getCaseValue();
|
||||
final String valueText = getCaseValueText(value, commentTracker);
|
||||
currentBranch.addCaseValue(valueText);
|
||||
currentBranch.addCaseValues(label, commentTracker);
|
||||
}
|
||||
else if (statement instanceof PsiSwitchLabeledRuleStatement) {
|
||||
openBranches.clear();
|
||||
defaultAlwaysExecuted = false;
|
||||
PsiSwitchLabeledRuleStatement rule = (PsiSwitchLabeledRuleStatement)statement;
|
||||
currentBranch = new SwitchStatementBranch();
|
||||
|
||||
PsiStatement ruleBody = rule.getBody();
|
||||
if (ruleBody != null) {
|
||||
currentBranch.addStatement(ruleBody);
|
||||
}
|
||||
if (rule.isDefaultCase()) {
|
||||
currentBranch.setAlwaysExecuted(defaultAlwaysExecuted);
|
||||
}
|
||||
currentBranch.addCaseValues(rule, commentTracker);
|
||||
openBranches.add(currentBranch);
|
||||
allBranches.add(currentBranch);
|
||||
}
|
||||
else {
|
||||
if (statement instanceof PsiStatement) {
|
||||
@@ -269,33 +282,11 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
return allBranches;
|
||||
}
|
||||
|
||||
private static Set<PsiSwitchLabelStatement> getFallThroughTargets(PsiCodeBlock body) {
|
||||
private static Set<PsiSwitchLabelStatementBase> getFallThroughTargets(PsiCodeBlock body) {
|
||||
return StreamEx.of(body.getStatements())
|
||||
.pairMap((s1, s2) -> s2 instanceof PsiSwitchLabelStatement && ControlFlowUtils.statementMayCompleteNormally(s1)
|
||||
? (PsiSwitchLabelStatement)s2 : null)
|
||||
.nonNull().toSet();
|
||||
}
|
||||
|
||||
private static String getCaseValueText(PsiExpression value, CommentTracker commentTracker) {
|
||||
value = PsiUtil.skipParenthesizedExprDown(value);
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (!(value instanceof PsiReferenceExpression)) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)value;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
|
||||
if (!(target instanceof PsiEnumConstant)) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
final PsiEnumConstant enumConstant = (PsiEnumConstant)target;
|
||||
final PsiClass aClass = enumConstant.getContainingClass();
|
||||
if (aClass == null) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
return aClass.getQualifiedName() + '.' + commentTracker.text(referenceExpression);
|
||||
.pairMap((s1, s2) -> s2 instanceof PsiSwitchLabelStatement && !(s1 instanceof PsiSwitchLabeledRuleStatement) &&
|
||||
ControlFlowUtils.statementMayCompleteNormally(s1) ? (PsiSwitchLabelStatement)s2 : null)
|
||||
.nonNull().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static void dumpBranch(SwitchStatementBranch branch,
|
||||
@@ -338,10 +329,10 @@ public class ConvertSwitchToIfIntention implements IntentionAction {
|
||||
if (!bodyStatements.isEmpty()) {
|
||||
PsiElement firstBodyElement = bodyStatements.get(0);
|
||||
PsiElement prev = PsiTreeUtil.skipWhitespacesAndCommentsBackward(firstBodyElement);
|
||||
if (prev instanceof PsiSwitchLabelStatement) {
|
||||
PsiExpression value = ((PsiSwitchLabelStatement)prev).getCaseValue();
|
||||
if (value != null) {
|
||||
out.append(CommentTracker.commentsBetween(value, firstBodyElement));
|
||||
if (prev instanceof PsiSwitchLabelStatementBase) {
|
||||
PsiExpressionList values = ((PsiSwitchLabelStatementBase)prev).getCaseValues();
|
||||
if (values != null) {
|
||||
out.append(CommentTracker.commentsBetween(values, firstBodyElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-2
@@ -15,8 +15,9 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiStatement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
|
||||
import java.util.*;
|
||||
@@ -91,4 +92,41 @@ class SwitchStatementBranch {
|
||||
public Set<PsiElement> getPendingDeclarations() {
|
||||
return Collections.unmodifiableSet(myPendingDeclarations);
|
||||
}
|
||||
|
||||
void addCaseValues(PsiSwitchLabelStatementBase label, CommentTracker commentTracker) {
|
||||
if (label.isDefaultCase()) {
|
||||
setDefault();
|
||||
}
|
||||
else {
|
||||
PsiExpressionList values = label.getCaseValues();
|
||||
if (values != null) {
|
||||
for (PsiExpression value : values.getExpressions()) {
|
||||
final String valueText = getCaseValueText(value, commentTracker);
|
||||
addCaseValue(valueText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCaseValueText(PsiExpression value, CommentTracker commentTracker) {
|
||||
value = PsiUtil.skipParenthesizedExprDown(value);
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (!(value instanceof PsiReferenceExpression)) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)value;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
|
||||
if (!(target instanceof PsiEnumConstant)) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
final PsiEnumConstant enumConstant = (PsiEnumConstant)target;
|
||||
final PsiClass aClass = enumConstant.getContainingClass();
|
||||
if (aClass == null) {
|
||||
return commentTracker.text(value);
|
||||
}
|
||||
return aClass.getQualifiedName() + '.' + commentTracker.text(referenceExpression);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
if (x == 0 || x == 1) {
|
||||
System.out.println("ready");
|
||||
System.out.println("steady");
|
||||
} else if (x == 2 || x == 3) {
|
||||
System.out.println("steady");
|
||||
}
|
||||
System.out.println("go");
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
//1
|
||||
/*2*/
|
||||
/*3*/
|
||||
/*4*/
|
||||
/*6*/
|
||||
/*7*/
|
||||
if (x == 0) {
|
||||
System.out.println("zero");/*5*/
|
||||
} else {
|
||||
System.out.println("non-zero");/*8*/
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
if (x == 0) {
|
||||
System.out.println(x);
|
||||
} else if (x == 1) {
|
||||
System.out.println("one");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
if (x == 0 || x == 1) {
|
||||
throw new IllegalArgumentException();
|
||||
} else if (x == 2 || x == 3) {
|
||||
if (Math.random() > 0.5) return;
|
||||
System.out.println("two or three");
|
||||
} else if (x == 4) {
|
||||
System.out.println("four");
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
switch<caret> (x) {
|
||||
case 0,1: System.out.println("ready");
|
||||
case 2,3: System.out.println("steady");
|
||||
default: System.out.println("go");
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
switch<caret> (x) {
|
||||
//1
|
||||
case /*2*/0/*3*/ -> /*4*/System.out.println("zero");/*5*/
|
||||
default /*6*/->/*7*/ System.out.println("non-zero");/*8*/
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
switch<caret> (x) {
|
||||
case 0 -> System.out.println(x);
|
||||
case 1 -> System.out.println("one");
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace 'switch' with 'if'" "true"
|
||||
class Test {
|
||||
void foo(int x) {
|
||||
switch<caret> (x) {
|
||||
case 0,1 -> throw new IllegalArgumentException();
|
||||
case 2,3 -> {
|
||||
if (Math.random() > 0.5) break;
|
||||
System.out.println("two or three");
|
||||
}
|
||||
case 4 -> System.out.println("four");
|
||||
default -> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class SwitchPredicate implements PsiElementPredicate {
|
||||
}
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
for (PsiStatement statement : statements) {
|
||||
if (statement instanceof PsiSwitchLabelStatement && !((PsiSwitchLabelStatement)statement).isDefaultCase()) {
|
||||
if (statement instanceof PsiSwitchLabelStatementBase && !((PsiSwitchLabelStatementBase)statement).isDefaultCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user