Generate CF instead of DEX for main-dex list tests.

Bug: b/132422247
Change-Id: I8a29f2eda6ebe73d56edab17d53c51a79c0c8867
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 2eb6a7f..25ffe36 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -10,77 +10,36 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import com.android.tools.r8.ByteDataView;
+import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.D8;
 import com.android.tools.r8.D8Command;
-import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.DiagnosticsMatcher;
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.R8Command;
 import com.android.tools.r8.StringResource;
 import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.dex.ApplicationWriter;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ClassAccessFlags;
-import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexString;
 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.graph.MethodAccessFlags;
-import com.android.tools.r8.graph.MethodCollection.MethodCollectionFactory;
-import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.graph.UseRegistry;
-import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadataProvider;
-import com.android.tools.r8.ir.code.CatchHandlers;
-import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.Phi.RegisterReadType;
-import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.Position.SyntheticPosition;
-import com.android.tools.r8.ir.code.ValueTypeConstraint;
-import com.android.tools.r8.ir.conversion.DexBuilder;
-import com.android.tools.r8.ir.conversion.IRBuilder;
-import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
-import com.android.tools.r8.ir.conversion.SourceCode;
-import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
-import com.android.tools.r8.ir.regalloc.RegisterAllocator;
-import com.android.tools.r8.ir.synthetic.SynthesizedCode;
 import com.android.tools.r8.jasmin.JasminBuilder;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
-import com.android.tools.r8.utils.AbortException;
-import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.transformers.ClassTransformer;
 import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.AndroidAppConsumers;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.MainDexListParser;
-import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.ThreadUtils;
-import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
 import com.google.common.collect.ImmutableList;
