Package Structure

Plugins are used by tools that want to allow external contributions to the results being produced by that tool. At the moment, the analysis server is the only tool that supports plugins, but we intend to add plugin support to the command-line analyzer and possibly other tools as well. For that reason, throughout this document we will generically refer to the tool running the plugins as simply the tool.

In order to describe the way tools use plugins, we need to refer to four different packages. In order to keep the discussion clear, we will refer to those packages as the target package, the host package, the bootstrap package, and the plugin package. (If you're not familiar with packages, you should read about the Dart package manager.)

The target package is the package for which the tool is producing analysis results. If the tool is the analysis server, this is a package that the user has opened in the client and is actively developing.

The host package is a package that contains the information necessary to find and run the plugin. Specifically, the host package contains the bootstrap package. In order for the tool to find and use the host package, the target package must have a dependency on the host package. This can be either a normal dependency or a dev dependency.

The bootstrap package is a small package embedded within the host package that is used to load the plugin package.

The plugin package is the package that contains the actual implementation of the plugin.

While you could technically merge the bootstrap and plugin packages, we recommend this structure because it minimizes the number of additional files that need to be downloaded by users who do not choose to enable the hosted plugin.

As a concrete example, the angular package has a plugin associated with it. In order to implement this, the angular package has a bootstrap package embedded within it. When a target package (a package implementing a web app) has a dependency on the angular package, it can list ‘angular’ as an approved host package and the angular plugin will be run.

Plugin Discovery

Plugins are used by a tool to analyze the target package only if the tool is explicitly told to run them. Tools look for a list of approved host packages in the analysis options file (analysis_options.yaml) associated with the target package. The list has the form:

analyzer:
  plugins:
    - host_package_1
    - host_package_2

If a listed host package can be found (via the .packages file associated with the target package), then the tool looks in the host package for the folder <host_package>/tools/analyzer_plugin. If that directory exists and contains a valid bootstrap package, then the bootstrap package is run as a plugin.

Bootstrap Package Structure

The other packages described above can have any valid package structure, but the bootstrap package is required to have two specific files.

First, it must have a file named tools/analyzer_plugin/pubspec.yaml that can be used by the pub command to produce a .packages file describing how to resolve the package: URIs found in it. Typically, the only dependency that needs to be included is a dependency on the plugin package.

Second, it must have a file named tools/analyzer_plugin/bin/plugin.dart that contains the entry point for the plugin. Every plugin will be run in a separate isolate. As a result, the entry point must have the following signature:

void main(List<String> args, SendPort sendPort) {
  // Invoke the real main method in the plugin package. 
}

The body of main should typically be a single line that invokes a method or function within the plugin package that will create and start the plugin.

Plugin Execution

When a bootstrap package is to be run, the contents of the directory containing the bootstrap package are copied to a temporary directory, the pub command is run in that directory to produce a .packages file for the bootstrap package, and the file tools/analyzer_plugin/bin/plugin.dart is run in its own isolate.