aboutsummaryrefslogtreecommitdiffstats
path: root/tests/features1921
diff options
context:
space:
mode:
authorAlexander Kriegisch <Alexander@Kriegisch.name>2023-10-05 11:29:04 +0700
committerAlexander Kriegisch <Alexander@Kriegisch.name>2023-10-05 11:29:04 +0700
commit72171c3724100618bf2c733316d23ff7578eeaa1 (patch)
tree9ee595318fd7a6c53578a1731b909cc89966b6b9 /tests/features1921
parent99f426e351b62310ce3c31348594b106a4bf624e (diff)
downloadaspectj-72171c3724100618bf2c733316d23ff7578eeaa1.tar.gz
aspectj-72171c3724100618bf2c733316d23ff7578eeaa1.zip
Make all existing tests run on JDK 21
This mostly affects pattern matching for switch and record patterns. Two tests which were working before for pattern matching for switch (preview 4), started to fail, so the corresponding code was commented out and https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466 recorded. Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'tests/features1921')
-rw-r--r--tests/features1921/java21/SwitchPatternPreview3Aspect.aj97
-rw-r--r--tests/features1921/java21/SwitchPatternPreview4OK.java157
2 files changed, 254 insertions, 0 deletions
diff --git a/tests/features1921/java21/SwitchPatternPreview3Aspect.aj b/tests/features1921/java21/SwitchPatternPreview3Aspect.aj
new file mode 100644
index 000000000..cab9a2bcd
--- /dev/null
+++ b/tests/features1921/java21/SwitchPatternPreview3Aspect.aj
@@ -0,0 +1,97 @@
+import java.util.List;
+import java.util.Locale;
+
+aspect SwitchPatternPreview3Aspect {
+ Object around(Object o) : execution(* doSomethingWithObject(*)) && args(o) {
+ System.out.println(switch (o) {
+ case null -> "null";
+ case Integer i -> String.format("int %d", i);
+ case Long l -> String.format("long %d", l);
+ case Double d -> String.format(Locale.ENGLISH, "double %f", d);
+ case String s -> String.format("String %s", s);
+ default -> o.toString();
+ });
+ return proceed(o);
+ }
+
+ before(Shape s) : execution(* doSomethingWithShape(*)) && args(s) {
+ System.out.println(switch (s) {
+ case Circle c when (c.calculateArea() > 100) -> "Large circle";
+ case Circle c -> "Small circle";
+ default -> "Non-circle";
+ });
+ }
+
+ after(S s) : execution(* doSomethingWithSealedClass(*)) && args(s) {
+ System.out.println(switch (s) {
+ case A a -> "Sealed sub-class A";
+ case B b -> "Sealed sub-class B";
+ case C c -> "Sealed sub-record C";
+ });
+ }
+
+ Object around(Integer i): execution(* doSomethingWithInteger(*)) && args(i) {
+ // This used to work in preview 4 (Java 20), but fails during runtime with
+ // java.lang.IndexOutOfBoundsException: Index 4 out of bounds for length 4
+ // in ECJ 3.36.0-SNAPSHOT with Java 21.
+ // See:
+ // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466.
+ //
+ // TODO: Activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466 is fixed.
+ /*
+ System.out.println(
+ switch (i) {
+ case null -> "value unavailable: " + i;
+ case -1, 1 -> "absolute value 1: " + i;
+ case Integer value when value > 0 -> "positive integer: " + i;
+ default -> "other integer: " + i;
+ }
+ );
+ */
+ return proceed(i);
+ }
+}
+
+class Shape {}
+class Rectangle extends Shape {}
+class Circle extends Shape {
+ private final double radius;
+ public Circle(double radius) { this.radius = radius; }
+ double calculateArea() { return Math.PI * radius * radius; }
+}
+
+sealed interface S permits A, B, C {}
+final class A implements S {}
+final class B implements S {}
+record C(int i) implements S {} // Implicitly final
+
+class Application {
+ public static void main(String[] args) {
+ doSomethingWithObject(null);
+ doSomethingWithObject(123);
+ doSomethingWithObject(999L);
+ doSomethingWithObject(12.34);
+ doSomethingWithObject("foo");
+ doSomethingWithObject(List.of(123, "foo", 999L, 12.34));
+
+ doSomethingWithShape(new Rectangle());
+ doSomethingWithShape(new Circle(5));
+ doSomethingWithShape(new Circle(6));
+
+ doSomethingWithSealedClass(new A());
+ doSomethingWithSealedClass(new B());
+ doSomethingWithSealedClass(new C(5));
+
+ doSomethingWithInteger(-1);
+ doSomethingWithInteger(0);
+ doSomethingWithInteger(42);
+ doSomethingWithInteger(-99);
+ doSomethingWithInteger(Integer.valueOf(123));
+ doSomethingWithInteger(null);
+ }
+
+ public static Object doSomethingWithObject(Object o) { return o; }
+ public static void doSomethingWithSealedClass(S s) {}
+ public static void doSomethingWithShape(Shape s) {}
+ public static Object doSomethingWithInteger(Integer o) { return o; }
+}
diff --git a/tests/features1921/java21/SwitchPatternPreview4OK.java b/tests/features1921/java21/SwitchPatternPreview4OK.java
new file mode 100644
index 000000000..c9caf7eca
--- /dev/null
+++ b/tests/features1921/java21/SwitchPatternPreview4OK.java
@@ -0,0 +1,157 @@
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Inspired by examples in https://openjdk.org/jeps/427
+ */
+public class SwitchPatternPreview4OK {
+ public static void main(String[] args) {
+
+ System.out.println(formatterPatternSwitch(null));
+ System.out.println(formatterPatternSwitch(123));
+ System.out.println(formatterPatternSwitch(999L));
+ System.out.println(formatterPatternSwitch(12.34));
+ System.out.println(formatterPatternSwitch("foo"));
+ System.out.println(formatterPatternSwitch(List.of(123, "foo", 999L, 12.34)));
+
+ System.out.println(testCircle(new Rectangle()));
+ System.out.println(testCircle(new Circle(5)));
+ System.out.println(testCircle(new Circle(6)));
+
+ System.out.println(testSealedCoverage(new A()));
+ System.out.println(testSealedCoverage(new B()));
+ System.out.println(testSealedCoverage(new C(5)));
+
+// constantLabelMustAppearBeforePattern(-1);
+// constantLabelMustAppearBeforePattern(0);
+// constantLabelMustAppearBeforePattern(42);
+// constantLabelMustAppearBeforePattern(-99);
+// constantLabelMustAppearBeforePattern(Integer.valueOf(123));
+// constantLabelMustAppearBeforePattern(null);
+
+ // TODO: Activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466 is fixed.
+ /*
+ constantLabelMustAppearBeforePatternInteger(-1);
+ constantLabelMustAppearBeforePatternInteger(0);
+ constantLabelMustAppearBeforePatternInteger(42);
+ constantLabelMustAppearBeforePatternInteger(-99);
+ constantLabelMustAppearBeforePatternInteger(Integer.valueOf(123));
+ constantLabelMustAppearBeforePatternInteger(null);
+ */
+
+ System.out.println(testGenericSealedExhaustive(new E<Integer>()));
+ }
+
+ static String formatterPatternSwitch(Object o) {
+ return switch (o) {
+ case null -> "null";
+ case Integer i -> String.format("int %d", i);
+ case Long l -> String.format("long %d", l);
+ case Double d -> String.format(Locale.ENGLISH, "double %f", d);
+ case String s -> String.format("String %s", s);
+ default -> o.toString();
+ };
+ }
+
+ static class Shape {}
+ static class Rectangle extends Shape {}
+ static class Circle extends Shape {
+ private final double radius;
+ public Circle(double radius) { this.radius = radius; }
+ double calculateArea() { return Math.PI * radius * radius; }
+ }
+
+ static String testCircle(Shape s) {
+ return switch (s) {
+ case Circle c when (c.calculateArea() > 100) -> "Large circle";
+ case Circle c -> "Small circle";
+ default -> "Non-circle";
+ };
+ }
+
+ sealed interface S permits A, B, C {}
+ final static class A implements S {}
+ final static class B implements S {}
+ static record C(int i) implements S {} // Implicitly final
+
+ static String testSealedCoverage(S s) {
+ return switch (s) {
+ case A a -> "Sealed sub-class A";
+ case B b -> "Sealed sub-class B";
+ case C c -> "Sealed sub-record C";
+ };
+ }
+
+ /**
+ * According to an example from JEP 420, this should work, but it does not, neither with Javac nor ECJ.
+ *
+ * See:
+ * https://openjdk.java.net/jeps/420#1b--Dominance-of-pattern-labels
+ * https://bugs.openjdk.java.net/browse/JDK-8273326
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=579355
+ *
+ * TODO: reactivate when implemented or move to preview 5 with Java 21, Eclipse 4.28.
+ */
+/*
+ static String constantLabelMustAppearBeforePattern(Object o) {
+ switch (o) {
+ case null -> System.out.println("value unavailable: " + o);
+ case -1, 1 -> System.out.println("special case:" + o);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + o);
+ case Integer i -> System.out.println("other integer: " + o);
+ default -> System.out.println("non-integer: " + o);
+ }
+ return o == null ? "null" : o.toString();
+ }
+*/
+
+ /**
+ * This used to work in preview 4 (Java 20), but fails during runtime with
+ * java.lang.IndexOutOfBoundsException: Index 4 out of bounds for length 4
+ * in ECJ 3.36.0-SNAPSHOT with Java 21.
+ * See:
+ * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466.
+ *
+ * TODO: Activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1466 is fixed.
+ */
+ static String constantLabelMustAppearBeforePatternInteger(Integer i) {
+ switch (i) {
+ case null -> System.out.println("value unavailable: " + i);
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ default -> System.out.println("other integer: " + i);
+ }
+ return i == null ? "null" : i.toString();
+ }
+
+ static void nullCanAppearAfterConstantLabel(Integer i) {
+ switch (i) {
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ case null -> System.out.println("value unavailable: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ default -> System.out.println("other integer: " + i);
+ }
+ }
+
+ /**
+ * According to an example from JEP 420, this should work with preview 2 (Java 18), and it does with Javac,
+ * but not with ECJ for Java 18, 19 and 20.
+ *
+ * See:
+ * https://openjdk.java.net/jeps/420#2--Exhaustiveness-of-switch-expressions-and-statements
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=579360
+ * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/587
+ *
+ * TODO: reactivate when implemented or move to preview 5 with Java 21.
+ */
+ sealed interface I<T> permits D, E {}
+ final static class D<X> implements I<String> {}
+ final static class E<Y> implements I<Y> {}
+
+ static int testGenericSealedExhaustive(I<Integer> i) {
+ return switch (i) {
+ // Exhaustive as no D case possible!
+ case E<Integer> bi -> 42;
+ };
+ }
+}