Merge "Enable and demonstrate Java 9 language features in libcore."
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 0f8df96..21645d3 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -127,6 +127,7 @@
java_resource_dirs: core_resource_dirs,
java_resources: [":android_icu4j_resources"],
+ java_version: "1.9",
required: [
"tzdata",
@@ -192,6 +193,7 @@
srcs: [":core_libart_java_files"],
java_resources: [":android_icu4j_resources"],
+ java_version: "1.9",
no_standard_libs: true,
libs: ["core-all"],
@@ -245,6 +247,7 @@
dex_preopt: {
enabled: false,
},
+ java_version: "1.9",
notice: "ojluni/NOTICE",
required: [
"tzdata",
@@ -497,6 +500,7 @@
droidstubs {
name: "core-current-stubs-gen",
srcs: [":core_api_files"],
+ java_version: "1.9",
installable: false,
no_framework_libs: true,
args: " --exclude-annotations",
diff --git a/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
new file mode 100644
index 0000000..7e201d0
--- /dev/null
+++ b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Proof of concept / dummy code whose only purpose is to demonstrate that Java 9
+ * language features are supported in libcore.
+ */
+public class Java9LanguageFeatures {
+
+ public interface Person {
+ String name();
+
+ default boolean isPalindrome() {
+ return name().equals(reverse(name()));
+ }
+
+ default boolean isPalindromeIgnoreCase() {
+ return name().equalsIgnoreCase(reverse(name()));
+ }
+
+ // Language feature: private interface method
+ private String reverse(String s) {
+ return new StringBuilder(s).reverse().toString();
+ }
+ }
+
+ @SafeVarargs
+ public static<T> String toListString(T... values) {
+ return toString(values).toString();
+ }
+
+ // Language feature: @SafeVarargs on private methods
+ @SafeVarargs
+ private static<T> List<String> toString(T... values) {
+ List<String> result = new ArrayList<>();
+ for (T value : values) {
+ result.add(value.toString());
+ }
+ return result;
+ }
+
+ public <T> AtomicReference<T> createReference(T content) {
+ // Language feature: <> on anonymous class
+ return new AtomicReference<>(content) { };
+ }
+
+ public static byte[] copy(byte[] bytes) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ InputStream inputStream = new ByteArrayInputStream(bytes);
+ try (inputStream) { // Language feature: try on effectively-final variable
+ int value;
+ while ((value = inputStream.read()) != -1) {
+ byteArrayOutputStream.write(value);
+ }
+ }
+ return byteArrayOutputStream.toByteArray();
+ }
+
+
+}
diff --git a/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java
new file mode 100644
index 0000000..cc48ec0
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/internal/Java9LanguageFeaturesTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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 java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+import junit.framework.TestCase;
+import libcore.internal.Java9LanguageFeatures;
+
+public class Java9LanguageFeaturesTest extends TestCase {
+
+ public static class SimplePerson implements Java9LanguageFeatures.Person {
+ private final String name;
+ public SimplePerson(String name) { this.name = Objects.requireNonNull(name); }
+ @Override public String toString() { return "Person: " + name; }
+ @Override public String name() { return name; }
+ }
+
+ public void testPrivateInterfaceMethods() {
+ assertFalse(new SimplePerson("Anna").isPalindrome());
+ assertTrue(new SimplePerson("Anna").isPalindromeIgnoreCase());
+ assertTrue(new SimplePerson("anna").isPalindrome());
+ assertTrue(new SimplePerson("bob").isPalindrome());
+ assertFalse(new SimplePerson("larry").isPalindrome());
+ assertFalse(new SimplePerson("larry").isPalindromeIgnoreCase());
+ }
+
+ public void testTryOnEffectivelyFinalVariables() throws IOException {
+ byte[] data = "Hello, world!".getBytes();
+ byte[] dataCopy = Java9LanguageFeatures.copy(data);
+ assertTrue(Arrays.equals(data, dataCopy));
+ assertTrue(data != dataCopy);
+ }
+
+ public void testDiamondOnAnonymousClasses() {
+ AtomicReference<String> ref = new Java9LanguageFeatures().createReference("Hello, world");
+ assertSame("Hello, world", ref.get());
+ }
+
+ public void testSafeVarargsOnPrivateMethod() {
+ assertEquals("[23, and, 42]", Java9LanguageFeatures.toListString(23, "and", 42L));
+ }
+
+}
diff --git a/mmodules/libart_oj/Android.bp b/mmodules/libart_oj/Android.bp
index 950e9b1..e3d7ded 100644
--- a/mmodules/libart_oj/Android.bp
+++ b/mmodules/libart_oj/Android.bp
@@ -38,6 +38,7 @@
no_standard_libs: true,
libs: ["core.intra.stubs"],
system_modules: "core-intra-stubs-system-modules",
+ java_version: "1.9",
openjdk9: {
javacflags: ["--patch-module=java.base=."],
},
diff --git a/mmodules/simple/Android.bp b/mmodules/simple/Android.bp
index 94e8164..ddfed99 100644
--- a/mmodules/simple/Android.bp
+++ b/mmodules/simple/Android.bp
@@ -41,6 +41,7 @@
name: "core-simple",
hostdex: true,
defaults: ["core-simple-defaults"],
+ java_version: "1.9",
}
// A guaranteed unstripped version of core-simple.
@@ -52,6 +53,7 @@
dex_preopt: {
enabled: false,
},
+ java_version: "1.9",
}
// A rule that checks we can build core-simple using only the source for
@@ -93,6 +95,7 @@
no_framework_libs: true,
installable: false,
+ java_version: "1.9",
args: "--show-annotation libcore.mmodule.IntraCoreMModuleApi",
}
@@ -111,4 +114,5 @@
openjdk9: {
javacflags: ["--patch-module=java.base=."],
},
+ java_version: "1.9",
}
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
index 0b5244c..df04980 100644
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -263,6 +263,7 @@
"luni/src/main/java/libcore/icu/NativeConverter.java",
"luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java",
"luni/src/main/java/libcore/icu/TimeZoneNames.java",
+ "luni/src/main/java/libcore/internal/Java9LanguageFeatures.java",
"luni/src/main/java/libcore/internal/StringPool.java",
"luni/src/main/java/libcore/io/AsynchronousCloseMonitor.java",
"luni/src/main/java/libcore/io/ClassPathURLStreamHandler.java",