IDEA-203119 Unwrap switch statement: support rule-cases and multiple expression cases

This commit is contained in:
Tagir Valeev
2018-11-28 17:58:18 +07:00
parent c51a61c71d
commit 81c9810bde
11 changed files with 228 additions and 5 deletions

View File

@@ -315,6 +315,11 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
PsiSwitchLabelStatementBase labelStatement = Objects.requireNonNull(PsiImplUtil.getSwitchLabel(label));
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;
}
if (!StreamEx.iterate(labelStatement, Objects::nonNull, l -> PsiTreeUtil.getPrevSiblingOfType(l, PsiSwitchLabelStatementBase.class))
.skip(1).map(PsiSwitchLabelStatementBase::getCaseValues)
.nonNull().flatArray(PsiExpressionList::getExpressions).allMatch(falseLabels::contains)) {

View File

@@ -1,6 +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.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.BlockUtils;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
@@ -10,11 +11,13 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ObjectUtils;
import com.siyeh.ig.psiutils.BreakConverter;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
public class UnwrapSwitchLabelFix implements LocalQuickFix {
@Nls(capitalization = Nls.Capitalization.Sentence)
@@ -32,13 +35,44 @@ public class UnwrapSwitchLabelFix implements LocalQuickFix {
if (labelStatement == null) return;
PsiSwitchStatement statement = labelStatement.getEnclosingSwitchStatement();
if (statement == null) return;
List<PsiSwitchLabelStatement> labels = PsiTreeUtil.getChildrenOfTypeAsList(statement.getBody(), PsiSwitchLabelStatement.class);
for (PsiSwitchLabelStatement otherLabel : labels) {
List<PsiSwitchLabelStatementBase> labels = PsiTreeUtil.getChildrenOfTypeAsList(statement.getBody(), PsiSwitchLabelStatementBase.class);
for (PsiSwitchLabelStatementBase otherLabel : labels) {
if (otherLabel != labelStatement) {
DeleteSwitchLabelFix.deleteLabel(otherLabel);
}
}
new CommentTracker().replaceAndRestoreComments(labelStatement, "default:");
ConvertSwitchToIfIntention.doProcessIntention(statement); // will not create 'if', just unwrap, because only default label is left
BreakConverter converter = BreakConverter.from(statement);
if (converter == null) return;
converter.process();
unwrap(labelStatement, statement);
}
private static void unwrap(PsiSwitchLabelStatementBase labelStatement, PsiSwitchStatement statement) {
PsiCodeBlock block = statement.getBody();
PsiStatement body =
labelStatement instanceof PsiSwitchLabeledRuleStatement ? ((PsiSwitchLabeledRuleStatement)labelStatement).getBody() : null;
if (body == null) {
new CommentTracker().deleteAndRestoreComments(labelStatement);
}
else if (body instanceof PsiBlockStatement) {
block = ((PsiBlockStatement)body).getCodeBlock();
}
else {
new CommentTracker().replaceAndRestoreComments(labelStatement, body);
}
PsiCodeBlock parent = ObjectUtils.tryCast(statement.getParent(), PsiCodeBlock.class);
CommentTracker ct = new CommentTracker();
if (parent != null && !BlockUtils.containsConflictingDeclarations(Objects.requireNonNull(block), parent)) {
ct.grabComments(statement);
ct.markUnchanged(block);
ct.insertCommentsBefore(statement);
BlockUtils.inlineCodeBlock(statement, block);
}
else if (block != null) {
ct.replaceAndRestoreComments(statement, ct.text(block));
}
else {
ct.deleteAndRestoreComments(statement);
}
}
}

View File

@@ -152,7 +152,7 @@ public class BlockUtils {
return forward ? element.getNextSibling() : element.getPrevSibling();
}
public static boolean containsConflictingDeclarations(PsiCodeBlock block, PsiCodeBlock parentBlock) {
public static boolean containsConflictingDeclarations(@NotNull PsiCodeBlock block, @NotNull PsiCodeBlock parentBlock) {
final PsiStatement[] statements = block.getStatements();
if (statements.length == 0) {
return false;

View File

@@ -0,0 +1,25 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
switch (x) {
//1
//2
//3
//4
case 5:
if (Math.random() > 0.5) break;
System.out.println("five-ten-fifteen"); //5
System.out.println("six"); //6
System.out.println("seven"); //7
break;
//other
}
System.out.println("oops");
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,24 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
int i = 5;
//1
//2
//3
//4
//6
//7
//other
{
if (Math.random() > 0.5) return;
int i = 6;
System.out.println("five-ten-fifteen"); //5
}
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,19 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
//1
//2
//3
//4
System.out.println("five-ten-fifteen"); //5
//6
//7
//other
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,20 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
//1
//2
//3
//4
//6
//7
//other
if (Math.random() > 0.5) return;
System.out.println("five-ten-fifteen"); //5
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,25 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
switch (x) {
case 1: System.out.println("one"); //1
case 2: System.out.println("two"); //2
case 3: System.out.println("three"); //3
case 4: System.out.println("four"); //4
case 0:case <caret>5:case 10:
if (Math.random() > 0.5) break;
System.out.println("five-ten-fifteen"); //5
case 6: System.out.println("six"); //6
case 7: System.out.println("seven"); //7
break;
default: System.out.println("and more"); //other
}
System.out.println("oops");
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,26 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
int i = 5;
switch (x) {
case 1 -> System.out.println("one"); //1
case 2 -> System.out.println("two"); //2
case 3 -> System.out.println("three"); //3
case 4 -> System.out.println("four"); //4
case 0, <caret>5, 10 -> {
if (Math.random() > 0.5) break;
int i = 6;
System.out.println("five-ten-fifteen"); //5
}
case 6 -> System.out.println("six"); //6
case 7 -> System.out.println("seven"); //7
default -> System.out.println("and more"); //other
}
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,21 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
switch (x) {
case 1 -> System.out.println("one"); //1
case 2 -> System.out.println("two"); //2
case 3 -> System.out.println("three"); //3
case 4 -> System.out.println("four"); //4
case 0, <caret>5, 10 -> System.out.println("five-ten-fifteen"); //5
case 6 -> System.out.println("six"); //6
case 7 -> System.out.println("seven"); //7
default -> System.out.println("and more"); //other
}
}
}
public static void main(String[] args) {
fff();
}
}

View File

@@ -0,0 +1,24 @@
// "Unwrap 'switch' statement" "true"
class Main {
static void fff(int x) {
if (x == 5) {
switch (x) {
case 1 -> System.out.println("one"); //1
case 2 -> System.out.println("two"); //2
case 3 -> System.out.println("three"); //3
case 4 -> System.out.println("four"); //4
case 0, <caret>5, 10 -> {
if (Math.random() > 0.5) break;
System.out.println("five-ten-fifteen"); //5
}
case 6 -> System.out.println("six"); //6
case 7 -> System.out.println("seven"); //7
default -> System.out.println("and more"); //other
}
}
}
public static void main(String[] args) {
fff();
}
}