@@ -5,10 +5,14 @@ part 'ast_visitor.dart';
55// AST structure mostly designed after the Mozilla Parser API:
66// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
77
8+ /// A node in the abstract syntax tree of a JavaScript program.
89abstract class Node {
10+ /// The parent of this node, or null if this is the [Program] node.
11+ ///
12+ /// If you transform the AST in any way, it is your own responsibility to update pointer pointers accordingly.
913 Node parent;
1014
11- /// Source-code offsets .
15+ /// Source-code offset .
1216 int start, end;
1317
1418 /// 1-based line number.
@@ -51,11 +55,17 @@ abstract class Node {
5155 dynamic visitBy (Visitor visitor);
5256}
5357
58+ /// Superclass for [Program] , [FunctionNode] , and [CatchClause] , which are the three types of node that
59+ /// can host local variables.
5460abstract class Scope extends Node {
5561 /// Variables declared in this scope, including the implicitly declared "arguments" variable.
5662 Set <String > environment;
5763}
5864
65+ /// A collection of [Program] nodes.
66+ ///
67+ /// This node is not generated by the parser, but is a convenient way to cluster multiple ASTs into a single AST,
68+ /// should you wish to do so.
5969class Programs extends Node {
6070 List <Program > programs = < Program > [];
6171
@@ -68,6 +78,7 @@ class Programs extends Node {
6878 visitBy (Visitor v) => v.visitPrograms (this );
6979}
7080
81+ /// The root node of a JavaScript AST, representing the top-level scope.
7182class Program extends Scope {
7283 /// Indicates where the program was parsed from.
7384 /// In principle, this can be anything, it is just a string passed to the parser for convenience.
@@ -84,6 +95,7 @@ class Program extends Scope {
8495 visitBy (Visitor v) => v.visitProgram (this );
8596}
8697
98+ /// A function, which may occur as a function expression, function declaration, or property accessor in an object literal.
8799class FunctionNode extends Scope {
88100 Name name;
89101 List <Name > params;
@@ -93,6 +105,7 @@ class FunctionNode extends Scope {
93105
94106 bool get isExpression => parent is FunctionExpression ;
95107 bool get isDeclaration => parent is FunctionDeclaration ;
108+ bool get isAccessor => parent is Property && (parent as Property ).isAccessor;
96109
97110 forEach (callback) {
98111 if (name != null ) callback (name);
@@ -138,8 +151,10 @@ class Name extends Node {
138151
139152///// STATEMENTS /////
140153
154+ /// Superclass for all nodes that are statements.
141155abstract class Statement extends Node {}
142156
157+ /// Statement of form: `;`
143158class EmptyStatement extends Statement {
144159 void forEach (callback) {}
145160
@@ -148,6 +163,7 @@ class EmptyStatement extends Statement {
148163 visitBy (Visitor v) => v.visitEmptyStatement (this );
149164}
150165
166+ /// Statement of form: `{ [body] }`
151167class BlockStatement extends Statement {
152168 List <Statement > body;
153169
@@ -160,6 +176,7 @@ class BlockStatement extends Statement {
160176 visitBy (Visitor v) => v.visitBlock (this );
161177}
162178
179+ /// Statement of form: `[expression];`
163180class ExpressionStatement extends Statement {
164181 Expression expression;
165182
@@ -172,6 +189,7 @@ class ExpressionStatement extends Statement {
172189 visitBy (Visitor v) => v.visitExpressionStatement (this );
173190}
174191
192+ /// Statement of form: `if ([condition]) then [then] else [otherwise]` .
175193class IfStatement extends Statement {
176194 Expression condition;
177195 Statement then;
@@ -190,6 +208,7 @@ class IfStatement extends Statement {
190208 visitBy (Visitor v) => v.visitIf (this );
191209}
192210
211+ /// Statement of form: `[label]: [body]`
193212class LabeledStatement extends Statement {
194213 Name label;
195214 Statement body;
@@ -206,6 +225,7 @@ class LabeledStatement extends Statement {
206225 visitBy (Visitor v) => v.visitLabeledStatement (this );
207226}
208227
228+ /// Statement of form: `break;` or `break [label];`
209229class BreakStatement extends Statement {
210230 Name label; // May be null.
211231
@@ -220,6 +240,7 @@ class BreakStatement extends Statement {
220240 visitBy (Visitor v) => v.visitBreak (this );
221241}
222242
243+ /// Statement of form: `continue;` or `continue [label];`
223244class ContinueStatement extends Statement {
224245 Name label; // May be null.
225246
@@ -234,6 +255,7 @@ class ContinueStatement extends Statement {
234255 visitBy (Visitor v) => v.visitContinue (this );
235256}
236257
258+ /// Statement of form: `with ([object]) { [body] }`
237259class WithStatement extends Statement {
238260 Expression object;
239261 Statement body;
@@ -250,6 +272,7 @@ class WithStatement extends Statement {
250272 visitBy (Visitor v) => v.visitWith (this );
251273}
252274
275+ /// Statement of form: `switch ([argument]) { [cases] }`
253276class SwitchStatement extends Statement {
254277 Expression argument;
255278 List <SwitchCase > cases;
@@ -266,13 +289,15 @@ class SwitchStatement extends Statement {
266289 visitBy (Visitor v) => v.visitSwitch (this );
267290}
268291
292+ /// Clause in a switch: `case [expression]: [body]` or `default: [body]` if [expression] is null.
269293class SwitchCase extends Node {
270294 Expression expression; // May be null (for default clause)
271295 List <Statement > body;
272296
273297 SwitchCase (this .expression, this .body);
274298 SwitchCase .defaultCase (this .body);
275299
300+ /// True if this is a default clause, and not a case clause.
276301 bool get isDefault => expression == null ;
277302
278303 forEach (callback) {
@@ -285,6 +310,7 @@ class SwitchCase extends Node {
285310 visitBy (Visitor v) => v.visitSwitchCase (this );
286311}
287312
313+ /// Statement of form: `return [argument];` or `return;`
288314class ReturnStatement extends Statement {
289315 Expression argument;
290316
@@ -297,6 +323,7 @@ class ReturnStatement extends Statement {
297323 visitBy (Visitor v) => v.visitReturn (this );
298324}
299325
326+ /// Statement of form: `throw [argument];`
300327class ThrowStatement extends Statement {
301328 Expression argument;
302329
@@ -309,6 +336,7 @@ class ThrowStatement extends Statement {
309336 visitBy (Visitor v) => v.visitThrow (this );
310337}
311338
339+ /// Statement of form: `try [block] catch [handler] finally [finalizer]` .
312340class TryStatement extends Statement {
313341 BlockStatement block;
314342 CatchClause handler; // May be null
@@ -327,6 +355,7 @@ class TryStatement extends Statement {
327355 visitBy (Visitor v) => v.visitTry (this );
328356}
329357
358+ /// A catch clause: `catch ([param]) [body]`
330359class CatchClause extends Scope {
331360 Name param;
332361 BlockStatement body;
@@ -343,6 +372,7 @@ class CatchClause extends Scope {
343372 visitBy (Visitor v) => v.visitCatchClause (this );
344373}
345374
375+ /// Statement of form: `while ([condition]) [body]`
346376class WhileStatement extends Statement {
347377 Expression condition;
348378 Statement body;
@@ -359,6 +389,7 @@ class WhileStatement extends Statement {
359389 visitBy (Visitor v) => v.visitWhile (this );
360390}
361391
392+ /// Statement of form: `do [body] while ([condition]);`
362393class DoWhileStatement extends Statement {
363394 Statement body;
364395 Expression condition;
@@ -375,8 +406,10 @@ class DoWhileStatement extends Statement {
375406 visitBy (Visitor v) => v.visitDoWhile (this );
376407}
377408
409+ /// Statement of form: `for ([init]; [condition]; [update]) [body]`
378410class ForStatement extends Statement {
379- Node init; // May be VariableDeclaration, Expression, or null.
411+ /// May be VariableDeclaration, Expression, or null.
412+ Node init;
380413 Expression condition; // May be null.
381414 Expression update; // May be null.
382415 Statement body;
@@ -395,8 +428,10 @@ class ForStatement extends Statement {
395428 visitBy (Visitor v) => v.visitFor (this );
396429}
397430
431+ /// Statement of form: `for ([left] in [right]) [body]`
398432class ForInStatement extends Statement {
399- Node left; // May be VariableDeclaration or Expression.
433+ /// May be VariableDeclaration or Expression.
434+ Node left;
400435 Expression right;
401436 Statement body;
402437
@@ -413,6 +448,7 @@ class ForInStatement extends Statement {
413448 visitBy (Visitor v) => v.visitForIn (this );
414449}
415450
451+ /// Statement of form: `function [function.name])([function.params]) { [function.body] }` .
416452class FunctionDeclaration extends Statement {
417453 FunctionNode function;
418454
@@ -425,6 +461,7 @@ class FunctionDeclaration extends Statement {
425461 visitBy (Visitor v) => v.visitFunctionDeclaration (this );
426462}
427463
464+ /// Statement of form: `var [declarations];`
428465class VariableDeclaration extends Statement {
429466 List <VariableDeclarator > declarations;
430467
@@ -437,6 +474,7 @@ class VariableDeclaration extends Statement {
437474 visitBy (Visitor v) => v.visitVariableDeclaration (this );
438475}
439476
477+ /// Variable declaration: `[name]` or `[name] = [init]` .
440478class VariableDeclarator extends Node {
441479 Name name;
442480 Expression init; // May be null.
@@ -453,6 +491,7 @@ class VariableDeclarator extends Node {
453491 visitBy (Visitor v) => v.visitVariableDeclarator (this );
454492}
455493
494+ /// Statement of form: `debugger;`
456495class DebuggerStatement extends Statement {
457496 forEach (callback) {}
458497
@@ -463,8 +502,10 @@ class DebuggerStatement extends Statement {
463502
464503///////
465504
505+ /// Superclass of all nodes that are expressions.
466506abstract class Expression extends Node {}
467507
508+ /// Expression of form: `this`
468509class ThisExpression extends Expression {
469510 forEach (callback) {}
470511
@@ -473,6 +514,7 @@ class ThisExpression extends Expression {
473514 visitBy (Visitor v) => v.visitThis (this );
474515}
475516
517+ /// Expression of form: `[ [expressions] ]`
476518class ArrayExpression extends Expression {
477519 List <Expression > expressions; // May CONTAIN nulls for omitted elements: e.g. [1,2,,,]
478520
@@ -491,6 +533,7 @@ class ArrayExpression extends Expression {
491533 visitBy (Visitor v) => v.visitArray (this );
492534}
493535
536+ /// Expression of form: `{ [properties] }`
494537class ObjectExpression extends Expression {
495538 List <Property > properties;
496539
@@ -503,6 +546,7 @@ class ObjectExpression extends Expression {
503546 visitBy (Visitor v) => v.visitObject (this );
504547}
505548
549+ /// Property initializer `[key]: [value]` , or getter `get [key] [value]` , or setter `set [key] [value]` .
506550class Property extends Node {
507551 Node key; // Literal or Name
508552 Node value; // Will be FunctionNode with no name for getters and setters
@@ -515,6 +559,7 @@ class Property extends Node {
515559 bool get isInit => kind == 'init' ;
516560 bool get isGetter => kind == 'get' ;
517561 bool get isSetter => kind == 'set' ;
562+ bool get isAccessor => isGetter || isSetter;
518563
519564 String get nameString => key is Name ? (key as Name ).value : (key as LiteralExpression ).value.toString ();
520565
@@ -534,6 +579,7 @@ class Property extends Node {
534579 visitBy (Visitor v) => v.visitProperty (this );
535580}
536581
582+ /// Expression of form: `function [function.name]([function.params]) { [function.body] }` .
537583class FunctionExpression extends Expression {
538584 FunctionNode function;
539585
@@ -546,6 +592,7 @@ class FunctionExpression extends Expression {
546592 visitBy (Visitor v) => v.visitFunctionExpression (this );
547593}
548594
595+ /// Comma-seperated expressions.
549596class SequenceExpression extends Expression {
550597 List <Expression > expressions;
551598
@@ -558,6 +605,8 @@ class SequenceExpression extends Expression {
558605 visitBy (Visitor v) => v.visitSequence (this );
559606}
560607
608+ /// Expression of form: `+[argument]` , or using any of the unary operators:
609+ /// `+, -, !, ~, typeof, void, delete`
561610class UnaryExpression extends Expression {
562611 String operator ; // May be: +, -, !, ~, typeof, void, delete
563612 Expression argument;
@@ -571,6 +620,8 @@ class UnaryExpression extends Expression {
571620 visitBy (Visitor v) => v.visitUnary (this );
572621}
573622
623+ /// Expression of form: `[left] + [right]` , or using any of the binary operators:
624+ /// `==, !=, ===, !==, <, <=, >, >=, <<, >>, >>>, +, -, *, /, %, |, ^, &, &&, ||, in, instanceof`
574625class BinaryExpression extends Expression {
575626 Expression left;
576627 String operator ; // May be: ==, !=, ===, !==, <, <=, >, >=, <<, >>, >>>, +, -, *, /, %, |, ^, &, &&, ||, in, instanceof
@@ -588,6 +639,8 @@ class BinaryExpression extends Expression {
588639 visitBy (Visitor v) => v.visitBinary (this );
589640}
590641
642+ /// Expression of form: `[left] = [right]` or `[left] += [right]` or using any of the assignment operators:
643+ /// `=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, |=, ^=, &=`
591644class AssignmentExpression extends Expression {
592645 Expression left;
593646 String operator ; // May be: =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, |=, ^=, &=
@@ -607,6 +660,7 @@ class AssignmentExpression extends Expression {
607660 visitBy (Visitor v) => v.visitAssignment (this );
608661}
609662
663+ /// Expression of form: `++[argument]` , `--[argument]` , `[argument]++` , `[argument]--` .
610664class UpdateExpression extends Expression {
611665 String operator ; // May be: ++, --
612666 Expression argument;
0 commit comments