Adding tests to check Java 11 language features

Bug: 207852002
Test: m
Test: EXPERIMENTAL_TARGET_JAVA_VERSION_11=true m
Test: atest CtsLibcoreTestCases:libcore/luni/src/test/java11language/java/libcore/libcore/internal/Java11LanguageFeaturesTest

Change-Id: If3bab4c5e6eafd40c80fa250f2b94632825c7211
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index e5aa957..4838a11 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -192,6 +192,12 @@
         ":okhttp_impl_files",
     ],
 
+    // Only add Java11LanguageFeatures if EXPERIMENTAL_TARGET_JAVA_VERSION_11
+    // flag is set to true
+    openjdk11: {
+        srcs: ["luni/src/main/java/libcore/internal/Java11LanguageFeatures.java"],
+    },
+
     sdk_version: "none",
     system_modules: "none",
     patch_module: "java.base",
@@ -317,6 +323,12 @@
 
     srcs: [":core_libart_java_files"],
 
+    // Only add Java11LanguageFeatures if EXPERIMENTAL_TARGET_JAVA_VERSION_11
+    // flag is set to true
+    openjdk11: {
+        srcs: ["luni/src/main/java/libcore/internal/Java11LanguageFeatures.java"],
+    },
+
     sdk_version: "none",
     system_modules: "core-all-system-modules",
     patch_module: "java.base",
@@ -565,6 +577,14 @@
     visibility: ["//libcore/luni/src/test/java9language"],
 }
 
