# The AST

An AST (abstract syntax tree) is a representation of the syntactic (or lexical)
structure of Dart code. The semantic structure of the code is modeled by the
[element][element] and [type][type] models.

## The Structure of an AST

An AST is composed of nodes (instances of `AstNode`) arranged as a tree. That
is, each node can have zero or more children, each of which is also a node, and
every node other than the root node has exactly one parent.

The root of the tree is typically a `CompilationUnit`. Compilation units have
children representing language constructs such as import directives and class
declarations. Class declarations have children representing, among other things,
each of the members of the class. The structure of the nodes is similar to, but
not identical to, the Dart language grammar.

As implied above, there are subclasses of `AstNode` for each production in the
grammar. The subclasses are defined in `package:analyzer/dart/ast/ast.dart`.

Every class of node provides access to its parent and children through getters.
For example, the class `BinaryExpression` defines the getters `parent`,
`leftOperand`, and `rightOperand`. It also provides getters for the tokens that
are a part of the construct (but not part of a child construct). In a binary
expression, for example, there is a getter to access the `operator`.

Every class of node and every token carries position information. You can ask
for the character `offset` of the beginning of the entity from the start of the
containing file, as well as the character `length`. For AST nodes, the offset
is the offset of this first token in the structure and the length includes the
end of the last token in the structure. Any whitespace before the first token or
after the last token is considered to be part of a parent node.

## The States of an AST

An AST can be in either of two states: unresolved or resolved. An unresolved
AST is one in which none of the nodes has any resolution information associated
with it. In an unresolved AST, the getters that access resolution information
will return `null`. A resolved AST is one in which all of the nodes have
resolution information associated with them.

So what do we mean by "resolution information"? Resolution is the process of
associating [element][element] and [type][type] information with an AST. These
topics are discussed in separate sections.

## Getting a Compilation Unit

If you have followed the steps in [Performing Analysis][analysis], and you want
to get the compilation unit for a file at a known `path`, then you can ask the
analysis session for an AST.

If you need an unresolved AST, then you can use the following method to access
the AST:

```dart
processFile(AnalysisSession session, String path) {
  ParsedUnitResult result = session.getParsedUnit(path);
  CompilationUnit unit = result.unit;
}
```

If you need a resolved AST, then you need to use the following asynchronous
method to access it:

```dart
processFile(AnalysisSession session, String path) async {
  ResolvedUnitResult result = await session.getResolvedUnit(path);
  CompilationUnit unit = result.unit;
}
```

## Traversing the Structure

There are two ways to traverse the structure of an AST: getters and visitors.

### Getters

Every node defines getters for accessing the parent and the children of that
node. Those getters can be used to traverse the structure, and are often the
most efficient way of doing so. For example, if you wanted to write a utility to
print the names of all of the members of each class in a given compilation unit,
it might look something like this:

```dart
void printMembers(CompilationUnit unit) {
  for (CompilationUnitMember unitMember in unit.declarations) {
    if (unitMember is ClassDeclaration) {
      print(unitMember.name.name);
      for (ClassMember classMember in unitMember.members) {
        if (classMember is MethodDeclaration) {
          print('  ${classMember.name}');
        } else if (classMember is FieldDeclaration) {
          for (VariableDeclaration field in classMember.fields.variables) {
            print('  ${field.name.name}');
          }
        } else if (classMember is ConstructorDeclaration) {
          if (classMember.name == null) {
            print('  ${unitMember.name.name}');
          } else {
            print('  ${unitMember.name.name}.${classMember.name.name}');
          }
        }
      }
    }
  }
}
```

### Visitors

Getters work well for cases like the above because compilation units cannot be
nested inside other compilation units, classes cannot be nested inside other
classes, etc. But when you're dealing with a structure that can be nested inside
similar structures (such as expressions, statements, and even functions), then
nested loops don't work very well. For those cases, the analyzer package
provides a visitor pattern.

There is a single visitor API, defined by the abstract class `AstVisitor`. It
defines a separate visit method for each class of AST node. For example, the
method `visitClassDeclaration` is used to visit a `ClassDeclaration`. If you
ask an AST node to accept a visitor, it will invoke the corresponding method on
the visitor interface.

If you want to define a visitor, you would create a subclass of one of the
concrete implementations of `AstVisitor`. The concrete subclasses are defined in
`package:analyzer/dart/ast/visitor.dart`. A couple of the most useful include
- `SimpleAstVisitor` which implements every visit method by doing nothing,
- `RecursiveAstVisitor` which will cause every node in a structure to be
  visited, and
- `GeneralizingAstVisitor` which makes it easy to visit general kinds of nodes,
  such as visiting any statement, or any expression.

As an example, let's assume you want to write some code to count the number of
`if` statements in a given structure. You need to visit every node, because you
can't know ahead of time where the `if` statements will be located, but there is
one specific class of node that you need to visit, so you don't need to handle
the general "groups" of nodes. The best approach for this example is to create a
subclass of `RecursiveAstVisitor`.

```dart
class IfCounter extends RecursiveAstVisitor<void> {
  int ifCount = 0;

  @override
  void visitIfStatement(IfStatement node) {
    ifCount++;
    super.visitIfStatement(node);
  }
}
```

## Differences From the Specification

Earlier we said that the structure of the tree is similar but not identical to
the grammar of the language. In addition to some minor differences, there is
one significant difference you should be aware of: the AST can express invalid
code. This is intentional. It allows the analyzer to recover better in the
presence of invalid code.

As an example, every function has a (possibly empty) list of parameters
associated with it. In Dart, parameters can either be positional or named, and
all of the positional parameters must be listed before the named parameters. But
in the AST, the parameters are allowed to occur in any order. The consequence of
this is that any code that traverses function parameters needs to be prepared
for them to occur in any order.

[analysis]: analysis.md
[element]: element.md
[type]: type.md
