Parser Functions

As mentioned parseSourceFile sets up the initial state and passes the work onto parseSourceFileWorker function.

parseSourceFileWorker

Starts by creating a SourceFile AST node. Then it goes into parsing source code starting from the parseStatements function. Once that returns, it then completes the SourceFile node with additional information such as its nodeCount, identifierCount and such.

parseStatements

One of the most significant parseFoo style functions (a concept we cover next). It switches by the the current token returned from the scanner. E.g. if the current token is a SemicolonToken it will call out to parseEmptyStatement to create an AST node for an empty statement.

Node creation

The parser has a bunch of parserFoo functions with bodies that create Foo nodes. These are generally called (from other parser functions) at a time where a Foo node is expected. A typical sample of this process is the parseEmptyStatement() function which is used to parse out empty statements like ;;;;;;. Here is the function in its entirety

  1. function parseEmptyStatement(): Statement {
  2. let node = <Statement>createNode(SyntaxKind.EmptyStatement);
  3. parseExpected(SyntaxKind.SemicolonToken);
  4. return finishNode(node);
  5. }

It shows three critical functions createNode, parseExpected and finishNode.

createNode

The parser’s createNode function function createNode(kind: SyntaxKind, pos?: number): Node is responsible for creating a Node, setting up its SyntaxKind as passed in, and set the initial position if passed in (or use the position from the current scanner state).

parseExpected

The parser’s parseExpected function function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage): boolean will check that the current token in the parser state matches the desired SyntaxKind. If not it will either report the diagnosticMessage sent in or create a generic one of the form foo expected. It internally uses the parseErrorAtPosition function (which uses the scanning positions) to give good error reporting.

finishNode

The parser’s finishNode function function finishNode<T extends Node>(node: T, end?: number): T sets up the end position for the node and additional useful stuff like the parserContextFlags it was parsed under as well as if there were any errors before parsing this node (if there were then we cannot reuse this AST node in incremental parsing).