Merge "Allow specifying R8 release version for run_on_as_app.py"
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg
similarity index 100%
rename from infra/config/cr-buildbucket.cfg
rename to infra/config/global/cr-buildbucket.cfg
diff --git a/infra/config/luci-logdog.cfg b/infra/config/global/luci-logdog.cfg
similarity index 100%
rename from infra/config/luci-logdog.cfg
rename to infra/config/global/luci-logdog.cfg
diff --git a/infra/config/luci-milo.cfg b/infra/config/global/luci-milo.cfg
similarity index 100%
rename from infra/config/luci-milo.cfg
rename to infra/config/global/luci-milo.cfg
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
similarity index 100%
rename from infra/config/luci-scheduler.cfg
rename to infra/config/global/luci-scheduler.cfg
diff --git a/infra/config/project.cfg b/infra/config/global/project.cfg
similarity index 100%
rename from infra/config/project.cfg
rename to infra/config/global/project.cfg
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 6a423ec..4755dca 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -38,6 +38,7 @@
import com.android.tools.r8.naming.ProguardMapSupplier;
import com.android.tools.r8.naming.SeedMapper;
import com.android.tools.r8.naming.SourceFileRewriter;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.optimize.ClassAndMemberPublicizer;
import com.android.tools.r8.optimize.MemberRebindingAnalysis;
import com.android.tools.r8.optimize.VisibilityBridgeRemover;
@@ -631,6 +632,10 @@
namingLens = new Minifier(appView.withLiveness(), rootSet, desugaredCallSites).run(timing);
timing.end();
} else {
+ if (appView.appInfo().hasLiveness()) {
+ // TODO(124726014): Rewrite signature annotations in lens rewriting instead of here?
+ new GenericSignatureRewriter(appView.withLiveness()).run();
+ }
namingLens = NamingLens.getIdentityLens();
}
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 b59b79b..d7426fc 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -6,14 +6,11 @@
import static com.android.tools.r8.utils.DescriptorUtils.DESCRIPTOR_PACKAGE_SEPARATOR;
import static com.android.tools.r8.utils.DescriptorUtils.INNER_CLASS_SEPARATOR;
import static com.android.tools.r8.utils.DescriptorUtils.getClassBinaryNameFromDescriptor;
-import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
import static com.android.tools.r8.utils.DescriptorUtils.getPackageBinaryNameFromJavaType;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
-import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -22,22 +19,18 @@
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.naming.signature.GenericSignatureAction;
-import com.android.tools.r8.naming.signature.GenericSignatureParser;
-import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
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.Reporter;
-import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
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.lang.reflect.GenericSignatureFormatError;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -45,8 +38,6 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
import java.util.stream.Collectors;
class ClassNameMinifier {
@@ -71,11 +62,6 @@
private final Namespace topLevelState;
- private final GenericSignatureRewriter genericSignatureRewriter = new GenericSignatureRewriter();
-
- private final GenericSignatureParser<DexType> genericSignatureParser =
- new GenericSignatureParser<>(genericSignatureRewriter);
-
ClassNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
this.appView = appView;
this.appInfo = appView.appInfo();
@@ -97,6 +83,7 @@
// Initialize top-level naming state.
topLevelState = new Namespace(
getPackageBinaryNameFromJavaType(options.getProguardConfiguration().getPackagePrefix()));
+
states.put("", topLevelState);
}
@@ -141,7 +128,7 @@
timing.end();
timing.begin("rename-generic");
- renameTypesInGenericSignatures();
+ new GenericSignatureRewriter(appView, renaming).run();
timing.end();
timing.begin("rename-arrays");
@@ -192,100 +179,6 @@
}
}
- private void parseError(
- DexDefinition item, Origin origin, String signature, GenericSignatureFormatError e) {
- StringBuilder message = new StringBuilder("Invalid signature '");
- message.append(signature);
- message.append("' for ");
- if (item.isDexClass()) {
- message.append("class ");
- message.append((item.asDexClass()).getType().toSourceString());
- } else if (item.isDexEncodedField()) {
- message.append("field ");
- message.append(item.toSourceString());
- } else {
- assert item.isDexEncodedMethod();
- message.append("method ");
- message.append(item.toSourceString());
- }
- message.append(".\n");
- message.append("Signature is ignored and will not be present in the output.\n");
- message.append("Parser error: ");
- message.append(e.getMessage());
- reporter.warning(new StringDiagnostic(message.toString(), origin));
- }
-
- private void renameTypesInGenericSignatures() {
- for (DexClass clazz : appInfo.classes()) {
- clazz.annotations =
- rewriteGenericSignatures(
- clazz.annotations,
- genericSignatureParser::parseClassSignature,
- (signature, e) -> parseError(clazz, clazz.getOrigin(), signature, e));
- clazz.forEachField(
- field ->
- field.annotations =
- rewriteGenericSignatures(
- field.annotations,
- genericSignatureParser::parseFieldSignature,
- (signature, e) -> parseError(field, clazz.getOrigin(), signature, e)));
- clazz.forEachMethod(
- method ->
- method.annotations =
- rewriteGenericSignatures(
- method.annotations,
- genericSignatureParser::parseMethodSignature,
- (signature, e) -> parseError(method, clazz.getOrigin(), signature, e)));
- }
- }
-
- private DexAnnotationSet rewriteGenericSignatures(
- DexAnnotationSet annotations,
- Consumer<String> parser,
- BiConsumer<String, GenericSignatureFormatError> parseError) {
- // There can be no more than one signature annotation in an annotation set.
- final int VALID = -1;
- int invalid = VALID;
- for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
- DexAnnotation annotation = annotations.annotations[i];
- if (DexAnnotation.isSignatureAnnotation(annotation, appInfo.dexItemFactory)) {
- String signature = DexAnnotation.getSignature(annotation);
- try {
- parser.accept(signature);
- annotations.annotations[i] = DexAnnotation.createSignatureAnnotation(
- genericSignatureRewriter.getRenamedSignature(),
- appInfo.dexItemFactory);
- } catch (GenericSignatureFormatError e) {
- parseError.accept(signature, e);
- invalid = i;
- }
- }
- }
-
- // Return the rewritten signatures if it was valid and could be rewritten.
- if (invalid == VALID) {
- return annotations;
- }
- // Remove invalid signature if found.
- DexAnnotation[] prunedAnnotations =
- new DexAnnotation[annotations.annotations.length - 1];
- int dest = 0;
- for (int i = 0; i < annotations.annotations.length; i++) {
- if (i != invalid) {
- prunedAnnotations[dest++] = annotations.annotations[i];
- }
- }
- assert dest == prunedAnnotations.length;
- return new DexAnnotationSet(prunedAnnotations);
- }
-
- /**
- * Registers the given type as used.
- * <p>
- * When {@link #keepInnerClassStructure} is true, keeping the name of an inner class will
- * automatically also keep the name of the outer class, as otherwise the structure would be
- * invalidated.
- */
private void registerClassAsUsed(DexType type) {
renaming.put(type, type.descriptor);
registerPackagePrefixesAsUsed(
@@ -526,73 +419,6 @@
}
}
- private class GenericSignatureRewriter implements GenericSignatureAction<DexType> {
-
- private StringBuilder renamedSignature;
-
- public String getRenamedSignature() {
- return renamedSignature.toString();
- }
-
- @Override
- public void parsedSymbol(char symbol) {
- renamedSignature.append(symbol);
- }
-
- @Override
- public void parsedIdentifier(String identifier) {
- renamedSignature.append(identifier);
- }
-
- @Override
- public DexType parsedTypeName(String name) {
- DexType type = appInfo.dexItemFactory.createType(getDescriptorFromClassBinaryName(name));
- type = appView.graphLense().lookupType(type);
- DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
- renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
- return type;
- }
-
- @Override
- public DexType parsedInnerTypeName(DexType enclosingType, String name) {
- assert enclosingType.isClassType();
- String enclosingDescriptor = enclosingType.toDescriptorString();
- DexType type =
- appInfo.dexItemFactory.createType(
- getDescriptorFromClassBinaryName(
- getClassBinaryNameFromDescriptor(enclosingDescriptor)
- + Minifier.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) {
- // Pick the renamed inner class from the fully renamed binary name.
- String fullRenamedBinaryName =
- getClassBinaryNameFromDescriptor(renamedDescriptor.toString());
- renamedSignature.append(
- fullRenamedBinaryName.substring(enclosingRenamedBinaryName.length() + 1));
- } else {
- // Did not find the class - keep the inner class name as is.
- // TODO(110085899): Warn about missing classes in signatures?
- renamedSignature.append(name);
- }
- return type;
- }
-
- @Override
- public void start() {
- renamedSignature = new StringBuilder();
- }
-
- @Override
- public void stop() {
- // nothing to do
- }
- }
-
/**
* Compute parent package prefix from the given package prefix.
*
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index af18595..be4fd39 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -34,8 +34,6 @@
public class Minifier {
- static final char INNER_CLASS_SEPARATOR = '$';
-
private final AppView<AppInfoWithLiveness> appView;
private final AppInfoWithLiveness appInfo;
private final RootSet rootSet;
@@ -129,7 +127,7 @@
String innerName = attribute.getInnerName().toString();
int lengthOfPrefix = inner.length() - innerName.length();
if (lengthOfPrefix < 0
- || inner.lastIndexOf(INNER_CLASS_SEPARATOR, lengthOfPrefix - 1) < 0
+ || inner.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR, lengthOfPrefix - 1) < 0
|| !inner.endsWith(innerName)) {
return lookupSimpleName(innerType, options.itemFactory);
}
@@ -141,7 +139,7 @@
if (inner.equals(innerTypeMapped)) {
return attribute.getInnerName();
}
- int index = innerTypeMapped.lastIndexOf(INNER_CLASS_SEPARATOR);
+ int index = innerTypeMapped.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR);
if (index < 0) {
// TODO(b/120639028): Replace this by "assert false" and remove the testing option.
// Hitting means we have converted a proper Outer$Inner relationship to an invalid one.
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
new file mode 100644
index 0000000..e55fc6e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -0,0 +1,208 @@
+// Copyright (c) 2019, 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.naming.signature;
+
+import static com.android.tools.r8.utils.DescriptorUtils.getClassBinaryNameFromDescriptor;
+import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexAnnotation;
+import com.android.tools.r8.graph.DexAnnotationSet;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinition;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
+import com.android.tools.r8.utils.DescriptorUtils;
+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.Supplier;
+
+public class GenericSignatureRewriter {
+
+ private final AppView<AppInfoWithLiveness> appView;
+ private final AppInfoWithLiveness appInfo;
+ private final Map<DexType, DexString> renaming;
+ private final Reporter reporter;
+
+ public GenericSignatureRewriter(AppView<AppInfoWithLiveness> appView) {
+ this(appView, Maps.newIdentityHashMap());
+ }
+
+ public GenericSignatureRewriter(
+ AppView<AppInfoWithLiveness> appView, Map<DexType, DexString> renaming) {
+ this.appView = appView;
+ this.appInfo = appView.appInfo();
+ this.renaming = renaming;
+ this.reporter = appView.options().reporter;
+ }
+
+ public void run() {
+ final GenericSignatureCollector genericSignatureCollector = new GenericSignatureCollector();
+ final GenericSignatureParser<DexType> genericSignatureParser =
+ new GenericSignatureParser<>(genericSignatureCollector);
+
+ for (DexClass clazz : appInfo.classes()) {
+ clazz.annotations =
+ rewriteGenericSignatures(
+ clazz.annotations,
+ genericSignatureParser::parseClassSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) -> parseError(clazz, clazz.getOrigin(), signature, e));
+ clazz.forEachField(
+ field ->
+ field.annotations =
+ rewriteGenericSignatures(
+ field.annotations,
+ genericSignatureParser::parseFieldSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) -> parseError(field, clazz.getOrigin(), signature, e)));
+ clazz.forEachMethod(
+ method ->
+ method.annotations =
+ rewriteGenericSignatures(
+ method.annotations,
+ genericSignatureParser::parseMethodSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) -> parseError(method, clazz.getOrigin(), signature, e)));
+ }
+ }
+
+ private DexAnnotationSet rewriteGenericSignatures(
+ DexAnnotationSet annotations,
+ Consumer<String> parser,
+ Supplier<String> collector,
+ BiConsumer<String, GenericSignatureFormatError> parseError) {
+ // There can be no more than one signature annotation in an annotation set.
+ final int VALID = -1;
+ int invalid = VALID;
+ for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
+ DexAnnotation annotation = annotations.annotations[i];
+ if (DexAnnotation.isSignatureAnnotation(annotation, appInfo.dexItemFactory)) {
+ String signature = DexAnnotation.getSignature(annotation);
+ try {
+ parser.accept(signature);
+ annotations.annotations[i] = DexAnnotation.createSignatureAnnotation(
+ collector.get(),
+ appInfo.dexItemFactory);
+ } catch (GenericSignatureFormatError e) {
+ parseError.accept(signature, e);
+ invalid = i;
+ }
+ }
+ }
+
+ // Return the rewritten signatures if it was valid and could be rewritten.
+ if (invalid == VALID) {
+ return annotations;
+ }
+ // Remove invalid signature if found.
+ DexAnnotation[] prunedAnnotations =
+ new DexAnnotation[annotations.annotations.length - 1];
+ int dest = 0;
+ for (int i = 0; i < annotations.annotations.length; i++) {
+ if (i != invalid) {
+ prunedAnnotations[dest++] = annotations.annotations[i];
+ }
+ }
+ assert dest == prunedAnnotations.length;
+ return new DexAnnotationSet(prunedAnnotations);
+ }
+
+ private void parseError(
+ DexDefinition item, Origin origin, String signature, GenericSignatureFormatError e) {
+ StringBuilder message = new StringBuilder("Invalid signature '");
+ message.append(signature);
+ message.append("' for ");
+ if (item.isDexClass()) {
+ message.append("class ");
+ message.append((item.asDexClass()).getType().toSourceString());
+ } else if (item.isDexEncodedField()) {
+ message.append("field ");
+ message.append(item.toSourceString());
+ } else {
+ assert item.isDexEncodedMethod();
+ message.append("method ");
+ message.append(item.toSourceString());
+ }
+ message.append(".\n");
+ message.append("Signature is ignored and will not be present in the output.\n");
+ message.append("Parser error: ");
+ message.append(e.getMessage());
+ reporter.warning(new StringDiagnostic(message.toString(), origin));
+ }
+
+ private class GenericSignatureCollector implements GenericSignatureAction<DexType> {
+ private StringBuilder renamedSignature;
+
+ public String getRenamedSignature() {
+ return renamedSignature.toString();
+ }
+
+ @Override
+ public void parsedSymbol(char symbol) {
+ renamedSignature.append(symbol);
+ }
+
+ @Override
+ public void parsedIdentifier(String identifier) {
+ renamedSignature.append(identifier);
+ }
+
+ @Override
+ public DexType parsedTypeName(String name) {
+ DexType type = appInfo.dexItemFactory.createType(getDescriptorFromClassBinaryName(name));
+ type = appView.graphLense().lookupType(type);
+ DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
+ renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
+ return type;
+ }
+
+ @Override
+ public DexType parsedInnerTypeName(DexType enclosingType, String name) {
+ assert enclosingType.isClassType();
+ String enclosingDescriptor = enclosingType.toDescriptorString();
+ DexType type =
+ appInfo.dexItemFactory.createType(
+ getDescriptorFromClassBinaryName(
+ 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) {
+ // Pick the renamed inner class from the fully renamed binary name.
+ String fullRenamedBinaryName =
+ getClassBinaryNameFromDescriptor(renamedDescriptor.toString());
+ renamedSignature.append(
+ fullRenamedBinaryName.substring(enclosingRenamedBinaryName.length() + 1));
+ } else {
+ // Did not find the class - keep the inner class name as is.
+ // TODO(110085899): Warn about missing classes in signatures?
+ renamedSignature.append(name);
+ }
+ return type;
+ }
+
+ @Override
+ public void start() {
+ renamedSignature = new StringBuilder();
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+ }
+}
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 85c4876..64a9c67 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -288,8 +288,7 @@
public LineNumberOptimization lineNumberOptimization = LineNumberOptimization.ON;
public static boolean shouldEnableKeepRuleSynthesisForRecompilation() {
- return Version.isDev()
- && System.getProperty("com.android.tools.r8.keepRuleSynthesisForRecompilation") != null;
+ return System.getProperty("com.android.tools.r8.keepRuleSynthesisForRecompilation") != null;
}
private static Set<String> getExtensiveLoggingFilter() {
diff --git a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
index 37a0215..fc74d19 100644
--- a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
+++ b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
@@ -4,9 +4,9 @@
package com.android.tools.r8.naming.b124357885;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
-import static org.hamcrest.CoreMatchers.allOf;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isNotRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueString;
+import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.AnnotationSubject;
@@ -26,8 +27,21 @@
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class B124357885Test extends TestBase {
+ public final boolean minification;
+
+ @Parameterized.Parameters(name = "Minification: {0}")
+ public static Boolean[] data() {
+ return BooleanUtils.values();
+ }
+
+ public B124357885Test(boolean minification) {
+ this.minification = minification;
+ }
private void checkSignatureAnnotation(CodeInspector inspector, AnnotationSubject signature) {
DexAnnotationElement[] elements = signature.getAnnotation().elements;
@@ -59,12 +73,13 @@
.addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
.addKeepMainRule(Main.class)
.addKeepRules("-keepattributes Signature,InnerClasses,EnclosingMethod")
+ .minification(minification)
.compile()
.inspect(inspector -> {
- assertThat(inspector.clazz(Main.class), allOf(isPresent(), not(isRenamed())));
- assertThat(inspector.clazz(Service.class), allOf(isPresent(), isRenamed()));
+ assertThat(inspector.clazz(Main.class), isNotRenamed());
+ assertThat(inspector.clazz(Service.class), isRenamed(minification));
assertThat(inspector.clazz(Foo.class), not(isPresent()));
- assertThat(inspector.clazz(FooImpl.class), allOf(isPresent(), isRenamed()));
+ assertThat(inspector.clazz(FooImpl.class), isRenamed(minification));
// TODO(124477502): Using uniqueMethodWithName("fooList") does not work.
assertEquals(1, inspector.clazz(Service.class).allMethods().size());
MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
index 103ffb9..417e40e 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/Matchers.java
@@ -146,6 +146,10 @@
};
}
+ public static Matcher<Subject> isRenamed(boolean isRenamed) {
+ return isRenamed ? isRenamed() : isNotRenamed();
+ }
+
public static Matcher<MemberSubject> isStatic() {
return new TypeSafeMatcher<MemberSubject>() {
@Override
diff --git a/third_party/opensource_apps.tar.gz.sha1 b/third_party/opensource_apps.tar.gz.sha1
index 4ee5113..1695642 100644
--- a/third_party/opensource_apps.tar.gz.sha1
+++ b/third_party/opensource_apps.tar.gz.sha1
@@ -1 +1 @@
-efed1b4bf62340b626cf2d0addb4f334664c0727
\ No newline at end of file
+682d306b6e9a1c6356f1dbfe23f5acef4bc23a2f
\ No newline at end of file
diff --git a/tools/run_on_as_app.py b/tools/run_on_as_app.py
index 1c6446e..ac27750 100755
--- a/tools/run_on_as_app.py
+++ b/tools/run_on_as_app.py
@@ -30,8 +30,7 @@
WORKING_DIR = os.environ['R8_BENCHMARK_DIR']
# For running on Golem all APPS are bundled as an x20-dependency and then copied
-# to WORKING_DIR. To make it easier to update the app-bundle, remove the folder
-# WORKING_DIR and then run run_on_as_app.py --download-only.
+# to WORKING_DIR. To update the app-bundle use 'run_on_as_app_x20_packager.py'.
APPS = {
# 'app-name': {
# 'git_repo': ...
@@ -103,7 +102,7 @@
'app_id': 'io.rover.app.debug',
'app_module': 'debug-app',
'git_repo': 'https://github.com/mkj-gram/rover-android.git',
- 'revision': 'd2e876e597b3af7eab406e38a0e08327a38bd942',
+ 'revision': '859af82ba56fe9035ae9949156c7a88e6012d930',
},
'Signal-Android': {
'app_id': 'org.thoughtcrime.securesms',
@@ -111,7 +110,7 @@
'flavor': 'play',
'git_repo': 'https://github.com/mkj-gram/Signal-Android.git',
'main_dex_rules': 'multidex-config.pro',
- 'revision': '85e1a10993e5e9ffe923f0798b26cbc44068ba31',
+ 'revision': 'a45d0c1fed20fa39e8b9445fe7790326f46b3166',
'releaseTarget': 'assemblePlayRelease',
'signed-apk-name': 'Signal-play-release-4.32.7.apk',
},
@@ -215,14 +214,14 @@
def IsTrackedByGit(file):
return subprocess.check_output(['git', 'ls-files', file]).strip() != ''
-def GitClone(git_url, revision, checkout_dir, options):
+def GitClone(git_url, revision, checkout_dir, quiet):
result = subprocess.check_output(
['git', 'clone', git_url, checkout_dir]).strip()
head_rev = utils.get_HEAD_sha1_for_checkout(checkout_dir)
if revision == head_rev:
return result
warn('Target revision is not head in {}.'.format(checkout_dir))
- with utils.ChangedWorkingDirectory(checkout_dir, quiet=options.quiet):
+ with utils.ChangedWorkingDirectory(checkout_dir, quiet=quiet):
subprocess.check_output(['git', 'reset', '--hard', revision])
return result
@@ -290,7 +289,8 @@
if not os.path.exists(checkout_dir) and not options.golem:
with utils.ChangedWorkingDirectory(WORKING_DIR, quiet=options.quiet):
- GitClone(config['git_repo'], config['revision'], checkout_dir, options)
+ GitClone(
+ config['git_repo'], config['revision'], checkout_dir, options.quiet)
checkout_rev = utils.get_HEAD_sha1_for_checkout(checkout_dir)
if config['revision'] != checkout_rev:
@@ -365,7 +365,12 @@
# Sanity check that keep rules have changed.
with open(ext_proguard_config_file) as new:
with open(proguard_config_file) as old:
- assert(sum(1 for line in new) > sum(1 for line in old))
+ assert(
+ sum(1 for line in new
+ if line.strip() and '-printconfiguration' not in line)
+ >
+ sum(1 for line in old
+ if line.strip() and '-printconfiguration' not in line))
# Extract min-sdk and target-sdk
(min_sdk, compile_sdk) = as_utils.GetMinAndCompileSdk(app, config,
@@ -748,13 +753,13 @@
options.shrinker.remove('r8-nolib-full')
return (options, args)
-def download_apps(options):
+def download_apps(quiet):
# Download apps and place in build
with utils.ChangedWorkingDirectory(WORKING_DIR):
for app, config in APPS.iteritems():
app_dir = os.path.join(WORKING_DIR, app)
if not os.path.exists(app_dir):
- GitClone(config['git_repo'], config['revision'], app_dir, options)
+ GitClone(config['git_repo'], config['revision'], app_dir, quiet)
def main(argv):
@@ -770,7 +775,7 @@
os.makedirs(WORKING_DIR)
if options.download_only:
- download_apps(options)
+ download_apps(options.quiet)
return
with utils.TempDir() as temp_dir:
diff --git a/tools/run_on_as_app_x20_packager.py b/tools/run_on_as_app_x20_packager.py
new file mode 100755
index 0000000..5c84626
--- /dev/null
+++ b/tools/run_on_as_app_x20_packager.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# Copyright (c) 2019, 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.
+
+import os
+import run_on_as_app
+import shutil
+import sys
+import upload_to_x20
+import utils
+
+def main():
+ # We need prodaccess to upload to x20
+ utils.check_prodacces()
+
+ working_dir = run_on_as_app.WORKING_DIR
+
+ print 'Removing directories that do not match checked out revision'
+ with utils.ChangedWorkingDirectory(working_dir):
+ for app, config in run_on_as_app.APPS.iteritems():
+ app_dir = os.path.join(working_dir, app)
+ if os.path.exists(app_dir) \
+ and utils.get_HEAD_sha1_for_checkout(app_dir) != config['revision']:
+ print 'Removing %s' % app_dir
+ shutil.rmtree(app_dir)
+
+ print 'Downloading all missing apps'
+ run_on_as_app.download_apps(quiet=False)
+
+ # Package all files as x20 dependency
+ parent_dir = os.path.dirname(working_dir)
+ with utils.ChangedWorkingDirectory(parent_dir):
+ print 'Creating archive for opensource_apps (this may take some time)'
+ working_dir_name = os.path.basename(working_dir)
+ app_dirs = [working_dir_name + '/' + name
+ for name in run_on_as_app.APPS.keys()]
+ filename = utils.create_archive("opensource_apps", app_dirs)
+ sha1 = utils.get_sha1(filename)
+ dest = os.path.join(upload_to_x20.GMSCORE_DEPS, sha1)
+ upload_to_x20.uploadFile(filename, dest)
+ sha1_file = '%s.sha1' % filename
+ with open(sha1_file, 'w') as output:
+ output.write(sha1)
+ shutil.move(sha1_file,
+ os.path.join(utils.THIRD_PARTY, 'opensource_apps.tar.gz.sha1'))
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/utils.py b/tools/utils.py
index 892fe7d..f6e0a70 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -271,9 +271,13 @@
subprocess.check_call(cmd)
def create_archive(name):
+ return create_archive(name, [name])
+
+def create_archive(name, sources):
tarname = '%s.tar.gz' % name
with tarfile.open(tarname, 'w:gz') as tar:
- tar.add(name)
+ for source in sources:
+ tar.add(source)
return tarname
def extract_dir(filename):
@@ -288,6 +292,9 @@
with tarfile.open(filename, 'r:gz') as tar:
tar.extractall(path=dirname)
+def check_prodacces():
+ subprocess.check_call(['prodaccess'])
+
# Note that gcs is eventually consistent with regards to list operations.
# This is not a problem in our case, but don't ever use this method
# for synchronization.