check-flagged-apis: api-versions.xml: correctly parse nested class ctor

The constructor of a nested class is represented as follows in
api-versions.xml:

  <class name="android/Clazz$Foo$Bar" since="1">
    <method name="&lt;init>()V"/>
  </class>

The nested dollar signs are not replaced by forward slashes before the
parsing logic uses `split("/")` to find the name of the inner-most
class, incorrectly resulting in `Class$Foo$Bar` instead of `Bar`. Fix
this by immediately replacing dollar signs with forward slashes after
extracting the package and class.

Also clean up the following call of `Symbol.create`.

Bug: 334870672
Test: atest --host check-flagged-apis-test
Change-Id: I8c0619faae90ded7eb14dcc20ecb94a086a1c764
This commit is contained in:
Mårten Kongstad
2024-05-06 10:28:02 +02:00
parent 5a99056218
commit 02525a88de
2 changed files with 25 additions and 3 deletions

View File

@@ -139,6 +139,27 @@ class CheckFlaggedApisTest {
assertEquals(expected, actual)
}
@Test
fun testParseApiVersionsNestedClasses() {
val apiVersions =
"""
<?xml version="1.0" encoding="utf-8"?>
<api version="3">
<class name="android/Clazz${'$'}Foo${'$'}Bar" since="1">
<method name="&lt;init>()V"/>
</class>
</api>
"""
.trim()
val expected: Set<Symbol> =
setOf(
Symbol("android/Clazz/Foo/Bar"),
Symbol("android/Clazz/Foo/Bar/Bar()"),
)
val actual = parseApiVersions(apiVersions.byteInputStream())
assertEquals(expected, actual)
}
@Test
fun testFindErrorsNoErrors() {
val expected = setOf<ApiError>()

View File

@@ -279,12 +279,13 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> {
var (methodName, methodArgs, _) = methodSignatureParts
val packageAndClassName =
requireNotNull(method.getParentNode()?.getAttribute("name")) {
"Bad XML: top level <method> element, or <class> element missing name attribute"
}
"Bad XML: top level <method> element, or <class> element missing name attribute"
}
.replace("$", "/")
if (methodName == "<init>") {
methodName = packageAndClassName.split("/").last()
}
output.add(Symbol.create("${packageAndClassName.replace("/", ".")}.$methodName($methodArgs)"))
output.add(Symbol.create("$packageAndClassName/$methodName($methodArgs)"))
}
return output