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())
+ }
+ }
}