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());