Use synthetic items in horizontal class merger

Change-Id: Idd37109e61c502e08b4709509cdcb3c82c9d645c
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index c54ab80..b77c8ed 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -495,16 +495,13 @@
             && options.isShrinking()) {
           timing.begin("HorizontalClassMerger");
           HorizontalClassMerger merger = new HorizontalClassMerger(appViewWithLiveness);
-          DirectMappedDexApplication.Builder appBuilder =
-              appView.appInfo().app().asDirect().builder();
           HorizontalClassMergerResult horizontalClassMergerResult =
-              merger.run(appBuilder, runtimeTypeCheckInfo);
+              merger.run(runtimeTypeCheckInfo);
           if (horizontalClassMergerResult != null) {
             // Must rewrite AppInfoWithLiveness before pruning the merged classes, to ensure that
             // allocations sites, fields accesses, etc. are correctly transferred to the target
             // classes.
-            appView.rewriteWithLensAndApplication(
-                horizontalClassMergerResult.getGraphLens(), appBuilder.build());
+            appView.rewriteWithLens(horizontalClassMergerResult.getGraphLens());
             horizontalClassMergerResult
                 .getFieldAccessInfoCollectionModifier()
                 .modify(appViewWithLiveness);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
index b700953..05e91a4 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/HorizontalClassMerger.java
@@ -6,7 +6,6 @@
 
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.horizontalclassmerging.policies.AllInstantiatedOrUninstantiated;
 import com.android.tools.r8.horizontalclassmerging.policies.CheckAbstractClasses;
 import com.android.tools.r8.horizontalclassmerging.policies.DontInlinePolicy;
@@ -58,7 +57,6 @@
   }
 
   public HorizontalClassMergerResult run(
-      DirectMappedDexApplication.Builder appBuilder,
       RuntimeTypeCheckInfo runtimeTypeCheckInfo) {
     MergeGroup initialGroup = new MergeGroup(appView.appInfo().classesWithDeterministicOrder());
 
@@ -87,7 +85,7 @@
 
     // Merge the classes.
     SyntheticArgumentClass syntheticArgumentClass =
-        new SyntheticArgumentClass.Builder(appBuilder, appView).build(allMergeClasses);
+        new SyntheticArgumentClass.Builder(appView).build(allMergeClasses);
     applyClassMergers(classMergers, syntheticArgumentClass);
 
     // Generate the graph lens.
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
index 6ef677b..3ac16de 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
@@ -4,21 +4,12 @@
 
 package com.android.tools.r8.horizontalclassmerging;
 
-import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ClassAccessFlags;
-import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.GenericSignature.ClassSignature;
-import com.android.tools.r8.origin.SynthesizedOrigin;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -53,61 +44,28 @@
 
   public static class Builder {
 
-    private final DirectMappedDexApplication.Builder appBuilder;
     private final AppView<AppInfoWithLiveness> appView;
 
-    Builder(DirectMappedDexApplication.Builder appBuilder, AppView<AppInfoWithLiveness> appView) {
-      this.appBuilder = appBuilder;
+    Builder(AppView<AppInfoWithLiveness> appView) {
       this.appView = appView;
     }
 
-    private DexType synthesizeClass(
-        DexProgramClass context, Iterable<DexProgramClass> mergeClasses, int index) {
-      DexType syntheticClassType =
-          appView
-              .dexItemFactory()
-              .createFreshTypeName(
-                  context.type.addSuffix(SYNTHETIC_CLASS_SUFFIX, appView.dexItemFactory()),
-                  type -> appView.appInfo().definitionForWithoutExistenceAssert(type) == null,
-                  index);
-
-      DexProgramClass clazz =
-          new DexProgramClass(
-              syntheticClassType,
-              null,
-              new SynthesizedOrigin("horizontal class merging", HorizontalClassMerger.class),
-              ClassAccessFlags.fromCfAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC),
-              appView.dexItemFactory().objectType,
-              DexTypeList.empty(),
-              null,
-              null,
-              Collections.emptyList(),
-              null,
-              Collections.emptyList(),
-              ClassSignature.noSignature(),
-              DexAnnotationSet.empty(),
-              DexEncodedField.EMPTY_ARRAY,
-              DexEncodedField.EMPTY_ARRAY,
-              DexEncodedMethod.EMPTY_ARRAY,
-              DexEncodedMethod.EMPTY_ARRAY,
-              appView.dexItemFactory().getSkipNameValidationForTesting(),
-              DexProgramClass::checksumFromType);
-
-      appBuilder.addSynthesizedClass(clazz);
-      appView.appInfo().addSynthesizedClass(clazz, mergeClasses);
-      return clazz.type;
+    private DexProgramClass synthesizeClass(DexProgramClass context, SyntheticKind syntheticKind) {
+      return appView
+          .getSyntheticItems()
+          .createFixedClass(syntheticKind, context, appView.dexItemFactory(), builder -> {});
     }
 
     public SyntheticArgumentClass build(Iterable<DexProgramClass> mergeClasses) {
       // Find a fresh name in an existing package.
       DexProgramClass context = mergeClasses.iterator().next();
       List<DexType> syntheticArgumentTypes = new ArrayList<>();
-      for (int i = 0;
-          i < appView.options().horizontalClassMergerOptions().getSyntheticArgumentCount();
-          i++) {
-        syntheticArgumentTypes.add(synthesizeClass(context, mergeClasses, i));
-      }
-
+      syntheticArgumentTypes.add(
+          synthesizeClass(context, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_1).getType());
+      syntheticArgumentTypes.add(
+          synthesizeClass(context, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_2).getType());
+      syntheticArgumentTypes.add(
+          synthesizeClass(context, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_3).getType());
       return new SyntheticArgumentClass(syntheticArgumentTypes);
     }
   }
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index c3a9d9c..ea95117 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -27,6 +27,9 @@
     COMPANION_CLASS("CompanionClass", false),
     LAMBDA("Lambda", false),
     INIT_TYPE_ARGUMENT("-IA", false, true),
+    HORIZONTAL_INIT_TYPE_ARGUMENT_1("$IA$1", false, true),
+    HORIZONTAL_INIT_TYPE_ARGUMENT_2("$IA$2", false, true),
+    HORIZONTAL_INIT_TYPE_ARGUMENT_3("$IA$3", false, true),
     // Method synthetics.
     BACKPORT("Backport", true),
     STATIC_INTERFACE_CALL("StaticInterfaceCall", true),
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 cf7e877..9c2516c 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1160,7 +1160,6 @@
     public boolean enableConstructorMerging = true;
     public boolean enableJavaLambdaMerging = false;
 
-    public int syntheticArgumentCount = 3;
     public int maxGroupSize = 30;
 
     public void disable() {
@@ -1183,10 +1182,6 @@
       return maxGroupSize;
     }
 
-    public int getSyntheticArgumentCount() {
-      return syntheticArgumentCount;
-    }
-
     public boolean isConstructorMergingEnabled() {
       return enableConstructorMerging;
     }
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
index d84c164..5b2dbe7 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
@@ -6,7 +6,7 @@
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.horizontalclassmerging.SyntheticArgumentClass;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -35,10 +35,8 @@
     return codeInspector.allClasses().stream()
         .filter(
             clazz ->
-                clazz.isSynthetic()
-                    && clazz
-                        .getOriginalName()
-                        .endsWith(SyntheticArgumentClass.SYNTHETIC_CLASS_SUFFIX))
+                SyntheticItemsTestUtils.isHorizontalInitializerTypeArgument(
+                    clazz.getOriginalReference()))
         .findFirst()
         .get();
   }
diff --git a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
index 6f3a6cc..46924fd 100644
--- a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
+++ b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
@@ -90,6 +90,15 @@
     return SyntheticNaming.isSynthetic(reference, null, SyntheticKind.INIT_TYPE_ARGUMENT);
   }
 
+  public static boolean isHorizontalInitializerTypeArgument(ClassReference reference) {
+    return SyntheticNaming.isSynthetic(
+            reference, null, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_1)
+        || SyntheticNaming.isSynthetic(
+            reference, null, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_2)
+        || SyntheticNaming.isSynthetic(
+            reference, null, SyntheticKind.HORIZONTAL_INIT_TYPE_ARGUMENT_3);
+  }
+
   public static Matcher<String> containsInternalSyntheticReference() {
     return containsString(SyntheticNaming.getPhaseSeparator(Phase.INTERNAL));
   }