From 5239ae0480d4f623aa9c9491b6bf75e3e568cc89 Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Wed, 21 Dec 2022 12:57:44 +0100 Subject: [PATCH] Add tests for Java 19 record patterns Signed-off-by: Alexander Kriegisch --- .../java19/RecordPatternsPreview1Aspect.aj | 35 +++++++++ .../java19/RecordPatternsPreview1Error.java | 24 ++++++ ...ordPatternsPreview1ExhaustivenessAspect.aj | 37 +++++++++ ...rdPatternsPreview1ExhaustivenessError.java | 22 ++++++ ...cordPatternsPreview1ExhaustivenessOK1.java | 28 +++++++ ...cordPatternsPreview1ExhaustivenessOK2.java | 10 +++ .../java19/RecordPatternsPreview1OK.java | 15 ++++ .../java19/SwitchPatternPreview3OK.java | 6 +- .../java18/SwitchPatternPreview2OK.java | 6 +- .../ajc1919/Java19PreviewFeaturesTests.java | 43 ++++++++++ .../aspectj/systemtest/ajc1919/ajc1919.xml | 78 ++++++++++++++++++- 11 files changed, 297 insertions(+), 7 deletions(-) create mode 100644 tests/features1919/java19/RecordPatternsPreview1Aspect.aj create mode 100644 tests/features1919/java19/RecordPatternsPreview1Error.java create mode 100644 tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj create mode 100644 tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java create mode 100644 tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java create mode 100644 tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java create mode 100644 tests/features1919/java19/RecordPatternsPreview1OK.java diff --git a/tests/features1919/java19/RecordPatternsPreview1Aspect.aj b/tests/features1919/java19/RecordPatternsPreview1Aspect.aj new file mode 100644 index 000000000..20f6a54e5 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1Aspect.aj @@ -0,0 +1,35 @@ +public aspect RecordPatternsPreview1Aspect { + public static void main(String[] args) { + doSomething(new Point(2, 7)); + doSomething(new Rectangle( + new ColoredPoint(new Point(1, 6), Color.RED), + new ColoredPoint(new Point(4, 6), Color.BLUE) + )); + } + + public static void doSomething(Object object) { + System.out.println("Doing something with " + object); + } + + before(Object object): execution(* doSomething(*)) && args(object) { + if (object instanceof Point p) { + int x = p.x(); + int y = p.y(); + System.out.println(x + y); + } + if (object instanceof Point(int x, int y)) + System.out.println(x * y); + + if (object instanceof Rectangle(ColoredPoint ul, ColoredPoint lr)) + System.out.println("Upper-left color: " + ul.c()); + if (object instanceof Rectangle(ColoredPoint(Point p, Color c), ColoredPoint lr)) + System.out.println("Upper-left color: " + c); + if (object instanceof Rectangle(ColoredPoint(Point(var x, var y), var c), var lr)) + System.out.println("Upper-left x coordinate: " + x); + } +} + +record Point(int x,int y){} +enum Color { RED, GREEN, BLUE } +record ColoredPoint(Point p, Color c) {} +record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {} diff --git a/tests/features1919/java19/RecordPatternsPreview1Error.java b/tests/features1919/java19/RecordPatternsPreview1Error.java new file mode 100644 index 000000000..2a5038e89 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1Error.java @@ -0,0 +1,24 @@ +/** + * This was not working as expected in ECJ after the initial Java 19 merge the JDT Core main line, + * see https://github.com/eclipse-jdt/eclipse.jdt.core/issues/450. + */ +public class RecordPatternsPreview1Error { + public static void main(String[] args) { + erroneousTest1(new Box<>("A")); + erroneousTest2(new Box<>("B")); + } + + static void erroneousTest1(Box bo) { + if (bo instanceof Box(var s)) { // Javac error: raw deconstruction patterns are not allowed + System.out.println("I'm a box"); + } + } + + static void erroneousTest2(Box b) { + if (b instanceof Box(var t)) { // Javac error: raw deconstruction patterns are not allowed + System.out.println("I'm a box"); + } + } +} + +record Box(T t) {} diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj new file mode 100644 index 000000000..44c7f12d0 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj @@ -0,0 +1,37 @@ +public aspect RecordPatternsPreview1ExhaustivenessAspect { + static Pair p2 = new Pair<>(new C(), new D()); + + public static void main(String[] args) { + doSomething(p2); + } + + public static void doSomething(Pair pair) { + System.out.println(pair.toString().replaceAll("@[0-9a-f]+", "@000")); + } + + before(Pair pair) : execution(* doSomething(Pair)) && args(pair) { + switch (pair) { + case Pair(I i, C c) -> System.out.println("x"); + case Pair(I i, D d) -> System.out.println("y"); + // TODO: Remove redundant default clause when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 + // has been fixed. But even with the default clause, it generates wrong byte code and throws runtime error: + // NoSuchMethodError: 'I Pair.x()' + default -> System.out.println("z"); + } + + switch (pair) { + case Pair(C c, I i) -> System.out.println("a"); + case Pair(D d, C c) -> System.out.println("b"); + case Pair(D d1, D d2) -> System.out.println("c"); + // TODO: remove redundant default clause when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 + // has been fixed. But even with the default clause, it generates wrong byte code and throws runtime error: + // NoSuchMethodError: 'I Pair.x()' + default -> System.out.println("d"); + } + } +} + +sealed interface I permits C, D { } +final class C implements I { } +final class D implements I { } +record Pair(T x, T y) { } diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java new file mode 100644 index 000000000..8df079474 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java @@ -0,0 +1,22 @@ +public class RecordPatternsPreview1ExhaustivenessError { + static Pair p2 = new Pair<>(new C(), new D()); + + public static void main(String[] args) { + exhaustiveSwitch(); + } + + static void exhaustiveSwitch() { + switch (p2) { + case Pair(C fst, D snd) -> System.out.println("a"); + case Pair(D fst, C snd) -> System.out.println("b"); + case Pair(I fst, C snd) -> System.out.println("c"); + } + } +} + +class A { } +class B extends A { } +sealed interface I permits C, D { } +final class C implements I { } +final class D implements I { } +record Pair(T x, T y) { } diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java new file mode 100644 index 000000000..4153d5021 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java @@ -0,0 +1,28 @@ +public class RecordPatternsPreview1ExhaustivenessOK1 { + static Pair p1 = new Pair<>(new A(), new B()); + static Pair p2 = new Pair<>(new C(), new D()); + + public static void main(String[] args) { + exhaustiveSwitch(); + } + + static void exhaustiveSwitch() { + switch (p2) { + case Pair(I i, C c) -> System.out.println("x"); + case Pair(I i, D d) -> System.out.println("y"); + } + + switch (p2) { + case Pair(C c, I i) -> System.out.println("a"); + case Pair(D d, C c) -> System.out.println("b"); + case Pair(D d1, D d2) -> System.out.println("c"); + } + } +} + +class A { } +class B extends A { } +sealed interface I permits C, D { } +final class C implements I { } +final class D implements I { } +record Pair(T x, T y) { } diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java new file mode 100644 index 000000000..8f80aad90 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java @@ -0,0 +1,10 @@ +public class RecordPatternsPreview1ExhaustivenessOK2 { + public static void main(String[] args) { + Person person = new Person("Bob", 12); + switch (person) { + case Person(var name, var age) -> System.out.println(name + " " + age); + } + } +} + +record Person(String name, int age) { } diff --git a/tests/features1919/java19/RecordPatternsPreview1OK.java b/tests/features1919/java19/RecordPatternsPreview1OK.java new file mode 100644 index 000000000..ba62f79d5 --- /dev/null +++ b/tests/features1919/java19/RecordPatternsPreview1OK.java @@ -0,0 +1,15 @@ +public class RecordPatternsPreview1OK { + static void printGenericBoxString1(Box objectBox) { + if (objectBox instanceof Box(String s)) { + System.out.println(s); + } + } + + static void printGenericBoxString2(Box stringBox) { + if (stringBox instanceof Box(var s)) { + System.out.println(s); + } + } +} + +record Box(T t) {} diff --git a/tests/features1919/java19/SwitchPatternPreview3OK.java b/tests/features1919/java19/SwitchPatternPreview3OK.java index 7060ec0c2..7395f08e9 100644 --- a/tests/features1919/java19/SwitchPatternPreview3OK.java +++ b/tests/features1919/java19/SwitchPatternPreview3OK.java @@ -149,13 +149,15 @@ public class SwitchPatternPreview3OK { } /** - * According to an example from JEP 420, this should work, and it does with Javac, but not with ECJ. + * 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 and 19. * * 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 3 with Java 19, Eclipse 4.24. + * TODO: reactivate when implemented or move to preview 4 with Java 20. */ /* sealed interface I permits A, B {} diff --git a/tests/features199/java18/SwitchPatternPreview2OK.java b/tests/features199/java18/SwitchPatternPreview2OK.java index b36b26bf2..c17fdc12b 100644 --- a/tests/features199/java18/SwitchPatternPreview2OK.java +++ b/tests/features199/java18/SwitchPatternPreview2OK.java @@ -90,13 +90,13 @@ public class SwitchPatternPreview2OK { } /** - * According to an example from JEP 420, this should work, and it does with Javac, but not with ECJ. + * 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 and 19. * * See: * https://openjdk.java.net/jeps/420#2--Exhaustiveness-of-switch-expressions-and-statements * https://bugs.eclipse.org/bugs/show_bug.cgi?id=579360 - * - * TODO: reactivate when implemented or move to preview 3 with Java 19, Eclipse 4.24. + * https://github.com/eclipse-jdt/eclipse.jdt.core/issues/587 */ /* sealed interface I permits A, B {} diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java index 39f9019f4..b4dc12f39 100644 --- a/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java +++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java @@ -42,6 +42,49 @@ public class Java19PreviewFeaturesTests extends XMLBasedAjcTestCaseForJava19Only runTest("switch pattern matching preview 3 error 2"); } + public void testRecordPatternsPreview1OK() { + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/450 + runTest("record patterns"); + } + + public void testRecordPatternsPreview1Error() { + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/450 + runTest("record patterns error"); + } + + public void testRecordPatternsPreview1ExhaustivenessOK1() { + // Falsely throws 'An enhanced switch statement should be exhaustive; a default label expected' twice, + // see https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 + // TODO: activate when fixed + System.out.println("TODO: activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 has been fixed"); + //runTest("record patterns exhaustiveness 1"); + } + + public void testRecordPatternsPreview1Aspect() { + runTest("record patterns aspect"); + } + + public void testRecordPatternsPreview1ExhaustivenessAspect() { + // TODO: Remove redundant default clauses in RecordPatternsPreview1Aspect when + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 has been fixed. Furthermore, activate '' + // action for XML test case in order to not just compile but also run the code. + System.out.println("TODO: fully activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 has been fixed"); + runTest("record patterns exhaustiveness aspect"); + } + + public void testRecordPatternsPreview1ExhaustivenessError() { + // See https://github.com/eclipse-jdt/eclipse.jdt.core/issues/455 + runTest("record patterns exhaustiveness error"); + } + + public void testRecordPatternsPreview1ExhaustivenessOK2() { + // Falsely throws 'An enhanced switch statement should be exhaustive; a default label expected', + // see https://github.com/eclipse-jdt/eclipse.jdt.core/issues/398 + // TODO: activate when fixed + System.out.println("TODO: activate when https://github.com/eclipse-jdt/eclipse.jdt.core/issues/398 has been fixed"); + //runTest("record patterns exhaustiveness 2"); + } + public static Test suite() { return XMLBasedAjcTestCase.loadSuite(Java19PreviewFeaturesTests.class); } diff --git a/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml index 9adc98bca..3741b338c 100644 --- a/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml +++ b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml @@ -88,8 +88,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + -- 2.39.5