Keep debug related information in R8 debug mode.
Bug: 202486757
Change-Id: Id332b953505c2e6fc8e8edeb5f11bbaad7122f99
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index bb22da1..c9ffe03 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -528,6 +528,11 @@
}
});
+ if (getMode() == CompilationMode.DEBUG) {
+ disableMinification = true;
+ configurationBuilder.disableOptimization();
+ }
+
if (disableTreeShaking) {
configurationBuilder.disableShrinking();
}
@@ -823,10 +828,8 @@
@Override
InternalOptions getInternalOptions() {
- InternalOptions internal = new InternalOptions(proguardConfiguration, getReporter());
+ InternalOptions internal = new InternalOptions(getMode(), proguardConfiguration, getReporter());
assert !internal.testing.allowOutlinerInterfaceArrayArguments; // Only allow in tests.
- assert !internal.debug;
- internal.debug = getMode() == CompilationMode.DEBUG;
internal.programConsumer = getProgramConsumer();
internal.minApiLevel = AndroidApiLevel.getAndroidApiLevel(getMinApiLevel());
internal.desugarState = getDesugarState();
@@ -835,40 +838,26 @@
assert !internal.ignoreMissingClasses;
internal.ignoreMissingClasses =
proguardConfiguration.isIgnoreWarnings()
- // TODO(70706667): We probably only want this in Proguard compatibility mode.
|| (forceProguardCompatibility
- && !proguardConfiguration.isOptimizing()
+ && !internal.isOptimizing()
&& !internal.isShrinking()
&& !internal.isMinifying());
assert !internal.verbose;
internal.mainDexKeepRules = mainDexKeepRules;
- internal.minimalMainDex = getMode() == CompilationMode.DEBUG;
+ internal.minimalMainDex = internal.debug;
internal.mainDexListConsumer = getMainDexListConsumer();
internal.lineNumberOptimization =
- !internal.debug && (proguardConfiguration.isOptimizing() || internal.isMinifying())
+ (internal.isOptimizing() || internal.isMinifying())
? LineNumberOptimization.ON
: LineNumberOptimization.OFF;
HorizontalClassMergerOptions horizontalClassMergerOptions =
internal.horizontalClassMergerOptions();
- assert proguardConfiguration.isOptimizing()
- || horizontalClassMergerOptions.isRestrictedToSynthetics();
+ assert internal.isOptimizing() || horizontalClassMergerOptions.isRestrictedToSynthetics();
assert !internal.enableTreeShakingOfLibraryMethodOverrides;
- assert internal.enableVerticalClassMerging || !proguardConfiguration.isOptimizing();
- if (internal.debug) {
- internal.getProguardConfiguration().getKeepAttributes().lineNumberTable = true;
- internal.getProguardConfiguration().getKeepAttributes().localVariableTable = true;
- internal.getProguardConfiguration().getKeepAttributes().localVariableTypeTable = true;
- internal.enableInlining = false;
- internal.enableClassInlining = false;
- internal.enableVerticalClassMerging = false;
- internal.enableClassStaticizer = false;
- internal.outline.enabled = false;
- internal.enableEnumUnboxing = false;
- internal.callSiteOptimizationOptions().disableOptimization();
- }
+ assert internal.enableVerticalClassMerging || !internal.isOptimizing();
if (!internal.isShrinking()) {
// If R8 is not shrinking, there is no point in running various optimizations since the
diff --git a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
index aea3e82..7c7e1d4 100644
--- a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
+++ b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
@@ -144,7 +145,12 @@
// We are using the proguard configuration for adapting resources.
InternalOptions options =
new InternalOptions(
+ // Set debug to ensure that we are writing all information to the application writer.
+ CompilationMode.DEBUG,
ProguardConfiguration.builder(factory, getReporter())
+ .disableShrinking()
+ .disableObfuscation()
+ .disableOptimization()
.addKeepAttributePatterns(ImmutableList.of("*"))
.addAdaptResourceFilenames(ProguardPathList.builder().addFileName("**").build())
.build(),
@@ -154,8 +160,6 @@
options.programConsumer = consumer;
assert consumer != null;
options.dataResourceConsumer = consumer.getDataResourceConsumer();
- // Set debug to ensure that we are writing all information to the application writer.
- options.debug = true;
return options;
}
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 9d2657a..28a7c30 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -179,25 +179,41 @@
}
// Constructor for R8.
- public InternalOptions(ProguardConfiguration proguardConfiguration, Reporter reporter) {
+ public InternalOptions(
+ CompilationMode mode, ProguardConfiguration proguardConfiguration, Reporter reporter) {
assert reporter != null;
assert proguardConfiguration != null;
+ this.debug = mode == CompilationMode.DEBUG;
this.reporter = reporter;
this.proguardConfiguration = proguardConfiguration;
itemFactory = proguardConfiguration.getDexItemFactory();
enableTreeShaking = proguardConfiguration.isShrinking();
enableMinification = proguardConfiguration.isObfuscating();
- // TODO(b/171457102): Avoid the need for this.
- // -dontoptimize disables optimizations by flipping related flags.
if (!proguardConfiguration.isOptimizing()) {
+ // TODO(b/171457102): Avoid the need for this.
+ // -dontoptimize disables optimizations by flipping related flags.
disableAllOptimizations();
}
+ if (debug) {
+ assert !isMinifying();
+ assert !isOptimizing();
+ keepDebugRelatedInformation();
+ }
configurationDebugging = proguardConfiguration.isConfigurationDebugging();
if (proguardConfiguration.isProtoShrinkingEnabled()) {
enableProtoShrinking();
}
}
+ private void keepDebugRelatedInformation() {
+ assert !proguardConfiguration.isObfuscating();
+ getProguardConfiguration().getKeepAttributes().sourceFile = true;
+ getProguardConfiguration().getKeepAttributes().sourceDebugExtension = true;
+ getProguardConfiguration().getKeepAttributes().lineNumberTable = true;
+ getProguardConfiguration().getKeepAttributes().localVariableTable = true;
+ getProguardConfiguration().getKeepAttributes().localVariableTypeTable = true;
+ }
+
void enableProtoShrinking() {
applyInliningToInlinee = true;
enableFieldBitAccessAnalysis = true;
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index e3c86ad..21113a9 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -766,7 +766,9 @@
return builder.build();
};
}
- InternalOptions options = new InternalOptions(keepConfig.apply(dexItemFactory), new Reporter());
+ InternalOptions options =
+ new InternalOptions(
+ CompilationMode.RELEASE, keepConfig.apply(dexItemFactory), new Reporter());
if (optionsConsumer != null) {
optionsConsumer.accept(options);
}
diff --git a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
index dbaa9c9..be7b225 100644
--- a/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
@@ -352,6 +352,10 @@
return addKeepAttributes(ProguardKeepAttributes.LINE_NUMBER_TABLE);
}
+ public T addKeepAttributeLocalVariableTable() {
+ return addKeepAttributes(ProguardKeepAttributes.LOCAL_VARIABLE_TABLE);
+ }
+
public T addKeepAttributeSignature() {
return addKeepAttributes(ProguardKeepAttributes.SIGNATURE);
}
diff --git a/src/test/java/com/android/tools/r8/debug/MinificationTest.java b/src/test/java/com/android/tools/r8/debug/MinificationTest.java
deleted file mode 100644
index b42d7fa..0000000
--- a/src/test/java/com/android/tools/r8/debug/MinificationTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (c) 2017, 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.debug;
-
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.OutputMode;
-import com.android.tools.r8.R8Command;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.debug.DebugTestConfig.RuntimeKind;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-/** Tests renaming of class and method names and corresponding proguard map output. */
-@RunWith(Parameterized.class)
-public class MinificationTest extends DebugTestBase {
-
- private static final String SOURCE_FILE = "Minified.java";
-
- @Parameterized.Parameters(name = "backend:{0} minification:{1} proguardMap:{2}")
- public static Collection minificationControl() {
- ImmutableList.Builder<Object> builder = ImmutableList.builder();
- for (RuntimeKind kind : RuntimeKind.values()) {
- for (MinifyMode mode : MinifyMode.values()) {
- builder.add((Object) new Object[] {kind, mode, false});
- if (mode.isMinify()) {
- builder.add((Object) new Object[] {kind, mode, true});
- }
- }
- }
- return builder.build();
- }
-
- @Rule
- public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
-
- private final RuntimeKind runtimeKind;
- private final MinifyMode minificationMode;
- private final boolean writeProguardMap;
-
- public MinificationTest(
- RuntimeKind runtimeKind, MinifyMode minificationMode, boolean writeProguardMap) {
- this.runtimeKind = runtimeKind;
- this.minificationMode = minificationMode;
- this.writeProguardMap = writeProguardMap;
- }
-
- private boolean minifiedNames() {
- return minificationMode.isMinify() && !writeProguardMap;
- }
-
- private DebugTestConfig getTestConfig() throws Throwable {
- List<String> proguardConfigurations = Collections.emptyList();
- ImmutableList.Builder<String> proguardConfigurationBuilder = ImmutableList.builder();
- if (!minificationMode.isMinify()) {
- proguardConfigurationBuilder.add("-dontobfuscate");
- } else if (minificationMode.isAggressive()) {
- proguardConfigurationBuilder.add("-overloadaggressively");
- }
- proguardConfigurationBuilder.add(
- "-keep public class Minified { public static void main(java.lang.String[]); }");
- proguardConfigurationBuilder.add("-keepattributes SourceFile");
- proguardConfigurationBuilder.add("-keepattributes LineNumberTable");
- proguardConfigurations = proguardConfigurationBuilder.build();
-
- Path outputPath = temp.getRoot().toPath().resolve("classes.zip");
- Path proguardMap = writeProguardMap ? temp.getRoot().toPath().resolve("proguard.map") : null;
- OutputMode outputMode =
- runtimeKind == RuntimeKind.CF ? OutputMode.ClassFile : OutputMode.DexIndexed;
- R8Command.Builder builder =
- R8Command.builder()
- .addProgramFiles(DEBUGGEE_JAR)
- .setOutput(outputPath, outputMode)
- .setMode(CompilationMode.DEBUG);
- if (runtimeKind == RuntimeKind.DEX) {
- AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
- builder.setMinApiLevel(minSdk.getLevel()).addLibraryFiles(ToolHelper.getAndroidJar(minSdk));
- } else if (runtimeKind == RuntimeKind.CF) {
- builder.addLibraryFiles(ToolHelper.getJava8RuntimeJar());
- }
- if (proguardMap != null) {
- builder.setProguardMapOutputPath(proguardMap);
- }
- if (!proguardConfigurations.isEmpty()) {
- builder.addProguardConfiguration(proguardConfigurations, Origin.unknown());
- }
- // Disable line number optimization if we're not using a Proguard map.
- ToolHelper.runR8(
- builder.build(),
- proguardMap == null
- ? (oc -> oc.lineNumberOptimization = LineNumberOptimization.OFF)
- : null);
-
- switch (runtimeKind) {
- case CF:
- {
- CfDebugTestConfig config = new CfDebugTestConfig(outputPath);
- config.setProguardMap(proguardMap);
- return config;
- }
- case DEX:
- {
- DexDebugTestConfig config = new DexDebugTestConfig(outputPath);
- config.setProguardMap(proguardMap);
- return config;
- }
- default:
- throw new Unreachable();
- }
- }
-
- @Test
- public void testBreakInMainClass() throws Throwable {
- final String className = "Minified";
- final String methodName = minifiedNames() ? "a" : "test";
- final String signature = "()V";
- final String innerClassName = minifiedNames() ? "a" : "Minified$Inner";
- final String innerMethodName = minifiedNames() ? "a" : "innerTest";
- final String innerSignature = "()I";
- DebugTestConfig config = getTestConfig();
- checkStructure(
- config,
- className,
- MethodSignature.fromSignature(methodName, signature),
- innerClassName,
- MethodSignature.fromSignature(innerMethodName, innerSignature));
- runDebugTest(
- config,
- className,
- breakpoint(className, methodName, signature),
- run(),
- checkMethod(className, methodName, signature),
- checkLine(SOURCE_FILE, 14),
- stepOver(INTELLIJ_FILTER),
- checkMethod(className, methodName, signature),
- checkLine(SOURCE_FILE, 15),
- stepInto(INTELLIJ_FILTER),
- checkMethod(innerClassName, innerMethodName, innerSignature),
- checkLine(8),
- run());
- }
-
- @Test
- public void testBreakInPossiblyRenamedClass() throws Throwable {
- final String className = "Minified";
- final String innerClassName = minifiedNames() ? "a" : "Minified$Inner";
- final String innerMethodName = minifiedNames() ? "a" : "innerTest";
- final String innerSignature = "()I";
- DebugTestConfig config = getTestConfig();
- checkStructure(
- config,
- className,
- innerClassName,
- MethodSignature.fromSignature(innerMethodName, innerSignature));
- runDebugTest(
- config,
- className,
- breakpoint(innerClassName, innerMethodName, innerSignature),
- run(),
- checkMethod(innerClassName, innerMethodName, innerSignature),
- checkLine(8),
- run());
- }
-
- private void checkStructure(
- DebugTestConfig config,
- String className,
- MethodSignature method,
- String innerClassName,
- MethodSignature innerMethod)
- throws Throwable {
- Path proguardMap = config.getProguardMap();
- String mappingFile = proguardMap == null ? null : proguardMap.toString();
- CodeInspector inspector = new CodeInspector(config.getPaths(), mappingFile, null);
- ClassSubject clazz = inspector.clazz(className);
- assertTrue(clazz.isPresent());
- if (method != null) {
- assertTrue(clazz.method(method).isPresent());
- }
- ClassSubject innerClass = inspector.clazz(innerClassName);
- assertTrue(innerClass.isPresent());
- assertTrue(innerClass.method(innerMethod).isPresent());
- }
-
- private void checkStructure(
- DebugTestConfig config, String className, String innerClassName, MethodSignature innerMethod)
- throws Throwable {
- checkStructure(config, className, null, innerClassName, innerMethod);
- }
-}
diff --git a/src/test/java/com/android/tools/r8/ir/InlineTest.java b/src/test/java/com/android/tools/r8/ir/InlineTest.java
index 909a929..6f5d826 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.ToolHelper.getMostRecentAndroidJar;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -93,7 +94,8 @@
Reporter reporter = new Reporter();
ProguardConfiguration proguardConfiguration =
ProguardConfiguration.builder(new DexItemFactory(), reporter).build();
- InternalOptions options = new InternalOptions(proguardConfiguration, reporter);
+ InternalOptions options =
+ new InternalOptions(CompilationMode.RELEASE, proguardConfiguration, reporter);
options.programConsumer = DexIndexedConsumer.emptyConsumer();
return options;
}
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index 116ce4a..df6d1a5 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -170,7 +170,9 @@
"-keep class " + CLASS_NAME,
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
"-dontoptimize");
- CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
+ CodeInspector inspector =
+ compileWithR8(builder, testBuilder -> testBuilder.debug().addKeepRules(pgConfigs))
+ .inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -373,6 +375,7 @@
builder,
testBuilder ->
testBuilder
+ .addDontOptimize()
.addKeepRules(
"-identifiernamestring class "
+ CLASS_NAME
@@ -420,9 +423,11 @@
"invoke-static {v1}, LExample;->foo(Ljava/lang/String;)V",
"return-void");
- List<String> pgConfigs = ImmutableList.of(
- "-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
- "-keep class " + CLASS_NAME);
+ List<String> pgConfigs =
+ ImmutableList.of(
+ "-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
+ "-keep class " + CLASS_NAME,
+ "-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
@@ -465,10 +470,12 @@
"return-void");
builder.addClass(BOO);
- List<String> pgConfigs = ImmutableList.of(
- "-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
- "-keep class " + CLASS_NAME,
- "-keep,allowobfuscation class " + BOO);
+ List<String> pgConfigs =
+ ImmutableList.of(
+ "-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
+ "-keep class " + CLASS_NAME,
+ "-keep,allowobfuscation class " + BOO,
+ "-dontoptimize");
CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
@@ -725,7 +732,6 @@
return testForR8(Backend.DEX)
.addProgramDexFileData(builder.compile())
.apply(configuration)
- .debug()
.compile();
}
}
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageDebugMinificationTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageDebugMinificationTest.java
index fe19640..23a5047 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageDebugMinificationTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageDebugMinificationTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.repackage;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndNotRenamed;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -70,7 +69,7 @@
MethodSubject main = mainClass.uniqueMethodWithName("main");
assertThat(main, isPresentAndNotRenamed());
ClassSubject aClass = inspector.clazz(A.class);
- assertThat(aClass, isPresentAndRenamed());
+ assertThat(aClass, isPresentAndNotRenamed());
LocalVariableTable localVariableTable = main.getLocalVariableTable();
// Take the second index which is localValue
assertEquals(2, localVariableTable.size());