Merge "check-flagged-apis: change internal format" into main

This commit is contained in:
Mårten Kongstad
2024-05-02 14:51:49 +00:00
committed by Gerrit Code Review
2 changed files with 31 additions and 21 deletions

View File

@@ -89,11 +89,11 @@ class CheckFlaggedApisTest {
fun testParseApiSignature() { fun testParseApiSignature() {
val expected = val expected =
setOf( setOf(
Pair(Symbol("android.Clazz"), Flag("android.flag.foo")), Pair(Symbol("android/Clazz"), Flag("android.flag.foo")),
Pair(Symbol("android.Clazz.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/FOO"), Flag("android.flag.foo")),
Pair(Symbol("android.Clazz.getErrorCode()"), 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/Builder"), Flag("android.flag.bar")),
) )
val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream()) val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
assertEquals(expected, actual) assertEquals(expected, actual)
@@ -111,11 +111,11 @@ class CheckFlaggedApisTest {
fun testParseApiVersions() { fun testParseApiVersions() {
val expected: Set<Symbol> = val expected: Set<Symbol> =
setOf( setOf(
Symbol("android.Clazz"), Symbol("android/Clazz"),
Symbol("android.Clazz.Clazz()"), Symbol("android/Clazz/Clazz()"),
Symbol("android.Clazz.FOO"), Symbol("android/Clazz/FOO"),
Symbol("android.Clazz.getErrorCode()"), Symbol("android/Clazz/getErrorCode()"),
Symbol("android.Clazz.Builder"), Symbol("android/Clazz/Builder"),
) )
val actual = parseApiVersions(API_VERSIONS.byteInputStream()) val actual = parseApiVersions(API_VERSIONS.byteInputStream())
assertEquals(expected, actual) assertEquals(expected, actual)
@@ -136,14 +136,14 @@ class CheckFlaggedApisTest {
fun testFindErrorsDisabledFlaggedApiIsPresent() { fun testFindErrorsDisabledFlaggedApiIsPresent() {
val expected = val expected =
setOf<ApiError>( setOf<ApiError>(
DisabledFlaggedApiIsPresentError(Symbol("android.Clazz"), Flag("android.flag.foo")), DisabledFlaggedApiIsPresentError(Symbol("android/Clazz"), Flag("android.flag.foo")),
DisabledFlaggedApiIsPresentError( DisabledFlaggedApiIsPresentError(
Symbol("android.Clazz.Clazz()"), 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/FOO"), Flag("android.flag.foo")),
DisabledFlaggedApiIsPresentError( DisabledFlaggedApiIsPresentError(
Symbol("android.Clazz.getErrorCode()"), Flag("android.flag.foo")), Symbol("android/Clazz/getErrorCode()"), Flag("android.flag.foo")),
DisabledFlaggedApiIsPresentError( DisabledFlaggedApiIsPresentError(
Symbol("android.Clazz.Builder"), Flag("android.flag.bar")), Symbol("android/Clazz/Builder"), Flag("android.flag.bar")),
) )
val actual = val actual =
findErrors( findErrors(

View File

@@ -41,21 +41,29 @@ import org.w3c.dom.Node
* a Java symbol slightly differently. To keep things consistent, all parsed APIs are converted to * a Java symbol slightly differently. To keep things consistent, all parsed APIs are converted to
* Symbols. * 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> * <pre>
* package.class.inner-class.field * package.class.inner-class.method(II[Landroid/util/Clazz;)
* </pre> * <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 @JvmInline
internal value class Symbol(val name: String) { internal value class Symbol(val name: String) {
companion object { 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. */ /** Create a new Symbol from a String that may include delimiters other than dot. */
fun create(name: String): Symbol { fun create(name: String): Symbol {
var sanitizedName = name var sanitizedName = name
for (ch in FORBIDDEN_CHARS) { for (ch in FORBIDDEN_CHARS) {
sanitizedName = sanitizedName.replace(ch, '.') sanitizedName = sanitizedName.replace(ch, '/')
} }
return Symbol(sanitizedName) return Symbol(sanitizedName)
} }
@@ -255,7 +263,9 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> {
"Bad XML: <field> element without name attribute" "Bad XML: <field> element without name attribute"
} }
val className = 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")) output.add(Symbol.create("${className.replace("/", ".")}.$fieldName"))
} }