Revert "Delegate wrapper conversion to subtypes"
This reverts commit f9bca89651809f9c0fd01067ec48f126d41b8512.
Reason for revert: Bot failure b/237563869.
Change-Id: Ifb61aae9996a2bd4bd70e848cdc4c734362a5529
diff --git a/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java b/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
index 2b46e36..137ac12 100644
--- a/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
+++ b/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
@@ -17,6 +17,8 @@
private static final Set<String> ENUM_WRAP_CONVERT_OWNER =
ImmutableSet.of(
+ "j$/nio/file/StandardOpenOption",
+ "j$/nio/file/LinkOption",
"j$/nio/file/attribute/PosixFilePermission",
"j$/util/stream/Collector$Characteristics");
private static final Set<String> WRAP_CONVERT_OWNER =
@@ -25,14 +27,18 @@
"j$/nio/file/spi/FileTypeDetector",
"j$/nio/file/Path",
"j$/nio/file/WatchEvent",
- "j$/nio/file/OpenOption");
+ "j$/nio/file/attribute/BasicFileAttributes",
+ "j$/nio/file/attribute/BasicFileAttributeView",
+ "j$/nio/file/attribute/FileOwnerAttributeView",
+ "j$/nio/file/attribute/PosixFileAttributes",
+ "j$/nio/file/attribute/PosixFileAttributeView");
static Map<String, String> getJavaWrapConvertOwnerMap() {
- return computeConvertOwnerMap("$Wrapper");
+ return computeConvertOwnerMap("$VivifiedWrapper");
}
static Map<String, String> getJ$WrapConvertOwnerMap() {
- return computeConvertOwnerMap("$VivifiedWrapper");
+ return computeConvertOwnerMap("$Wrapper");
}
private static HashMap<String, String> computeConvertOwnerMap(String suffix) {
diff --git a/src/library_desugar/java/j$/nio/file/OpenOption.java b/src/library_desugar/java/j$/nio/file/OpenOption.java
index a22eb7c..8b063d1 100644
--- a/src/library_desugar/java/j$/nio/file/OpenOption.java
+++ b/src/library_desugar/java/j$/nio/file/OpenOption.java
@@ -4,12 +4,4 @@
package j$.nio.file;
-public class OpenOption {
- public static java.nio.file.OpenOption wrap_convert(j$.nio.file.OpenOption option) {
- return null;
- }
-
- public static j$.nio.file.OpenOption wrap_convert(java.nio.file.OpenOption option) {
- return null;
- }
-}
+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
index 781ab5f..cb01ec0 100644
--- a/src/library_desugar/java/j$/nio/file/Path.java
+++ b/src/library_desugar/java/j$/nio/file/Path.java
@@ -6,7 +6,7 @@
public class Path {
- public static j$.nio.file.Path wrap_convert(java.nio.file.Path path) {
+ public static j$.nio.file.Path inverted_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/spi/FileSystemProvider.java b/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java
index 8db22b3..38152b3 100644
--- a/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java
+++ b/src/library_desugar/java/j$/nio/file/spi/FileSystemProvider.java
@@ -5,8 +5,7 @@
package j$.nio.file.spi;
public class FileSystemProvider {
- public static java.nio.file.spi.FileSystemProvider inverted_wrap_convert(
- j$.nio.file.spi.FileSystemProvider provider) {
+ 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 5909b09..d02344d 100644
--- a/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java
+++ b/src/library_desugar/java/java/adapter/HybridFileSystemProvider.java
@@ -27,7 +27,7 @@
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.inverted_wrap_convert(provider);
+ return j$.nio.file.spi.FileSystemProvider.wrap_convert(provider);
} catch (ClassNotFoundException ignored) {
// We reach this path is API < 26.
}
diff --git a/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java b/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
index da93736..af2c8f7 100644
--- a/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
+++ b/src/library_desugar/java/java/adapter/HybridFileTypeDetector.java
@@ -29,7 +29,7 @@
static class PlatformFileTypeDetector extends FileTypeDetector {
@Override
public String probeContentType(Path path) throws IOException {
- return j$.nio.file.Files.probeContentType(j$.nio.file.Path.wrap_convert(path));
+ return j$.nio.file.Files.probeContentType(j$.nio.file.Path.inverted_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
index b68aeb2..71b172a 100644
--- a/src/library_desugar/java/java/nio/file/FileApiFlips.java
+++ b/src/library_desugar/java/java/nio/file/FileApiFlips.java
@@ -78,7 +78,7 @@
} catch (ClassCastException cce) {
throw exceptionOpenOption(cce);
}
- convertedSet.add(j$.nio.file.OpenOption.wrap_convert(option));
+ convertedSet.add(OpenOptionConversions.convert(option));
}
return convertedSet;
}
@@ -90,7 +90,7 @@
} catch (ClassCastException cce) {
throw exceptionOpenOption(cce);
}
- convertedSet.add(j$.nio.file.OpenOption.wrap_convert(option));
+ convertedSet.add(OpenOptionConversions.convert(option));
}
return convertedSet;
}
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 c895d52..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,6 +4,8 @@
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) {
@@ -20,4 +22,67 @@
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/jdk11/desugar_jdk_libs_path.json b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
index f2e565f..7b767e1 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
@@ -132,7 +132,6 @@
"java.nio.file.spi.FileSystemProvider",
"java.nio.file.spi.FileTypeDetector",
"java.nio.file.AccessMode",
- "java.nio.file.OpenOption",
"java.nio.file.StandardOpenOption",
"java.nio.file.LinkOption",
"java.nio.file.CopyOption",
@@ -146,7 +145,6 @@
"java.nio.file.attribute.PosixFilePermission",
"java.nio.file.attribute.BasicFileAttributes",
"java.nio.file.attribute.PosixFileAttributes",
- "java.nio.file.attribute.FileAttributeView",
"java.nio.file.attribute.FileOwnerAttributeView",
"java.nio.file.attribute.PosixFileAttributeView",
"java.nio.file.attribute.BasicFileAttributeView"
@@ -159,7 +157,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"
}
},
{
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 41ab157..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
@@ -46,7 +46,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
@@ -364,12 +363,7 @@
}
assert context.isNotProgramClass();
Iterable<DexMethod> methods =
- appView
- .options()
- .machineDesugaredLibrarySpecification
- .getWrappers()
- .get(context.type)
- .getMethods();
+ appView.options().machineDesugaredLibrarySpecification.getWrappers().get(context.type);
assert methods != null;
ClasspathOrLibraryClass classpathOrLibraryContext = context.asClasspathOrLibraryClass();
DexType type = context.type;
@@ -480,24 +474,13 @@
eventConsumer::acceptWrapperClasspathClass);
}
- private void synthesizeProgramConversionMethod(
+ private void getExistingProgramConversionMethod(
SyntheticKindSelector kindSelector,
DexProgramClass context,
- List<DexType> subwrappers,
DexClass wrapper,
DexClass reverseWrapper) {
DexField wrapperField = getWrapperUniqueField(wrapper);
DexField reverseWrapperField = getWrapperUniqueField(reverseWrapper);
- List<DexMethod> subwrapperConvertList = new ArrayList<>();
- for (DexType subwrapper : subwrappers) {
- DexClass subwrapperClass = appView.definitionFor(subwrapper);
- assert subwrapperClass != null;
- DexProgramClass subwrapperWrapper =
- getExistingProgramWrapper(
- subwrapperClass,
- subwrapperClass.isEnum() ? kinds -> kinds.ENUM_CONVERSION : kindSelector);
- subwrapperConvertList.add(getConversion(subwrapperWrapper));
- }
DexProto proto = factory.createProto(reverseWrapperField.type, wrapperField.type);
appView
.getSyntheticItems()
@@ -513,27 +496,14 @@
methodBuilder,
proto,
computeProgramConversionMethodCode(
- wrapperField, reverseWrapperField, context, subwrapperConvertList)));
- }
-
- private DexMethod getConversion(DexProgramClass subwrapperWrapper) {
- Iterator<DexEncodedMethod> iterator = subwrapperWrapper.directMethods().iterator();
- DexEncodedMethod method;
- do {
- method = iterator.next();
- } while (!method.isStatic());
- assert method.getName() == factory.convertMethodName;
- return method.getReference();
+ wrapperField, reverseWrapperField, context)));
}
private CfCode computeProgramConversionMethodCode(
- DexField wrapperField,
- DexField reverseWrapperField,
- DexClass context,
- List<DexMethod> subwrapperConvertList) {
+ DexField wrapperField, DexField reverseWrapperField, DexClass context) {
assert context.isProgramClass();
return new NullableConversionCfCodeProvider.WrapperConversionCfCodeProvider(
- appView, reverseWrapperField, wrapperField, subwrapperConvertList)
+ appView, reverseWrapperField, wrapperField)
.generateCfCode();
}
@@ -665,7 +635,7 @@
librarySpecification
.getWrappers()
.forEach(
- (type, descriptor) -> {
+ (type, methods) -> {
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
@@ -674,25 +644,20 @@
if (validClassToWrap.isEnum()) {
enumConverter.ensureProgramEnumConversionClass(validClassToWrap, eventConsumer);
} else {
- validClassesToWrap.put(
- validClassToWrap.asProgramClass(), descriptor.getMethods());
- synthesizeProgramWrappersWithoutVirtualMethods(
- validClassToWrap, descriptor.getSubwrappers(), eventConsumer);
+ validClassesToWrap.put(validClassToWrap.asProgramClass(), methods);
+ ensureProgramWrappersWithoutVirtualMethods(validClassToWrap, eventConsumer);
}
}
});
validClassesToWrap.forEach(
(clazz, methods) ->
- synthesizeProgramWrappersVirtualMethods(
- clazz, methods, eventConsumer, processingContext));
+ ensureProgramWrappersVirtualMethods(clazz, methods, eventConsumer, processingContext));
}
// We generate first the two wrappers with the constructor method and the fields, then we
// the two conversion methods which requires the wrappers to know both fields.
- private void synthesizeProgramWrappersWithoutVirtualMethods(
- DexClass context,
- List<DexType> subwrappers,
- DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer) {
+ private void ensureProgramWrappersWithoutVirtualMethods(
+ DexClass context, DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer eventConsumer) {
assert eventConsumer != null;
assert context.isProgramClass();
DexType type = context.type;
@@ -708,13 +673,13 @@
vivifiedTypeFor(type),
programContext,
eventConsumer);
- synthesizeProgramConversionMethod(
- kinds -> kinds.WRAPPER, programContext, subwrappers, wrapper, vivifiedWrapper);
- synthesizeProgramConversionMethod(
- kinds -> kinds.VIVIFIED_WRAPPER, programContext, subwrappers, vivifiedWrapper, wrapper);
+ getExistingProgramConversionMethod(
+ kinds -> kinds.WRAPPER, programContext, wrapper, vivifiedWrapper);
+ getExistingProgramConversionMethod(
+ kinds -> kinds.VIVIFIED_WRAPPER, programContext, vivifiedWrapper, wrapper);
}
- private void synthesizeProgramWrappersVirtualMethods(
+ private void ensureProgramWrappersVirtualMethods(
DexProgramClass context,
Iterable<DexMethod> methods,
CfClassSynthesizerDesugaringEventConsumer eventConsumer,
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 5c70c34..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 {
@@ -445,7 +443,6 @@
}
public HumanRewritingFlags build() {
- validate();
return new HumanRewritingFlags(
ImmutableMap.copyOf(rewritePrefix),
ImmutableSet.copyOf(dontRewritePrefix),
@@ -465,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 4aa99b6..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
@@ -145,7 +145,7 @@
return rewritingFlags.isEmulatedInterfaceRewrittenType(type);
}
- public Map<DexType, WrapperDescriptor> getWrappers() {
+ public Map<DexType, List<DexMethod>> getWrappers() {
return rewritingFlags.getWrappers();
}
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 5ad734b..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
@@ -10,12 +10,13 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.IdentityHashMap;
-import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
@@ -38,7 +39,7 @@
Map<DexMethod, DexMethod> emulatedVirtualRetargetThroughEmulatedInterface,
Map<DexMethod, DexMethod[]> apiGenericTypesConversion,
Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces,
- LinkedHashMap<DexType, WrapperDescriptor> wrappers,
+ Map<DexType, List<DexMethod>> wrappers,
Map<DexType, DexType> legacyBackport,
Set<DexType> dontRetarget,
Map<DexType, CustomConversionDescriptor> customConversions,
@@ -100,8 +101,8 @@
// Emulated interface descriptors.
private final Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces;
- // Wrapper descriptors.
- private final LinkedHashMap<DexType, WrapperDescriptor> wrappers;
+ // Wrappers and the list of methods they implement.
+ private final Map<DexType, List<DexMethod>> wrappers;
private final Map<DexType, DexType> legacyBackport;
private final Set<DexType> dontRetarget;
@@ -159,7 +160,7 @@
return emulatedInterfaces;
}
- public Map<DexType, WrapperDescriptor> getWrappers() {
+ public Map<DexType, List<DexMethod>> getWrappers() {
return wrappers;
}
@@ -248,7 +249,7 @@
ImmutableMap.builder();
private final ImmutableMap.Builder<DexType, EmulatedInterfaceDescriptor> emulatedInterfaces =
ImmutableMap.builder();
- private final LinkedHashMap<DexType, WrapperDescriptor> wrappers = new LinkedHashMap<>();
+ private final ImmutableMap.Builder<DexType, List<DexMethod>> wrappers = ImmutableMap.builder();
private final ImmutableMap.Builder<DexType, DexType> legacyBackport = ImmutableMap.builder();
private final ImmutableSet.Builder<DexType> dontRetarget = ImmutableSet.builder();
private final ImmutableMap.Builder<DexType, CustomConversionDescriptor> customConversions =
@@ -307,8 +308,8 @@
apiGenericTypesConversion.put(method, conversions);
}
- public void addWrapper(DexType type, WrapperDescriptor descriptor) {
- this.wrappers.put(type, descriptor);
+ public void addWrapper(DexType wrapperConversion, List<DexMethod> methods) {
+ wrappers.put(wrapperConversion, ImmutableList.copyOf(methods));
}
public void putLegacyBackport(DexType src, DexType target) {
@@ -366,7 +367,7 @@
emulatedVirtualRetargetThroughEmulatedInterface.build(),
apiGenericTypesConversion.build(),
emulatedInterfaces.build(),
- wrappers,
+ wrappers.build(),
legacyBackport.build(),
dontRetarget.build(),
customConversions.build(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/WrapperDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/WrapperDescriptor.java
deleted file mode 100644
index f4a158c..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/WrapperDescriptor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.ir.desugar.desugaredlibrary.machinespecification;
-
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
-import java.util.List;
-
-public class WrapperDescriptor {
- private final List<DexMethod> methods;
- private final List<DexType> subwrappers;
-
- public WrapperDescriptor(List<DexMethod> methods, List<DexType> directSubtypes) {
- this.methods = methods;
- this.subwrappers = directSubtypes;
- }
-
- public List<DexMethod> getMethods() {
- return methods;
- }
-
- public List<DexType> getSubwrappers() {
- return subwrappers;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineWrapperConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineWrapperConverter.java
index a7ed82c..c0d9157 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineWrapperConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineWrapperConverter.java
@@ -12,19 +12,14 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.WrapperDescriptor;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -42,53 +37,6 @@
HumanRewritingFlags rewritingFlags,
MachineRewritingFlags.Builder builder,
BiConsumer<String, Set<? extends DexReference>> warnConsumer) {
- Map<DexType, WrapperDescriptorBuilder> descriptors = initializeDescriptors(rewritingFlags);
- fillDescriptors(rewritingFlags, descriptors);
- // The descriptors have to be ordered so that when processing a type, subtypes have been
- // processed before.
- LinkedHashMap<DexType, WrapperDescriptorBuilder> orderedDescriptors =
- orderDescriptors(descriptors);
- finalizeWrapperDescriptors(orderedDescriptors, builder);
- warnConsumer.accept("The following types to wrap are missing: ", missingClasses);
- }
-
- private static class WrapperDescriptorBuilder {
- private final List<DexMethod> methods = new ArrayList<>();
- private final List<DexType> subwrappers = new ArrayList<>();
-
- public WrapperDescriptorBuilder() {}
-
- public List<DexMethod> getMethods() {
- return methods;
- }
-
- public List<DexType> getSubwrappers() {
- return subwrappers;
- }
-
- public void addSubwrapper(DexType type) {
- subwrappers.add(type);
- }
-
- public WrapperDescriptor toWrapperDescriptor() {
- methods.sort(DexMethod::compareTo);
- subwrappers.sort(DexType::compareTo);
- return new WrapperDescriptor(
- ImmutableList.copyOf(methods), ImmutableList.copyOf(subwrappers));
- }
- }
-
- private Map<DexType, WrapperDescriptorBuilder> initializeDescriptors(
- HumanRewritingFlags rewritingFlags) {
- Map<DexType, WrapperDescriptorBuilder> descriptors = new IdentityHashMap<>();
- for (DexType wrapperType : rewritingFlags.getWrapperConversions().keySet()) {
- descriptors.put(wrapperType, new WrapperDescriptorBuilder());
- }
- return descriptors;
- }
-
- private void fillDescriptors(
- HumanRewritingFlags rewritingFlags, Map<DexType, WrapperDescriptorBuilder> descriptors) {
rewritingFlags
.getWrapperConversions()
.forEach(
@@ -96,91 +44,53 @@
DexClass wrapperClass = appInfo.definitionFor(wrapperType);
if (wrapperClass == null) {
missingClasses.add(wrapperType);
- descriptors.remove(wrapperType);
return;
}
- WrapperDescriptorBuilder descriptor = descriptors.get(wrapperType);
- fillDescriptors(wrapperClass, excludedMethods, descriptor, descriptors);
+ List<DexMethod> methods;
+ if (wrapperClass.isEnum()) {
+ methods = ImmutableList.of();
+ } else {
+ methods = allImplementedMethods(wrapperClass, excludedMethods);
+ methods.sort(DexMethod::compareTo);
+ }
+ builder.addWrapper(wrapperType, methods);
});
+ warnConsumer.accept("The following types to wrap are missing: ", missingClasses);
}
- private LinkedHashMap<DexType, WrapperDescriptorBuilder> orderDescriptors(
- Map<DexType, WrapperDescriptorBuilder> descriptors) {
- LinkedHashMap<DexType, WrapperDescriptorBuilder> orderedDescriptors = new LinkedHashMap<>();
- List<DexType> preOrdered = new ArrayList<>(descriptors.keySet());
- preOrdered.sort(DexType::compareTo);
- LinkedList<DexType> workList = new LinkedList<>(preOrdered);
- while (!workList.isEmpty()) {
- DexType dexType = workList.removeFirst();
- WrapperDescriptorBuilder descriptor = descriptors.get(dexType);
- List<DexType> subwrappers = descriptor.getSubwrappers();
- if (Iterables.all(subwrappers, orderedDescriptors::containsKey)) {
- orderedDescriptors.put(dexType, descriptor);
- } else {
- workList.addLast(dexType);
- }
- }
- return orderedDescriptors;
- }
-
- private void finalizeWrapperDescriptors(
- LinkedHashMap<DexType, WrapperDescriptorBuilder> descriptors,
- MachineRewritingFlags.Builder builder) {
- descriptors.forEach(
- (type, descriptor) -> {
- LinkedList<DexType> workList = new LinkedList<>(descriptor.getSubwrappers());
- while (!workList.isEmpty()) {
- DexType dexType = workList.removeFirst();
- List<DexType> subwrappers = descriptors.get(dexType).getSubwrappers();
- descriptor.getSubwrappers().removeAll(subwrappers);
- workList.addAll(subwrappers);
- }
- builder.addWrapper(type, descriptor.toWrapperDescriptor());
- });
- }
-
- private void fillDescriptors(
- DexClass wrapperClass,
- Set<DexMethod> excludedMethods,
- WrapperDescriptorBuilder descriptor,
- Map<DexType, WrapperDescriptorBuilder> descriptors) {
+ private List<DexMethod> allImplementedMethods(
+ DexClass wrapperClass, Set<DexMethod> excludedMethods) {
HashSet<Wrapper<DexMethod>> wrappers = new HashSet<>();
for (DexMethod excludedMethod : excludedMethods) {
wrappers.add(equivalence.wrap(excludedMethod));
}
LinkedList<DexClass> workList = new LinkedList<>();
- List<DexMethod> implementedMethods = descriptor.getMethods();
+ List<DexMethod> implementedMethods = new ArrayList<>();
workList.add(wrapperClass);
while (!workList.isEmpty()) {
DexClass dexClass = workList.removeFirst();
- if (dexClass != wrapperClass && descriptors.containsKey(dexClass.type)) {
- descriptors.get(dexClass.type).addSubwrapper(wrapperClass.type);
- }
- if (!wrapperClass.isEnum()) {
- for (DexEncodedMethod virtualMethod : dexClass.virtualMethods()) {
- if (!virtualMethod.isPrivateMethod()
- // Don't include hashCode and equals overrides, as hashCode and equals are added to
- // all wrappers regardless.
- && (!appInfo.dexItemFactory().objectMembers.hashCode.match(virtualMethod))
- && (!appInfo.dexItemFactory().objectMembers.equals.match(virtualMethod))) {
- assert virtualMethod.isProtectedMethod() || virtualMethod.isPublicMethod();
- boolean alreadyAdded =
- wrappers.contains(equivalence.wrap(virtualMethod.getReference()));
- // This looks quadratic but given the size of the collections met in practice for
- // desugared libraries (Max ~15) it does not matter.
- if (!alreadyAdded) {
- for (DexMethod alreadyImplementedMethod : implementedMethods) {
- if (alreadyImplementedMethod.match(virtualMethod.getReference())) {
- alreadyAdded = true;
- break;
- }
+ for (DexEncodedMethod virtualMethod : dexClass.virtualMethods()) {
+ if (!virtualMethod.isPrivateMethod()
+ // Don't include hashCode and equals overrides, as hashCode and equals are added to
+ // all wrappers regardless.
+ && (!appInfo.dexItemFactory().objectMembers.hashCode.match(virtualMethod))
+ && (!appInfo.dexItemFactory().objectMembers.equals.match(virtualMethod))) {
+ assert virtualMethod.isProtectedMethod() || virtualMethod.isPublicMethod();
+ boolean alreadyAdded = wrappers.contains(equivalence.wrap(virtualMethod.getReference()));
+ // This looks quadratic but given the size of the collections met in practice for
+ // desugared libraries (Max ~15) it does not matter.
+ if (!alreadyAdded) {
+ for (DexMethod alreadyImplementedMethod : implementedMethods) {
+ if (alreadyImplementedMethod.match(virtualMethod.getReference())) {
+ alreadyAdded = true;
+ break;
}
}
- if (!alreadyAdded) {
- assert !virtualMethod.isFinal()
- : "Cannot wrap final method " + virtualMethod + " while wrapping " + wrapperClass;
- implementedMethods.add(virtualMethod.getReference());
- }
+ }
+ if (!alreadyAdded) {
+ assert !virtualMethod.isFinal()
+ : "Cannot wrap final method " + virtualMethod + " while wrapping " + wrapperClass;
+ implementedMethods.add(virtualMethod.getReference());
}
}
}
@@ -197,5 +107,6 @@
workList.add(superClass);
}
}
+ return implementedMethods;
}
}
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 8f0f2f4..a32d51e 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
@@ -193,19 +193,14 @@
public static class WrapperConversionCfCodeProvider extends NullableConversionCfCodeProvider {
- private final DexField reverseWrapperField;
- private final DexField wrapperField;
- private final List<DexMethod> subwrapperConvertList;
+ DexField reverseWrapperField;
+ DexField wrapperField;
public WrapperConversionCfCodeProvider(
- AppView<?> appView,
- DexField reverseWrapperField,
- DexField wrapperField,
- List<DexMethod> subwrapperConvertList) {
+ AppView<?> appView, DexField reverseWrapperField, DexField wrapperField) {
super(appView, wrapperField.holder);
this.reverseWrapperField = reverseWrapperField;
this.wrapperField = wrapperField;
- this.subwrapperConvertList = subwrapperConvertList;
}
@Override
@@ -233,23 +228,6 @@
instructions.add(unwrapDest);
instructions.add(frame.clone());
- // if (arg instanceOf Subtype) {
- // return SubtypeWrapper.convert((Subtype) arg)
- // };
- for (DexMethod convert : subwrapperConvertList) {
- CfLabel dest = new CfLabel();
- DexType convertArgType = convert.getArgumentType(0, true);
- instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
- instructions.add(new CfInstanceOf(convertArgType));
- instructions.add(new CfIf(If.Type.EQ, ValueType.INT, dest));
- instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
- instructions.add(new CfCheckCast(convertArgType));
- instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, convert, false));
- instructions.add(new CfReturn(ValueType.fromDexType(reverseWrapperField.type)));
- instructions.add(dest);
- instructions.add(frame.clone());
- }
-
// return new Wrapper(wrappedValue);
instructions.add(new CfNew(wrapperField.holder));
instructions.add(CfStackInstruction.fromAsm(Opcodes.DUP));
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
index a61445b..278ec26 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
@@ -14,12 +14,9 @@
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
-import java.util.Arrays;
import java.util.List;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
-import java.util.stream.BaseStream;
-import java.util.stream.IntStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -33,7 +30,7 @@
private final CompilationSpecification compilationSpecification;
private static final AndroidApiLevel MIN_SUPPORTED = AndroidApiLevel.N;
- private static final String EXPECTED_RESULT = StringUtils.lines("true", "true", "true", "true");
+ private static final String EXPECTED_RESULT = StringUtils.lines("true", "true");
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
@@ -67,22 +64,6 @@
@SuppressWarnings("all")
public static void main(String[] args) {
- consumerTest();
- streamTest();
- }
-
- private static void streamTest() {
- // Type wrapper.
- IntStream intStream = Arrays.stream(new int[] {1});
- BaseStream<?, ?> unwrapped = CustomLibClass.identity(intStream);
- System.out.println(unwrapped == intStream);
-
- // Vivified wrapper.
- IntStream consumer = CustomLibClass.getStream();
- System.out.println(CustomLibClass.testStream(consumer));
- }
-
- private static void consumerTest() {
// Type wrapper.
IntConsumer intConsumer = i -> {};
IntConsumer unwrappedIntConsumer = CustomLibClass.identity(intConsumer);
@@ -114,21 +95,5 @@
public static boolean testConsumer(DoubleConsumer doubleConsumer) {
return doubleConsumer == consumer;
}
-
- private static IntStream intStream = Arrays.stream(new int[] {0});
-
- @SuppressWarnings("WeakerAccess")
- public static BaseStream<Integer, IntStream> identity(IntStream arg) {
- return arg;
- }
-
- public static IntStream getStream() {
- return intStream;
- }
-
- @SuppressWarnings("WeakerAccess")
- public static boolean testStream(BaseStream<?, ?> stream) {
- return stream == intStream;
- }
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/InputStreamTransferToTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/InputStreamTransferToTest.java
index 7721551..54c88bf 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/InputStreamTransferToTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdk11/InputStreamTransferToTest.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.desugar.desugaredlibrary.jdk11;
-import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.SPECIFICATIONS_WITH_CF2CF;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_PATH;
import com.android.tools.r8.TestParameters;
@@ -38,9 +38,9 @@
@Parameters(name = "{0}, spec: {1}, {2}")
public static List<Object[]> data() {
return buildParameters(
- getTestParameters().withAllRuntimesAndApiLevels().enableApiLevelsForCf().build(),
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
ImmutableList.of(JDK11_PATH),
- SPECIFICATIONS_WITH_CF2CF);
+ DEFAULT_SPECIFICATIONS);
}
public InputStreamTransferToTest(