# Metalava

Metalava is a metadata generator intended for JVM type projects. The main
users of this tool are Android Platform and AndroidX libraries, however this
tool also works on non-Android libraries.

Metalava has many features related to API management. Some examples of the most
commonly used ones are:

* Allows extracting the API (into signature text files, into stub API files
  which in turn get compiled into android.jar, the Android SDK library) and
  more importantly to hide code intended to be implementation only, driven by
  javadoc comments like @hide, @doconly, @removed, etc, as well as various
  annotations.

* Extracting source level annotations into external annotations file (such as
  the typedef annotations, which cannot be stored in the SDK as .class level
  annotations) to ship alongside the Android SDK and used by Android Lint.

* Diffing versions of the API and determining whether a newer version is
  compatible with the older version. (See [COMPATIBILITY.md](COMPATIBILITY.md))

## Building and running

To download the code and any dependencies required for building, see [DOWNLOADING.md](DOWNLOADING.md)

To build:

    $ cd tools/metalava
    $ ./gradlew

It puts build artifacts in `../../out/metalava/`.

To run the metalava executable:

### Through Gradle 

To list all the options:

    $ ./gradlew run

To run it with specific arguments:

    $ ./gradlew run --args="--api path/to/api.txt"

### Through distribution artifact

First build it with:

    $ ./gradlew installDist

