Revert "Revert "Cast method call args in CVF fix if they don't match expected types""

This reverts commit 02c9ddf66c3c2e309ef94ac3e7cf41b0e343bfb1.

Original change was aosp/2430534. It seems some of the test outputs were slightly different under the AGP updgrade for some reason (this version has some additional lines like "@@ -55 +66" in the fix diffs).

Test: Updated unit tests from original change

Reason for revert: This change was reverted as part of the AGP downgrade but was unrelated.

Change-Id: I281ca286f5a4715597989ab30d82908663fa239d
diff --git a/lint-checks/integration-tests/src/main/java/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java b/lint-checks/integration-tests/src/main/java/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java
new file mode 100644
index 0000000..2128027
--- /dev/null
+++ b/lint-checks/integration-tests/src/main/java/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx;
+
+import android.widget.BaseAdapter;
+
+import androidx.annotation.RequiresApi;
+
+import java.nio.CharBuffer;
+
+/**
+ * Contains unsafe calls to a method with a variable number of arguments which are implicitly cast.
+ */
+@SuppressWarnings("unused")
+public class AutofixOnUnsafeCallWithImplicitVarArgsCast {
+    /**
+     * Calls the vararg method with no args.
+     */
+    @RequiresApi(27)
+    public void callVarArgsMethodNoArgs(BaseAdapter adapter) {
+        adapter.setAutofillOptions();
+    }
+
+    /**
+     *Calls the vararg method with one args.
+     */
+    @RequiresApi(27)
+    public void callVarArgsMethodOneArg(BaseAdapter adapter, CharBuffer vararg) {
+        adapter.setAutofillOptions(vararg);
+    }
+
+    /**
+     * Calls the vararg method with multiple args.
+     */
+    @RequiresApi(27)
+    public void callVarArgsMethodManyArgs(BaseAdapter adapter, CharBuffer vararg1,
+            CharBuffer vararg2, CharBuffer vararg3) {
+        adapter.setAutofillOptions(vararg1, vararg2, vararg3);
+    }
+}
diff --git a/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitParamCast.java b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitParamCast.java
new file mode 100644
index 0000000..cc20718
--- /dev/null
+++ b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitParamCast.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx;
+
+import android.app.Notification;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Tests to ensure the generated lint fix does not leave in implicit casts from a new argument type.
+ */
+@SuppressWarnings("unused")
+public class AutofixUnsafeCallWithImplicitParamCast {
+    /**
+     * This uses the Notification.MessagingStyle type, but setBuilder is defined on
+     * Notification.Style, and the two classes were introduced in different API levels.
+     */
+    @RequiresApi(24)
+    public void castReceiver(Notification.MessagingStyle style, Notification.Builder builder) {
+        style.setBuilder(builder);
+    }
+
+    /**
+     * This uses Notification.CarExtender, but extend is defined with Notification.Extender as a
+     * parameter, and the two classes were introduced at different API levels.
+     */
+    @RequiresApi(23)
+    public void castParameter(Notification.Builder builder, Notification.CarExtender extender) {
+        builder.extend(extender);
+    }
+}
diff --git a/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitCast.java b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitReturnCast.java
similarity index 95%
rename from lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitCast.java
rename to lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitReturnCast.java
index 0e074a7..0eed5cb 100644
--- a/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitCast.java
+++ b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeCallWithImplicitReturnCast.java
@@ -24,10 +24,10 @@
 import androidx.annotation.RequiresApi;
 
 /**
- * Tests to ensure the generated lint fix does not leave in implicit casts from a new type.
+ * Tests to ensure the generated lint fix does not leave in implicit casts from a new return type.
  */
 @SuppressWarnings("unused")
