Initial documentation for the public API

Change-Id: Id859cf8ff40cd8c0ebce88874f11ca69c2697c59
Reviewed-on: https://dart-review.googlesource.com/c/79479
Reviewed-by: Danny Tuppeny <dantup@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/doc/tutorial/analysis.md b/pkg/analyzer/doc/tutorial/analysis.md
new file mode 100644
index 0000000..a44d6a5
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/analysis.md
@@ -0,0 +1,110 @@
+# Performing Analysis
+
+This document explains how to use the analyzer package to analyze Dart code.
+
+## 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,
+
+- which defined variables are defined, if any, and what their value is, and
+
+- any configuration information included in an analysis options file.
+
+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
+main() {
+  List<String> includedPaths = <String>[/* ... */];
+  AnalysisContextCollection collection =
+      new AnalysisContextCollection(includedPaths);
+  analyzeSomeFiles(collection, includedPaths);
+}
+```
+
+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
+analyzeSomeFiles(
+    AnalysisContextCollection collection, List<String> includedPaths) {
+  for (String path in includedPaths) {
+    AnalysisContext context = collection.contextFor(path);
+    analyzeSingleFile(context, path);
+  }
+}
+```
+
+## 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
+analyzeAllFiles(AnalysisContextCollection collection) {
+  for (AnalysisContext context in collection.contexts) {
+    for (String path in context.contextRoot.analyzedFiles()) {
+      analyzeSingleFile(context, path);
+    }
+  }
+}
+```
+
+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
+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
diff --git a/pkg/analyzer/doc/tutorial/ast.md b/pkg/analyzer/doc/tutorial/ast.md
new file mode 100644
index 0000000..843728b
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/ast.md
@@ -0,0 +1,185 @@
+# 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 either a synchronous or
+asynchronous method to access the AST:
+
+```dart
+main() async {
+  ParseResult result = await session.getParsedAst(path);
+  CompilationUnit unit = result.unit;
+}
+```
+
+or
+
+```dart
+main() {
+  ParseResult result = session.getParsedAstSync(path);
+  CompilationUnit unit = result.unit;
+}
+```
+
+If you need a resolved AST, then you need to use the following asynchronous
+method to access it:
+
+```dart
+main() async {
+  ResolveResult result = await session.getResolvedAst(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'll probably want to subclass 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.
+
+The one time you might want to implement `AstVisitor` rather than to extend one
+of the concrete subclasses is if it's critical that you implement _every_ visit
+method. The downside of doing this is that every time the AST structure is
+updated because of an enhancement to the language, your code will need to be
+updated to implement the newly added visit methods.
+
+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, so you'd want 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
diff --git a/pkg/analyzer/doc/tutorial/element.md b/pkg/analyzer/doc/tutorial/element.md
new file mode 100644
index 0000000..b16e4a4
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/element.md
@@ -0,0 +1,152 @@
+# The Element Model
+
+The element model, together with the [type][type] model, describes the semantic
+(as opposed to syntactic) structure of Dart code. The syntactic structure of the
+code is modeled by the [AST][ast].
+
+Generally speaking, an element represents something that is declared in the
+code, such as a class, method, or variable. Elements can be explicitly declared,
+such as the class defined by a class declaration, or implicitly declared, such
+as the default constructor defined for concrete classes that do not have any
+explicit constructor declarations.
+
+There are a few elements that represent entities that are not declared. For
+example, there is an element representing a compilation unit (`.dart` file) and
+another representing a library.
+
+## The Structure of the Element Model
+
+Elements are organized in a tree structure in which the children of an element
+are the elements that are logically (and often syntactically) part of the
+declaration of the parent. For example, the elements representing the methods
+and fields in a class are children of the element representing the class.
+
+Every complete element structure is rooted by an instance of the class
+`LibraryElement`. A library element represents a single Dart library. Every
+library is defined by one or more compilation units (the library and all of its
+parts). The compilation units are represented by the class
+`CompilationUnitElement` and are children of the library that is defined by
+them. Each compilation unit can contain zero or more top-level declarations,
+such as classes, functions, and variables. Each of these is in turn
+represented as an element that is a child of the compilation unit. Classes
+contain methods and fields, methods can contain local variables, etc.
+
+The element model does not contain everything in the code, only those things
+that are declared by the code. For example, it does not include any
+representation of the statements in a method body, but if one of those
+statements declares a local variable then the local variable will be represented
+by an element.
+
+## Getting a Compilation Unit Element
+
+If you have followed the steps in [Performing Analysis][analysis], and you want
+to get the compilation unit element for a file at a known `path`, then you can
+ask the analysis session for the compilation unit representing that file.
+
+```dart
+analyzeSingleFile(AnalysisSession session, String path) async {
+  UnitElementResult result = await session.UnitElementResult(path);
+  CompilationUnitElement element = result.element;
+}
+```
+
+(If you also need the resolved AST for the file, you can ask the session to
+`getResolvedAst`, and the returned result will have the library element for the
+library containing the compilation unit.)
+
+## Traversing the Structure
+
+There are two ways to traverse the structure of an AST: getters and visitors.
+
+### Getters
+
+Every element defines getters for accessing the parent and the children of that
+element. 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(CompilationUnitElement unitElement) {
+  for (ClassElement classElement in unitElement.types) {
+    print(classElement.name);
+    for (ConstructorElement constructorElement in classElement.constructors) {
+      if (!constructorElement.isSynthetic) {
+        if (constructorElement.name == null) {
+          print('  ${constructorElement.name}');
+        } else {
+          print('  ${classElement.name}.${constructorElement.name}');
+        }
+      }
+    }
+    for (FieldElement fieldElement in classElement.fields) {
+      if (!fieldElement.isSynthetic) {
+        print('  ${fieldElement.name}');
+      }
+    }
+    for (PropertyAccessorElement accessorElement in classElement.accessors) {
+      if (!accessorElement.isSynthetic) {
+        print('  ${accessorElement.name}');
+      }
+    }
+    for (MethodElement methodElement in classElement.methods) {
+      if (!methodElement.isSynthetic) {
+        print('  ${methodElement.name}');
+      }
+    }
+  }
+}
+```
+
+### Visitors
+
+Getters work well for most uses, but there might be times when it is easier to
+use a visitor pattern.
+
+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 functions), then nested loops don't work as well.
+For those cases, the analyzer package provides a visitor pattern.
+
+There is a single visitor API, defined by the abstract class `ElementVisitor`.
+It defines a separate visit method for each class of element. For example, the
+method `visitClassElement` is used to visit a `ClassElement`. If you ask an
+element to accept a visitor, it will invoke the corresponding method on the
+visitor interface.
+
+If you want to define a visitor, you'll probably want to subclass one of the
+concrete implementations of `ElementVisitor`. The concrete subclasses are
+defined in `package:analyzer/dart/element/visitor.dart`. A couple of the most
+useful include
+- `SimpleElementVisitor` which implements every visit method by doing nothing,
+- `RecursiveElementVisitor` which will cause every element in a structure to be
+  visited, and
+- `GeneralizingElementVisitor` which makes it easy to visit kinds of nodes, such
+  as visiting any executable element (method, function, accessor, or
+  constructor).
+
+As an example, let's assume you want to write some code to compute the largest
+number of parameters defined for any function or method in a given structure.
+You need to visit every element because functions can be nested inside
+functions. But because methods and functions are represented by different
+classes of elements, it would be useful to use a visitor that will generalize
+both to allow you to just visit executable elements (those that have
+parameters). Hence, you'd want to create a subclass of
+`GeneralizingElementVisitor`.
+
+```dart
+class ParameterCounter extends GeneralizingElementVisitor<void> {
+  int maxParameterCount = 0;
+
+  @override
+  void visitExecutableElement(ExecutableElement element) {
+    maxParameterCount = math.max(maxParameterCount, element.parameters.length);
+    super.visitExecutableElement(element);
+  }
+}
+```
+
+[analysis]: analysis.md
+[ast]: ast.md
+[type]: type.md
diff --git a/pkg/analyzer/doc/tutorial/introduction.md b/pkg/analyzer/doc/tutorial/introduction.md
new file mode 100644
index 0000000..3d07efe
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/introduction.md
@@ -0,0 +1,2 @@
+# Introduction
+
diff --git a/pkg/analyzer/doc/tutorial/tutorial.md b/pkg/analyzer/doc/tutorial/tutorial.md
new file mode 100644
index 0000000..aa9a3b2
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/tutorial.md
@@ -0,0 +1,29 @@
+# Analyzing Dart
+
+This is the table of contents for a set of tutorials that explain how to use the
+analyzer package to analyze Dart source code.
+
+## Pages
+
+The following is a list of the pages available in this tutorial.
+
+[Introduction][introduction] -
+What capabilities does the analyzer package support?
+
+[Performing Analysis][analysis]
+How to set up the objects used to analyze code.
+
+[The AST][ast]
+What is an AST?
+
+[The Element Model][element]
+What is the element model?
+
+[The Type Model][type]
+What is the type model?
+
+[analysis]: analysis.md
+[ast]: ast.md
+[element]: element.md
+[introduction]: introduction.md
+[type]: type.md
diff --git a/pkg/analyzer/doc/tutorial/type.md b/pkg/analyzer/doc/tutorial/type.md
new file mode 100644
index 0000000..1384082
--- /dev/null
+++ b/pkg/analyzer/doc/tutorial/type.md
@@ -0,0 +1,36 @@
+# The Type Model
+
+The type model represents the type information defined by the language
+specification.
+
+## Kinds of Types
+
+There are four classes of types, all of which are a subtype of the abstract
+class `DartType`.
+
+### Interface Types
+
+### Function Types
+
+### The Void Type
+
+### The Type Dynamic
+
+## Accessing Types
+
+There are two ways to get an instance of `DartType`: from the [AST][ast] and
+from the [element][element] model.
+
+In a resolved AST, every expression has a non-`null` `staticType`.
+
+Every element also has type information associated with it. Elements that define
+a type, such as a `ClassElement`, can return the type that they define. Elements
+that represent a function can return the `returnType` of the function as well as
+the `functionType` of the function. Elements that represent a variable (which
+includes fields and parameters) can return the explicitly or implicitly declared
+type of the variable.
+
+## Operations on Types
+
+[ast]: ast.md
+[element]: element.md