Reland "Use local FileSystem through conversions on high API devices"
This reverts commit 688b2c24f7630758c232801c9cff51d2f78886a6.
Change-Id: Ic07720fd208164a213872a0b40b2a2098326fa84
diff --git a/src/library_desugar/java/j$/nio/file/FileSystem.java b/src/library_desugar/java/j$/nio/file/FileSystem.java
new file mode 100644
index 0000000..a7a49a2
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/FileSystem.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+import j$.nio.file.spi.FileSystemProvider;
+
+public class FileSystem {
+ public FileSystemProvider provider() {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/FileSystems.java b/src/library_desugar/java/j$/nio/file/FileSystems.java
new file mode 100644
index 0000000..d7214ca
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/FileSystems.java
@@ -0,0 +1,11 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class FileSystems {
+ public static FileSystem getDefault() {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/Files.java b/src/library_desugar/java/j$/nio/file/Files.java
index 2825d24..f34593b 100644
--- a/src/library_desugar/java/j$/nio/file/Files.java
+++ b/src/library_desugar/java/j$/nio/file/Files.java
@@ -5,10 +5,9 @@
package j$.nio.file;
import java.io.IOException;
-import java.nio.file.Path;
public class Files {
- public static String probeContentType(Path path) throws IOException {
+ public static String probeContentType(j$.nio.file.Path path) throws IOException {
return null;
}
}
diff --git a/src/library_desugar/java/j$/nio/file/LinkOption.java b/src/library_desugar/java/j$/nio/file/LinkOption.java
new file mode 100644
index 0000000..b8cf168
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/LinkOption.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class LinkOption extends OpenOption {
+ public static java.nio.file.LinkOption wrap_convert(j$.nio.file.LinkOption option) {
+ return null;
+ }
+
+ public static j$.nio.file.LinkOption wrap_convert(java.nio.file.LinkOption option) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/OpenOption.java b/src/library_desugar/java/j$/nio/file/OpenOption.java
new file mode 100644
index 0000000..8b063d1
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/OpenOption.java
@@ -0,0 +1,7 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class OpenOption {}
diff --git a/src/library_desugar/java/j$/nio/file/Path.java b/src/library_desugar/java/j$/nio/file/Path.java
new file mode 100644
index 0000000..781ab5f
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/Path.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class Path {
+
+ public static j$.nio.file.Path wrap_convert(java.nio.file.Path path) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/StandardOpenOption.java b/src/library_desugar/java/j$/nio/file/StandardOpenOption.java
new file mode 100644
index 0000000..a65da37
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/StandardOpenOption.java
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class StandardOpenOption extends OpenOption {
+
+ public static java.nio.file.StandardOpenOption wrap_convert(
+ j$.nio.file.StandardOpenOption option) {
+ return null;
+ }
+
+ public static j$.nio.file.StandardOpenOption wrap_convert(
+ java.nio.file.StandardOpenOption option) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/WatchEvent.java b/src/library_desugar/java/j$/nio/file/WatchEvent.java
new file mode 100644
index 0000000..fd977e9
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/WatchEvent.java
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file;
+
+public class WatchEvent<T> {
+
+ public static java.nio.file.WatchEvent<?> wrap_convert(j$.nio.file.WatchEvent<?> option) {
+ return null;
+ }
+
+ public static j$.nio.file.WatchEvent<?> wrap_convert(java.nio.file.WatchEvent<?> option) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributeView.java b/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributeView.java
new file mode 100644
index 0000000..774cf2c
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributeView.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class BasicFileAttributeView extends FileAttributeView {
+ public static java.nio.file.attribute.BasicFileAttributeView wrap_convert(
+ j$.nio.file.attribute.BasicFileAttributeView fileAttributeView) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.BasicFileAttributeView wrap_convert(
+ java.nio.file.attribute.BasicFileAttributeView fileAttributeView) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributes.java b/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributes.java
new file mode 100644
index 0000000..dd91a95
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/BasicFileAttributes.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class BasicFileAttributes {
+ public static java.nio.file.attribute.BasicFileAttributes wrap_convert(
+ j$.nio.file.attribute.BasicFileAttributes fileAttributes) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.BasicFileAttributes wrap_convert(
+ java.nio.file.attribute.BasicFileAttributes fileAttributes) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/FileAttributeView.java b/src/library_desugar/java/j$/nio/file/attribute/FileAttributeView.java
new file mode 100644
index 0000000..34046eb3
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/FileAttributeView.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class FileAttributeView {
+ public static java.nio.file.attribute.FileAttributeView wrap_convert(
+ j$.nio.file.attribute.FileAttributeView fileAttributeView) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.FileAttributeView wrap_convert(
+ java.nio.file.attribute.FileAttributeView fileAttributeView) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/FileOwnerAttributeView.java b/src/library_desugar/java/j$/nio/file/attribute/FileOwnerAttributeView.java
new file mode 100644
index 0000000..34a637d
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/FileOwnerAttributeView.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class FileOwnerAttributeView extends FileAttributeView {
+ public static java.nio.file.attribute.FileOwnerAttributeView wrap_convert(
+ j$.nio.file.attribute.FileOwnerAttributeView fileAttributeView) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.FileOwnerAttributeView wrap_convert(
+ java.nio.file.attribute.FileOwnerAttributeView fileAttributeView) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributeView.java b/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributeView.java
new file mode 100644
index 0000000..bb24cb7
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributeView.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class PosixFileAttributeView extends FileAttributeView {
+ public static java.nio.file.attribute.PosixFileAttributeView wrap_convert(
+ j$.nio.file.attribute.PosixFileAttributeView fileAttributeView) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.PosixFileAttributeView wrap_convert(
+ java.nio.file.attribute.PosixFileAttributeView fileAttributeView) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributes.java b/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributes.java
new file mode 100644
index 0000000..5e61814
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/PosixFileAttributes.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class PosixFileAttributes extends BasicFileAttributes {
+ public static java.nio.file.attribute.PosixFileAttributes wrap_convert(
+ j$.nio.file.attribute.PosixFileAttributes fileAttributes) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.PosixFileAttributes wrap_convert(
+ java.nio.file.attribute.PosixFileAttributes fileAttributes) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/attribute/PosixFilePermission.java b/src/library_desugar/java/j$/nio/file/attribute/PosixFilePermission.java
new file mode 100644
index 0000000..94dbcbf
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/attribute/PosixFilePermission.java
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.attribute;
+
+public class PosixFilePermission {
+ public static java.nio.file.attribute.PosixFilePermission wrap_convert(
+ j$.nio.file.attribute.PosixFilePermission permission) {
+ return null;
+ }
+
+ public static j$.nio.file.attribute.PosixFilePermission wrap_convert(
+ java.nio.file.attribute.PosixFilePermission permission) {
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java b/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java
new file mode 100644
index 0000000..38152b3
--- /dev/null
+++ b/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package j$.nio.file.spi;
+
+public class FileSystemProvider {
+ public static java.nio.file.spi.FileSystemProvider wrap_convert(FileSystemProvider provider) {
+ // Rewritten in ASM to the wrapper method.
+ return null;
+ }
+}
diff --git a/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java b/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java
index 658c351..d02344d 100644
--- a/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java
+++ b/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java
@@ -4,13 +4,12 @@
package java.adapter;
-import android.os.Build.VERSION;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import desugar.sun.nio.fs.DesugarDefaultFileSystemProvider;
+import j$.nio.file.FileSystems;
import java.net.URI;
import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
import java.nio.file.spi.FileSystemProvider;
/**
@@ -23,20 +22,26 @@
INSTANCE.getFileSystem(URI.create("file:///"));
private static FileSystemProvider getFileSystemProvider() {
- if (VERSION.SDK_INT >= 26) {
- return FileSystems.getDefault().provider();
- } else {
- try {
- // In headless, android.os is absent so the following line will throw.
- // We cannot set the ThreadPolicy in headless and it is irrelevant.
- // If we are not in headless, the class will be found and we can set the thread policy.
- Class.forName("android.os.Build");
- setThreadPolicy();
- } catch (ClassNotFoundException ignored) {
- // Headless mode.
- }
- return DesugarDefaultFileSystemProvider.instance();
+ try {
+ // On API 26 and above, FileSystems is present.
+ Class.forName("java.nio.file.FileSystems");
+ j$.nio.file.FileSystem fileSystem = FileSystems.getDefault();
+ j$.nio.file.spi.FileSystemProvider provider = fileSystem.provider();
+ return j$.nio.file.spi.FileSystemProvider.wrap_convert(provider);
+ } catch (ClassNotFoundException ignored) {
+ // We reach this path is API < 26.
}
+ // The DesugarDefaultFileSystemProvider requires the ThreadPolicy to be set to work correctly.
+ // We cannot set the ThreadPolicy in headless and it should not matter.
+ // In headless, android.os is absent so the following line will throw.
+ // In headfull, android.os is present and we set the thread policy.
+ try {
+ Class.forName("android.os.Build");
+ setThreadPolicy();
+ } catch (ClassNotFoundException ignored) {
+ // Headless mode.
+ }
+ return DesugarDefaultFileSystemProvider.instance();
}
private static void setThreadPolicy() {
diff --git a/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java b/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
index 1caf2f1..da93736 100644
--- a/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
+++ b/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
@@ -4,7 +4,6 @@
package java.adapter;
-import android.os.Build.VERSION;
import desugar.sun.nio.fs.DesugarDefaultFileTypeDetector;
import java.io.IOException;
import java.nio.file.Path;
@@ -18,18 +17,19 @@
private HybridFileTypeDetector() {}
public static FileTypeDetector create() {
- if (VERSION.SDK_INT >= 26) {
+ try {
+ // On API 26 and above, java.nio.file.Files is present.
+ Class.forName("java.nio.file.Files");
return new PlatformFileTypeDetector();
- } else {
+ } catch (ClassNotFoundException ignored) {
return DesugarDefaultFileTypeDetector.create();
}
}
- static class PlatformFileTypeDetector extends java.nio.file.spi.FileTypeDetector {
+ static class PlatformFileTypeDetector extends FileTypeDetector {
@Override
public String probeContentType(Path path) throws IOException {
- // Relies at runtime on java.nio.file.Files.
- return j$.nio.file.Files.probeContentType(path);
+ return j$.nio.file.Files.probeContentType(j$.nio.file.Path.wrap_convert(path));
}
}
}
diff --git a/src/library_desugar/java/java/nio/file/FileApiFlips.java b/src/library_desugar/java/java/nio/file/FileApiFlips.java
new file mode 100644
index 0000000..fae6648
--- /dev/null
+++ b/src/library_desugar/java/java/nio/file/FileApiFlips.java
@@ -0,0 +1,170 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package java.nio.file;
+
+import static java.util.ConversionRuntimeException.exception;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class FileApiFlips {
+
+ public static Class<?> flipFileAttributes(Class<?> attributesClass) {
+ if (attributesClass == null) {
+ return null;
+ }
+ if (attributesClass == j$.nio.file.attribute.BasicFileAttributes.class) {
+ return java.nio.file.attribute.BasicFileAttributes.class;
+ }
+ if (attributesClass == j$.nio.file.attribute.PosixFileAttributes.class) {
+ return java.nio.file.attribute.PosixFileAttributes.class;
+ }
+ if (attributesClass == java.nio.file.attribute.BasicFileAttributes.class) {
+ return j$.nio.file.attribute.BasicFileAttributes.class;
+ }
+ if (attributesClass == java.nio.file.attribute.PosixFileAttributes.class) {
+ return j$.nio.file.attribute.PosixFileAttributes.class;
+ }
+ throw exception("java.nio.file.attribute.BasicFileAttributes", attributesClass);
+ }
+
+ public static Class<?> flipFileAttributeView(Class<?> attributeView) {
+ if (attributeView == null) {
+ return null;
+ }
+ if (attributeView == j$.nio.file.attribute.BasicFileAttributeView.class) {
+ return java.nio.file.attribute.BasicFileAttributeView.class;
+ }
+ if (attributeView == j$.nio.file.attribute.PosixFileAttributeView.class) {
+ return java.nio.file.attribute.PosixFileAttributeView.class;
+ }
+ if (attributeView == j$.nio.file.attribute.FileOwnerAttributeView.class) {
+ return java.nio.file.attribute.FileOwnerAttributeView.class;
+ }
+ if (attributeView == java.nio.file.attribute.BasicFileAttributeView.class) {
+ return j$.nio.file.attribute.BasicFileAttributeView.class;
+ }
+ if (attributeView == java.nio.file.attribute.PosixFileAttributeView.class) {
+ return j$.nio.file.attribute.PosixFileAttributeView.class;
+ }
+ if (attributeView == java.nio.file.attribute.FileOwnerAttributeView.class) {
+ return j$.nio.file.attribute.FileOwnerAttributeView.class;
+ }
+ throw exception("java.nio.file.attribute.FileAttributeView", attributeView);
+ }
+
+ public static RuntimeException exceptionOpenOption(Object suffix) {
+ throw exception("java.nio.file.OpenOption", suffix);
+ }
+
+ public static Set<?> flipOpenOptionSet(Set<?> openOptionSet) {
+ if (openOptionSet == null || openOptionSet.isEmpty()) {
+ return openOptionSet;
+ }
+ HashSet<Object> convertedSet = new HashSet<>();
+ Object guineaPig = openOptionSet.iterator().next();
+ if (guineaPig instanceof java.nio.file.OpenOption) {
+ for (Object item : openOptionSet) {
+ java.nio.file.OpenOption option;
+ try {
+ option = (java.nio.file.OpenOption) item;
+ } catch (ClassCastException cce) {
+ throw exceptionOpenOption(cce);
+ }
+ convertedSet.add(OpenOptionConversions.convert(option));
+ }
+ return convertedSet;
+ }
+ if (guineaPig instanceof j$.nio.file.OpenOption) {
+ for (Object item : openOptionSet) {
+ j$.nio.file.OpenOption option;
+ try {
+ option = (j$.nio.file.OpenOption) item;
+ } catch (ClassCastException cce) {
+ throw exceptionOpenOption(cce);
+ }
+ convertedSet.add(OpenOptionConversions.convert(option));
+ }
+ return convertedSet;
+ }
+ throw exceptionOpenOption(guineaPig.getClass());
+ }
+
+ public static RuntimeException exceptionPosixPermission(Object suffix) {
+ throw exception("java.nio.file.attribute.PosixFilePermission", suffix);
+ }
+
+ public static Set<?> flipPosixPermissionSet(Set<?> posixPermissions) {
+ if (posixPermissions == null || posixPermissions.isEmpty()) {
+ return posixPermissions;
+ }
+ HashSet<Object> convertedSet = new HashSet<>();
+ Object guineaPig = posixPermissions.iterator().next();
+ if (guineaPig instanceof java.nio.file.attribute.PosixFilePermission) {
+ for (Object item : posixPermissions) {
+ java.nio.file.attribute.PosixFilePermission permission;
+ try {
+ permission = (java.nio.file.attribute.PosixFilePermission) item;
+ } catch (ClassCastException cce) {
+ throw exceptionPosixPermission(cce);
+ }
+ convertedSet.add(j$.nio.file.attribute.PosixFilePermission.wrap_convert(permission));
+ }
+ return convertedSet;
+ }
+ if (guineaPig instanceof j$.nio.file.attribute.PosixFilePermission) {
+ for (Object item : posixPermissions) {
+ j$.nio.file.attribute.PosixFilePermission permission;
+ try {
+ permission = (j$.nio.file.attribute.PosixFilePermission) item;
+ } catch (ClassCastException cce) {
+ throw exceptionPosixPermission(cce);
+ }
+ convertedSet.add(j$.nio.file.attribute.PosixFilePermission.wrap_convert(permission));
+ }
+ return convertedSet;
+ }
+ throw exceptionPosixPermission(guineaPig.getClass());
+ }
+
+ public static RuntimeException exceptionWatchEvent(Object suffix) {
+ throw exception("java.nio.file.WatchEvent", suffix);
+ }
+
+ public static List<?> flipWatchEventList(List<?> watchEventList) {
+ if (watchEventList == null || watchEventList.isEmpty()) {
+ return watchEventList;
+ }
+ List<Object> convertedList = new ArrayList<>();
+ Object guineaPig = watchEventList.get(0);
+ if (guineaPig instanceof java.nio.file.WatchEvent) {
+ for (Object item : watchEventList) {
+ java.nio.file.WatchEvent<?> watchEvent;
+ try {
+ watchEvent = (java.nio.file.WatchEvent<?>) item;
+ } catch (ClassCastException cce) {
+ throw exceptionWatchEvent(cce);
+ }
+ convertedList.add(j$.nio.file.WatchEvent.wrap_convert(watchEvent));
+ }
+ return convertedList;
+ }
+ if (guineaPig instanceof j$.nio.file.WatchEvent) {
+ for (Object item : watchEventList) {
+ j$.nio.file.WatchEvent<?> watchEvent;
+ try {
+ watchEvent = (j$.nio.file.WatchEvent<?>) item;
+ } catch (ClassCastException cce) {
+ throw exceptionWatchEvent(cce);
+ }
+ convertedList.add(j$.nio.file.WatchEvent.wrap_convert(watchEvent));
+ }
+ return convertedList;
+ }
+ throw exceptionWatchEvent(guineaPig.getClass());
+ }
+}
diff --git a/src/library_desugar/java/java/nio/file/OpenOptionConversions.java b/src/library_desugar/java/java/nio/file/OpenOptionConversions.java
new file mode 100644
index 0000000..bfe4968
--- /dev/null
+++ b/src/library_desugar/java/java/nio/file/OpenOptionConversions.java
@@ -0,0 +1,35 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package java.nio.file;
+
+import static java.util.ConversionRuntimeException.exception;
+
+public class OpenOptionConversions {
+ public static java.nio.file.OpenOption convert(j$.nio.file.OpenOption option) {
+ if (option == null) {
+ return null;
+ }
+ if (option instanceof j$.nio.file.StandardOpenOption) {
+ return j$.nio.file.StandardOpenOption.wrap_convert((j$.nio.file.StandardOpenOption) option);
+ }
+ if (option instanceof j$.nio.file.LinkOption) {
+ return j$.nio.file.LinkOption.wrap_convert((j$.nio.file.LinkOption) option);
+ }
+ throw exception("java.nio.file.OpenOption", option);
+ }
+
+ public static j$.nio.file.OpenOption convert(java.nio.file.OpenOption option) {
+ if (option == null) {
+ return null;
+ }
+ if (option instanceof java.nio.file.StandardOpenOption) {
+ return j$.nio.file.StandardOpenOption.wrap_convert((java.nio.file.StandardOpenOption) option);
+ }
+ if (option instanceof java.nio.file.LinkOption) {
+ return j$.nio.file.LinkOption.wrap_convert((java.nio.file.LinkOption) option);
+ }
+ throw exception("java.nio.file.OpenOption", option);
+ }
+}
diff --git a/src/library_desugar/java/java/nio/file/attribute/FileAttributeConversions.java b/src/library_desugar/java/java/nio/file/attribute/FileAttributeConversions.java
index f4c4beb..332c89b 100644
--- a/src/library_desugar/java/java/nio/file/attribute/FileAttributeConversions.java
+++ b/src/library_desugar/java/java/nio/file/attribute/FileAttributeConversions.java
@@ -4,7 +4,10 @@
package java.nio.file.attribute;
+import static java.util.ConversionRuntimeException.exception;
+
public class FileAttributeConversions {
+
public static java.nio.file.attribute.FileTime convert(j$.nio.file.attribute.FileTime fileTime) {
if (fileTime == null) {
return null;
@@ -18,4 +21,68 @@
}
return j$.nio.file.attribute.FileTime.fromMillis(fileTime.toMillis());
}
+
+ public static java.nio.file.attribute.FileAttributeView convert(
+ j$.nio.file.attribute.FileAttributeView fileAttributeView) {
+ if (fileAttributeView == null) {
+ return null;
+ }
+ if (fileAttributeView instanceof j$.nio.file.attribute.PosixFileAttributeView) {
+ return j$.nio.file.attribute.PosixFileAttributeView.wrap_convert(
+ (j$.nio.file.attribute.PosixFileAttributeView) fileAttributeView);
+ }
+ if (fileAttributeView instanceof j$.nio.file.attribute.FileOwnerAttributeView) {
+ return j$.nio.file.attribute.FileOwnerAttributeView.wrap_convert(
+ (j$.nio.file.attribute.FileOwnerAttributeView) fileAttributeView);
+ }
+ if (fileAttributeView instanceof j$.nio.file.attribute.BasicFileAttributeView) {
+ return j$.nio.file.attribute.BasicFileAttributeView.wrap_convert(
+ (j$.nio.file.attribute.BasicFileAttributeView) fileAttributeView);
+ }
+ throw exception("java.nio.file.attribute.FileAttributeView", fileAttributeView);
+ }
+
+ public static j$.nio.file.attribute.FileAttributeView convert(
+ java.nio.file.attribute.FileAttributeView fileAttributeView) {
+ if (fileAttributeView == null) {
+ return null;
+ }
+ if (fileAttributeView instanceof java.nio.file.attribute.PosixFileAttributeView) {
+ return j$.nio.file.attribute.PosixFileAttributeView.wrap_convert(
+ (java.nio.file.attribute.PosixFileAttributeView) fileAttributeView);
+ }
+ if (fileAttributeView instanceof java.nio.file.attribute.FileOwnerAttributeView) {
+ return j$.nio.file.attribute.FileOwnerAttributeView.wrap_convert(
+ (java.nio.file.attribute.FileOwnerAttributeView) fileAttributeView);
+ }
+ if (fileAttributeView instanceof java.nio.file.attribute.BasicFileAttributeView) {
+ return j$.nio.file.attribute.BasicFileAttributeView.wrap_convert(
+ (java.nio.file.attribute.BasicFileAttributeView) fileAttributeView);
+ }
+ throw exception("java.nio.file.attribute.FileAttributeView", fileAttributeView);
+ }
+
+ public static java.nio.file.attribute.BasicFileAttributes convert(
+ j$.nio.file.attribute.BasicFileAttributes fileAttributes) {
+ if (fileAttributes == null) {
+ return null;
+ }
+ if (fileAttributes instanceof j$.nio.file.attribute.PosixFileAttributes) {
+ return j$.nio.file.attribute.PosixFileAttributes.wrap_convert(
+ (j$.nio.file.attribute.PosixFileAttributes) fileAttributes);
+ }
+ return j$.nio.file.attribute.BasicFileAttributes.wrap_convert(fileAttributes);
+ }
+
+ public static j$.nio.file.attribute.BasicFileAttributes convert(
+ java.nio.file.attribute.BasicFileAttributes fileAttributes) {
+ if (fileAttributes == null) {
+ return null;
+ }
+ if (fileAttributes instanceof java.nio.file.attribute.PosixFileAttributes) {
+ return j$.nio.file.attribute.PosixFileAttributes.wrap_convert(
+ (java.nio.file.attribute.PosixFileAttributes) fileAttributes);
+ }
+ return j$.nio.file.attribute.BasicFileAttributes.wrap_convert(fileAttributes);
+ }
}
diff --git a/src/library_desugar/java/java/util/ConversionRuntimeException.java b/src/library_desugar/java/java/util/ConversionRuntimeException.java
new file mode 100644
index 0000000..896be1e
--- /dev/null
+++ b/src/library_desugar/java/java/util/ConversionRuntimeException.java
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package java.util;
+
+public class ConversionRuntimeException extends RuntimeException {
+
+ public ConversionRuntimeException(String message) {
+ super(message);
+ }
+
+ public static RuntimeException exception(String type, Object suffix) {
+ throw new ConversionRuntimeException("Unsupported " + type + " :" + suffix);
+ }
+}
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_path.json b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
index 4f0ec65..038efba 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
@@ -105,11 +105,15 @@
"retarget_method_with_emulated_dispatch": {
"java.nio.file.Path java.io.File#toPath()": "java.io.DesugarFile"
},
- "api_conversion_collection": {
- "java.nio.channels.AsynchronousFileChannel java.nio.file.spi.FileSystemProvider#newAsynchronousFileChannel(java.nio.file.Path, java.util.Set, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute[])" : [1, "OpenOption"],
- "java.nio.channels.SeekableByteChannel java.nio.file.spi.FileSystemProvider#newByteChannel(java.nio.file.Path, java.util.Set, java.nio.file.attribute.FileAttribute[])" : [1, "OpenOption"],
- "java.nio.channels.FileChannel java.nio.file.spi.FileSystemProvider#newFileChannel(java.nio.file.Path, java.util.Set, java.nio.file.attribute.FileAttribute[])" : [1, "OpenOption"],
- "java.util.List java.nio.file.WatchKey#pollEvents()": [-1, "java.nio.file.WatchEvent"]
+ "api_generic_types_conversion": {
+ "java.nio.channels.AsynchronousFileChannel java.nio.file.spi.FileSystemProvider#newAsynchronousFileChannel(java.nio.file.Path, java.util.Set, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute[])" : [1, "java.util.Set java.nio.file.FileApiFlips#flipOpenOptionSet(java.util.Set)"],
+ "java.nio.channels.SeekableByteChannel java.nio.file.spi.FileSystemProvider#newByteChannel(java.nio.file.Path, java.util.Set, java.nio.file.attribute.FileAttribute[])" : [1, "java.util.Set java.nio.file.FileApiFlips#flipOpenOptionSet(java.util.Set)"],
+ "java.nio.channels.FileChannel java.nio.file.spi.FileSystemProvider#newFileChannel(java.nio.file.Path, java.util.Set, java.nio.file.attribute.FileAttribute[])" : [1, "java.util.Set java.nio.file.FileApiFlips#flipOpenOptionSet(java.util.Set)"],
+ "java.util.List java.nio.file.WatchKey#pollEvents()": [-1, "java.util.List java.nio.file.FileApiFlips#flipWatchEventList(java.util.List)"],
+ "java.nio.file.attribute.FileAttributeView java.nio.file.spi.FileSystemProvider#getFileAttributeView(java.nio.file.Path, java.lang.Class, java.nio.file.LinkOption[])": [1, "java.lang.Class java.nio.file.FileApiFlips#flipFileAttributeView(java.lang.Class)"],
+ "java.nio.file.attribute.BasicFileAttributes java.nio.file.spi.FileSystemProvider#readAttributes(java.nio.file.Path, java.lang.Class, java.nio.file.LinkOption[])": [1, "java.lang.Class java.nio.file.FileApiFlips#flipFileAttributes(java.lang.Class)"],
+ "java.util.Set java.nio.file.attribute.PosixFileAttributes#permissions()": [-1, "java.util.Set java.nio.file.FileApiFlips#flipPosixPermissionSet(java.util.Set)"],
+ "void java.nio.file.attribute.PosixFileAttributeView#setPermissions(java.util.Set)": [0, "java.util.Set java.nio.file.FileApiFlips#flipPosixPermissionSet(java.util.Set)"]
},
"wrapper_conversion": [
"java.nio.channels.AsynchronousChannel",
@@ -117,6 +121,7 @@
"java.nio.file.Path",
"java.nio.file.FileSystem",
"java.nio.file.WatchService",
+ "java.nio.file.WatchEvent",
"java.nio.file.WatchEvent$Kind",
"java.nio.file.WatchKey",
"java.nio.file.Watchable",
@@ -124,19 +129,24 @@
"java.nio.file.WatchEvent$Modifier",
"java.nio.file.attribute.UserPrincipalLookupService",
"java.nio.file.spi.FileSystemProvider",
+ "java.nio.file.spi.FileTypeDetector",
"java.nio.file.AccessMode",
+ "java.nio.file.StandardOpenOption",
"java.nio.file.LinkOption",
"java.nio.file.CopyOption",
"java.nio.file.attribute.GroupPrincipal",
"java.nio.file.attribute.FileAttribute",
- "java.nio.file.attribute.FileAttributeView",
"java.nio.file.attribute.UserPrincipal",
"java.nio.file.FileStore",
"java.nio.file.attribute.FileStoreAttributeView",
"java.nio.file.DirectoryStream$Filter",
"java.nio.file.DirectoryStream",
- "java.nio.file.OpenOption",
- "java.nio.file.attribute.BasicFileAttributes"
+ "java.nio.file.attribute.PosixFilePermission",
+ "java.nio.file.attribute.BasicFileAttributes",
+ "java.nio.file.attribute.PosixFileAttributes",
+ "java.nio.file.attribute.FileOwnerAttributeView",
+ "java.nio.file.attribute.PosixFileAttributeView",
+ "java.nio.file.attribute.BasicFileAttributeView"
],
"wrapper_conversion_excluding": {
"java.nio.channels.AsynchronousFileChannel": [
@@ -146,7 +156,10 @@
]
},
"custom_conversion": {
- "java.nio.file.attribute.FileTime": "java.nio.file.attribute.FileAttributeConversions"
+ "java.nio.file.OpenOption": "java.nio.file.OpenOptionConversions",
+ "java.nio.file.attribute.FileTime": "java.nio.file.attribute.FileAttributeConversions",
+ "java.nio.file.attribute.BasicFileAttributes": "java.nio.file.attribute.FileAttributeConversions",
+ "java.nio.file.attribute.FileAttributeView": "java.nio.file.attribute.FileAttributeConversions"
}
},
{
@@ -395,14 +408,33 @@
"sun.nio.fs.BasicFileAttributesHolder": "j$.sun.nio.fs.BasicFileAttributesHolder",
"sun.nio.fs.DynamicFileAttributeView": "j$.sun.nio.fs.DynamicFileAttributeView",
"sun.util.PreHashedMap": "j$.sun.util.PreHashedMap",
- "java.adapter" : "j$.adapter"
+ "java.adapter" : "j$.adapter",
+ "java.util.ConversionRuntimeException": "j$.util.ConversionRuntimeException"
},
"rewrite_derived_prefix": {
- "java.nio.file.attribute.FileTime": {
- "j$.nio.file.attribute.FileTime": "java.nio.file.attribute.FileTime"
+ "java.nio.file.attribute.": {
+ "j$.nio.file.attribute.": "java.nio.file.attribute."
+ },
+ "java.nio.file.OpenOption": {
+ "j$.nio.file.OpenOption": "java.nio.file.OpenOption"
+ },
+ "java.nio.file.StandardOpenOption": {
+ "j$.nio.file.StandardOpenOption": "java.nio.file.StandardOpenOption"
+ },
+ "java.nio.file.LinkOption": {
+ "j$.nio.file.LinkOption": "java.nio.file.LinkOption"
},
"java.nio.file.Files": {
"j$.nio.file.Files": "java.nio.file.Files"
+ },
+ "java.nio.file.FileSystem": {
+ "j$.nio.file.FileSystem": "java.nio.file.FileSystem"
+ },
+ "java.nio.file.spi.FileSystemProvider": {
+ "j$.nio.file.spi.FileSystemProvider": "java.nio.file.spi.FileSystemProvider"
+ },
+ "java.nio.file.Path": {
+ "j$.nio.file.Path": "java.nio.file.Path"
}
},
"retarget_method": {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
index 29ecfd2..0e6bd6a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryConversionCfProvider.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion;
import static com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter.methodWithVivifiedTypeInSignature;
+import static com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter.vivifiedTypeFor;
import com.android.tools.r8.cf.code.CfArrayLoad;
import com.android.tools.r8.cf.code.CfArrayStore;
@@ -156,9 +157,12 @@
computeReturnConversion(method, false, eventConsumer, context, contextSupplier);
DexMethod[] parameterConversions =
computeParameterConversions(method, true, eventConsumer, context, contextSupplier);
+ DexType newHolder =
+ appView.typeRewriter.hasRewrittenType(method.getHolderType(), appView)
+ ? vivifiedTypeFor(method.getHolderType(), appView)
+ : method.getHolderType();
DexMethod forwardMethod =
- convertedMethod(
- method, true, returnConversion, parameterConversions, wrapperField.getType());
+ convertedMethod(method, true, returnConversion, parameterConversions, newHolder);
CfCode cfCode =
new APIConversionCfCodeProvider(
appView,
@@ -467,12 +471,13 @@
private DexMethod internalComputeReturnConversion(
DexMethod invokedMethod,
- BiFunction<DexType, DexType, DexMethod> methodSupplier,
+ BiFunction<DexType, DexMethod, DexMethod> methodSupplier,
ProgramMethod context) {
DexType returnType = invokedMethod.proto.returnType;
- if (wrapperSynthesizer.shouldConvert(returnType, invokedMethod, context)) {
- DexType apiConversionCollection = getReturnApiConversionCollection(invokedMethod);
- return methodSupplier.apply(returnType, apiConversionCollection);
+ DexMethod apiGenericTypesConversion = getReturnApiGenericConversion(invokedMethod);
+ if (wrapperSynthesizer.shouldConvert(
+ returnType, apiGenericTypesConversion, invokedMethod, context)) {
+ return methodSupplier.apply(returnType, apiGenericTypesConversion);
}
return null;
}
@@ -486,9 +491,9 @@
return internalComputeParameterConversions(
invokedMethod,
wrapperSynthesizer,
- (argType, apiConversionCollection) ->
+ (argType, apiGenericTypesConversion) ->
wrapperSynthesizer.ensureConversionMethod(
- argType, destIsVivified, apiConversionCollection, eventConsumer, contextSupplier),
+ argType, destIsVivified, apiGenericTypesConversion, eventConsumer, contextSupplier),
context);
}
@@ -501,41 +506,42 @@
return internalComputeParameterConversions(
invokedMethod,
wrapperSynthesizer,
- (argType, apiConversionCollection) ->
+ (argType, apiGenericTypesConversion) ->
wrapperSynthesizer.getExistingProgramConversionMethod(
- argType, destIsVivified, apiConversionCollection, eventConsumer, contextSupplier),
+ argType, destIsVivified, apiGenericTypesConversion, eventConsumer, contextSupplier),
context);
}
private DexMethod[] internalComputeParameterConversions(
DexMethod invokedMethod,
DesugaredLibraryWrapperSynthesizer wrapperSynthesizor,
- BiFunction<DexType, DexType, DexMethod> methodSupplier,
+ BiFunction<DexType, DexMethod, DexMethod> methodSupplier,
ProgramMethod context) {
DexMethod[] parameterConversions = new DexMethod[invokedMethod.getArity()];
DexType[] parameters = invokedMethod.proto.parameters.values;
for (int i = 0; i < parameters.length; i++) {
- DexType apiConversionCollection = getApiConversionCollection(invokedMethod, i);
+ DexMethod apiGenericTypesConversion = getApiGenericConversion(invokedMethod, i);
DexType argType = parameters[i];
- if (wrapperSynthesizor.shouldConvert(argType, invokedMethod, context)) {
- parameterConversions[i] = methodSupplier.apply(argType, apiConversionCollection);
+ if (wrapperSynthesizor.shouldConvert(
+ argType, apiGenericTypesConversion, invokedMethod, context)) {
+ parameterConversions[i] = methodSupplier.apply(argType, apiGenericTypesConversion);
}
}
return parameterConversions;
}
- public DexType getReturnApiConversionCollection(DexMethod method) {
- return getApiConversionCollection(method, method.getArity());
+ public DexMethod getReturnApiGenericConversion(DexMethod method) {
+ return getApiGenericConversion(method, method.getArity());
}
- public DexType getApiConversionCollection(DexMethod method, int parameterIndex) {
- DexType[] dexTypes =
+ public DexMethod getApiGenericConversion(DexMethod method, int parameterIndex) {
+ DexMethod[] conversions =
appView
.options()
.machineDesugaredLibrarySpecification
- .getApiConversionCollection()
+ .getApiGenericConversion()
.get(method);
- return dexTypes == null ? null : dexTypes[parameterIndex];
+ return conversions == null ? null : conversions[parameterIndex];
}
private DexMethod convertedMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
index a930b12..d28ccaf 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
@@ -33,7 +33,6 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
import com.android.tools.r8.ir.synthetic.apiconverter.NullableConversionCfCodeProvider;
import com.android.tools.r8.ir.synthetic.apiconverter.NullableConversionCfCodeProvider.ArrayConversionCfCodeProvider;
-import com.android.tools.r8.ir.synthetic.apiconverter.NullableConversionCfCodeProvider.CollectionConversionCfCodeProvider;
import com.android.tools.r8.ir.synthetic.apiconverter.WrapperConstructorCfCodeProvider;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.MethodPosition;
@@ -118,13 +117,15 @@
|| appView.getSyntheticItems().isSyntheticOfKind(type, kinds -> kinds.VIVIFIED_WRAPPER);
}
- public boolean shouldConvert(DexType type, DexMethod method) {
- return shouldConvert(type, method, null);
- }
-
- public boolean shouldConvert(DexType type, DexMethod method, ProgramMethod context) {
+ public boolean shouldConvert(
+ DexType type, DexMethod apiGenericTypesConversion, DexMethod method, ProgramMethod context) {
if (type.isArrayType()) {
- return shouldConvert(type.toBaseType(appView.dexItemFactory()), method, context);
+ assert apiGenericTypesConversion == null;
+ return shouldConvert(
+ type.toBaseType(appView.dexItemFactory()), apiGenericTypesConversion, method, context);
+ }
+ if (apiGenericTypesConversion != null) {
+ return true;
}
if (!appView.typeRewriter.hasRewrittenType(type, appView)) {
return false;
@@ -139,13 +140,12 @@
public DexMethod ensureConversionMethod(
DexType type,
boolean destIsVivified,
- DexType apiConversionCollection,
+ DexMethod apiGenericTypesConversion,
DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer,
Supplier<UniqueContext> contextSupplier) {
- if (apiConversionCollection != null) {
+ if (apiGenericTypesConversion != null) {
assert !type.isArrayType();
- return ensureCollectionConversionMethod(
- type, destIsVivified, apiConversionCollection, eventConsumer, contextSupplier);
+ return apiGenericTypesConversion;
}
DexType srcType = destIsVivified ? type : vivifiedTypeFor(type);
DexType destType = destIsVivified ? vivifiedTypeFor(type) : type;
@@ -171,68 +171,6 @@
return conversion;
}
- private DexMethod ensureCollectionConversionMethod(
- DexType type,
- boolean destIsVivified,
- DexType apiConversionCollection,
- DesugaredLibraryClasspathWrapperSynthesizeEventConsumer eventConsumer,
- Supplier<UniqueContext> contextSupplier) {
- assert type == factory.setType || type == factory.listType;
- DexMethod conversion =
- ensureConversionMethod(
- apiConversionCollection,
- destIsVivified,
- null, // We do not support nested collections.
- eventConsumer,
- contextSupplier);
- return ensureCollectionConversionMethod(type, eventConsumer, contextSupplier, conversion);
- }
-
- private DexMethod ensureCollectionConversionMethodFromExistingBaseConversion(
- DexType type,
- boolean destIsVivified,
- DexType apiConversionCollection,
- DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer,
- Supplier<UniqueContext> contextSupplier) {
- assert type == factory.setType || type == factory.listType;
- DexMethod conversion =
- getExistingProgramConversionMethod(
- apiConversionCollection,
- destIsVivified,
- null, // We do not support nested collections.
- eventConsumer,
- contextSupplier);
- return ensureCollectionConversionMethod(type, eventConsumer, contextSupplier, conversion);
- }
-
- private DexMethod ensureCollectionConversionMethod(
- DexType collectionType,
- DesugaredLibraryWrapperSynthesizerEventConsumer eventConsumer,
- Supplier<UniqueContext> contextSupplier,
- DexMethod conversion) {
- ProgramMethod collectionConversion =
- appView
- .getSyntheticItems()
- .createMethod(
- kinds -> kinds.COLLECTION_CONVERSION,
- contextSupplier.get(),
- appView,
- builder ->
- builder
- .setProto(factory.createProto(collectionType, collectionType))
- .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
- .setCode(
- codeSynthesizor ->
- new CollectionConversionCfCodeProvider(
- appView,
- codeSynthesizor.getHolderType(),
- collectionType,
- conversion)
- .generateCfCode()));
- eventConsumer.acceptCollectionConversion(collectionConversion);
- return collectionConversion.getReference();
- }
-
private DexMethod ensureArrayConversionMethod(
DexType type,
DexType srcType,
@@ -300,13 +238,12 @@
public DexMethod getExistingProgramConversionMethod(
DexType type,
boolean destIsVivified,
- DexType apiConversionCollection,
+ DexMethod apiGenericTypesConversion,
DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer,
Supplier<UniqueContext> contextSupplier) {
- if (apiConversionCollection != null) {
+ if (apiGenericTypesConversion != null) {
assert !type.isArrayType();
- return ensureCollectionConversionMethodFromExistingBaseConversion(
- type, destIsVivified, apiConversionCollection, eventConsumer, contextSupplier);
+ return apiGenericTypesConversion;
}
DexType srcType = destIsVivified ? type : vivifiedTypeFor(type);
DexType destType = destIsVivified ? vivifiedTypeFor(type) : type;
@@ -699,7 +636,6 @@
.getWrappers()
.forEach(
(type, methods) -> {
- assert !librarySpecification.getCustomConversions().containsKey(type);
DexClass validClassToWrap = getValidClassToWrap(type);
// In broken set-ups we can end up having a json files containing wrappers of non
// desugared classes. Such wrappers are not required since the class won't be
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
index 189dca8..1aa5f62 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecificationParser.java
@@ -48,7 +48,7 @@
static final String API_LEVEL_BELOW_OR_EQUAL_KEY = "api_level_below_or_equal";
static final String API_LEVEL_GREATER_OR_EQUAL_KEY = "api_level_greater_or_equal";
- static final String API_CONVERSION_COLLECTION = "api_conversion_collection";
+ static final String API_GENERIC_TYPES_CONVERSION = "api_generic_types_conversion";
static final String WRAPPER_CONVERSION_KEY = "wrapper_conversion";
static final String WRAPPER_CONVERSION_EXCLUDING_KEY = "wrapper_conversion_excluding";
static final String CUSTOM_CONVERSION_KEY = "custom_conversion";
@@ -264,15 +264,15 @@
builder.putDontRewritePrefix(dontRewritePrefix.getAsString());
}
}
- if (jsonFlagSet.has(API_CONVERSION_COLLECTION)) {
+ if (jsonFlagSet.has(API_GENERIC_TYPES_CONVERSION)) {
for (Map.Entry<String, JsonElement> methodAndDescription :
- jsonFlagSet.get(API_CONVERSION_COLLECTION).getAsJsonObject().entrySet()) {
+ jsonFlagSet.get(API_GENERIC_TYPES_CONVERSION).getAsJsonObject().entrySet()) {
JsonArray array = methodAndDescription.getValue().getAsJsonArray();
for (int i = 0; i < array.size(); i += 2) {
- builder.addApiConversionCollection(
+ builder.addApiGenericTypesConversion(
parseMethod(methodAndDescription.getKey()),
array.get(i).getAsInt(),
- stringDescriptorToDexType(array.get(i + 1).getAsString()));
+ parseMethod(array.get(i + 1).getAsString()));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
index 94ae8d0..f17235f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanRewritingFlags.java
@@ -15,13 +15,11 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
public class HumanRewritingFlags {
@@ -34,7 +32,7 @@
private final Map<DexMethod, DexType> covariantRetarget;
private final Map<DexMethod, DexType> retargetMethod;
private final Map<DexMethod, DexType> retargetMethodEmulatedDispatch;
- private final Map<DexMethod, DexType[]> apiConversionCollection;
+ private final Map<DexMethod, DexMethod[]> apiGenericTypesConversion;
private final Map<DexType, DexType> legacyBackport;
private final Map<DexType, DexType> customConversions;
private final Set<DexMethod> dontRewriteInvocation;
@@ -53,7 +51,7 @@
Map<DexMethod, DexType> covariantRetarget,
Map<DexMethod, DexType> retargetMethod,
Map<DexMethod, DexType> retargetMethodEmulatedDispatch,
- Map<DexMethod, DexType[]> apiConversionCollection,
+ Map<DexMethod, DexMethod[]> apiGenericTypesConversion,
Map<DexType, DexType> legacyBackport,
Map<DexType, DexType> customConversion,
Set<DexMethod> dontRewriteInvocation,
@@ -70,7 +68,7 @@
this.covariantRetarget = covariantRetarget;
this.retargetMethod = retargetMethod;
this.retargetMethodEmulatedDispatch = retargetMethodEmulatedDispatch;
- this.apiConversionCollection = apiConversionCollection;
+ this.apiGenericTypesConversion = apiGenericTypesConversion;
this.legacyBackport = legacyBackport;
this.customConversions = customConversion;
this.dontRewriteInvocation = dontRewriteInvocation;
@@ -118,7 +116,7 @@
covariantRetarget,
retargetMethod,
retargetMethodEmulatedDispatch,
- apiConversionCollection,
+ apiGenericTypesConversion,
legacyBackport,
customConversions,
dontRewriteInvocation,
@@ -164,8 +162,8 @@
return retargetMethodEmulatedDispatch;
}
- public Map<DexMethod, DexType[]> getApiConversionCollection() {
- return apiConversionCollection;
+ public Map<DexMethod, DexMethod[]> getApiGenericConversion() {
+ return apiGenericTypesConversion;
}
public Map<DexType, DexType> getLegacyBackport() {
@@ -221,7 +219,7 @@
private final Map<DexMethod, DexType> covariantRetarget;
private final Map<DexMethod, DexType> retargetMethod;
private final Map<DexMethod, DexType> retargetMethodEmulatedDispatch;
- private final Map<DexMethod, DexType[]> apiConversionCollection;
+ private final Map<DexMethod, DexMethod[]> apiGenericTypesConversion;
private final Map<DexType, DexType> legacyBackport;
private final Map<DexType, DexType> customConversions;
private final Set<DexMethod> dontRewriteInvocation;
@@ -265,7 +263,7 @@
Map<DexMethod, DexType> covariantRetarget,
Map<DexMethod, DexType> retargetMethod,
Map<DexMethod, DexType> retargetMethodEmulatedDispatch,
- Map<DexMethod, DexType[]> apiConversionCollection,
+ Map<DexMethod, DexMethod[]> apiConversionCollection,
Map<DexType, DexType> backportCoreLibraryMember,
Map<DexType, DexType> customConversions,
Set<DexMethod> dontRewriteInvocation,
@@ -284,7 +282,7 @@
this.covariantRetarget = new IdentityHashMap<>(covariantRetarget);
this.retargetMethod = new IdentityHashMap<>(retargetMethod);
this.retargetMethodEmulatedDispatch = new IdentityHashMap<>(retargetMethodEmulatedDispatch);
- this.apiConversionCollection = new IdentityHashMap<>(apiConversionCollection);
+ this.apiGenericTypesConversion = new IdentityHashMap<>(apiConversionCollection);
this.legacyBackport = new IdentityHashMap<>(backportCoreLibraryMember);
this.customConversions = new IdentityHashMap<>(customConversions);
this.dontRewriteInvocation = Sets.newIdentityHashSet();
@@ -406,12 +404,13 @@
return this;
}
- public void addApiConversionCollection(DexMethod method, int index, DexType type) {
- DexType[] types =
- apiConversionCollection.computeIfAbsent(method, k -> new DexType[method.getArity() + 1]);
+ public void addApiGenericTypesConversion(DexMethod method, int index, DexMethod conversion) {
+ DexMethod[] types =
+ apiGenericTypesConversion.computeIfAbsent(
+ method, k -> new DexMethod[method.getArity() + 1]);
int actualIndex = index == -1 ? method.getArity() : index;
assert types[actualIndex] == null;
- types[actualIndex] = type;
+ types[actualIndex] = conversion;
}
public Builder putLegacyBackport(DexType backportType, DexType rewrittenBackportType) {
@@ -444,7 +443,6 @@
}
public HumanRewritingFlags build() {
- validate();
return new HumanRewritingFlags(
ImmutableMap.copyOf(rewritePrefix),
ImmutableSet.copyOf(dontRewritePrefix),
@@ -455,7 +453,7 @@
ImmutableMap.copyOf(covariantRetarget),
ImmutableMap.copyOf(retargetMethod),
ImmutableMap.copyOf(retargetMethodEmulatedDispatch),
- ImmutableMap.copyOf(apiConversionCollection),
+ ImmutableMap.copyOf(apiGenericTypesConversion),
ImmutableMap.copyOf(legacyBackport),
ImmutableMap.copyOf(customConversions),
ImmutableSet.copyOf(dontRewriteInvocation),
@@ -464,19 +462,5 @@
ImmutableMap.copyOf(amendLibraryMethod),
ImmutableMap.copyOf(amendLibraryField));
}
-
- private void validate() {
- SetView<DexType> dups =
- Sets.intersection(customConversions.keySet(), wrapperConversions.keySet());
- if (!dups.isEmpty()) {
- throw reporter.fatalError(
- new StringDiagnostic(
- "Invalid desugared library configuration. "
- + "Duplicate types in custom conversions and wrapper conversions: "
- + String.join(
- ", ", dups.stream().map(DexType::toString).collect(Collectors.toSet())),
- origin));
- }
- }
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
index 4e08dc9..16b0b9f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
@@ -120,8 +120,8 @@
return rewritingFlags.getEmulatedVirtualRetargetThroughEmulatedInterface();
}
- public Map<DexMethod, DexType[]> getApiConversionCollection() {
- return rewritingFlags.getApiConversionCollection();
+ public Map<DexMethod, DexMethod[]> getApiGenericConversion() {
+ return rewritingFlags.getApiGenericConversion();
}
public void forEachRetargetMethod(Consumer<DexMethod> consumer) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
index cafb6c8..e125c53 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
@@ -37,7 +37,7 @@
Map<DexMethod, DexMethod> nonEmulatedVirtualRetarget,
Map<DexMethod, EmulatedDispatchMethodDescriptor> emulatedVirtualRetarget,
Map<DexMethod, DexMethod> emulatedVirtualRetargetThroughEmulatedInterface,
- Map<DexMethod, DexType[]> apiConversionCollection,
+ Map<DexMethod, DexMethod[]> apiGenericTypesConversion,
Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces,
Map<DexType, List<DexMethod>> wrappers,
Map<DexType, DexType> legacyBackport,
@@ -55,7 +55,7 @@
this.emulatedVirtualRetarget = emulatedVirtualRetarget;
this.emulatedVirtualRetargetThroughEmulatedInterface =
emulatedVirtualRetargetThroughEmulatedInterface;
- this.apiConversionCollection = apiConversionCollection;
+ this.apiGenericTypesConversion = apiGenericTypesConversion;
this.emulatedInterfaces = emulatedInterfaces;
this.wrappers = wrappers;
this.legacyBackport = legacyBackport;
@@ -96,7 +96,7 @@
private final Map<DexMethod, DexMethod> emulatedVirtualRetargetThroughEmulatedInterface;
// Encodes weither specific parameter collections need to be wrapped differently.
- private final Map<DexMethod, DexType[]> apiConversionCollection;
+ private final Map<DexMethod, DexMethod[]> apiGenericTypesConversion;
// Emulated interface descriptors.
private final Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces;
@@ -146,8 +146,8 @@
return emulatedVirtualRetargetThroughEmulatedInterface;
}
- public Map<DexMethod, DexType[]> getApiConversionCollection() {
- return apiConversionCollection;
+ public Map<DexMethod, DexMethod[]> getApiGenericConversion() {
+ return apiGenericTypesConversion;
}
public void forEachRetargetMethod(Consumer<DexMethod> consumer) {
@@ -245,7 +245,7 @@
emulatedVirtualRetarget = ImmutableMap.builder();
private final ImmutableMap.Builder<DexMethod, DexMethod>
emulatedVirtualRetargetThroughEmulatedInterface = ImmutableMap.builder();
- private final ImmutableMap.Builder<DexMethod, DexType[]> apiConversionCollection =
+ private final ImmutableMap.Builder<DexMethod, DexMethod[]> apiGenericTypesConversion =
ImmutableMap.builder();
private final ImmutableMap.Builder<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces =
ImmutableMap.builder();
@@ -304,8 +304,8 @@
emulatedVirtualRetargetThroughEmulatedInterface.put(src, dest);
}
- public void addApiConversionCollection(DexMethod method, DexType[] dexTypes) {
- apiConversionCollection.put(method, dexTypes);
+ public void addApiGenericTypesConversion(DexMethod method, DexMethod[] conversions) {
+ apiGenericTypesConversion.put(method, conversions);
}
public void addWrapper(DexType wrapperConversion, List<DexMethod> methods) {
@@ -365,7 +365,7 @@
nonEmulatedVirtualRetarget.build(),
emulatedVirtualRetarget.build(),
emulatedVirtualRetargetThroughEmulatedInterface.build(),
- apiConversionCollection.build(),
+ apiGenericTypesConversion.build(),
emulatedInterfaces.build(),
wrappers.build(),
legacyBackport.build(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
index dea440e..1097b06 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
@@ -97,7 +97,7 @@
ComputedApiLevel.unknown());
rewritingFlags.getAmendLibraryMethod().forEach(builder::amendLibraryMethod);
rewritingFlags.getAmendLibraryField().forEach(builder::amendLibraryField);
- rewritingFlags.getApiConversionCollection().forEach(builder::addApiConversionCollection);
+ rewritingFlags.getApiGenericConversion().forEach(builder::addApiGenericTypesConversion);
new HumanToMachineRetargetConverter(appInfo)
.convertRetargetFlags(rewritingFlags, builder, this::warnMissingReferences);
new HumanToMachineEmulatedInterfaceConverter(appInfo)
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/NullableConversionCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/NullableConversionCfCodeProvider.java
index 10e267b..fb04da0 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/NullableConversionCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/apiconverter/NullableConversionCfCodeProvider.java
@@ -244,117 +244,4 @@
return standardCfCodeFromInstructions(instructions);
}
}
-
- public static class CollectionConversionCfCodeProvider extends NullableConversionCfCodeProvider {
-
- private final DexType collectionType;
- private final DexMethod conversion;
-
- public CollectionConversionCfCodeProvider(
- AppView<?> appView, DexType holder, DexType collectionType, DexMethod conversion) {
- super(appView, holder);
- this.collectionType = collectionType;
- this.conversion = conversion;
- }
-
- @Override
- public CfCode generateCfCode() {
- DexItemFactory factory = appView.dexItemFactory();
- List<CfInstruction> instructions = new ArrayList<>();
-
- // if (arg == null) { return null; }
- generateNullCheck(instructions);
- instructions.add(
- CfFrame.builder().appendLocal(FrameType.initialized(collectionType)).build());
-
- CfFrame frame =
- CfFrame.builder()
- .appendLocal(FrameType.initialized(collectionType))
- .appendLocal(FrameType.initialized(collectionType))
- .appendLocal(FrameType.initialized(factory.iteratorType))
- .build();
-
- // Collection<E> t1 = new Collection<E>();
- if (collectionType == factory.setType) {
- DexType hashSetType = factory.createType("Ljava/util/HashSet;");
- instructions.add(new CfNew(hashSetType));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKESPECIAL,
- factory.createMethod(
- hashSetType,
- factory.createProto(factory.voidType),
- factory.constructorMethodName),
- false));
- } else {
- assert collectionType == factory.listType;
- DexType arrayListType = factory.createType("Ljava/util/ArrayList;");
- instructions.add(new CfNew(arrayListType));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKESPECIAL,
- factory.createMethod(
- arrayListType,
- factory.createProto(factory.voidType),
- factory.constructorMethodName),
- false));
- }
- instructions.add(new CfStore(ValueType.OBJECT, 1));
-
- // Iterator<E> t2 = receiver.iterator();
- instructions.add(new CfLoad(ValueType.OBJECT, 0));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKEINTERFACE,
- factory.createMethod(
- factory.collectionType, factory.createProto(factory.iteratorType), "iterator"),
- true));
- instructions.add(new CfStore(ValueType.OBJECT, 2));
-
- // while(t2.hasNext())
- CfLabel returnLabel = new CfLabel();
- CfLabel loopLabel = new CfLabel();
- instructions.add(loopLabel);
- instructions.add(frame);
- instructions.add(new CfLoad(ValueType.fromDexType(factory.iteratorType), 2));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKEINTERFACE,
- factory.createMethod(
- factory.iteratorType, factory.createProto(factory.booleanType), "hasNext"),
- true));
- instructions.add(new CfConstNumber(0, ValueType.INT));
- instructions.add(new CfIfCmp(If.Type.EQ, ValueType.INT, returnLabel));
-
- // {t1.add(convert(t2.next());}
- instructions.add(new CfLoad(ValueType.fromDexType(collectionType), 1));
- instructions.add(new CfLoad(ValueType.fromDexType(factory.iteratorType), 2));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKEINTERFACE,
- factory.createMethod(
- factory.iteratorType,
- factory.createProto(conversion.getArgumentType(0, true)),
- "next"),
- true));
- instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, conversion, false));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKEINTERFACE,
- factory.createMethod(
- factory.collectionType,
- factory.createProto(factory.booleanType, factory.objectType),
- "add"),
- true));
- instructions.add(new CfGoto(loopLabel));
-
- // return t1;
- instructions.add(returnLabel);
- instructions.add(frame.clone());
- instructions.add(new CfLoad(ValueType.fromDexType(collectionType), 1));
- instructions.add(new CfReturn(ValueType.fromDexType(collectionType)));
-
- return standardCfCodeFromInstructions(instructions);
- }
- }
}
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index c9f0ee8..3186dc1 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -89,6 +89,11 @@
return this;
}
+ public L8TestBuilder addKeepRules(String keepRule) throws IOException {
+ this.keepRules.add(keepRule);
+ return this;
+ }
+
public L8TestBuilder addKeepRuleFile(Path keepRuleFile) throws IOException {
this.keepRules.add(FileUtils.readTextFile(keepRuleFile, StandardCharsets.UTF_8));
return this;
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index b22d6d3..810ea37 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.ToolHelper.DexVm.Kind;
import com.android.tools.r8.benchmarks.BenchmarkResults;
+import com.android.tools.r8.desugar.desugaredlibrary.jdk11.ConversionConverter;
import com.android.tools.r8.desugar.desugaredlibrary.jdk11.DesugaredLibraryJDK11Undesugarer;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.errors.Unreachable;
@@ -187,10 +188,13 @@
public static final Path DESUGARED_JDK_11_LIB_JAR =
Paths.get(OPEN_JDK_DIR + "desugar_jdk_libs_11/desugar_jdk_libs.jar");
+ public static Path getConvertedDesugaredLibConversions() {
+ return ConversionConverter.convertJar(DESUGAR_LIB_CONVERSIONS);
+ }
+
public static Path getUndesugaredJdk11LibJarForTesting() {
return DesugaredLibraryJDK11Undesugarer.undesugaredJarJDK11(
- Paths.get("build/libs"),
- Paths.get(OPEN_JDK_DIR + "desugar_jdk_libs_11/desugar_jdk_libs.jar"));
+ Paths.get("build/libs"), DESUGARED_JDK_11_LIB_JAR);
}
public static boolean isLocalDevelopment() {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
index 2a185ea..d303418 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/EmulatedInterfacesTest.java
@@ -15,6 +15,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.dex.code.DexInstruction;
@@ -59,6 +60,7 @@
@Test
public void testEmulatedInterface() throws Exception {
+ new CodeInspector(ToolHelper.getConvertedDesugaredLibConversions());
Assume.assumeTrue(libraryDesugaringSpecification.hasEmulatedInterfaceDesugaring(parameters));
CodeInspector inspector =
testForL8(parameters.getApiLevel())
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
index 566b0a0..e58134c 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/ProgramRewritingTest.java
@@ -52,7 +52,7 @@
"JDK8_CL",
ImmutableSet.of(
DESUGARED_JDK_8_LIB_JAR,
- ToolHelper.DESUGAR_LIB_CONVERSIONS,
+ ToolHelper.getConvertedDesugaredLibConversions(),
ToolHelper.getCoreLambdaStubs()),
JDK8.getSpecification(),
ImmutableSet.of(ToolHelper.getAndroidJar(AndroidApiLevel.O)),
@@ -63,7 +63,7 @@
"JDK11_CL",
ImmutableSet.of(
ToolHelper.getUndesugaredJdk11LibJarForTesting(),
- ToolHelper.DESUGAR_LIB_CONVERSIONS,
+ ToolHelper.getConvertedDesugaredLibConversions(),
ToolHelper.getCoreLambdaStubs()),
JDK11.getSpecification(),
ImmutableSet.of(ToolHelper.getAndroidJar(AndroidApiLevel.R)),
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
index da9064b..3afc61c 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
@@ -6,13 +6,19 @@
import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FieldSubject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -64,11 +70,23 @@
.addKeepMainRule(Executor.class)
.noMinification()
.compile()
+ .inspectL8(this::assertVersionUID)
.withArt6Plus64BitsLib()
.run(parameters.getRuntime(), Executor.class)
.assertSuccessWithOutput(EXPECTED_RESULT);
}
+ private void assertVersionUID(CodeInspector inspector) {
+ ClassSubject mapClass = inspector.clazz("j$.util.concurrent.ConcurrentHashMap");
+ if (parameters.getApiLevel().isLessThan(AndroidApiLevel.N)) {
+ assertTrue(mapClass.isPresent());
+ FieldSubject serialVersionUID = mapClass.uniqueFieldWithName("serialVersionUID");
+ assertTrue(serialVersionUID.isPresent());
+ } else {
+ assertFalse(mapClass.isPresent());
+ }
+ }
+
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
static class Executor {
public static void main(String[] args) throws Exception {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ChannelSetTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ChannelSetTest.java
index 193507a..91549ff 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ChannelSetTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ChannelSetTest.java
@@ -45,7 +45,15 @@
private final LibraryDesugaringSpecification libraryDesugaringSpecification;
private final CompilationSpecification compilationSpecification;
- private static final String EXPECTED_RESULT =
+ private static final String EXPECTED_RESULT_DESUGARING =
+ StringUtils.lines(
+ "bytes written: 11",
+ "String written: Hello World",
+ "bytes read: 11",
+ "String read: Hello World",
+ "bytes read: 11",
+ "unsupported");
+ private static final String EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM =
StringUtils.lines(
"bytes written: 11",
"String written: Hello World",
@@ -53,8 +61,9 @@
"String read: Hello World",
"bytes read: 11",
"String read: Hello World",
- "unsupported");
- private static final String EXPECTED_RESULT_26 =
+ "bytes read: 11",
+ "String read: Hello World");
+ private static final String EXPECTED_RESULT_NO_DESUGARING =
StringUtils.lines(
"bytes written: 11",
"String written: Hello World",
@@ -97,7 +106,7 @@
}
@Test
- public void test() throws Exception {
+ public void test() throws Throwable {
testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
.addProgramClasses(TestClass.class)
.setCustomLibrarySpecification(
@@ -113,9 +122,12 @@
}
private String getExpectedResult() {
- return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.O)
- ? EXPECTED_RESULT_26
- : EXPECTED_RESULT;
+ if (!libraryDesugaringSpecification.hasNioFileDesugaring(parameters)) {
+ return EXPECTED_RESULT_NO_DESUGARING;
+ }
+ return libraryDesugaringSpecification.usesPlatformFileSystem(parameters)
+ ? EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM
+ : EXPECTED_RESULT_DESUGARING;
}
public static class CustomLib {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java
new file mode 100644
index 0000000..5ccb580
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/ConversionConverter.java
@@ -0,0 +1,161 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.desugar.desugaredlibrary.jdk11;
+
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.transformers.ClassFileTransformer;
+import com.android.tools.r8.transformers.MethodTransformer;
+import com.android.tools.r8.utils.StreamUtils;
+import com.android.tools.r8.utils.ZipUtils;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import org.objectweb.asm.Opcodes;
+
+public class ConversionConverter {
+
+ private static final Map<String, String> JAVA_WRAP_CONVERT_OWNER = new HashMap<>();
+ private static final Map<String, String> J$_WRAP_CONVERT_OWNER = new HashMap<>();
+
+ static {
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/spi/FileSystemProvider",
+ "java/nio/file/spi/FileSystemProvider$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/spi/FileTypeDetector", "java/nio/file/spi/FileTypeDetector$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/StandardOpenOption", "java/nio/file/StandardOpenOption$EnumConversion");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/LinkOption", "java/nio/file/LinkOption$EnumConversion");
+ JAVA_WRAP_CONVERT_OWNER.put("j$/nio/file/Path", "java/nio/file/Path$Wrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/WatchEvent", "java/nio/file/WatchEvent$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/BasicFileAttributes",
+ "java/nio/file/attribute/BasicFileAttributes$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/BasicFileAttributeView",
+ "java/nio/file/attribute/BasicFileAttributeView$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/FileOwnerAttributeView",
+ "java/nio/file/attribute/FileOwnerAttributeView$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFileAttributes",
+ "java/nio/file/attribute/PosixFileAttributes$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFileAttributeView",
+ "java/nio/file/attribute/PosixFileAttributeView$VivifiedWrapper");
+ JAVA_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFilePermission",
+ "java/nio/file/attribute/PosixFilePermission$EnumConversion");
+
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/spi/FileSystemProvider", "java/nio/file/spi/FileSystemProvider$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/spi/FileTypeDetector", "java/nio/file/spi/FileTypeDetector$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/StandardOpenOption", "java/nio/file/StandardOpenOption$EnumConversion");
+ J$_WRAP_CONVERT_OWNER.put("j$/nio/file/LinkOption", "java/nio/file/LinkOption$EnumConversion");
+ J$_WRAP_CONVERT_OWNER.put("j$/nio/file/Path", "java/nio/file/Path$VivifiedWrapper");
+ J$_WRAP_CONVERT_OWNER.put("j$/nio/file/WatchEvent", "java/nio/file/WatchEvent$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/BasicFileAttributes",
+ "java/nio/file/attribute/BasicFileAttributes$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/BasicFileAttributeView",
+ "java/nio/file/attribute/BasicFileAttributeView$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/FileOwnerAttributeView",
+ "java/nio/file/attribute/FileOwnerAttributeView$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFileAttributes",
+ "java/nio/file/attribute/PosixFileAttributes$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFileAttributeView",
+ "java/nio/file/attribute/PosixFileAttributeView$Wrapper");
+ J$_WRAP_CONVERT_OWNER.put(
+ "j$/nio/file/attribute/PosixFilePermission",
+ "java/nio/file/attribute/PosixFilePermission$EnumConversion");
+ }
+
+ public static Path convertJar(Path jar) {
+ String fileName = jar.getFileName().toString();
+ String newFileName =
+ fileName.substring(0, fileName.length() - ".jar".length()) + "_converted.jar";
+ Path convertedJar = jar.getParent().resolve(newFileName);
+ return internalConvert(jar, convertedJar);
+ }
+
+ private static synchronized Path internalConvert(Path jar, Path convertedJar) {
+ if (Files.exists(convertedJar)) {
+ return convertedJar;
+ }
+
+ OpenOption[] options =
+ new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
+ try (ZipOutputStream out =
+ new ZipOutputStream(
+ new BufferedOutputStream(Files.newOutputStream(convertedJar, options)))) {
+ new ConversionConverter().convert(jar, out);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return convertedJar;
+ }
+
+ private void convert(Path desugaredLibraryFiles, ZipOutputStream out) throws IOException {
+ ZipUtils.iter(
+ desugaredLibraryFiles,
+ ((entry, input) -> {
+ if (!entry.getName().endsWith(".class")) {
+ return;
+ }
+ final byte[] bytes = StreamUtils.streamToByteArrayClose(input);
+ final byte[] rewrittenBytes =
+ transformInvoke(entry.getName().substring(0, entry.getName().length() - 6), bytes);
+ ZipUtils.writeToZipStream(out, entry.getName(), rewrittenBytes, ZipEntry.STORED);
+ }));
+ }
+
+ private byte[] transformInvoke(String descriptor, byte[] bytes) {
+ return ClassFileTransformer.create(bytes, Reference.classFromDescriptor(descriptor))
+ .addMethodTransformer(getMethodTransformer())
+ .transform();
+ }
+
+ private MethodTransformer getMethodTransformer() {
+ return new MethodTransformer() {
+ @Override
+ public void visitMethodInsn(
+ int opcode, String owner, String name, String descriptor, boolean isInterface) {
+ if (opcode == Opcodes.INVOKESTATIC && name.equals("wrap_convert")) {
+ if (!JAVA_WRAP_CONVERT_OWNER.containsKey(owner)
+ || !J$_WRAP_CONVERT_OWNER.containsKey(owner)) {
+ throw new RuntimeException("Cannot transform wrap_convert method for " + owner);
+ }
+ if (owner.startsWith("java")) {
+ String newOwner = J$_WRAP_CONVERT_OWNER.get(owner);
+ super.visitMethodInsn(opcode, newOwner, "convert", descriptor, isInterface);
+ return;
+ } else if (owner.startsWith("j$")) {
+ String newOwner = JAVA_WRAP_CONVERT_OWNER.get(owner);
+ super.visitMethodInsn(opcode, newOwner, "convert", descriptor, isInterface);
+ return;
+ } else {
+ throw new RuntimeException("Cannot transform wrap_convert method for " + owner);
+ }
+ }
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+ }
+ };
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/DesugaredLibraryJDK11Undesugarer.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/DesugaredLibraryJDK11Undesugarer.java
index e2ecec4..c9c9a31 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/DesugaredLibraryJDK11Undesugarer.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/DesugaredLibraryJDK11Undesugarer.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.transformers.ClassFileTransformer;
import com.android.tools.r8.transformers.MethodTransformer;
import com.android.tools.r8.utils.StreamUtils;
import com.android.tools.r8.utils.ZipUtils;
@@ -74,7 +75,7 @@
}
private byte[] transformInvoke(String descriptor, byte[] bytes) {
- return transformer(bytes, Reference.classFromDescriptor(descriptor))
+ return ClassFileTransformer.create(bytes, Reference.classFromDescriptor(descriptor))
.addMethodTransformer(getMethodTransformer())
.transform();
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileTypeDetectorTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileTypeDetectorTest.java
index 7848f02..c40b5c4 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileTypeDetectorTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FileTypeDetectorTest.java
@@ -74,7 +74,7 @@
}
@Test
- public void test() throws Exception {
+ public void test() throws Throwable {
testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
.addInnerClasses(getClass())
.addProgramClasses(GoogleIcon.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FilesTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FilesTest.java
index 1e4a04e..673109b 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FilesTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/FilesTest.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
@@ -39,7 +38,7 @@
@RunWith(Parameterized.class)
public class FilesTest extends DesugaredLibraryTestBase {
- private static final String EXPECTED_RESULT =
+ private static final String EXPECTED_RESULT_DESUGARING_FILE_SYSTEM =
StringUtils.lines(
"bytes written: 11",
"String written: Hello World",
@@ -50,7 +49,7 @@
"null",
"true",
"unsupported");
- private static final String EXPECTED_RESULT_24_26 =
+ private static final String EXPECTED_RESULT_DESUGARING_FILE_SYSTEM_PLATFORM_CHANNEL =
StringUtils.lines(
"bytes written: 11",
"String written: Hello World",
@@ -61,7 +60,7 @@
"null",
"true",
"unsupported");
- private static final String EXPECTED_RESULT_26 =
+ private static final String EXPECTED_RESULT_PLATFORM_FILE_SYSTEM =
StringUtils.lines(
"bytes written: 11",
"String written: Hello World",
@@ -100,16 +99,16 @@
}
private String getExpectedResult() {
- if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.O)) {
- return EXPECTED_RESULT_26;
+ if (libraryDesugaringSpecification.usesPlatformFileSystem(parameters)) {
+ return EXPECTED_RESULT_PLATFORM_FILE_SYSTEM;
}
- return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)
- ? EXPECTED_RESULT_24_26
- : EXPECTED_RESULT;
+ return libraryDesugaringSpecification.hasNioChannelDesugaring(parameters)
+ ? EXPECTED_RESULT_DESUGARING_FILE_SYSTEM
+ : EXPECTED_RESULT_DESUGARING_FILE_SYSTEM_PLATFORM_CHANNEL;
}
@Test
- public void test() throws Exception {
+ public void test() throws Throwable {
testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
@@ -146,7 +145,7 @@
try {
PosixFileAttributes posixAttributes = Files.readAttributes(path, PosixFileAttributes.class);
- if (attributes != null) {
+ if (posixAttributes != null) {
System.out.println(
posixAttributes.permissions().contains(PosixFilePermission.OWNER_READ));
} else {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/PathTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/PathTest.java
index 542ac06..26e16bc 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/PathTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/PathTest.java
@@ -28,7 +28,14 @@
private final LibraryDesugaringSpecification libraryDesugaringSpecification;
private final CompilationSpecification compilationSpecification;
- private static final String EXPECTED_RESULT = StringUtils.lines("x.txt", "dir", "dir/x.txt", "/");
+ private static final String EXPECTED_RESULT_DESUGARING =
+ StringUtils.lines(
+ "x.txt", "dir", "dir/x.txt", "/", "class j$.desugar.sun.nio.fs.DesugarLinuxFileSystem");
+ private static final String EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM =
+ StringUtils.lines(
+ "x.txt", "dir", "dir/x.txt", "/", "class j$.nio.file.FileSystem$VivifiedWrapper");
+ private static final String EXPECTED_RESULT_NO_DESUGARING =
+ StringUtils.lines("x.txt", "dir", "dir/x.txt", "/", "class sun.nio.fs.LinuxFileSystem");
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
@@ -47,13 +54,25 @@
this.compilationSpecification = compilationSpecification;
}
+ private String getExpectedResult() {
+ if (!libraryDesugaringSpecification.hasNioFileDesugaring(parameters)) {
+ return EXPECTED_RESULT_NO_DESUGARING;
+ }
+ return libraryDesugaringSpecification.usesPlatformFileSystem(parameters)
+ ? EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM
+ : EXPECTED_RESULT_DESUGARING;
+ }
+
@Test
- public void test() throws Exception {
+ public void test() throws Throwable {
testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+ .addL8KeepRules("-keepnames class j$.desugar.sun.nio.fs.**")
+ .addL8KeepRules("-keepnames class j$.nio.file.FileSystem**")
.addInnerClasses(PathTest.class)
.addKeepMainRule(TestClass.class)
+ .compile()
.run(parameters.getRuntime(), TestClass.class)
- .assertSuccessWithOutput(EXPECTED_RESULT);
+ .assertSuccessWithOutput(getExpectedResult());
}
public static class TestClass {
@@ -67,6 +86,7 @@
Path resolve = path2.resolve(path1);
System.out.println(resolve);
System.out.println(resolve.getFileSystem().getSeparator());
+ System.out.println(resolve.getFileSystem().getClass());
}
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11NioFileTests.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11NioFileTests.java
index 5cb8e57..8168e33 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11NioFileTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11NioFileTests.java
@@ -136,7 +136,6 @@
"WatchServiceBasic",
"WatchServiceFileTreeModifier",
"WatchServiceDeleteInterference",
- "WatchServiceMayFlies",
"WatchServiceLotsOfCancels",
"WatchServiceSensitivityModifier");
private static final List<String> FAILING_MAIN_TESTS =
@@ -157,6 +156,7 @@
"FilesTemporaryFiles",
"FilesCheckPermissions",
"FilesMisc",
+ "WatchServiceMayFlies", // Works but longest to run by far.
"WatchServiceWithSecurityManager",
"WatchServiceUpdateInterference",
"WatchServiceLotsOfCloses");
@@ -272,10 +272,12 @@
.compile()
.withArt6Plus64BitsLib();
int success = 0;
+ int failures = 0;
for (String mainTestClass : SUCCESSFUL_MAIN_TESTS) {
SingleTestRunResult<?> run = compileResult.run(parameters.getRuntime(), mainTestClass);
if (run.getExitCode() != 0) {
System.out.println("Main Fail " + mainTestClass);
+ failures++;
} else {
success++;
}
@@ -286,6 +288,7 @@
parameters.getRuntime(), "TestNGMainRunner", verbosity, testNGTestClass);
if (!result.getStdOut().contains(StringUtils.lines(testNGTestClass + ": SUCCESS"))) {
System.out.println("TestNG Fail " + testNGTestClass);
+ failures++;
} else {
success++;
}
@@ -293,7 +296,9 @@
// TODO(b/234689867): Understand and fix these issues.
// Most issues seem to come from the missing secure.properties file. This file is not accessed
// in all tests on all API levels, hence a different number of failures on each level.
- assertTrue(success >= 15);
+ System.out.println("Successes :" + success + "; failures " + failures);
+ assertTrue(success >= 11);
+ assertTrue(failures <= 20);
}
@Test
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
index b9ca3f1..5a2c8b0 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
@@ -44,6 +44,7 @@
private final LibraryDesugaringSpecification libraryDesugaringSpecification;
private final CompilationSpecification compilationSpecification;
private final TestCompilerBuilder<?, ?, ?, ? extends SingleTestRunResult<?>, ?> builder;
+ private String l8ExtraKeepRules = "";
private Consumer<InternalOptions> l8OptionModifier = ConsumerUtils.emptyConsumer();
private boolean l8FinalPrefixVerification = true;
@@ -205,6 +206,13 @@
return this;
}
+ public DesugaredLibraryTestBuilder<T> addL8KeepRules(String keepRules) {
+ if (compilationSpecification.isL8Shrink()) {
+ l8ExtraKeepRules += keepRules + "\n";
+ }
+ return this;
+ }
+
public DesugaredLibraryTestBuilder<T> addKeepClassAndMembersRules(Class<?>... clazz) {
withR8TestBuilder(b -> b.addKeepClassAndMembersRules(clazz));
return this;
@@ -348,7 +356,7 @@
L8TestCompileResult nonShrunk =
test.testForL8(parameters.getApiLevel(), Backend.CF)
.apply(libraryDesugaringSpecification::configureL8TestBuilder)
- .apply(this::configure)
+ .apply(b -> configure(b, Backend.CF))
.compile();
String keepRules =
collectKeepRulesWithTraceReferences(compile.writeToZip(), nonShrunk.writeToZip());
@@ -362,13 +370,16 @@
b ->
libraryDesugaringSpecification.configureL8TestBuilder(
b, compilationSpecification.isL8Shrink(), keepRule))
- .apply(this::configure)
+ .apply(b -> configure(b, parameters.getBackend()))
.compile();
}
- private void configure(L8TestBuilder l8Builder) {
+ private void configure(L8TestBuilder l8Builder, Backend backend) {
l8Builder
.applyIf(!l8FinalPrefixVerification, L8TestBuilder::ignoreFinalPrefixVerification)
+ .applyIf(
+ compilationSpecification.isL8Shrink() && !backend.isCf() && !l8ExtraKeepRules.isEmpty(),
+ b -> b.addKeepRules(l8ExtraKeepRules))
.addOptionsModifier(l8OptionModifier);
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
index 539ad9a..d0b9e66 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/LibraryDesugaringSpecification.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.L8TestBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -152,7 +153,7 @@
Descriptor descriptor) {
this(
name,
- ImmutableSet.of(desugarJdkLibs, ToolHelper.DESUGAR_LIB_CONVERSIONS),
+ ImmutableSet.of(desugarJdkLibs, ToolHelper.getConvertedDesugaredLibConversions()),
Paths.get("src/library_desugar/" + specificationPath),
ImmutableSet.of(ToolHelper.getAndroidJar(androidJarLevel)),
descriptor,
@@ -254,6 +255,14 @@
return parameters.getApiLevel().getLevel() < descriptor.getNioFileDesugaring();
}
+ public boolean hasNioChannelDesugaring(TestParameters parameters) {
+ return hasNioFileDesugaring(parameters) && parameters.getApiLevel().getLevel() < 24;
+ }
+
+ public boolean usesPlatformFileSystem(TestParameters parameters) {
+ return parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V8_1_0);
+ }
+
public boolean hasAnyDesugaring(TestParameters parameters) {
return hasAnyDesugaring(parameters.getApiLevel());
}