Skip to content

Commit 81be2f3

Browse files
committed
..
1 parent 150cdfc commit 81be2f3

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

lib/parsejs.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ export 'src/lexer.dart' show ParseError;
1212
/// Parse [text] as a JavaScript program and return its AST.
1313
///
1414
/// Options:
15-
/// - [filename]: an string indicating where the source came from (this string has no special syntax or meaning).
15+
///
16+
/// - [filename]: a string indicating where the source came from (this string has no special syntax or meaning).
17+
///
1618
/// - [firstLine]: line number to associate with the first line of code.
19+
///
1720
/// - [handleNoise]: tolerate noise, such as hash bangs (#!) and HTML comment markers (<!--,-->) (default: true).
21+
///
1822
/// - [annotations]: if true, [Node.parent], [Scope.environment], and [Name.scope] will be initialized (default: true).
1923
Program parsejs(String text, {String filename, int firstLine : 1, bool handleNoise : true, bool annotations : true}) {
2024
Offsets offset = new Offsets(0, text.length, firstLine);

lib/src/ast.dart

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
89
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.
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.
5460
abstract 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.
5969
class 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.
7182
class 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.
8799
class 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.
141155
abstract class Statement extends Node {}
142156

157+
/// Statement of form: `;`
143158
class 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] }`
151167
class 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];`
163180
class 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]`.
175193
class 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]`
193212
class 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];`
209229
class 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];`
223244
class 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] }`
237259
class 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] }`
253276
class 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.
269293
class 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;`
288314
class 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];`
300327
class 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]`.
312340
class 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]`
330359
class 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]`
346376
class 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]);`
362393
class 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]`
378410
class 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]`
398432
class 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] }`.
416452
class 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];`
428465
class 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]`.
440478
class 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;`
456495
class 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.
466506
abstract class Expression extends Node {}
467507

508+
/// Expression of form: `this`
468509
class 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] ]`
476518
class 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] }`
494537
class 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]`.
506550
class 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] }`.
537583
class 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.
549596
class 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`
561610
class 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`
574625
class 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+
/// `=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, |=, ^=, &=`
591644
class 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]--`.
610664
class UpdateExpression extends Expression {
611665
String operator; // May be: ++, --
612666
Expression argument;

0 commit comments

Comments
 (0)