# Performing Analysis

This document explains how to use the analyzer package to analyze Dart code.

## Conceptual Model

The analysis of Dart code depends on a set of metadata (data outside the code
being analyzed). An _analysis context_ is a representation of a set of code that
should be analyzed using the same sources of metadata (same
`package_config.json` file). That set of code typically corresponds to a
package.

Despite the fact that the analyzer APIs do not support its use in an incremental
system, it is used that way by the analysis server, and that fact has influenced
the design of those APIs.

Specifically, in an incremental system the metadata can change over time.
Analysis results obtained with one state of the metadata won't necessarily be
consistent with results obtained with a different state of the metadata. Clients
that need to work in an incremental environment need to know whether the results
are consistent. (Clients that aren't running in an incremental environment can
typically ignore this complication.)

An _analysis session_ provides a way for clients to know when newly requested
results would be inconsistent with previously requested results. Each analysis
session is associated with a single analysis context and represents a specific
state of the metadata for that context. An instance of
`InconsistentAnalysisException` is thrown by a session if the state of the
metadata has changed since the session was created. This prevents clients from
getting results that would be inconsistent.

## Configuring the Contexts

If you want to use the analyzer package to analyze one or more files, then you
need to start by configuring the analysis context(s) in which analysis is to be
performed. An analysis context tells the analyzer how to perform analysis, and
includes such information as

- how to resolve `package:` URIs, and

- which defined variables are defined, if any, and what their value is.

Fortunately, the analyzer package can do most of the work for you. All you need
to do is create an instance of `AnalysisContextCollection`, giving it the paths
to all of the files, or directories containing files, that you want to be able
to analyze.

```dart
void main() {
  List<String> includedPaths = <String>[/* ... */];
  AnalysisContextCollection collection =
      new AnalysisContextCollection(includedPaths: includedPaths);
  analyzeSomeFiles(collection, includedPaths);
}

void analyzeSomeFiles(
    AnalysisContextCollection collection, List<String> includedPaths) {
  // See below.
}
```

The collection will create one or more analysis contexts that can be used to
correctly analyze all of the files and directories that were specified.

## Analyzing Individual Files

You might already know the paths to the files that you want to analyze. This
would be the case, for example, if you're analyzing a single file (and hence
created a list of length 1 when you created the collection). If that's the case,
then you can ask the collection for the context associated with each of those
files. If you have more than one file to analyze, don't assume that all of the
files will be analyzed by the same context.

For example, if you have defined the collection as above, you could perform
analysis with the following:

```dart
void analyzeSomeFiles(
    AnalysisContextCollection collection, List<String> includedPaths) {
  for (String path in includedPaths) {
    AnalysisContext context = collection.contextFor(path);
    analyzeSingleFile(context, path);
  }
}

void analyzeSingleFile(AnalysisContext context, String path) {
  // See below.
}
```

## Analyzing Multiple Files

If you don't know all of the files that need to be analyzed, you can analyze
all of the files in the included files and directories by using a slightly
different API:

```dart
void analyzeAllFiles(AnalysisContextCollection collection) {
  for (AnalysisContext context in collection.contexts) {
    for (String path in context.contextRoot.analyzedFiles()) {
      analyzeSingleFile(context, path);
    }
  }
}

void analyzeSingleFile(AnalysisContext context, String path) {
  // See below.
}
```

The files returned this way will include _all_ of the files in all of the
directories, including those that are not '.dart' files, except for those files
that have explicitly been excluded or that are in directories that have been
explicitly excluded. If you're only interested in analyzing `.dart` files, then
you would need to manually filter out other files.

## Accessing Analysis Results

Analysis contexts do not provide direct access to analysis results. Instead, you
need to ask the context for an analysis session and then ask the session to
perform the analysis.

```dart
void analyzeSingleFile(AnalysisContext context, String path) {
  AnalysisSession session = context.currentSession;
  // ...
}
```

The session either provides the requested results or throws an exception if the
results that would have been returned would have been inconsistent with other
results returned by the same session.

While this might seem odd, the API was designed this way to provide safety when
performing analysis in an environment in which the state of the files being
analyzed can change over time.

If you are analyzing multiple files and no exception is thrown, then you know
that the results are all consistent with each other. If an exception is thrown,
and consistency is important, then you can request the new current session from
the context and re-request all of the needed analyses.

Several of the methods on `AnalysisSession` are discussed in the sections that
describe the results that those methods are used to access, including the
tutorials on [ASTs][ast] and [elements][element].

[ast]: ast.md
[element]: element.md
