`AnnotationAttribute.legacyValue` is being removed. This revealed a couple of errors in the tests that also needed fixing: 1. A test used an unresolved `Flags.FLAG_NEW_GEOCODER` reference in the `@FlaggedApi`. That is invalid because all flags are resolved and replaced with their literal value in signature files. 2. Another test was simply missing some `"`s around the flag value. Flag: EXEMPT minor refactoring of build tool Bug: 354633349 Test: m checkbuild Change-Id: I7317ec23ec80517433c2f7e19e29aff7a15186fc
95 lines
3.3 KiB
Kotlin
95 lines
3.3 KiB
Kotlin
/*
|
|
* Copyright (C) 2023 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.platform.coverage
|
|
|
|
import com.android.tools.metalava.model.CallableItem
|
|
import com.android.tools.metalava.model.ClassItem
|
|
import com.android.tools.metalava.model.Item
|
|
import com.android.tools.metalava.model.text.ApiFile
|
|
import com.android.tools.metalava.model.value.asString
|
|
import java.io.File
|
|
import java.io.FileWriter
|
|
|
|
/** Usage: extract-flagged-apis <api text file> <output .pb file> */
|
|
fun main(args: Array<String>) {
|
|
val cb = ApiFile.parseApi(listOf(File(args[0])))
|
|
val builder = FlagApiMap.newBuilder()
|
|
for (pkg in cb.getPackages().packages) {
|
|
val packageName = pkg.qualifiedName()
|
|
pkg.allClasses().forEach {
|
|
extractFlaggedApisFromClass(it, it.methods(), packageName, builder)
|
|
extractFlaggedApisFromClass(it, it.constructors(), packageName, builder)
|
|
}
|
|
}
|
|
val flagApiMap = builder.build()
|
|
FileWriter(args[1]).use { it.write(flagApiMap.toString()) }
|
|
}
|
|
|
|
fun extractFlaggedApisFromClass(
|
|
classItem: ClassItem,
|
|
callables: List<CallableItem>,
|
|
packageName: String,
|
|
builder: FlagApiMap.Builder
|
|
) {
|
|
if (callables.isEmpty()) return
|
|
val classFlag = getClassFlag(classItem)
|
|
for (callable in callables) {
|
|
val callableFlag = getFlagAnnotation(callable) ?: classFlag
|
|
val api =
|
|
JavaMethod.newBuilder()
|
|
.setPackageName(packageName)
|
|
.setClassName(classItem.fullName())
|
|
.setMethodName(callable.name())
|
|
for (param in callable.parameters()) {
|
|
api.addParameters(param.type().toTypeString())
|
|
}
|
|
if (callableFlag != null) {
|
|
addFlaggedApi(builder, api, callableFlag)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun addFlaggedApi(builder: FlagApiMap.Builder, api: JavaMethod.Builder, flag: String) {
|
|
if (builder.containsFlagToApi(flag)) {
|
|
val updatedApis = builder.getFlagToApiOrThrow(flag).toBuilder().addJavaMethods(api).build()
|
|
builder.putFlagToApi(flag, updatedApis)
|
|
} else {
|
|
val apis = FlaggedApis.newBuilder().addJavaMethods(api).build()
|
|
builder.putFlagToApi(flag, apis)
|
|
}
|
|
}
|
|
|
|
fun getClassFlag(classItem: ClassItem): String? {
|
|
var classFlag = getFlagAnnotation(classItem)
|
|
var cur = classItem
|
|
// If a class is not a nested class, use its @FlaggedApi annotation value.
|
|
// Otherwise, use the flag value of the closest outer class that is annotated by @FlaggedApi.
|
|
while (classFlag == null) {
|
|
cur = cur.containingClass() ?: break
|
|
classFlag = getFlagAnnotation(cur)
|
|
}
|
|
return classFlag
|
|
}
|
|
|
|
fun getFlagAnnotation(item: Item): String? {
|
|
return item.modifiers
|
|
.findAnnotation("android.annotation.FlaggedApi")
|
|
?.findAttribute("value")
|
|
?.value
|
|
?.asString()
|
|
}
|