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 <vikas.prabha...@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-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists