src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
changeset 51563 de411d537aae
parent 50181 f854b76b6a0c
child 51721 96b76dca2be8
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Aug 28 09:01:54 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Wed Aug 29 09:36:17 2018 +0200
@@ -47,10 +47,12 @@
 
 import javax.tools.JavaFileManager.Location;
 
+import com.sun.source.tree.CaseTree.CaseKind;
 import com.sun.source.tree.ModuleTree.ModuleKind;
 import com.sun.tools.javac.code.Directive.ExportsDirective;
 import com.sun.tools.javac.code.Directive.OpensDirective;
 import com.sun.tools.javac.code.Type.ModuleType;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.PolyKind;
 
 /**
  * Root class for abstract syntax tree nodes. It provides definitions
@@ -149,10 +151,14 @@
          */
         SWITCH,
 
-        /** Case parts in switch statements, of type Case.
+        /** Case parts in switch statements/expressions, of type Case.
          */
         CASE,
 
+        /** Switch expression statements, of type Switch.
+         */
+        SWITCH_EXPRESSION,
+
         /** Synchronized statements, of type Synchonized.
          */
         SYNCHRONIZED,
@@ -1238,21 +1244,50 @@
      * A "case  :" of a switch.
      */
     public static class JCCase extends JCStatement implements CaseTree {
-        public JCExpression pat;
+        //as CaseKind is deprecated for removal (as it is part of a preview feature),
+        //using indirection through these fields to avoid unnecessary @SuppressWarnings:
+        @SuppressWarnings("removal")
+        public static final CaseKind STATEMENT = CaseKind.STATEMENT;
+        @SuppressWarnings("removal")
+        public static final CaseKind RULE = CaseKind.RULE;
+        @SuppressWarnings("removal")
+        public final CaseKind caseKind;
+        public List<JCExpression> pats;
         public List<JCStatement> stats;
-        protected JCCase(JCExpression pat, List<JCStatement> stats) {
-            this.pat = pat;
+        public JCTree body;
+        public boolean completesNormally;
+        protected JCCase(@SuppressWarnings("removal") CaseKind caseKind, List<JCExpression> pats,
+                         List<JCStatement> stats, JCTree body) {
+            Assert.checkNonNull(pats);
+            Assert.check(pats.isEmpty() || pats.head != null);
+            this.caseKind = caseKind;
+            this.pats = pats;
             this.stats = stats;
+            this.body = body;
         }
         @Override
         public void accept(Visitor v) { v.visitCase(this); }
 
-        @DefinedBy(Api.COMPILER_TREE)
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() { return Kind.CASE; }
-        @DefinedBy(Api.COMPILER_TREE)
-        public JCExpression getExpression() { return pat; }
-        @DefinedBy(Api.COMPILER_TREE)
-        public List<JCStatement> getStatements() { return stats; }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public JCExpression getExpression() { return pats.head; }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        @SuppressWarnings("removal")
+        public List<JCExpression> getExpressions() { return pats; }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        @SuppressWarnings("removal")
+        public List<JCStatement> getStatements() {
+            return caseKind == CaseKind.STATEMENT ? stats : null;
+        }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        @SuppressWarnings("removal")
+        public JCTree getBody() { return body; }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        @SuppressWarnings("removal")
+        public CaseKind getCaseKind() {
+            return caseKind;
+        }
         @Override @DefinedBy(Api.COMPILER_TREE)
         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
             return v.visitCase(this, d);
@@ -1264,6 +1299,36 @@
     }
 
     /**
+     * A "switch ( ) { }" construction.
+     */
+    @SuppressWarnings("removal")
+    public static class JCSwitchExpression extends JCPolyExpression implements SwitchExpressionTree {
+        public JCExpression selector;
+        public List<JCCase> cases;
+        protected JCSwitchExpression(JCExpression selector, List<JCCase> cases) {
+            this.selector = selector;
+            this.cases = cases;
+        }
+        @Override
+        public void accept(Visitor v) { v.visitSwitchExpression(this); }
+
+        @DefinedBy(Api.COMPILER_TREE)
+        public Kind getKind() { return Kind.SWITCH_EXPRESSION; }
+        @DefinedBy(Api.COMPILER_TREE)
+        public JCExpression getExpression() { return selector; }
+        @DefinedBy(Api.COMPILER_TREE)
+        public List<JCCase> getCases() { return cases; }
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public <R,D> R accept(TreeVisitor<R,D> v, D d) {
+            return v.visitSwitchExpression(this, d);
+        }
+        @Override
+        public Tag getTag() {
+            return SWITCH_EXPRESSION;
+        }
+    }
+
+    /**
      * A synchronized block.
      */
     public static class JCSynchronized extends JCStatement implements SynchronizedTree {
@@ -1484,19 +1549,27 @@
      * A break from a loop or switch.
      */
     public static class JCBreak extends JCStatement implements BreakTree {
-        public Name label;
+        public JCExpression value;
         public JCTree target;
-        protected JCBreak(Name label, JCTree target) {
-            this.label = label;
+        protected JCBreak(JCExpression value, JCTree target) {
+            this.value = value;
             this.target = target;
         }
         @Override
         public void accept(Visitor v) { v.visitBreak(this); }
+        public boolean isValueBreak() {
+            return target != null && target.hasTag(SWITCH_EXPRESSION);
+        }
 
         @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() { return Kind.BREAK; }
         @DefinedBy(Api.COMPILER_TREE)
-        public Name getLabel() { return label; }
+        public Name getLabel() {
+            return value != null && value.getKind() == Kind.IDENTIFIER ? ((JCIdent) value).getName() : null;
+        }
+        @DefinedBy(Api.COMPILER_TREE)
+        @SuppressWarnings("removal")
+        public JCExpression getValue() { return value; }
         @Override @DefinedBy(Api.COMPILER_TREE)
         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
             return v.visitBreak(this, d);
@@ -2934,9 +3007,9 @@
 
     /** (let int x = 3; in x+2) */
     public static class LetExpr extends JCExpression {
-        public List<JCVariableDecl> defs;
+        public List<JCStatement> defs;
         public JCExpression expr;
-        protected LetExpr(List<JCVariableDecl> defs, JCExpression expr) {
+        protected LetExpr(List<JCStatement> defs, JCExpression expr) {
             this.defs = defs;
             this.expr = expr;
         }
@@ -2994,7 +3067,9 @@
         JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body);
         JCLabeledStatement Labelled(Name label, JCStatement body);
         JCSwitch Switch(JCExpression selector, List<JCCase> cases);
-        JCCase Case(JCExpression pat, List<JCStatement> stats);
+        JCSwitchExpression SwitchExpression(JCExpression selector, List<JCCase> cases);
+        JCCase Case(@SuppressWarnings("removal") CaseKind caseKind, List<JCExpression> pat,
+                    List<JCStatement> stats, JCTree body);
         JCSynchronized Synchronized(JCExpression lock, JCBlock body);
         JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer);
         JCTry Try(List<JCTree> resources,
@@ -3007,7 +3082,7 @@
                                 JCExpression elsepart);
         JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart);
         JCExpressionStatement Exec(JCExpression expr);
-        JCBreak Break(Name label);
+        JCBreak Break(JCExpression value);
         JCContinue Continue(Name label);
         JCReturn Return(JCExpression expr);
         JCThrow Throw(JCExpression expr);
@@ -3049,7 +3124,7 @@
         JCProvides Provides(JCExpression serviceName, List<JCExpression> implNames);
         JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId);
         JCUses Uses(JCExpression qualId);
-        LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr);
+        LetExpr LetExpr(List<JCStatement> defs, JCExpression expr);
     }
 
     /** A generic visitor class for trees.
@@ -3070,6 +3145,7 @@
         public void visitLabelled(JCLabeledStatement that)   { visitTree(that); }
         public void visitSwitch(JCSwitch that)               { visitTree(that); }
         public void visitCase(JCCase that)                   { visitTree(that); }
+        public void visitSwitchExpression(JCSwitchExpression that)               { visitTree(that); }
         public void visitSynchronized(JCSynchronized that)   { visitTree(that); }
         public void visitTry(JCTry that)                     { visitTree(that); }
         public void visitCatch(JCCatch that)                 { visitTree(that); }