Then run it with:

    $ ../../out/metalava/install/metalava/bin/metalava
                    _        _
     _ __ ___   ___| |_ __ _| | __ ___   ____ _
    | '_ ` _ \ / _ \ __/ _` | |/ _` \ \ / / _` |
    | | | | | |  __/ || (_| | | (_| |\ V / (_| |
    |_| |_| |_|\___|\__\__,_|_|\__,_| \_/ \__,_|

    metalava extracts metadata from source code to generate artifacts such as the
    signature files, the SDK stub files, external annotations etc.

    Usage: metalava <flags>

    Flags:

    --help                                This message.
    --quiet                               Only include vital output
    --verbose                             Include extra diagnostic output

    ...

(*output truncated*)

## Features

* Ability to read in an existing android.jar file instead of from source, which
  means we can regenerate signature files etc for older versions according to
  new formats (e.g. to fix past errors in doclava, such as annotation instance
  methods which were accidentally not included.)

* Ability to merge in data (annotations etc) from external sources, such as
  IntelliJ external annotations data as well as signature files containing
  annotations. This isn't just merged at export time, it's merged at codebase
  load time such that it can be part of the API analysis.

* Support for an updated signature file format (which is described in [FORMAT.md](FORMAT.md))

  * Address errors in the doclava1 format which for example was missing
    annotation class instance methods

  * Improve the signature format such that it for example labels enums "enum"
    instead of "abstract class extends java.lang.Enum", annotations as
    "@interface" instead of "abstract class extends java.lang.Annotation", sorts
    modifiers in the canonical modifier order, using "extends" instead of
    "implements" for the superclass of an interface, and many other similar
    tweaks outlined in the `Compatibility` class. (Metalava also allows (and
    ignores) block comments in the signature files.)

  * Add support for writing (and reading) annotations into the signature
    files. This is vital now that some of these annotations become part of the
    API contract (in particular nullness contracts, as well as parameter names
    and default values.)

  * Support for a "compact" nullness format -- one based on Kotlin's
    syntax. Since the goal is to have **all** API elements explicitly state
    their nullness contract, the signature files would very quickly become
    bloated with @NonNull and @Nullable annotations everywhere. So instead, the
    signature format now uses a suffix of `?` for nullable, `!` for not yet
    annotated, and nothing for non-null.

    Instead of

        method public java.lang.Double convert0(java.lang.Float);
        method @Nullable public java.lang.Double convert1(@NonNull java.lang.Float);

    we have

        method public java.lang.Double! convert0(java.lang.Float!);
        method public java.lang.Double? convert1(java.lang.Float);

  * Other compactness improvements: Skip packages in some cases both for export
    and reinsert during import. Specifically, drop "java.lang."  from package
    names such that you have

        method public void onUpdate(int, String);

    instead of

        method public void onUpdate(int, java.lang.String);

    Similarly, annotations (the ones considered part of the API; unknown
    annotations are not included in signature files) use just the simple name
    instead of the full package name, e.g. `@UiThread` instead of
    `@android.annotation.UiThread`.

  * Misc documentation handling; for example, it attempts to fix sentences that
    javadoc will mistreat, such as sentences that "end" with "e.g. ".  It also
    looks for various common typos and fixes those; here's a sample error
    message running metalava on master: Enhancing docs:

        frameworks/base/core/java/android/content/res/AssetManager.java:166: error: Replaced Kitkat with KitKat in documentation for Method android.content.res.AssetManager.getLocales() [Typo]
        frameworks/base/core/java/android/print/PrinterCapabilitiesInfo.java:122: error: Replaced Kitkat with KitKat in documentation for Method android.print.PrinterCapabilitiesInfo.Builder.setColorModes(int, int) [Typo]

* Built-in support for injecting new annotations for use by the Kotlin compiler,
  not just nullness annotations found in the source code and annotations merged
  in from external sources, but also inferring whether nullness annotations have
  recently changed and if so marking them as @Migrate (which lets the Kotlin
  compiler treat errors in the user code as warnings instead of errors.)

* Support for generating documentation into the stubs files (so we can run
  javadoc or [Dokka](https://github.com/Kotlin/dokka) on the stubs files instead
  of the source code). This means that the documentation tool itself does not
  need to be able to figure out which parts of the source code is included in
  the API and which one is implementation; it is simply handed the filtered API
  stub sources that include documentation.

* Support for parsing Kotlin files. API files can now be implemented in Kotlin
  as well and metalava will parse and extract API information from them just as
  is done for Java files.

* Like doclava1, metalava can diff two APIs and warn about API compatibility
  problems such as removing API elements. Metalava adds new warnings around
  nullness, such as attempting to change a nullness contract incompatibly
  (e.g. you can change a parameter from non null to nullable for final classes,
  but not versa).  It also lets you diff directly on a source tree; it does not
  require you to create two signature files to diff.

* Consistent stubs: In doclava1, the code which iterated over the API and
  generated the signature files and generated the stubs had diverged, so there
  was some inconsistency. In metalava the stub files contain **exactly** the
  same signatures as in the signature files.

  (This turned out to be incredibly important; this revealed for example that
  StringBuilder.setLength(int) was missing from the API signatures since it is a
  public method inherited from a package protected super class, which the API
  extraction code in doclava1 missed, but accidentally included in the SDK
  anyway since it packages package private classes. Metalava strictly applies
  the exact same API as is listed in the signature files, and once this was
  hooked up to the build it immediately became apparent that it was missing
  important methods that should really be part of the API.)

* API Lint: Metalava can optionally (with --api-lint) run a series of additional
  checks on the public API in the codebase and flag issues that are discouraged
  or forbidden by the Android API Council; there are currently around 80 checks.
  Some of these take advantage of looking at the source code which wasn't
  possible with the signature-file based Python version; for example, it looks
  inside method bodies to see if you're synchronizing on this or the current
  class, which is forbidden.

* Baselines: Metalava can report all of its issues into a "baseline" file, which
  records the current set of issues. From that point forward, when metalava
  finds a problem, it will only be reported if it is not already in the
  baseline.  This lets you enforce new issues going forward without having to
  fix all existing violations. Periodically, as older issues are fixed, you can
  regenerate the baseline. For issues with some false positives, such as API
  Lint, being able to check in the set of accepted or verified false positives
  is quite important.

* Metalava can generate reports about nullness annotation coverage (which helps
  target efforts since we plan to annotate the entire API). First, it can
  generate a raw count:

        Nullness Annotation Coverage Statistics:
        1279 out of 46900 methods were annotated (2%)
        2 out of 21683 fields were annotated (0%)
        2770 out of 47492 parameters were annotated (5%)

  More importantly, you can also point it to some existing compiled applications
  (.class or .jar files) and it will then measure the annotation coverage of the
  APIs used by those applications. This lets us target the most important APIs
  that are currently used by a corpus of apps and target our annotation efforts
  in a targeted way. For example, running the analysis on the current version of
  framework, and pointing it to the
  [Plaid](https://github.com/nickbutcher/plaid) app's compiled output with

      ... --annotation-coverage-of ~/plaid/app/build/intermediates/classes/debug

  This produces the following output:

    324 methods and fields were missing nullness annotations out of 650 total
    API references.  API nullness coverage is 50%

    ```
    | Qualified Class Name                                         |      Usage Count |
    |--------------------------------------------------------------|-----------------:|
    | android.os.Parcel                                            |              146 |
    | android.view.View                                            |              119 |
    | android.view.ViewPropertyAnimator                            |              114 |
    | android.content.Intent                                       |              104 |
    | android.graphics.Rect                                        |               79 |
    | android.content.Context                                      |               61 |
    | android.widget.TextView                                      |               53 |
    | android.transition.TransitionValues                          |               49 |
    | android.animation.Animator                                   |               34 |
    | android.app.ActivityOptions                                  |               34 |
    | android.view.LayoutInflater                                  |               31 |
    | android.app.Activity                                         |               28 |
    | android.content.SharedPreferences                            |               26 |
    | android.content.SharedPreferences.Editor                     |               26 |
    | android.text.SpannableStringBuilder                          |               23 |
    | android.view.ViewGroup.MarginLayoutParams                    |               21 |
    | ... (99 more items                                           |                  |
    ```

Top referenced un-annotated members:

    ```
    | Member                                                       |      Usage Count |
    |--------------------------------------------------------------|-----------------:|
    | Parcel.readString()                                          |               62 |
    | Parcel.writeString(String)                                   |               62 |
    | TextView.setText(CharSequence)                               |               34 |
    | TransitionValues.values                                      |               28 |
    | View.getContext()                                            |               28 |
    | ViewPropertyAnimator.setDuration(long)                       |               26 |
    | ViewPropertyAnimator.setInterpolator(android.animation.Ti... |               26 |
    | LayoutInflater.inflate(int, android.view.ViewGroup, boole... |               23 |
    | Rect.left                                                    |               22 |
    | Rect.top                                                     |               22 |
    | Intent.Intent(android.content.Context, Class<?>)             |               21 |
    | Rect.bottom                                                  |               21 |
    | TransitionValues.view                                        |               21 |
    | VERSION.SDK_INT                                              |               18 |
    | Context.getResources()                                       |               18 |
    | EditText.getText()                                           |               18 |
    | ... (309 more items                                          |                  |
    ```

  From this it's clear that it would be useful to start annotating
  android.os.Parcel and android.view.View for example where there are
  unannotated APIs that are frequently used, at least by this app.

* Built on top of a full, type-resolved AST. Doclava1 was integrated with
  javadoc, which meant that most of the source tree was opaque. Therefore, as
  just one example, the code which generated documentation for typedef constants
  had to require the constants to all share a single prefix it could look
  for. However, in metalava, annotation references are available at the AST
  level, so it can resolve references and map them back to the original field
  references and include those directly.

* Support for extracting annotations. Metalava can also generate the external
  annotation files needed by Studio and lint in Gradle, which captures the
  typedefs (@IntDef and @StringDef classes) in the source code. Prior to this
  this was generated manually via the development/tools/extract code. This also
  merges in manually curated data; some of this is in the manual/ folder in this
  project.

* Support for extracting API levels (api-versions.xml). This was generated by
  separate code (tools/base/misc/api-generator), invoked during the build. This
  functionality is now rolled into metalava, which has one very important
  attribute: metalava will use this information when recording API levels for
  API usage. (Prior to this, this was based on signature file parsing in
  doclava, which sometimes generated incorrect results. Metalava uses the
  android.jar files themselves to ensure that it computes the exact available
  SDK data for each API level.)

* Misc other features. For example, if you use the @VisibleForTesting annotation
  from the support library, where you can express the intended visibility if the
  method had not required visibility for testing, then metalava will treat that
  method using the intended visibility instead when generating signature files
  and stubs.

## Architecture & Implementation

Metalava is implemented on top of IntelliJ parsing APIs (PSI and UAST). However,
these are hidden behind a "model": an abstraction layer which only exposes high
level concepts like packages, classes and inner classes, methods, fields, and
modifier lists (including annotations).

This is done for multiple reasons:

(1) It allows us to have multiple "back-ends": for example, metalava can read in
    a model not just from parsing source code, but from reading older SDK
    android.jar files (e.g. backed by bytecode) or reading previous signature
    files.  Reading in multiple versions of an API lets doclava perform
    "diffing", such as warning if an API is changing in an incompatible way. It
    can also generate signature files in the new format (including data that was
    missing in older signature files, such as annotation methods) without having
    to parse older source code which may no longer be easy to parse.

(2) There's a lot of logic for deciding whether code found in the source tree
    should be included in the API. With the model approach we can build up an
    API and for example mark a subset of its methods as included. By having a
    separate hierarchy we can easily perform this work once and pass around our
    filtered model instead of passing around PsiClass and PsiMethod instances
    and having to keep the filtered data separately and remembering to always
    consult the filter, not the PSI elements directly.

The basic API element class is "Item". (In doclava1 this was called a
"DocInfo".)  There are several sub interfaces of Item: PackageItem, ClassItem,
MemberItem, MethodItem, FieldItem, ParameterItem, etc. And then there are
several implementation hierarchies: One is PSI based, where you point metalava
to a source tree or a .jar file, and it constructs Items built on top of PSI:
PsiPackageItem, PsiClassItem, PsiMethodItem, etc. Another is textual, based on
signature files: TextPackageItem, TextClassItem, and so on.

The "Codebase" class captures a complete API snapshot (including classes that
are hidden, which is why it's called a "Codebase" rather than an "API").

There are methods to load codebases - from source folders, from a .jar file,
from a signature file. That's how API diffing is performed: you load two
codebases (from whatever source you want, typically a previous API signature
file and the current set of source folders), and then you "diff" the two.

There are several key helpers that help with the implementation, detailed next.

### Visiting Items

First, metalava provides an ItemVisitor. This lets you visit the API easily.
For example, here's how you can visit every class:

    coebase.accept(object : ItemVisitor() {
        override fun visitClass(cls: ClassItem) {
            // code operating on the class here
        }
    })

Similarly you can visit all items (regardless of type) by overriding
`visitItem`, or to specifically visit methods, fields and so on overriding
`visitPackage`, `visitClass`, `visitMethod`, etc.

There is also an `ApiVisitor`. This is a subclass of the `ItemVisitor`, but
which limits itself to visiting code elements that are part of the API.

This is how for example the SignatureWriter and the StubWriter are both
implemented: they simply extend `ApiVisitor`, which means they'll only export
the API items in the codebase, and then in each relevant method they emit the
signature or stub data:

    class SignatureWriter(
            private val writer: PrintWriter,
            private val generateDefaultConstructors: Boolean,
            private val filter: (Item) -> Boolean) : ApiVisitor(
            visitConstructorsAsMethods = false) {

    ....

    override fun visitConstructor(constructor: ConstructorItem) {
        writer.print("    ctor ")
        writeModifiers(constructor)
        writer.print(constructor.containingClass().fullName())
        writeParameterList(constructor)
        writeThrowsList(constructor)
        writer.print(";\n")
    }

    ....

### Visiting Types

There is a `TypeVisitor` similar to `ItemVisitor` which you can use to visit all
types in the codebase.

When computing the API, all types that are included in the API should be
included (e.g. if `List<Foo>` is part of the API then `Foo` must be too).  This
is easy to do with the `TypeVisitor`.

### Diffing Codebases

Another visitor which helps with implementation is the ComparisonVisitor:

    open class ComparisonVisitor {
        open fun compare(old: Item, new: Item) {}
        open fun added(item: Item) {}
        open fun removed(item: Item) {}

        open fun compare(old: PackageItem, new: PackageItem) { }
        open fun compare(old: ClassItem, new: ClassItem) { }
        open fun compare(old: MethodItem, new: MethodItem) { }
        open fun compare(old: FieldItem, new: FieldItem) { }
        open fun compare(old: ParameterItem, new: ParameterItem) { }

        open fun added(item: PackageItem) { }
        open fun added(item: ClassItem) { }
        open fun added(item: MethodItem) { }
        open fun added(item: FieldItem) { }
        open fun added(item: ParameterItem) { }

        open fun removed(item: PackageItem) { }
        open fun removed(item: ClassItem) { }
        open fun removed(item: MethodItem) { }
        open fun removed(item: FieldItem) { }
        open fun removed(item: ParameterItem) { }
    }

This makes it easy to perform API comparison operations.

For example, metalava has a feature to mark "newly annotated" nullness
annotations as migrated. To do this, it just extends `ComparisonVisitor`,
overrides the `compare(old: Item, new: Item)` method, and checks whether the old
item has no nullness annotations and the new one does, and if so, also marks the
new annotations as @Migrate.

Similarly, the API Check can simply override

    open fun removed(item: Item) {
        reporter.report(error, item, "Removing ${Item.describe(item)} is not allowed")
    }

to flag all API elements that have been removed as invalid (since you cannot
remove API. (The real check is slightly more complicated; it looks into the
hierarchy to see if there still is an inherited method with the same signature,
in which case the deletion is allowed.))

### Documentation Generation

As mentioned above, metalava generates documentation directly into the stubs
files, which can then be processed by Dokka and Javadoc to generate the same
docs as before.

Doclava1 was integrated with javadoc directly, so the way it generated metadata
docs (such as documenting permissions, ranges and typedefs from annotations) was
to insert auxiliary tags (`@range`, `@permission`, etc) and then this would get
converted into English docs later via `macros_override.cs`.

This it not how metalava does it; it generates the English documentation
directly. This was not just convenient for the implementation (since metalava
does not use javadoc data structures to pass maps like the arguments for the
typedef macro), but should also help Dokka -- and arguably the Kotlin code which
generates the documentation is easier to reason about and to update when it's
handling loop conditionals. (As a result I for example improved some of the
grammar, e.g. when it's listing a number of possible constants the conjunction
is usually "or", but if it's a flag, the sentence begins with "a combination of
" and then the conjunction at the end should be "and").
