Create a collection class for synthetic items.

Bug: 158159959
Change-Id: I1719827d39020a3abeba594282cb883cb3c79729
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index e7b932d..bf2a37f 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -167,7 +167,7 @@
       DexApplication app = new ApplicationReader(inputApp, options, timing).read(executor);
       PrefixRewritingMapper rewritePrefix =
           options.desugaredLibraryConfiguration.createPrefixRewritingMapper(options);
-      AppInfo appInfo = new AppInfo(app);
+      AppInfo appInfo = AppInfo.createInitialAppInfo(app);
 
       final CfgPrinter printer = options.printCfg ? new CfgPrinter() : null;
 
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index 1171440..8e6c389 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -90,7 +90,7 @@
                     null,
                     executor,
                     new DexFileMergerHelper(inputOrdering)::keepFirstProgramClassConflictResolver);
-        AppInfo appInfo = new AppInfo(app);
+        AppInfo appInfo = AppInfo.createInitialAppInfo(app);
         app = D8.optimize(app, appInfo, options, timing, executor);
 
         List<Marker> markers = app.dexItemFactory.extractMarkers();
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index 8d2d47d..b7ece81 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -86,7 +86,7 @@
         assert !options.hasMethodsFilter();
 
         // Run d8 optimize to ensure jumbo strings are handled.
-        AppInfo appInfo = new AppInfo(featureApp);
+        AppInfo appInfo = AppInfo.createInitialAppInfo(featureApp);
         featureApp = D8.optimize(featureApp, appInfo, options, timing, executor);
         // We create a specific consumer for each split.
         Path outputDir = Paths.get(output).resolve(entry.getKey());
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index 7913783..2bfba83 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -311,7 +311,7 @@
         lintFile(compilationApiLevel, minApiLevel, ".txt"), desugaredApisSignatures);
 
     // Write a header jar with the desugared APIs.
