Extend profile rewriting to covariant return type annotations

Bug: b/265729283
Change-Id: I1084ad589809911d7bb1016e08ee81643ae2207b
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index e607b66..64734f8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -220,7 +220,7 @@
             : CfInstructionDesugaringCollection.create(appView, appView.apiLevelCompute());
     this.covariantReturnTypeAnnotationTransformer =
         options.processCovariantReturnTypeAnnotations
-            ? new CovariantReturnTypeAnnotationTransformer(this, appView.dexItemFactory())
+            ? new CovariantReturnTypeAnnotationTransformer(appView, this)
             : null;
     if (appView.options().desugarState.isOn()
         && appView.options().apiModelingOptions().enableOutliningOfMethods) {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
index 1d06a25..0092f10 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/PrimaryD8L8IRConverter.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformerEventConsumer;
 import com.android.tools.r8.ir.desugar.ProgramAdditions;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter;
 import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceApplicationRewriter;
@@ -91,7 +92,7 @@
       new L8InnerOuterAttributeEraser(appView).run();
     }
 
-    processCovariantReturnTypeAnnotations(builder);
+    processCovariantReturnTypeAnnotations(builder, artProfileCollectionAdditions);
 
     timing.end();
 
@@ -338,9 +339,13 @@
     programAdditions.apply(executorService);
   }
 
