Work around field initializer exception

This is https://youtrack.jetbrains.com/issue/KT-63552, which is fixed
but we don't have the latest build, work around it in the meantime.

Bug: 300081840
Test: Added test, followup CL passes AndroidX presubmit target
Change-Id: I45a802e7ebe232506e206131501b6569b5186fdb
diff --git a/metalava-model-psi/src/main/java/com/android/tools/metalava/model/psi/PsiFieldItem.kt b/metalava-model-psi/src/main/java/com/android/tools/metalava/model/psi/PsiFieldItem.kt
index bf80eba..bf5f8cf 100644
--- a/metalava-model-psi/src/main/java/com/android/tools/metalava/model/psi/PsiFieldItem.kt
+++ b/metalava-model-psi/src/main/java/com/android/tools/metalava/model/psi/PsiFieldItem.kt
@@ -23,6 +23,7 @@
 import com.intellij.psi.PsiCallExpression
 import com.intellij.psi.PsiClass
 import com.intellij.psi.PsiEnumConstant
+import com.intellij.psi.PsiExpression
 import com.intellij.psi.PsiField
 import com.intellij.psi.PsiModifierListOwner
 import com.intellij.psi.PsiPrimitiveType
@@ -74,13 +75,27 @@
         }
 
         return if (!requireConstant) {
-            val initializer = psiField.initializer ?: return null
+            val initializer = psiField.safeInitializer() ?: return null
             JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false)
         } else {
             null
         }
     }
 
+    /**
+     * Work around exception from getting initializer of emptyArray() / arrayOf():
+     * https://youtrack.jetbrains.com/issue/KT-63552
+     *
+     * TODO(b/316343051): remove this workaround
+     */
+    private fun PsiField.safeInitializer(): PsiExpression? {
+        return try {
+            initializer
+        } catch (e: NoSuchElementException) {
+            null
+        }
+    }
+
     override fun isEnumConstant(): Boolean = isEnumConstant
 
     override fun name(): String = name
@@ -187,7 +202,7 @@
             // field initialization. If that right hand side for example represents a method call,
             // and the method we're calling is annotated with @NonNull, then the field (since it is
             // final) will always be @NonNull as well.
-            when (val initializer = psiField.initializer) {
+            when (val initializer = psiField.safeInitializer()) {
                 is PsiReference -> {
                     val resolved = initializer.resolve()
                     if (
diff --git a/metalava-model-psi/src/test/java/com/android/tools/metalava/model/psi/PsiFieldItemTest.kt b/metalava-model-psi/src/test/java/com/android/tools/metalava/model/psi/PsiFieldItemTest.kt
index 83e352e..6dcc131 100644
--- a/metalava-model-psi/src/test/java/com/android/tools/metalava/model/psi/PsiFieldItemTest.kt
+++ b/metalava-model-psi/src/test/java/com/android/tools/metalava/model/psi/PsiFieldItemTest.kt
@@ -19,6 +19,7 @@
 import com.android.tools.metalava.testing.kotlin
 import kotlin.test.Test
 import kotlin.test.assertNotNull
+import kotlin.test.assertNull
 import kotlin.test.assertSame
 
 class PsiFieldItemTest : BasePsiTest() {
@@ -31,4 +32,23 @@
             assertSame(field, field.property?.backingField)
         }
     }
+
+    @Test
+    fun `no error for initializer of arrayOf`() {
+        testCodebase(
+            kotlin(
+                """
+                package test.pkg
+                class Foo {
+                    val x: Array<String> = arrayOf()
+                }
+            """
+            )
+        ) { codebase ->
+            val fooClass = codebase.assertClass("test.pkg.Foo")
+            val x = fooClass.fields().single()
+            assertNull(x.initialValue(false))
+            assertNull(x.implicitNullness())
+        }
+    }
 }