aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMårten Kongstad <amhk@google.com>2024-05-06 14:58:18 +0200
committerMårten Kongstad <amhk@google.com>2024-05-07 13:28:53 +0200
commitd2c707613e650b7c0f9ec02d6c469cecb408973c (patch)
treee9e4cb600d84d14059c2980e71c219e487787fda
parent04d8b46c37a2b68c41ea91614d810f84353da63b (diff)
downloadbuild-d2c707613e650b7c0f9ec02d6c469cecb408973c.tar.gz
check-flagged-apis: consider interfaces when looking up symbol
When searching for potential errors, if a symbol can't be found in the api-verions.xml data, check if it is present in any of the class' interfaces. A follow-up CL will add similar logic to handle super classes. Bug: 334870672 Test: atest --host check-flagged-apis-test Change-Id: Ia6dfcfa8495b89465db60f6a4eb77d304112046b
-rw-r--r--tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt41
-rw-r--r--tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt34
2 files changed, 73 insertions, 2 deletions
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
index 29604f4e31..3cd6a24256 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/CheckFlaggedApisTest.kt
@@ -172,6 +172,47 @@ class CheckFlaggedApisTest {
}
@Test
+ fun testFindErrorsVerifyImplements() {
+ val apiSignature =
+ """
+ // Signature format: 2.0
+ package android {
+ @FlaggedApi("android.flag.foo") public final class Clazz implements android.Interface {
+ method @FlaggedApi("android.flag.foo") public boolean foo();
+ method @FlaggedApi("android.flag.foo") public boolean bar();
+ }
+ public interface Interface {
+ method public boolean bar();
+ }
+ }
+ """
+ .trim()
+
+ val apiVersions =
+ """
+ <?xml version="1.0" encoding="utf-8"?>
+ <api version="3">
+ <class name="android/Clazz" since="1">
+ <implements name="android/Interface"/>
+ <method name="foo()Z"/>
+ </class>
+ <class name="android/Interface" since="1">
+ <method name="bar()Z"/>
+ </class>
+ </api>
+ """
+ .trim()
+
+ val expected = setOf<ApiError>()
+ val actual =
+ findErrors(
+ parseApiSignature("in-memory", apiSignature.byteInputStream()),
+ parseFlagValues(generateFlagsProto(ENABLED, ENABLED)),
+ parseApiVersions(apiVersions.byteInputStream()))
+ assertEquals(expected, actual)
+ }
+
+ @Test
fun testFindErrorsDisabledFlaggedApiIsPresent() {
val expected =
setOf<ApiError>(
diff --git a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
index 0d2d24e19f..867ee94a9a 100644
--- a/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
+++ b/tools/check-flagged-apis/src/com/android/checkflaggedapis/Main.kt
@@ -333,15 +333,45 @@ internal fun findErrors(
flags: Map<Flag, Boolean>,
symbolsInOutput: Set<Symbol>
): Set<ApiError> {
+ fun Set<Symbol>.containsSymbol(symbol: Symbol): Boolean {
+ // trivial case: the symbol is explicitly listed in api-versions.xml
+ if (contains(symbol)) {
+ return true
+ }
+
+ // non-trivial case: the symbol could be part of the surrounding class'
+ // super class or interfaces
+ val (className, memberName) =
+ when (symbol) {
+ is ClassSymbol -> return false
+ is MemberSymbol -> {
+ Pair(symbol.clazz, symbol.member)
+ }
+ }
+ val clazz = find { it is ClassSymbol && it.clazz == className } as? ClassSymbol?
+ if (clazz == null) {
+ return false
+ }
+
+ for (interfaceName in clazz.interfaces) {
+ // createMethod is the same as createField, except it allows parenthesis
+ val interfaceSymbol = Symbol.createMethod(interfaceName, memberName)
+ if (contains(interfaceSymbol)) {
+ return true
+ }
+ }
+
+ return false
+ }
val errors = mutableSetOf<ApiError>()
for ((symbol, flag) in flaggedSymbolsInSource) {
try {
if (flags.getValue(flag)) {
- if (!symbolsInOutput.contains(symbol)) {
+ if (!symbolsInOutput.containsSymbol(symbol)) {
errors.add(EnabledFlaggedApiNotPresentError(symbol, flag))
}
} else {
- if (symbolsInOutput.contains(symbol)) {
+ if (symbolsInOutput.containsSymbol(symbol)) {
errors.add(DisabledFlaggedApiIsPresentError(symbol, flag))
}
}