Merge "Add initial luci files for bot move"
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 51f9de0..c0008dc 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.cf.FixedLocalValue;
import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -618,6 +619,13 @@
return realRegisterNumberFromAllocated(value.asFixedRegisterValue().getRegister());
}
LiveIntervals intervals = value.getLiveIntervals();
+ if (intervals == null) {
+ throw new CompilationError(
+ "Unexpected attempt to get register for a value without a register in method `"
+ + code.method.method.toSourceString()
+ + "`.",
+ code.origin);
+ }
if (intervals.hasSplits()) {
intervals = intervals.getSplitCovering(instructionNumber);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
index dc8925a..996f83f 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
@@ -386,24 +386,44 @@
wildcard = wildcards.get(wildcardIndex);
assert wildcard.isPattern();
wildcardPattern = wildcard.asPattern();
+
boolean includeSeparators = pattern.length() > (i + 1) && pattern.charAt(i + 1) == '*';
- int nextPatternIndex = i + (includeSeparators ? 2 : 1);
- // Fast cases for the common case where a pattern ends with '**' or '*'.
+ boolean includeAll =
+ includeSeparators && pattern.length() > (i + 2) && pattern.charAt(i + 2) == '*';
+ int nextPatternIndex = i + 1;
+ if (includeAll) {
+ nextPatternIndex += 2;
+ } else if (includeSeparators) {
+ nextPatternIndex += 1;
+ }
+
+ // Fast cases for the common case where a pattern ends with '*', '**', or '***'.
if (nextPatternIndex == pattern.length()) {
- wildcardPattern.setCaptured(name.substring(nameIndex, name.length()));
+ wildcardPattern.setCaptured(name.substring(nameIndex));
+ if (includeAll) {
+ return true;
+ }
if (includeSeparators) {
return kind == ClassOrType.CLASS || !isArrayType(name);
}
boolean hasSeparators = containsSeparatorsStartingAt(name, nameIndex);
return !hasSeparators && (kind == ClassOrType.CLASS || !isArrayType(name));
}
+
// Match the rest of the pattern against the (non-empty) rest of the class name.
for (int nextNameIndex = nameIndex; nextNameIndex < name.length(); nextNameIndex++) {
wildcardPattern.setCaptured(name.substring(nameIndex, nextNameIndex));
- if (!includeSeparators && name.charAt(nextNameIndex) == '.') {
- return matchClassOrTypeNameImpl(
- pattern, nextPatternIndex, name, nextNameIndex, wildcards, wildcardIndex + 1,
- kind);
+ if (!includeSeparators) {
+ if (name.charAt(nextNameIndex) == '.') {
+ return matchClassOrTypeNameImpl(
+ pattern,
+ nextPatternIndex,
+ name,
+ nextNameIndex,
+ wildcards,
+ wildcardIndex + 1,
+ kind);
+ }
}
if (kind == ClassOrType.TYPE && name.charAt(nextNameIndex) == '[') {
return matchClassOrTypeNameImpl(
@@ -416,11 +436,12 @@
return true;
}
}
- // Finally, check the case where the '*' or '**' eats all of the class name.
- wildcardPattern.setCaptured(name.substring(nameIndex, name.length()));
+
+ // Finally, check the case where the '*', '**', or '***' eats all of the class name.
+ wildcardPattern.setCaptured(name.substring(nameIndex));
return matchClassOrTypeNameImpl(
- pattern, nextPatternIndex, name, name.length(), wildcards, wildcardIndex + 1,
- kind);
+ pattern, nextPatternIndex, name, name.length(), wildcards, wildcardIndex + 1, kind);
+
case '?':
wildcard = wildcards.get(wildcardIndex);
assert wildcard.isPattern();
@@ -432,6 +453,7 @@
nameIndex++;
wildcardIndex++;
break;
+
case '<':
wildcard = wildcards.get(wildcardIndex);
assert wildcard.isBackReference();
@@ -446,6 +468,7 @@
wildcardIndex++;
i = pattern.indexOf(">", i);
break;
+
default:
if (nameIndex == name.length() || patternChar != name.charAt(nameIndex++)) {
return false;
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 659a8fc..37a0215 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
@@ -89,7 +89,7 @@
// Convince R8 we only use subtypes to get class merging of Foo into FooImpl.
Foo<String> foo = new FooImpl<>();
- System.out.println(foo.getClass().getTypeName());
+ System.out.println(foo.getClass().getCanonicalName());
}
}
diff --git a/src/test/java/com/android/tools/r8/proguard/rules/ProguardMatchAllRuleWithPrefixTest.java b/src/test/java/com/android/tools/r8/proguard/rules/ProguardMatchAllRuleWithPrefixTest.java
new file mode 100644
index 0000000..d5f456b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/proguard/rules/ProguardMatchAllRuleWithPrefixTest.java
@@ -0,0 +1,59 @@
+// 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.proguard.rules;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+
+/** Regression test for b/124584385. */
+public class ProguardMatchAllRuleWithPrefixTest extends TestBase {
+
+ @Test
+ public void test() throws Exception {
+ CodeInspector inspector =
+ testForR8(Backend.DEX)
+ .addProgramClasses(TestClass.class)
+ .addKeepRules(
+ "-keep,allowobfuscation class com.android.tools.r8.*** {",
+ " com.android.tools.r8.*** methodA();",
+ " com.android.tools.r8.***Class methodB();",
+ " com.android.tools.r8.***[] methodC();",
+ " com.android.tools.r8.***Class[] methodD();",
+ "}")
+ .compile()
+ .inspector();
+
+ ClassSubject classSubject = inspector.clazz(TestClass.class);
+ assertThat(classSubject, isPresent());
+ assertThat(classSubject.uniqueMethodWithName("methodA"), isPresent());
+ assertThat(classSubject.uniqueMethodWithName("methodB"), isPresent());
+ assertThat(classSubject.uniqueMethodWithName("methodC"), isPresent());
+ assertThat(classSubject.uniqueMethodWithName("methodD"), isPresent());
+ }
+
+ static class TestClass {
+
+ TestClass methodA() {
+ return new TestClass();
+ }
+
+ TestClass methodB() {
+ return new TestClass();
+ }
+
+ TestClass[] methodC() {
+ return new TestClass[0];
+ }
+
+ TestClass[] methodD() {
+ return new TestClass[0];
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index aa083da..f585226 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -321,6 +321,14 @@
return obfuscatedTypeName != null ? obfuscatedTypeName : originalTypeName;
}
+ String getOriginalTypeName(String minifiedTypeName) {
+ String originalTypeName = null;
+ if (mapping != null) {
+ originalTypeName = mapType(obfuscatedToOriginalMapping, minifiedTypeName);
+ }
+ return originalTypeName != null ? originalTypeName : minifiedTypeName;
+ }
+
InstructionSubject createInstructionSubject(Instruction instruction) {
DexInstructionSubject dexInst = new DexInstructionSubject(instruction);
if (dexInst.isInvoke()) {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 6581a47..dd7cd85 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -143,18 +143,14 @@
// X method(X) -> a
//
// whereas the final signature is for X.a is "a (a)"
- String[] OriginalParameters = new String[signature.parameters.length];
- for (int i = 0; i < OriginalParameters.length; i++) {
- String obfuscated = signature.parameters[i];
- String original = codeInspector.obfuscatedToOriginalMapping.get(obfuscated);
- OriginalParameters[i] = original != null ? original : obfuscated;
+ String[] originalParameters = new String[signature.parameters.length];
+ for (int i = 0; i < originalParameters.length; i++) {
+ originalParameters[i] = codeInspector.getOriginalTypeName(signature.parameters[i]);
}
- String obfuscatedReturnType = signature.type;
- String originalReturnType = codeInspector.obfuscatedToOriginalMapping.get(obfuscatedReturnType);
- String returnType = originalReturnType != null ? originalReturnType : obfuscatedReturnType;
+ String returnType = codeInspector.getOriginalTypeName(signature.type);
MethodSignature lookupSignature =
- new MethodSignature(signature.name, returnType, OriginalParameters);
+ new MethodSignature(signature.name, returnType, originalParameters);
MemberNaming memberNaming = clazz.naming.lookup(lookupSignature);
return memberNaming != null ? (MethodSignature) memberNaming.getOriginalSignature() : signature;
diff --git a/tools/as_utils.py b/tools/as_utils.py
index 817f7ed..363e1b9 100644
--- a/tools/as_utils.py
+++ b/tools/as_utils.py
@@ -47,6 +47,14 @@
'Unsupported gradle version: {} (must use at least gradle '
+ 'version 3.2)').format(gradle_version)
+def add_settings_gradle(checkout_dir, name):
+ settings_file = os.path.join(checkout_dir, 'settings.gradle')
+ if os.path.isfile(settings_file):
+ return
+
+ with open(settings_file, "w+") as f:
+ f.write("rootProject.name = '{}'\n".format(name))
+
def remove_r8_dependency(checkout_dir):
build_file = os.path.join(checkout_dir, 'build.gradle')
assert os.path.isfile(build_file), (
diff --git a/tools/run_on_as_app.py b/tools/run_on_as_app.py
index d6dd647..f3cc2eb 100755
--- a/tools/run_on_as_app.py
+++ b/tools/run_on_as_app.py
@@ -107,6 +107,7 @@
'app_module': '',
'flavor': 'play',
'git_repo': 'https://github.com/mkj-gram/Signal-Android.git',
+ 'main_dex_rules': 'multidex-config.pro',
'revision': '85e1a10993e5e9ffe923f0798b26cbc44068ba31',
'releaseTarget': 'assemblePlayRelease',
'signed-apk-name': 'Signal-play-release-4.32.7.apk',
@@ -353,6 +354,13 @@
# Now rebuild generated apk.
previous_apk = apk_dest
+
+ # We may need main dex rules when re-compiling with R8 as standalone.
+ main_dex_rules = None
+ if config.get('main_dex_rules'):
+ main_dex_rules = os.path.join(
+ checkout_dir, config.get('main_dex_rules'))
+
for i in range(1, options.r8_compilation_steps):
try:
recompiled_apk_dest = os.path.join(
@@ -360,7 +368,7 @@
RebuildAppWithShrinker(
app, previous_apk, recompiled_apk_dest,
ext_proguard_config_file, shrinker, min_sdk, compile_sdk,
- options, temp_dir)
+ options, temp_dir, main_dex_rules)
recompilation_result = {
'apk_dest': recompiled_apk_dest,
'build_status': 'success',
@@ -394,6 +402,11 @@
shrinker,
' for recompilation' if keepRuleSynthesisForRecompilation else ''))
+ # Add settings.gradle file if it is not present to prevent gradle from finding
+ # the settings.gradle file in the r8 root when apps are placed under
+ # $R8/build.
+ as_utils.add_settings_gradle(checkout_dir, app)
+
# Add 'r8.jar' from top-level build.gradle.
as_utils.add_r8_dependency(checkout_dir, temp_dir, IsMinifiedR8(shrinker))
@@ -478,7 +491,7 @@
def RebuildAppWithShrinker(
app, apk, apk_dest, proguard_config_file, shrinker, min_sdk, compile_sdk,
- options, temp_dir):
+ options, temp_dir, main_dex_rules):
assert 'r8' in shrinker
assert apk_dest.endswith('.apk')
@@ -502,6 +515,10 @@
cmd.append('--lib')
cmd.append(android_optional_jar)
+ if main_dex_rules:
+ cmd.append('--main-dex-rules')
+ cmd.append(main_dex_rules)
+
utils.RunCmd(cmd, quiet=options.quiet)
# Make a copy of the given APK, move the newly generated dex files into the