Reland "Introduce maintain prefix for UncheckedIOException"
This reverts commit 91f09367ae012d5eced370ebc1846a7c06ed4960.
Change-Id: I78c82fa43b8e24b39f375c0b30381d02f3dadbc8
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json b/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
index de5d525..57f7c3e 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_alternative_3.json
@@ -55,7 +55,6 @@
"api_level_below_or_equal": 23,
"rewrite_prefix": {
"java.io.DesugarBufferedReader": "j$.io.DesugarBufferedReader",
- "java.io.UncheckedIOException": "j$.io.UncheckedIOException",
"java.util.DoubleSummaryStatistics": "j$.util.DoubleSummaryStatistics",
"java.util.IntSummaryStatistics": "j$.util.IntSummaryStatistics",
"java.util.LongSummaryStatistics": "j$.util.LongSummaryStatistics",
@@ -70,6 +69,9 @@
"java.util.function.": "j$.util.function.",
"java.util.stream.": "j$.util.stream."
},
+ "maintain_prefix": [
+ "java.io.UncheckedIOException"
+ ],
"emulate_interface": {
"java.lang.Iterable": "j$.lang.Iterable",
"java.util.Collection": "j$.util.Collection",
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 7f74668..acbd677 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -539,7 +539,6 @@
assert !internal.isMinifying();
assert !internal.passthroughDexCode;
internal.passthroughDexCode = true;
- assert internal.neverMergePrefixes.contains("j$.");
// Assert some of R8 optimizations are disabled.
assert !internal.inlinerOptions().enableInlining;
diff --git a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
index 3e33ca8..7bfd947 100644
--- a/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
+++ b/src/main/java/com/android/tools/r8/dex/CodeToKeep.java
@@ -25,6 +25,7 @@
static CodeToKeep createCodeToKeep(InternalOptions options, NamingLens namingLens) {
if ((!namingLens.hasPrefixRewritingLogic()
+ && options.machineDesugaredLibrarySpecification.getMaintainType().isEmpty()
&& !options.machineDesugaredLibrarySpecification.hasEmulatedInterfaces())
|| options.isDesugaredLibraryCompilation()
|| options.testing.enableExperimentalDesugaredLibraryKeepRuleGenerator) {
@@ -67,6 +68,7 @@
private boolean shouldKeep(DexType type) {
return namingLens.prefixRewrittenType(type) != null
+ || options.machineDesugaredLibrarySpecification.getMaintainType().contains(type)
|| options.machineDesugaredLibrarySpecification.isCustomConversionRewrittenType(type)
|| options.machineDesugaredLibrarySpecification.isEmulatedInterfaceRewrittenType(type)
// TODO(b/158632510): This should prefix match on DexString.
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 461fdbf..5936d8c 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
@@ -51,6 +51,7 @@
static final String WRAPPER_CONVERSION_EXCLUDING_KEY = "wrapper_conversion_excluding";
static final String CUSTOM_CONVERSION_KEY = "custom_conversion";
static final String REWRITE_PREFIX_KEY = "rewrite_prefix";
+ static final String MAINTAIN_PREFIX_KEY = "maintain_prefix";
static final String RETARGET_STATIC_FIELD_KEY = "retarget_static_field";
static final String RETARGET_METHOD_KEY = "retarget_method";
static final String RETARGET_METHOD_EMULATED_DISPATCH_KEY =
@@ -242,6 +243,11 @@
builder.putRewritePrefix(rewritePrefix.getKey(), rewritePrefix.getValue().getAsString());
}
}
+ if (jsonFlagSet.has(MAINTAIN_PREFIX_KEY)) {
+ for (JsonElement maintainPrefix : jsonFlagSet.get(MAINTAIN_PREFIX_KEY).getAsJsonArray()) {
+ builder.putMaintainPrefix(maintainPrefix.getAsString());
+ }
+ }
if (jsonFlagSet.has(REWRITE_DERIVED_PREFIX_KEY)) {
for (Map.Entry<String, JsonElement> prefixToMatch :
jsonFlagSet.get(REWRITE_DERIVED_PREFIX_KEY).getAsJsonObject().entrySet()) {
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 6d22218..b0c7920 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
@@ -26,6 +26,7 @@
public class HumanRewritingFlags {
private final Map<String, String> rewritePrefix;
+ private final Set<String> maintainPrefix;
private final Map<String, Map<String, String>> rewriteDerivedPrefix;
private final Map<DexType, DexType> emulatedInterfaces;
private final Map<DexField, DexType> retargetStaticField;
@@ -41,6 +42,7 @@
HumanRewritingFlags(
Map<String, String> rewritePrefix,
+ Set<String> maintainPrefix,
Map<String, Map<String, String>> rewriteDerivedPrefix,
Map<DexType, DexType> emulateLibraryInterface,
Map<DexField, DexType> retargetStaticField,
@@ -54,6 +56,7 @@
Map<DexMethod, MethodAccessFlags> amendLibraryMethod,
Map<DexField, FieldAccessFlags> amendLibraryField) {
this.rewritePrefix = rewritePrefix;
+ this.maintainPrefix = maintainPrefix;
this.rewriteDerivedPrefix = rewriteDerivedPrefix;
this.emulatedInterfaces = emulateLibraryInterface;
this.retargetStaticField = retargetStaticField;
@@ -71,6 +74,7 @@
public static HumanRewritingFlags empty() {
return new HumanRewritingFlags(
ImmutableMap.of(),
+ ImmutableSet.of(),
ImmutableMap.of(),
ImmutableMap.of(),
ImmutableMap.of(),
@@ -94,6 +98,7 @@
reporter,
origin,
rewritePrefix,
+ maintainPrefix,
rewriteDerivedPrefix,
emulatedInterfaces,
retargetStaticField,
@@ -112,6 +117,10 @@
return rewritePrefix;
}
+ public Set<String> getMaintainPrefix() {
+ return maintainPrefix;
+ }
+
public Map<String, Map<String, String>> getRewriteDerivedPrefix() {
return rewriteDerivedPrefix;
}
@@ -175,6 +184,7 @@
private final Origin origin;
private final Map<String, String> rewritePrefix;
+ private final Set<String> maintainPrefix;
private final Map<String, Map<String, String>> rewriteDerivedPrefix;
private final Map<DexType, DexType> emulatedInterfaces;
private final Map<DexField, DexType> retargetStaticField;
@@ -193,6 +203,7 @@
reporter,
origin,
new HashMap<>(),
+ Sets.newIdentityHashSet(),
new HashMap<>(),
new IdentityHashMap<>(),
new IdentityHashMap<>(),
@@ -211,6 +222,7 @@
Reporter reporter,
Origin origin,
Map<String, String> rewritePrefix,
+ Set<String> maintainPrefix,
Map<String, Map<String, String>> rewriteDerivedPrefix,
Map<DexType, DexType> emulateLibraryInterface,
Map<DexField, DexType> retargetStaticField,
@@ -226,6 +238,7 @@
this.reporter = reporter;
this.origin = origin;
this.rewritePrefix = new HashMap<>(rewritePrefix);
+ this.maintainPrefix = Sets.newHashSet(maintainPrefix);
this.rewriteDerivedPrefix = new HashMap<>(rewriteDerivedPrefix);
this.emulatedInterfaces = new IdentityHashMap<>(emulateLibraryInterface);
this.retargetStaticField = new IdentityHashMap<>(retargetStaticField);
@@ -267,6 +280,11 @@
return this;
}
+ public Builder putMaintainPrefix(String prefix) {
+ maintainPrefix.add(prefix);
+ return this;
+ }
+
public Builder putRewriteDerivedPrefix(
String prefixToMatch, String prefixToRewrite, String rewrittenPrefix) {
Map<String, String> map =
@@ -366,6 +384,7 @@
validate();
return new HumanRewritingFlags(
ImmutableMap.copyOf(rewritePrefix),
+ ImmutableSet.copyOf(maintainPrefix),
ImmutableMap.copyOf(rewriteDerivedPrefix),
ImmutableMap.copyOf(emulatedInterfaces),
ImmutableMap.copyOf(retargetStaticField),
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 5216a03..d974c56 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
@@ -84,6 +84,10 @@
return rewritingFlags.getRewriteType();
}
+ public Set<DexType> getMaintainType() {
+ return rewritingFlags.getMaintainType();
+ }
+
public Map<DexType, DexType> getRewriteDerivedTypeOnly() {
return rewritingFlags.getRewriteDerivedTypeOnly();
}
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 bc566af3..dcaa744 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
@@ -27,6 +27,7 @@
MachineRewritingFlags(
Map<DexType, DexType> rewriteType,
+ Set<DexType> maintainType,
Map<DexType, DexType> rewriteDerivedTypeOnly,
Map<DexField, DexField> staticFieldRetarget,
Map<DexMethod, DexMethod> staticRetarget,
@@ -41,6 +42,7 @@
Map<DexMethod, MethodAccessFlags> amendLibraryMethods,
Map<DexField, FieldAccessFlags> amendLibraryFields) {
this.rewriteType = rewriteType;
+ this.maintainType = maintainType;
this.rewriteDerivedTypeOnly = rewriteDerivedTypeOnly;
this.staticFieldRetarget = staticFieldRetarget;
this.staticRetarget = staticRetarget;
@@ -59,6 +61,8 @@
// Rewrites all the references to the keys as well as synthetic types derived from any key.
private final Map<DexType, DexType> rewriteType;
+ // Maintains the references in the desugared library dex file.
+ private final Set<DexType> maintainType;
// Rewrites only synthetic types derived from any key.
private final Map<DexType, DexType> rewriteDerivedTypeOnly;
@@ -98,6 +102,10 @@
return rewriteType;
}
+ public Set<DexType> getMaintainType() {
+ return maintainType;
+ }
+
public Map<DexType, DexType> getRewriteDerivedTypeOnly() {
return rewriteDerivedTypeOnly;
}
@@ -193,6 +201,7 @@
Builder() {}
private final Map<DexType, DexType> rewriteType = new IdentityHashMap<>();
+ private final ImmutableSet.Builder<DexType> maintainType = ImmutableSet.builder();
private final Map<DexType, DexType> rewriteDerivedTypeOnly = new IdentityHashMap<>();
private final ImmutableMap.Builder<DexField, DexField> staticFieldRetarget =
ImmutableMap.builder();
@@ -224,6 +233,11 @@
rewriteType.put(src, target);
}
+ public void maintainType(DexType type) {
+ assert type != null;
+ maintainType.add(type);
+ }
+
public void rewriteDerivedTypeOnly(DexType src, DexType target) {
rewriteDerivedTypeOnly.put(src, target);
}
@@ -283,6 +297,7 @@
public MachineRewritingFlags build() {
return new MachineRewritingFlags(
rewriteType,
+ maintainType.build(),
rewriteDerivedTypeOnly,
staticFieldRetarget.build(),
staticRetarget.build(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
index 87c03e3..78fc59f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
@@ -25,6 +26,7 @@
private final String synthesizedPrefix;
private final boolean libraryCompilation;
private final Map<DexString, DexString> descriptorPrefix;
+ private final Set<DexString> descriptorMaintainPrefix;
private final Map<DexString, Map<DexString, DexString>> descriptorDifferentPrefix;
private final Set<DexString> usedPrefix = Sets.newIdentityHashSet();
@@ -38,6 +40,7 @@
this.synthesizedPrefix = humanSpec.getSynthesizedLibraryClassesPackagePrefix();
this.libraryCompilation = humanSpec.isLibraryCompilation();
this.descriptorPrefix = convertRewritePrefix(rewritingFlags.getRewritePrefix());
+ this.descriptorMaintainPrefix = convertMaintainPrefix(rewritingFlags.getMaintainPrefix());
this.descriptorDifferentPrefix =
convertRewriteDifferentPrefix(rewritingFlags.getRewriteDerivedPrefix());
}
@@ -56,6 +59,7 @@
private void warnIfUnusedPrefix(BiConsumer<String, Set<DexString>> warnConsumer) {
Set<DexString> prefixes = Sets.newIdentityHashSet();
prefixes.addAll(descriptorPrefix.keySet());
+ prefixes.addAll(descriptorMaintainPrefix);
prefixes.addAll(descriptorDifferentPrefix.keySet());
prefixes.removeAll(usedPrefix);
warnConsumer.accept("The following prefixes do not match any type: ", prefixes);
@@ -99,6 +103,7 @@
private void registerClassType(DexType type) {
registerType(type);
+ registerMaintainType(type);
registerDifferentType(type);
}
@@ -109,6 +114,15 @@
}
}
+ private void registerMaintainType(DexType type) {
+ DexString prefix = prefixMatching(type, descriptorMaintainPrefix);
+ if (prefix == null) {
+ return;
+ }
+ builder.maintainType(type);
+ usedPrefix.add(prefix);
+ }
+
private void registerDifferentType(DexType type) {
DexString prefix = prefixMatching(type, descriptorDifferentPrefix.keySet());
if (prefix == null) {
@@ -160,6 +174,14 @@
return mapBuilder.build();
}
+ private ImmutableSet<DexString> convertMaintainPrefix(Set<String> maintainPrefix) {
+ ImmutableSet.Builder<DexString> builder = ImmutableSet.builder();
+ for (String prefix : maintainPrefix) {
+ builder.add(toDescriptorPrefix(prefix));
+ }
+ return builder.build();
+ }
+
private ImmutableMap<DexString, DexString> convertRewritePrefix(
Map<String, String> rewritePrefix) {
ImmutableMap.Builder<DexString, DexString> mapBuilder = ImmutableMap.builder();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index dc739bb..3919202 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -98,6 +98,13 @@
if (isEmulatedInterface(clazz.type)) {
return true;
}
+ if (appView
+ .options()
+ .machineDesugaredLibrarySpecification
+ .getMaintainType()
+ .contains(clazz.type)) {
+ return true;
+ }
return appView.typeRewriter.hasRewrittenType(clazz.type, appView);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index 2ae7d7d..778ed23 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -713,7 +713,10 @@
DexClass clazz, DexMethod invokedMethod, ProgramMethod context) {
DexClassAndMethod superTarget =
appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context);
- if (clazz.isInterface() && appView.typeRewriter.hasRewrittenType(clazz.type, appView)) {
+ if (clazz.isInterface()
+ && clazz.isLibraryClass()
+ && helper.isInDesugaredLibrary(clazz)
+ && !helper.isEmulatedInterface(clazz.type)) {
if (superTarget != null && superTarget.getDefinition().isDefaultMethod()) {
DexClass holder = superTarget.getHolder();
if (holder.isLibraryClass() && holder.isInterface()) {
diff --git a/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java b/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
index 46e77e8..d462818 100644
--- a/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/L8TreePruner.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.TypeRewriter;
import com.android.tools.r8.utils.InternalOptions;
-import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
@@ -22,25 +21,24 @@
public class L8TreePruner {
private final InternalOptions options;
- private final Set<DexType> emulatedInterfaces = Sets.newIdentityHashSet();
- private final Set<DexType> backports = Sets.newIdentityHashSet();
private final List<DexType> pruned = new ArrayList<>();
public L8TreePruner(InternalOptions options) {
this.options = options;
- backports.addAll(options.machineDesugaredLibrarySpecification.getLegacyBackport().keySet());
- emulatedInterfaces.addAll(
- options.machineDesugaredLibrarySpecification.getEmulatedInterfaces().keySet());
}
public DexApplication prune(DexApplication app, TypeRewriter typeRewriter) {
+ Set<DexType> maintainType = options.machineDesugaredLibrarySpecification.getMaintainType();
+ Set<DexType> emulatedInterfaces =
+ options.machineDesugaredLibrarySpecification.getEmulatedInterfaces().keySet();
Map<DexType, DexProgramClass> typeMap = new IdentityHashMap<>();
List<DexProgramClass> toKeep = new ArrayList<>();
boolean pruneNestMember = false;
for (DexProgramClass aClass : app.classes()) {
typeMap.put(aClass.type, aClass);
if (typeRewriter.hasRewrittenType(aClass.type, null)
- || emulatedInterfaces.contains(aClass.type)) {
+ || emulatedInterfaces.contains(aClass.type)
+ || maintainType.contains(aClass.type)) {
toKeep.add(aClass);
} else {
pruneNestMember |= aClass.isInANest();
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 50c315a..133f721 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -274,6 +274,7 @@
// Flag to toggle if the prefix based merge restriction should be enforced.
public boolean enableNeverMergePrefixes = true;
+ // TODO(b/227277105): Control merging with desugared library and maintain prefix.
public Set<String> neverMergePrefixes = ImmutableSet.of("j$.");
public boolean classpathInterfacesMayHaveStaticInitialization = false;
@@ -937,6 +938,10 @@
}
timing.begin("Load machine specification");
loadMachineDesugaredLibrarySpecification.accept(timing, app);
+ if (!machineDesugaredLibrarySpecification.getMaintainType().isEmpty()) {
+ // TODO(b/227277105): Control merging with desugared library and maintain prefix.
+ neverMergePrefixes = ImmutableSet.of();
+ }
timing.end();
}
diff --git a/src/test/java/com/android/tools/r8/L8TestBuilder.java b/src/test/java/com/android/tools/r8/L8TestBuilder.java
index 7a42ab1..2ff60ba 100644
--- a/src/test/java/com/android/tools/r8/L8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/L8TestBuilder.java
@@ -184,7 +184,10 @@
.inspect(
inspector ->
inspector.forAllClasses(
- clazz -> assertTrue(clazz.getFinalName().startsWith("j$."))));
+ clazz ->
+ assertTrue(
+ clazz.getFinalName().startsWith("j$.")
+ || clazz.getFinalName().startsWith("java."))));
}
private Collection<Path> getProgramFiles() {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
index f79b585..93ea904 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/BufferedReaderTest.java
@@ -51,13 +51,7 @@
}
private String expectedOutput() {
- return StringUtils.lines(
- "Hello",
- "Larry",
- "Page",
- parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N)
- ? "Caught java.io.UncheckedIOException"
- : "Caught j$.io.UncheckedIOException");
+ return StringUtils.lines("Hello", "Larry", "Page", "Caught java.io.UncheckedIOException");
}
DesugaredLibrarySpecification configurationAlternative3(