-public abstract class AutofixUnsafeCallWithImplicitCast {
+public abstract class AutofixUnsafeCallWithImplicitReturnCast {
     /**
      * This method creates an AdaptiveIconDrawable and implicitly casts it to Drawable.
      */
diff --git a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
index 62d19a0..f26db17 100644
--- a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
@@ -46,6 +46,7 @@
 import com.intellij.psi.PsiClassType
 import com.intellij.psi.PsiCompiledElement
 import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiEllipsisType
 import com.intellij.psi.PsiExpressionList
 import com.intellij.psi.PsiMethod
 import com.intellij.psi.PsiMethodCallExpression
@@ -67,6 +68,7 @@
 import org.jetbrains.uast.UThisExpression
 import org.jetbrains.uast.getContainingUClass
 import org.jetbrains.uast.getContainingUMethod
+import org.jetbrains.uast.isNullLiteral
 import org.jetbrains.uast.util.isConstructorCall
 import org.jetbrains.uast.util.isMethodCall
 
@@ -532,7 +534,8 @@
                 call.receiver,
                 call.valueArguments,
                 wrapperClassName,
-                wrapperMethodName
+                wrapperMethodName,
+                wrapperMethodParams
             )
 
             val fix = fix()
@@ -688,6 +691,7 @@
          * @param callValueArguments Arguments of the call to the platform method
          * @param wrapperClassName Name of the generated wrapper class
          * @param wrapperMethodName Name of the generated wrapper method
+         * @param wrapperMethodParams Param types of the wrapper method
          * @return Source code for a call to the static wrapper method
          */
         private fun generateWrapperCall(
@@ -696,6 +700,7 @@
             callValueArguments: List<UExpression>,
             wrapperClassName: String,
             wrapperMethodName: String,
+            wrapperMethodParams: List<PsiType>
         ): String {
             val callReceiverStr = when {
                 // Static method
@@ -708,15 +713,34 @@
                 // it must be a call to an instance method using `this` implicitly.
                 callReceiver == null ->
                     "this"
-                // Otherwise, use the original call receiver string (removing extra parens)
+                // Use the original call receiver string (removing extra parens), casting if needed
                 else ->
-                    unwrapExpression(callReceiver).asSourceString()
+                    createArgumentString(unwrapExpression(callReceiver), wrapperMethodParams[0])
             }
 
             val callValues = if (callValueArguments.isNotEmpty()) {
-                callValueArguments.joinToString(separator = ", ") { argument ->
-                    argument.asSourceString()
+                // The first element in the wrapperMethodParams is the receiver, so drop that.
+                // Also drop the last parameter, because it is special-cased later.
+                val paramTypesWithoutReceiverAndFinal = wrapperMethodParams.drop(1).dropLast(1)
+                // For varargs methods, what we care about for the last type is the type of each
+                // vararg, not the containing type.
+                val finalParamType = if (method.isVarArgs) {
+                    (wrapperMethodParams.last() as PsiEllipsisType).componentType
+                } else {
+                    wrapperMethodParams.last()
                 }
+
+                callValueArguments.mapIndexed { argIndex, arg ->
+                    // The number of args might be greater than the number of param types due to
+                    // varargs, repeat the final param type for all args after exhausting the
+                    // paramTypesWithoutReceiverAndFinal list.
+                    val expectedType = if (argIndex < paramTypesWithoutReceiverAndFinal.size) {
+                        paramTypesWithoutReceiverAndFinal[argIndex]
+                    } else {
+                        finalParamType
+                    }
+                    createArgumentString(arg, expectedType)
+                }.joinToString(separator = ", ")
             } else {
                 null
             }
@@ -727,6 +751,24 @@
         }
 
         /**
+         * Creates the string representation of an argument in the wrapper call. If the type of the
+         * arg is not identical to the parameter type of the wrapper method, casts to that type.
+         */
+        private fun createArgumentString(arg: UExpression, expectedType: PsiType): String {
+            val argType = arg.getExpressionType()
+            val expectedTypeText = expectedType.canonicalText
+            // If the arg is the expected type, use as normal, otherwise, cast to expected type.
+            // Uses text-base equality instead of directly comparing types because certain types
+            // (eq. java.lang.Class<T>) are not necessarily equal to instances of the same type.
+            // There isn't really a point in casting if the arg is null.
+            return if (argType?.equalsToText(expectedTypeText) == true || arg.isNullLiteral()) {
+                arg.asSourceString()
+            } else {
+                "($expectedTypeText) ${arg.asSourceString()}"
+            }
+        }
+
+        /**
          * Remove parentheses from the expression (unwrap the expression until it is no longer a
          * UParenthesizedExpression).
          */
diff --git a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
index 55398d8..5cfe867 100644
--- a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
+++ b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
@@ -82,7 +82,7 @@
 Fix for src/androidx/sample/core/widget/ListViewCompat.java line 39: Extract to static inner class:
 @@ -39 +39
 -             listView.scrollListBy(y);
-+             Api19Impl.scrollListBy(listView, y);
++             Api19Impl.scrollListBy((android.widget.AbsListView) listView, y);
 @@ -91 +91
 + @androidx.annotation.RequiresApi(19)
 + static class Api19Impl {
@@ -100,7 +100,7 @@
 Fix for src/androidx/sample/core/widget/ListViewCompat.java line 69: Extract to static inner class:
 @@ -69 +69
 -             return listView.canScrollList(direction);
-+             return Api19Impl.canScrollList(listView, direction);
++             return Api19Impl.canScrollList((android.widget.AbsListView) listView, direction);
 @@ -91 +91
 + @androidx.annotation.RequiresApi(19)
 + static class Api19Impl {
@@ -530,7 +530,7 @@
 Fix for src/androidx/AutofixUnsafeCallToThis.java line 48: Extract to static inner class:
 @@ -48 +48
 -             this.getClipToPadding();
-+             Api21Impl.getClipToPadding(this);
++             Api21Impl.getClipToPadding((ViewGroup) this);
 @@ -60 +60
 + @androidx.annotation.RequiresApi(21)
 + static class Api21Impl {
@@ -609,34 +609,34 @@
     }
 
     @Test
-    fun `Auto-fix with implicit class cast from new type (issue 214389795)`() {
+    fun `Auto-fix with implicit class cast from new return type (issue 214389795)`() {
         val input = arrayOf(
-            javaSample("androidx.AutofixUnsafeCallWithImplicitCast"),
+            javaSample("androidx.AutofixUnsafeCallWithImplicitReturnCast"),
             RequiresApi
         )
 
         /* ktlint-disable max-line-length */
         val expected = """
-src/androidx/AutofixUnsafeCallWithImplicitCast.java:36: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:36: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
         return new AdaptiveIconDrawable(null, null);
                ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitCast.java:44: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:44: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
         return new AdaptiveIconDrawable(null, null);
                ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitCast.java:52: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:52: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
         return Icon.createWithAdaptiveBitmap(null);
                     ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitCast.java:60: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:60: Error: This call references a method added in API level 26; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
         return Icon.createWithAdaptiveBitmap(null);
                     ~~~~~~~~~~~~~~~~~~~~~~~~
-src/androidx/AutofixUnsafeCallWithImplicitCast.java:68: Error: This call references a method added in API level 24; however, the containing class androidx.AutofixUnsafeCallWithImplicitCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java:68: Error: This call references a method added in API level 24; however, the containing class androidx.AutofixUnsafeCallWithImplicitReturnCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
         useStyle(new Notification.DecoratedCustomViewStyle());
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 5 errors, 0 warnings
         """
 
         val expectedFix = """
-Fix for src/androidx/AutofixUnsafeCallWithImplicitCast.java line 36: Extract to static inner class:
+Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 36: Extract to static inner class:
 @@ -36 +36
 -         return new AdaptiveIconDrawable(null, null);
 +         return Api26Impl.createAdaptiveIconDrawableReturnsDrawable(null, null);
@@ -654,7 +654,7 @@
 +
 @@ -78 +89
 + }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitCast.java line 44: Extract to static inner class:
+Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 44: Extract to static inner class:
 @@ -44 +44
 -         return new AdaptiveIconDrawable(null, null);
 +         return Api26Impl.createAdaptiveIconDrawable(null, null);
@@ -672,7 +672,7 @@
 +
 @@ -78 +89
 + }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitCast.java line 52: Extract to static inner class:
+Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 52: Extract to static inner class:
 @@ -52 +52
 -         return Icon.createWithAdaptiveBitmap(null);
 +         return Api26Impl.createWithAdaptiveBitmapReturnsObject(null);
@@ -690,7 +690,7 @@
 +
 @@ -78 +89
 + }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitCast.java line 60: Extract to static inner class:
+Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 60: Extract to static inner class:
 @@ -60 +60
 -         return Icon.createWithAdaptiveBitmap(null);
 +         return Api26Impl.createWithAdaptiveBitmap(null);
@@ -708,7 +708,7 @@
 +
 @@ -78 +89
 + }
-Fix for src/androidx/AutofixUnsafeCallWithImplicitCast.java line 68: Extract to static inner class:
+Fix for src/androidx/AutofixUnsafeCallWithImplicitReturnCast.java line 68: Extract to static inner class:
 @@ -68 +68
 -         useStyle(new Notification.DecoratedCustomViewStyle());
 +         useStyle(Api24Impl.createDecoratedCustomViewStyleReturnsStyle());
@@ -769,4 +769,147 @@
 
         check(*input).expect(expected).expectFixDiffs(expectedFix)
     }
+
+    @Test
+    fun `Auto-fix with implicit class cast from new parameter type (issue 266845827)`() {
+        val input = arrayOf(
+            javaSample("androidx.AutofixUnsafeCallWithImplicitParamCast"),
+            RequiresApi
+        )
+
+        /* ktlint-disable max-line-length */
+        val expected = """
+src/androidx/AutofixUnsafeCallWithImplicitParamCast.java:34: Error: This call references a method added in API level 16; however, the containing class androidx.AutofixUnsafeCallWithImplicitParamCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+        style.setBuilder(builder);
+              ~~~~~~~~~~
+src/androidx/AutofixUnsafeCallWithImplicitParamCast.java:43: Error: This call references a method added in API level 20; however, the containing class androidx.AutofixUnsafeCallWithImplicitParamCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+        builder.extend(extender);
+                ~~~~~~
+2 errors, 0 warnings
+        """
+
+        val expectedFix = """
+Fix for src/androidx/AutofixUnsafeCallWithImplicitParamCast.java line 34: Extract to static inner class:
+@@ -34 +34
+-         style.setBuilder(builder);
++         Api16Impl.setBuilder((Notification.Style) style, builder);
+@@ -45 +45
++ @RequiresApi(16)
++ static class Api16Impl {
++     private Api16Impl() {
++         // This class is not instantiable.
++     }
++
++     @DoNotInline
++     static void setBuilder(Notification.Style style, Notification.Builder builder) {
++         style.setBuilder(builder);
++     }
++
+@@ -46 +57
++ }
+Fix for src/androidx/AutofixUnsafeCallWithImplicitParamCast.java line 43: Extract to static inner class:
+@@ -43 +43
+-         builder.extend(extender);
++         Api20Impl.extend(builder, (Notification.Extender) extender);
+@@ -45 +45
++ @RequiresApi(20)
++ static class Api20Impl {
++     private Api20Impl() {
++         // This class is not instantiable.
++     }
++
++     @DoNotInline
++     static Notification.Builder extend(Notification.Builder builder, Notification.Extender extender) {
++         return builder.extend(extender);
++     }
++
+@@ -46 +57
++ }
+        """
+        /* ktlint-enable max-line-length */
+
+        check(*input).expect(expected).expectFixDiffs(expectedFix)
+    }
+
+    @Test
+    fun `Auto-fix for method with varargs that are implicitly cast (issue 266845827)`() {
+        val input = arrayOf(
+            javaSample("androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast"),
+            RequiresApi
+        )
+
+        /* ktlint-disable max-line-length */
+        val expected = """
+src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:35: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+        adapter.setAutofillOptions();
+                ~~~~~~~~~~~~~~~~~~
+src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:43: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+        adapter.setAutofillOptions(vararg);
+                ~~~~~~~~~~~~~~~~~~
+src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java:52: Error: This call references a method added in API level 27; however, the containing class androidx.AutofixOnUnsafeCallWithImplicitVarArgsCast is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+        adapter.setAutofillOptions(vararg1, vararg2, vararg3);
+                ~~~~~~~~~~~~~~~~~~
+3 errors, 0 warnings
+        """
+
+        val expectedFix = """
+Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 35: Extract to static inner class:
+@@ -35 +35
+-         adapter.setAutofillOptions();
++         Api27Impl.setAutofillOptions(adapter);
+@@ -54 +54
++ @RequiresApi(27)
++ static class Api27Impl {
++     private Api27Impl() {
++         // This class is not instantiable.
++     }
++
++     @DoNotInline
++     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
++         baseAdapter.setAutofillOptions(options);
++     }
++
+@@ -55 +66
++ }
+Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 43: Extract to static inner class:
+@@ -43 +43
+-         adapter.setAutofillOptions(vararg);
++         Api27Impl.setAutofillOptions(adapter, (java.lang.CharSequence) vararg);
+@@ -54 +54
++ @RequiresApi(27)
++ static class Api27Impl {
++     private Api27Impl() {
++         // This class is not instantiable.
++     }
++
++     @DoNotInline
++     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
++         baseAdapter.setAutofillOptions(options);
++     }
++
+@@ -55 +66
++ }
+Fix for src/androidx/AutofixOnUnsafeCallWithImplicitVarArgsCast.java line 52: Extract to static inner class:
+@@ -52 +52
+-         adapter.setAutofillOptions(vararg1, vararg2, vararg3);
++         Api27Impl.setAutofillOptions(adapter, (java.lang.CharSequence) vararg1, (java.lang.CharSequence) vararg2, (java.lang.CharSequence) vararg3);
+@@ -54 +54
++ @RequiresApi(27)
++ static class Api27Impl {
++     private Api27Impl() {
++         // This class is not instantiable.
++     }
++
++     @DoNotInline
++     static void setAutofillOptions(BaseAdapter baseAdapter, java.lang.CharSequence... options) {
++         baseAdapter.setAutofillOptions(options);
++     }
++
+@@ -55 +66
++ }
+        """
+        /* ktlint-enable max-line-length */
+
+        check(*input).expect(expected).expectFixDiffs(expectedFix)
+    }
 }