Update metalava to work with reified methods

This CL updates metalava to work with the latest UAST
which includes the fix for
https://youtrack.jetbrains.com/issue/KT-34316.

Sadly, we found a new regression (see comment in ApiFileTest)
https://youtrack.jetbrains.com/issue/KT-38173

Test: Unit tests included and updated
Bug: 152039666
Bug: KT-34316
Change-Id: Ic28b1bb39ba6b3fe8551a1c53f060ebbbe09f148
diff --git a/build.gradle.kts b/build.gradle.kts
index 39e8b04..8d9434b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -54,7 +54,7 @@
     }
 }
 
-val studioVersion: String = "27.0.0-beta02"
+val studioVersion: String = "27.1.0-alpha05"
 val kotlinVersion: String = "1.3.20"
 
 dependencies {
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
index fa4cef8..69aa109 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiModifierItem.kt
@@ -25,7 +25,6 @@
 import com.android.tools.metalava.model.ModifierList
 import com.android.tools.metalava.model.MutableModifierList
 import com.intellij.psi.PsiDocCommentOwner
-import com.intellij.psi.PsiMethod
 import com.intellij.psi.PsiModifier
 import com.intellij.psi.PsiModifierList
 import com.intellij.psi.PsiModifierListOwner
@@ -42,7 +41,7 @@
 import org.jetbrains.uast.UMethod
 import org.jetbrains.uast.UVariable
 import org.jetbrains.uast.kotlin.KotlinNullabilityUAnnotation
-import org.jetbrains.uast.kotlin.declarations.KotlinUMethodWithFakeLightDelegate
+import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
 
 class PsiModifierItem(
     codebase: Codebase,
@@ -110,8 +109,8 @@
             var ktModifierList: KtModifierList? = null
             if (modifierList is KtLightModifierList<*>) {
                 ktModifierList = modifierList.kotlinOrigin
-            } else if (modifierList is LightModifierList && element is KotlinUMethodWithFakeLightDelegate) {
-                ktModifierList = element.original.modifierList
+            } else if (modifierList is LightModifierList && element is KotlinUMethod) {
+                ktModifierList = element.sourcePsi?.modifierList
             }
             if (ktModifierList != null) {
                 if (ktModifierList.hasModifier(KtTokens.VARARG_KEYWORD)) {
@@ -129,9 +128,9 @@
                 if (ktModifierList.hasModifier(KtTokens.INFIX_KEYWORD)) {
                     flags = flags or INFIX
                 }
-                    if (ktModifierList.hasModifier(KtTokens.CONST_KEYWORD)) {
-                        flags = flags or CONST
-                    }
+                if (ktModifierList.hasModifier(KtTokens.CONST_KEYWORD)) {
+                    flags = flags or CONST
+                }
                 if (ktModifierList.hasModifier(KtTokens.OPERATOR_KEYWORD)) {
                     flags = flags or OPERATOR
                 }
@@ -139,16 +138,14 @@
                     flags = flags or INLINE
 
                     // Workaround for b/117565118:
-                    if (element is PsiMethod) {
-                        val t =
-                            ((element as? UMethod)?.sourcePsi as? KtNamedFunction)?.typeParameterList?.text ?: ""
-                        if (t.contains("reified") &&
-                            !ktModifierList.hasModifier(KtTokens.PRIVATE_KEYWORD) &&
-                            !ktModifierList.hasModifier(KtTokens.INTERNAL_KEYWORD)
-                        ) {
-                            // Switch back from private to public
-                            visibilityFlags = PUBLIC
-                        }
+                    val func = (element as? UMethod)?.sourcePsi as? KtNamedFunction
+                    if (func != null &&
+                        (func.typeParameterList?.text ?: "").contains("reified") &&
+                        !ktModifierList.hasModifier(KtTokens.PRIVATE_KEYWORD) &&
+                        !ktModifierList.hasModifier(KtTokens.INTERNAL_KEYWORD)
+                    ) {
+                        // Switch back from private to public
+                        visibilityFlags = PUBLIC
                     }
                 }
                 if (ktModifierList.hasModifier(KtTokens.SUSPEND_KEYWORD)) {
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
index ead3577..c76c984 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
@@ -50,7 +50,6 @@
 import com.intellij.psi.PsiWildcardType
 import com.intellij.psi.util.PsiTypesUtil
 import com.intellij.psi.util.TypeConversionUtil
-import org.jetbrains.kotlin.asJava.elements.KtLightTypeParameter
 import java.util.function.Predicate
 
 /** Represents a type backed by PSI */
@@ -534,7 +533,7 @@
                             sb.append(">")
                             return
                         } else if (element is PsiTypeParameter) {
-                            if (element is KtLightTypeParameter && element.kotlinOrigin.text.startsWith("reified")) {
+                            if (PsiTypeParameterItem.isReified(element)) {
                                 sb.append("reified ")
                             }
                             sb.append(element.name)
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeParameterItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeParameterItem.kt
index 91d27ee..de15c4a 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeParameterItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeParameterItem.kt
@@ -20,6 +20,7 @@
 import com.android.tools.metalava.model.TypeParameterItem
 import com.android.tools.metalava.model.psi.ClassType.TYPE_PARAMETER
 import com.intellij.psi.PsiTypeParameter
+import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterBuilder
 import org.jetbrains.kotlin.asJava.elements.KtLightTypeParameter
 
 class PsiTypeParameterItem(
@@ -42,7 +43,7 @@
     override fun bounds(): List<ClassItem> = bounds
 
     override fun isReified(): Boolean {
-        return element is KtLightTypeParameter && element.kotlinOrigin.text.startsWith("reified")
+        return isReified(element as? PsiTypeParameter)
     }
 
     private lateinit var bounds: List<ClassItem>
@@ -75,5 +76,18 @@
             item.initialize(emptyList(), emptyList(), emptyList(), emptyList(), emptyList())
             return item
         }
+
+        fun isReified(element: PsiTypeParameter?): Boolean {
+            element ?: return false
+            if (element is KtLightTypeParameter &&
+                element.kotlinOrigin.text.startsWith("reified")) {
+                return true
+            } else if (element is KotlinLightTypeParameterBuilder) {
+                if (element.sourcePsi.text.startsWith("reified")) {
+                    return true
+                }
+            }
+            return false
+        }
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
index 5a62c2a..8c4f3f5 100644
--- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
@@ -416,27 +416,11 @@
                     method public final <T> T getSystemService(java.lang.Class<T>);
                   }
                   public final class _java_Kt {
-                    method public inline <T> T systemService1();
+                    method public static inline <reified T> T systemService1(test.pkg.Context);
                     method public static inline java.lang.String systemService2(test.pkg.Context);
                   }
                 }
                 """
-// b/152039666 parameters from methods using reified types are dropped
-// API should contain <reified T>
-// Actual expected output:
-//          api = """
-//                package test.pkg {
-//                  public class Context {
-//                    ctor public Context();
-//                    method public final <T> T getSystemService(java.lang.Class<T>);
-//                  }
-//                  public final class _java_Kt {
-//                    method public static inline <reified T> T systemService1(test.pkg.Context);
-//                    method public static inline java.lang.String systemService2(test.pkg.Context);
-//                  }
-//                }
-//                """
-
         )
     }
 
@@ -464,25 +448,12 @@
                 package test.pkg {
                   public final class TestKt {
                     method public static inline <T> void a(@Nullable T t);
-                    method public inline <T> void b();
-                    method public inline <T> void e();
-                    method public inline <T> void f();
+                    method public static inline <reified T> void b(@Nullable T t);
+                    method public static inline <reified T> void e(@Nullable T t);
+                    method public static inline <reified T> void f(@Nullable T, @Nullable T t);
                   }
                 }
                 """
-// b/152039666 parameters from methods using reified types are dropped
-// API should contain <reified T>
-// Actual expected output:
-//          api = """
-//                package test.pkg {
-//                  public final class TestKt {
-//                    method public static inline <T> void a(@Nullable T t);
-//                    method public static inline <reified T> void b(@Nullable T t);
-//                    method public static inline <reified T> void e(@Nullable T t);
-//                    method public static inline <reified T> void f(@Nullable T, @Nullable T t);
-//                  }
-//                }
-//                """
         )
     }
 
