| /* | |
| * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| import java.util.Objects; | |
| import java.util.function.BiFunction; | |
| import java.util.function.Consumer; | |
| import java.util.function.Function; | |
| /* | |
| * @test | |
| * @bug 8262891 8268333 8268896 8269802 8269808 8270151 8269113 8277864 8290709 8339296 | |
| * @summary Check behavior of pattern switches. | |
| */ | |
| public class Switches { | |
| public static void main(String... args) { | |
| new Switches().run(); | |
| } | |
| void run() { | |
| run(this::typeTestPatternSwitchTest); | |
| run(this::typeTestPatternSwitchExpressionTest); | |
| run(this::testBooleanSwitchExpression); | |
| assertFalse(testNullSwitch(null)); | |
| assertTrue(testNullSwitch("")); | |
| runArrayTypeTest(this::testArrayTypeStatement); | |
| runArrayTypeTest(this::testArrayTypeExpression); | |
| runEnumTest(this::testEnumExpression1); | |
| runEnumTest(this::testEnumExpression2); | |
| runEnumTest(this::testEnumWithGuards1); | |
| runEnumTest(this::testEnumWithGuards2); | |
| runEnumTest(this::testEnumWithGuards3); | |
| runEnumTest(this::testEnumWithGuards4); | |
| runEnumTest(this::testEnumWithGuards5); | |
| runEnumTest(this::testEnumWithGuardsExpression1); | |
| runEnumTest(this::testEnumWithGuardsExpression2); | |
| runEnumTest(this::testEnumWithGuardsExpression3); | |
| runEnumTest(this::testEnumWithGuardsExpression4); | |
| runEnumTest(this::testEnumWithGuardsExpression5); | |
| runEnumTest(this::testStringWithGuards1); | |
| runEnumTest(this::testStringWithGuardsExpression1); | |
| runEnumTest(this::testIntegerWithGuards1); | |
| runEnumTest(this::testIntegerWithGuardsExpression1); | |
| runStringWithConstant(this::testStringWithConstant); | |
| runStringWithConstant(this::testStringWithConstantExpression); | |
| runFallThrough(this::testFallThroughStatement); | |
| runFallThrough(this::testFallThroughExpression); | |
| runFallThrough(this::testFallThrough2Statement); | |
| runFallThrough(this::testFallThrough2Expression); | |
| npeTest(this::npeTestStatement); | |
| npeTest(this::npeTestExpression); | |
| npeTest(this::switchOverNullNPE); | |
| exhaustiveStatementSane(""); | |
| exhaustiveStatementSane(null); | |
| exhaustiveStatementSane2(null); | |
| exhaustiveStatementSane2(new A()); | |
| exhaustiveStatementSane2(new B()); | |
| switchNestingTest(this::switchNestingStatementStatement); | |
| switchNestingTest(this::switchNestingStatementExpression); | |
| switchNestingTest(this::switchNestingExpressionStatement); | |
| switchNestingTest(this::switchNestingExpressionExpression); | |
| switchNestingTest(this::switchNestingIfSwitch); | |
| npeTest(x -> switchOverNull1()); | |
| assertEquals(2, switchOverNull2()); | |
| assertEquals(2, switchOverNull3()); | |
| assertEquals(5, switchOverPrimitiveInt(0)); | |
| assertEquals(7, switchOverPrimitiveInt(1)); | |
| assertEquals(9, switchOverPrimitiveInt(2)); | |
| assertEquals("a", deconstructStatement(new R("a"))); | |
| assertEquals("1", deconstructStatement(new R(1))); | |
| assertEquals("other", deconstructStatement("")); | |
| assertEquals("a", deconstructExpression(new R("a"))); | |
| assertEquals("1", deconstructExpression(new R(1))); | |
| assertEquals("other", deconstructExpression("")); | |
| assertEquals("a", translationTest("a")); | |
| assertEquals("Rb", translationTest(new R("b"))); | |
| assertEquals("R2c", translationTest(new R2("c"))); | |
| assertEquals("other", translationTest(0)); | |
| assertEquals("OK", totalPatternAndNull(Integer.valueOf(42))); | |
| assertEquals("OK", totalPatternAndNull(null)); | |
| assertEquals("1", nullAfterTotal(Integer.valueOf(42))); | |
| assertEquals("OK", nullAfterTotal(null)); | |
| emptyFallThrough(1); | |
| emptyFallThrough(""); | |
| emptyFallThrough(1.0); | |
| testSimpleSwitch(); | |
| testSimpleSwitchExpression(); | |
| assertEquals(0, constantAndPatternGuardInteger(0, true)); | |
| assertEquals(0, constantAndPatternGuardInteger(1, true)); | |
| assertEquals(1, constantAndPatternGuardInteger(1, false)); | |
| assertEquals(2, constantAndPatternGuardInteger(0, false)); | |
| assertEquals(0, constantAndPatternGuardString("", true)); | |
| assertEquals(0, constantAndPatternGuardString("a", true)); | |
| assertEquals(1, constantAndPatternGuardString("a", false)); | |
| assertEquals(2, constantAndPatternGuardString("", false)); | |
| assertEquals(0, constantAndPatternGuardEnum(E.A, true)); | |
| assertEquals(0, constantAndPatternGuardEnum(E.B, true)); | |
| assertEquals(1, constantAndPatternGuardEnum(E.B, false)); | |
| assertEquals(2, constantAndPatternGuardEnum(E.A, false)); | |
| assertEquals(0, nestedSwitchesInArgumentPosition(1)); | |
| assertEquals(1, nestedSwitchesInArgumentPosition(new R(1))); | |
| assertEquals(5, nestedSwitchesInArgumentPosition(new R(new R("hello")))); | |
| } | |
| void run(Function<Object, Integer> mapper) { | |
| assertEquals(2, mapper.apply("2")); | |
| assertEquals(3, mapper.apply("3")); | |
| assertEquals(8, mapper.apply(new StringBuilder("4"))); | |
| assertEquals(2, mapper.apply(2)); | |
| assertEquals(3, mapper.apply(3)); | |
| assertEquals(-1, mapper.apply(2.0)); | |
| assertEquals(-1, mapper.apply(new Object())); | |
| } | |
| void runArrayTypeTest(Function<Object, String> mapper) { | |
| assertEquals("arr0", mapper.apply(new int[0])); | |
| assertEquals("str6", mapper.apply("string")); | |
| assertEquals("i1", mapper.apply(1)); | |
| assertEquals("", mapper.apply(1.0)); | |
| } | |
| void runDefaultTest(Function<Object, String> mapper) { | |
| assertEquals("default", mapper.apply(new int[0])); | |
| assertEquals("str6", mapper.apply("string")); | |
| assertEquals("default", mapper.apply(1)); | |
| assertEquals("default", mapper.apply(1.0)); | |
| } | |
| void runEnumTest(Function<E, String> mapper) { | |
| assertEquals("a", mapper.apply(E.A)); | |
| assertEquals("b", mapper.apply(E.B)); | |
| assertEquals("C", mapper.apply(E.C)); | |
| assertEquals("null", mapper.apply(null)); | |
| } | |
| void runStringWithConstant(Function<String, Integer> mapper) { | |
| assertEquals(1, mapper.apply("A")); | |
| assertEquals(2, mapper.apply("AA")); | |
| assertEquals(0, mapper.apply("")); | |
| assertEquals(-1, mapper.apply(null)); | |
| } | |
| void runFallThrough(Function<Integer, Integer> mapper) { | |
| assertEquals(2, mapper.apply(1)); | |
| } | |
| void npeTest(Consumer<I> testCase) { | |
| try { | |
| testCase.accept(null); | |
| throw new AssertionError("Expected a NullPointerException, but got nothing."); | |
| } catch (NullPointerException ex) { | |
| //OK | |
| } | |
| } | |
| void switchNestingTest(BiFunction<Object, Object, String> testCase) { | |
| assertEquals("string, string", testCase.apply("", "")); | |
| assertEquals("string, other", testCase.apply("", 1)); | |
| assertEquals("other, string", testCase.apply(1, "")); | |
| assertEquals("other, other", testCase.apply(1, 1)); | |
| } | |
| int typeTestPatternSwitchTest(Object o) { | |
| switch (o) { | |
| case String s: return Integer.parseInt(s.toString()); | |
| case CharSequence s: return 2 * Integer.parseInt(s.toString()); | |
| case Integer i: return i; | |
| case Object x: return -1; | |
| } | |
| } | |
| int typeTestPatternSwitchExpressionTest(Object o) { | |
| return switch (o) { | |
| case String s -> Integer.parseInt(s.toString()); | |
| case @Deprecated CharSequence s -> { yield 2 * Integer.parseInt(s.toString()); } | |
| case final Integer i -> i; | |
| case Object x -> -1; | |
| }; | |
| } | |
| int testBooleanSwitchExpression(Object o) { | |
| Object x; | |
| if (switch (o) { | |
| default -> false; | |
| }) { | |
| return -3; | |
| } else if (switch (o) { | |
| case String s -> (x = s) != null; | |
| default -> false; | |
| }) { | |
| return Integer.parseInt(x.toString()); | |
| } else if (switch (o) { | |
| case CharSequence s -> { | |
| x = s; | |
| yield true; | |
| } | |
| default -> false; | |
| }) { | |
| return 2 * Integer.parseInt(x.toString()); | |
| } | |
| return typeTestPatternSwitchTest(o); | |
| } | |
| boolean testNullSwitch(Object o) { | |
| return switch (o) { | |
| case null -> false; | |
| default -> true; | |
| }; | |
| } | |
| String testArrayTypeStatement(Object o) { | |
| String res; | |
| switch (o) { | |
| case Integer i -> res = "i" + i; | |
| case int[] arr -> res = "arr" + arr.length; | |
| case String str -> res = "str" + str.length(); | |
| default -> res = ""; | |
| } | |
| return res; | |
| } | |
| String testArrayTypeExpression(Object o) { | |
| return switch (o) { | |
| case Integer i -> "i" + i; | |
| case int[] arr -> "arr" + arr.length; | |
| case String str -> "str" + str.length(); | |
| default -> ""; | |
| }; | |
| } | |
| int testStringWithConstant(String str) { | |
| switch (str) { | |
| case "A": return 1; | |
| case null: return -1; | |
| case String s: return s.length(); | |
| } | |
| } | |
| int testStringWithConstantExpression(String str) { | |
| return switch (str) { | |
| case "A" -> 1; | |
| case null -> -1; | |
| case String s -> s.length(); | |
| }; | |
| } | |
| String testEnumExpression1(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case E x -> String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumExpression2(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case E x -> String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumWithGuards1(E e) { | |
| switch (e) { | |
| case A: return "a"; | |
| case B: return "b"; | |
| case C: return String.valueOf(e); | |
| case E x when "A".equals(x.name()): return "broken"; | |
| case E x: return String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testEnumWithGuardsExpression1(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case C -> String.valueOf(e); | |
| case E x when "A".equals(x.name()) -> "broken"; | |
| case E x -> String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumWithGuards2(E e) { | |
| switch (e) { | |
| case A: return "a"; | |
| case B: return "b"; | |
| case E x when "C".equals(x.name()): return "C"; | |
| case E x: return e == E.C ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testEnumWithGuardsExpression2(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case E x when "C".equals(x.name()) -> "C"; | |
| case E x -> e == E.C ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumWithGuards3(E e) { | |
| switch (e) { | |
| case A: return "a"; | |
| case B: return "b"; | |
| case Object x when "C".equals(x.toString()): return "C"; | |
| case E x: return e == E.C ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testEnumWithGuardsExpression3(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case Object x when "C".equals(x.toString()) -> "C"; | |
| case E x -> e == E.C ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumWithGuards4(E e) { | |
| switch (e) { | |
| case A: return "a"; | |
| case B: return "b"; | |
| case Runnable x when "C".equals(x.toString()): return "C"; | |
| case E x: return e == E.C ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testEnumWithGuardsExpression4(E e) { | |
| return switch (e) { | |
| case A -> "a"; | |
| case B -> "b"; | |
| case Runnable x when "C".equals(x.toString()) -> "C"; | |
| case E x -> e == E.C ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testEnumWithGuards5(Object e) { | |
| switch (e) { | |
| case E.A: return "a"; | |
| case E.B: return "b"; | |
| case Runnable x when "C".equals(x.toString()): return "C"; | |
| case E x: return e == E.C ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| default: throw new AssertionError("Unexpected case!"); | |
| } | |
| } | |
| String testEnumWithGuardsExpression5(Object e) { | |
| return switch (e) { | |
| case E.A -> "a"; | |
| case E.B -> "b"; | |
| case Runnable x when "C".equals(x.toString()) -> "C"; | |
| case E x -> e == E.C ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| default -> throw new AssertionError("Unexpected case!"); | |
| }; | |
| } | |
| String testStringWithGuards1(E e) { | |
| switch (e != null ? e.name() : null) { | |
| case "A": return "a"; | |
| case Switches.ConstantClassClash: return "b"; | |
| case String x when "C".equals(x): return "C"; | |
| case String x: return "C".equals(x) ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testStringWithGuardsExpression1(E e) { | |
| return switch (e != null ? e.name() : null) { | |
| case "A" -> "a"; | |
| case ConstantClassClash -> "b"; | |
| case String x when "C".equals(x) -> "C"; | |
| case String x -> e == E.C ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| String testIntegerWithGuards1(E e) { | |
| switch (e != null ? e.ordinal() : null) { | |
| case 0: return "a"; | |
| case 1: return "b"; | |
| case Integer x when x.equals(2): return "C"; | |
| case Integer x: return Objects.equals(x, 2) ? "broken" : String.valueOf(x); | |
| case null: return "null"; | |
| } | |
| } | |
| String testIntegerWithGuardsExpression1(E e) { | |
| return switch (e != null ? e.ordinal() : null) { | |
| case 0 -> "a"; | |
| case 1 -> "b"; | |
| case Integer x when x.equals(2) -> "C"; | |
| case Integer x -> Objects.equals(x, 2) ? "broken" : String.valueOf(x); | |
| case null -> "null"; | |
| }; | |
| } | |
| Integer testFallThroughStatement(Integer i) { | |
| int r = 0; | |
| switch (i) { | |
| case Integer o when o != null: | |
| r = 1; | |
| default: | |
| r = 2; | |
| } | |
| return r; | |
| } | |
| Integer testFallThroughExpression(Integer i) { | |
| int r = switch (i) { | |
| case Integer o when o != null: | |
| r = 1; | |
| default: | |
| r = 2; | |
| yield r; | |
| }; | |
| return r; | |
| } | |
| Integer testFallThrough2Statement(Integer i) { | |
| int r = 0; | |
| switch (i) { | |
| case Integer o when o != null: | |
| r = 1; | |
| case null, default: | |
| r = 2; | |
| } | |
| return r; | |
| } | |
| Integer testFallThrough2Expression(Integer i) { | |
| int r = switch (i) { | |
| case Integer o when o != null: | |
| r = 1; | |
| case null, default: | |
| r = 2; | |
| yield r; | |
| }; | |
| return r; | |
| } | |
| void npeTestStatement(I i) { | |
| switch (i) { | |
| case A a -> {} | |
| case B b -> {} | |
| } | |
| } | |
| void npeTestExpression(I i) { | |
| int j = switch (i) { | |
| case A a -> 0; | |
| case B b -> 1; | |
| }; | |
| } | |
| void exhaustiveStatementSane(Object o) { | |
| try { | |
| switch (o) { | |
| case Object obj:; //no break intentionally - should not fall through to any possible default | |
| } | |
| if (o == null) { | |
| throw new AssertionError(); | |
| } | |
| } catch (NullPointerException ex) { | |
| if (o != null) { | |
| throw new AssertionError(); | |
| } | |
| } | |
| switch (o) { | |
| case Object obj: int i; | |
| case null:; //no break intentionally - should not fall through to any possible default | |
| } | |
| } | |
| void exhaustiveStatementSane2(I i) { | |
| switch (i) { | |
| case A a: break; | |
| case B b:; //no break intentionally - should not fall through to any possible default | |
| case null:; | |
| } | |
| switch (i) { | |
| case A a -> {} | |
| case B b -> {} | |
| case null -> {} | |
| } | |
| } | |
| String switchNestingStatementStatement(Object o1, Object o2) { | |
| switch (o1) { | |
| case String s1 -> { | |
| switch (o2) { | |
| case String s2 -> { | |
| return "string, string"; | |
| } | |
| default -> { | |
| return "string, other"; | |
| } | |
| } | |
| } | |
| default -> { | |
| switch (o2) { | |
| case String s2 -> { | |
| return "other, string"; | |
| } | |
| default -> { | |
| return "other, other"; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| String switchNestingStatementExpression(Object o1, Object o2) { | |
| switch (o1) { | |
| case String s1 -> { | |
| return switch (o2) { | |
| case String s2 -> "string, string"; | |
| default -> "string, other"; | |
| }; | |
| } | |
| default -> { | |
| return switch (o2) { | |
| case String s2 -> "other, string"; | |
| default -> "other, other"; | |
| }; | |
| } | |
| } | |
| } | |
| String switchNestingExpressionStatement(Object o1, Object o2) { | |
| return switch (o1) { | |
| case String s1 -> { | |
| switch (o2) { | |
| case String s2 -> { | |
| yield "string, string"; | |
| } | |
| default -> { | |
| yield "string, other"; | |
| } | |
| } | |
| } | |
| default -> { | |
| switch (o2) { | |
| case String s2 -> { | |
| yield "other, string"; | |
| } | |
| default -> { | |
| yield "other, other"; | |
| } | |
| } | |
| } | |
| }; | |
| } | |
| String switchNestingExpressionExpression(Object o1, Object o2) { | |
| return switch (o1) { | |
| case String s1 -> | |
| switch (o2) { | |
| case String s2 -> "string, string"; | |
| default -> "string, other"; | |
| }; | |
| default -> | |
| switch (o2) { | |
| case String s2 -> "other, string"; | |
| default -> "other, other"; | |
| }; | |
| }; | |
| } | |
| String switchNestingIfSwitch(Object o1, Object o2) { | |
| BiFunction<Object, Object, String> f = (n1, n2) -> { | |
| if (o1 instanceof CharSequence cs) { | |
| return switch (cs) { | |
| case String s1 -> | |
| switch (o2) { | |
| case String s2 -> "string, string"; | |
| default -> "string, other"; | |
| }; | |
| default -> | |
| switch (o2) { | |
| case String s2 -> "other, string"; | |
| default -> "other, other"; | |
| }; | |
| }; | |
| } else { | |
| return switch (o2) { | |
| case String s2 -> "other, string"; | |
| default -> "other, other"; | |
| }; | |
| } | |
| }; | |
| return f.apply(o1, o2); | |
| } | |
| private void switchOverNullNPE(I i) { | |
| int r = switch (null) { | |
| default -> 1; | |
| }; | |
| } | |
| private int switchOverNull1() { | |
| return switch (null) { | |
| case Object o -> 2; | |
| }; | |
| } | |
| private int switchOverNull2() { | |
| return switch (null) { | |
| case null -> 2; | |
| default -> 1; | |
| }; | |
| } | |
| private int switchOverNull3() { | |
| return switch (null) { | |
| case null -> 2; | |
| case Object o -> 1; | |
| }; | |
| } | |
| private int switchOverPrimitiveInt(Integer i) { | |
| return switch (i) { | |
| case 0 -> 5 + 0; | |
| case Integer j when j == 1 -> 6 + j; | |
| case Integer j -> 7 + j; | |
| }; | |
| } | |
| String deconstructStatement(Object o) { | |
| switch (o) { | |
| case R(String s) -> {return s;} | |
| case R(Integer i) -> {return i.toString();} | |
| case Object x -> {return "other";} | |
| } | |
| } | |
| String deconstructExpression(Object o) { | |
| return switch (o) { | |
| case R(String s) -> s; | |
| case R(Integer i) -> i.toString(); | |
| case Object x -> "other"; | |
| }; | |
| } | |
| String translationTest(Object o) { | |
| return switch (o) { | |
| case R(String s) -> "R" + s; | |
| case String s -> s; | |
| case R2(String s) -> "R2" + s; | |
| default -> "other"; | |
| }; | |
| } | |
| String totalPatternAndNull(Integer in) { | |
| return switch (in) { | |
| case -1: { yield "";} | |
| case null: { yield "OK";} | |
| case Integer i: { yield "OK";} | |
| }; | |
| } | |
| String nullAfterTotal(Object o) { | |
| return switch (o) { | |
| case Object obj: { yield "1";} | |
| case null: { yield "OK";} | |
| }; | |
| } | |
| void emptyFallThrough(Object o) { | |
| switch (o) { | |
| case Integer i: | |
| case String s: | |
| case Object obj: | |
| } | |
| } | |
| void testSimpleSwitch() { | |
| Object o = ""; | |
| int res; | |
| switch (o) { | |
| default -> res = 1; | |
| }; | |
| assertEquals(1, res); | |
| } | |
| void testSimpleSwitchExpression() { | |
| Object o = ""; | |
| int res = switch (o) { | |
| default -> 1; | |
| }; | |
| assertEquals(1, res); | |
| } | |
| int constantAndPatternGuardInteger(Integer i, boolean g) { | |
| return switch (i) { | |
| case Integer j when g -> 0; | |
| case 1 -> 1; | |
| case Integer j -> 2; | |
| }; | |
| } | |
| int constantAndPatternGuardString(String s, boolean g) { | |
| return switch (s) { | |
| case String t when g -> 0; | |
| case "a" -> 1; | |
| case String t -> 2; | |
| }; | |
| } | |
| int constantAndPatternGuardEnum(E e, boolean g) { | |
| return switch (e) { | |
| case E f when g -> 0; | |
| case E.B -> 1; | |
| case E f -> 2; | |
| }; | |
| } | |
| int nestedSwitchesInArgumentPosition(Object o1) { | |
| return id(switch (o1) { | |
| case R(var o2) -> switch (o2) { | |
| case R(String s) -> s; | |
| default -> "n"; | |
| }; | |
| default -> ""; | |
| }); | |
| } | |
| int id(String s) { | |
| return s.length(); | |
| } | |
| int id(int i) { | |
| return i; | |
| } | |
| //verify that for cases like: | |
| //case ConstantClassClash -> | |
| //ConstantClassClash is interpreted as a field, not as a class | |
| private static final String ConstantClassClash = "B"; | |
| private static class ConstantClassClash {} | |
| sealed interface I {} | |
| final class A implements I {} | |
| final class B implements I {} | |
| void assertEquals(int expected, int actual) { | |
| if (expected != actual) { | |
| throw new AssertionError("Expected: " + expected + ", but got: " + actual); | |
| } | |
| } | |
| void assertEquals(String expected, String actual) { | |
| if (!Objects.equals(expected, actual)) { | |
| throw new AssertionError("Expected: " + expected + ", but got: " + actual); | |
| } | |
| } | |
| void assertTrue(boolean actual) { | |
| if (!actual) { | |
| throw new AssertionError("Expected: true, but got false"); | |
| } | |
| } | |
| void assertFalse(boolean actual) { | |
| if (actual) { | |
| throw new AssertionError("Expected: false, but got true"); | |
| } | |
| } | |
| public enum E implements Runnable { | |
| A, B, C; | |
| @Override public void run() {} | |
| } | |
| record R(Object o) {} | |
| record R2(Object o) {} | |
| } |