You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ar...@apache.org on 2019/05/02 05:34:11 UTC

[netbeans] branch master updated: [NETBEANS-2349] Convert switch to switch expression (#1193)

This is an automated email from the ASF dual-hosted git repository.

arusinha pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new ac510a0  [NETBEANS-2349] Convert switch to switch expression (#1193)
ac510a0 is described below

commit ac510a00be35b5c04054a14b9394f5419c3ca7c4
Author: Vikas Prabhakar <vi...@oracle.com>
AuthorDate: Thu May 2 11:03:59 2019 +0530

    [NETBEANS-2349] Convert switch to switch expression (#1193)
    
    * [NETBEANS-2349] Convert switch to switch expression
    
    * [NETBEANS-2349] Add return scenario
    
    * Format correction
    
    * [NETBEANS-2349] Implement review feedbacks
    
    * [NETBEANS-2349] replace SWITCH_EXPRESSION strings to variable TreeShims.SWITCH_EXPRESSION
---
 .../java/completion/JavaCompletionTask.java        |   4 +-
 .../java/hints/errors/DifferentCaseKindsFix.java   |   4 +-
 .../modules/java/hints/errors/Utilities.java       |  72 +++++-
 .../java/hints/jdk/ConvertSwitchToRuleSwitch.java  |  33 ++-
 .../hints/jdk/ConvertSwitchToRuleSwitchTest.java   | 247 ++++++++++++++++++++-
 .../org/netbeans/api/java/source/WorkingCopy.java  |   3 +-
 .../netbeans/modules/java/source/TreeShims.java    |   5 +-
 .../modules/java/source/pretty/VeryPretty.java     |  49 +++-
 .../modules/java/source/save/CasualDiff.java       |   2 +-
 .../modules/java/source/save/Reformatter.java      |   6 +-
 .../modules/java/source/save/Reindenter.java       |   2 +-
 .../api/java/source/gen/SwitchExpressionTest.java  |   3 +-
 .../modules/java/hints/spiimpl/Utilities.java      |  11 +-
 13 files changed, 399 insertions(+), 42 deletions(-)

diff --git a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
index 8e925dc..5d2966d 100644
--- a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
+++ b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
@@ -2354,7 +2354,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
         if (caseExpressionTree != null && ((sourcePositions.getStartPosition(root, caseExpressionTree) >= offset)
                 || (caseErroneousTree != null && caseErroneousTree.getKind() == Tree.Kind.ERRONEOUS && ((ErroneousTree) caseErroneousTree).getErrorTrees().isEmpty() && sourcePositions.getEndPosition(root, caseErroneousTree) >= offset))) {
 
-            if (parentPath.getLeaf().getKind() == Tree.Kind.SWITCH || parentPath.getLeaf().getKind().toString().equals("SWITCH_EXPRESSION")) { //NOI18N
+            if (parentPath.getLeaf().getKind() == Tree.Kind.SWITCH || parentPath.getLeaf().getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
                 ExpressionTree exprTree = null;
                 if (parentPath.getLeaf().getKind() == Tree.Kind.SWITCH) {
                     exprTree = ((SwitchTree) parentPath.getLeaf()).getExpression();
@@ -3707,7 +3707,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
         if (path != null && path.getLeaf().getKind() == Tree.Kind.SWITCH) {
             SwitchTree st = (SwitchTree) path.getLeaf();
             caseTrees = st.getCases();
-        } else if (path != null && path.getLeaf().getKind().toString().equals("SWITCH_EXPRESSION")) { //NOI18N
+        } else if (path != null && path.getLeaf().getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
             caseTrees = TreeShims.getCases(path.getLeaf());
         }
 
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java b/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
index c91f65e1..ec75b07 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/errors/DifferentCaseKindsFix.java
@@ -60,7 +60,7 @@ public class DifferentCaseKindsFix implements ErrorRule<Void> {
         TreePath parentPath = treePath.getParentPath();
         List<? extends CaseTree> caseTrees = null;
         boolean flag = false;
-        if(parentPath.getLeaf().getKind().toString().equals("SWITCH_EXPRESSION")){
+        if(parentPath.getLeaf().getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)){
             caseTrees = TreeShims.getCases(parentPath.getLeaf());            
         } else {
             flag = true;
@@ -135,7 +135,7 @@ public class DifferentCaseKindsFix implements ErrorRule<Void> {
         protected void performRewrite(TransformationContext ctx) {
             TreePath tp = ctx.getPath();
             Tree switchBlock = tp.getParentPath().getLeaf();
-            Utilities.performRewriteRuleSwitch(ctx, tp, switchBlock);
+            Utilities.performRewriteRuleSwitch(ctx, tp, switchBlock, false);
         }
 
     } 
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java b/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
index 43886a2..1113c9b 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java
@@ -3111,14 +3111,57 @@ public class Utilities {
         return scanner.completesNormally;
     }
 
-    public static void performRewriteRuleSwitch(JavaFix.TransformationContext ctx, TreePath tp, Tree st) {
+    public static boolean isCompatibleWithSwitchExpression(SwitchTree st) {
+        boolean firstCase = true;
+        Name leftTreeName = null;
+        for (CaseTree ct : st.getCases()) {
+            List<StatementTree> statements = new ArrayList<>(ct.getStatements());
+            switch (statements.size()) {
+                case 0:
+                    break;
+                case 1:
+                    if (firstCase && leftTreeName == null && statements.get(0).getKind() == Tree.Kind.RETURN) {
+                        break;
+                    } else {
+                        return false;
+                    }
+                case 2:
+                    if (statements.get(0).getKind() == Tree.Kind.EXPRESSION_STATEMENT && statements.get(1).getKind() == Tree.Kind.BREAK) {
+                        StatementTree statementTree = statements.get(0);
+                        JCTree.JCExpressionStatement jceTree = (JCTree.JCExpressionStatement) statementTree;
+                        if (!(jceTree.expr instanceof JCTree.JCAssign)) {
+                            return false;
+                        }
+                        JCTree.JCAssign assignTree = (JCTree.JCAssign) jceTree.expr;
+                        if (firstCase) {
+                            leftTreeName = ((JCTree.JCIdent) assignTree.lhs).name;
+                            firstCase = false;
+                            break;
+                        } else if (leftTreeName != null && leftTreeName.contentEquals(((JCTree.JCIdent) assignTree.lhs).name)) {
+                            break;
+                        } else {
+                            return false;
+                        }
+                    } else {
+                        return false;
+                    }
+                default:
+                    return false;
+            }
+        }
+        return true;
+    }
+
+    public static void performRewriteRuleSwitch(JavaFix.TransformationContext ctx, TreePath tp, Tree st, boolean isExpression) {
         WorkingCopy wc = ctx.getWorkingCopy();
         TreeMaker make = wc.getTreeMaker();
         List<CaseTree> newCases = new ArrayList<>();
         List<? extends CaseTree> cases;
         Set<VariableElement> variablesDeclaredInOtherCases = new HashSet<>();
         List<ExpressionTree> patterns = new ArrayList<>();
-        boolean switchExpressionFlag = st.getKind().toString().equals("SWITCH_EXPRESSION");
+        Tree variable = null;
+        boolean isReturnExpression = false;
+        boolean switchExpressionFlag = st.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION);
         if (switchExpressionFlag) {
             cases = TreeShims.getCases(st);
         } else {
@@ -3130,7 +3173,7 @@ public class Utilities {
             patterns.addAll(TreeShims.getExpressions(ct));
             List<StatementTree> statements;
             if (ct.getStatements() == null) {
-                statements = new ArrayList<>(((JCTree.JCCase) ct).stats);//Collections.singletonList((StatementTree) TreeShims.getBody(ct));
+                statements = new ArrayList<>(((JCTree.JCCase) ct).stats);
             } else {
                 statements = new ArrayList<>(ct.getStatements());
             }
@@ -3201,7 +3244,20 @@ public class Utilities {
                     body = statements.get(0);
                 }
             }
-            newCases.add(make.Case(patterns, body));
+            if (isExpression) {
+                if (statements.get(0).getKind() == Tree.Kind.RETURN) {
+                    body = ((JCTree.JCReturn) statements.get(0)).getExpression();
+                    isReturnExpression = true;
+                } else {
+                    JCTree.JCExpressionStatement jceTree = (JCTree.JCExpressionStatement) statements.get(0);
+                    body = ((JCTree.JCAssign) jceTree.expr).rhs;
+                    variable = ((JCTree.JCAssign) jceTree.expr).lhs;
+                }
+                newCases.add(make.Case(patterns, make.ExpressionStatement((ExpressionTree) body)));
+            } else {
+                newCases.add(make.Case(patterns, body));
+            }
+
             patterns = new ArrayList<>();
             for (StatementTree statement : getSwitchStatement(ct)) {
                 if (statement.getKind() == Tree.Kind.VARIABLE) {
@@ -3209,7 +3265,13 @@ public class Utilities {
                 }
             }
         }
-        if (switchExpressionFlag) {
+        if (isReturnExpression) {
+            ExpressionTree et = (ExpressionTree) make.SwitchExpression(TreeShims.getExpressions(st).get(0), newCases);
+            wc.rewrite(st, make.Return(et));
+        } else if (isExpression) {
+            ExpressionTree et = (ExpressionTree) make.SwitchExpression(TreeShims.getExpressions(st).get(0), newCases);
+            wc.rewrite(st, make.ExpressionStatement((ExpressionTree) make.Assignment((ExpressionTree) variable, et)));
+        } else if (switchExpressionFlag) {
             wc.rewrite(st, make.SwitchExpression(TreeShims.getExpressions(st).get(0), newCases));
         } else {
             wc.rewrite((SwitchTree) st, make.Switch(((SwitchTree) st).getExpression(), newCases));
diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
index c5b5302..1c54a05 100644
--- a/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
+++ b/java/java.hints/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitch.java
@@ -39,11 +39,13 @@ import org.openide.util.NbBundle.Messages;
 @Messages({
     "DN_org.netbeans.modules.java.hints.jdk.ConvertSwitchToRuleSwitch=Convert switch to rule switch",
     "DESC_org.netbeans.modules.java.hints.jdk.ConvertSwitchToRuleSwitch=Converts switch to rule switch",
+    "DN_org.netbeans.modules.java.hints.jdk.ConvertSwitchStatementToSwitchExpression=Convert switch to switch expression",
+    "DESC_org.netbeans.modules.java.hints.jdk.ConvertSwitchStatementToSwitchExpression=Converts switch to switch expression",
 })
 public class ConvertSwitchToRuleSwitch {
     
     @TriggerTreeKind(Tree.Kind.SWITCH)
-    @Messages("ERR_ConverSwitchToRuleSwitch=Convert switch to rule switch")
+    @Messages({"ERR_ConvertSwitchToRuleSwitch=Convert switch to rule switch", "ERR_ConvertSwitchToSwitchExpression=Convert switch to switch expression"})
     public static ErrorDescription switch2RuleSwitch(HintContext ctx) {
         if (!CompilerOptionsQuery.getOptions(ctx.getInfo().getFileObject()).getArguments().contains("--enable-preview"))
             return null;
@@ -66,7 +68,11 @@ public class ConvertSwitchToRuleSwitch {
             wasDefault = ct.getExpression() == null;
             wasEmpty = ct.getStatements().isEmpty();
         }
-        return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConverSwitchToRuleSwitch(), new FixImpl(ctx.getInfo(), ctx.getPath()).toEditorFix());
+        if (wasDefault && Utilities.isCompatibleWithSwitchExpression(st)) {
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertSwitchToSwitchExpression(), new FixImpl1(ctx.getInfo(), ctx.getPath()).toEditorFix());
+        } else {
+            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_ConvertSwitchToRuleSwitch(), new FixImpl(ctx.getInfo(), ctx.getPath()).toEditorFix());
+        }
     }
 
     private static final class FixImpl extends JavaFix {
@@ -85,8 +91,27 @@ public class ConvertSwitchToRuleSwitch {
         protected void performRewrite(TransformationContext ctx) {
             TreePath tp = ctx.getPath();
             SwitchTree st = (SwitchTree) tp.getLeaf();
-            Utilities.performRewriteRuleSwitch(ctx, tp, st);
+            Utilities.performRewriteRuleSwitch(ctx, tp, st, false);
+        }
+    }
+
+    private static final class FixImpl1 extends JavaFix {
+
+        public FixImpl1(CompilationInfo info, TreePath switchStatement) {
+            super(info, switchStatement);
+        }
+
+        @Override
+        @Messages("FIX_ConvertToSwitchExpression=Convert to switch expression")
+        protected String getText() {
+            return Bundle.FIX_ConvertToSwitchExpression();
+        }
+
+        @Override
+        protected void performRewrite(JavaFix.TransformationContext ctx) {
+            TreePath tp = ctx.getPath();
+            SwitchTree st = (SwitchTree) tp.getLeaf();
+            Utilities.performRewriteRuleSwitch(ctx, tp, st, true);
         }
-        
     }
 }
diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
index f204ad8..b800860 100644
--- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
+++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/jdk/ConvertSwitchToRuleSwitchTest.java
@@ -51,7 +51,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -81,7 +81,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -111,7 +111,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -160,7 +160,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -183,14 +183,14 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                        "         String result;\n" +
                        "         switch (p) {\n" +
                        "             case 0: result = \"1\"; break;\n" +
-                       "             default: result = \"d\"; break;\n" +
+                       "             default: result = \"d\"; System.out.println(result); break;\n" +
                        "         }\n" +
                        "     }\n" +
                        "}\n")
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -199,7 +199,9 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                               "         String result;\n" +
                               "         switch (p) {\n" +
                               "             case 0 -> result = \"1\";\n" +
-                              "             default -> result = \"d\";\n" +
+                              "             default -> {\n" +
+                              "                 result = \"d\"; System.out.println(result);\n" +
+                              "             }\n" +
                               "         }\n" +
                               "     }\n" +
                               "}\n");
@@ -227,7 +229,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -306,7 +308,7 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                 .sourceLevel(SourceVersion.latest().name())
                 .options("--enable-preview")
                 .run(ConvertSwitchToRuleSwitch.class)
-                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConverSwitchToRuleSwitch())
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
                 .applyFix()
                 .assertCompilable()
                 .assertOutput("package test;" +
@@ -455,6 +457,233 @@ public class ConvertSwitchToRuleSwitchTest extends NbTestCase {
                               "}");
     }
 
+    //Test cases for switch expression
+
+    public void testSwitch2SwitchExpression() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private void test(int p) {\n" +
+                       "         String result;\n" +
+                       "         switch (p) {\n" +
+                       "             case 1: result = \"1\"; break;\n" +
+                       "             case 2: result = \"2\"; break;\n" +
+                       "             case 3: result = \"3\"; break;\n" +
+                       "             default: result = \"default\"; break;\n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private void test(int p) {\n" +
+                              "         String result;\n" +
+                              "         result = switch (p) {\n" +
+                              "             case 1 -> \"1\";\n" +
+                              "             case 2 -> \"2\";\n" +
+                              "             case 3 -> \"3\";\n" +
+                              "             default -> \"default\";\n" +
+                              "         };\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
+    public void testSwitch2SwitchExpressionMultiCase() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private void test(int p) {\n" +
+                       "         String result;\n" +
+                       "         switch (p) {\n" +
+                       "             case 1:\n" +
+                       "             case 2: result = \"2\"; break;\n" +
+                       "             case 3: result = \"3\"; break;\n" +
+                       "             default: result = \"default\"; break;\n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("3:9-3:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private void test(int p) {\n" +
+                              "         String result;\n" +
+                              "         result = switch (p) {\n" +
+                              "             case 1, 2 -> \"2\";\n" +
+                              "             case 3 -> \"3\";\n" +
+                              "             default -> \"default\";\n" +
+                              "         };\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
+    public void testSwitch2SwitchExpressionNestedInnerSwitchExpression() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private void test(int p) {\n" +
+                       "         int i = 10;\n" +
+                       "         String result;\n" +
+                       "         switch (p) {\n" +
+                       "             case 1: result = switch (i) {\n" +
+                       "                         case 1 -> \"one\"; \n" +
+                       "                         default -> \"Inner default\"; \n" +
+                       "                     }; break;\n" +
+                       "             case 2: result = \"2\"; break;\n" +
+                       "             default: result = \"default\"; break;\n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("4:9-4:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private void test(int p) {\n" +
+                              "         int i = 10;\n" +
+                              "         String result;\n" +
+                              "         result = switch (p) {\n" +
+                              "             case 1 -> switch (i) {\n" +
+                              "                 case 1 -> \"one\";\n" +
+                              "                 default -> \"Inner default\";\n" +
+                              "         };\n" +
+                              "             case 2 -> \"2\";\n" +
+                              "             default -> \"default\";\n" +
+                              "         };\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
+    public void testSwitch2SwitchExpressionReturnValue() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private String test(int p) {\n" +
+                       "         switch (p) {\n" +
+                       "             case 1: return \"1\"; \n" +
+                       "             default: return \"default\"; \n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("2:9-2:15:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private String test(int p) {\n" +
+                              "         return switch (p) {\n" +
+                              "             case 1 -> \"1\";\n" +
+                              "             default -> \"default\";\n" +
+                              "         };\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
+    public void testSwitch2SwitchExpressionNestedOuterSwitchStatement() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private void test(int p) {\n" +
+                       "         String result;\n" +
+                       "         int x = 10;\n" +
+                       "         switch (p) {\n" +
+                       "             case 1 : \n" +
+                       "                switch (x) {\n" +
+                       "                    case 1 : result = \"1\"; break;\n" +
+                       "                    default : result =  \"Inner Default\"; break;\n" +
+                       "                }\n" +
+                       "             break;\n" +
+                       "             default:\n" +
+                       "                result = \"d\";\n" +
+                       "                break;\n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("4:9-4:15:verifier:" + Bundle.ERR_ConvertSwitchToRuleSwitch())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private void test(int p) {\n" +
+                              "         String result;\n" +
+                              "         int x = 10;\n" +
+                              "         switch (p) {\n" +
+                              "             case 1 -> {\n" +
+                              "                switch (x) {\n" +
+                              "                    case 1 : result = \"1\"; break;\n" +
+                              "                    default : result =  \"Inner Default\"; break;\n" +
+                              "                 }\n" +
+                              "             }\n" +
+                              "             default -> result = \"d\";\n" +
+                              "         }\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
+    public void testSwitch2SwitchExpressionNestedInnerSwitchStatement() throws Exception {
+        HintTest.create()
+                .input("package test;" +
+                       "public class Test {\n" +
+                       "     private void test(int p) {\n" +
+                       "         String result;\n" +
+                       "         int x = 10;\n" +
+                       "         switch (p) {\n" +
+                       "             case 1 : \n" +
+                       "                switch (x) {\n" +
+                       "                    case 1 : result = \"1\"; break;\n" +
+                       "                    default : result =  \"Inner Default\"; break;\n" +
+                       "                }\n" +
+                       "                break;\n" +
+                       "             default:\n" +
+                       "                result = \"d\";\n" +
+                       "                break;\n" +
+                       "         }\n" +
+                       "     }\n" +
+                       "}\n")
+                .sourceLevel(SourceVersion.latest().name())
+                .options("--enable-preview")
+                .run(ConvertSwitchToRuleSwitch.class)
+                .findWarning("6:16-6:22:verifier:" + Bundle.ERR_ConvertSwitchToSwitchExpression())
+                .applyFix()
+                .assertCompilable()
+                .assertOutput("package test;" +
+                              "public class Test {\n" +
+                              "     private void test(int p) {\n" +
+                              "         String result;\n" +
+                              "         int x = 10;\n" +
+                              "         switch (p) {\n" +
+                              "             case 1 :\n" +
+                              "             result = switch (x) {\n" +
+                              "                 case 1 -> \"1\";\n" +
+                              "                 default ->  \"Inner Default\";\n" +
+                              "             };\n" +
+                              "                 break;\n\n" +
+                              "             default:\n" +
+                              "                 result = \"d\";\n" +
+                              "                 break;\n" +
+                              "         }\n" +
+                              "     }\n" +
+                              "}\n");
+    }
+
     public static Test suite() {
         TestSuite suite = new TestSuite();
         try {
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/WorkingCopy.java b/java/java.source.base/src/org/netbeans/api/java/source/WorkingCopy.java
index 6f74af6..1cbeef7 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/WorkingCopy.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/WorkingCopy.java
@@ -82,6 +82,7 @@ import org.openide.util.Parameters;
 import static org.netbeans.api.java.source.ModificationResult.*;
 import org.netbeans.api.lexer.TokenSequence;
 import org.netbeans.modules.java.source.FileObjectFromTemplateCreator;
+import org.netbeans.modules.java.source.TreeShims;
 import org.netbeans.modules.java.source.builder.CommentHandlerService;
 import org.netbeans.modules.java.source.builder.CommentSetImpl;
 import org.netbeans.modules.java.source.builder.TreeFactory;
@@ -864,7 +865,7 @@ public class WorkingCopy extends CompilationController {
                     Tree t;
                     if (translated != null) {
                         t = translate(translated);
-                    } else if (tree != null && tree.getKind().toString().equals("SWITCH_EXPRESSION")) {
+                    } else if (tree != null && tree.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
                         t = visitSwitchExpression(tree, null);
                     } else {
                         t = super.translate(tree);
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
index 9dbd309..d6e4746 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
@@ -21,7 +21,6 @@ package org.netbeans.modules.java.source;
 import com.sun.source.tree.BreakTree;
 import com.sun.source.tree.CaseTree;
 import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.StatementTree;
 import com.sun.source.tree.SwitchTree;
 import com.sun.source.tree.Tree;
 import com.sun.tools.javac.tree.JCTree;
@@ -35,6 +34,8 @@ import java.util.List;
 
 public class TreeShims {
 
+    public static final String SWITCH_EXPRESSION = "SWITCH_EXPRESSION"; //NOI18N
+
     public static List<? extends ExpressionTree> getExpressions(CaseTree node) {
         try {
             Method getExpressions = CaseTree.class.getDeclaredMethod("getExpressions");
@@ -64,7 +65,7 @@ public class TreeShims {
             case "CASE":
                 exprTrees = getExpressions((CaseTree) node);
                 break;
-            case "SWITCH_EXPRESSION": {
+            case SWITCH_EXPRESSION: {
                 try {
                     Class swExprTreeClass = Class.forName("com.sun.source.tree.SwitchExpressionTree");
                     Method getExpressions = swExprTreeClass.getDeclaredMethod("getExpression");
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
index 793a388..5231dbc 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/pretty/VeryPretty.java
@@ -84,6 +84,7 @@ import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Convert;
 import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
 
@@ -402,7 +403,11 @@ public final class VeryPretty extends JCTree.Visitor implements DocTreeVisitor<V
             } else {
                 boolean saveComments = this.commentsEnabled;
                 this.commentsEnabled = printComments;
-                t.accept(this);
+                if (t.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
+                    visitSwitchExpression(t);
+                } else {
+                    t.accept(this);
+                }
                 this.commentsEnabled = saveComments;
             }
 
@@ -1268,6 +1273,47 @@ public final class VeryPretty extends JCTree.Visitor implements DocTreeVisitor<V
 	print('}');
     }
 
+    public void visitSwitchExpression(Tree tree) {
+        print("switch");
+        print(cs.spaceBeforeSwitchParen() ? " (" : "(");
+        if (cs.spaceWithinSwitchParens()) {
+            print(' ');
+        }
+        printNoParenExpr((JCTree) TreeShims.getExpressions(tree).get(0));
+        print(cs.spaceWithinSwitchParens() ? " )" : ")");
+        int bcol = out.leftMargin;
+        switch (cs.getOtherBracePlacement()) {
+            case NEW_LINE:
+                newline();
+                toColExactly(bcol);
+                break;
+            case NEW_LINE_HALF_INDENTED:
+                newline();
+                bcol += (indentSize >> 1);
+                toColExactly(bcol);
+                break;
+            case NEW_LINE_INDENTED:
+                newline();
+                bcol += indentSize;
+                toColExactly(bcol);
+                break;
+        }
+        if (cs.spaceBeforeSwitchLeftBrace()) {
+            needSpace();
+        }
+        print('{');
+        if (!TreeShims.getCases(tree).isEmpty()) {
+            newline();
+            ListBuffer<JCTree.JCCase> newTcases = new ListBuffer<JCTree.JCCase>();
+            for (CaseTree t : TreeShims.getCases(tree)) {
+                newTcases.append((JCTree.JCCase) t);
+            }
+            printStats(newTcases.toList());
+            toColExactly(bcol);
+        }
+        print('}');
+    }
+
     @Override
     public void visitCase(JCCase tree) {
         int old = cs.indentCasesFromSwitch() ? indent() : out.leftMargin;
@@ -1294,6 +1340,7 @@ public final class VeryPretty extends JCTree.Visitor implements DocTreeVisitor<V
         } else {
             print(" -> "); //TODO: configure spaces!
             printStat(tree.stats.head);
+            undent(old);
         }
     }
 
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
index 87377e3..b175482 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
@@ -5612,7 +5612,7 @@ public class CasualDiff {
                   }
                   break;
               }
-              if(oldT.getKind().toString().equals("SWITCH_EXPRESSION")){
+              if(oldT.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)){
                   retVal = diffSwitchExpression(oldT, newT, elementBounds);
                   break;
               }
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
index 2bcf4b4..36d5b64 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
@@ -578,7 +578,7 @@ public class Reformatter implements ReformatTask {
             try {
                 if (endPos < 0)
                     return false;
-                Boolean ret = tokens.offset() <= endPos ? (tree.getKind().toString().equals("SWITCH_EXPRESSION")) ? scanSwitchExpression(tree,p) : super.scan(tree, p) : null; //NOI18N
+                Boolean ret = tokens.offset() <= endPos ? (tree.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) ? scanSwitchExpression(tree,p) : super.scan(tree, p) : null;
                 return ret != null ? ret : true;
             }
             finally {
@@ -2592,7 +2592,7 @@ public class Reformatter implements ReformatTask {
             boolean indentCases = cs.indentCasesFromSwitch() ;
             int old = lastIndent;
             int halfIndent = lastIndent;
-            if (node.getKind().toString().equals("SWITCH_EXPRESSION")) {
+            if (node.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
                 continuationIndent = false;
             }
             switch (bracePlacement) {
@@ -2632,7 +2632,7 @@ public class Reformatter implements ReformatTask {
                     }
                     break;
             }
-            if (node.getKind().toString().equals("SWITCH_EXPRESSION")) { //NOI18N
+            if (node.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
                 old = indent;
                 indent = lastIndent + indentSize;
             }
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
index f07d1d2..597c093 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
@@ -780,7 +780,7 @@ public class Reindenter implements IndentTask {
                 }
                 break;
             default:
-                if (last.getKind().toString().equals("SWITCH_EXPRESSION")) {  //NOI18N
+                if (last.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
                    currentIndent = getSwitchIndent(startOffset, endOffset,nextTokenId,lastPos,currentIndent) ;
                 }
                 else currentIndent = getContinuationIndent(path, currentIndent);
diff --git a/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/SwitchExpressionTest.java b/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/SwitchExpressionTest.java
index 81a3897..344996e 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/SwitchExpressionTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/SwitchExpressionTest.java
@@ -31,7 +31,6 @@ import com.sun.source.tree.VariableTree;
 import com.sun.tools.javac.tree.JCTree;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -169,7 +168,7 @@ public class SwitchExpressionTest extends TreeRewriteTestBase {
                 Tree switchBlock = switcExpression.getInitializer();
                 List<? extends CaseTree> cases;
                 List<ExpressionTree> patterns = new ArrayList<>();
-                boolean switchExpressionFlag = switchBlock.getKind().toString().equals("SWITCH_EXPRESSION");
+                boolean switchExpressionFlag = switchBlock.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION);
                 if (switchExpressionFlag) {
                     cases = TreeShims.getCases(switchBlock);
                 } else {
diff --git a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
index 75ff372..8a911af 100644
--- a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
+++ b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
@@ -55,10 +55,8 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.comp.Annotate;
-import com.sun.tools.javac.comp.ArgumentAttr;
 import com.sun.tools.javac.comp.Attr;
 import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.comp.Modules;
 import com.sun.tools.javac.comp.Todo;
@@ -92,13 +90,10 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
-import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URI;
 import java.nio.CharBuffer;
@@ -116,8 +111,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.AnnotationValueVisitor;
@@ -173,7 +166,6 @@ import org.netbeans.spi.editor.hints.Severity;
 import org.netbeans.spi.java.classpath.support.ClassPathSupport;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
-import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
 import org.openide.util.NbCollections;
 import org.openide.util.WeakListeners;
@@ -199,6 +191,7 @@ public class Utilities {
     }
 
     private static final String DISABLE_ERRORS = "disable-java-errors";
+    private static final String SWITCH_EXPRESSION = "SWITCH_EXPRESSION";
     
 
     public static <E> Iterable<E> checkedIterableByFilter(final Iterable raw, final Class<E> type, final boolean strict) {
@@ -377,7 +370,7 @@ public class Utilities {
             patternTree = ((SwitchTree) switchTree).getCases().get(0);
         }
 
-        if (patternTree == null || isErrorTree(patternTree) || "SWITCH_EXPRESSION".equals(patternTree.getKind().name())) {
+        if (patternTree == null || isErrorTree(patternTree) || SWITCH_EXPRESSION.equals(patternTree.getKind().name())) {
             SourcePositions[] currentPatternTreePositions = new SourcePositions[1];
             List<Diagnostic<? extends JavaFileObject>> currentPatternTreeErrors = new LinkedList<Diagnostic<? extends JavaFileObject>>();
             Tree currentPatternTree = parseStatement(c, "{" + pattern + "}", currentPatternTreePositions, currentPatternTreeErrors);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists