check-flagged-apis: change internal format
Switch the internal format to represent Symbols to (something close to) the format described in section 4.3.2 of the JVM spec, i.e. com/android/SomeClass/someMethod(II[Ljava/lang/String;)Z This will make parsing method parameters from api-versions.xml easier, as that file already uses this format, and converting API signature files to the same format is less painful than going in the other direction. Bug: 334870672 Test: atest --host check-flagged-apis-test Change-Id: I1e1fb8fe208cd51cce2cc129f5aa1cb495672c16
This commit is contained in:
@@ -89,11 +89,11 @@ class CheckFlaggedApisTest {
|
||||
fun testParseApiSignature() {
|
||||
val expected =
|
||||
setOf(
|
||||
Pair(Symbol("android.Clazz"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android.Clazz.Clazz()"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android.Clazz.FOO"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android.Clazz.getErrorCode()"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android.Clazz.Builder"), Flag("android.flag.bar")),
|
||||
Pair(Symbol("android/Clazz"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
|
||||
Pair(Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
|
||||
)
|
||||
val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
|
||||
assertEquals(expected, actual)
|
||||
@@ -111,11 +111,11 @@ class CheckFlaggedApisTest {
|
||||
fun testParseApiVersions() {
|
||||
val expected: Set<Symbol> =
|
||||
setOf(
|
||||
Symbol("android.Clazz"),
|
||||
Symbol("android.Clazz.Clazz()"),
|
||||
Symbol("android.Clazz.FOO"),
|
||||
Symbol("android.Clazz.getErrorCode()"),
|
||||
Symbol("android.Clazz.Builder"),
|
||||
Symbol("android/Clazz"),
|
||||
Symbol("android/Clazz/Clazz()"),
|
||||
Symbol("android/Clazz/FOO"),
|
||||
Symbol("android/Clazz/getErrorCode()"),
|
||||
Symbol("android/Clazz/Builder"),
|
||||
)
|
||||
val actual = parseApiVersions(API_VERSIONS.byteInputStream())
|
||||
assertEquals(expected, actual)
|
||||
@@ -136,14 +136,14 @@ class CheckFlaggedApisTest {
|
||||
fun testFindErrorsDisabledFlaggedApiIsPresent() {
|
||||
val expected =
|
||||
setOf<ApiError>(
|
||||
DisabledFlaggedApiIsPresentError(Symbol("android.Clazz"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(
|
||||
Symbol("android.Clazz.Clazz()"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(Symbol("android.Clazz.FOO"), Flag("android.flag.foo")),
|
||||
Symbol("android/Clazz/Clazz()"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(Symbol("android/Clazz/FOO"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(
|
||||
Symbol("android.Clazz.getErrorCode()"), Flag("android.flag.foo")),
|
||||
Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
|
||||
DisabledFlaggedApiIsPresentError(
|
||||
Symbol("android.Clazz.Builder"), Flag("android.flag.bar")),
|
||||
Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
|
||||
)
|
||||
val actual =
|
||||
findErrors(
|
||||
|
@@ -41,21 +41,29 @@ import org.w3c.dom.Node
|
||||
* a Java symbol slightly differently. To keep things consistent, all parsed APIs are converted to
|
||||
* Symbols.
|
||||
*
|
||||
* All parts of the fully qualified name of the Symbol are separated by a dot, e.g.:
|
||||
* Symbols are encoded using the format similar to the one described in section 4.3.2 of the JVM
|
||||
* spec [1], that is, "package.class.inner-class.method(int, int[], android.util.Clazz)" is
|
||||
* represented as
|
||||
* <pre>
|
||||
* package.class.inner-class.field
|
||||
* </pre>
|
||||
* package.class.inner-class.method(II[Landroid/util/Clazz;)
|
||||
* <pre>
|
||||
*
|
||||
* Where possible, the format has been simplified (to make translation of the
|
||||
* various input formats easier): for instance, only / is used as delimiter (#
|
||||
* and $ are never used).
|
||||
*
|
||||
* 1. https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.2
|
||||
*/
|
||||
@JvmInline
|
||||
internal value class Symbol(val name: String) {
|
||||
companion object {
|
||||
private val FORBIDDEN_CHARS = listOf('#', '$')
|
||||
private val FORBIDDEN_CHARS = listOf('#', '$', '.')
|
||||
|
||||
/** Create a new Symbol from a String that may include delimiters other than dot. */
|
||||
fun create(name: String): Symbol {
|
||||
var sanitizedName = name
|
||||
for (ch in FORBIDDEN_CHARS) {
|
||||
sanitizedName = sanitizedName.replace(ch, '.')
|
||||
sanitizedName = sanitizedName.replace(ch, '/')
|
||||
}
|
||||
return Symbol(sanitizedName)
|
||||
}
|
||||
@@ -255,7 +263,9 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> {
|
||||
"Bad XML: <field> element without name attribute"
|
||||
}
|
||||
val className =
|
||||
requireNotNull(field.getParentNode()?.getAttribute("name")) { "Bad XML: top level <field> element" }
|
||||
requireNotNull(field.getParentNode()?.getAttribute("name")) {
|
||||
"Bad XML: top level <field> element"
|
||||
}
|
||||
output.add(Symbol.create("${className.replace("/", ".")}.$fieldName"))
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user