Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c3571fe authored by Mårten Kongstad's avatar Mårten Kongstad
Browse files

check-flagged-apis: record interfaces when parsing classes

Extend ClassSymbol with a list of the interfaces that class implements.
This will be used in a follow-up CL to improve the logic that checks if
a class member exists in the api-versions.xml data.

Bug: 334870672
Test: atest --host check-flagged-apis-test
Change-Id: I4db7ff47c3ce40ca892cb872810dd559426dfcb8
parent a1fe3713
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ class CheckFlaggedApisTest {
  fun testParseApiSignature() {
    val expected =
        setOf(
            Pair(Symbol.createClass("android/Clazz"), Flag("android.flag.foo")),
            Pair(Symbol.createClass("android/Clazz", setOf()), Flag("android.flag.foo")),
            Pair(Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")),
            Pair(Symbol.createField("android/Clazz", "FOO"), Flag("android.flag.foo")),
            Pair(Symbol.createMethod("android/Clazz", "getErrorCode()"), Flag("android.flag.foo")),
@@ -108,7 +108,7 @@ class CheckFlaggedApisTest {
            Pair(
                Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
                Flag("android.flag.foo")),
            Pair(Symbol.createClass("android/Clazz/Builder"), Flag("android.flag.bar")),
            Pair(Symbol.createClass("android/Clazz/Builder", setOf()), Flag("android.flag.bar")),
        )
    val actual = parseApiSignature("in-memory", API_SIGNATURE.byteInputStream())
    assertEquals(expected, actual)
@@ -126,14 +126,14 @@ class CheckFlaggedApisTest {
  fun testParseApiVersions() {
    val expected: Set<Symbol> =
        setOf(
            Symbol.createClass("android/Clazz"),
            Symbol.createClass("android/Clazz", setOf()),
            Symbol.createMethod("android/Clazz", "Clazz()"),
            Symbol.createField("android/Clazz", "FOO"),
            Symbol.createMethod("android/Clazz", "getErrorCode()"),
            Symbol.createMethod("android/Clazz", "setData(I[[ILandroid/util/Utility;)"),
            Symbol.createMethod("android/Clazz", "setVariableData(I[Landroid/util/Atom;)"),
            Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
            Symbol.createClass("android/Clazz/Builder"),
            Symbol.createClass("android/Clazz/Builder", setOf()),
        )
    val actual = parseApiVersions(API_VERSIONS.byteInputStream())
    assertEquals(expected, actual)
@@ -153,7 +153,7 @@ class CheckFlaggedApisTest {
            .trim()
    val expected: Set<Symbol> =
        setOf(
            Symbol.createClass("android/Clazz/Foo/Bar"),
            Symbol.createClass("android/Clazz/Foo/Bar", setOf()),
            Symbol.createMethod("android/Clazz/Foo/Bar", "Bar()"),
        )
    val actual = parseApiVersions(apiVersions.byteInputStream())
@@ -176,7 +176,7 @@ class CheckFlaggedApisTest {
    val expected =
        setOf<ApiError>(
            DisabledFlaggedApiIsPresentError(
                Symbol.createClass("android/Clazz"), Flag("android.flag.foo")),
                Symbol.createClass("android/Clazz", setOf()), Flag("android.flag.foo")),
            DisabledFlaggedApiIsPresentError(
                Symbol.createMethod("android/Clazz", "Clazz()"), Flag("android.flag.foo")),
            DisabledFlaggedApiIsPresentError(
@@ -193,7 +193,7 @@ class CheckFlaggedApisTest {
                Symbol.createMethod("android/Clazz", "innerClassArg(Landroid/Clazz/Builder;)"),
                Flag("android.flag.foo")),
            DisabledFlaggedApiIsPresentError(
                Symbol.createClass("android/Clazz/Builder"), Flag("android.flag.bar")),
                Symbol.createClass("android/Clazz/Builder", setOf()), Flag("android.flag.bar")),
        )
    val actual =
        findErrors(
+20 −5
Original line number Diff line number Diff line
@@ -58,8 +58,8 @@ internal sealed class Symbol {
  companion object {
    private val FORBIDDEN_CHARS = listOf('#', '$', '.')

    fun createClass(clazz: String): Symbol {
      return ClassSymbol(toInternalFormat(clazz))
    fun createClass(clazz: String, interfaces: Set<String>): Symbol {
      return ClassSymbol(toInternalFormat(clazz), interfaces.map { toInternalFormat(it) }.toSet())
    }

    fun createField(clazz: String, field: String): Symbol {
@@ -83,7 +83,7 @@ internal sealed class Symbol {
  abstract fun toPrettyString(): String
}

internal data class ClassSymbol(val clazz: String) : Symbol() {
internal data class ClassSymbol(val clazz: String, val interfaces: Set<String>) : Symbol() {
  override fun toPrettyString(): String = "$clazz"
}

@@ -195,7 +195,10 @@ internal fun parseApiSignature(path: String, input: InputStream): Set<Pair<Symbo
      object : BaseItemVisitor() {
        override fun visitClass(cls: ClassItem) {
          getFlagOrNull(cls)?.let { flag ->
            val symbol = Symbol.createClass(cls.baselineElementId())
            val symbol =
                Symbol.createClass(
                    cls.baselineElementId(),
                    cls.allInterfaces().map { it.baselineElementId() }.toSet())
            output.add(Pair(symbol, flag))
          }
        }
@@ -257,7 +260,19 @@ internal fun parseApiVersions(input: InputStream): Set<Symbol> {
        requireNotNull(cls.getAttribute("name")) {
          "Bad XML: <class> element without name attribute"
        }
    output.add(Symbol.createClass(className))
    val interfaces = mutableSetOf<String>()
    val children = cls.getChildNodes()
    for (j in 0.rangeUntil(children.getLength())) {
      val child = children.item(j)
      if (child.getNodeName() == "implements") {
        val interfaceName =
            requireNotNull(child.getAttribute("name")) {
              "Bad XML: <implements> element without name attribute"
            }
        interfaces.add(interfaceName)
      }
    }
    output.add(Symbol.createClass(className, interfaces))
  }

  val fields = document.getElementsByTagName("field")