@@ -614,13 +585,12 @@
                 // Signature format: 3.0
                 package test.pkg {
                   public final class TestKt {
-                    method @UiThread public inline <Args> test.pkg2.NavArgsLazy<Args>! navArgs();
+                    method @UiThread public static inline <reified Args> test.pkg2.NavArgsLazy<Args>! navArgs(test.pkg2.Fragment);
                   }
                 }
                 """,
-// b/152039666 parameters from methods using reified types are dropped
-// API should contain <reified T>
-// Actual expected output:
+//            Actual expected API is below. However, due to KT-38173 the extends information is
+//              missing
 //            api = """
 //                // Signature format: 3.0
 //                package test.pkg {
diff --git a/src/test/java/com/android/tools/metalava/ApiLintTest.kt b/src/test/java/com/android/tools/metalava/ApiLintTest.kt
index be56d35..12532b3 100644
--- a/src/test/java/com/android/tools/metalava/ApiLintTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiLintTest.kt
@@ -837,6 +837,7 @@
                 src/android/pkg/CheckSynchronization.java:23: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization.errorMethod3() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
                 src/android/pkg/CheckSynchronization2.kt:5: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization2.errorMethod1() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
                 src/android/pkg/CheckSynchronization2.kt:8: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization2.errorMethod2() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
