Use fully qualified class names in class verification failure autofix
This is a similar issue to aosp/2120172, but that only fixed the call receiver type.
Unit tests and studio shorten names differently, and for the two tests updated in this CL the previous behavior is better and still what happens in studio.
For one test (with java.lang.Class), the new test behavior is also correct. For the other (with drawable.Drawable), the new test behavior is incorrect: b/241573146. I'll file a separate bug to look at the test again for after the lint bug is responded to.
Test: Replaced existing unit test for qualified receiver type to also use qualified type for param and return.
Bug: 236721202
Change-Id: I73c2d7cf78e8e568b6cee11258ac6a09061ab300
diff --git a/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeMethodWithQualifiedClass.java b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeMethodWithQualifiedClass.java
index 86767db..3f660a4 100644
--- a/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeMethodWithQualifiedClass.java
+++ b/lint-checks/integration-tests/src/main/java/androidx/AutofixUnsafeMethodWithQualifiedClass.java
@@ -16,22 +16,25 @@
package androidx;
-import android.view.SearchEvent;
-import android.view.Window;
+import android.print.PrintAttributes;
import androidx.annotation.RequiresApi;
/**
- * Test class containing unsafe method reference that uses a value defined with a qualified class.
+ * Test class containing unsafe method reference that uses qualified class names.
*/
@SuppressWarnings("unused")
public class AutofixUnsafeMethodWithQualifiedClass {
/**
- * This method uses Window.Callback (not Callback), so the fix should also use Window.Callback.
+ * This method call:
+ * - has a receiver of type PrintAttributes.Builder
+ * - takes param of type PrintAttributes.MediaSize
+ * - has return type PrintAttributes.Builder
+ * In the generated fix, all three types should appear as qualified class names.
*/
- @RequiresApi(23)
- public boolean unsafeReferenceOnQualifiedClass(Window.Callback callback,
- SearchEvent searchEvent) {
- return callback.onSearchRequested(searchEvent);
+ @RequiresApi(19)
+ public void unsafeReferenceWithQualifiedClasses(PrintAttributes.Builder builder,
+ PrintAttributes.MediaSize mediaSize) {
+ builder.setMediaSize(mediaSize);
}
}
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 56316d6..8437ae7 100644
--- a/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/ClassVerificationFailureDetector.kt
@@ -704,7 +704,7 @@
}
val typedParams = method.parameters.map { param ->
- "${(param.type as? PsiType)?.presentableText} ${param.name}"
+ "${(param.type as? PsiType)?.canonicalText} ${param.name}"
}
val typedParamsStr = (listOfNotNull(hostParam) + typedParams).joinToString(", ")
@@ -724,7 +724,7 @@
receiverStr = "new "
} else {
wrapperMethodName = methodName
- returnTypeStr = method.returnType?.presentableText ?: "void"
+ returnTypeStr = method.returnType?.canonicalText ?: "void"
returnStmtStr = if ("void" == returnTypeStr) "" else "return "
receiverStr = if (isStatic) "$hostType." else "$hostVar."
}
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 aa02f01..4c7d4ab 100644
--- a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
+++ b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
@@ -301,7 +301,7 @@
+ }
+
+ @annotation.DoNotInline
-+ static <T> T getSystemService(Context context, Class<T> serviceClass) {
++ static <T> T getSystemService(Context context, java.lang.Class<T> serviceClass) {
+ return context.getSystemService(serviceClass);
+ }
+
@@ -377,7 +377,7 @@
+ }
+
+ @DoNotInline
-+ static void getOutline(Drawable drawable, Outline outline) {
++ static void getOutline(drawable.Drawable drawable, Outline outline) {
+ drawable.getOutline(outline);
+ }
+
@@ -395,7 +395,7 @@
+ }
+
+ @DoNotInline
-+ static void getOutline(Drawable drawable, Outline outline) {
++ static void getOutline(drawable.Drawable drawable, Outline outline) {
+ drawable.getOutline(outline);
+ }
+
@@ -408,7 +408,7 @@
}
@Test
- fun `Auto-fix includes fully qualified class name (issue 205035683)`() {
+ fun `Auto-fix includes fully qualified class name (issue 205035683, 236721202)`() {
val input = arrayOf(
javaSample("androidx.AutofixUnsafeMethodWithQualifiedClass"),
RequiresApi
@@ -416,30 +416,30 @@
/* ktlint-disable max-line-length */
val expected = """
-src/androidx/AutofixUnsafeMethodWithQualifiedClass.java:35: Error: This call references a method added in API level 23; however, the containing class androidx.AutofixUnsafeMethodWithQualifiedClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
- return callback.onSearchRequested(searchEvent);
- ~~~~~~~~~~~~~~~~~
+src/androidx/AutofixUnsafeMethodWithQualifiedClass.java:38: Error: This call references a method added in API level 19; however, the containing class androidx.AutofixUnsafeMethodWithQualifiedClass is reachable from earlier API levels and will fail run-time class verification. [ClassVerificationFailure]
+ builder.setMediaSize(mediaSize);
+ ~~~~~~~~~~~~
1 errors, 0 warnings
"""
val expectedFixDiffs = """
-Fix for src/androidx/AutofixUnsafeMethodWithQualifiedClass.java line 35: Extract to static inner class:
-@@ -35 +35
-- return callback.onSearchRequested(searchEvent);
-+ return Api23Impl.onSearchRequested(callback, searchEvent);
-@@ -37 +37
-+ @RequiresApi(23)
-+ static class Api23Impl {
-+ private Api23Impl() {
+Fix for src/androidx/AutofixUnsafeMethodWithQualifiedClass.java line 38: Extract to static inner class:
+@@ -38 +38
+- builder.setMediaSize(mediaSize);
++ Api19Impl.setMediaSize(builder, mediaSize);
+@@ -40 +40
++ @RequiresApi(19)
++ static class Api19Impl {
++ private Api19Impl() {
+ // This class is not instantiable.
+ }
+
+ @DoNotInline
-+ static boolean onSearchRequested(Window.Callback callback, SearchEvent p) {
-+ return callback.onSearchRequested(p);
++ static PrintAttributes.Builder setMediaSize(PrintAttributes.Builder builder, PrintAttributes.MediaSize mediaSize) {
++ return builder.setMediaSize(mediaSize);
+ }
+
-@@ -38 +49
+@@ -41 +52
+ }
"""
/* ktlint-enable max-line-length */