-  private void processCovariantReturnTypeAnnotations(Builder<?> builder) {
+  private void processCovariantReturnTypeAnnotations(
+      Builder<?> builder, ArtProfileCollectionAdditions artProfileCollectionAdditions) {
     if (covariantReturnTypeAnnotationTransformer != null) {
-      covariantReturnTypeAnnotationTransformer.process(builder);
+      covariantReturnTypeAnnotationTransformer.process(
+          builder,
+          CovariantReturnTypeAnnotationTransformerEventConsumer.create(
+              artProfileCollectionAdditions));
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
index 1143afd..c9ef3ed 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
 import com.android.tools.r8.graph.DexApplication;
@@ -53,23 +54,31 @@
 // the contained CovariantReturnType annotations.
 public final class CovariantReturnTypeAnnotationTransformer {
 
+  private final AppView<?> appView;
   private final IRConverter converter;
-  private final MethodProcessorEventConsumer eventConsumer = MethodProcessorEventConsumer.empty();
+  private final MethodProcessorEventConsumer methodProcessorEventConsumer =
+      MethodProcessorEventConsumer.empty();
   private final DexItemFactory factory;
 
-  public CovariantReturnTypeAnnotationTransformer(IRConverter converter, DexItemFactory factory) {
+  public CovariantReturnTypeAnnotationTransformer(AppView<?> appView, IRConverter converter) {
+    this.appView = appView;
     this.converter = converter;
-    this.factory = factory;
+    this.factory = appView.dexItemFactory();
   }
 
-  public void process(DexApplication.Builder<?> builder) {
+  public void process(
+      DexApplication.Builder<?> builder,
+      CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
     // List of methods that should be added to the next class.
     List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation = new LinkedList<>();
     List<DexEncodedMethod> covariantReturnTypeMethods = new LinkedList<>();
     for (DexProgramClass clazz : builder.getProgramClasses()) {
       // Construct the methods that should be added to clazz.
       buildCovariantReturnTypeMethodsForClass(
-          clazz, methodsWithCovariantReturnTypeAnnotation, covariantReturnTypeMethods);
+          clazz,
+          methodsWithCovariantReturnTypeAnnotation,
+          covariantReturnTypeMethods,
+          eventConsumer);
       if (covariantReturnTypeMethods.isEmpty()) {
         continue;
       }
@@ -79,6 +88,7 @@
       methodsWithCovariantReturnTypeAnnotation.clear();
       covariantReturnTypeMethods.clear();
     }
+    eventConsumer.finished(appView);
   }
 
   private void updateClass(
@@ -111,12 +121,14 @@
   private void buildCovariantReturnTypeMethodsForClass(
       DexProgramClass clazz,
       List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation,
-      List<DexEncodedMethod> covariantReturnTypeMethods) {
+      List<DexEncodedMethod> covariantReturnTypeMethods,
+      CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
     clazz.forEachProgramVirtualMethod(
         method -> {
           if (methodHasCovariantReturnTypeAnnotation(method.getDefinition())) {
             methodsWithCovariantReturnTypeAnnotation.add(method.getDefinition());
-            buildCovariantReturnTypeMethodsForMethod(method, covariantReturnTypeMethods);
+            buildCovariantReturnTypeMethodsForMethod(
+                method, covariantReturnTypeMethods, eventConsumer);
           }
         });
   }
@@ -134,11 +146,13 @@
   // variantReturnTypes annotations on the given method. Adds the newly constructed, synthetic
   // methods to the list covariantReturnTypeMethods.
   private void buildCovariantReturnTypeMethodsForMethod(
-      ProgramMethod method, List<DexEncodedMethod> covariantReturnTypeMethods) {
+      ProgramMethod method,
+      List<DexEncodedMethod> covariantReturnTypeMethods,
+      CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
     assert methodHasCovariantReturnTypeAnnotation(method.getDefinition());
     for (DexType covariantReturnType : getCovariantReturnTypes(method)) {
       DexEncodedMethod covariantReturnTypeMethod =
-          buildCovariantReturnTypeMethod(method, covariantReturnType);
+          buildCovariantReturnTypeMethod(method, covariantReturnType, eventConsumer);
       covariantReturnTypeMethods.add(covariantReturnTypeMethod);
     }
   }
@@ -149,7 +163,9 @@
   //
   // Note: any "synchronized" or "strictfp" modifier could be dropped safely.
   private DexEncodedMethod buildCovariantReturnTypeMethod(
-      ProgramMethod method, DexType covariantReturnType) {
+      ProgramMethod method,
+      DexType covariantReturnType,
+      CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
     DexProgramClass methodHolder = method.getHolder();
     DexMethod methodReference = method.getReference();
     DexEncodedMethod methodDefinition = method.getDefinition();
@@ -183,7 +199,8 @@
             .build();
     // Optimize to generate DexCode instead of CfCode.
     ProgramMethod programMethod = new ProgramMethod(methodHolder, newVirtualMethod);
-    converter.optimizeSynthesizedMethod(programMethod, eventConsumer);
+    converter.optimizeSynthesizedMethod(programMethod, methodProcessorEventConsumer);
+    eventConsumer.acceptCovariantReturnTypeBridgeMethod(programMethod, method);
     return newVirtualMethod;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java
new file mode 100644
index 0000000..a639916
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformerEventConsumer.java
@@ -0,0 +1,53 @@
+// Copyright (c) 2023, 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.ir.desugar;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileCollectionAdditions;
+import com.android.tools.r8.profile.art.rewriting.ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer;
+
+public interface CovariantReturnTypeAnnotationTransformerEventConsumer {
+
+  void acceptCovariantReturnTypeBridgeMethod(ProgramMethod bridge, ProgramMethod target);
+
+  void finished(AppView<?> appView);
+
+  static CovariantReturnTypeAnnotationTransformerEventConsumer create(
+      ArtProfileCollectionAdditions artProfileCollectionAdditions) {
+    if (artProfileCollectionAdditions.isNop()) {
+      return empty();
+    }
+    return ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.attach(
+        artProfileCollectionAdditions, empty());
+  }
+
+  static EmptyCovariantReturnTypeAnnotationTransformerEventConsumer empty() {
+    return EmptyCovariantReturnTypeAnnotationTransformerEventConsumer.getInstance();
+  }
+
+  class EmptyCovariantReturnTypeAnnotationTransformerEventConsumer
+      implements CovariantReturnTypeAnnotationTransformerEventConsumer {
+
+    private static final EmptyCovariantReturnTypeAnnotationTransformerEventConsumer INSTANCE =
+        new EmptyCovariantReturnTypeAnnotationTransformerEventConsumer();
+
+    private EmptyCovariantReturnTypeAnnotationTransformerEventConsumer() {}
+
+    static EmptyCovariantReturnTypeAnnotationTransformerEventConsumer getInstance() {
+      return INSTANCE;
+    }
+
+    @Override
+    public void acceptCovariantReturnTypeBridgeMethod(ProgramMethod bridge, ProgramMethod target) {
+      // Intentionally empty.
+    }
+
+    @Override
+    public void finished(AppView<?> appView) {
+      // Intentionally empty.
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
new file mode 100644
index 0000000..2188363
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/profile/art/rewriting/ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer.java
@@ -0,0 +1,45 @@
+// Copyright (c) 2023, 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.profile.art.rewriting;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformerEventConsumer;
+
+public class ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer
+    implements CovariantReturnTypeAnnotationTransformerEventConsumer {
+
+  private final ConcreteArtProfileCollectionAdditions additionsCollection;
+  private final CovariantReturnTypeAnnotationTransformerEventConsumer parent;
+
+  private ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
+      ConcreteArtProfileCollectionAdditions additionsCollection,
+      CovariantReturnTypeAnnotationTransformerEventConsumer parent) {
+    this.additionsCollection = additionsCollection;
+    this.parent = parent;
+  }
+
+  public static CovariantReturnTypeAnnotationTransformerEventConsumer attach(
+      ArtProfileCollectionAdditions additionsCollection,
+      CovariantReturnTypeAnnotationTransformerEventConsumer eventConsumer) {
+    if (additionsCollection.isNop()) {
+      return eventConsumer;
+    }
+    return new ArtProfileRewritingCovariantReturnTypeAnnotationTransformerEventConsumer(
+        additionsCollection.asConcrete(), eventConsumer);
+  }
+
+  @Override
+  public void acceptCovariantReturnTypeBridgeMethod(ProgramMethod bridge, ProgramMethod target) {
+    additionsCollection.addMethodIfContextIsInProfile(bridge, target);
+    parent.acceptCovariantReturnTypeBridgeMethod(bridge, target);
+  }
+
+  @Override
+  public void finished(AppView<?> appView) {
+    additionsCollection.commit(appView);
+    parent.finished(appView);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java b/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
index b1899a3..8967763 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/annotations/CovariantReturnTypeAnnotationTransformerTest.java
@@ -5,21 +5,30 @@
 package com.android.tools.r8.ir.desugar.annotations;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
 import com.android.tools.r8.AsmTestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
 import java.util.Collections;
+import java.util.List;
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class CovariantReturnTypeAnnotationTransformerTest extends AsmTestBase {
+
   public static final String PACKAGE_NAME = "com/android/tools/r8/ir/desugar/annotations";
   public static final String CRT_BINARY_NAME = "dalvik/annotation/codegen/CovariantReturnType";
   public static final String CRTS_INNER_NAME = "CovariantReturnTypes";
@@ -28,10 +37,18 @@
   public static final String CRT_TYPE_NAME = CRT_BINARY_NAME.replace('/', '.');
   public static final String CRTS_TYPE_NAME = CRT_BINARY_NAME.replace('/', '.');
 
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDexRuntimesAndAllApiLevels().build();
+  }
+
   @Test
   public void testVersion1WithClient1And2() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             ToolHelper.getClassAsBytes(Client.class),
             ToolHelper.getClassAsBytes(A.class),
             ToolHelper.getClassAsBytes(B.class),
@@ -46,8 +63,8 @@
 
   @Test
   public void testVersion1WithClient3() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
             ToolHelper.getClassAsBytes(A.class),
             ToolHelper.getClassAsBytes(B.class),
@@ -63,8 +80,8 @@
 
   @Test
   public void testVersion2WithClient1And2() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             ToolHelper.getClassAsBytes(Client.class),
             ToolHelper.getClassAsBytes(A.class),
             com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
@@ -79,8 +96,8 @@
 
   @Test
   public void testVersion2WithClient3() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
             ToolHelper.getClassAsBytes(A.class),
             com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
@@ -100,8 +117,8 @@
 
   @Test
   public void testVersion3WithClient3() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             com.android.tools.r8.ir.desugar.annotations.version3.ClientDump.dump(),
             ToolHelper.getClassAsBytes(A.class),
             com.android.tools.r8.ir.desugar.annotations.version3.BDump.dump(),
@@ -116,8 +133,8 @@
 
   @Test
   public void testVersion3WithClient1And2() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             ToolHelper.getClassAsBytes(Client.class),
             ToolHelper.getClassAsBytes(A.class),
             com.android.tools.r8.ir.desugar.annotations.version3.BDump.dump(),
@@ -132,8 +149,8 @@
 
   @Test
   public void testRepeatedCompilation() throws Exception {
-    AndroidApp input =
-        buildAndroidApp(
+    List<byte[]> input =
+        ImmutableList.of(
             ToolHelper.getClassAsBytes(Client.class),
             ToolHelper.getClassAsBytes(A.class),
             com.android.tools.r8.ir.desugar.annotations.version2.BDump.dump(),
@@ -142,51 +159,73 @@
     // Version 2 contains annotations.
     checkPresenceOfCovariantAnnotations(input, true);
 
-    AndroidApp output =
-        compileWithD8(input, options -> options.processCovariantReturnTypeAnnotations = true);
-
-    // Compilation output does not contain annotations.
-    checkPresenceOfCovariantAnnotations(output, false);
+    Path output =
+        testForD8(parameters.getBackend())
+            .addProgramClassFileData(input)
+            .addOptionsModification(options -> options.processCovariantReturnTypeAnnotations = true)
+            .setMinApi(parameters.getApiLevel())
+            .compile()
+            // Compilation output does not contain annotations.
+            .inspect(inspector -> checkPresenceOfCovariantAnnotations(inspector, false))
+            .writeToZip();
 
     // Compilation will fail with a compilation error the second time if the implementation does
     // not remove the CovariantReturnType annotations properly during the first compilation.
-    compileWithD8(output, options -> options.processCovariantReturnTypeAnnotations = true);
+    testForD8(parameters.getBackend())
+        .addProgramFiles(output)
+        .addOptionsModification(options -> options.processCovariantReturnTypeAnnotations = true)
+        .setMinApi(parameters.getApiLevel())
+        .compile();
   }
 
   private void succeedsWithOption(
-      AndroidApp input, boolean option, boolean checkPresenceOfSyntheticMethods) throws Exception {
-    AndroidApp output =
-        compileWithD8(input, options -> options.processCovariantReturnTypeAnnotations = option);
-    String stdout = runOnArt(output, Client.class.getCanonicalName());
-    assertEquals(getExpectedOutput(), stdout);
-    checkPresenceOfCovariantAnnotations(output, false);
-    if (option && checkPresenceOfSyntheticMethods) {
-      checkPresenceOfSyntheticMethods(output);
-    }
-  }
-
-  private void failsWithOption(AndroidApp input, boolean option) throws Exception {
-    AndroidApp output =
-        compileWithD8(input, options -> options.processCovariantReturnTypeAnnotations = option);
-    checkPresenceOfCovariantAnnotations(output, false);
-    ToolHelper.ProcessResult result = runOnArtRaw(output, Client.class.getCanonicalName());
-    assertThat(result.stderr, containsString("java.lang.NoSuchMethodError"));
-  }
-
-  private void succeedsIndependentOfFlag(AndroidApp input, boolean checkPresenceOfSyntheticMethods)
+      List<byte[]> input, boolean option, boolean checkPresenceOfSyntheticMethods)
       throws Exception {
+    testForD8(parameters.getBackend())
+        .addProgramClassFileData(input)
+        .addOptionsModification(options -> options.processCovariantReturnTypeAnnotations = option)
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              checkPresenceOfCovariantAnnotations(inspector, false);
+              if (option && checkPresenceOfSyntheticMethods) {
+                checkPresenceOfSyntheticMethods(inspector);
+              }
+            })
+        .run(parameters.getRuntime(), Client.class.getCanonicalName())
+        .assertSuccessWithOutput(getExpectedOutput());
+  }
+
+  private void failsWithOption(List<byte[]> input, boolean option) throws Exception {
+    testForD8(parameters.getBackend())
+        .addProgramClassFileData(input)
+        .addOptionsModification(options -> options.processCovariantReturnTypeAnnotations = option)
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(inspector -> checkPresenceOfCovariantAnnotations(inspector, false))
+        .run(parameters.getRuntime(), Client.class.getCanonicalName())
+        .assertFailureWithErrorThatThrows(NoSuchMethodError.class);
+  }
+
+  private void succeedsIndependentOfFlag(
+      List<byte[]> input, boolean checkPresenceOfSyntheticMethods) throws Exception {
     succeedsWithOption(input, true, checkPresenceOfSyntheticMethods);
     succeedsWithOption(input, false, checkPresenceOfSyntheticMethods);
   }
 
-  private void failsIndependentOfFlag(AndroidApp input) throws Exception {
+  private void failsIndependentOfFlag(List<byte[]> input) throws Exception {
     failsWithOption(input, true);
     failsWithOption(input, false);
   }
 
-  private void checkPresenceOfCovariantAnnotations(AndroidApp app, boolean expected)
+  private void checkPresenceOfCovariantAnnotations(List<byte[]> input, boolean expected)
       throws Exception {
-    CodeInspector inspector = new CodeInspector(app);
+    CodeInspector inspector = new CodeInspector(buildAndroidApp(input));
+    checkPresenceOfCovariantAnnotations(inspector, expected);
+  }
+
+  private void checkPresenceOfCovariantAnnotations(CodeInspector inspector, boolean expected) {
     assertEquals(
         expected,
         inspector.allClasses().stream()
@@ -196,9 +235,7 @@
                         .anyMatch(method -> method.annotation(CRTS_TYPE_NAME).isPresent())));
   }
 
-  private void checkPresenceOfSyntheticMethods(AndroidApp output) throws Exception {
-    CodeInspector inspector = new CodeInspector(output);
-
+  private void checkPresenceOfSyntheticMethods(CodeInspector inspector) throws Exception {
     // Get classes A, B, and C.
     ClassSubject clazzA = inspector.clazz(A.class.getCanonicalName());
     assertThat(clazzA, isPresent());