-    AppInfo appInfo = new AppInfo(app);
+    AppInfo appInfo = AppInfo.createInitialAppInfo(app);
     AppView<?> appView = AppView.createForD8(appInfo);
     CfApplicationWriter writer =
         new CfApplicationWriter(
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 8049508..99a87d3 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -126,7 +126,7 @@
           options.desugaredLibraryConfiguration.createPrefixRewritingMapper(options);
 
       DexApplication app = new L8TreePruner(options).prune(lazyApp, rewritePrefix);
-      AppInfo appInfo = new AppInfo(app);
+      AppInfo appInfo = AppInfo.createInitialAppInfo(app);
 
       AppView<?> appView = AppView.createForL8(appInfo, rewritePrefix);
       IRConverter converter = new IRConverter(appView, timing);
diff --git a/src/main/java/com/android/tools/r8/PrintUses.java b/src/main/java/com/android/tools/r8/PrintUses.java
index 45ce043..35d0906 100644
--- a/src/main/java/com/android/tools/r8/PrintUses.java
+++ b/src/main/java/com/android/tools/r8/PrintUses.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.ResolutionResult;
+import com.android.tools.r8.graph.SyntheticItems;
 import com.android.tools.r8.graph.UseRegistry;
 import com.android.tools.r8.ir.desugar.LambdaDescriptor;
 import com.android.tools.r8.utils.AndroidApp;
@@ -361,7 +362,8 @@
     InternalOptions options = new InternalOptions();
     application =
         new ApplicationReader(inputApp, options, new Timing("PrintUses")).read().toDirect();
-    appInfo = new AppInfoWithClassHierarchy(application);
+    appInfo =
+        new AppInfoWithClassHierarchy(application, SyntheticItems.createInitialSyntheticItems());
   }
 
   private void analyze() {
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index ee67876..453b526 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -3,56 +3,49 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.graph;
 
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy.CreateDesugaringViewOnAppInfo;
 import com.android.tools.r8.graph.FieldResolutionResult.SuccessfulFieldResolutionResult;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.BooleanBox;
 import com.android.tools.r8.utils.InternalOptions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 public class AppInfo implements DexDefinitionSupplier {
 
   private final DexApplication app;
   private final DexItemFactory dexItemFactory;
-
-  // For some optimizations, e.g. optimizing synthetic classes, we may need to resolve the current
-  // class being optimized.
-  private final ConcurrentHashMap<DexType, DexProgramClass> synthesizedClasses;
+  private final SyntheticItems syntheticItems;
 
   // Set when a new AppInfo replaces a previous one. All public methods should verify that the
   // current instance is not obsolete, to ensure that we almost use the most recent AppInfo.
   private final BooleanBox obsolete;
 
-  public AppInfo(DexApplication application) {
-    this(application, new ConcurrentHashMap<>(), new BooleanBox());
+  public static AppInfo createInitialAppInfo(DexApplication application) {
+    return new AppInfo(application, SyntheticItems.createInitialSyntheticItems(), new BooleanBox());
   }
 
-  // For desugaring.
-  protected AppInfo(AppInfo appInfo) {
-    this(appInfo.app, appInfo.synthesizedClasses, appInfo.obsolete);
+  public AppInfo(DexApplication application, SyntheticItems syntheticItems) {
+    this(application, syntheticItems.commit(application), new BooleanBox());
   }
 
   // For AppInfoWithLiveness.
   protected AppInfo(AppInfoWithClassHierarchy previous) {
-    this(
-        ((AppInfo) previous).app,
-        new ConcurrentHashMap<>(((AppInfo) previous).synthesizedClasses),
-        new BooleanBox());
+    this(previous.app(), previous.getSyntheticItems().commit(previous.app()), new BooleanBox());
   }
 
-  private AppInfo(
-      DexApplication application,
-      ConcurrentHashMap<DexType, DexProgramClass> synthesizedClasses,
-      BooleanBox obsolete) {
+  // For desugaring.
+  // This is a view onto the app info and is the only place the pending synthetics are shared.
+  AppInfo(CreateDesugaringViewOnAppInfo witness, AppInfo appInfo) {
+    this(appInfo.app, appInfo.syntheticItems, appInfo.obsolete);
+    assert witness != null;
+  }
+
+  private AppInfo(DexApplication application, SyntheticItems syntheticItems, BooleanBox obsolete) {
     this.app = application;
     this.dexItemFactory = application.dexItemFactory;
-    this.synthesizedClasses = synthesizedClasses;
+    this.syntheticItems = syntheticItems;
     this.obsolete = obsolete;
   }
 
@@ -60,10 +53,6 @@
     return app.options;
   }
 
-  public void copyMetadataFromPrevious(AppInfo previous) {
-    this.synthesizedClasses.putAll(previous.synthesizedClasses);
-  }
-
   public boolean isObsolete() {
     return obsolete.get();
   }
@@ -92,25 +81,18 @@
     return dexItemFactory;
   }
 
+  public SyntheticItems getSyntheticItems() {
+    return syntheticItems;
+  }
+
   public void addSynthesizedClass(DexProgramClass clazz) {
     assert checkIfObsolete();
-    assert clazz.type.isD8R8SynthesizedClassType();
-    DexProgramClass previous = synthesizedClasses.put(clazz.type, clazz);
-    assert previous == null || previous == clazz;
+    syntheticItems.addSyntheticClass(clazz);
   }
 
   public Collection<DexProgramClass> synthesizedClasses() {
     assert checkIfObsolete();
-    return Collections.unmodifiableCollection(synthesizedClasses.values());
-  }
-
-  private Map<DexField, DexEncodedField> computeFieldDefinitions(DexType type) {
-    Builder<DexField, DexEncodedField> builder = ImmutableMap.builder();
-    DexClass clazz = definitionFor(type);
-    if (clazz != null) {
-      clazz.forEachField(field -> builder.put(field.field, field));
-    }
-    return builder.build();
+    return syntheticItems.getSyntheticClasses();
   }
 
   public Collection<DexProgramClass> classes() {
@@ -130,9 +112,9 @@
 
   public final DexClass definitionForWithoutExistenceAssert(DexType type) {
     assert checkIfObsolete();
-    DexProgramClass cached = synthesizedClasses.get(type);
+    DexProgramClass cached = syntheticItems.getSyntheticClass(type);
     if (cached != null) {
-      assert app.definitionFor(type) == null;
+      assert app.definitionFor(type) == null : "Program type also in pending synthetics: " + type;
       return cached;
     }
     return app.definitionFor(type);
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
index 481af1e..3c29286 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -39,13 +39,19 @@
  */
 public class AppInfoWithClassHierarchy extends AppInfo {
 
-  public AppInfoWithClassHierarchy(DexApplication application) {
-    super(application);
+  private static final CreateDesugaringViewOnAppInfo WITNESS = new CreateDesugaringViewOnAppInfo();
+
+  static class CreateDesugaringViewOnAppInfo {
+    private CreateDesugaringViewOnAppInfo() {}
+  }
+
+  public AppInfoWithClassHierarchy(DexApplication application, SyntheticItems syntheticItems) {
+    super(application, syntheticItems);
   }
 
   // For desugaring.
-  private AppInfoWithClassHierarchy(AppInfo appInfo) {
-    super(appInfo);
+  private AppInfoWithClassHierarchy(CreateDesugaringViewOnAppInfo witness, AppInfo appInfo) {
+    super(witness, appInfo);
   }
 
   // For AppInfoWithLiveness.
@@ -55,11 +61,11 @@
 
   public static AppInfoWithClassHierarchy createForDesugaring(AppInfo appInfo) {
     assert !appInfo.hasClassHierarchy();
-    return new AppInfoWithClassHierarchy(appInfo);
+    return new AppInfoWithClassHierarchy(WITNESS, appInfo);
   }
 
   public AppInfoWithClassHierarchy rebuild(Function<DexApplication, DexApplication> fn) {
-    return new AppInfoWithClassHierarchy(fn.apply(app()));
+    return new AppInfoWithClassHierarchy(fn.apply(app()), getSyntheticItems());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 6431d85..75fe24e 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -126,7 +126,8 @@
   }
 
   public static AppView<AppInfoWithClassHierarchy> createForR8(DexApplication application) {
-    AppInfoWithClassHierarchy appInfo = new AppInfoWithClassHierarchy(application);
+    AppInfoWithClassHierarchy appInfo =
+        new AppInfoWithClassHierarchy(application, SyntheticItems.createInitialSyntheticItems());
     return new AppView<>(
         appInfo, WholeProgramOptimizations.ON, defaultPrefixRewritingMapper(appInfo));
   }
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 f1ddad4..491178a 100644
--- a/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
+++ b/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
@@ -48,7 +48,7 @@
     this.writeIR = writeIR;
     this.writeCode = writeCode;
     if (writeIR) {
-      this.appInfo = new AppInfo(application.toDirect());
+      this.appInfo = AppInfo.createInitialAppInfo(application.toDirect());
       if (options.programConsumer == null) {
         // Use class-file backend, since the CF frontend for testing does not support desugaring of
         // synchronized methods for the DEX backend (b/109789541).
diff --git a/src/main/java/com/android/tools/r8/graph/SyntheticItems.java b/src/main/java/com/android/tools/r8/graph/SyntheticItems.java
new file mode 100644
index 0000000..09953df
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/SyntheticItems.java
@@ -0,0 +1,51 @@
+// Copyright (c) 2020, 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.graph;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class SyntheticItems {
+
+  // For some optimizations, e.g. optimizing synthetic classes, we may need to resolve the current
+  // class being optimized.
+  private final ConcurrentHashMap<DexType, DexProgramClass> synthesizedClasses =
+      new ConcurrentHashMap<>();
+
+  private SyntheticItems() {}
+
+  public static SyntheticItems createInitialSyntheticItems() {
+    return new SyntheticItems();
+  }
+
+  public Collection<DexProgramClass> getSyntheticClasses() {
+    return Collections.unmodifiableCollection(synthesizedClasses.values());
+  }
+
+  public void addSyntheticClass(DexProgramClass clazz) {
+    assert clazz.type.isD8R8SynthesizedClassType();
+    DexProgramClass previous = synthesizedClasses.put(clazz.type, clazz);
+    assert previous == null || previous == clazz;
+  }
+
+  public DexProgramClass getSyntheticClass(DexType type) {
+    return synthesizedClasses.get(type);
+  }
+
+  public SyntheticItems commit(DexApplication application) {
+    assert verifyAllSyntheticsAreInApp(application, this);
+    // All synthetics are in the app proper and no further meta-data is present so the empty
+    // collection is currently returned here.
+    return new SyntheticItems();
+  }
+
+  private static boolean verifyAllSyntheticsAreInApp(
+      DexApplication app, SyntheticItems synthetics) {
+    for (DexProgramClass clazz : synthetics.getSyntheticClasses()) {
+      assert app.programDefinitionFor(clazz.type) != null;
+    }
+    return true;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 8c65c1e..347f495 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -105,7 +105,7 @@
     if (androidApp != null) {
       DexApplication app =
           new ApplicationReader(androidApp, options, Timing.empty()).read(executor);
-      appInfo = new AppInfo(app);
+      appInfo = AppInfo.createInitialAppInfo(app);
     }
     AppView<?> appView = AppView.createForD8(appInfo, rewritePrefix);
     BackportedMethodRewriter.RewritableMethods rewritableMethods =
diff --git a/src/main/java/com/android/tools/r8/relocator/Relocator.java b/src/main/java/com/android/tools/r8/relocator/Relocator.java
index a33424b..e45afd6 100644
--- a/src/main/java/com/android/tools/r8/relocator/Relocator.java
+++ b/src/main/java/com/android/tools/r8/relocator/Relocator.java
@@ -79,8 +79,7 @@
     Timing timing = Timing.create("Relocator", options);
     try {
       DexApplication app = new ApplicationReader(inputApp, options, timing).read(executor);
-
-      AppInfo appInfo = new AppInfo(app);
+      AppInfo appInfo = AppInfo.createInitialAppInfo(app);
       AppView<?> appView = AppView.createForRelocator(appInfo);
       appView.setAppServices(AppServices.builder(appView).build());
 
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 3197121..6c2cb3a 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -40,6 +40,7 @@
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
 import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.graph.SyntheticItems;
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryAPIConverter;
@@ -195,6 +196,7 @@
   // TODO(zerny): Clean up the constructors so we have just one.
   AppInfoWithLiveness(
       DirectMappedDexApplication application,
+      SyntheticItems syntheticItems,
       Set<DexType> deadProtoTypes,
       Set<DexType> missingTypes,
       Set<DexType> liveTypes,
@@ -235,7 +237,7 @@
       EnumValueInfoMapCollection enumValueInfoMaps,
       Set<DexType> constClassReferences,
       Map<DexType, Visibility> initClassReferences) {
-    super(application);
+    super(application, syntheticItems);
     this.deadProtoTypes = deadProtoTypes;
     this.missingTypes = missingTypes;
     this.liveTypes = liveTypes;
@@ -406,7 +408,6 @@
         previous.enumValueInfoMaps,
         previous.constClassReferences,
         previous.initClassReferences);
-    copyMetadataFromPrevious(previous);
   }
 
   private AppInfoWithLiveness(
@@ -416,6 +417,7 @@
       Collection<DexReference> additionalPinnedItems) {
     this(
         application,
+        previous.getSyntheticItems(),
         previous.deadProtoTypes,
         previous.missingTypes,
         previous.liveTypes,
@@ -458,7 +460,6 @@
         previous.enumValueInfoMaps,
         previous.constClassReferences,
         previous.initClassReferences);
-    copyMetadataFromPrevious(previous);
     assert keepInfo.verifyNoneArePinned(removedClasses, previous);
   }
 
@@ -1000,6 +1001,7 @@
 
     return new AppInfoWithLiveness(
         application,
+        getSyntheticItems(),
         deadProtoTypes,
         missingTypes,
         lens.rewriteTypes(liveTypes),
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 6ed64fe..87159c4 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -3032,6 +3032,7 @@
     AppInfoWithLiveness appInfoWithLiveness =
         new AppInfoWithLiveness(
             app,
+            appInfo.getSyntheticItems(),
             deadProtoTypes,
             mode.isFinalTreeShaking()
                 ? Sets.union(initialMissingTypes, missingTypes)
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 545ab13..32a2904 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -35,6 +35,7 @@
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.graph.SmaliWriter;
 import com.android.tools.r8.graph.SubtypingInfo;
+import com.android.tools.r8.graph.SyntheticItems;
 import com.android.tools.r8.jasmin.JasminBuilder;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
@@ -588,13 +589,16 @@
   }
 
   protected static AppView<AppInfo> computeAppView(AndroidApp app) throws Exception {
-    AppInfo appInfo = new AppInfo(readApplicationForDexOutput(app, new InternalOptions()));
+    AppInfo appInfo =
+        AppInfo.createInitialAppInfo(readApplicationForDexOutput(app, new InternalOptions()));
     return AppView.createForD8(appInfo);
   }
 
   protected static AppInfoWithClassHierarchy computeAppInfoWithClassHierarchy(AndroidApp app)
       throws Exception {
-    return new AppInfoWithClassHierarchy(readApplicationForDexOutput(app, new InternalOptions()));
+    return new AppInfoWithClassHierarchy(
+        readApplicationForDexOutput(app, new InternalOptions()),
+        SyntheticItems.createInitialSyntheticItems());
   }
 
   protected static AppView<AppInfoWithClassHierarchy> computeAppViewWithSubtyping(AndroidApp app)
diff --git a/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java b/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
index 04c8788..96d5012 100644
--- a/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
+++ b/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
@@ -71,7 +71,7 @@
     InternalOptions options = new InternalOptions();
     DexApplication dexApplication =
         new ApplicationReader(application, options, Timing.empty()).read();
-    AppView<?> appView = AppView.createForD8(new AppInfo(dexApplication));
+    AppView<?> appView = AppView.createForD8(AppInfo.createInitialAppInfo(dexApplication));
 
     // Build the code, and split the code into three blocks.
     MethodSubject methodSubject = getMethodSubject(application, signature);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
index cdb9264..2485f20 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
@@ -134,7 +134,7 @@
 
     InternalOptions options = new InternalOptions();
     options.debug = true;
-    AppInfo appInfo = new AppInfo(DexApplication.builder(options, null).build());
+    AppInfo appInfo = AppInfo.createInitialAppInfo(DexApplication.builder(options, null).build());
     AppView<?> appView = AppView.createForD8(appInfo);
     IRCode code =
         new IRCode(
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
index 3c202dd..3f7bb60 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
@@ -367,7 +367,8 @@
   public void multipleLiveTempRegisters() {
     InternalOptions options = new InternalOptions();
     AppView<AppInfo> appInfo =
-        AppView.createForD8(new AppInfo(DexApplication.builder(options, null).build()));
+        AppView.createForD8(
+            AppInfo.createInitialAppInfo(DexApplication.builder(options, null).build()));
     TypeElement objectType =
         TypeElement.fromDexType(options.itemFactory.objectType, Nullability.maybeNull(), appInfo);
     CollectMovesIterator moves = new CollectMovesIterator();
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
index e246335..ca5b2c0 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
@@ -56,7 +56,7 @@
   @Test
   public void splitOverlappingInactiveIntervalWithNoNextUse() {
     InternalOptions options = new InternalOptions();
-    AppInfo appInfo = new AppInfo(DexApplication.builder(options, null).build());
+    AppInfo appInfo = AppInfo.createInitialAppInfo(DexApplication.builder(options, null).build());
     AppView<?> appView = AppView.createForD8(appInfo);
     IRCode code = simpleCode();
     MyRegisterAllocator allocator = new MyRegisterAllocator(appView, code);
diff --git a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
index f4884c3..ad6c793 100644
--- a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
+++ b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
@@ -79,7 +79,7 @@
 
     ProgramMethod method = getProgramMethod(originalApplication, methodSig);
     // Get the IR pre-optimization.
-    IRCode code = method.buildIR(AppView.createForD8(new AppInfo(application)));
+    IRCode code = method.buildIR(AppView.createForD8(AppInfo.createInitialAppInfo(application)));
 
     // Find the exit block and assert that the value is a phi merging the exceptional edge
     // with the normal edge.
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 d4f8b5b..299a6c0 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
@@ -62,7 +62,8 @@
   @Override
   public IRCode buildIR() {
     assert codeInspector.application.options.programConsumer != null;
-    return getProgramMethod().buildIR(AppView.createForD8(new AppInfo(codeInspector.application)));
+    return getProgramMethod()
+        .buildIR(AppView.createForD8(AppInfo.createInitialAppInfo(codeInspector.application)));
   }
 
   @Override