Add support for --convert-to-jdiff <signature> <xml>
am: de6bb6f932
Change-Id: I8878854a0d9ef096692823aa6b4047f10ef72e5a
diff --git a/.idea/dictionaries/metalava.xml b/.idea/dictionaries/metalava.xml
index 8c70194..9841166 100644
--- a/.idea/dictionaries/metalava.xml
+++ b/.idea/dictionaries/metalava.xml
@@ -8,6 +8,7 @@
<w>bytecode</w>
<w>canonicalized</w>
<w>codebases</w>
+ <w>compat</w>
<w>ctor</w>
<w>dataname</w>
<w>devsite</w>
@@ -28,6 +29,7 @@
<w>interop</w>
<w>jaif</w>
<w>javadocs</w>
+ <w>jdiff</w>
<w>jvmstatic</w>
<w>knowntags</w>
<w>kotlinx</w>
@@ -43,6 +45,7 @@
<w>nullness</w>
<w>offlinemode</w>
<w>parsecomments</w>
+ <w>proguard</w>
<w>realtime</w>
<w>referenceonly</w>
<w>resourcesdir</w>
diff --git a/src/main/java/com/android/tools/metalava/DocAnalyzer.kt b/src/main/java/com/android/tools/metalava/DocAnalyzer.kt
index 5f5938f..9cae0ff 100644
--- a/src/main/java/com/android/tools/metalava/DocAnalyzer.kt
+++ b/src/main/java/com/android/tools/metalava/DocAnalyzer.kt
@@ -1,7 +1,6 @@
package com.android.tools.metalava
import com.android.SdkConstants.ATTR_VALUE
-import com.android.SdkConstants.VALUE_TRUE
import com.android.sdklib.SdkVersionInfo
import com.android.sdklib.repository.AndroidSdkHandler
import com.android.tools.lint.LintCliClient
@@ -29,6 +28,13 @@
import java.util.regex.Pattern
/**
+ * Whether to include textual descriptions of the API requirements instead
+ * of just inserting a since-tag. This should be off if there is post-processing
+ * to convert since tags in the documentation tool used.
+ */
+const val ADD_API_LEVEL_TEXT = false
+
+/**
* Walk over the API and apply tweaks to the documentation, such as
* - Looking for annotations and converting them to auxiliary tags
* that will be processed by the documentation tools later.
@@ -603,6 +609,7 @@
}
fun applyApiLevels(applyApiLevelsXml: File) {
+ @Suppress("DEPRECATION") // still using older lint-api when building with soong
val client = object : LintCliClient() {
override fun findResource(relativePath: String): File? {
if (relativePath == ApiLookup.XML_FILE_PATH) {
@@ -616,7 +623,7 @@
}
override fun getCacheDir(name: String?, create: Boolean): File? {
- if (create && System.getProperty(ENV_VAR_METALAVA_TESTS_RUNNING) == VALUE_TRUE) {
+ if (create && java.lang.Boolean.getBoolean(ENV_VAR_METALAVA_TESTS_RUNNING)) {
// Pick unique directory during unit tests
return Files.createTempDir()
}
@@ -654,7 +661,10 @@
private fun addApiLevelDocumentation(level: Int, item: Item) {
if (level > 1) {
- appendDocumentation("Requires API level ${describeApiLevel(level)}", item, false)
+ @Suppress("ConstantConditionIf")
+ if (ADD_API_LEVEL_TEXT) { // See 113933920: Remove "Requires API level" from method comment
+ appendDocumentation("Requires API level ${describeApiLevel(level)}", item, false)
+ }
// Also add @since tag, unless already manually entered.
// TODO: Override it everywhere in case the existing doc is wrong (we know
// better), and at least for OpenJDK sources we *should* since the since tags
diff --git a/src/main/java/com/android/tools/metalava/Driver.kt b/src/main/java/com/android/tools/metalava/Driver.kt
index 56e8f56..351805e 100644
--- a/src/main/java/com/android/tools/metalava/Driver.kt
+++ b/src/main/java/com/android/tools/metalava/Driver.kt
@@ -181,27 +181,7 @@
private fun processFlags() {
val stopwatch = Stopwatch.createStarted()
- // --copy-annotations?
- val privateAnnotationsSource = options.privateAnnotationsSource
- val privateAnnotationsTarget = options.privateAnnotationsTarget
- if (privateAnnotationsSource != null && privateAnnotationsTarget != null) {
- val rewrite = RewriteAnnotations()
- // Support pointing to both stub-annotations and stub-annotations/src/main/java
- val src = File(privateAnnotationsSource, "src${File.separator}main${File.separator}java")
- val source = if (src.isDirectory) src else privateAnnotationsSource
- source.listFiles()?.forEach { file ->
- rewrite.modifyAnnotationSources(null, file, File(privateAnnotationsTarget, file.name))
- }
- }
-
- // --rewrite-annotations?
- options.rewriteAnnotations?.let { RewriteAnnotations().rewriteAnnotations(it) }
-
- // Convert android.jar files?
- options.androidJarSignatureFiles?.let { root ->
- // Generate API signature files for all the historical JAR files
- ConvertJarsToSignatureFiles().convertJars(root)
- }
+ processNonCodebaseFlags()
val codebase =
if (options.sources.size == 1 && options.sources[0].path.endsWith(SdkConstants.DOT_TXT)) {
@@ -451,6 +431,46 @@
invokeDocumentationTool()
}
+fun processNonCodebaseFlags() {
+ // --copy-annotations?
+ val privateAnnotationsSource = options.privateAnnotationsSource
+ val privateAnnotationsTarget = options.privateAnnotationsTarget
+ if (privateAnnotationsSource != null && privateAnnotationsTarget != null) {
+ val rewrite = RewriteAnnotations()
+ // Support pointing to both stub-annotations and stub-annotations/src/main/java
+ val src = File(privateAnnotationsSource, "src${File.separator}main${File.separator}java")
+ val source = if (src.isDirectory) src else privateAnnotationsSource
+ source.listFiles()?.forEach { file ->
+ rewrite.modifyAnnotationSources(null, file, File(privateAnnotationsTarget, file.name))
+ }
+ }
+
+ // --rewrite-annotations?
+ options.rewriteAnnotations?.let { RewriteAnnotations().rewriteAnnotations(it) }
+
+ // Convert android.jar files?
+ options.androidJarSignatureFiles?.let { root ->
+ // Generate API signature files for all the historical JAR files
+ ConvertJarsToSignatureFiles().convertJars(root)
+ }
+
+ for ((signatureFile, jDiffFile) in options.convertToXmlFiles) {
+ val apiType = ApiType.ALL
+ val apiEmit = apiType.getEmitFilter()
+ val apiReference = apiType.getReferenceFilter()
+
+ val signatureApi = SignatureFileLoader.load(
+ file = signatureFile,
+ kotlinStyleNulls = options.inputKotlinStyleNulls,
+ supportsStagedNullability = true
+ )
+
+ createReportFile(signatureApi, jDiffFile, "JDiff File") { printWriter ->
+ JDiffXmlWriter(printWriter, apiEmit, apiReference, signatureApi.preFiltered)
+ }
+ }
+}
+
/**
* Checks compatibility of the given codebase with the codebase described in the
* signature file.
@@ -611,20 +631,18 @@
}
private fun migrateNulls(codebase: Codebase, previous: Codebase) {
- if (options.migrateNulls) {
- val codebaseSupportsNullability = previous.supportsStagedNullability
- val prevSupportsNullability = previous.supportsStagedNullability
- try {
- previous.supportsStagedNullability = true
- codebase.supportsStagedNullability = true
- previous.compareWith(
- NullnessMigration(), codebase,
- ApiPredicate()
- )
- } finally {
- previous.supportsStagedNullability = prevSupportsNullability
- codebase.supportsStagedNullability = codebaseSupportsNullability
- }
+ val codebaseSupportsNullability = codebase.supportsStagedNullability
+ val prevSupportsNullability = previous.supportsStagedNullability
+ try {
+ previous.supportsStagedNullability = true
+ codebase.supportsStagedNullability = true
+ previous.compareWith(
+ NullnessMigration(), codebase,
+ ApiPredicate()
+ )
+ } finally {
+ previous.supportsStagedNullability = prevSupportsNullability
+ codebase.supportsStagedNullability = codebaseSupportsNullability
}
}
diff --git a/src/main/java/com/android/tools/metalava/Options.kt b/src/main/java/com/android/tools/metalava/Options.kt
index e120aec..a4a2472 100644
--- a/src/main/java/com/android/tools/metalava/Options.kt
+++ b/src/main/java/com/android/tools/metalava/Options.kt
@@ -38,86 +38,86 @@
private const val MAX_LINE_WIDTH = 90
-private const val ARGS_COMPAT_OUTPUT = "--compatible-output"
-private const val ARG_HELP = "--help"
-private const val ARG_VERSION = "--version"
-private const val ARG_QUIET = "--quiet"
-private const val ARG_VERBOSE = "--verbose"
-private const val ARG_CLASS_PATH = "--classpath"
-private const val ARG_SOURCE_PATH = "--source-path"
-private const val ARG_SOURCE_FILES = "--source-files"
-private const val ARG_API = "--api"
-private const val ARG_XML_API = "--api-xml"
-private const val ARG_PRIVATE_API = "--private-api"
-private const val ARG_DEX_API = "--dex-api"
-private const val ARG_PRIVATE_DEX_API = "--private-dex-api"
-private const val ARG_SDK_VALUES = "--sdk-values"
-private const val ARG_REMOVED_API = "--removed-api"
-private const val ARG_REMOVED_DEX_API = "--removed-dex-api"
-private const val ARG_MERGE_ANNOTATIONS = "--merge-annotations"
-private const val ARG_INPUT_API_JAR = "--input-api-jar"
-private const val ARG_EXACT_API = "--exact-api"
-private const val ARG_STUBS = "--stubs"
-private const val ARG_DOC_STUBS = "--doc-stubs"
-private const val ARG_STUBS_SOURCE_LIST = "--write-stubs-source-list"
-private const val ARG_DOC_STUBS_SOURCE_LIST = "--write-doc-stubs-source-list"
-private const val ARG_PROGUARD = "--proguard"
-private const val ARG_EXTRACT_ANNOTATIONS = "--extract-annotations"
-private const val ARG_EXCLUDE_ANNOTATIONS = "--exclude-annotations"
-private const val ARG_HIDE_PACKAGE = "--hide-package"
-private const val ARG_MANIFEST = "--manifest"
-private const val ARG_PREVIOUS_API = "--previous-api"
-private const val ARG_CURRENT_API = "--current-api"
-private const val ARG_MIGRATE_NULLNESS = "--migrate-nullness"
-private const val ARG_CHECK_COMPATIBILITY = "--check-compatibility"
-private const val ARG_CHECK_COMPATIBILITY_API_CURRENT = "--check-compatibility:api:current"
-private const val ARG_CHECK_COMPATIBILITY_API_RELEASED = "--check-compatibility:api:released"
-private const val ARG_CHECK_COMPATIBILITY_REMOVED_CURRENT = "--check-compatibility:removed:current"
-private const val ARG_CHECK_COMPATIBILITY_REMOVED_RELEASED = "--check-compatibility:removed:released"
-private const val ARG_INPUT_KOTLIN_NULLS = "--input-kotlin-nulls"
-private const val ARG_OUTPUT_KOTLIN_NULLS = "--output-kotlin-nulls"
-private const val ARG_OUTPUT_DEFAULT_VALUES = "--output-default-values"
-private const val ARG_ANNOTATION_COVERAGE_STATS = "--annotation-coverage-stats"
-private const val ARG_ANNOTATION_COVERAGE_OF = "--annotation-coverage-of"
-private const val ARG_WRITE_CLASS_COVERAGE_TO = "--write-class-coverage-to"
-private const val ARG_WRITE_MEMBER_COVERAGE_TO = "--write-member-coverage-to"
-private const val ARG_WARNINGS_AS_ERRORS = "--warnings-as-errors"
-private const val ARG_LINTS_AS_ERRORS = "--lints-as-errors"
-private const val ARG_SHOW_ANNOTATION = "--show-annotation"
-private const val ARG_SHOW_UNANNOTATED = "--show-unannotated"
-private const val ARG_COLOR = "--color"
-private const val ARG_NO_COLOR = "--no-color"
-private const val ARG_OMIT_COMMON_PACKAGES = "--omit-common-packages"
-private const val ARG_SKIP_JAVA_IN_COVERAGE_REPORT = "--skip-java-in-coverage-report"
-private const val ARG_NO_BANNER = "--no-banner"
-private const val ARG_ERROR = "--error"
-private const val ARG_WARNING = "--warning"
-private const val ARG_LINT = "--lint"
-private const val ARG_HIDE = "--hide"
-private const val ARG_UNHIDE_CLASSPATH_CLASSES = "--unhide-classpath-classes"
-private const val ARG_ALLOW_REFERENCING_UNKNOWN_CLASSES = "--allow-referencing-unknown-classes"
-private const val ARG_NO_UNKNOWN_CLASSES = "--no-unknown-classes"
-private const val ARG_APPLY_API_LEVELS = "--apply-api-levels"
-private const val ARG_GENERATE_API_LEVELS = "--generate-api-levels"
-private const val ARG_ANDROID_JAR_PATTERN = "--android-jar-pattern"
-private const val ARG_CURRENT_VERSION = "--current-version"
-private const val ARG_CURRENT_CODENAME = "--current-codename"
-private const val ARG_CURRENT_JAR = "--current-jar"
-private const val ARG_CHECK_KOTLIN_INTEROP = "--check-kotlin-interop"
-private const val ARG_PUBLIC = "--public"
-private const val ARG_PROTECTED = "--protected"
-private const val ARG_PACKAGE = "--package"
-private const val ARG_PRIVATE = "--private"
-private const val ARG_HIDDEN = "--hidden"
-private const val ARG_NO_DOCS = "--no-docs"
-private const val ARG_JAVA_SOURCE = "--java-source"
-private const val ARG_REGISTER_ARTIFACT = "--register-artifact"
-private const val ARG_COPY_ANNOTATIONS = "--copy-annotations"
-private const val ARG_INCLUDE_ANNOTATION_CLASSES = "--include-annotation-classes"
-private const val ARG_REWRITE_ANNOTATIONS = "--rewrite-annotations"
-private const val ARG_INCLUDE_SOURCE_RETENTION = "--include-source-retention"
-private const val ARG_INCLUDE_SIG_VERSION = "--include-signature-version"
-private const val ARG_UPDATE_API = "--update-api"
+const val ARGS_COMPAT_OUTPUT = "--compatible-output"
+const val ARG_HELP = "--help"
+const val ARG_VERSION = "--version"
+const val ARG_QUIET = "--quiet"
+const val ARG_VERBOSE = "--verbose"
+const val ARG_CLASS_PATH = "--classpath"
+const val ARG_SOURCE_PATH = "--source-path"
+const val ARG_SOURCE_FILES = "--source-files"
+const val ARG_API = "--api"
+const val ARG_XML_API = "--api-xml"
+const val ARG_CONVERT_TO_JDIFF = "--convert-to-jdiff"
+const val ARG_PRIVATE_API = "--private-api"
+const val ARG_DEX_API = "--dex-api"
+const val ARG_PRIVATE_DEX_API = "--private-dex-api"
+const val ARG_SDK_VALUES = "--sdk-values"
+const val ARG_REMOVED_API = "--removed-api"
+const val ARG_REMOVED_DEX_API = "--removed-dex-api"
+const val ARG_MERGE_ANNOTATIONS = "--merge-annotations"
+const val ARG_INPUT_API_JAR = "--input-api-jar"
+const val ARG_EXACT_API = "--exact-api"
+const val ARG_STUBS = "--stubs"
+const val ARG_DOC_STUBS = "--doc-stubs"
+const val ARG_STUBS_SOURCE_LIST = "--write-stubs-source-list"
+const val ARG_DOC_STUBS_SOURCE_LIST = "--write-doc-stubs-source-list"
+const val ARG_PROGUARD = "--proguard"
+const val ARG_EXTRACT_ANNOTATIONS = "--extract-annotations"
+const val ARG_EXCLUDE_ANNOTATIONS = "--exclude-annotations"
+const val ARG_HIDE_PACKAGE = "--hide-package"
+const val ARG_MANIFEST = "--manifest"
+const val ARG_MIGRATE_NULLNESS = "--migrate-nullness"
+const val ARG_CHECK_COMPATIBILITY = "--check-compatibility"
+const val ARG_CHECK_COMPATIBILITY_API_CURRENT = "--check-compatibility:api:current"
+const val ARG_CHECK_COMPATIBILITY_API_RELEASED = "--check-compatibility:api:released"
+const val ARG_CHECK_COMPATIBILITY_REMOVED_CURRENT = "--check-compatibility:removed:current"
+const val ARG_CHECK_COMPATIBILITY_REMOVED_RELEASED = "--check-compatibility:removed:released"
+const val ARG_INPUT_KOTLIN_NULLS = "--input-kotlin-nulls"
+const val ARG_OUTPUT_KOTLIN_NULLS = "--output-kotlin-nulls"
+const val ARG_OUTPUT_DEFAULT_VALUES = "--output-default-values"
+const val ARG_ANNOTATION_COVERAGE_STATS = "--annotation-coverage-stats"
+const val ARG_ANNOTATION_COVERAGE_OF = "--annotation-coverage-of"
+const val ARG_WRITE_CLASS_COVERAGE_TO = "--write-class-coverage-to"
+const val ARG_WRITE_MEMBER_COVERAGE_TO = "--write-member-coverage-to"
+const val ARG_WARNINGS_AS_ERRORS = "--warnings-as-errors"
+const val ARG_LINTS_AS_ERRORS = "--lints-as-errors"
+const val ARG_SHOW_ANNOTATION = "--show-annotation"
+const val ARG_SHOW_UNANNOTATED = "--show-unannotated"
+const val ARG_COLOR = "--color"
+const val ARG_NO_COLOR = "--no-color"
+const val ARG_OMIT_COMMON_PACKAGES = "--omit-common-packages"
+const val ARG_SKIP_JAVA_IN_COVERAGE_REPORT = "--skip-java-in-coverage-report"
+const val ARG_NO_BANNER = "--no-banner"
+const val ARG_ERROR = "--error"
+const val ARG_WARNING = "--warning"
+const val ARG_LINT = "--lint"
+const val ARG_HIDE = "--hide"
+const val ARG_UNHIDE_CLASSPATH_CLASSES = "--unhide-classpath-classes"
+const val ARG_ALLOW_REFERENCING_UNKNOWN_CLASSES = "--allow-referencing-unknown-classes"
+const val ARG_NO_UNKNOWN_CLASSES = "--no-unknown-classes"
+const val ARG_APPLY_API_LEVELS = "--apply-api-levels"
+const val ARG_GENERATE_API_LEVELS = "--generate-api-levels"
+const val ARG_ANDROID_JAR_PATTERN = "--android-jar-pattern"
+const val ARG_CURRENT_VERSION = "--current-version"
+const val ARG_CURRENT_CODENAME = "--current-codename"
+const val ARG_CURRENT_JAR = "--current-jar"
+const val ARG_CHECK_KOTLIN_INTEROP = "--check-kotlin-interop"
+const val ARG_PUBLIC = "--public"
+const val ARG_PROTECTED = "--protected"
+const val ARG_PACKAGE = "--package"
+const val ARG_PRIVATE = "--private"
+const val ARG_HIDDEN = "--hidden"
+const val ARG_NO_DOCS = "--no-docs"
+const val ARG_JAVA_SOURCE = "--java-source"
+const val ARG_REGISTER_ARTIFACT = "--register-artifact"
+const val ARG_INCLUDE_ANNOTATIONS = "--include-annotations"
+const val ARG_COPY_ANNOTATIONS = "--copy-annotations"
+const val ARG_INCLUDE_ANNOTATION_CLASSES = "--include-annotation-classes"
+const val ARG_REWRITE_ANNOTATIONS = "--rewrite-annotations"
+const val ARG_INCLUDE_SOURCE_RETENTION = "--include-source-retention"
+const val ARG_INCLUDE_SIG_VERSION = "--include-signature-version"
+const val ARG_UPDATE_API = "--update-api"
const val ARG_DEX_API_MAPPING = "--dex-api-mapping"
const val ARG_GENERATE_DOCUMENTATION = "--generate-documentation"
@@ -149,6 +149,8 @@
private val mutableHidePackages: MutableList<String> = mutableListOf()
/** Internal list backing [skipEmitPackages] */
private val mutableSkipEmitPackages: MutableList<String> = mutableListOf()
+ /** Internal list backing [convertToXmlFiles] */
+ private val mutableConvertToXmlFiles: MutableList<Pair<File, File>> = mutableListOf()
/** Ignored flags we've already warned about - store here such that we don't keep reporting them */
private val alreadyWarned: MutableSet<String> = mutableSetOf()
@@ -342,9 +344,6 @@
/** The list of compatibility checks to run */
val compatibilityChecks: List<CheckRequest> = mutableCompatibilityChecks
- /** Whether we should migrate nulls based on the previous API in [migrateNullsFrom] */
- var migrateNulls: Boolean = false
-
/** Existing external annotation files to merge in */
var mergeAnnotations: List<File> = mutableMergeAnnotations
@@ -423,6 +422,9 @@
/** Map from XML API descriptor file to corresponding artifact id name */
val artifactRegistrations = ArtifactTagger()
+ /** List of signature files to export as JDiff files */
+ val convertToXmlFiles = mutableConvertToXmlFiles
+
/** Temporary folder to use instead of the JDK default, if any */
var tempFolder: File? = null
@@ -543,7 +545,7 @@
// Note that this only affects stub generation, not signature files.
// For signature files, clear the compatibility mode
// (--annotations-in-signatures)
- "--include-annotations" -> generateAnnotations = true
+ ARG_INCLUDE_ANNOTATIONS -> generateAnnotations = true
// Flag used by test suite to avoid including locations in
// the output when diffing against golden files
@@ -593,17 +595,14 @@
ARG_INCLUDE_ANNOTATION_CLASSES -> copyStubAnnotationsFrom = stringToExistingDir(getValue(args, ++index))
ARG_INCLUDE_SOURCE_RETENTION -> includeSourceRetentionAnnotations = true
- ARG_PREVIOUS_API -> {
+ "--previous-api" -> {
migrateNullsFrom = stringToExistingFile(getValue(args, ++index))
- /* Don't flag this yet: allow a short quiet grace period
reporter.report(Errors.DEPRECATED_OPTION, null as File?,
- "$ARG_PREVIOUS_API is deprecated; instead " +
+ "--previous-api is deprecated; instead " +
"use $ARG_MIGRATE_NULLNESS $migrateNullsFrom")
- */
}
ARG_MIGRATE_NULLNESS -> {
- migrateNulls = true
// See if the next argument specifies the nullness API codebase
if (index < args.size - 1) {
val nextArg = args[index + 1]
@@ -617,14 +616,12 @@
}
}
- ARG_CURRENT_API -> {
+ "--current-api" -> {
val file = stringToExistingFile(getValue(args, ++index))
mutableCompatibilityChecks.add(CheckRequest(file, ApiType.PUBLIC_API, ReleaseType.DEV))
- /* Don't flag this yet: allow a short quiet grace period
reporter.report(Errors.DEPRECATED_OPTION, null as File?,
- "$ARG_CURRENT_API is deprecated; instead " +
- "use $ARG_CHECK_COMPATIBILITY $checkCompatibilityApiCurrent")
- */
+ "--current-api is deprecated; instead " +
+ "use $ARG_CHECK_COMPATIBILITY_API_CURRENT")
}
ARG_CHECK_COMPATIBILITY -> {
@@ -797,6 +794,12 @@
artifactRegistrations.register(artifactId, descriptor)
}
+ ARG_CONVERT_TO_JDIFF -> {
+ val signatureFile = stringToExistingFile(getValue(args, ++index))
+ val jDiffFile = stringToNewFile(getValue(args, ++index))
+ mutableConvertToXmlFiles.add(Pair(signatureFile, jDiffFile))
+ }
+
"--write-android-jar-signatures" -> {
val root = stringToExistingDir(getValue(args, ++index))
if (!File(root, "prebuilts/sdk").isDirectory) {
@@ -1127,10 +1130,6 @@
/** Makes sure that the flag combinations make sense */
private fun checkFlagConsistency() {
- if (migrateNulls && migrateNullsFrom == null) {
- throw DriverException(stderr = "$ARG_MIGRATE_NULLNESS requires $ARG_PREVIOUS_API")
- }
-
if (apiJar != null && sources.isNotEmpty()) {
throw DriverException(stderr = "Specify either $ARG_SOURCE_FILES or $ARG_INPUT_API_JAR, not both")
}
@@ -1203,6 +1202,7 @@
return file
}
+ @Suppress("unused")
private fun stringToExistingDirs(value: String): List<File> {
val files = mutableListOf<File>()
for (path in value.split(File.pathSeparatorChar)) {
@@ -1247,6 +1247,7 @@
return file
}
+ @Suppress("unused")
private fun stringToExistingFileOrDir(value: String): File {
val file = fileForPath(value)
if (!file.exists()) {
@@ -1425,7 +1426,6 @@
"", "\nExtracting Signature Files:",
// TODO: Document --show-annotation!
"$ARG_API <file>", "Generate a signature descriptor file",
- "$ARG_XML_API <file>", "Like $ARG_API, but emits the API in the JDiff XML format instead",
"$ARG_PRIVATE_API <file>", "Generate a signature descriptor file listing the exact private APIs",
"$ARG_DEX_API <file>", "Generate a DEX signature descriptor file listing the APIs",
"$ARG_PRIVATE_DEX_API <file>", "Generate a DEX signature descriptor file listing the exact private APIs",
@@ -1488,6 +1488,11 @@
"$ARG_LINT <id>", "Report issues of the given id as having lint-severity",
"$ARG_HIDE <id>", "Hide/skip issues of the given id",
+ "", "\nJDiff:",
+ "$ARG_XML_API <file>", "Like $ARG_API, but emits the API in the JDiff XML format instead",
+ "$ARG_CONVERT_TO_JDIFF <sig> <xml>", "Reads in the given signature file, and writes it out " +
+ "in the JDiff XML format. Can be specified multiple times.",
+
"", "\nStatistics:",
ARG_ANNOTATION_COVERAGE_STATS, "Whether $PROGRAM_NAME should emit coverage statistics for " +
"annotations, listing the percentage of the API that has been annotated with nullness information.",
diff --git a/src/test/java/com/android/tools/metalava/AndroidApiChecksTest.kt b/src/test/java/com/android/tools/metalava/AndroidApiChecksTest.kt
index 93f2c8c..080e347 100644
--- a/src/test/java/com/android/tools/metalava/AndroidApiChecksTest.kt
+++ b/src/test/java/com/android/tools/metalava/AndroidApiChecksTest.kt
@@ -181,7 +181,7 @@
src/android/pkg/NullMentions.java:19: warning: Return value of 'method4' documentation mentions 'null' without declaring @NonNull or @Nullable [Nullable:123]
src/android/pkg/NullMentions.java:8: warning: Field 'field2' documentation mentions 'null' without declaring @NonNull or @Nullable [Nullable:123]
""",
- extraArguments = arrayOf("--warning", "Nullable"), // Hidden by default
+ extraArguments = arrayOf(ARG_WARNING, "Nullable"), // Hidden by default
sourceFiles = *arrayOf(
java(
"""
@@ -225,7 +225,7 @@
warnings = """
src/android/pkg/NullMentions.java:15: warning: Field 'field1' documentation mentions constants without declaring an @IntDef [IntDef:124]
""",
- extraArguments = arrayOf("--warning", "IntDef"), // Hidden by default
+ extraArguments = arrayOf(ARG_WARNING, "IntDef"), // Hidden by default
sourceFiles = *arrayOf(
java(
"""
diff --git a/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt b/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
index fec71c8..ddafb8e 100644
--- a/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
+++ b/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
@@ -24,7 +24,7 @@
@Test
fun `Test emitting annotation statistics`() {
check(
- extraArguments = arrayOf("--annotation-coverage-stats"),
+ extraArguments = arrayOf(ARG_ANNOTATION_COVERAGE_STATS),
expectedOutput = """
Nullness Annotation Coverage Statistics:
0 out of 1 eligible fields (out of 2 total fields) were annotated (0%)
@@ -58,7 +58,7 @@
@Test
fun `Static final initialized fields are not nullable`() {
check(
- extraArguments = arrayOf("--annotation-coverage-stats"),
+ extraArguments = arrayOf(ARG_ANNOTATION_COVERAGE_STATS),
expectedOutput = """
Nullness Annotation Coverage Statistics:
0 out of 0 eligible fields (out of 0 total fields) were annotated (100%)
diff --git a/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt b/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
index b909a06..6471b92 100644
--- a/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
+++ b/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
@@ -56,9 +56,9 @@
),
// Skip the annotations themselves from the output
extraArguments = arrayOf(
- "--hide-package", "android.annotation",
- "--hide-package", "androidx.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "androidx.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
),
api = """
package test.pkg {
diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
index 9543d14..a7cb243 100644
--- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
@@ -106,7 +106,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
checkDoclava1 = false /* doesn't support parameter names */
)
}
@@ -141,7 +141,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
checkDoclava1 = false /* doesn't support default Values */
)
}
@@ -210,7 +210,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation", "--hide-package", "some.other.pkg"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation", ARG_HIDE_PACKAGE, "some.other.pkg"),
includeSignatureVersion = true,
checkDoclava1 = false /* doesn't support default Values */
)
@@ -286,7 +286,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation", "--hide-package", "androidx.collection"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation", ARG_HIDE_PACKAGE, "androidx.collection"),
includeSignatureVersion = true,
checkDoclava1 = false /* doesn't support default Values */
)
@@ -547,7 +547,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
checkDoclava1 = false /* doesn't support Kotlin... */
)
}
@@ -634,7 +634,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
checkDoclava1 = false /* doesn't support Kotlin... */
)
}
@@ -686,7 +686,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
checkDoclava1 = false /* doesn't support default Values */
)
}
@@ -778,7 +778,7 @@
}
}
""",
- extraArguments = arrayOf("--hide", "KotlinKeyword")
+ extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@@ -1265,7 +1265,7 @@
warnings = """
src/test/pkg/Foo.java:6: warning: method test.pkg.Foo.findViewById(int) should not be annotated @Nullable; it should be left unspecified to make it a platform type [ExpectedPlatformType:149]
""",
- extraArguments = arrayOf("--warning", "ExpectedPlatformType"),
+ extraArguments = arrayOf(ARG_WARNING, "ExpectedPlatformType"),
api = """
package test.pkg {
public abstract class Foo {
@@ -2408,7 +2408,7 @@
check(
checkDoclava1 = true,
extraArguments = arrayOf(
- "--hide-package", "com.squareup.okhttp"
+ ARG_HIDE_PACKAGE, "com.squareup.okhttp"
),
sourceFiles = *arrayOf(
java(
diff --git a/src/test/java/com/android/tools/metalava/ArtifactTaggerTest.kt b/src/test/java/com/android/tools/metalava/ArtifactTaggerTest.kt
index 940447c..24b9595 100644
--- a/src/test/java/com/android/tools/metalava/ArtifactTaggerTest.kt
+++ b/src/test/java/com/android/tools/metalava/ArtifactTaggerTest.kt
@@ -80,7 +80,7 @@
}
"""
),
- extraArguments = arrayOf("--error", "NoArtifactData,BrokenArtifactFile"),
+ extraArguments = arrayOf(ARG_ERROR, "NoArtifactData,BrokenArtifactFile"),
warnings = """
src/test/pkg/foo/Foo.java:2: error: Class test.pkg.foo.Foo belongs to multiple artifacts: my.library.group:foo:1.0.0 and my.library.group:bar:3.1.4 [BrokenArtifactFile:130]
src/test/pkg/foo/Foo.java:4: error: Class test.pkg.foo.Foo.Inner belongs to multiple artifacts: my.library.group:foo:1.0.0 and my.library.group:bar:3.1.4 [BrokenArtifactFile:130]
diff --git a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
index dde73d3..245406e 100644
--- a/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
+++ b/src/test/java/com/android/tools/metalava/CompatibilityCheckTest.kt
@@ -248,7 +248,7 @@
),
supportParameterName
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation")
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation")
)
}
@@ -796,7 +796,7 @@
),
suppressLintSource
),
- extraArguments = arrayOf("--hide-package", "android.annotation")
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "android.annotation")
)
}
@@ -1728,9 +1728,9 @@
),
extraArguments = arrayOf(
- "--show-annotation", "android.annotation.TestApi",
- "--hide-package", "android.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_SHOW_ANNOTATION, "android.annotation.TestApi",
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
),
checkCompatibilityApi =
@@ -2165,7 +2165,7 @@
checkDoclava1 = false,
extraArguments = arrayOf(
"--omit-locations",
- "--hide",
+ ARG_HIDE,
suppressLevels[apiLevel]
?: "AddedPackage,AddedClass,AddedMethod,AddedInterface,AddedField,ChangedDeprecated,RemovedField,RemovedClass,RemovedDeprecatedClass" +
(if ((apiLevel == 19 || apiLevel == 20) && loadPrevAsSignature) ",ChangedType" else "")
@@ -2192,7 +2192,7 @@
checkDoclava1 = false,
extraArguments = arrayOf(
"--omit-locations",
- "--hide",
+ ARG_HIDE,
suppressLevels[apiLevel]
?: "AddedPackage,AddedClass,AddedMethod,AddedInterface,AddedField,ChangedDeprecated,RemovedField,RemovedClass,RemovedDeprecatedClass"
),
diff --git a/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt b/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
index 3a24c98..a61b43b 100644
--- a/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
+++ b/src/test/java/com/android/tools/metalava/DocAnalyzerTest.kt
@@ -420,7 +420,6 @@
"""
package android.widget;
/**
- * Requires API level 21 (Android 5.0, Lollipop)
* @since 21
*/
@SuppressWarnings({"unchecked", "deprecation", "all"})
@@ -431,8 +430,6 @@
* <br>
* This method must be called on the thread that originally created
* this UI element. This is typically the main thread of your app.
- * <br>
- * Requires API level 24 (Android 7.0, Nougat)
* @since 24
* @return blah blah blah
*/
@@ -1072,7 +1069,6 @@
"""
package android.widget;
/**
- * Requires API level 21 (Android 5.0, Lollipop)
* @since 21
*/
@SuppressWarnings({"unchecked", "deprecation", "all"})
@@ -1080,8 +1076,6 @@
public Toolbar() { throw new RuntimeException("Stub!"); }
/**
* Existing documentation for {@linkplain #getCurrentContentInsetEnd()} here.
- * <br>
- * Requires API level 24 (Android 7.0, Nougat)
* @since 24
* @return blah blah blah
*/
@@ -1142,8 +1136,6 @@
public class Camera {
public Camera() { throw new RuntimeException("Stub!"); }
/**
- *
- * Requires API level 14 (Android 4.0, IceCreamSandwich)
* @deprecated
* <p class="caution"><strong>This class was deprecated in API level 21.</strong></p>
* Use something else.
@@ -1280,7 +1272,6 @@
"""
package test.pkg;
/**
- * Requires API level 21 (Android 5.0, Lollipop)
* @since 21
*/
@SuppressWarnings({"unchecked", "deprecation", "all"})
@@ -1495,9 +1486,9 @@
check(
extraArguments = arrayOf(
- "--write-stubs-source-list",
+ ARG_STUBS_SOURCE_LIST,
sourceList,
- "--generate-documentation",
+ ARG_GENERATE_DOCUMENTATION,
javadoc.path,
"-sourcepath",
"STUBS_DIR",
diff --git a/src/test/java/com/android/tools/metalava/DriverTest.kt b/src/test/java/com/android/tools/metalava/DriverTest.kt
index 252a0d5..21e5418 100644
--- a/src/test/java/com/android/tools/metalava/DriverTest.kt
+++ b/src/test/java/com/android/tools/metalava/DriverTest.kt
@@ -19,7 +19,6 @@
import com.android.SdkConstants
import com.android.SdkConstants.DOT_JAVA
import com.android.SdkConstants.DOT_KT
-import com.android.SdkConstants.VALUE_TRUE
import com.android.ide.common.process.DefaultProcessExecutor
import com.android.ide.common.process.LoggedProcessOutputHandler
import com.android.ide.common.process.ProcessException
@@ -45,6 +44,7 @@
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
+import org.junit.Before
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import java.io.File
@@ -60,6 +60,11 @@
@get:Rule
var temporaryFolder = TemporaryFolder()
+ @Before
+ fun setup() {
+ System.setProperty(ENV_VAR_METALAVA_TESTS_RUNNING, SdkConstants.VALUE_TRUE)
+ }
+
private fun createProject(vararg files: TestFile): File {
val dir = temporaryFolder.newFolder("project")
@@ -251,10 +256,13 @@
/**
* Whether to include the signature version in signatures
*/
- includeSignatureVersion: Boolean = false
+ includeSignatureVersion: Boolean = false,
+ /**
+ * List of signature files to convert to JDiff XML and the
+ * expected XML output
+ */
+ convertToJDiff: List<Pair<String, String>> = emptyList()
) {
- System.setProperty(ENV_VAR_METALAVA_TESTS_RUNNING, VALUE_TRUE)
-
// Ensure different API clients don't interfere with each other
try {
val method = ApiLookup::class.java.getDeclaredMethod("dispose")
@@ -303,6 +311,9 @@
val packages = sourceFiles.asSequence().map { findPackage(it.getContents()!!) }.filterNotNull().toSet()
val sourcePathDir = File(project, "src")
+ if (!sourcePathDir.isDirectory) {
+ sourcePathDir.mkdirs()
+ }
val sourcePath = sourcePathDir.path
val sourceList =
if (signatureSource != null) {
@@ -315,7 +326,7 @@
} else {
arrayOf(
signatureFile.path,
- "--hide",
+ ARG_HIDE,
"HiddenSuperclass"
) // Suppress warning #111
}
@@ -333,7 +344,7 @@
.map { it.path }
.joinToString(separator = File.pathSeparator) { it }
- arrayOf("--classpath", classpathString)
+ arrayOf(ARG_CLASS_PATH, classpathString)
} else {
emptyArray()
}
@@ -348,7 +359,7 @@
val mergeAnnotationsArgs = if (mergeXmlAnnotations != null) {
val merged = File(project, "merged-annotations.xml")
Files.asCharSink(merged, Charsets.UTF_8).write(mergeXmlAnnotations.trimIndent())
- arrayOf("--merge-annotations", merged.path)
+ arrayOf(ARG_MERGE_ANNOTATIONS, merged.path)
} else {
emptyArray()
}
@@ -356,7 +367,7 @@
val signatureAnnotationsArgs = if (mergeSignatureAnnotations != null) {
val merged = File(project, "merged-annotations.txt")
Files.asCharSink(merged, Charsets.UTF_8).write(mergeSignatureAnnotations.trimIndent())
- arrayOf("--merge-annotations", merged.path)
+ arrayOf(ARG_MERGE_ANNOTATIONS, merged.path)
} else {
emptyArray()
}
@@ -364,7 +375,7 @@
val javaStubAnnotationsArgs = if (mergeJavaStubAnnotations != null) {
val merged = File(project, "merged-annotations.java")
Files.asCharSink(merged, Charsets.UTF_8).write(mergeJavaStubAnnotations.trimIndent())
- arrayOf("--merge-annotations", merged.path)
+ arrayOf(ARG_MERGE_ANNOTATIONS, merged.path)
} else {
emptyArray()
}
@@ -437,44 +448,44 @@
val manifestFileArgs = if (manifest != null) {
val file = File(project, "manifest.xml")
Files.asCharSink(file, Charsets.UTF_8).write(manifest.trimIndent())
- arrayOf("--manifest", file.path)
+ arrayOf(ARG_MANIFEST, file.path)
} else {
emptyArray()
}
val migrateNullsArguments = if (migrateNullsApiFile != null) {
- arrayOf("--migrate-nullness", migrateNullsApiFile.path)
+ arrayOf(ARG_MIGRATE_NULLNESS, migrateNullsApiFile.path)
} else {
emptyArray()
}
val checkCompatibilityArguments = if (checkCompatibilityApiFile != null) {
- arrayOf("--check-compatibility:api:current", checkCompatibilityApiFile.path)
+ arrayOf(ARG_CHECK_COMPATIBILITY_API_CURRENT, checkCompatibilityApiFile.path)
} else {
emptyArray()
}
val checkCompatibilityApiReleasedArguments = if (checkCompatibilityApiReleasedFile != null) {
- arrayOf("--check-compatibility:api:released", checkCompatibilityApiReleasedFile.path)
+ arrayOf(ARG_CHECK_COMPATIBILITY_API_RELEASED, checkCompatibilityApiReleasedFile.path)
} else {
emptyArray()
}
val checkCompatibilityRemovedCurrentArguments = if (checkCompatibilityRemovedApiCurrentFile != null) {
- arrayOf("--check-compatibility:removed:current", checkCompatibilityRemovedApiCurrentFile.path)
+ arrayOf(ARG_CHECK_COMPATIBILITY_REMOVED_CURRENT, checkCompatibilityRemovedApiCurrentFile.path)
} else {
emptyArray()
}
val checkCompatibilityRemovedReleasedArguments = if (checkCompatibilityRemovedApiReleasedFile != null) {
- arrayOf("--check-compatibility:removed:released", checkCompatibilityRemovedApiReleasedFile.path)
+ arrayOf(ARG_CHECK_COMPATIBILITY_REMOVED_RELEASED, checkCompatibilityRemovedApiReleasedFile.path)
} else {
emptyArray()
}
- val quiet = if (expectedOutput != null && !extraArguments.contains("--verbose")) {
+ val quiet = if (expectedOutput != null && !extraArguments.contains(ARG_VERBOSE)) {
// If comparing output, avoid noisy output such as the banner etc
- arrayOf("--quiet")
+ arrayOf(ARG_QUIET)
} else {
emptyArray()
}
@@ -490,7 +501,7 @@
val file = jar.createFile(root)
sb.append(file.path)
}
- arrayOf("--annotation-coverage-of", sb.toString())
+ arrayOf(ARG_ANNOTATION_COVERAGE_OF, sb.toString())
} else {
emptyArray()
}
@@ -498,7 +509,7 @@
var proguardFile: File? = null
val proguardKeepArguments = if (proguard != null) {
proguardFile = File(project, "proguard.cfg")
- arrayOf("--proguard", proguardFile.path)
+ arrayOf(ARG_PROGUARD, proguardFile.path)
} else {
emptyArray()
}
@@ -506,15 +517,15 @@
val showAnnotationArguments = if (showAnnotations.isNotEmpty() || includeSystemApiAnnotations) {
val args = mutableListOf<String>()
for (annotation in showAnnotations) {
- args.add("--show-annotation")
+ args.add(ARG_SHOW_ANNOTATION)
args.add(annotation)
}
if (includeSystemApiAnnotations && !args.contains("android.annotation.SystemApi")) {
- args.add("--show-annotation")
+ args.add(ARG_SHOW_ANNOTATION)
args.add("android.annotation.SystemApi")
}
if (includeSystemApiAnnotations && !args.contains("android.annotation.TestApi")) {
- args.add("--show-annotation")
+ args.add(ARG_SHOW_ANNOTATION)
args.add("android.annotation.TestApi")
}
args.toTypedArray()
@@ -524,14 +535,14 @@
val showUnannotatedArgs =
if (showUnannotated) {
- arrayOf("--show-unannotated")
+ arrayOf(ARG_SHOW_UNANNOTATED)
} else {
emptyArray()
}
val includeSourceRetentionAnnotationArgs =
if (includeSourceRetentionAnnotations) {
- arrayOf("--include-source-retention")
+ arrayOf(ARG_INCLUDE_SOURCE_RETENTION)
} else {
emptyArray()
}
@@ -539,7 +550,7 @@
var removedApiFile: File? = null
val removedArgs = if (removedApi != null) {
removedApiFile = temporaryFolder.newFile("removed.txt")
- arrayOf("--removed-api", removedApiFile.path)
+ arrayOf(ARG_REMOVED_API, removedApiFile.path)
} else {
emptyArray()
}
@@ -547,7 +558,7 @@
var removedDexApiFile: File? = null
val removedDexArgs = if (removedDexApi != null) {
removedDexApiFile = temporaryFolder.newFile("removed-dex.txt")
- arrayOf("--removed-dex-api", removedDexApiFile.path)
+ arrayOf(ARG_REMOVED_DEX_API, removedDexApiFile.path)
} else {
emptyArray()
}
@@ -555,7 +566,7 @@
var apiFile: File? = null
val apiArgs = if (api != null) {
apiFile = temporaryFolder.newFile("public-api.txt")
- arrayOf("--api", apiFile.path)
+ arrayOf(ARG_API, apiFile.path)
} else {
emptyArray()
}
@@ -563,7 +574,7 @@
var exactApiFile: File? = null
val exactApiArgs = if (exactApi != null) {
exactApiFile = temporaryFolder.newFile("exact-api.txt")
- arrayOf("--exact-api", exactApiFile.path)
+ arrayOf(ARG_EXACT_API, exactApiFile.path)
} else {
emptyArray()
}
@@ -571,7 +582,7 @@
var apiXmlFile: File? = null
val apiXmlArgs = if (apiXml != null) {
apiXmlFile = temporaryFolder.newFile("public-api-xml.txt")
- arrayOf("--api-xml", apiXmlFile.path)
+ arrayOf(ARG_XML_API, apiXmlFile.path)
} else {
emptyArray()
}
@@ -579,7 +590,7 @@
var privateApiFile: File? = null
val privateApiArgs = if (privateApi != null) {
privateApiFile = temporaryFolder.newFile("private.txt")
- arrayOf("--private-api", privateApiFile.path)
+ arrayOf(ARG_PRIVATE_API, privateApiFile.path)
} else {
emptyArray()
}
@@ -587,7 +598,7 @@
var dexApiFile: File? = null
val dexApiArgs = if (dexApi != null) {
dexApiFile = temporaryFolder.newFile("public-dex.txt")
- arrayOf("--dex-api", dexApiFile.path)
+ arrayOf(ARG_DEX_API, dexApiFile.path)
} else {
emptyArray()
}
@@ -595,7 +606,7 @@
var dexApiMappingFile: File? = null
val dexApiMappingArgs = if (dexApiMapping != null) {
dexApiMappingFile = temporaryFolder.newFile("api-mapping.txt")
- arrayOf("--dex-api-mapping", dexApiMappingFile.path)
+ arrayOf(ARG_DEX_API_MAPPING, dexApiMappingFile.path)
} else {
emptyArray()
}
@@ -603,7 +614,27 @@
var privateDexApiFile: File? = null
val privateDexApiArgs = if (privateDexApi != null) {
privateDexApiFile = temporaryFolder.newFile("private-dex.txt")
- arrayOf("--private-dex-api", privateDexApiFile.path)
+ arrayOf(ARG_PRIVATE_DEX_API, privateDexApiFile.path)
+ } else {
+ emptyArray()
+ }
+
+ val convertToJDiffFiles = mutableListOf<Pair<File, File>>()
+ val convertToJDiffArgs = if (convertToJDiff.isNotEmpty()) {
+ val args = mutableListOf<String>()
+ var index = 1
+ for ((signatures, xml) in convertToJDiff) {
+ val convertSig = temporaryFolder.newFile("jdiff-signatures$index.txt")
+ convertSig.writeText(signatures.trimIndent(), Charsets.UTF_8)
+ val output = temporaryFolder.newFile("jdiff-output$index.xml")
+ convertToJDiffFiles += Pair(convertSig, output)
+ index++
+
+ args += ARG_CONVERT_TO_JDIFF
+ args += convertSig.path
+ args += output.path
+ }
+ args.toTypedArray()
} else {
emptyArray()
}
@@ -612,9 +643,9 @@
val stubsArgs = if (stubs.isNotEmpty()) {
stubsDir = temporaryFolder.newFolder("stubs")
if (docStubs) {
- arrayOf("--doc-stubs", stubsDir.path)
+ arrayOf(ARG_DOC_STUBS, stubsDir.path)
} else {
- arrayOf("--stubs", stubsDir.path)
+ arrayOf(ARG_STUBS, stubsDir.path)
}
} else {
emptyArray()
@@ -623,7 +654,7 @@
var stubsSourceListFile: File? = null
val stubsSourceListArgs = if (stubsSourceList != null) {
stubsSourceListFile = temporaryFolder.newFile("droiddoc-src-list")
- arrayOf("--write-stubs-source-list", stubsSourceListFile.path)
+ arrayOf(ARG_STUBS_SOURCE_LIST, stubsSourceListFile.path)
} else {
emptyArray()
}
@@ -633,7 +664,7 @@
ApiLookup::class.java.getDeclaredMethod("dispose").apply { isAccessible = true }.invoke(null)
applyApiLevelsXmlFile = temporaryFolder.newFile("api-versions.xml")
Files.asCharSink(applyApiLevelsXmlFile!!, Charsets.UTF_8).write(applyApiLevelsXml.trimIndent())
- arrayOf("--apply-api-levels", applyApiLevelsXmlFile.path)
+ arrayOf(ARG_APPLY_API_LEVELS, applyApiLevelsXmlFile.path)
} else {
emptyArray()
}
@@ -655,7 +686,7 @@
if (kotlinPath.isNotEmpty() &&
sourceList.asSequence().any { it.endsWith(DOT_KT) }
) {
- arrayOf("--classpath", kotlinPath.joinToString(separator = File.pathSeparator) { it })
+ arrayOf(ARG_CLASS_PATH, kotlinPath.joinToString(separator = File.pathSeparator) { it })
} else {
emptyArray()
}
@@ -670,7 +701,7 @@
sdk_widgets != null
) {
val dir = File(project, "sdk-files")
- sdkFilesArgs = arrayOf("--sdk-values", dir.path)
+ sdkFilesArgs = arrayOf(ARG_SDK_VALUES, dir.path)
sdkFilesDir = dir
} else {
sdkFilesArgs = emptyArray()
@@ -685,7 +716,7 @@
Files.asCharSink(signatureFile, Charsets.UTF_8).write(signatures.trimIndent())
index++
- args.add("--register-artifact")
+ args.add(ARG_REGISTER_ARTIFACT)
args.add(signatureFile.path)
args.add(artifactId)
}
@@ -697,15 +728,15 @@
val extractedAnnotationsZip: File?
val extractAnnotationsArgs = if (extractAnnotations != null) {
extractedAnnotationsZip = temporaryFolder.newFile("extracted-annotations.zip")
- arrayOf("--extract-annotations", extractedAnnotationsZip.path)
+ arrayOf(ARG_EXTRACT_ANNOTATIONS, extractedAnnotationsZip.path)
} else {
extractedAnnotationsZip = null
emptyArray()
}
val actualOutput = runDriver(
- "--no-color",
- "--no-banner",
+ ARG_NO_COLOR,
+ ARG_NO_BANNER,
// Tell metalava where to store temp folder: place them under the
// test root folder such that we clean up the output strings referencing
@@ -716,16 +747,16 @@
// For the tests we want to treat references to APIs like java.io.Closeable
// as a class that is part of the API surface, not as a hidden class as would
// be the case when analyzing a complete API surface
- // "--unhide-classpath-classes",
- "--allow-referencing-unknown-classes",
+ // ARG_UNHIDE_CLASSPATH_CLASSES,
+ ARG_ALLOW_REFERENCING_UNKNOWN_CLASSES,
// Annotation generation temporarily turned off by default while integrating with
// SDK builds; tests need these
- "--include-annotations",
+ ARG_INCLUDE_ANNOTATIONS,
- "--sourcepath",
+ ARG_SOURCE_PATH,
sourcePath,
- "--classpath",
+ ARG_CLASS_PATH,
androidJar.path,
*classpathArgs,
*kotlinPathArgs,
@@ -740,11 +771,11 @@
*dexApiMappingArgs,
*stubsArgs,
*stubsSourceListArgs,
- "--compatible-output=${if (compatibilityMode) "yes" else "no"}",
- "--output-kotlin-nulls=${if (outputKotlinStyleNulls) "yes" else "no"}",
- "--input-kotlin-nulls=${if (inputKotlinStyleNulls) "yes" else "no"}",
- "--omit-common-packages=${if (omitCommonPackages) "yes" else "no"}",
- "--include-signature-version=${if (includeSignatureVersion) "yes" else "no"}",
+ "$ARGS_COMPAT_OUTPUT=${if (compatibilityMode) "yes" else "no"}",
+ "$ARG_OUTPUT_KOTLIN_NULLS=${if (outputKotlinStyleNulls) "yes" else "no"}",
+ "$ARG_INPUT_KOTLIN_NULLS=${if (inputKotlinStyleNulls) "yes" else "no"}",
+ "$ARG_OMIT_COMMON_PACKAGES=${if (omitCommonPackages) "yes" else "no"}",
+ "$ARG_INCLUDE_SIG_VERSION=${if (includeSignatureVersion) "yes" else "no"}",
*coverageStats,
*quiet,
*mergeAnnotationsArgs,
@@ -757,6 +788,7 @@
*checkCompatibilityRemovedReleasedArguments,
*proguardKeepArguments,
*manifestFileArgs,
+ *convertToJDiffArgs,
*applyApiLevelsXmlArgs,
*showAnnotationArguments,
*showUnannotatedArgs,
@@ -777,27 +809,41 @@
if (api != null && apiFile != null) {
assertTrue("${apiFile.path} does not exist even though --api was used", apiFile.exists())
- val expectedText = readFile(apiFile, stripBlankLines, trim)
- assertEquals(stripComments(api, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(apiFile, stripBlankLines, trim)
+ assertEquals(stripComments(api, stripLineComments = false).trimIndent(), actualText)
// Make sure we can read back the files we write
ApiFile.parseApi(apiFile, options.outputKotlinStyleNulls, true)
}
if (apiXml != null && apiXmlFile != null) {
- assertTrue("${apiXmlFile.path} does not exist even though --api-xml was used", apiXmlFile.exists())
- val expectedText = readFile(apiXmlFile, stripBlankLines, trim)
- assertEquals(stripComments(apiXml, stripLineComments = false).trimIndent(), expectedText)
+ assertTrue("${apiXmlFile.path} does not exist even though $ARG_XML_API was used",
+ apiXmlFile.exists())
+ val actualText = readFile(apiXmlFile, stripBlankLines, trim)
+ assertEquals(stripComments(apiXml, stripLineComments = false).trimIndent(), actualText)
// Make sure we can read back the files we write
XmlUtils.parseDocument(apiXmlFile.readText(Charsets.UTF_8), false)
}
+ if (convertToJDiffFiles.isNotEmpty()) {
+ for (i in 0 until convertToJDiff.size) {
+ val expected = convertToJDiff[i].second
+ val converted = convertToJDiffFiles[i].second
+ assertTrue("${converted.path} does not exist even though $ARG_CONVERT_TO_JDIFF was used",
+ converted.exists())
+ val actualText = readFile(converted, stripBlankLines, trim)
+ assertEquals(stripComments(expected, stripLineComments = false).trimIndent(), actualText)
+ // Make sure we can read back the files we write
+ XmlUtils.parseDocument(converted.readText(Charsets.UTF_8), false)
+ }
+ }
+
if (removedApi != null && removedApiFile != null) {
assertTrue(
"${removedApiFile.path} does not exist even though --removed-api was used",
removedApiFile.exists()
)
- val expectedText = readFile(removedApiFile, stripBlankLines, trim)
- assertEquals(stripComments(removedApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(removedApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(removedApi, stripLineComments = false).trimIndent(), actualText)
// Make sure we can read back the files we write
ApiFile.parseApi(removedApiFile, options.outputKotlinStyleNulls, true)
}
@@ -807,8 +853,8 @@
"${removedDexApiFile.path} does not exist even though --removed-dex-api was used",
removedDexApiFile.exists()
)
- val expectedText = readFile(removedDexApiFile, stripBlankLines, trim)
- assertEquals(stripComments(removedDexApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(removedDexApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(removedDexApi, stripLineComments = false).trimIndent(), actualText)
}
if (exactApi != null && exactApiFile != null) {
@@ -816,8 +862,8 @@
"${exactApiFile.path} does not exist even though --exact-api was used",
exactApiFile.exists()
)
- val expectedText = readFile(exactApiFile, stripBlankLines, trim)
- assertEquals(stripComments(exactApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(exactApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(exactApi, stripLineComments = false).trimIndent(), actualText)
// Make sure we can read back the files we write
ApiFile.parseApi(exactApiFile, options.outputKotlinStyleNulls, true)
}
@@ -827,8 +873,8 @@
"${privateApiFile.path} does not exist even though --private-api was used",
privateApiFile.exists()
)
- val expectedText = readFile(privateApiFile, stripBlankLines, trim)
- assertEquals(stripComments(privateApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(privateApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(privateApi, stripLineComments = false).trimIndent(), actualText)
// Make sure we can read back the files we write
ApiFile.parseApi(privateApiFile, options.outputKotlinStyleNulls, true)
}
@@ -838,8 +884,8 @@
"${dexApiFile.path} does not exist even though --dex-api was used",
dexApiFile.exists()
)
- val expectedText = readFile(dexApiFile, stripBlankLines, trim)
- assertEquals(stripComments(dexApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(dexApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(dexApi, stripLineComments = false).trimIndent(), actualText)
}
if (privateDexApi != null && privateDexApiFile != null) {
@@ -847,8 +893,8 @@
"${privateDexApiFile.path} does not exist even though --private-dex-api was used",
privateDexApiFile.exists()
)
- val expectedText = readFile(privateDexApiFile, stripBlankLines, trim)
- assertEquals(stripComments(privateDexApi, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(privateDexApiFile, stripBlankLines, trim)
+ assertEquals(stripComments(privateDexApi, stripLineComments = false).trimIndent(), actualText)
}
if (dexApiMapping != null && dexApiMappingFile != null) {
@@ -856,8 +902,8 @@
"${dexApiMappingFile.path} does not exist even though --dex-api-maping was used",
dexApiMappingFile.exists()
)
- val expectedText = readFile(dexApiMappingFile, stripBlankLines, trim)
- assertEquals(stripComments(dexApiMapping, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(dexApiMappingFile, stripBlankLines, trim)
+ assertEquals(stripComments(dexApiMapping, stripLineComments = false).trimIndent(), actualText)
}
if (proguard != null && proguardFile != null) {
@@ -953,8 +999,8 @@
)
}
}
- val expectedText = readFile(stubFile, stripBlankLines, trim)
- assertEquals(stub, expectedText)
+ val actualText = readFile(stubFile, stripBlankLines, trim)
+ assertEquals(stub, actualText)
}
}
@@ -963,8 +1009,8 @@
"${stubsSourceListFile.path} does not exist even though --write-stubs-source-list was used",
stubsSourceListFile.exists()
)
- val expectedText = readFile(stubsSourceListFile, stripBlankLines, trim)
- assertEquals(stripComments(stubsSourceList, stripLineComments = false).trimIndent(), expectedText)
+ val actualText = readFile(stubsSourceListFile, stripBlankLines, trim)
+ assertEquals(stripComments(stubsSourceList, stripLineComments = false).trimIndent(), actualText)
}
if (checkCompilation && stubsDir != null && CHECK_STUB_COMPILATION) {
@@ -1318,13 +1364,13 @@
// separately on each test; slower but reliable.
val doclavaArg = when (argument) {
- "--api" -> "-api"
- "--removed-api" -> "-removedApi"
+ ARG_API -> "-api"
+ ARG_REMOVED_API -> "-removedApi"
else -> if (argument.startsWith("--")) argument.substring(1) else argument
}
val showAnnotationArgsDoclava1: Array<String> = if (showAnnotationArgs.isNotEmpty()) {
- showAnnotationArgs.map { if (it == "--show-annotation") "-showAnnotation" else it }.toTypedArray()
+ showAnnotationArgs.map { if (it == ARG_SHOW_ANNOTATION) "-showAnnotation" else it }.toTypedArray()
} else {
emptyArray()
}
diff --git a/src/test/java/com/android/tools/metalava/JDiffXmlTest.kt b/src/test/java/com/android/tools/metalava/JDiffXmlTest.kt
index 3f6597e..44649e5 100644
--- a/src/test/java/com/android/tools/metalava/JDiffXmlTest.kt
+++ b/src/test/java/com/android/tools/metalava/JDiffXmlTest.kt
@@ -474,4 +474,70 @@
"""
)
}
+
+ @Test
+ fun `Test conversion flag`() {
+ check(
+ compatibilityMode = true,
+ convertToJDiff = listOf(
+ Pair(
+ """
+ package test.pkg {
+ public class MyTest1 {
+ ctor public MyTest1();
+ }
+ }
+ """,
+ """
+ <api>
+ <package name="test.pkg"
+ >
+ <class name="MyTest1"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+ >
+ <constructor name="MyTest1"
+ type="test.pkg.MyTest1"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+ >
+ </constructor>
+ </class>
+ </package>
+ </api>
+ """
+ ),
+ Pair(
+ """
+ package test.pkg {
+ public class MyTest2 {
+ }
+ }
+ """,
+ """
+ <api>
+ <package name="test.pkg"
+ >
+ <class name="MyTest2"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+ >
+ </class>
+ </package>
+ </api>
+ """
+ )
+ )
+ )
+ }
}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/Java9LanguageFeaturesTest.kt b/src/test/java/com/android/tools/metalava/Java9LanguageFeaturesTest.kt
index e5233fa..4b218f9 100644
--- a/src/test/java/com/android/tools/metalava/Java9LanguageFeaturesTest.kt
+++ b/src/test/java/com/android/tools/metalava/Java9LanguageFeaturesTest.kt
@@ -48,7 +48,7 @@
}
}
""",
- extraArguments = arrayOf("--java-source", "1.9")
+ extraArguments = arrayOf(ARG_JAVA_SOURCE, "1.9")
)
}
@@ -143,7 +143,7 @@
}
}
""",
- extraArguments = arrayOf("--java-source", "1.9")
+ extraArguments = arrayOf(ARG_JAVA_SOURCE, "1.9")
)
}
}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/KeepFileTest.kt b/src/test/java/com/android/tools/metalava/KeepFileTest.kt
index 442b2c1..960d825 100644
--- a/src/test/java/com/android/tools/metalava/KeepFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/KeepFileTest.kt
@@ -79,7 +79,7 @@
<init>();
}
""",
- extraArguments = arrayOf("--hide", "KotlinKeyword")
+ extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/KotlinInteropChecksTest.kt b/src/test/java/com/android/tools/metalava/KotlinInteropChecksTest.kt
index 2360fb2..4e32d1d 100644
--- a/src/test/java/com/android/tools/metalava/KotlinInteropChecksTest.kt
+++ b/src/test/java/com/android/tools/metalava/KotlinInteropChecksTest.kt
@@ -22,7 +22,7 @@
@Test
fun `Hard Kotlin keywords`() {
check(
- extraArguments = arrayOf("--check-kotlin-interop"),
+ extraArguments = arrayOf(ARG_CHECK_KOTLIN_INTEROP),
warnings = """
src/test/pkg/Test.java:5: warning: Avoid method names that are Kotlin hard keywords ("fun"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords [KotlinKeyword:141]
src/test/pkg/Test.java:6: warning: Avoid parameter names that are Kotlin hard keywords ("typealias"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords [KotlinKeyword:141]
@@ -49,7 +49,7 @@
@Test
fun `Sam-compatible parameters should be last`() {
check(
- extraArguments = arrayOf("--check-kotlin-interop"),
+ extraArguments = arrayOf(ARG_CHECK_KOTLIN_INTEROP),
warnings = """
src/test/pkg/Test.java:10: warning: SAM-compatible parameters (such as parameter 1, "run", in test.pkg.Test.error) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions [SamShouldBeLast:142]
src/test/pkg/test.kt:7: warning: lambda parameters (such as parameter 1, "bar", in test.pkg.TestKt.error) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions [SamShouldBeLast:142]
@@ -88,7 +88,7 @@
@Test
fun `Companion object methods should be marked with JvmStatic`() {
check(
- extraArguments = arrayOf("--check-kotlin-interop"),
+ extraArguments = arrayOf(ARG_CHECK_KOTLIN_INTEROP),
warnings = """
src/test/pkg/Foo.kt:7: warning: Companion object constants like INTEGER_ONE should be marked @JvmField for Java interoperability; see https://android.github.io/kotlin-guides/interop.html#companion-constants [MissingJvmstatic:143]
src/test/pkg/Foo.kt:13: warning: Companion object methods like missing should be marked @JvmStatic for Java interoperability; see https://android.github.io/kotlin-guides/interop.html#companion-functions [MissingJvmstatic:143]
@@ -123,7 +123,7 @@
@Test
fun `Methods with default parameters should specify JvmOverloads`() {
check(
- extraArguments = arrayOf("--check-kotlin-interop"),
+ extraArguments = arrayOf(ARG_CHECK_KOTLIN_INTEROP),
warnings = """
src/test/pkg/Foo.kt:8: warning: A Kotlin method with default parameter values should be annotated with @JvmOverloads for better Java interoperability; see https://android.github.io/kotlin-guides/interop.html#function-overloads-for-defaults [MissingJvmstatic:143]
""",
@@ -150,7 +150,7 @@
@Test
fun `Methods which throw exceptions should document them`() {
check(
- extraArguments = arrayOf("--check-kotlin-interop"),
+ extraArguments = arrayOf(ARG_CHECK_KOTLIN_INTEROP),
warnings = """
src/test/pkg/Foo.kt:6: error: Method Foo.error_throws_multiple_times appears to be throwing java.io.FileNotFoundException; this should be recorded with a @Throws annotation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions [DocumentExceptions:145]
src/test/pkg/Foo.kt:16: error: Method Foo.error_throwsCheckedExceptionWithWrongExceptionClassInThrows appears to be throwing java.io.FileNotFoundException; this should be recorded with a @Throws annotation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions [DocumentExceptions:145]
diff --git a/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt b/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
index 36cac2d..cdc8f25 100644
--- a/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
+++ b/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
@@ -273,7 +273,7 @@
androidxNonNullSource,
androidxNullableSource
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
"""
package test.pkg {
@@ -323,7 +323,7 @@
androidxNonNullSource,
androidxNullableSource
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
"""
package test.pkg {
@@ -371,7 +371,7 @@
androidxNonNullSource,
androidxNullableSource
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
// TODO: Handle multiple nullness annotations
migrateNullsApi =
"""
@@ -439,7 +439,7 @@
androidxNonNullSource,
androidxNullableSource
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
// TODO: Handle multiple nullness annotations
migrateNullsApi =
"""
@@ -517,7 +517,7 @@
}
}
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation"),
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation"),
stubs = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
arrayOf(
"""
diff --git a/src/test/java/com/android/tools/metalava/OptionsTest.kt b/src/test/java/com/android/tools/metalava/OptionsTest.kt
index cb5f34c..34f4761 100644
--- a/src/test/java/com/android/tools/metalava/OptionsTest.kt
+++ b/src/test/java/com/android/tools/metalava/OptionsTest.kt
@@ -87,8 +87,6 @@
Extracting Signature Files:
--api <file> Generate a signature descriptor file
---api-xml <file> Like --api, but emits the API in the JDiff XML
- format instead
--private-api <file> Generate a signature descriptor file listing the
exact private APIs
--dex-api <file> Generate a DEX signature descriptor file listing
@@ -176,6 +174,13 @@
lint-severity
--hide <id> Hide/skip issues of the given id
+JDiff:
+--api-xml <file> Like --api, but emits the API in the JDiff XML
+ format instead
+--convert-to-jdiff <sig> <xml> Reads in the given signature file, and writes it
+ out in the JDiff XML format. Can be specified
+ multiple times.
+
Statistics:
--annotation-coverage-stats Whether metalava should emit coverage statistics
for annotations, listing the percentage of the
@@ -245,7 +250,7 @@
@Test
fun `Test invalid arguments`() {
- val args = listOf("--no-color", "--blah-blah-blah")
+ val args = listOf(ARG_NO_COLOR, "--blah-blah-blah")
val stdout = StringWriter()
val stderr = StringWriter()
@@ -268,7 +273,7 @@
@Test
fun `Test help`() {
- val args = listOf("--no-color", "--help")
+ val args = listOf(ARG_NO_COLOR, "--help")
val stdout = StringWriter()
val stderr = StringWriter()
diff --git a/src/test/java/com/android/tools/metalava/RewriteAnnotationsTest.kt b/src/test/java/com/android/tools/metalava/RewriteAnnotationsTest.kt
index dc9b24a..b8c2a41 100644
--- a/src/test/java/com/android/tools/metalava/RewriteAnnotationsTest.kt
+++ b/src/test/java/com/android/tools/metalava/RewriteAnnotationsTest.kt
@@ -34,10 +34,10 @@
assertTrue(source.path, source.isDirectory)
val target = temporaryFolder.newFolder()
runDriver(
- "--no-color",
- "--no-banner",
+ ARG_NO_COLOR,
+ ARG_NO_BANNER,
- "--copy-annotations",
+ ARG_COPY_ANNOTATIONS,
source.path,
target.path
)
@@ -102,10 +102,10 @@
bytecode.createFile(compiledStubs)
runDriver(
- "--no-color",
- "--no-banner",
+ ARG_NO_COLOR,
+ ARG_NO_BANNER,
- "--rewrite-annotations",
+ ARG_REWRITE_ANNOTATIONS,
compiledStubs.path
)
@@ -139,10 +139,10 @@
val jarFile = jarDesc.createFile(temporaryFolder.root)
runDriver(
- "--no-color",
- "--no-banner",
+ ARG_NO_COLOR,
+ ARG_NO_BANNER,
- "--rewrite-annotations",
+ ARG_REWRITE_ANNOTATIONS,
jarFile.path
)
diff --git a/src/test/java/com/android/tools/metalava/ShowAnnotationTest.kt b/src/test/java/com/android/tools/metalava/ShowAnnotationTest.kt
index 9bc5daf..4ef3a20 100644
--- a/src/test/java/com/android/tools/metalava/ShowAnnotationTest.kt
+++ b/src/test/java/com/android/tools/metalava/ShowAnnotationTest.kt
@@ -47,9 +47,9 @@
),
extraArguments = arrayOf(
- "--error", "UnhiddenSystemApi",
- "--hide-package", "android.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_ERROR, "UnhiddenSystemApi",
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
),
api = """
@@ -106,9 +106,9 @@
),
extraArguments = arrayOf(
- "--error", "UnhiddenSystemApi",
- "--hide-package", "android.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_ERROR, "UnhiddenSystemApi",
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
),
api = """
@@ -167,9 +167,9 @@
),
extraArguments = arrayOf(
- "--show-annotation", "android.annotation.TestApi",
- "--hide-package", "android.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_SHOW_ANNOTATION, "android.annotation.TestApi",
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
),
api = """
@@ -249,9 +249,9 @@
""",
includeSystemApiAnnotations = true,
extraArguments = arrayOf(
- "--show-annotation", "android.annotation.TestApi",
- "--hide-package", "android.annotation",
- "--hide-package", "android.support.annotation"
+ ARG_SHOW_ANNOTATION, "android.annotation.TestApi",
+ ARG_HIDE_PACKAGE, "android.annotation",
+ ARG_HIDE_PACKAGE, "android.support.annotation"
)
)
}
diff --git a/src/test/java/com/android/tools/metalava/StubsTest.kt b/src/test/java/com/android/tools/metalava/StubsTest.kt
index ac0e50d..25dca98 100644
--- a/src/test/java/com/android/tools/metalava/StubsTest.kt
+++ b/src/test/java/com/android/tools/metalava/StubsTest.kt
@@ -3332,7 +3332,7 @@
@androidx.annotation.Nullable
package test.pkg;
""",
- extraArguments = arrayOf("--hide-package", "androidx.annotation")
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation")
)
}
@@ -3410,14 +3410,14 @@
}
"""
),
- extraArguments = arrayOf("--hide-package", "androidx.annotation")
+ extraArguments = arrayOf(ARG_HIDE_PACKAGE, "androidx.annotation")
)
}
@Test
fun `Ensure we emit both deprecated javadoc and annotation with exclude-annotations`() {
check(
- extraArguments = arrayOf("--exclude-annotations"),
+ extraArguments = arrayOf(ARG_EXCLUDE_ANNOTATIONS),
compatibilityMode = false,
sourceFiles = *arrayOf(
java(
@@ -3455,7 +3455,7 @@
@Test
fun `Ensure we emit runtime and deprecated annotations in stubs with exclude-annotations`() {
check(
- extraArguments = arrayOf("--exclude-annotations"),
+ extraArguments = arrayOf(ARG_EXCLUDE_ANNOTATIONS),
compatibilityMode = false,
sourceFiles = *arrayOf(
java(
@@ -3592,8 +3592,8 @@
fun `Test update-api should not generate stubs`() {
check(
extraArguments = arrayOf(
- "--update-api",
- "--exclude-annotations"
+ ARG_UPDATE_API,
+ ARG_EXCLUDE_ANNOTATIONS
),
compatibilityMode = false,
sourceFiles = *arrayOf(
diff --git a/src/test/java/com/android/tools/metalava/apilevels/ApiGeneratorTest.kt b/src/test/java/com/android/tools/metalava/apilevels/ApiGeneratorTest.kt
index 8ea2750..c62331d 100644
--- a/src/test/java/com/android/tools/metalava/apilevels/ApiGeneratorTest.kt
+++ b/src/test/java/com/android/tools/metalava/apilevels/ApiGeneratorTest.kt
@@ -16,6 +16,8 @@
package com.android.tools.metalava.apilevels
+import com.android.tools.metalava.ARG_ANDROID_JAR_PATTERN
+import com.android.tools.metalava.ARG_GENERATE_API_LEVELS
import com.android.tools.metalava.DriverTest
import com.android.utils.XmlUtils
import com.google.common.truth.Truth
@@ -46,11 +48,11 @@
check(
extraArguments = arrayOf(
- "--generate-api-levels",
+ ARG_GENERATE_API_LEVELS,
outputPath,
- "--android-jar-pattern",
+ ARG_ANDROID_JAR_PATTERN,
"${oldSdkJars.path}/android-%/android.jar",
- "--android-jar-pattern",
+ ARG_ANDROID_JAR_PATTERN,
"${platformJars.path}/%/public/android.jar"
),
checkDoclava1 = false,