Remove DexApplication#toDirect

This removes DexApplication#toDirect so that it is now only possible to call toDirect on a LazyLoadedDexApplication.

During compilation it should always be known which type of app we have, and thus we should never be in a situation where calling toDirect() on a DirectMappedDexApplication should be needed.

Change-Id: Ic6a077fa978b4fe88a438a7539e0e58e75afd5c0
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 2393dab..5e116de 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -284,7 +284,8 @@
         // without iterating again the IR. We fall-back to writing one app with rewriting and
         // merging it with the other app in rewriteNonDexInputs.
         timing.begin("Rewrite non-dex inputs");
-        DexApplication app = rewriteNonDexInputs(appView, inputApp, executor, marker, timing);
+        LazyLoadedDexApplication app =
+            rewriteNonDexInputs(appView, inputApp, executor, marker, timing);
         timing.end();
         appView.rebuildAppInfo(app);
         appView.setNamingLens(NamingLens.getIdentityLens());
@@ -404,7 +405,7 @@
         "Api reference stubber", () -> new ApiReferenceStubber(appView).run(executorService));
   }
 
-  private static DexApplication rewriteNonDexInputs(
+  private static LazyLoadedDexApplication rewriteNonDexInputs(
       AppView<AppInfo> appView,
       AndroidApp inputApp,
       ExecutorService executor,
@@ -440,9 +441,9 @@
     builder.getProgramResourceProviders().clear();
     builder.addProgramResourceProvider(convertedCfFiles);
     AndroidApp newAndroidApp = builder.build();
-    DexApplication newApp =
+    LazyLoadedDexApplication newApp =
         new ApplicationReader(newAndroidApp, appView.options(), timing).read(executor);
-    DexApplication.Builder<?> finalDexApp = newApp.builder();
+    LazyLoadedDexApplication.Builder finalDexApp = newApp.builder();
     for (DexProgramClass dexProgramClass : dexProgramClasses) {
       finalDexApp.addProgramClass(dexProgramClass);
     }
diff --git a/src/main/java/com/android/tools/r8/Disassemble.java b/src/main/java/com/android/tools/r8/Disassemble.java
index 7ddbafb..a800696 100644
--- a/src/main/java/com/android/tools/r8/Disassemble.java
+++ b/src/main/java/com/android/tools/r8/Disassemble.java
@@ -5,9 +5,9 @@
 
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.graph.AssemblyWriter;
-import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexByteCodeWriter;
 import com.android.tools.r8.graph.DexByteCodeWriter.OutputStreamProvider;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.graph.SmaliWriter;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.origin.CommandLineOrigin;
@@ -351,7 +351,7 @@
       throws IOException {
     ExecutorService executor = ThreadUtils.getExecutorService(options);
     try {
-      DexApplication application =
+      LazyLoadedDexApplication application =
           new ApplicationReader(
                   AndroidApp.builder()
                       .addProgramResourceProvider(() -> Collections.singletonList(programResource))
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 50ad4cd..a2d7fef 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -12,10 +12,10 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppServices;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ImmediateAppSubtypingInfo;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.keepanno.annotations.KeepForApi;
 import com.android.tools.r8.profile.rewriting.ProfileCollectionAdditions;
 import com.android.tools.r8.shaking.Enqueuer;
@@ -48,7 +48,7 @@
   private void run(AndroidApp app, ExecutorService executor, SortingStringConsumer consumer)
       throws IOException {
     try {
-      DexApplication application =
+      LazyLoadedDexApplication application =
           new ApplicationReader(app, options, Timing.empty()).read(executor);
       traceMainDexForGenerateMainDexList(executor, application)
           .forEach(type -> consumer.accept(type.toBinaryName() + ".class", options.reporter));
@@ -62,12 +62,12 @@
       throws ExecutionException {
     return traceMainDex(
         AppView.createForD8MainDexTracing(
-            appView.app().toDirect(), appView.appInfo().getMainDexInfo()),
+            appView.app().asLazy().toDirect(), appView.appInfo().getMainDexInfo()),
         executor);
   }
 
   public MainDexInfo traceMainDexForGenerateMainDexList(
-      ExecutorService executor, DexApplication application) throws ExecutionException {
+      ExecutorService executor, LazyLoadedDexApplication application) throws ExecutionException {
     return traceMainDex(AppView.createForR8(application.toDirect()), executor);
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java b/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
index 40c2ff0..38264ec 100644
--- a/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
+++ b/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
@@ -43,7 +43,7 @@
   private final RetracerForCodePrinting retracer;
 
   public AssemblyWriter(
-      DexApplication application,
+      LazyLoadedDexApplication application,
       InternalOptions options,
       boolean allInfo,
       boolean writeIR,
@@ -52,7 +52,7 @@
   }
 
   public AssemblyWriter(
-      DexApplication application,
+      LazyLoadedDexApplication application,
       InternalOptions options,
       boolean allInfo,
       boolean writeIR,
diff --git a/src/main/java/com/android/tools/r8/graph/DexApplication.java b/src/main/java/com/android/tools/r8/graph/DexApplication.java
index 2c41285..dde97f9 100644
--- a/src/main/java/com/android/tools/r8/graph/DexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DexApplication.java
@@ -7,7 +7,6 @@
 package com.android.tools.r8.graph;
 
 import com.android.tools.r8.DataResourceProvider;
-import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.timing.Timing;
@@ -252,11 +251,14 @@
   }
 
   public DirectMappedDexApplication asDirect() {
-    throw new Unreachable("Cannot use a LazyDexApplication where a DirectDexApplication is"
-        + " expected.");
+    return null;
   }
 
-  public abstract DirectMappedDexApplication toDirect();
+  public boolean isDirect() {
+    return false;
+  }
 
-  public abstract boolean isDirect();
+  public LazyLoadedDexApplication asLazy() {
+    return null;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
index 3f654fa..4ac87e6 100644
--- a/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/DirectMappedDexApplication.java
@@ -131,11 +131,6 @@
   }
 
   @Override
-  public DirectMappedDexApplication toDirect() {
-    return this;
-  }
-
-  @Override
   public boolean isDirect() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
index a4cc5a7..9c29a82 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyLoadedDexApplication.java
@@ -370,13 +370,12 @@
   }
 
   @Override
-  public DirectMappedDexApplication toDirect() {
-    return new DirectMappedDexApplication.Builder(this).build().asDirect();
+  public LazyLoadedDexApplication asLazy() {
+    return this;
   }
 
-  @Override
-  public boolean isDirect() {
-    return false;
+  public DirectMappedDexApplication toDirect() {
+    return new DirectMappedDexApplication.Builder(this).build();
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
index 35d8ff3..bc3be29 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/lint/SupportedClassesGenerator.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.FieldResolutionResult;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.MethodResolutionResult;
 import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
@@ -503,7 +504,7 @@
     ExecutorService executorService = ThreadUtils.getExecutorService(options);
     assert !options.ignoreJavaLibraryOverride;
     options.ignoreJavaLibraryOverride = true;
-    DexApplication appForMax = applicationReader.read(executorService);
+    LazyLoadedDexApplication appForMax = applicationReader.read(executorService);
     options.ignoreJavaLibraryOverride = false;
     DexClass varHandle =
         appForMax.definitionFor(
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
index 5906b9f..61362ac 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
@@ -184,7 +184,7 @@
           desugaredOutputClasses.add(clazz);
         }
       }
-      DirectMappedDexApplication app = appView.app().toDirect();
+      DirectMappedDexApplication app = appView.app().asLazy().toDirect();
       outputClasspathClasses = app.classpathClasses();
       outputLibraryClasses = app.libraryClasses();
       startupProfile = appView.getStartupProfile();
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
index b690ee9..4fc37c5 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
@@ -119,6 +119,7 @@
     DirectMappedDexApplication finalApp =
         inspector
             .getApplication()
+            .asLazy()
             .toDirect()
             .builder()
             .replaceLibraryClasses(libHolder.libraryClasses())
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 efbccf0..5058af1 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.ImmediateAppSubtypingInfo;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
@@ -463,7 +464,8 @@
         application, options, methodSubject, ImmutableList.of(codeA, codeB));
   }
 
-  protected DexApplication buildApplication(SmaliBuilder builder, InternalOptions options) {
+  protected LazyLoadedDexApplication buildApplication(
+      SmaliBuilder builder, InternalOptions options) {
     try {
       AndroidApp app =
           AndroidApp.builder()
diff --git a/src/test/testbase/java/com/android/tools/r8/TestBase.java b/src/test/testbase/java/com/android/tools/r8/TestBase.java
index 17ba25b..4fe4ad3 100644
--- a/src/test/testbase/java/com/android/tools/r8/TestBase.java
+++ b/src/test/testbase/java/com/android/tools/r8/TestBase.java
@@ -34,7 +34,6 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppServices;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
@@ -45,6 +44,7 @@
 import com.android.tools.r8.graph.GenericSignature;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
 import com.android.tools.r8.graph.ImmediateAppSubtypingInfo;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.SmaliWriter;
 import com.android.tools.r8.jasmin.JasminBuilder;
@@ -898,8 +898,8 @@
     return newJar;
   }
 
-  private static DexApplication readApplicationForDexOutput(AndroidApp app, InternalOptions options)
-      throws Exception {
+  private static LazyLoadedDexApplication readApplicationForDexOutput(
+      AndroidApp app, InternalOptions options) throws Exception {
     assert options.programConsumer == null;
     options.programConsumer = DexIndexedConsumer.emptyConsumer();
     return new ApplicationReader(app, options, Timing.empty()).read();
@@ -959,7 +959,7 @@
     if (optionsConsumer != null) {
       optionsConsumer.accept(options);
     }
-    DexApplication dexApplication = readApplicationForDexOutput(app, options);
+    LazyLoadedDexApplication dexApplication = readApplicationForDexOutput(app, options);
     AppView<AppInfoWithClassHierarchy> appView = AppView.createForR8(dexApplication.toDirect());
     appView.setAppServices(AppServices.builder(appView).build());
     return appView;
diff --git a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
index 7ecd693..e929946 100644
--- a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
@@ -29,6 +29,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.shaking.FilteredClassPath;
@@ -2704,8 +2705,8 @@
   }
 
   public static void disassemble(AndroidApp app, PrintStream ps) throws IOException {
-    DexApplication application =
-        new ApplicationReader(app, new InternalOptions(), Timing.empty()).read().toDirect();
+    LazyLoadedDexApplication application =
+        new ApplicationReader(app, new InternalOptions(), Timing.empty()).read();
     new AssemblyWriter(application, new InternalOptions(), true, false, true).write(ps);
   }