aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Sladkey <fsladkey@google.com>2024-05-10 15:06:14 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-05-10 15:06:14 +0000
commit9cf5a1c34dc99cc5d470bda7214abf1398c7db76 (patch)
tree6c9508f04a1c4cc72de9d624ef3d08f0c335f279
parentaf148c71b7970c64f5696b8981bcb9ff109bf28d (diff)
parenta65d2253abb0aae1e74d579c96c6b83024efe163 (diff)
downloadsupport-9cf5a1c34dc99cc5d470bda7214abf1398c7db76.tar.gz
Merge "Add enum entry parsing" into androidx-main
-rw-r--r--binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KLibDumpParser.kt26
-rw-r--r--binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensions.kt8
-rw-r--r--binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KLibDumpParserTest.kt20
-rw-r--r--binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensionsTest.kt23
-rw-r--r--binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/resources/annotation.txt148
5 files changed, 224 insertions, 1 deletions
diff --git a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KLibDumpParser.kt b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KLibDumpParser.kt
index 80e1bf97dbb..ebf8e738950 100644
--- a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KLibDumpParser.kt
+++ b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KLibDumpParser.kt
@@ -24,6 +24,7 @@ package androidx.binarycompatibilityvalidator
import org.jetbrains.kotlin.library.abi.AbiClass
import org.jetbrains.kotlin.library.abi.AbiCompoundName
import org.jetbrains.kotlin.library.abi.AbiDeclaration
+import org.jetbrains.kotlin.library.abi.AbiEnumEntry
import org.jetbrains.kotlin.library.abi.AbiFunction
import org.jetbrains.kotlin.library.abi.AbiModality
import org.jetbrains.kotlin.library.abi.AbiProperty
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.library.abi.LibraryAbi
import org.jetbrains.kotlin.library.abi.LibraryManifest
import org.jetbrains.kotlin.library.abi.impl.AbiClassImpl
import org.jetbrains.kotlin.library.abi.impl.AbiConstructorImpl
+import org.jetbrains.kotlin.library.abi.impl.AbiEnumEntryImpl
import org.jetbrains.kotlin.library.abi.impl.AbiFunctionImpl
import org.jetbrains.kotlin.library.abi.impl.AbiPropertyImpl
import org.jetbrains.kotlin.library.abi.impl.AbiSignaturesImpl
@@ -118,6 +120,8 @@ class KlibDumpParser(klibDump: String) {
return parseFunction(parentQualifiedName)
} else if (cursor.hasPropertyKind()) {
return parseProperty(parentQualifiedName)
+ } else if (cursor.hasEnumEntry()) {
+ return parseEnumEntry(parentQualifiedName)
} else if (cursor.currentLine.isBlank()) {
cursor.nextLine()
} else {
@@ -210,6 +214,27 @@ class KlibDumpParser(klibDump: String) {
)
}
+ internal fun parseEnumEntry(parentQualifiedName: AbiQualifiedName?): AbiEnumEntry {
+ cursor.parseEnumEntryKind()
+ val enumName = cursor.parseEnumName()
+ ?: throw ParseException(cursor, "Failed to parse enum name")
+ val relativeName = parentQualifiedName?.let {
+ it.relativeName.value + "." + enumName
+ } ?: throw ParseException(cursor, "Enum entry must have parent qualified name")
+ val qualifiedName = AbiQualifiedName(
+ parentQualifiedName.packageName,
+ AbiCompoundName(
+ relativeName
+ )
+ )
+ cursor.nextLine()
+ return AbiEnumEntryImpl(
+ qualifiedName = qualifiedName,
+ signatures = fakeSignatures,
+ annotations = emptySet()
+ )
+ }
+
/** Parse all declarations which belong to a parent such as a class **/
private fun parseChildDeclarations(
parentQualifiedName: AbiQualifiedName?
@@ -333,6 +358,7 @@ class KlibDumpParser(klibDump: String) {
companion object {
// placeholder signatures, currently not considered during parsing / compatibility checking
+ // https://github.com/JetBrains/kotlin/blob/master/compiler/util-klib-abi/ReadMe.md
private val fakeSignatures = AbiSignaturesImpl(
signatureV1 = null,
signatureV2 = null
diff --git a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensions.kt b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensions.kt
index dfc2502f6be..e3efaac6dab 100644
--- a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensions.kt
+++ b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/main/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensions.kt
@@ -95,6 +95,8 @@ internal fun Cursor.hasPropertyKind(): Boolean {
return subCursor.parsePropertyKind() != null
}
+internal fun Cursor.hasEnumEntry(): Boolean = parseEnumEntryKind(peek = true) != null
+
internal fun Cursor.hasGetter() = hasPropertyAccessor(GetterOrSetter.GETTER)
internal fun Cursor.hasSetter() = hasPropertyAccessor(GetterOrSetter.SETTER)
@@ -248,7 +250,7 @@ fun Cursor.parseTypeParams(peek: Boolean = false): List<AbiTypeParameter>? {
return typeParams
}
-fun Cursor.parseTypeParam(peek: Boolean = false): AbiTypeParameter? {
+internal fun Cursor.parseTypeParam(peek: Boolean = false): AbiTypeParameter? {
val cursor = subCursor(peek)
val tag = cursor.parseTag() ?: return null
cursor.parseSymbol("^:")
@@ -335,6 +337,10 @@ internal fun Cursor.parseTargets(): List<String> {
return targets
}
+internal fun Cursor.parseEnumEntryKind(peek: Boolean = false) = parseSymbol("enum\\sentry", peek)
+
+internal fun Cursor.parseEnumName() = parseSymbol("^[A-Z_]+")
+
/**
* Used to check if declarations after a property are getter / setter methods which should be
* attached to that property.
diff --git a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KLibDumpParserTest.kt b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KLibDumpParserTest.kt
index cf373354802..0a726c61d35 100644
--- a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KLibDumpParserTest.kt
+++ b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KLibDumpParserTest.kt
@@ -29,6 +29,7 @@ class KlibDumpParserTest {
private val collectionDump = getJavaResource("collection.txt").readText()
private val datastoreCoreDump = getJavaResource("datastore.txt").readText()
+ private val annotationDump = getJavaResource("annotation.txt").readText()
private val uniqueTargetDump = getJavaResource("unique_targets.txt").readText()
@Test
@@ -192,6 +193,20 @@ class KlibDumpParserTest {
}
@Test
+ fun parseAnEnumEntry() {
+ val input = "enum entry GROUP_ID // androidx.annotation/RestrictTo.Scope.GROUP_ID|null[0]"
+ val parsed = KlibDumpParser(input).parseEnumEntry(
+ AbiQualifiedName(
+ AbiCompoundName("androidx.annotation"),
+ AbiCompoundName("RestrictTo.Scope")
+ )
+ )
+ assertThat(parsed.qualifiedName.toString()).isEqualTo(
+ "androidx.annotation/RestrictTo.Scope.GROUP_ID"
+ )
+ }
+
+ @Test
fun parseFullCollectionKlibDumpSucceeds() {
val parsed = KlibDumpParser(collectionDump).parse()
assertThat(parsed).isNotNull()
@@ -202,6 +217,11 @@ class KlibDumpParserTest {
val parsed = KlibDumpParser(datastoreCoreDump).parse()
assertThat(parsed).isNotNull()
}
+ @Test
+ fun parseFullAnnotationKlibDumpSucceeds() {
+ val parsed = KlibDumpParser(annotationDump).parse()
+ assertThat(parsed).isNotNull()
+ }
@Test
fun parseUniqueTargetsSucceeds() {
diff --git a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensionsTest.kt b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensionsTest.kt
index 418e93c95b2..5888511a16c 100644
--- a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensionsTest.kt
+++ b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/java/androidx/binarycompatibilityvalidator/KlibParsingCursorExtensionsTest.kt
@@ -521,4 +521,27 @@ class KlibParsingCursorExtensionsTest {
val targets = cursor.parseTargets()
assertThat(targets).containsExactly("linuxX64", "iosX64")
}
+
+ @Test fun parseEnumEntryName() {
+ val input = "SOME_ENUM something else"
+ val cursor = Cursor(input)
+ val enumName = cursor.parseEnumName()
+ assertThat(enumName).isEqualTo("SOME_ENUM")
+ assertThat(cursor.currentLine).isEqualTo("something else")
+ }
+
+ @Test fun parseEnumEntryKind() {
+ val input = "enum entry SOME_ENUM"
+ val cursor = Cursor(input)
+ val enumName = cursor.parseEnumEntryKind()
+ assertThat(enumName).isEqualTo("enum entry")
+ assertThat(cursor.currentLine).isEqualTo("SOME_ENUM")
+ }
+
+ @Test fun hasEnumEntry() {
+ val input = "enum entry SOME_ENUM"
+ val cursor = Cursor(input)
+ assertThat(cursor.hasEnumEntry()).isTrue()
+ assertThat(cursor.currentLine).isEqualTo(input)
+ }
}
diff --git a/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/resources/annotation.txt b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/resources/annotation.txt
new file mode 100644
index 00000000000..ea4293887d0
--- /dev/null
+++ b/binarycompatibilityvalidator/binarycompatibilityvalidator/src/test/resources/annotation.txt
@@ -0,0 +1,148 @@
+// Klib ABI Dump
+// Targets: [macosX64, macosX64.androidNativeArm32, macosX64.androidNativeArm64, macosX64.androidNativeX64, macosX64.androidNativeX86, macosX64.iosArm64, macosX64.iosSimulatorArm64, macosX64.iosX64, macosX64.linuxX64, macosX64.macosArm64]
+// Rendering settings:
+// - Signature version: 2
+// - Show manifest properties: true
+// - Show declarations: true
+
+// Library unique name: <androidx.annotation:annotation>
+open annotation class androidx.annotation/AnyThread : kotlin/Annotation { // androidx.annotation/AnyThread|null[0]
+ constructor <init>() // androidx.annotation/AnyThread.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/CallSuper : kotlin/Annotation { // androidx.annotation/CallSuper|null[0]
+ constructor <init>() // androidx.annotation/CallSuper.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/CheckResult : kotlin/Annotation { // androidx.annotation/CheckResult|null[0]
+ constructor <init>(kotlin/String =...) // androidx.annotation/CheckResult.<init>|<init>(kotlin.String){}[0]
+ final val suggest // androidx.annotation/CheckResult.suggest|{}suggest[0]
+ final fun <get-suggest>(): kotlin/String // androidx.annotation/CheckResult.suggest.<get-suggest>|<get-suggest>(){}[0]
+}
+open annotation class androidx.annotation/ColorInt : kotlin/Annotation { // androidx.annotation/ColorInt|null[0]
+ constructor <init>() // androidx.annotation/ColorInt.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/ColorLong : kotlin/Annotation { // androidx.annotation/ColorLong|null[0]
+ constructor <init>() // androidx.annotation/ColorLong.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/Discouraged : kotlin/Annotation { // androidx.annotation/Discouraged|null[0]
+ constructor <init>(kotlin/String) // androidx.annotation/Discouraged.<init>|<init>(kotlin.String){}[0]
+ final val message // androidx.annotation/Discouraged.message|{}message[0]
+ final fun <get-message>(): kotlin/String // androidx.annotation/Discouraged.message.<get-message>|<get-message>(){}[0]
+}
+open annotation class androidx.annotation/EmptySuper : kotlin/Annotation { // androidx.annotation/EmptySuper|null[0]
+ constructor <init>() // androidx.annotation/EmptySuper.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/FloatRange : kotlin/Annotation { // androidx.annotation/FloatRange|null[0]
+ constructor <init>(kotlin/Double =..., kotlin/Double =..., kotlin/Boolean =..., kotlin/Boolean =...) // androidx.annotation/FloatRange.<init>|<init>(kotlin.Double;kotlin.Double;kotlin.Boolean;kotlin.Boolean){}[0]
+ final val from // androidx.annotation/FloatRange.from|{}from[0]
+ final fun <get-from>(): kotlin/Double // androidx.annotation/FloatRange.from.<get-from>|<get-from>(){}[0]
+ final val fromInclusive // androidx.annotation/FloatRange.fromInclusive|{}fromInclusive[0]
+ final fun <get-fromInclusive>(): kotlin/Boolean // androidx.annotation/FloatRange.fromInclusive.<get-fromInclusive>|<get-fromInclusive>(){}[0]
+ final val to // androidx.annotation/FloatRange.to|{}to[0]
+ final fun <get-to>(): kotlin/Double // androidx.annotation/FloatRange.to.<get-to>|<get-to>(){}[0]
+ final val toInclusive // androidx.annotation/FloatRange.toInclusive|{}toInclusive[0]
+ final fun <get-toInclusive>(): kotlin/Boolean // androidx.annotation/FloatRange.toInclusive.<get-toInclusive>|<get-toInclusive>(){}[0]
+}
+open annotation class androidx.annotation/GuardedBy : kotlin/Annotation { // androidx.annotation/GuardedBy|null[0]
+ constructor <init>(kotlin/String) // androidx.annotation/GuardedBy.<init>|<init>(kotlin.String){}[0]
+ final val value // androidx.annotation/GuardedBy.value|{}value[0]
+ final fun <get-value>(): kotlin/String // androidx.annotation/GuardedBy.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/IntDef : kotlin/Annotation { // androidx.annotation/IntDef|null[0]
+ constructor <init>(kotlin/IntArray... =..., kotlin/Boolean =..., kotlin/Boolean =...) // androidx.annotation/IntDef.<init>|<init>(kotlin.IntArray...;kotlin.Boolean;kotlin.Boolean){}[0]
+ final val flag // androidx.annotation/IntDef.flag|{}flag[0]
+ final fun <get-flag>(): kotlin/Boolean // androidx.annotation/IntDef.flag.<get-flag>|<get-flag>(){}[0]
+ final val open // androidx.annotation/IntDef.open|{}open[0]
+ final fun <get-open>(): kotlin/Boolean // androidx.annotation/IntDef.open.<get-open>|<get-open>(){}[0]
+ final val value // androidx.annotation/IntDef.value|{}value[0]
+ final fun <get-value>(): kotlin/IntArray // androidx.annotation/IntDef.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/IntRange : kotlin/Annotation { // androidx.annotation/IntRange|null[0]
+ constructor <init>(kotlin/Long =..., kotlin/Long =...) // androidx.annotation/IntRange.<init>|<init>(kotlin.Long;kotlin.Long){}[0]
+ final val from // androidx.annotation/IntRange.from|{}from[0]
+ final fun <get-from>(): kotlin/Long // androidx.annotation/IntRange.from.<get-from>|<get-from>(){}[0]
+ final val to // androidx.annotation/IntRange.to|{}to[0]
+ final fun <get-to>(): kotlin/Long // androidx.annotation/IntRange.to.<get-to>|<get-to>(){}[0]
+}
+open annotation class androidx.annotation/LongDef : kotlin/Annotation { // androidx.annotation/LongDef|null[0]
+ constructor <init>(kotlin/LongArray... =..., kotlin/Boolean =..., kotlin/Boolean =...) // androidx.annotation/LongDef.<init>|<init>(kotlin.LongArray...;kotlin.Boolean;kotlin.Boolean){}[0]
+ final val flag // androidx.annotation/LongDef.flag|{}flag[0]
+ final fun <get-flag>(): kotlin/Boolean // androidx.annotation/LongDef.flag.<get-flag>|<get-flag>(){}[0]
+ final val open // androidx.annotation/LongDef.open|{}open[0]
+ final fun <get-open>(): kotlin/Boolean // androidx.annotation/LongDef.open.<get-open>|<get-open>(){}[0]
+ final val value // androidx.annotation/LongDef.value|{}value[0]
+ final fun <get-value>(): kotlin/LongArray // androidx.annotation/LongDef.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/MainThread : kotlin/Annotation { // androidx.annotation/MainThread|null[0]
+ constructor <init>() // androidx.annotation/MainThread.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/OpenForTesting : kotlin/Annotation { // androidx.annotation/OpenForTesting|null[0]
+ constructor <init>() // androidx.annotation/OpenForTesting.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/RequiresApi : kotlin/Annotation { // androidx.annotation/RequiresApi|null[1]
+ constructor <init>(kotlin/Int =..., kotlin/Int =...) // androidx.annotation/RequiresApi.<init>|<init>(kotlin.Int;kotlin.Int){}[1]
+ final val api // androidx.annotation/RequiresApi.api|{}api[1]
+ final fun <get-api>(): kotlin/Int // androidx.annotation/RequiresApi.api.<get-api>|<get-api>(){}[1]
+ final val value // androidx.annotation/RequiresApi.value|{}value[1]
+ final fun <get-value>(): kotlin/Int // androidx.annotation/RequiresApi.value.<get-value>|<get-value>(){}[1]
+}
+open annotation class androidx.annotation/RequiresFeature : kotlin/Annotation { // androidx.annotation/RequiresFeature|null[0]
+ constructor <init>(kotlin/String, kotlin/String) // androidx.annotation/RequiresFeature.<init>|<init>(kotlin.String;kotlin.String){}[0]
+ final val enforcement // androidx.annotation/RequiresFeature.enforcement|{}enforcement[0]
+ final fun <get-enforcement>(): kotlin/String // androidx.annotation/RequiresFeature.enforcement.<get-enforcement>|<get-enforcement>(){}[0]
+ final val name // androidx.annotation/RequiresFeature.name|{}name[0]
+ final fun <get-name>(): kotlin/String // androidx.annotation/RequiresFeature.name.<get-name>|<get-name>(){}[0]
+}
+open annotation class androidx.annotation/RestrictTo : kotlin/Annotation { // androidx.annotation/RestrictTo|null[0]
+ constructor <init>(kotlin/Array<out androidx.annotation/RestrictTo.Scope>...) // androidx.annotation/RestrictTo.<init>|<init>(kotlin.Array<out|androidx.annotation.RestrictTo.Scope>...){}[0]
+ final enum class Scope : kotlin/Enum<androidx.annotation/RestrictTo.Scope> { // androidx.annotation/RestrictTo.Scope|null[0]
+ enum entry GROUP_ID // androidx.annotation/RestrictTo.Scope.GROUP_ID|null[0]
+ enum entry LIBRARY // androidx.annotation/RestrictTo.Scope.LIBRARY|null[0]
+ enum entry LIBRARY_GROUP // androidx.annotation/RestrictTo.Scope.LIBRARY_GROUP|null[0]
+ enum entry LIBRARY_GROUP_PREFIX // androidx.annotation/RestrictTo.Scope.LIBRARY_GROUP_PREFIX|null[0]
+ enum entry SUBCLASSES // androidx.annotation/RestrictTo.Scope.SUBCLASSES|null[0]
+ enum entry TESTS // androidx.annotation/RestrictTo.Scope.TESTS|null[0]
+ final fun valueOf(kotlin/String): androidx.annotation/RestrictTo.Scope // androidx.annotation/RestrictTo.Scope.valueOf|valueOf#static(kotlin.String){}[0]
+ final fun values(): kotlin/Array<androidx.annotation/RestrictTo.Scope> // androidx.annotation/RestrictTo.Scope.values|values#static(){}[0]
+ }
+ final val value // androidx.annotation/RestrictTo.value|{}value[0]
+ final fun <get-value>(): kotlin/Array<out androidx.annotation/RestrictTo.Scope> // androidx.annotation/RestrictTo.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/ReturnThis : kotlin/Annotation { // androidx.annotation/ReturnThis|null[0]
+ constructor <init>() // androidx.annotation/ReturnThis.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/Size : kotlin/Annotation { // androidx.annotation/Size|null[0]
+ constructor <init>(kotlin/Long =..., kotlin/Long =..., kotlin/Long =..., kotlin/Long =...) // androidx.annotation/Size.<init>|<init>(kotlin.Long;kotlin.Long;kotlin.Long;kotlin.Long){}[0]
+ final val max // androidx.annotation/Size.max|{}max[0]
+ final fun <get-max>(): kotlin/Long // androidx.annotation/Size.max.<get-max>|<get-max>(){}[0]
+ final val min // androidx.annotation/Size.min|{}min[0]
+ final fun <get-min>(): kotlin/Long // androidx.annotation/Size.min.<get-min>|<get-min>(){}[0]
+ final val multiple // androidx.annotation/Size.multiple|{}multiple[0]
+ final fun <get-multiple>(): kotlin/Long // androidx.annotation/Size.multiple.<get-multiple>|<get-multiple>(){}[0]
+ final val value // androidx.annotation/Size.value|{}value[0]
+ final fun <get-value>(): kotlin/Long // androidx.annotation/Size.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/StringDef : kotlin/Annotation { // androidx.annotation/StringDef|null[0]
+ constructor <init>(kotlin/Array<out kotlin/String>... =..., kotlin/Boolean =...) // androidx.annotation/StringDef.<init>|<init>(kotlin.Array<out|kotlin.String>...;kotlin.Boolean){}[0]
+ final val open // androidx.annotation/StringDef.open|{}open[0]
+ final fun <get-open>(): kotlin/Boolean // androidx.annotation/StringDef.open.<get-open>|<get-open>(){}[0]
+ final val value // androidx.annotation/StringDef.value|{}value[0]
+ final fun <get-value>(): kotlin/Array<out kotlin/String> // androidx.annotation/StringDef.value.<get-value>|<get-value>(){}[0]
+}
+open annotation class androidx.annotation/UiThread : kotlin/Annotation { // androidx.annotation/UiThread|null[0]
+ constructor <init>() // androidx.annotation/UiThread.<init>|<init>(){}[0]
+}
+open annotation class androidx.annotation/VisibleForTesting : kotlin/Annotation { // androidx.annotation/VisibleForTesting|null[0]
+ constructor <init>(kotlin/Int =...) // androidx.annotation/VisibleForTesting.<init>|<init>(kotlin.Int){}[0]
+ final object Companion { // androidx.annotation/VisibleForTesting.Companion|null[0]
+ final const val NONE // androidx.annotation/VisibleForTesting.Companion.NONE|{}NONE[0]
+ final fun <get-NONE>(): kotlin/Int // androidx.annotation/VisibleForTesting.Companion.NONE.<get-NONE>|<get-NONE>(){}[0]
+ final const val PACKAGE_PRIVATE // androidx.annotation/VisibleForTesting.Companion.PACKAGE_PRIVATE|{}PACKAGE_PRIVATE[0]
+ final fun <get-PACKAGE_PRIVATE>(): kotlin/Int // androidx.annotation/VisibleForTesting.Companion.PACKAGE_PRIVATE.<get-PACKAGE_PRIVATE>|<get-PACKAGE_PRIVATE>(){}[0]
+ final const val PRIVATE // androidx.annotation/VisibleForTesting.Companion.PRIVATE|{}PRIVATE[0]
+ final fun <get-PRIVATE>(): kotlin/Int // androidx.annotation/VisibleForTesting.Companion.PRIVATE.<get-PRIVATE>|<get-PRIVATE>(){}[0]
+ final const val PROTECTED // androidx.annotation/VisibleForTesting.Companion.PROTECTED|{}PROTECTED[0]
+ final fun <get-PROTECTED>(): kotlin/Int // androidx.annotation/VisibleForTesting.Companion.PROTECTED.<get-PROTECTED>|<get-PROTECTED>(){}[0]
+ }
+ final val otherwise // androidx.annotation/VisibleForTesting.otherwise|{}otherwise[0]
+ final fun <get-otherwise>(): kotlin/Int // androidx.annotation/VisibleForTesting.otherwise.<get-otherwise>|<get-otherwise>(){}[0]
+}