Version 2.0.85
Cherry pick: Add test reproducing lack of signature rewriting when
desugaring
CL: https://r8-review.googlesource.com/52041
Cherry pick: Change GenericSignatureRewriter to use a naming lens
CL: https://r8-review.googlesource.com/52044
Cherry pick: Should not use withLiveness as input to GenericSignatureRewriter
CL: https://r8-review.googlesource.com/52090
Bug: 158124557
Change-Id: Ib475c534bc3e5f5bd7aba54d50ea33dbe2a72c3f
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index cf5e6c8..713f1eb 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -20,7 +20,9 @@
import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
import com.android.tools.r8.ir.optimize.AssertionsRewriter;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
+import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.CfgPrinter;
@@ -172,8 +174,8 @@
}
}
- IRConverter converter =
- new IRConverter(AppView.createForD8(appInfo, options, rewritePrefix), timing, printer);
+ AppView<AppInfo> appView = AppView.createForD8(appInfo, options, rewritePrefix);
+ IRConverter converter = new IRConverter(appView, timing, printer);
app = converter.convert(app, executor);
if (options.printCfg) {
@@ -212,13 +214,18 @@
markers.add(marker);
}
+ NamingLens namingLens =
+ PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix);
+
+ new GenericSignatureRewriter(appView, namingLens).run(appView.appInfo().classes());
+
new ApplicationWriter(
app,
null,
options,
marker == null ? null : ImmutableList.copyOf(markers),
GraphLense.getIdentityLense(),
- PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix),
+ namingLens,
null)
.write(executor);
options.printWarnings();
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index a692e1d..9fcccc6 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -15,7 +15,9 @@
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.shaking.AnnotationRemover;
import com.android.tools.r8.shaking.L8TreePruner;
@@ -127,13 +129,17 @@
app = converter.convert(app, executor);
assert appView.appInfo() == appInfo;
+ NamingLens namingLens =
+ PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix);
+ new GenericSignatureRewriter(appView, namingLens).run(appInfo.classes());
+
new CfApplicationWriter(
app,
appView,
options,
options.getMarker(Tool.L8),
GraphLense.getIdentityLense(),
- PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix),
+ namingLens,
null)
.write(options.getClassFileConsumer(), executor);
options.printWarnings();
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 462a4ae..e9ea099 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -719,11 +719,6 @@
new Minifier(appView.withLiveness(), desugaredCallSites).run(executorService, timing);
timing.end();
} else {
- // Rewrite signature annotations for applications that are not minified.
- if (appView.appInfo().hasLiveness()) {
- // TODO(b/124726014): Rewrite signature annotations in lens rewriting instead of here?
- new GenericSignatureRewriter(appView.withLiveness()).run(appView.appInfo().classes());
- }
namingLens = NamingLens.getIdentityLens();
}
@@ -784,14 +779,20 @@
options.syntheticProguardRulesConsumer.accept(synthesizedProguardRules);
}
+ NamingLens prefixRewritingNamingLens =
+ PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
+ options, appView.rewritePrefix, namingLens);
+
+ new GenericSignatureRewriter(appView, prefixRewritingNamingLens)
+ .run(appView.appInfo().classes());
+
// Generate the resulting application resources.
writeApplication(
executorService,
application,
appView,
appView.graphLense(),
- PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
- options, appView.rewritePrefix, namingLens),
+ prefixRewritingNamingLens,
options,
proguardMapSupplier);
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 492d049..bc4c231 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.0.84";
+ public static final String LABEL = "2.0.85";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index 512dde8..468cdcc 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -13,26 +13,22 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
-import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardPackageNameList;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
-import com.android.tools.r8.utils.IteratorUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -145,18 +141,6 @@
}
timing.end();
- timing.begin("rename-generic");
- new GenericSignatureRewriter(appView, renaming)
- .run(
- new Iterable<DexProgramClass>() {
- @Override
- public Iterator<DexProgramClass> iterator() {
- return IteratorUtils.<DexClass, DexProgramClass>filter(
- classes.iterator(), DexClass::isProgramClass);
- }
- });
- timing.end();
-
timing.begin("rename-arrays");
appView.dexItemFactory().forAllTypes(this::renameArrayTypeIfNeeded);
timing.end();
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index 7747eda..1851249 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -14,14 +14,13 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
-import com.google.common.collect.Maps;
import java.lang.reflect.GenericSignatureFormatError;
-import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -29,22 +28,24 @@
public class GenericSignatureRewriter {
- private final AppView<AppInfoWithLiveness> appView;
- private final Map<DexType, DexString> renaming;
+ private final AppView<?> appView;
+ private final NamingLens namingLens;
+ private final InternalOptions options;
private final Reporter reporter;
- public GenericSignatureRewriter(AppView<AppInfoWithLiveness> appView) {
- this(appView, Maps.newIdentityHashMap());
- }
-
- public GenericSignatureRewriter(
- AppView<AppInfoWithLiveness> appView, Map<DexType, DexString> renaming) {
+ public GenericSignatureRewriter(AppView<?> appView, NamingLens namingLens) {
this.appView = appView;
- this.renaming = renaming;
- this.reporter = appView.options().reporter;
+ this.namingLens = namingLens;
+ this.options = appView.options();
+ this.reporter = options.reporter;
}
public void run(Iterable<? extends DexProgramClass> classes) {
+ // Rewrite signature annotations for applications that are minified or if we have liveness
+ // information, since we could have pruned types.
+ if (namingLens.isIdentityLens() && !appView.appInfo().hasLiveness()) {
+ return;
+ }
final GenericSignatureCollector genericSignatureCollector = new GenericSignatureCollector();
final GenericSignatureParser<DexType> genericSignatureParser =
new GenericSignatureParser<>(genericSignatureCollector);
@@ -195,10 +196,10 @@
String originalDescriptor = getDescriptorFromClassBinaryName(name);
DexType type =
appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
- if (appView.appInfo().wasPruned(type)) {
+ if (appView.appInfo().hasLiveness() && appView.appInfo().withLiveness().wasPruned(type)) {
type = appView.dexItemFactory().objectType;
}
- DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
+ DexString renamedDescriptor = namingLens.lookupDescriptor(type);
if (parserPosition == ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION
&& currentClassContext != null) {
// We may have merged the type down to the current class type.
@@ -245,16 +246,14 @@
getClassBinaryNameFromDescriptor(enclosingDescriptor)
+ DescriptorUtils.INNER_CLASS_SEPARATOR
+ name));
- String enclosingRenamedBinaryName =
- getClassBinaryNameFromDescriptor(
- renaming.getOrDefault(enclosingType, enclosingType.descriptor).toString());
type = appView.graphLense().lookupType(type);
- DexString renamedDescriptor = renaming.get(type);
- if (renamedDescriptor != null) {
+ String renamedDescriptor = namingLens.lookupDescriptor(type).toString();
+ if (!renamedDescriptor.equals(type.toDescriptorString())) {
// TODO(b/147504070): If this is a merged class equal to the class context, do not add.
// Pick the renamed inner class from the fully renamed binary name.
- String fullRenamedBinaryName =
- getClassBinaryNameFromDescriptor(renamedDescriptor.toString());
+ String fullRenamedBinaryName = getClassBinaryNameFromDescriptor(renamedDescriptor);
+ String enclosingRenamedBinaryName =
+ getClassBinaryNameFromDescriptor(namingLens.lookupDescriptor(enclosingType).toString());
int innerClassPos = enclosingRenamedBinaryName.length() + 1;
if (innerClassPos < fullRenamedBinaryName.length()) {
renamedSignature.append(fullRenamedBinaryName.substring(innerClassPos));
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
new file mode 100644
index 0000000..ff07b24
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, 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;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.time.LocalDate;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DesugaredGenericSignatureTest extends DesugaredLibraryTestBase {
+
+ private final TestParameters parameters;
+ private final boolean shrinkDesugaredLibrary;
+ private static final String EXPECTED = StringUtils.lines("1970", "1", "2");
+
+ @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withDexRuntimes().withAllApiLevels().build(), BooleanUtils.values());
+ }
+
+ public DesugaredGenericSignatureTest(TestParameters parameters, boolean shrinkDesugaredLibrary) {
+ this.parameters = parameters;
+ this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ testForD8()
+ .addInnerClasses(DesugaredGenericSignatureTest.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .setIncludeClassesChecksum(true)
+ .compile()
+ .inspect(this::checkRewrittenSignature)
+ .addDesugaredCoreLibraryRunClassPath(
+ this::buildDesugaredLibrary,
+ parameters.getApiLevel(),
+ keepRuleConsumer.get(),
+ shrinkDesugaredLibrary)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ testForR8(parameters.getBackend())
+ .addInnerClasses(DesugaredGenericSignatureTest.class)
+ .addKeepMainRule(Main.class)
+ .addKeepAllClassesRuleWithAllowObfuscation()
+ .addKeepAttributes(
+ ProguardKeepAttributes.SIGNATURE,
+ ProguardKeepAttributes.INNER_CLASSES,
+ ProguardKeepAttributes.ENCLOSING_METHOD)
+ .enableInliningAnnotations()
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .compile()
+ .inspect(this::checkRewrittenSignature)
+ .addDesugaredCoreLibraryRunClassPath(
+ this::buildDesugaredLibrary,
+ parameters.getApiLevel(),
+ keepRuleConsumer.get(),
+ shrinkDesugaredLibrary)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ private void checkRewrittenSignature(CodeInspector inspector) {
+ if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+ return;
+ }
+ ClassSubject javaTimeBox = inspector.clazz(JavaTimeDateBox.class);
+ assertThat(javaTimeBox, isPresent());
+ ClassSubject box = inspector.clazz(Box.class);
+ assertThat(box, isPresent());
+ String finalBoxDescriptor = box.getFinalDescriptor();
+ assertEquals(
+ "Ljava/lang/Object;"
+ + finalBoxDescriptor.substring(0, finalBoxDescriptor.length() - 1)
+ + "<Lj$/time/LocalDate;>;",
+ javaTimeBox.getFinalSignatureAttribute());
+ }
+
+ public interface Box<T> {
+ T addOne(T t);
+ }
+
+ public static class JavaTimeDateBox implements Box<java.time.LocalDate> {
+
+ @Override
+ @NeverInline
+ public LocalDate addOne(LocalDate localDate) {
+ return localDate.plusDays(1);
+ }
+ }
+
+ public static class Main {
+
+ public static Box<java.time.LocalDate> bar() {
+ return new JavaTimeDateBox();
+ }
+
+ public static void main(String[] args) {
+ LocalDate localDate = bar().addOne(LocalDate.of(1970, 1, 1));
+ System.out.println(localDate.getYear());
+ System.out.println(localDate.getMonthValue());
+ System.out.println(localDate.getDayOfMonth());
+ }
+ }
+}