+// A filegroup that provides access to a source file for a toolchain test that
+// checks Java 11 language features are handled properly by JarJar.
+filegroup {
+    name: "core-java-11-language-features-source",
+    srcs: ["luni/src/main/java/libcore/internal/Java11LanguageFeatures.java"],
+    visibility: ["//libcore/luni/src/test/java11language"],
+}
+
 genrule {
     name: "core-tests-smali-dex",
     srcs: ["luni/src/test/java/**/*.smali"],
@@ -636,6 +656,7 @@
     static_libs: [
         "core-compat-test-rules",
         "core-java-9-language-tests",
+        "core-java-11-language-tests",
         "core-test-rules",
         "core-tests-support",
         "junit-params",
diff --git a/luni/src/main/java/libcore/internal/Java11LanguageFeatures.java b/luni/src/main/java/libcore/internal/Java11LanguageFeatures.java
new file mode 100644
index 0000000..250d473
--- /dev/null
+++ b/luni/src/main/java/libcore/internal/Java11LanguageFeatures.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.internal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Proof of concept / fake code whose only purpose is to demonstrate that Java 11
+ * language features are supported in libcore.
+ */
+public class Java11LanguageFeatures {
+
+    public static String collectUpperCaseStrings(List<String> list) {
+        // Language feature: local-variable syntax for lambda
+        return list.stream()
+            .map((var item) -> item.toUpperCase())
+            .collect(Collectors.joining(" "));
+    }
+
+    public static String guessTheString(String guess) {
+        // Language feature (Java 10): local-variable type inference
+        var answer = "The answer to the universe, life and everything";
+        if (!(answer instanceof String)) {
+            return null;
+        }
+        if (!guess.equals(answer)) {
+            return "";
+        }
+        return answer;
+    }
+
+    public static class Person {
+        // Language feature: Reflection on private fields/methods of nest-mates
+        // Note: This at the moment is not supported yet in Android and calling these methods will
+        // result in exceptions (b/210843415).
+        private final String name;
+        private final Vocabulary vocabulary = new Vocabulary();
+
+        public Person(String name) {
+            this.name = name;
+        }
+
+        public String greet() throws NoSuchMethodException, InvocationTargetException,
+               NoSuchFieldException, IllegalAccessException {
+            Method greetFn = Vocabulary.class.getDeclaredMethod("greet");
+            return (String) greetFn.invoke(vocabulary);
+        }
+
+        private class Vocabulary {
+
+            private String greet() throws NoSuchFieldException, IllegalAccessException {
+                Field nameField = Person.class.getDeclaredField("name");
+                String nameValue = (String) nameField.get(Person.this);
+                return "Hello " + nameValue;
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java11language/Android.bp b/luni/src/test/java11language/Android.bp
new file mode 100644
index 0000000..44afdbd
--- /dev/null
+++ b/luni/src/test/java11language/Android.bp
@@ -0,0 +1,85 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Android tests related to Java 11 language features.
+
+// Use jarjar to repackage Java11LanguageFeatures, to be used in tests below.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
+java_library {
+    name: "core-java-11-language-features-repackaged-for-test",
+    hostdex: true,
+
+    srcs: [":core-java-11-language-features-source"],
+    jarjar_rules: "jarjar_rules_java11_language_features.txt",
+    java_version: "11",
+
+    sdk_version: "none",
+    system_modules: "core-all-system-modules",
+    patch_module: "java.base",
+
+    visibility: ["//visibility:private"],
+}
+
+// Generate a clone of Java11LanguageFeaturesTest which uses a version of
+// Java11LanguageFeatures repackaged by jarjar. This ensures that jarjar is able
+// to handle a class file which must be at least v55 and includes bytecode
+// compiled from Java 11 language features.
+filegroup {
+    name: "core-rewrite-java-11-test-for-jarjar-sed-script",
+    srcs: ["rewrite-test-for-jarjar.sed"],
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "core-java-11-language-features-test-src",
+    srcs: ["java/libcore/libcore/internal/Java11LanguageFeaturesTest.java"],
+    visibility: ["//visibility:private"],
+}
+
+genrule {
+    name: "core-gen-test-repackaged-java-11-language-features",
+    srcs: [
+        ":core-rewrite-java-11-test-for-jarjar-sed-script",
+        ":core-java-11-language-features-test-src",
+    ],
+    out: ["libcore/libcore/internal/Java11LanguageFeaturesJarjarTest.java"],
+    cmd: "sed -r -f $(location :core-rewrite-java-11-test-for-jarjar-sed-script) $(location :core-java-11-language-features-test-src) > $(out)",
+    visibility: ["//visibility:private"],
+}
+
+java_library {
+    name: "core-java-11-language-tests",
+    hostdex: true,
+    srcs: [
+        ":core-gen-test-repackaged-java-11-language-features",
+    ],
+    openjdk11: {
+        srcs: ["java/**/*.java"],
+    },
+    sdk_version: "none",
+    system_modules: "core-all-system-modules",
+    static_libs: [
+        "core-java-11-language-features-repackaged-for-test",
+        "junit",
+    ],
+    visibility: ["//libcore"],
+    java_version: "11",
+}
diff --git a/luni/src/test/java11language/jarjar_rules_java11_language_features.txt b/luni/src/test/java11language/jarjar_rules_java11_language_features.txt
new file mode 100644
index 0000000..dee72bc
--- /dev/null
+++ b/luni/src/test/java11language/jarjar_rules_java11_language_features.txt
@@ -0,0 +1 @@
+rule libcore.internal.** libcore.internal.repackaged.@1
diff --git a/luni/src/test/java11language/java/libcore/libcore/internal/Java11LanguageFeaturesTest.java b/luni/src/test/java11language/java/libcore/libcore/internal/Java11LanguageFeaturesTest.java
new file mode 100644
index 0000000..055f19b
--- /dev/null
+++ b/luni/src/test/java11language/java/libcore/libcore/internal/Java11LanguageFeaturesTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.libcore.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import libcore.internal.Java11LanguageFeatures;
+
+import org.junit.Test;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class Java11LanguageFeaturesTest {
+
+    @Test
+    public void testVarForLambda() {
+        assertEquals("ONE TWO THREE",
+                Java11LanguageFeatures.collectUpperCaseStrings(
+                        Arrays.asList("one", "two", "three")));
+    }
+
+    @Test
+    public void testLocalVariableTypeInference() {
+        assertEquals("", Java11LanguageFeatures.guessTheString("42"));
+        assertEquals("The answer to the universe, life and everything",
+                Java11LanguageFeatures.guessTheString(
+                        "The answer to the universe, life and everything"));
+    }
+
+    @Test
+    @Ignore("b/210843415")
+    public void testReflectionOnPrivateNestmate() throws Throwable {
+        Java11LanguageFeatures.Person person = new Java11LanguageFeatures.Person("R2D2");
+        assertEquals("Hello R2D2", person.greet());
+    }
+}
diff --git a/luni/src/test/java11language/rewrite-test-for-jarjar.sed b/luni/src/test/java11language/rewrite-test-for-jarjar.sed
new file mode 100644
index 0000000..eb350b1
--- /dev/null
+++ b/luni/src/test/java11language/rewrite-test-for-jarjar.sed
@@ -0,0 +1,21 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is a sed script that modifies Java source code in two ways.
+
+# Replace libcore.internal with libcore.internal.repackaged in imports:
+s/import libcore.internal/import libcore.internal.repackaged/
+
+# Replace Test with JarjarTest in class declarations.
+s/class ([A-Za-z0-9_]+)Test/class \1JarjarTest/