@@ -5,10 +5,14 @@ part 'ast_visitor.dart';
5
5
// AST structure mostly designed after the Mozilla Parser API:
6
6
// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
7
7
8
+ /// A node in the abstract syntax tree of a JavaScript program.
8
9
abstract 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.
9
13
Node parent;
10
14
11
- /// Source-code offsets .
15
+ /// Source-code offset .
12
16
int start, end;
13
17
14
18
/// 1-based line number.
@@ -51,11 +55,17 @@ abstract class Node {
51
55
dynamic visitBy (Visitor visitor);
52
56
}
53
57
58
+ /// Superclass for [Program] , [FunctionNode] , and [CatchClause] , which are the three types of node that
59
+ /// can host local variables.
54
60
abstract class Scope extends Node {
55
61
/// Variables declared in this scope, including the implicitly declared "arguments" variable.
56
62
Set <String > environment;
57
63
}
58
64
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.
59
69
class Programs extends Node {
60
70
List <Program > programs = < Program > [];
61
71
@@ -68,6 +78,7 @@ class Programs extends Node {
68
78
visitBy (Visitor v) => v.visitPrograms (this );
69
79
}
70
80
81
+ /// The root node of a JavaScript AST, representing the top-level scope.
71
82
class Program extends Scope {
72
83
/// Indicates where the program was parsed from.
73
84
/// 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 {
84
95
visitBy (Visitor v) => v.visitProgram (this );
85
96
}
86
97
98
+ /// A function, which may occur as a function expression, function declaration, or property accessor in an object literal.
87
99
class FunctionNode extends Scope {
88
100
Name name;
89
101
List <Name > params;
@@ -93,6 +105,7 @@ class FunctionNode extends Scope {
93
105
94
106
bool get isExpression => parent is FunctionExpression ;
95
107
bool get isDeclaration => parent is FunctionDeclaration ;
108
+ bool get isAccessor => parent is Property && (parent as Property ).isAccessor;
96
109
97
110
forEach (callback) {
98
111
if (name != null ) callback (name);
@@ -138,8 +151,10 @@ class Name extends Node {
138
151
139
152
///// STATEMENTS /////
140
153
154
+ /// Superclass for all nodes that are statements.
141
155
abstract class Statement extends Node {}
142
156
157
+ /// Statement of form: `;`
143
158
class EmptyStatement extends Statement {
144
159
void forEach (callback) {}
145
160
@@ -148,6 +163,7 @@ class EmptyStatement extends Statement {
148
163
visitBy (Visitor v) => v.visitEmptyStatement (this );
149
164
}
150
165
166
+ /// Statement of form: `{ [body] }`
151
167
class BlockStatement extends Statement {
152
168
List <Statement > body;
153
169
@@ -160,6 +176,7 @@ class BlockStatement extends Statement {
160
176
visitBy (Visitor v) => v.visitBlock (this );
161
177
}
162
178
179
+ /// Statement of form: `[expression];`
163
180
class ExpressionStatement extends Statement {
164
181
Expression expression;
165
182
@@ -172,6 +189,7 @@ class ExpressionStatement extends Statement {
172
189
visitBy (Visitor v) => v.visitExpressionStatement (this );
173
190
}
174
191
192
+ /// Statement of form: `if ([condition]) then [then] else [otherwise]` .
175
193
class IfStatement extends Statement {
176
194
Expression condition;
177
195
Statement then;
@@ -190,6 +208,7 @@ class IfStatement extends Statement {
190
208
visitBy (Visitor v) => v.visitIf (this );
191
209
}
192
210
211
+ /// Statement of form: `[label]: [body]`
193
212
class LabeledStatement extends Statement {
194
213
Name label;
195
214
Statement body;
@@ -206,6 +225,7 @@ class LabeledStatement extends Statement {
206
225
visitBy (Visitor v) => v.visitLabeledStatement (this );
207
226
}
208
227
228
+ /// Statement of form: `break;` or `break [label];`
209
229
class BreakStatement extends Statement {
210
230
Name label; // May be null.
211
231
@@ -220,6 +240,7 @@ class BreakStatement extends Statement {
220
240
visitBy (Visitor v) => v.visitBreak (this );
221
241
}
222
242
243
+ /// Statement of form: `continue;` or `continue [label];`
223
244
class ContinueStatement extends Statement {
224
245
Name label; // May be null.
225
246
@@ -234,6 +255,7 @@ class ContinueStatement extends Statement {
234
255
visitBy (Visitor v) => v.visitContinue (this );
235
256
}
236
257
258
+ /// Statement of form: `with ([object]) { [body] }`
237
259
class WithStatement extends Statement {
238
260
Expression object;
239
261
Statement body;
@@ -250,6 +272,7 @@ class WithStatement extends Statement {
250
272
visitBy (Visitor v) => v.visitWith (this );
251
273
}
252
274
275
+ /// Statement of form: `switch ([argument]) { [cases] }`
253
276
class SwitchStatement extends Statement {
254
277
Expression argument;
255
278
List <SwitchCase > cases;
@@ -266,13 +289,15 @@ class SwitchStatement extends Statement {
266
289
visitBy (Visitor v) => v.visitSwitch (this );
267
290
}
268
291
292
+ /// Clause in a switch: `case [expression]: [body]` or `default: [body]` if [expression] is null.
269
293
class SwitchCase extends Node {
270
294
Expression expression; // May be null (for default clause)
271
295
List <Statement > body;
272
296
273
297
SwitchCase (this .expression, this .body);
274
298
SwitchCase .defaultCase (this .body);
275
299
300
+ /// True if this is a default clause, and not a case clause.
276
301
bool get isDefault => expression == null ;
277
302
278
303
forEach (callback) {
@@ -285,6 +310,7 @@ class SwitchCase extends Node {
285
310
visitBy (Visitor v) => v.visitSwitchCase (this );
286
311
}
287
312
313
+ /// Statement of form: `return [argument];` or `return;`
288
314
class ReturnStatement extends Statement {
289
315
Expression argument;
290
316
@@ -297,6 +323,7 @@ class ReturnStatement extends Statement {
297
323
visitBy (Visitor v) => v.visitReturn (this );
298
324
}
299
325
326
+ /// Statement of form: `throw [argument];`
300
327
class ThrowStatement extends Statement {
301
328
Expression argument;
302
329
@@ -309,6 +336,7 @@ class ThrowStatement extends Statement {
309
336
visitBy (Visitor v) => v.visitThrow (this );
310
337
}
311
338
339
+ /// Statement of form: `try [block] catch [handler] finally [finalizer]` .
312
340
class TryStatement extends Statement {
313
341
BlockStatement block;
314
342
CatchClause handler; // May be null
@@ -327,6 +355,7 @@ class TryStatement extends Statement {
327
355
visitBy (Visitor v) => v.visitTry (this );
328
356
}
329
357
358
+ /// A catch clause: `catch ([param]) [body]`
330
359
class CatchClause extends Scope {
331
360
Name param;
332
361
BlockStatement body;
@@ -343,6 +372,7 @@ class CatchClause extends Scope {
343
372
visitBy (Visitor v) => v.visitCatchClause (this );
344
373
}
345
374
375
+ /// Statement of form: `while ([condition]) [body]`
346
376
class WhileStatement extends Statement {
347
377
Expression condition;
348
378
Statement body;
@@ -359,6 +389,7 @@ class WhileStatement extends Statement {
359
389
visitBy (Visitor v) => v.visitWhile (this );
360
390
}
361
391
392
+ /// Statement of form: `do [body] while ([condition]);`
362
393
class DoWhileStatement extends Statement {
363
394
Statement body;
364
395
Expression condition;
@@ -375,8 +406,10 @@ class DoWhileStatement extends Statement {
375
406
visitBy (Visitor v) => v.visitDoWhile (this );
376
407
}
377
408
409
+ /// Statement of form: `for ([init]; [condition]; [update]) [body]`
378
410
class ForStatement extends Statement {
379
- Node init; // May be VariableDeclaration, Expression, or null.
411
+ /// May be VariableDeclaration, Expression, or null.
412
+ Node init;
380
413
Expression condition; // May be null.
381
414
Expression update; // May be null.
382
415
Statement body;
@@ -395,8 +428,10 @@ class ForStatement extends Statement {
395
428
visitBy (Visitor v) => v.visitFor (this );
396
429
}
397
430
431
+ /// Statement of form: `for ([left] in [right]) [body]`
398
432
class ForInStatement extends Statement {
399
- Node left; // May be VariableDeclaration or Expression.
433
+ /// May be VariableDeclaration or Expression.
434
+ Node left;
400
435
Expression right;
401
436
Statement body;
402
437
@@ -413,6 +448,7 @@ class ForInStatement extends Statement {
413
448
visitBy (Visitor v) => v.visitForIn (this );
414
449
}
415
450
451
+ /// Statement of form: `function [function.name])([function.params]) { [function.body] }` .
416
452
class FunctionDeclaration extends Statement {
417
453
FunctionNode function;
418
454
@@ -425,6 +461,7 @@ class FunctionDeclaration extends Statement {
425
461
visitBy (Visitor v) => v.visitFunctionDeclaration (this );
426
462
}
427
463
464
+ /// Statement of form: `var [declarations];`
428
465
class VariableDeclaration extends Statement {
429
466
List <VariableDeclarator > declarations;
430
467
@@ -437,6 +474,7 @@ class VariableDeclaration extends Statement {
437
474
visitBy (Visitor v) => v.visitVariableDeclaration (this );
438
475
}
439
476
477
+ /// Variable declaration: `[name]` or `[name] = [init]` .
440
478
class VariableDeclarator extends Node {
441
479
Name name;
442
480
Expression init; // May be null.
@@ -453,6 +491,7 @@ class VariableDeclarator extends Node {
453
491
visitBy (Visitor v) => v.visitVariableDeclarator (this );
454
492
}
455
493
494
+ /// Statement of form: `debugger;`
456
495
class DebuggerStatement extends Statement {
457
496
forEach (callback) {}
458
497
@@ -463,8 +502,10 @@ class DebuggerStatement extends Statement {
463
502
464
503
///////
465
504
505
+ /// Superclass of all nodes that are expressions.
466
506
abstract class Expression extends Node {}
467
507
508
+ /// Expression of form: `this`
468
509
class ThisExpression extends Expression {
469
510
forEach (callback) {}
470
511
@@ -473,6 +514,7 @@ class ThisExpression extends Expression {
473
514
visitBy (Visitor v) => v.visitThis (this );
474
515
}
475
516
517
+ /// Expression of form: `[ [expressions] ]`
476
518
class ArrayExpression extends Expression {
477
519
List <Expression > expressions; // May CONTAIN nulls for omitted elements: e.g. [1,2,,,]
478
520
@@ -491,6 +533,7 @@ class ArrayExpression extends Expression {
491
533
visitBy (Visitor v) => v.visitArray (this );
492
534
}
493
535
536
+ /// Expression of form: `{ [properties] }`
494
537
class ObjectExpression extends Expression {
495
538
List <Property > properties;
496
539
@@ -503,6 +546,7 @@ class ObjectExpression extends Expression {
503
546
visitBy (Visitor v) => v.visitObject (this );
504
547
}
505
548
549
+ /// Property initializer `[key]: [value]` , or getter `get [key] [value]` , or setter `set [key] [value]` .
506
550
class Property extends Node {
507
551
Node key; // Literal or Name
508
552
Node value; // Will be FunctionNode with no name for getters and setters
@@ -515,6 +559,7 @@ class Property extends Node {
515
559
bool get isInit => kind == 'init' ;
516
560
bool get isGetter => kind == 'get' ;
517
561
bool get isSetter => kind == 'set' ;
562
+ bool get isAccessor => isGetter || isSetter;
518
563
519
564
String get nameString => key is Name ? (key as Name ).value : (key as LiteralExpression ).value.toString ();
520
565
@@ -534,6 +579,7 @@ class Property extends Node {
534
579
visitBy (Visitor v) => v.visitProperty (this );
535
580
}
536
581
582
+ /// Expression of form: `function [function.name]([function.params]) { [function.body] }` .
537
583
class FunctionExpression extends Expression {
538
584
FunctionNode function;
539
585
@@ -546,6 +592,7 @@ class FunctionExpression extends Expression {
546
592
visitBy (Visitor v) => v.visitFunctionExpression (this );
547
593
}
548
594
595
+ /// Comma-seperated expressions.
549
596
class SequenceExpression extends Expression {
550
597
List <Expression > expressions;
551
598
@@ -558,6 +605,8 @@ class SequenceExpression extends Expression {
558
605
visitBy (Visitor v) => v.visitSequence (this );
559
606
}
560
607
608
+ /// Expression of form: `+[argument]` , or using any of the unary operators:
609
+ /// `+, -, !, ~, typeof, void, delete`
561
610
class UnaryExpression extends Expression {
562
611
String operator ; // May be: +, -, !, ~, typeof, void, delete
563
612
Expression argument;
@@ -571,6 +620,8 @@ class UnaryExpression extends Expression {
571
620
visitBy (Visitor v) => v.visitUnary (this );
572
621
}
573
622
623
+ /// Expression of form: `[left] + [right]` , or using any of the binary operators:
624
+ /// `==, !=, ===, !==, <, <=, >, >=, <<, >>, >>>, +, -, *, /, %, |, ^, &, &&, ||, in, instanceof`
574
625
class BinaryExpression extends Expression {
575
626
Expression left;
576
627
String operator ; // May be: ==, !=, ===, !==, <, <=, >, >=, <<, >>, >>>, +, -, *, /, %, |, ^, &, &&, ||, in, instanceof
@@ -588,6 +639,8 @@ class BinaryExpression extends Expression {
588
639
visitBy (Visitor v) => v.visitBinary (this );
589
640
}
590
641
642
+ /// Expression of form: `[left] = [right]` or `[left] += [right]` or using any of the assignment operators:
643
+ /// `=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, |=, ^=, &=`
591
644
class AssignmentExpression extends Expression {
592
645
Expression left;
593
646
String operator ; // May be: =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, |=, ^=, &=
@@ -607,6 +660,7 @@ class AssignmentExpression extends Expression {
607
660
visitBy (Visitor v) => v.visitAssignment (this );
608
661
}
609
662
663
+ /// Expression of form: `++[argument]` , `--[argument]` , `[argument]++` , `[argument]--` .
610
664
class UpdateExpression extends Expression {
611
665
String operator ; // May be: ++, --
612
666
Expression argument;
0 commit comments