| import org.checkerframework.common.value.qual.*; |
| |
| // Test case for switch statements. Not really about the value checker (more about |
| // whether the semantics of switch are correct in general), but I needed some |
| // checker to try it out on. |
| public class Switch { |
| void test1(@IntVal({1, 2, 3, 4, 5}) int x) { |
| |
| // easy version, no fall through |
| switch (x) { |
| case 1: |
| @IntVal({1}) int y = x; |
| break; |
| case 2: |
| @IntVal({2}) int w = x; |
| // :: error: (assignment) |
| @IntVal({1}) int z = x; |
| break; |
| default: |
| @IntVal({3, 4, 5}) int q = x; |
| break; |
| } |
| } |
| |
| void test2(@IntVal({1, 2, 3, 4, 5}) int x) { |
| |
| // harder version, fall through |
| switch (x) { |
| case 1: |
| @IntVal({1}) int y = x; |
| case 2: |
| case 3: |
| @IntVal({1, 2, 3}) int w = x; |
| // :: error: (assignment) |
| @IntVal({2, 3}) int z = x; |
| // :: error: (assignment) |
| @IntVal({3}) int z1 = x; |
| break; |
| default: |
| @IntVal({4, 5}) int q = x; |
| |
| // :: error: (assignment) |
| @IntVal(5) int q2 = x; |
| break; |
| } |
| } |
| |
| void test3(@IntVal({1, 2, 3, 4, 5}) int x) { |
| |
| // harder version, fall through |
| switch (x) { |
| case 1: |
| @IntVal({1}) int y = x; |
| case 2: |
| case 3: |
| @IntVal({1, 2, 3}) int w = x; |
| // :: error: (assignment) |
| @IntVal({2, 3}) int z = x; |
| // :: error: (assignment) |
| @IntVal({3}) int z1 = x; |
| break; |
| case 4: |
| default: |
| @IntVal({4, 5}) int q = x; |
| |
| // :: error: (assignment) |
| @IntVal(5) int q2 = x; |
| break; |
| } |
| } |
| |
| void test4(int x) { |
| switch (x) { |
| case 1: |
| @IntVal({1}) int y = x; |
| break; |
| case 2: |
| case 3: |
| @IntVal({2, 3}) int z = x; |
| break; |
| case 4: |
| default: |
| return; |
| } |
| @IntVal({1, 2, 3}) int y = x; |
| // :: error: (assignment) |
| @IntVal(4) int y2 = x; |
| } |
| |
| void test5(@IntVal({0, 1, 2, 3, 4}) int x) { |
| @IntVal({0, 1, 2, 3, 4, 5}) int y = x; |
| switch (y = y + 1) { |
| case 1: |
| @IntVal({1}) int a = y; |
| // :: error: (assignment) |
| @IntVal({2}) int b = y; |
| case 2: |
| case 3: |
| @IntVal({1, 2, 3}) int c = y; |
| break; |
| default: |
| // :: error: (assignment) |
| @IntVal({4}) int d = y; |
| // :: error: (assignment) |
| @IntVal({5}) int e = y; |
| @IntVal({4, 5}) int f = y; |
| break; |
| } |
| } |
| |
| void testInts1(@IntRange(from = 0, to = 100) int x) { |
| switch (x) { |
| case 0: |
| case 1: |
| case 2: |
| @IntVal({0, 1, 2}) int z = x; |
| return; |
| default: |
| } |
| |
| @IntRange(from = 3, to = 100) int z = x; |
| } |
| |
| void testInts2(@IntRange(from = 0, to = 100) int x) { |
| |
| // harder version, fall through |
| switch (x) { |
| case 0: |
| @IntVal(0) int a = x; |
| break; |
| case 1: |
| @IntVal(1) int b = x; |
| break; |
| case 2: |
| @IntVal(2) int c = x; |
| default: |
| @IntRange(from = 2, to = 100) int d = x; |
| break; |
| } |
| } |
| |
| void testChars(char x) { |
| switch (x) { |
| case 'a': |
| case 2: |
| @IntVal({'a', 2}) int z = x; |
| break; |
| case 'b': |
| @IntVal('b') int v = x; |
| break; |
| default: |
| return; |
| } |
| @IntVal({'a', 2, 'b'}) int y = x; |
| } |
| |
| void testStrings1(String s) { |
| switch (s) { |
| case "Good": |
| @StringVal("Good") String x = s; |
| case "Bye": |
| @StringVal({"Good", "Bye"}) String y = s; |
| break; |
| case "Hello": |
| @StringVal("Hello") String z = s; |
| break; |
| default: |
| return; |
| } |
| @StringVal({"Good", "Bye", "Hello"}) String q = s; |
| } |
| |
| void testStrings2(String s) { |
| String a; |
| switch (a = s) { |
| case "Good": |
| @StringVal("Good") String x1 = a; |
| @StringVal("Good") String x2 = s; |
| case "Bye": |
| @StringVal({"Good", "Bye"}) String y1 = a; |
| @StringVal({"Good", "Bye"}) String y2 = s; |
| break; |
| case "Hello": |
| @StringVal("Hello") String z1 = a; |
| @StringVal("Hello") String z2 = s; |
| break; |
| default: |
| return; |
| } |
| @StringVal({"Good", "Bye", "Hello"}) String q1 = a; |
| @StringVal({"Good", "Bye", "Hello"}) String q2 = s; |
| } |
| } |