The parser is the second phase of the TypeScript compilation pipeline. It consumes the token stream produced by the Scanner and constructs an Abstract Syntax Tree (AST) that represents the syntactic structure of the source code. The parser produces a fully-formed tree of Node objects, each tagged with a SyntaxKind, which is then passed to the Binder for semantic analysis.
For information about lexical analysis and tokenization, see Scanner. For information about symbol creation and scope analysis, see Binder.
The parser implements a recursive descent algorithm that processes tokens sequentially and builds the AST bottom-up. The parser maintains state about the current parsing context and uses lookahead to resolve ambiguities in the TypeScript grammar.
Title: Parser Implementation Flow
Sources: src/compiler/parser.ts1-9700 src/compiler/scanner.ts1-2500
The primary entry point is the parseSourceFile function defined in parser.ts, which initializes the parser state and begins parsing:
Sources: src/compiler/parser.ts1200-1450
The parser uses a specialized node factory (parseNodeFactory) created via createNodeFactory. This factory is configured with specific flags to optimize node creation during the parsing phase:
BaseNodeFactory for low-level node allocation.Sources: src/compiler/parser.ts432-441 src/compiler/factory/nodeFactory.ts1-500
Every node in the AST has a kind property of type SyntaxKind, which identifies what syntactic construct the node represents. The SyntaxKind enum in types.ts contains over 300 values.
| Category | SyntaxKind Range | Example Values |
|---|---|---|
| Tokens | Unknown to LastKeyword | Identifier, NumericLiteral, PlusToken, IfKeyword |
| Names | QualifiedName, ComputedPropertyName | QualifiedName (A.B) |
| Type Nodes | TypePredicate to ImportType | TypeReference, UnionType, IntersectionType |
| Expressions | ArrayLiteralExpression to SatisfiesExpression | BinaryExpression, CallExpression, ArrowFunction |
| Statements | VariableStatement to DebuggerStatement | IfStatement, ForStatement, ReturnStatement |
| Declarations | FunctionDeclaration, ClassDeclaration, etc. | InterfaceDeclaration, EnumDeclaration |
| JSDoc | JSDocTypeExpression to JSDocImportTag | JSDocComment, JSDocParameterTag |
Sources: src/compiler/types.ts40-492
Title: AST Node Hierarchy Mapping
Sources: src/compiler/types.ts800-1500
All nodes share a common base structure defined in the Node interface:
| Property | Type | Description |
|---|---|---|
kind | SyntaxKind | Identifies the type of node. |
pos | number | Start position (including trivia). |
end | number | End position. |
flags | NodeFlags | Parsing context and metadata flags. |
parent | Node | Parent node (set by binder). |
transformFlags | TransformFlags | Flags for the transformation pipeline. |
Sources: src/compiler/types.ts800-850
The parser uses recursive descent, where each grammar production has a corresponding parsing function. These functions consume tokens and recursively call other parsing functions to build the AST.
| Function | Purpose | Returns |
|---|---|---|
parseSourceFile() | Entry point for a file. | SourceFile |
parseStatement() | Dispatches to specific statement parsers. | Statement |
parseExpression() | Dispatches to expression parsers. | Expression |
parseTypeNode() | Parses type annotations. | TypeNode |
parseClassDeclaration() | Parses class syntax and members. | ClassDeclaration |
parseBinaryExpression() | Handles operator precedence. | Expression |
Sources: src/compiler/parser.ts3000-9000
The TypeScript grammar contains ambiguities (e.g., <T>(x: T) => x vs <T>x) that require looking ahead. The parser uses speculationHelper to handle these cases.
Title: Speculation Mechanism in parser.ts
Sources: src/compiler/parser.ts414-418 src/compiler/parser.ts2000-2500
When the parser encounters unexpected tokens, it uses synchronization points (like statement boundaries or closing braces) to skip tokens and continue parsing. This ensures that multiple syntax errors can be reported in a single pass. Error messages are retrieved from diagnosticMessages.json.
Sources: src/compiler/parser.ts1500-2000 src/compiler/diagnosticMessages.json1-500
The parser supports incremental parsing via IncrementalParser.SyntaxCursor. When a file is edited, the parser can reuse nodes from the previous AST if the text within their range has not changed.
Sources: src/compiler/parser.ts1200-1450
The parser maintains context flags to track state, such as whether it is currently inside an async function or a generator.
These flags track the parsing context for function signatures:
| Flag | Purpose |
|---|---|
Yield | Inside generator function (yield is a keyword). |
Await | Inside async function (await is a keyword). |
Type | Currently parsing type parameters. |
Sources: src/compiler/parser.ts405-412
NodeFlags are propagated during parsing to children:
| Flag | Meaning |
|---|---|
JavaScriptFile | Parsing a .js or .jsx file. |
JsonFile | Parsing a .json file. |
AwaitContext | await expressions are syntactically valid here. |
Sources: src/compiler/types.ts782-848
pos: The start of the node, including leading trivia (whitespace/comments).end: The end of the node, excluding trailing trivia.This preservation of trivia is critical for the Language Service to provide accurate formatting and comment preservation.
Sources: src/compiler/types.ts28-36
Lists of nodes (e.g., function parameters) are stored in a NodeArray<T>, which extends the standard Array but adds pos and end properties to track the range of the entire collection.
Sources: src/compiler/types.ts3800-3850
JSDoc comments are parsed and attached to the succeeding declaration. The parser supports various tags defined in SyntaxKind (e.g., JSDocParameterTag, JSDocReturnTag). JSDoc parsing is governed by the jsDocParsingMode parameter.
Sources: src/compiler/parser.ts7500-9000
When parsing .tsx files, the parser switches modes to handle JSX tags. This includes parsing JsxElement, JsxSelfClosingElement, and JsxAttributes.
Sources: src/compiler/parser.ts6500-7500
Sources:
Refresh this wiki