Revert "Don't read DEX code from archives in any R8 compilation."

This reverts commit 893e91c0deb098a1c8db518e49ca980bbd8c9c1b.

Reason for revert: Breaks MainDexListTests

Change-Id: Ib1c78ec159d69ef48e4e3ad1d0e654ddfa2a3324
diff --git a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
index 80f679b..b638235 100644
--- a/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
+++ b/src/main/java/com/android/tools/r8/CompatProguardCommandBuilder.java
@@ -15,6 +15,7 @@
       boolean forceProguardCompatibility, DiagnosticsHandler diagnosticsHandler) {
     super(diagnosticsHandler);
     setProguardCompatibility(forceProguardCompatibility);
+    setIgnoreDexInArchive(true);
   }
 
   public CompatProguardCommandBuilder(boolean forceProguardCompatibility) {
@@ -25,5 +26,6 @@
       boolean forceProguardCompatibility, boolean disableVerticalClassMerging) {
     setProguardCompatibility(forceProguardCompatibility);
     setDisableVerticalClassMerging(disableVerticalClassMerging);
+    setIgnoreDexInArchive(true);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 1496f40..7923102 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -127,17 +127,14 @@
 
     Builder(DiagnosticsHandler diagnosticsHandler) {
       super(diagnosticsHandler);
-      setIgnoreDexInArchive(true);
     }
 
     private Builder(AndroidApp app) {
       super(app);
-      setIgnoreDexInArchive(true);
     }
 
     private Builder(AndroidApp app, DiagnosticsHandler diagnosticsHandler) {
       super(app, diagnosticsHandler);
-      setIgnoreDexInArchive(true);
     }
 
     // Internal
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index f375004..013a15b 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -22,7 +22,6 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestCompilerBuilder;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.references.Reference;
@@ -61,15 +60,16 @@
   private static final String EXAMPLE_SRC_DIR = ToolHelper.EXAMPLES_DIR;
   private static final String EXAMPLE_O_SRC_DIR = ToolHelper.EXAMPLES_ANDROID_O_DIR;
 
-  @Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withNoneRuntime().build();
+  @Parameters(name = "{0}, {1}")
+  public static List<Object[]> data() {
+    return buildParameters(getTestParameters().withNoneRuntime().build(), Backend.values());
   }
 
-  private final Backend backend = Backend.CF;
+  private final Backend backend;
 
-  public MainDexTracingTest(TestParameters parameters) {
+  public MainDexTracingTest(TestParameters parameters, Backend backend) {
     parameters.assertNoneRuntime();
+    this.backend = backend;
   }
 
   private Path getInputJar(Path cfJar) throws Exception {
diff --git a/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
new file mode 100644
index 0000000..67e965d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
@@ -0,0 +1,176 @@
+// 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.smali;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+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 RemoveWriteOfUnusedFieldsTest extends SmaliTestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDexRuntimes().build();
+  }
+
+  public RemoveWriteOfUnusedFieldsTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void unreadStaticFieldsRemoved() throws Exception {
+    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
+
+    // All these static fields are set but never read.
+    builder.addStaticField("booleanField", "Z");
+    builder.addStaticField("byteField", "B");
+    builder.addStaticField("shortField", "S");
+    builder.addStaticField("intField", "I");
+    builder.addStaticField("longField", "J");
+    builder.addStaticField("floatField", "F");
+    builder.addStaticField("doubleField", "D");
+    builder.addStaticField("charField", "C");
+    builder.addStaticField("objectField", "Ljava/lang/Object;");
+    builder.addStaticField("stringField", "Ljava/lang/String;");
+    builder.addStaticField("testField", "LTest;");
+
+    builder.addStaticMethod("void", "test", ImmutableList.of(),
+        2,
+        "const               v0, 0", // single non-float typed zero (ie, int type)
+        "sput-boolean        v0, LTest;->booleanField:Z",
+        "sput-byte           v0, LTest;->byteField:B",
+        "sput-char           v0, LTest;->charField:C",
+        "sput-short          v0, LTest;->shortField:S",
+        "sput                v0, LTest;->intField:I",
+        "const               v0, 0", // float typed zero
+        "sput                v0, LTest;->floatField:F",
+        "const               v0, 0", // reference typed null
+        "sput-object         v0, LTest;->objectField:Ljava/lang/Object;",
+        "sput-object         v0, LTest;->stringField:Ljava/lang/String;",
+        "sput-object         v0, LTest;->testField:LTest;",
+        "const-wide          v0, 0", // wide typed long
+        "sput-wide           v0, LTest;->longField:J",
+        "const-wide          v0, 0", // wide typed double
+        "sput-wide           v0, LTest;->doubleField:D",
+        "return-void");
+
+    builder.addMainMethod(
+        0,
+        "    invoke-static       { }, LTest;->test()V",
+        "    return-void                             ");
+
+    AndroidApp input =
+        AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+    Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+    input.writeToZip(inputPath, OutputMode.DexIndexed);
+    ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
+    testForR8(parameters.getBackend())
+        .addProgramFiles(inputPath)
+        .addKeepMainRule("Test")
+        .setMinApi(parameters.getRuntime())
+        .compile()
+        .inspect(
+            inspector -> {
+              MethodSubject method =
+                  inspector.clazz("Test").method("void", "test", ImmutableList.of());
+              assertThat(
+                  "Expected method to be removed entirely because it does not have side effects",
+                  method,
+                  not(isPresent()));
+            });
+  }
+
+  @Test
+  public void unreadInstanceFieldsRemoved() throws Exception {
+    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
+
+    // All these instance fields are set but never read.
+    builder.addInstanceField("booleanField", "Z");
+    builder.addInstanceField("byteField", "B");
+    builder.addInstanceField("shortField", "S");
+    builder.addInstanceField("intField", "I");
+    builder.addInstanceField("longField", "J");
+    builder.addInstanceField("floatField", "F");
+    builder.addInstanceField("doubleField", "D");
+    builder.addInstanceField("charField", "C");
+    builder.addInstanceField("objectField", "Ljava/lang/Object;");
+    builder.addInstanceField("stringField", "Ljava/lang/String;");
+    builder.addInstanceField("testField", "LTest;");
+
+    builder.addInstanceMethod("void", "test", ImmutableList.of(),
+        2,
+        "const               v0, 0",
+        "iput-boolean        v0, p0, LTest;->booleanField:Z",
+        "iput-byte           v0, p0, LTest;->byteField:B",
+        "iput-char           v0, p0, LTest;->charField:C",
+        "iput-short          v0, p0, LTest;->shortField:S",
+        "iput                v0, p0, LTest;->intField:I",
+        "const               v0, 0",
+        "iput                v0, p0, LTest;->floatField:F",
+        "const               v0, 0",
+        "iput-object         v0, p0, LTest;->objectField:Ljava/lang/Object;",
+        "iput-object         v0, p0, LTest;->stringField:Ljava/lang/String;",
+        "iput-object         v0, p0, LTest;->testField:LTest;",
+        "const-wide          v0, 0",
+        "iput-wide           v0, p0, LTest;->longField:J",
+        "const-wide          v0, 0",
+        "iput-wide           v0, p0, LTest;->doubleField:D",
+        "return-void");
+
+    builder.addInitializer(ImmutableList.of(), 0,
+        "invoke-direct {p0}, Ljava/lang/Object;-><init>()V",
+        "return-void"
+    );
+
+    builder.addMainMethod(
+        1,
+        "    new-instance         v0, LTest;",
+        "    invoke-direct        { v0 }, LTest;-><init>()V",
+        "    invoke-virtual       { v0 }, LTest;->test()V",
+        "    return-void                             ");
+
+    AndroidApp input =
+        AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+    Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+    input.writeToZip(inputPath, OutputMode.DexIndexed);
+    ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
+    testForR8(parameters.getBackend())
+        .addProgramFiles(inputPath)
+        .addKeepMainRule("Test")
+        .addKeepRules("-keep class Test { void test(); }")
+        .setMinApi(parameters.getRuntime())
+        .compile()
+        .inspect(
+            inspector -> {
+              MethodSubject method =
+                  inspector.clazz("Test").method("void", "test", ImmutableList.of());
+              DexCode code = method.getMethod().getCode().asDexCode();
+              assertTrue(code.isEmptyVoidMethod());
+            });
+  }
+}