1 /*
   2  * @test /nodynamiccopyright/
   3  * @bug 8206986 8222169 8224031
   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 ${jdk.version} 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(convert1(null), -2);
  31         assertEquals(convert2("A"), 0);
  32         assertEquals(convert2("B"), 0);
  33         assertEquals(convert2("C"), 1);
  34         assertEquals(convert2(""), -1);
  35         localClass(T.A);
  36         assertEquals(castSwitchExpressions(T.A), "A");
  37     }
  38 
  39     private String print(T t) {
  40         return switch (t) {
  41             case A -> "A";
  42             case B -> { yield "B"; }
  43             default -> { yield "other"; }
  44         };
  45     }
  46 
  47     private String exhaustive1(T t) {
  48         return switch (t) {
  49             case A -> "A";
  50             case B -> { yield "B"; }
  51             case C -> "C";
  52             case D -> "D";
  53         };
  54     }
  55 
  56     private String exhaustive2(T t) {
  57         return switch (t) {
  58             case A -> "A";
  59             case B -> "B";
  60             case C -> "C";
  61             case D -> "D";
  62         };
  63     }
  64 
  65     private String scopesIsolated(T t) {
  66         return switch (t) {
  67             case A -> { String res = "A"; yield res;}
  68             case B -> { String res = "B"; yield res;}
  69             default -> { String res = "default"; yield res;}
  70         };
  71     }
  72 
  73     private Supplier<String> lambdas1(T t) {
  74         return switch (t) {
  75             case A -> () -> "A";
  76             case B -> { yield () -> "B"; }
  77             default -> () -> "default";
  78         };
  79     }
  80 
  81     private Supplier<String> lambdas2(T t) {
  82         return switch (t) {
  83             case A: yield () -> "A";
  84             case B: { yield () -> "B"; }
  85             default: yield () -> "default";
  86         };
  87     }
  88 
  89     private int convert1(String s) {
  90         return s == null
  91                 ? -2
  92                 : switch (s) {
  93                       case "A", "B" -> 0;
  94                       case "C" -> { yield 1; }
  95                       default -> -1;
  96                   };
  97     }
  98 
  99     private int convert2(String s) {
 100         return switch (s) {
 101             case "A", "B": yield 0;
 102             case "C": yield 1;
 103             default: yield -1;
 104         };
 105     }
 106 
 107     private void localClass(T t) {
 108         String good = "good";
 109         class L {
 110             public String c() {
 111                 STOP: switch (t) {
 112                     default: break STOP;
 113                 }
 114                 return switch (t) {
 115                     default: yield good;
 116                 };
 117             }
 118         }
 119         String result = new L().c();
 120         if (!Objects.equals(result, good)) {
 121             throw new AssertionError("Unexpected result: " + result);
 122         }
 123     }
 124 
 125     private String castSwitchExpressions(T t) {
 126         return (String) switch (t) {
 127             case A -> "A";
 128             default -> 1;
 129         };
 130     }
 131 
 132     private void check(T t, String expected) {
 133         String result = print(t);
 134         assertEquals(result, expected);
 135     }
 136 
 137     private void assertEquals(Object result, Object expected) {
 138         if (!Objects.equals(result, expected)) {
 139             throw new AssertionError("Unexpected result: " + result);
 140         }
 141     }
 142 
 143     enum T {
 144         A, B, C, D;
 145     }
 146     void t() {
 147         Runnable r = () -> {};
 148         r.run();
 149     }
 150 }