# Introduction

The purpose of this page is to give you an overview of what an analyzer plugin
is and what it can do.

## What is a plugin?

An analyzer plugin is a piece of code that communicates with the analysis server
to provide additional analysis support. The additional support is often specific
to a package or set of packages. For example, there is a plugin that provides
analysis specific to the Angular framework. Plugins are not required to be
specific to a package, but if the additional analysis is general enough, we
would urge you to consider contributing it back to the Dart project so that
everyone can more easily benefit from your work.

Plugins are written in Dart. They are executed by the analysis server by running
them in the same VM as the analysis server, but each plugin is run in a separate
isolate. The analysis server communicates with the plugins using a wire protocol
that is specified in the [plugin API][pluginapi] document. This API is similar
to the API used by the analysis server to communicate with clients.

The API consists of three kinds of communication. When the analysis server needs
information from the plugin, or needs to pass information to the plugin, it
sends a *request*. The plugin is required to answer every request with a
*response*. If the request was a request for information, then the response will
contain the requested information. Otherwise, the response is merely an
acknowledgement that the request was received. In addition, the plugin can send
a *notification* to the server to provide information to the server.

## What can plugins do?

The scope of what a plugin can do is defined by the [plugin API][pluginapi], but
it's useful to start with a high level overview.

### Lifecycle management

The API includes support for managing the lifecycle of a plugin. There is no
guarantee about when plugins will be started or stopped relative to either the
server or to each other.

When a plugin is first started, the analysis server will send a
`plugin.versionCheck` request to the plugin to verify that the plugin is using
the same version of the API as the server and therefore can communicate with the
server. This exchange also serves to communicate some other information between
the two participants.

When the server is asked to shut down, it will send a `plugin.shutdown` request
to the plugin to shut it down. This gives the plugin an opportunity to release
system resources or perform any other necessary actions. If a plugin encounters
an error that causes it to need to shut down, it should send a `plugin.error`
notification to the server to indicate that it is doing so.

### Managing analysis

The API includes support for managing which files are analyzed. There is no
requirement for when a plugin should perform the analysis, but to optimize the
user experience plugins should provide information to the server as quickly as
possible.

The analysis server sends an `analysis.setContextRoots` request to plugins to
tell them which files to analyze. Each `ContextRoot` indicates the root
directory containing the files to be analyzed (included) and any files and
directories within the root that should *not* be analyzed (excluded). Plugins
can read and use excluded files in the process of analyzing included files, but
should not report results for excluded files.

In order to improve the user experience, the analysis server will send an
`analysis.setPriorityFiles` request to specify which files should take priority
over other files. These are typically the files that are open and visible in the
client.

The analysis server will send an `analysis.handleWatchEvents` request to the
plugin when one or more files (within a context root) have been modified. The
plugin is expected to re-analyze those files in order to update the results for
those files.

The analysis server will send an `analysis.updateContent` request when the user
has edited a file but the edited content has not yet been written to disk. This
allows the plugin to provide analysis results as the user is typing.

### Requesting Analysis Results

In order to accommodate the workflow of clients, there are two ways for the
server to request analysis results from a plugin.

First, the server can send a request to request specific results for a specific
file. This is typically used for client-side functionality that the user has to
explicitly request and that clients will not retain long term. For example,
there is a request to get code completion suggestions. These requests are
discussed below.

For functionality that is always available, or for results that can change
without the client being aware that new data should be requested, there is a
subscription model. The server will send an `analysis.setSubscriptions` request
to the plugin. This request tells the plugin which results should be sent to the
server when the results become available. The plugin does not send any results
in the response to the request, but instead is expected to send a notification
to the server when the results have been computed. The notifications that can be
requested are also discussed below.

If the server has explicitly requested results, either by a request or by a
subscription, the plugin should provide those results even if the file is an
excluded file. This exception to the general rule does *not* apply to the
implicit subscription for diagnostics.

Plugins should *not* send analysis results that duplicate the information
computed by the analysis server itself. The expectation is for plugins to
extend this information, not replicate it.

### Diagnostics

Plugins can generate diagnostics to make users aware of problems in the code
that they have written. Diagnostics are typically displayed in the editor region
and might also be displayed in a separate diagnostics view or as decorations on
a directory structure view.

Plugins are expected to send any diagnostics that they generate for any of the
analyzed files (files that are included in a context root and not excluded).
Essentially, there is an implicit subscription for errors for all (non-excluded)
files. The plugin should send the errors in an `analysis.errors` notification.

### Semantic highlighting

Highlight information is used to color the content of the editor view.

If the server has subscribed for highlighting information in some set of files,
then the plugin should send the information in an `analysis.highlights`
notification whenever the information needs to be updated.

### Navigation

Navigation information is used by clients to allow users to navigate to the
location at which an identifier is defined.

Navigation information can be requested both by an `analysis.getNavigation`
request and by a subscription. If the server has subscribed for navigation
information in some set of files, then the plugin should send the information in
an `analysis.navigation` notification whenever the information needs to be
updated.

There is a tutorial explaining how to implement [navigation][navigation].

### Mark occurrences

Occurrences information is used by clients to highlight (or mark) all uses
within a given file of a single identifier when the user selects one use of that
identifier.

If the server has subscribed for occurrences information in some set of files,
then the plugin should send the information in an `analysis.occurrences`
notification whenever the information needs to be updated.

### Outline

Outline information is typically used by clients to provide a tree indicating
the nesting structure of declarations within the code.

If the server has subscribed for outline information in some set of files, then
the plugin should send the information in an `analysis.outline` notification
whenever the information needs to be updated.

### Folding

Folding information is used to allow users to collapse regions of text.

If the server has subscribed for folding information in some set of files, then
the plugin should send the information in an `analysis.folding` notification
whenever the information needs to be updated.

### Code completion

Code completion suggestions are used to provide possible completions at some
point in the text.

When the client request completion suggestions, the server will send a
`completion.getSuggestions` request. The plugin should only send suggestions
that would not also be returned by the server.

There is a tutorial explaining how to implement [code completion][completion].

### Fixes and assists

Fixes and assists are a set of edits that users can choose to have applied to
the code. They differ from a refactoring in that they cannot request additional
information from the user. For example, a rename refactoring needs to know the
new name, which requires prompting the user, and hence could not be implemented
as either a fix or an assist.

Fixes are associated with specific diagnostics, and hence should only be
generated if the diagnostics with which they are associated have been generated.
For example, if a diagnostic has been produced to indicate that a required
semicolon is missing, a fix might be generated to insert a semicolon.

The analysis server will request fixes by sending an `edit.getFixes` request.

Plugins should provide fixes for as many of the diagnostics they generate as
possible, but only when those fixes provide value to the user. (For example, a
fix to insert a semicolon is arguably harder to use than simply typing the
semicolon would be, and therefore is of questionable value.)

There is a tutorial explaining how to implement [fixes][fixes].

Assists are generally context-specific and hence should only be generated if the
cursor is in the right context. For example, if there is an assist to convert an
expression-style function body (one introduced by `=>`) into a block-style
function body, it should only be generated if the cursor is within an
expression-style function body.

The analysis server will request assists by sending an `edit.getAssists`
request.

There is a tutorial explaining how to implement [assists][assists].

[assists]: assists.md
[completion]: completion.md
[fixes]: fixes.md
[navigation]: navigation.md
[pluginapi]: https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/main/pkg/analyzer_plugin/doc/api.html
