aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/maven.yml2
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java6
-rw-r--r--testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19Only.java40
-rw-r--r--testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19OrLater.java27
-rw-r--r--tests/features1919/java19/SwitchPatternPreview3Aspect.aj88
-rw-r--r--tests/features1919/java19/SwitchPatternPreview3Error1.java13
-rw-r--r--tests/features1919/java19/SwitchPatternPreview3Error2.java21
-rw-r--r--tests/features1919/java19/SwitchPatternPreview3OK.java172
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/AllTests19.java2
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc1919/Ajc1919TestsJava.java32
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc1919/AllTestsAspectJ1919.java33
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc1919/Bugs1919Tests.java31
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java54
-rw-r--r--tests/src/test/java/org/aspectj/systemtest/ajc1919/SanityTestsJava19.java87
-rw-r--r--tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml95
-rw-r--r--tests/src/test/resources/org/aspectj/systemtest/ajc1919/sanity-tests-19.xml70
16 files changed, 770 insertions, 3 deletions
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index b8fbbf386..c1bf1b3bf 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
# Check for available Temurin releases on https://adoptium.net/releases.html
- java: [ 11, 17, 18 ]
+ java: [ 11, 17, 19 ]
runs-on: ubuntu-latest
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java
index 6c2240b9d..87c36f2ff 100644
--- a/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java
@@ -100,8 +100,10 @@ public interface Constants {
short MINOR_17 = 0;
short MAJOR_18 = 62;
short MINOR_18 = 0;
-// short MAJOR_19 = 63;
-// short MINOR_19 = 0;
+ short MAJOR_19 = 63;
+ short MINOR_19 = 0;
+// short MAJOR_20 = 64;
+// short MINOR_20 = 0;
int PREVIEW_MINOR_VERSION = 65535;
diff --git a/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19Only.java b/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19Only.java
new file mode 100644
index 000000000..e0a99283d
--- /dev/null
+++ b/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19Only.java
@@ -0,0 +1,40 @@
+/* *******************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ * ******************************************************************/
+package org.aspectj.testing;
+
+import org.aspectj.util.LangUtil;
+
+/**
+ * Makes sure tests are running on the right level of JDK.
+ *
+ * @author Alexander Kriegisch
+ */
+public abstract class XMLBasedAjcTestCaseForJava19Only extends XMLBasedAjcTestCase {
+
+ @Override
+ public void setUp() throws Exception {
+ // Activate this block after upgrading to JDT Core Java 20
+ /*
+ throw new IllegalStateException(
+ "These tests need a Java 19 level AspectJ compiler " +
+ "(e.g. because they use version-specific preview features). " +
+ "This compiler does not support preview features of a previous version anymore."
+ );
+ */
+ // Activate this block before upgrading to JDT Core Java 20
+ if (!LangUtil.is19VMOrGreater() || LangUtil.is20VMOrGreater()) {
+ throw new IllegalStateException(
+ "These tests should be run on Java 19 only " +
+ "(e.g. because they use version-specific preview features)"
+ );
+ }
+ super.setUp();
+ }
+
+}
diff --git a/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19OrLater.java b/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19OrLater.java
new file mode 100644
index 000000000..95beffef5
--- /dev/null
+++ b/testing/src/test/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava19OrLater.java
@@ -0,0 +1,27 @@
+/* *******************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ * ******************************************************************/
+package org.aspectj.testing;
+
+import org.aspectj.util.LangUtil;
+
+/**
+ * Makes sure tests are running on the right level of JDK.
+ *
+ * @author Alexander Kriegisch
+ */
+public abstract class XMLBasedAjcTestCaseForJava19OrLater extends XMLBasedAjcTestCase {
+
+ @Override
+ public void setUp() throws Exception {
+ if (!LangUtil.is19VMOrGreater())
+ throw new IllegalStateException("These tests should be run on Java 19 or later");
+ super.setUp();
+ }
+
+}
diff --git a/tests/features1919/java19/SwitchPatternPreview3Aspect.aj b/tests/features1919/java19/SwitchPatternPreview3Aspect.aj
new file mode 100644
index 000000000..ae147dad7
--- /dev/null
+++ b/tests/features1919/java19/SwitchPatternPreview3Aspect.aj
@@ -0,0 +1,88 @@
+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) {
+ 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/features1919/java19/SwitchPatternPreview3Error1.java b/tests/features1919/java19/SwitchPatternPreview3Error1.java
new file mode 100644
index 000000000..5f3895cc3
--- /dev/null
+++ b/tests/features1919/java19/SwitchPatternPreview3Error1.java
@@ -0,0 +1,13 @@
+/**
+ * Inspired by examples in https://openjdk.java.net/jeps/420
+ */
+public class SwitchPatternPreview3Error1 {
+ static void constantLabelsMustAppearBeforePatterns1(Integer i) {
+ switch (i) {
+ case null -> System.out.println("value unavailable: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ default -> System.out.println("other integer: " + i);
+ }
+ }
+}
diff --git a/tests/features1919/java19/SwitchPatternPreview3Error2.java b/tests/features1919/java19/SwitchPatternPreview3Error2.java
new file mode 100644
index 000000000..c02c4d3cc
--- /dev/null
+++ b/tests/features1919/java19/SwitchPatternPreview3Error2.java
@@ -0,0 +1,21 @@
+/**
+ * Inspired by examples in https://openjdk.java.net/jeps/420
+ */
+public class SwitchPatternPreview3Error2 {
+ static void constantLabelsMustAppearBeforePatterns2(Object o) {
+ switch (o) {
+ case null -> System.out.println("value unavailable: " + o);
+ // This seems to be a bug in JEP 420 implementation. Those constants should be compatible with 'Object'.
+ // case -1, 1 -> System.out.println("absolute value 1: " + o);
+ // case "hello" -> System.out.println("string value: " + o);
+
+ // 'Integer value' dominates the next two, more specific ones -> error
+ case Integer value -> System.out.println("other integer: " + o);
+ case Integer value when (value == 1 || value == -1) -> System.out.println("absolute value 1: " + o);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + o);
+
+ case String value when value.startsWith("hello") -> System.out.println("greeting: " + o);
+ default -> System.out.println("other type: " + o);
+ }
+ }
+}
diff --git a/tests/features1919/java19/SwitchPatternPreview3OK.java b/tests/features1919/java19/SwitchPatternPreview3OK.java
new file mode 100644
index 000000000..7060ec0c2
--- /dev/null
+++ b/tests/features1919/java19/SwitchPatternPreview3OK.java
@@ -0,0 +1,172 @@
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Inspired by examples in https://openjdk.org/jeps/427
+ */
+public class SwitchPatternPreview3OK {
+ 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);
+
+ constantLabelMustAppearBeforePatternInteger(-1);
+ constantLabelMustAppearBeforePatternInteger(0);
+ constantLabelMustAppearBeforePatternInteger(42);
+ constantLabelMustAppearBeforePatternInteger(-99);
+ constantLabelMustAppearBeforePatternInteger(Integer.valueOf(123));
+ constantLabelMustAppearBeforePatternInteger(null);
+
+// System.out.println(testGenericSealedExhaustive(new B<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 3 with Java 19, Eclipse 4.24.
+ */
+ /*
+ static String constantLabelMustAppearBeforePattern(Object o) {
+ switch (o) {
+ case null -> System.out.println("value unavailable: " + i);
+ case -1, 1 -> System.out.println("special case:" + o);
+ case Integer i && i > 0 -> System.out.println("positive integer: " + o);
+ case Integer i -> System.out.println("other integer: " + o);
+ default -> System.out.println("non-integer: " + o);
+ }
+ return i == null ? "null" : i.toString();
+ }
+ */
+
+ 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);
+ }
+ }
+
+ static void defaultCanAppearBeforePattern(Integer i) {
+ switch (i) {
+ case null -> System.out.println("value unavailable: " + i);
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ default -> System.out.println("other integer: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ }
+ }
+
+ static void defaultCanAppearBeforeNull(Integer i) {
+ switch (i) {
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ default -> System.out.println("other integer: " + i);
+ case null -> System.out.println("value unavailable: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ }
+ }
+
+ static void defaultCanAppearBeforeConstantLabel(Integer i) {
+ switch (i) {
+ case null -> System.out.println("value unavailable: " + i);
+ default -> System.out.println("other integer: " + i);
+ case -1, 1 -> System.out.println("absolute value 1: " + i);
+ case Integer value when value > 0 -> System.out.println("positive integer: " + i);
+ }
+ }
+
+ /**
+ * According to an example from JEP 420, this should work, and it does with Javac, but not with ECJ.
+ *
+ * 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.
+ */
+ /*
+ sealed interface I<T> permits A, B {}
+ final static class A<X> implements I<String> {}
+ final static class B<Y> implements I<Y> {}
+
+ static int testGenericSealedExhaustive(I<Integer> i) {
+ return switch (i) {
+ // Exhaustive as no A case possible!
+ case B<Integer> bi -> 42;
+ };
+ }
+ */
+}
diff --git a/tests/src/test/java/org/aspectj/systemtest/AllTests19.java b/tests/src/test/java/org/aspectj/systemtest/AllTests19.java
index d14bc54cb..21ad9de90 100644
--- a/tests/src/test/java/org/aspectj/systemtest/AllTests19.java
+++ b/tests/src/test/java/org/aspectj/systemtest/AllTests19.java
@@ -9,6 +9,7 @@ package org.aspectj.systemtest;
import org.aspectj.systemtest.ajc190.AllTestsAspectJ190;
import org.aspectj.systemtest.ajc191.AllTestsAspectJ191;
+import org.aspectj.systemtest.ajc1919.AllTestsAspectJ1919;
import org.aspectj.systemtest.ajc192.AllTestsAspectJ192;
import org.aspectj.systemtest.ajc193.AllTestsAspectJ193;
import org.aspectj.systemtest.ajc195.AllTestsAspectJ195;
@@ -38,6 +39,7 @@ public class AllTests19 {
suite.addTest(AllTestsAspectJ197.suite());
suite.addTest(AllTestsAspectJ198.suite());
suite.addTest(AllTestsAspectJ199.suite());
+ suite.addTest(AllTestsAspectJ1919.suite());
suite.addTest(AllTests18.suite());
// $JUnit-END$
return suite;
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/Ajc1919TestsJava.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Ajc1919TestsJava.java
new file mode 100644
index 000000000..5f471490d
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Ajc1919TestsJava.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc1919;
+
+import junit.framework.Test;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.testing.XMLBasedAjcTestCaseForJava19OrLater;
+
+/**
+ * @author Alexander Kriegisch
+ */
+public class Ajc1919TestsJava extends XMLBasedAjcTestCaseForJava19OrLater {
+
+ public void testDummyJava19() {
+ //runTest("dummy Java 19");
+ }
+
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(Ajc1919TestsJava.class);
+ }
+
+ @Override
+ protected java.net.URL getSpecFile() {
+ return getClassResource("ajc1919.xml");
+ }
+
+}
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/AllTestsAspectJ1919.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/AllTestsAspectJ1919.java
new file mode 100644
index 000000000..da1a81f97
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/AllTestsAspectJ1919.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc1919;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.aspectj.util.LangUtil;
+
+/**
+ * @author Alexander Kriegisch
+ */
+public class AllTestsAspectJ1919 {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("AspectJ 1.9.19 tests");
+ suite.addTest(Bugs1919Tests.suite());
+ if (LangUtil.is19VMOrGreater()) {
+ suite.addTest(SanityTestsJava19.suite());
+ suite.addTest(Ajc1919TestsJava.suite());
+ }
+ // Do not run tests using a previous compiler's preview features anymore. They would all fail.
+ // TODO: Comment out the following block when upgrading JDT Core to Java 20
+ if (LangUtil.is19VMOrGreater() && !LangUtil.is20VMOrGreater()) {
+ suite.addTest(Java19PreviewFeaturesTests.suite());
+ }
+ return suite;
+ }
+}
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/Bugs1919Tests.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Bugs1919Tests.java
new file mode 100644
index 000000000..38441267e
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Bugs1919Tests.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc1919;
+
+import junit.framework.Test;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+
+/**
+ * @author Alexander Kriegisch
+ */
+public class Bugs1919Tests extends XMLBasedAjcTestCase {
+
+ public void testDummyBug() {
+ //runTest("dummy Java 19 bug");
+ }
+
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(Bugs1919Tests.class);
+ }
+
+ @Override
+ protected java.net.URL getSpecFile() {
+ return getClassResource("ajc1919.xml");
+ }
+
+}
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java
new file mode 100644
index 000000000..39f9019f4
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/Java19PreviewFeaturesTests.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc1919;
+
+import junit.framework.Test;
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.testing.XMLBasedAjcTestCaseForJava19Only;
+
+/**
+ * @author Alexander Kriegisch
+ */
+public class Java19PreviewFeaturesTests extends XMLBasedAjcTestCaseForJava19Only {
+
+ public void testSwitchPatternMatchingPreview3Java() {
+ runTest("switch pattern matching preview 3 java");
+ checkVersion("SwitchPatternPreview3OK", Constants.MAJOR_19, Constants.PREVIEW_MINOR_VERSION);
+ }
+
+ public void testSwitchPatternMatchingPreview3Aspect() {
+ runTest("switch pattern matching preview 3 aspect");
+ checkVersion("SwitchPatternPreview3Aspect", Constants.MAJOR_19, Constants.PREVIEW_MINOR_VERSION);
+ checkVersion("Application", Constants.MAJOR_19, Constants.PREVIEW_MINOR_VERSION);
+ checkVersion("Shape", Constants.MAJOR_19, Constants.PREVIEW_MINOR_VERSION);
+ checkVersion("S", Constants.MAJOR_19, Constants.PREVIEW_MINOR_VERSION);
+ }
+
+ public void testSwitchPatternMatchingCaseLabelDominatedByPrecedingError() {
+ runTest("switch pattern matching error");
+ }
+
+ public void testSwitchPatternMatchingPreview3Error1() {
+ runTest("switch pattern matching preview 3 error 1");
+ }
+
+ public void testSwitchPatternMatchingPreview3Error2() {
+ runTest("switch pattern matching preview 3 error 2");
+ }
+
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(Java19PreviewFeaturesTests.class);
+ }
+
+ @Override
+ protected java.net.URL getSpecFile() {
+ return getClassResource("ajc1919.xml");
+ }
+
+}
diff --git a/tests/src/test/java/org/aspectj/systemtest/ajc1919/SanityTestsJava19.java b/tests/src/test/java/org/aspectj/systemtest/ajc1919/SanityTestsJava19.java
new file mode 100644
index 000000000..fa2abafe5
--- /dev/null
+++ b/tests/src/test/java/org/aspectj/systemtest/ajc1919/SanityTestsJava19.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc1919;
+
+import junit.framework.Test;
+import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.testing.XMLBasedAjcTestCaseForJava19OrLater;
+
+/*
+ * Some very trivial tests that help verify things are OK.
+ * These are a copy of the earlier Sanity Tests created for 1.6 but these supply the -19 option
+ * to check code generation and modification with that version specified.
+ *
+ * @author Alexander Kriegisch
+ */
+public class SanityTestsJava19 extends XMLBasedAjcTestCaseForJava19OrLater {
+
+ public static final int bytecode_version_for_JDK_level = 63;
+
+ // Incredibly trivial test programs that check the compiler works at all (these are easy-ish to debug)
+ public void testSimpleJava_A() {
+ runTest("simple - a");
+ }
+
+ public void testSimpleJava_B() {
+ runTest("simple - b");
+ }
+
+ public void testSimpleCode_C() {
+ runTest("simple - c");
+ }
+
+ public void testSimpleCode_D() {
+ runTest("simple - d");
+ }
+
+ public void testSimpleCode_E() {
+ runTest("simple - e");
+ }
+
+ public void testSimpleCode_F() {
+ runTest("simple - f");
+ }
+
+ public void testSimpleCode_G() {
+ runTest("simple - g");
+ }
+
+ public void testSimpleCode_H() {
+ runTest("simple - h", true);
+ }
+
+ public void testSimpleCode_I() {
+ runTest("simple - i");
+ }
+
+ public void testVersionCorrect1() {
+ runTest("simple - j");
+ checkVersion("A", bytecode_version_for_JDK_level, 0);
+ }
+
+ public void testVersionCorrect2() {
+ runTest("simple - k");
+ checkVersion("A", bytecode_version_for_JDK_level, 0);
+ }
+
+ public void testVersionCorrect4() {
+ runTest("simple - m");
+ // Must be 49.0 when -1.5 is specified
+ checkVersion("A", 49, 0);
+ }
+
+ public static Test suite() {
+ return XMLBasedAjcTestCase.loadSuite(SanityTestsJava19.class);
+ }
+
+ @Override
+ protected java.net.URL getSpecFile() {
+ return getClassResource("sanity-tests-19.xml");
+ }
+
+}
diff --git a/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml
new file mode 100644
index 000000000..9adc98bca
--- /dev/null
+++ b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/ajc1919.xml
@@ -0,0 +1,95 @@
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+
+<!--
+ Java 19: no new final language features, only preview/incubator ones:
+ - "JEP 427: Pattern Matching for switch (Third Preview)" (syntax change, introducing 'when')
+ - "JEP 405: Record Patterns (Preview)"
+ - "JEP 425: Virtual Threads (Preview)" (API only)
+ - "JEP 428: Structured Concurrency (Incubator)" (API only)
+-->
+<suite>
+
+ <!-- Java ?? final, Java 17, 18, 19 preview -->
+ <ajc-test dir="features1919/java19" vm="19" title="switch pattern matching preview 3 java">
+ <compile files="SwitchPatternPreview3OK.java" options="--enable-preview -19" />
+ <run class="SwitchPatternPreview3OK" vmargs="--enable-preview">
+ <message></message>
+ <stdout>
+ <line text="null" />
+ <line text="int 123" />
+ <line text="long 999" />
+ <line text="double 12.340000" />
+ <line text="String foo" />
+ <line text="[123, foo, 999, 12.34]" />
+ <line text="Non-circle" />
+ <line text="Small circle" />
+ <line text="Large circle" />
+ <line text="Sealed sub-class A" />
+ <line text="Sealed sub-class B" />
+ <line text="Sealed sub-record C" />
+ <line text="absolute value 1: -1" />
+ <line text="other integer: 0" />
+ <line text="positive integer: 42" />
+ <line text="other integer: -99" />
+ <line text="positive integer: 123" />
+ <line text="value unavailable: null" />
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <!-- Java ?? final, Java 17, 18, 19 preview -->
+ <ajc-test dir="features1919/java19" vm="19" title="switch pattern matching preview 3 aspect">
+ <compile files="SwitchPatternPreview3Aspect.aj" options="--enable-preview -19" />
+ <run class="Application" vmargs="--enable-preview">
+ <stdout>
+ <line text="null" />
+ <line text="int 123" />
+ <line text="long 999" />
+ <line text="double 12.340000" />
+ <line text="String foo" />
+ <line text="[123, foo, 999, 12.34]" />
+ <line text="Non-circle" />
+ <line text="Small circle" />
+ <line text="Large circle" />
+ <line text="Sealed sub-class A" />
+ <line text="Sealed sub-class B" />
+ <line text="Sealed sub-record C" />
+ <line text="absolute value 1: -1" />
+ <line text="other integer: 0" />
+ <line text="positive integer: 42" />
+ <line text="other integer: -99" />
+ <line text="positive integer: 123" />
+ <line text="value unavailable: null" />
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <!-- Java ?? final, Java 17, 18, 19 preview -->
+ <ajc-test dir="features198/java17" vm="19" title="switch pattern matching error">
+ <compile files="SwitchPatternError.java" options="--enable-preview -19">
+ <!-- TODO: Add correct compiler error message, as soon as JDT Core supports it -->
+ <message kind="error" file="SwitchPatternError.java" text="This case label is dominated by one of the preceding case label"/>
+ </compile>
+ </ajc-test>
+
+ <!-- Java ?? final, Java 17, 18, 19 preview -->
+ <ajc-test dir="features1919/java19" vm="19" title="switch pattern matching preview 3 error 1">
+ <compile files="SwitchPatternPreview3Error1.java" options="--enable-preview -19">
+ <!-- TODO: Add correct compiler error message, as soon as JDT Core supports it -->
+ <message kind="error" file="SwitchPatternPreview3Error1.java" text="This case label is dominated by one of the preceding case label"/>
+ </compile>
+ </ajc-test>
+
+ <!-- Java ?? final, Java 17, 18, 19 preview -->
+ <ajc-test dir="features1919/java19" vm="19" title="switch pattern matching preview 3 error 2">
+ <compile files="SwitchPatternPreview3Error2.java" options="--enable-preview -19">
+ <!-- TODO: Add correct compiler error message, as soon as JDT Core supports it -->
+ <message kind="error" file="SwitchPatternPreview3Error2.java" text="This case label is dominated by one of the preceding case label"/>
+ </compile>
+ </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>
+
+</suite>
diff --git a/tests/src/test/resources/org/aspectj/systemtest/ajc1919/sanity-tests-19.xml b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/sanity-tests-19.xml
new file mode 100644
index 000000000..25df39e53
--- /dev/null
+++ b/tests/src/test/resources/org/aspectj/systemtest/ajc1919/sanity-tests-19.xml
@@ -0,0 +1,70 @@
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+
+<suite>
+
+ <!-- empty class -->
+ <ajc-test dir="bugs160/simplejava" title="simple - a">
+ <compile files="SimpleA.java" options="-19"/>
+ </ajc-test>
+
+ <!-- class with one method -->
+ <ajc-test dir="bugs160/simplejava" title="simple - b">
+ <compile files="SimpleB.java" options="-19"/>
+ <run class="SimpleB"/>
+ </ajc-test>
+
+ <!-- empty aspect -->
+ <ajc-test dir="bugs160/simplejava" title="simple - c">
+ <compile files="SimpleC.java" options="-19"/>
+ </ajc-test>
+
+ <!-- simple before -->
+ <ajc-test dir="bugs160/simplejava" title="simple - d">
+ <compile files="SimpleD.java" options="-19"/>
+ </ajc-test>
+
+ <!-- simple itd field -->
+ <ajc-test dir="bugs160/simplejava" title="simple - e">
+ <compile files="SimpleE.java" options="-19"/>
+ </ajc-test>
+
+ <!-- aspect with main calling a static method -->
+ <ajc-test dir="bugs160/simplejava" title="simple - f">
+ <compile files="SimpleF.java" options="-19"/>
+ </ajc-test>
+
+ <!-- pertarget -->
+ <ajc-test dir="bugs160/simplejava" title="simple - g">
+ <compile files="SimpleG.java" options="-19"/>
+ </ajc-test>
+
+ <!-- generic ctor itds -->
+ <ajc-test dir="bugs160/simplejava" title="simple - h">
+ <compile files="SimpleH.java" options="-19"/>
+ </ajc-test>
+
+ <!-- overriding generic itd methods -->
+ <ajc-test dir="bugs160/simplejava" title="simple - i">
+ <compile files="SimpleI.java" options="-19"/>
+ </ajc-test>
+
+ <!-- check class file version is 63.0 (Java 19) -->
+ <ajc-test dir="bugs160/simplejava" title="simple - j">
+ <compile files="SimpleJ.java" options="-19"/>
+ </ajc-test>
+
+ <!-- check class file version is 63.0 (Java 19) -->
+ <ajc-test dir="bugs160/simplejava" title="simple - k">
+ <compile files="SimpleJ.java" options="-source 19"/>
+ </ajc-test>
+
+ <!-- check class file version is 49.0 -->
+ <ajc-test dir="bugs160/simplejava" title="simple - m">
+ <compile files="SimpleJ.java" options="-1.5"/>
+ </ajc-test>
+
+ <ajc-test dir="bugs160/simplejava" title="simple - n">
+ <compile files="SimpleN.java" options="-19"/>
+ </ajc-test>
+
+</suite>