1 /*
   2  * @test /nodynamiccopyright/
   3  * @bug 8206986
   4  * @summary Check expression switch works.
   5  * @compile/fail/ref=ExpressionSwitch-old.out -source 9 -Xlint:-options -XDrawDiagnostics ExpressionSwitch.java
   6  * @compile --enable-preview -source 12 ExpressionSwitch.java
   7  * @run main/othervm --enable-preview ExpressionSwitch
   8  */
   9 
  10 import java.util.Objects;
  11 import java.util.function.Supplier;
  12 
  13 public class ExpressionSwitch {
  14     public static void main(String... args) {
  15         new ExpressionSwitch().run();
  16     }
  17 
  18     private void run() {
  19         check(T.A, "A");
  20         check(T.B, "B");
  21         check(T.C, "other");
  22         assertEquals(exhaustive1(T.C), "C");
  23         assertEquals(scopesIsolated(T.B), "B");
  24         assertEquals(lambdas1(T.B).get(), "B");
  25         assertEquals(lambdas2(T.B).get(), "B");
  26         assertEquals(convert1("A"), 0);
  27         assertEquals(convert1("B"), 0);
  28         assertEquals(convert1("C"), 1);
  29         assertEquals(convert1(""), -1);
  30         assertEquals(convert2("A"), 0);
  31         assertEquals(convert2("B"), 0);
  32         assertEquals(convert2("C"), 1);
  33         assertEquals(convert2(""), -1);
  34         localClass(T.A);
  35     }
  36 
  37     private String print(T t) {
  38         return switch (t) {
  39             case A -> "A";
  40             case B -> { break "B"; }
  41             default -> { break "other"; }
  42         };
  43     }
  44 
  45     private String exhaustive1(T t) {
  46         return switch (t) {
  47             case A -> "A";
  48             case B -> { break "B"; }
  49             case C -> "C";
  50             case D -> "D";
  51         };
  52     }
  53 
  54     private String exhaustive2(T t) {
  55         return switch (t) {
  56             case A -> "A";
  57             case B -> "B";
  58             case C -> "C";
  59             case D -> "D";
  60         };
  61     }
  62 
  63     private String scopesIsolated(T t) {
  64         return switch (t) {
  65             case A -> { String res = "A"; break res;}
  66             case B -> { String res = "B"; break res;}
  67             default -> { String res = "default"; break res;}
  68         };
  69     }
  70 
  71     private Supplier<String> lambdas1(T t) {
  72         return switch (t) {
  73             case A -> () -> "A";
  74             case B -> { break () -> "B"; }
  75             default -> () -> "default";
  76         };
  77     }
  78 
  79     private Supplier<String> lambdas2(T t) {
  80         return switch (t) {
  81             case A: break () -> "A";
  82             case B: { break () -> "B"; }
  83             default: break () -> "default";
  84         };
  85     }
  86 
  87     private int convert1(String s) {
  88         return switch (s) {
  89             case "A", "B" -> 0;
  90             case "C" -> { break 1; }
  91             default -> -1;
  92         };
  93     }
  94 
  95     private int convert2(String s) {
  96         return switch (s) {
  97             case "A", "B": break 0;
  98             case "C": break 1;
  99             default: break -1;
 100         };
 101     }
 102 
 103     private void localClass(T t) {
 104         String good = "good";
 105         class L {
 106             public String c() {
 107                 STOP: switch (t) {
 108                     default: break STOP;
 109                 }
 110                 return switch (t) {
 111                     default: break good;
 112                 };
 113             }
 114         }
 115         String result = new L().c();
 116         if (!Objects.equals(result, good)) {
 117             throw new AssertionError("Unexpected result: " + result);
 118         }
 119     }
 120 
 121     private void check(T t, String expected) {
 122         String result = print(t);
 123         assertEquals(result, expected);
 124     }
 125 
 126     private void assertEquals(Object result, Object expected) {
 127         if (!Objects.equals(result, expected)) {
 128             throw new AssertionError("Unexpected result: " + result);
 129         }
 130     }
 131 
 132     enum T {
 133         A, B, C, D;
 134     }
 135     void t() {
 136         Runnable r = () -> {};
 137         r.run();
 138     }
 139 }