@@ -89,26 +48,22 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
 
 @RunWith(Parameterized.class)
 public class MainDexListTests extends TestBase {
@@ -154,21 +109,22 @@
 
     // Generates an application with many classes, every even in one package and every odd in
     // another. Keep the number of methods low enough for single dex application.
-    AndroidApp generated = generateApplication(
-        MANY_CLASSES, AndroidApiLevel.getDefault().getLevel(),
-        MANY_CLASSES_SINGLE_DEX_METHODS_PER_CLASS);
-    generated.write(getManyClassesSingleDexAppPath(), OutputMode.DexIndexed);
+    generateApplication(
+        getManyClassesSingleDexAppPath(), MANY_CLASSES, MANY_CLASSES_SINGLE_DEX_METHODS_PER_CLASS);
 
     // Generates an application with many classes, every even in one package and every odd in
     // another. Add enough methods so the application cannot fit into one dex file.
-    generated = generateApplication(
-        MANY_CLASSES, AndroidApiLevel.L.getLevel(), MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
-    generated.write(getManyClassesMultiDexAppPath(), OutputMode.DexIndexed);
+    generateApplication(
+        getManyClassesMultiDexAppPath(), MANY_CLASSES, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
 
     // Generates an application with two classes, each with the maximum possible number of methods.
-    generated = generateApplication(TWO_LARGE_CLASSES, AndroidApiLevel.N.getLevel(),
-        MAX_METHOD_COUNT);
-    generated.write(getTwoLargeClassesAppPath(), OutputMode.DexIndexed);
+    generateApplication(getTwoLargeClassesAppPath(), TWO_LARGE_CLASSES, getLargeClassMethodCount());
+  }
+
+  private static int getLargeClassMethodCount() {
+    int otherConstantPoolEntries = 23;
+    int maxMethodCount = MAX_METHOD_COUNT - otherConstantPoolEntries;
+    return maxMethodCount;
   }
 
   private static Path getTwoLargeClassesAppPath() {
@@ -183,17 +139,10 @@
     return generatedApplicationsFolder.getRoot().toPath().resolve("many-classes-stereo.zip");
   }
 
-  private static Path getManyClassesForceMultiDexAppPath() {
-    return generatedApplicationsFolder.getRoot().toPath().resolve("many-classes-stereo-forced.zip");
-  }
-
-  private static Set<DexType> parse(Path path, DexItemFactory itemFactory) throws IOException {
+  private static Set<DexType> parse(Path path, DexItemFactory itemFactory) {
     return MainDexListParser.parseList(StringResource.fromFile(path), itemFactory);
   }
 
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
   @Test
   public void checkGeneratedFileFitInSingleDexFile() {
     assertTrue(MANY_CLASSES_COUNT * MANY_CLASSES_SINGLE_DEX_METHODS_PER_CLASS <= MAX_METHOD_COUNT);
@@ -221,20 +170,23 @@
         getTwoLargeClassesAppPath(),
         false,
         test -> {
-          TestDiagnosticsHandler handler = new TestDiagnosticsHandler();
+          TestDiagnosticMessagesImpl handler = new TestDiagnosticMessagesImpl();
           try {
             test.run(handler);
             fail("Expect to fail, for there are too many classes for the main-dex list.");
           } catch (Throwable e) {
             assert e instanceof CompilationFailedException;
-            assertEquals(1, handler.errors.size());
-            DexFileOverflowDiagnostic overflow = (DexFileOverflowDiagnostic) handler.errors.get(0);
+            handler.assertErrorsMatch(
+                DiagnosticsMatcher.diagnosticType(DexFileOverflowDiagnostic.class));
+            DexFileOverflowDiagnostic overflow =
+                (DexFileOverflowDiagnostic) handler.getErrors().get(0);
             // Make sure {@link MonoDexDistributor} was _not_ used, i.e., a spec was given.
             assertTrue(overflow.hasMainDexSpecification());
             // Make sure what exceeds the limit is the number of methods.
             assertTrue(overflow.getNumberOfMethods() > overflow.getMaximumNumberOfMethods());
             assertEquals(
-                TWO_LARGE_CLASSES.size() * MAX_METHOD_COUNT, overflow.getNumberOfMethods());
+                TWO_LARGE_CLASSES.size() * getLargeClassMethodCount(),
+                overflow.getNumberOfMethods());
           }
         });
   }
@@ -261,7 +213,7 @@
 
   @Test
   public void allClassesInMainDex() throws Throwable {
-    // Degenerated case with an app thats fit into a single dex, and where the main dex list
+    // Degenerated case with an app that fits into a single dex, and where the main dex list
     // contains all classes.
     verifyMainDexContains(MANY_CLASSES, getManyClassesSingleDexAppPath(), true);
   }
@@ -273,14 +225,16 @@
         getManyClassesMultiDexAppPath(),
         false,
         test -> {
-          TestDiagnosticsHandler handler = new TestDiagnosticsHandler();
+          TestDiagnosticMessagesImpl handler = new TestDiagnosticMessagesImpl();
           try {
             test.run(handler);
             fail("Expect to fail, for there are too many classes for the main-dex list.");
           } catch (Throwable e) {
             assert e instanceof CompilationFailedException;
-            assertEquals(1, handler.errors.size());
-            DexFileOverflowDiagnostic overflow = (DexFileOverflowDiagnostic) handler.errors.get(0);
+            handler.assertErrorsMatch(
+                DiagnosticsMatcher.diagnosticType(DexFileOverflowDiagnostic.class));
+            DexFileOverflowDiagnostic overflow =
+                (DexFileOverflowDiagnostic) handler.getErrors().get(0);
             // Make sure {@link MonoDexDistributor} was _not_ used, i.e., a main-dex spec was given.
             assertTrue(overflow.hasMainDexSpecification());
             // Make sure what exceeds the limit is the number of methods.
@@ -552,44 +506,6 @@
             .collect(Collectors.toList()), false);
   }
 
-  @Test
-  public void checkIntermediateMultiDex() throws Exception {
-    // Generates an application with many classes, every even in one package and every odd in
-    // another. Add enough methods so the application cannot fit into one dex file.
-    // Notice that this one allows multidex while using lower API.
-    AndroidApp generated = generateApplication(
-        MANY_CLASSES, AndroidApiLevel.K.getLevel(), true, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
-    generated.write(getManyClassesForceMultiDexAppPath(), OutputMode.DexIndexed);
-    // Make sure the generated app indeed has multiple dex files.
-    assertTrue(generated.getDexProgramResourcesForTesting().size() > 1);
-  }
-
-  @Test
-  public void testMultiDexFailDueToMinApi() throws Exception {
-    // Generates an application with many classes, every even in one package and every odd in
-    // another. Add enough methods so the application cannot fit into one dex file.
-    // Notice that this one fails due to the min API.
-    TestDiagnosticsHandler handler = new TestDiagnosticsHandler();
-    try {
-      generateApplication(
-          MANY_CLASSES,
-          AndroidApiLevel.K.getLevel(),
-          false,
-          MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS,
-          handler);
-      fail("Expect to fail, for there are many classes while multidex is not enabled.");
-    } catch (AbortException e) {
-      assertEquals(1, handler.errors.size());
-      DexFileOverflowDiagnostic overflow = (DexFileOverflowDiagnostic) handler.errors.get(0);
-      // Make sure {@link MonoDexDistributor} was used, i.e., no main-dex specification was given.
-      assertFalse(overflow.hasMainDexSpecification());
-      // Make sure what exceeds the limit is the number of methods.
-      assertEquals(
-          MANY_CLASSES_COUNT * MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS,
-          overflow.getNumberOfMethods());
-    }
-  }
-
   private static String typeToEntry(String type) {
     return type.replace(".", "/") + FileUtils.CLASS_EXTENSION;
   }
@@ -637,7 +553,7 @@
       boolean minimalMainDex,
       MultiDexTestMode testMode,
       DiagnosticsHandler handler)
-      throws IOException, ExecutionException, CompilationFailedException {
+      throws IOException, CompilationFailedException {
     AndroidApp originalApp = AndroidApp.builder().addProgramFiles(app).build();
     CodeInspector originalInspector = new CodeInspector(originalApp);
     for (String clazz : mainDex) {
@@ -663,8 +579,8 @@
         builder.addMainDexListFiles(mainDexList);
         break;
       case MULTIPLE_FILES: {
-        // Partion the main dex list into several files.
-        List<List<String>> partitions = Lists.partition(mainDex, Math.max(mainDex.size() / 3, 1));
+          // Partition the main dex list into several files.
+          List<List<String>> partitions = Lists.partition(mainDex, Math.max(mainDex.size() / 3, 1));
         List<Path> mainDexListFiles = new ArrayList<>();
         for (List<String> partition : partitions) {
           Path partialMainDexList = temp.newFile().toPath();
@@ -725,7 +641,7 @@
           singleDexApp,
           test -> {
             try {
-              test.run(new TestDiagnosticsHandler());
+              test.run(new TestDiagnosticMessagesImpl());
             } catch (Throwable e) {
               throw new RuntimeException(e);
             }
@@ -748,270 +664,46 @@
     }
   }
 
-  public static AndroidApp generateApplication(List<String> classes, int minApi, int methodCount)
-      throws IOException, ExecutionException {
-    return generateApplication(classes, minApi, false, methodCount);
+  private static void generateApplication(Path output, List<String> classes, int methodCount)
+      throws IOException {
+    ArchiveConsumer consumer = new ArchiveConsumer(output);
+    for (String typename : classes) {
+      String descriptor = DescriptorUtils.javaTypeToDescriptor(typename);
+      byte[] bytes =
+          transformer(ClassStub.class)
+              .setClassDescriptor(descriptor)
+              .addClassTransformer(
+                  new ClassTransformer() {
+                    @Override
+                    public MethodVisitor visitMethod(
+                        int access,
+                        String name,
+                        String descriptor,
+                        String signature,
+                        String[] exceptions) {
+                      // This strips <init>() too.
+                      if (name.equals("methodStub")) {
+                        for (int i = 0; i < methodCount; i++) {
+                          MethodVisitor mv =
+                              super.visitMethod(
+                                  access, "method" + i, descriptor, signature, exceptions);
+                          mv.visitCode();
+                          mv.visitInsn(Opcodes.RETURN);
+                          mv.visitMaxs(0, 0);
+                          mv.visitEnd();
+                        }
+                      }
+                      return null;
+                    }
+                  })
+              .transform();
+      consumer.accept(ByteDataView.of(bytes), descriptor, null);
+    }
+    consumer.finished(null);
   }
 
-  private static AndroidApp generateApplication(
-      List<String> classes, int minApi, boolean intermediate, int methodCount)
-      throws IOException, ExecutionException {
-    return generateApplication(
-        classes, minApi, intermediate, methodCount, new DiagnosticsHandler() {});
-  }
-
-  private static AndroidApp generateApplication(
-      List<String> classes,
-      int minApi,
-      boolean intermediate,
-      int methodCount,
-      DiagnosticsHandler diagnosticsHandler)
-      throws IOException, ExecutionException {
-    Timing timing = Timing.empty();
-    InternalOptions options =
-        new InternalOptions(new DexItemFactory(), new Reporter(diagnosticsHandler));
-    options.setMinApiLevel(AndroidApiLevel.getAndroidApiLevel(minApi));
-    options.intermediate = intermediate;
-    DexItemFactory factory = options.itemFactory;
-    AppView<?> appView = AppView.createForR8(DexApplication.builder(options, timing).build());
-    DexApplication.Builder<?> builder = DexApplication.builder(options, timing);
-    for (String clazz : classes) {
-      DexString desc = factory.createString(DescriptorUtils.javaTypeToDescriptor(clazz));
-      DexType type = factory.createType(desc);
-      DexProgramClass programClass =
-          new DexProgramClass(
-              type,
-              null,
-              new SynthesizedOrigin("test", MainDexListTests.class),
-              ClassAccessFlags.fromSharedAccessFlags(0),
-              factory.objectType,
-              DexTypeList.empty(),
-              null,
-              null,
-              Collections.emptyList(),
-              Collections.emptyList(),
-              null,
-              Collections.emptyList(),
-              ClassSignature.noSignature(),
-              DexAnnotationSet.empty(),
-              DexEncodedField.EMPTY_ARRAY,
-              DexEncodedField.EMPTY_ARRAY,
-              MethodCollectionFactory.empty(),
-              false,
-              DexProgramClass::invalidChecksumRequest);
-      DexEncodedMethod[] directMethods = new DexEncodedMethod[methodCount];
-      for (int i = 0; i < methodCount; i++) {
-        MethodAccessFlags access = MethodAccessFlags.fromSharedAccessFlags(0, false);
-        access.setPublic();
-        access.setStatic();
-        DexMethod voidReturnMethod =
-            factory.createMethod(
-                desc,
-                factory.createString("method" + i),
-                factory.voidDescriptor,
-                DexString.EMPTY_ARRAY);
-        Code code =
-            new SynthesizedCode(
-                (ignored, callerPosition) -> new ReturnVoidCode(voidReturnMethod, callerPosition)) {
-              @Override
-              public Consumer<UseRegistry> getRegistryCallback(DexClassAndMethod method) {
-                throw new Unreachable();
-              }
-            };
-        DexEncodedMethod method =
-            DexEncodedMethod.builder()
-                .setMethod(voidReturnMethod)
-                .setAccessFlags(access)
-                .setCode(code)
-                .disableAndroidApiLevelCheck()
-                .build();
-        ProgramMethod programMethod = new ProgramMethod(programClass, method);
-        IRCode ir =
-            code.buildIR(
-                programMethod,
-                appView,
-                Origin.unknown(),
-                new MutableMethodConversionOptions(options));
-        RegisterAllocator allocator = new LinearScanRegisterAllocator(appView, ir);
-        programMethod.setCode(
-            new DexBuilder(ir, BytecodeMetadataProvider.empty(), allocator, options).build(),
-            appView);
-        directMethods[i] = method;
-      }
-      programClass.getMethodCollection().addDirectMethods(Arrays.asList(directMethods));
-      builder.addProgramClass(programClass);
-    }
-    DirectMappedDexApplication application = builder.build().toDirect();
-    ApplicationWriter writer =
-        new ApplicationWriter(
-            AppView.createForD8(
-                AppInfo.createInitialAppInfo(
-                    application, GlobalSyntheticsStrategy.forNonSynthesizing())),
-            null);
-    ExecutorService executor = ThreadUtils.getExecutorService(options);
-    AndroidAppConsumers compatSink = new AndroidAppConsumers(options);
-    try {
-      writer.write(executor);
-    } finally {
-      executor.shutdown();
-    }
-    options.signalFinishedToConsumers();
-    return compatSink.build();
-  }
-
-  // Code stub to generate methods with "return-void" bodies.
-  private static class ReturnVoidCode implements SourceCode {
-
-    private final Position position;
-
-    public ReturnVoidCode(DexMethod method, Position callerPosition) {
-      this.position =
-          SyntheticPosition.builder()
-              .setLine(0)
-              .setMethod(method)
-              .setCallerPosition(callerPosition)
-              .build();
-    }
-
-    @Override
-    public int instructionCount() {
-      return 1;
-    }
-
-    @Override
-    public int instructionIndex(int instructionOffset) {
-      return instructionOffset;
-    }
-
-    @Override
-    public int instructionOffset(int instructionIndex) {
-      return instructionIndex;
-    }
-
-    @Override
-    public DebugLocalInfo getIncomingLocalAtBlock(int register, int blockOffset) {
-      return null;
-    }
-
-    @Override
-    public DexType getPhiTypeForBlock(
-        int register, int blockOffset, ValueTypeConstraint constraint, RegisterReadType readType) {
-      throw new Unreachable("Should never generate a phi");
-    }
-
-    @Override
-    public DebugLocalInfo getIncomingLocal(int register) {
-      return null;
-    }
-
-    @Override
-    public DebugLocalInfo getOutgoingLocal(int register) {
-      return null;
-    }
-
-    @Override
-    public int traceInstruction(int instructionIndex, IRBuilder builder) {
-      return instructionIndex;
-    }
-
-    @Override
-    public void setUp() {
-      // Intentionally empty.
-    }
-
-    @Override
-    public void clear() {
-      // Intentionally empty.
-    }
-
-    @Override
-    public void buildPrelude(IRBuilder builder) {
-      // Intentionally empty.
-    }
-
-    @Override
-    public void buildInstruction(
-        IRBuilder builder, int instructionIndex, boolean firstBlockInstruction) {
-      assert instructionIndex == 0;
-      builder.addReturn();
-    }
-
-    @Override
-    public void buildBlockTransfer(
-        IRBuilder builder, int predecessorOffset, int successorOffset, boolean isExceptional) {
-      throw new Unreachable();
-    }
-
-    @Override
-    public void buildPostlude(IRBuilder builder) {
-      // Intentionally empty.
-    }
-
-    @Override
-    public void resolveAndBuildSwitch(
-        int value, int fallthroughOffset, int payloadOffset, IRBuilder builder) {
-      throw new Unreachable();
-    }
-
-    @Override
-    public void resolveAndBuildNewArrayFilledData(
-        int arrayRef, int payloadOffset, IRBuilder builder) {
-      throw new Unreachable();
-    }
-
-    @Override
-    public CatchHandlers<Integer> getCurrentCatchHandlers(IRBuilder builder) {
-      return null;
-    }
-
-    @Override
-    public int getMoveExceptionRegister(int instructionIndex) {
-      throw new Unreachable();
-    }
-
-    @Override
-    public Position getCanonicalDebugPositionAtOffset(int offset) {
-      return Position.none();
-    }
-
-    @Override
-    public Position getCurrentPosition() {
-      return position;
-    }
-
-    @Override
-    public boolean verifyRegister(int register) {
-      throw new Unreachable();
-    }
-
-    @Override
-    public boolean verifyCurrentInstructionCanThrow() {
-      throw new Unreachable();
-    }
-
-    @Override
-    public boolean verifyLocalInScope(DebugLocalInfo local) {
-      throw new Unreachable();
-    }
-  }
-
-  private class TestDiagnosticsHandler implements DiagnosticsHandler {
-
-    public List<Diagnostic> errors = new ArrayList<>();
-    public List<Diagnostic> warnings = new ArrayList<>();
-
-    public int numberOfErrorsAndWarnings() {
-      return errors.size() + warnings.size();
-    }
-
-    @Override
-    public void error(Diagnostic error) {
-      errors.add(error);
-    }
-
-    @Override
-    public void warning(Diagnostic warning) {
-      warnings.add(warning);
-    }
+  // Simple stub/template for generating the input classes.
+  public static class ClassStub {
+    public static void methodStub() {}
   }
 }