+                src/android/pkg/CheckSynchronization2.kt:13: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization2.errorMethod3() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
                 src/android/pkg/CheckSynchronization2.kt:16: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization2.errorMethod4() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
                 src/android/pkg/CheckSynchronization2.kt:18: error: Internal locks must not be exposed (synchronizing on this or class is still externally observable): method android.pkg.CheckSynchronization2.errorMethod5() [VisiblySynchronized] [Rule M5 in go/android-api-guidelines]
                 """,
diff --git a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
index 22805d1..bfb4e07 100644
--- a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
+++ b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
@@ -2479,20 +2479,10 @@
         check(
             compatibilityMode = false,
             inputKotlinStyleNulls = true,
-// b/152039666 parameters from methods using reified types are dropped
-// API should contain <reified T>, but now it sees it as removed / added methods
-// Actual expected output:
-//          warnings = """
-//            src/test/pkg/test.kt:5: error: Method test.pkg.TestKt.add made type variable T reified: incompatible change [ChangedThrows]
-//            src/test/pkg/test.kt:8: error: Method test.pkg.TestKt.two made type variable S reified: incompatible change [ChangedThrows]
-//            """,
             warnings = """
-                src/test/pkg/test.kt: error: Added method test.pkg.TestKt.add() [AddedMethod]
-                TESTROOT/current-api.txt:3: error: Removed method test.pkg.TestKt.add(T) [RemovedMethod]
-                src/test/pkg/test.kt: error: Added method test.pkg.TestKt.two() [AddedMethod]
-                TESTROOT/current-api.txt:6: error: Removed method test.pkg.TestKt.two(S,T) [RemovedMethod]
-                src/test/pkg/test.kt: error: Added method test.pkg.TestKt.unchanged() [AddedMethod]
-                TESTROOT/current-api.txt:5: error: Removed method test.pkg.TestKt.unchanged(T) [RemovedMethod]           """,
+                src/test/pkg/test.kt:5: error: Method test.pkg.TestKt.add made type variable T reified: incompatible change [ChangedThrows]
+                src/test/pkg/test.kt:8: error: Method test.pkg.TestKt.two made type variable S reified: incompatible change [ChangedThrows]
+                """,
             checkCompatibilityApi = """
                 package test.pkg {
                   public final class TestKt {