From 4e5430011fc9283074339b39754b0f07ff5d8a04 Mon Sep 17 00:00:00 2001
From: Alexander Kriegisch <Alexander@Kriegisch.name>
Date: Wed, 17 Mar 2021 23:38:08 +0700
Subject: Add Java 15 / AspectJ 1.9.7 test suite

Also fix some minor details in Java 14 suite

Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
---
 tests/features197/java15/Employee.java        |  1 +
 tests/features197/java15/HiddenClass.java     |  6 +++++
 tests/features197/java15/HiddenClassDemo.java | 39 +++++++++++++++++++++++++++
 tests/features197/java15/Manager.java         |  1 +
 tests/features197/java15/Person.java          |  5 ++++
 tests/features197/java15/PersonAspect.aj      | 17 ++++++++++++
 tests/features197/java15/PersonaNonGrata.java |  2 ++
 tests/features197/java15/TopManager.java      | 10 +++++++
 8 files changed, 81 insertions(+)
 create mode 100644 tests/features197/java15/Employee.java
 create mode 100644 tests/features197/java15/HiddenClass.java
 create mode 100644 tests/features197/java15/HiddenClassDemo.java
 create mode 100644 tests/features197/java15/Manager.java
 create mode 100644 tests/features197/java15/Person.java
 create mode 100644 tests/features197/java15/PersonAspect.aj
 create mode 100644 tests/features197/java15/PersonaNonGrata.java
 create mode 100644 tests/features197/java15/TopManager.java

(limited to 'tests/features197')

diff --git a/tests/features197/java15/Employee.java b/tests/features197/java15/Employee.java
new file mode 100644
index 000000000..9b0b9da99
--- /dev/null
+++ b/tests/features197/java15/Employee.java
@@ -0,0 +1 @@
+public final class Employee extends Person {}
diff --git a/tests/features197/java15/HiddenClass.java b/tests/features197/java15/HiddenClass.java
new file mode 100644
index 000000000..f1ef61166
--- /dev/null
+++ b/tests/features197/java15/HiddenClass.java
@@ -0,0 +1,6 @@
+public class HiddenClass implements Test {
+  @Override
+  public void concat(String... words) {
+    System.out.println(String.join(" ", words));
+  }
+}
diff --git a/tests/features197/java15/HiddenClassDemo.java b/tests/features197/java15/HiddenClassDemo.java
new file mode 100644
index 000000000..0b7f0ab17
--- /dev/null
+++ b/tests/features197/java15/HiddenClassDemo.java
@@ -0,0 +1,39 @@
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
+
+import java.io.FileInputStream;
+
+import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
+
+public class HiddenClassDemo {
+  public static void main(String[] args) throws Throwable {
+    // Step 1: Create lookup object
+    MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+    // Step 2: Fetch or create the class bytes we want to define
+    byte[] bytes = Thread.currentThread().getContextClassLoader()
+      .getResourceAsStream("HiddenClass.class")
+      .readAllBytes();
+
+    // Step 3: Define hidden class
+    Class<?> clazz = lookup.defineHiddenClass(bytes, true, NESTMATE).lookupClass();
+    // Hidden classes have class names like my.package.MyClass/0x2a23f5, but no canonical name (null)
+    System.out.println("Hidden class name = " + clazz.getName());
+    System.out.println("Hidden class canonical name = " + clazz.getCanonicalName ());
+    // Hidden classes cannot be resolved by any class loader (ClassNotFoundException)
+    try {
+      Class.forName(clazz.getName());
+    }
+    catch (ClassNotFoundException e) {
+      System.out.println("Class.forName resolution error = " + e);
+    }
+
+    //Step 4: Create instance of hidden class object and call interface method
+    Test test = (Test) clazz.getConstructor(null).newInstance(null);
+    test.concat("Hello", "from", "dynamically", "defined", "hidden", "class");
+  }
+}
+
+interface Test {
+  void concat(String... words);
+}
diff --git a/tests/features197/java15/Manager.java b/tests/features197/java15/Manager.java
new file mode 100644
index 000000000..09b897d1e
--- /dev/null
+++ b/tests/features197/java15/Manager.java
@@ -0,0 +1 @@
+public non-sealed class Manager extends Person {}
diff --git a/tests/features197/java15/Person.java b/tests/features197/java15/Person.java
new file mode 100644
index 000000000..cdd87d7f3
--- /dev/null
+++ b/tests/features197/java15/Person.java
@@ -0,0 +1,5 @@
+public abstract sealed class Person permits Employee, Manager {
+  public void sayHello(String name) {
+    System.out.println("Hello " + name);
+  }
+}
diff --git a/tests/features197/java15/PersonAspect.aj b/tests/features197/java15/PersonAspect.aj
new file mode 100644
index 000000000..695a4de36
--- /dev/null
+++ b/tests/features197/java15/PersonAspect.aj
@@ -0,0 +1,17 @@
+public aspect PersonAspect {
+  // Weave into sealed class
+  void around(String name): execution(void sayHello(*)) && args(name) {
+    proceed("Sir " + name);
+  }
+
+  // ITD into non-sealed subclass of sealed class
+  private String Manager.jobTitle;
+
+  public void TopManager.setJobTitle(String jobTitle) {
+    this.jobTitle = jobTitle;
+  }
+
+  public String TopManager.getJobTitle() {
+    return jobTitle;
+  }
+}
diff --git a/tests/features197/java15/PersonaNonGrata.java b/tests/features197/java15/PersonaNonGrata.java
new file mode 100644
index 000000000..fc801536d
--- /dev/null
+++ b/tests/features197/java15/PersonaNonGrata.java
@@ -0,0 +1,2 @@
+// This should not compile because Person is sealed and does not allow PersonaNonGrata as a subclass
+public final class PersonaNonGrata extends Person {}
diff --git a/tests/features197/java15/TopManager.java b/tests/features197/java15/TopManager.java
new file mode 100644
index 000000000..e1dfdc367
--- /dev/null
+++ b/tests/features197/java15/TopManager.java
@@ -0,0 +1,10 @@
+public class TopManager extends Manager {
+  public static void main(String[] args) {
+    TopManager topManager = new TopManager();
+    topManager.sayHello("John");
+
+    // Call ITD methods
+    topManager.setJobTitle("CEO");
+    System.out.println(topManager.getJobTitle());
+  }
+}
-- 
cgit v1.2.3