]> source.dussan.org Git - aspectj.git/commitdiff
Add tests for Java 19 record patterns
authorAlexander Kriegisch <Alexander@Kriegisch.name>
Wed, 21 Dec 2022 11:57:44 +0000 (12:57 +0100)
committerAlexander Kriegisch <Alexander@Kriegisch.name>
Wed, 21 Dec 2022 11:57:44 +0000 (12:57 +0100)
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
tests/features1919/java19/RecordPatternsPreview1Aspect.aj [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1Error.java [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java [new file with mode: 0644]
tests/features1919/java19/RecordPatternsPreview1OK.java [new file with mode: 0644]
tests/features1919/java19/SwitchPatternPreview3OK.java
tests/features199/java18/SwitchPatternPreview2OK.java
tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java
tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml

diff --git a/tests/features1919/java19/RecordPatternsPreview1Aspect.aj b/tests/features1919/java19/RecordPatternsPreview1Aspect.aj
new file mode 100644 (file)
index 0000000..20f6a54
--- /dev/null
@@ -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 (file)
index 0000000..2a5038e
--- /dev/null
@@ -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<Object> 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 t) {}
diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessAspect.aj
new file mode 100644 (file)
index 0000000..44c7f12
--- /dev/null
@@ -0,0 +1,37 @@
+public aspect RecordPatternsPreview1ExhaustivenessAspect {
+  static Pair<I> 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 i, C c) -> System.out.println("x");
+      case Pair<I>(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<I>(C c, I i) -> System.out.println("a");
+      case Pair<I>(D d, C c) -> System.out.println("b");
+      case Pair<I>(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>(T x, T y) { }
diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessError.java
new file mode 100644 (file)
index 0000000..8df0794
--- /dev/null
@@ -0,0 +1,22 @@
+public class RecordPatternsPreview1ExhaustivenessError {
+  static Pair<I> p2 = new Pair<>(new C(), new D());
+
+  public static void main(String[] args) {
+    exhaustiveSwitch();
+  }
+
+  static void exhaustiveSwitch() {
+    switch (p2) {
+      case Pair<I>(C fst, D snd) -> System.out.println("a");
+      case Pair<I>(D fst, C snd) -> System.out.println("b");
+      case Pair<I>(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>(T x, T y) { }
diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK1.java
new file mode 100644 (file)
index 0000000..4153d50
--- /dev/null
@@ -0,0 +1,28 @@
+public class RecordPatternsPreview1ExhaustivenessOK1 {
+  static Pair<A> p1 = new Pair<>(new A(), new B());
+  static Pair<I> p2 = new Pair<>(new C(), new D());
+
+  public static void main(String[] args) {
+    exhaustiveSwitch();
+  }
+
+  static void exhaustiveSwitch() {
+    switch (p2) {
+      case Pair<I>(I i, C c) -> System.out.println("x");
+      case Pair<I>(I i, D d) -> System.out.println("y");
+    }
+
+    switch (p2) {
+      case Pair<I>(C c, I i) -> System.out.println("a");
+      case Pair<I>(D d, C c) -> System.out.println("b");
+      case Pair<I>(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>(T x, T y) { }
diff --git a/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java b/tests/features1919/java19/RecordPatternsPreview1ExhaustivenessOK2.java
new file mode 100644 (file)
index 0000000..8f80aad
--- /dev/null
@@ -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 (file)
index 0000000..ba62f79
--- /dev/null
@@ -0,0 +1,15 @@
+public class RecordPatternsPreview1OK {
+  static void printGenericBoxString1(Box<Object> objectBox) {
+    if (objectBox instanceof Box<Object>(String s)) {
+      System.out.println(s);
+    }
+  }
+
+  static void printGenericBoxString2(Box<String> stringBox) {
+    if (stringBox instanceof Box<String>(var s)) {
+      System.out.println(s);
+    }
+  }
+}
+
+record Box<T>(T t) {}
index 7060ec0c25927d804608749c7e31562925117d25..7395f08e920ab559ba9dced36459c8c41fd0f05c 100644 (file)
@@ -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<T> permits A, B {}
index b36b26bf23edfbfc62603fc719b4352c6cd4e09d..c17fdc12b567ce871105f38cfbbb90d1cc4cdf52 100644 (file)
@@ -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<T> permits A, B {}
index 39f9019f455975584f98d80a3793ded7301e953b..b4dc12f39f2519a07585a059f13c8218c1ba2b74 100644 (file)
@@ -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 '<run />'
+    //   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);
   }
index 9adc98bca461d2d18d1072472c40b592dc8dcb33..3741b338c62b6b7944a747a7c8083cbe00931635 100644 (file)
                </compile>
        </ajc-test>
 
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns">
+    <compile files="RecordPatternsPreview1OK.java" options="--enable-preview -19"/>
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns error">
+               <compile files="RecordPatternsPreview1Error.java" options="--enable-preview -19">
+                       <message kind="error" file="RecordPatternsPreview1Error.java" text="Raw types are not allowed in record patterns"/>
+                       <message kind="error" file="RecordPatternsPreview1Error.java" text="Raw types are not allowed in record patterns"/>
+               </compile>
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns exhaustiveness 1">
+               <compile files="RecordPatternsPreview1ExhaustivenessOK1.java" options="--enable-preview -19"/>
+               <run class="RecordPatternsPreview1ExhaustivenessOK1" vmargs="--enable-preview">
+                       <stdout>
+                               <line text="y"/>
+                               <line text="a"/>
+                       </stdout>
+               </run>
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns exhaustiveness aspect">
+               <compile files="RecordPatternsPreview1ExhaustivenessAspect.aj" options="--enable-preview -19"/>
+               <!--
+                       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()'
+               -->
+               <!--run class="RecordPatternsPreview1ExhaustivenessAspect" vmargs="-XXX-enable-preview">
+                       <stdout>
+                               <line text="y"/>
+                               <line text="a"/>
+                               <line text="Pair[x=C@000, y=D@000]"/>
+                       </stdout>
+               </run-->
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns aspect">
+               <compile files="RecordPatternsPreview1Aspect.aj" options="--enable-preview -19"/>
+               <run class="RecordPatternsPreview1Aspect" vmargs="--enable-preview">
+                       <stdout>
+                               <line text="9"/>
+                               <line text="14"/>
+                               <line text="Doing something with Point[x=2, y=7]"/>
+                               <line text="Upper-left color: RED"/>
+                               <line text="Upper-left color: RED"/>
+                               <line text="Upper-left x coordinate: 1"/>
+                               <line text="Doing something with Rectangle[upperLeft=ColoredPoint[p=Point[x=1, y=6], c=RED], lowerRight=ColoredPoint[p=Point[x=4, y=6], c=BLUE]]"/>
+                       </stdout>
+               </run>
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns exhaustiveness error">
+               <compile files="RecordPatternsPreview1ExhaustivenessError.java" options="--enable-preview -19">
+                       <message kind="error" file="RecordPatternsPreview1ExhaustivenessError.java" text="An enhanced switch statement should be exhaustive; a default label expected"/>
+               </compile>
+       </ajc-test>
+
+       <!-- Java ?? final, Java 19 preview -->
+       <ajc-test dir="features1919/java19" vm="19" title="record patterns exhaustiveness 2">
+               <compile files="RecordPatternsPreview1ExhaustivenessOK2.java" options="--enable-preview -19"/>
+               <run class="RecordPatternsPreview1ExhaustivenessOK2" vmargs="--enable-preview">
+                       <stdout>
+                               <line text="Bob 12"/>
+                       </stdout>
+               </run>
+       </ajc-test>
+
        <!-- Currently, there are no bugfixes with tests in this AspectJ vesion -->
-  <ajc-test dir="bugs1919/github_99999" vm="19" title="dummy Java 19">
-       </ajc-test>
+       <ajc-test dir="bugs1919/github_99999" vm="19" title="dummy Java 19">
+       </ajc-test>
 
 </suite>