OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of js_ast; | 5 part of js_ast; |
6 | 6 |
7 abstract class NodeVisitor<T> { | 7 abstract class NodeVisitor<T> { |
8 T visitProgram(Program node); | 8 T visitProgram(Program node); |
9 | 9 |
10 T visitBlock(Block node); | 10 T visitBlock(Block node); |
(...skipping 23 matching lines...) Expand all Loading... |
34 T visitVariableDeclarationList(VariableDeclarationList node); | 34 T visitVariableDeclarationList(VariableDeclarationList node); |
35 T visitAssignment(Assignment node); | 35 T visitAssignment(Assignment node); |
36 T visitVariableInitialization(VariableInitialization node); | 36 T visitVariableInitialization(VariableInitialization node); |
37 T visitConditional(Conditional cond); | 37 T visitConditional(Conditional cond); |
38 T visitNew(New node); | 38 T visitNew(New node); |
39 T visitCall(Call node); | 39 T visitCall(Call node); |
40 T visitBinary(Binary node); | 40 T visitBinary(Binary node); |
41 T visitPrefix(Prefix node); | 41 T visitPrefix(Prefix node); |
42 T visitPostfix(Postfix node); | 42 T visitPostfix(Postfix node); |
43 T visitSpread(Spread node); | 43 T visitSpread(Spread node); |
| 44 T visitYield(Yield node); |
44 | 45 |
45 T visitIdentifier(Identifier node); | 46 T visitIdentifier(Identifier node); |
46 T visitThis(This node); | 47 T visitThis(This node); |
47 T visitSuper(Super node); | 48 T visitSuper(Super node); |
48 T visitAccess(PropertyAccess node); | 49 T visitAccess(PropertyAccess node); |
49 T visitRestParameter(RestParameter node); | 50 T visitRestParameter(RestParameter node); |
50 | 51 |
51 T visitNamedFunction(NamedFunction node); | 52 T visitNamedFunction(NamedFunction node); |
52 T visitFun(Fun node); | 53 T visitFun(Fun node); |
53 T visitArrowFun(ArrowFun node); | 54 T visitArrowFun(ArrowFun node); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 return visitExpression(node); | 134 return visitExpression(node); |
134 } | 135 } |
135 } | 136 } |
136 T visitConditional(Conditional node) => visitExpression(node); | 137 T visitConditional(Conditional node) => visitExpression(node); |
137 T visitNew(New node) => visitExpression(node); | 138 T visitNew(New node) => visitExpression(node); |
138 T visitCall(Call node) => visitExpression(node); | 139 T visitCall(Call node) => visitExpression(node); |
139 T visitBinary(Binary node) => visitExpression(node); | 140 T visitBinary(Binary node) => visitExpression(node); |
140 T visitPrefix(Prefix node) => visitExpression(node); | 141 T visitPrefix(Prefix node) => visitExpression(node); |
141 T visitPostfix(Postfix node) => visitExpression(node); | 142 T visitPostfix(Postfix node) => visitExpression(node); |
142 T visitSpread(Spread node) => visitPrefix(node); | 143 T visitSpread(Spread node) => visitPrefix(node); |
| 144 T visitYield(Yield node) => visitExpression(node); |
143 T visitAccess(PropertyAccess node) => visitExpression(node); | 145 T visitAccess(PropertyAccess node) => visitExpression(node); |
144 | 146 |
145 T visitIdentifier(Identifier node) => visitExpression(node); | 147 T visitIdentifier(Identifier node) => visitExpression(node); |
146 T visitThis(This node) => visitExpression(node); | 148 T visitThis(This node) => visitExpression(node); |
147 T visitSuper(Super node) => visitExpression(node); | 149 T visitSuper(Super node) => visitExpression(node); |
148 | 150 |
149 T visitRestParameter(RestParameter node) => visitNode(node); | 151 T visitRestParameter(RestParameter node) => visitNode(node); |
150 | 152 |
151 T visitNamedFunction(NamedFunction node) => visitExpression(node); | 153 T visitNamedFunction(NamedFunction node) => visitExpression(node); |
152 T visitFunctionExpression(FunctionExpression node) => visitExpression(node); | 154 T visitFunctionExpression(FunctionExpression node) => visitExpression(node); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 for (var node in exprs) { | 609 for (var node in exprs) { |
608 comma = (comma == null) ? node : new Binary(op, comma, node); | 610 comma = (comma == null) ? node : new Binary(op, comma, node); |
609 } | 611 } |
610 return comma; | 612 return comma; |
611 } | 613 } |
612 | 614 |
613 int get precedenceLevel; | 615 int get precedenceLevel; |
614 | 616 |
615 Statement toStatement() => new ExpressionStatement(toVoidExpression()); | 617 Statement toStatement() => new ExpressionStatement(toVoidExpression()); |
616 Statement toReturn() => new Return(this); | 618 Statement toReturn() => new Return(this); |
| 619 Statement toYieldStatement({bool star: false}) => |
| 620 new ExpressionStatement(new Yield(this, star: star)); |
617 | 621 |
618 Expression toVoidExpression() => this; | 622 Expression toVoidExpression() => this; |
619 Expression toAssignExpression(Expression left) => new Assignment(left, this); | 623 Expression toAssignExpression(Expression left) => new Assignment(left, this); |
620 Statement toVariableDeclaration(Identifier name) => | 624 Statement toVariableDeclaration(Identifier name) => |
621 new VariableDeclarationList('let', | 625 new VariableDeclarationList('let', |
622 [new VariableInitialization(name, this)]).toStatement(); | 626 [new VariableInitialization(name, this)]).toStatement(); |
623 } | 627 } |
624 | 628 |
625 class LiteralExpression extends Expression { | 629 class LiteralExpression extends Expression { |
626 final String template; | 630 final String template; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 Statement toStatement() { | 788 Statement toStatement() { |
785 if (!isCommaOperator) return super.toStatement(); | 789 if (!isCommaOperator) return super.toStatement(); |
786 return new Block([left.toStatement(), right.toStatement()]); | 790 return new Block([left.toStatement(), right.toStatement()]); |
787 } | 791 } |
788 | 792 |
789 Statement toReturn() { | 793 Statement toReturn() { |
790 if (!isCommaOperator) return super.toReturn(); | 794 if (!isCommaOperator) return super.toReturn(); |
791 return new Block([left.toStatement(), right.toReturn()]); | 795 return new Block([left.toStatement(), right.toReturn()]); |
792 } | 796 } |
793 | 797 |
| 798 Statement toYieldStatement({bool star: false}) { |
| 799 if (!isCommaOperator) return super.toYieldStatement(star: star); |
| 800 return new Block([left.toStatement(), right.toYieldStatement(star: star)]); |
| 801 } |
| 802 |
794 List<Expression> commaToExpressionList() { | 803 List<Expression> commaToExpressionList() { |
795 if (!isCommaOperator) throw new StateError('not a comma expression'); | 804 if (!isCommaOperator) throw new StateError('not a comma expression'); |
796 var exprs = []; | 805 var exprs = []; |
797 _flattenComma(exprs, left); | 806 _flattenComma(exprs, left); |
798 _flattenComma(exprs, right); | 807 _flattenComma(exprs, right); |
799 return exprs; | 808 return exprs; |
800 } | 809 } |
801 | 810 |
802 static void _flattenComma(List<Expression> exprs, Expression node) { | 811 static void _flattenComma(List<Expression> exprs, Expression node) { |
803 if (node is Binary && node.isCommaOperator) { | 812 if (node is Binary && node.isCommaOperator) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 } | 972 } |
964 | 973 |
965 abstract class FunctionExpression extends Expression { | 974 abstract class FunctionExpression extends Expression { |
966 List<Parameter> get params; | 975 List<Parameter> get params; |
967 get body; // Expression or block | 976 get body; // Expression or block |
968 } | 977 } |
969 | 978 |
970 class Fun extends FunctionExpression { | 979 class Fun extends FunctionExpression { |
971 final List<Parameter> params; | 980 final List<Parameter> params; |
972 final Block body; | 981 final Block body; |
| 982 /** Whether this is a JS generator (`function*`) that may contain `yield`. */ |
| 983 final bool isGenerator; |
| 984 |
973 final AsyncModifier asyncModifier; | 985 final AsyncModifier asyncModifier; |
974 | 986 |
975 Fun(this.params, this.body, {this.asyncModifier: const AsyncModifier.sync()}); | 987 Fun(this.params, this.body, {this.isGenerator: false, |
| 988 this.asyncModifier: const AsyncModifier.sync()}); |
976 | 989 |
977 accept(NodeVisitor visitor) => visitor.visitFun(this); | 990 accept(NodeVisitor visitor) => visitor.visitFun(this); |
978 | 991 |
979 void visitChildren(NodeVisitor visitor) { | 992 void visitChildren(NodeVisitor visitor) { |
980 for (Parameter param in params) param.accept(visitor); | 993 for (Parameter param in params) param.accept(visitor); |
981 body.accept(visitor); | 994 body.accept(visitor); |
982 } | 995 } |
983 | 996 |
984 Fun _clone() => new Fun(params, body, asyncModifier: asyncModifier); | 997 Fun _clone() => new Fun(params, body, |
| 998 isGenerator: isGenerator, asyncModifier: asyncModifier); |
985 | 999 |
986 int get precedenceLevel => CALL; | 1000 int get precedenceLevel => ASSIGNMENT; |
987 } | 1001 } |
988 | 1002 |
989 class ArrowFun extends FunctionExpression { | 1003 class ArrowFun extends FunctionExpression { |
990 final List<Parameter> params; | 1004 final List<Parameter> params; |
991 final body; // Expression or Block | 1005 final body; // Expression or Block |
992 | 1006 |
993 ArrowFun(this.params, this.body); | 1007 ArrowFun(this.params, this.body); |
994 | 1008 |
995 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); | 1009 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); |
996 | 1010 |
997 void visitChildren(NodeVisitor visitor) { | 1011 void visitChildren(NodeVisitor visitor) { |
998 for (Parameter param in params) param.accept(visitor); | 1012 for (Parameter param in params) param.accept(visitor); |
999 body.accept(visitor); | 1013 body.accept(visitor); |
1000 } | 1014 } |
1001 | 1015 |
1002 ArrowFun _clone() => new ArrowFun(params, body); | 1016 ArrowFun _clone() => new ArrowFun(params, body); |
1003 | 1017 |
1004 /// Ensure parens always get generated if necessary. | 1018 /// Ensure parens always get generated if necessary. |
1005 // TODO(jmesserly): I'm not sure the printer is handling this correctly for | 1019 // TODO(jmesserly): I'm not sure the printer is handling this correctly for |
1006 // function() { ... } either. | 1020 // function() { ... } either. |
1007 int get precedenceLevel => ASSIGNMENT; | 1021 int get precedenceLevel => ASSIGNMENT; |
1008 } | 1022 } |
1009 | 1023 |
| 1024 /** |
| 1025 * The Dart sync, sync*, async, and async* modifier. |
| 1026 * See [DartYield]. |
| 1027 * |
| 1028 * This is not used for JS functions. |
| 1029 */ |
1010 class AsyncModifier { | 1030 class AsyncModifier { |
1011 final bool isAsync; | 1031 final bool isAsync; |
1012 final bool isYielding; | 1032 final bool isYielding; |
1013 final String description; | 1033 final String description; |
1014 | 1034 |
1015 const AsyncModifier.sync() | 1035 const AsyncModifier.sync() |
1016 : isAsync = false, | 1036 : isAsync = false, |
1017 isYielding = false, | 1037 isYielding = false, |
1018 description = "sync"; | 1038 description = "sync"; |
1019 const AsyncModifier.async() | 1039 const AsyncModifier.async() |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 void visitChildren(NodeVisitor visitor) { | 1250 void visitChildren(NodeVisitor visitor) { |
1231 tag.accept(visitor); | 1251 tag.accept(visitor); |
1232 template.accept(visitor); | 1252 template.accept(visitor); |
1233 } | 1253 } |
1234 | 1254 |
1235 TaggedTemplate _clone() => new TaggedTemplate(tag, template); | 1255 TaggedTemplate _clone() => new TaggedTemplate(tag, template); |
1236 | 1256 |
1237 int get precedenceLevel => CALL; | 1257 int get precedenceLevel => CALL; |
1238 } | 1258 } |
1239 | 1259 |
| 1260 // TODO(jmesserly): parser does not support this yet. |
| 1261 class Yield extends Expression { |
| 1262 final Expression value; |
| 1263 |
| 1264 /** |
| 1265 * Whether this yield expression is a `yield*` that iterates each item in |
| 1266 * [value]. |
| 1267 */ |
| 1268 final bool star; |
| 1269 |
| 1270 Yield(this.value, {this.star: false}); |
| 1271 |
| 1272 accept(NodeVisitor visitor) => visitor.visitYield(this); |
| 1273 |
| 1274 void visitChildren(NodeVisitor visitor) { |
| 1275 value.accept(visitor); |
| 1276 } |
| 1277 |
| 1278 Yield _clone() => new Yield(value); |
| 1279 |
| 1280 int get precedenceLevel => YIELD; |
| 1281 } |
| 1282 |
1240 class ClassDeclaration extends Statement { | 1283 class ClassDeclaration extends Statement { |
1241 final ClassExpression classExpr; | 1284 final ClassExpression classExpr; |
1242 | 1285 |
1243 ClassDeclaration(this.classExpr); | 1286 ClassDeclaration(this.classExpr); |
1244 | 1287 |
1245 accept(NodeVisitor visitor) => visitor.visitClassDeclaration(this); | 1288 accept(NodeVisitor visitor) => visitor.visitClassDeclaration(this); |
1246 visitChildren(NodeVisitor visitor) => classExpr.accept(visitor); | 1289 visitChildren(NodeVisitor visitor) => classExpr.accept(visitor); |
1247 ClassDeclaration _clone() => new ClassDeclaration(classExpr); | 1290 ClassDeclaration _clone() => new ClassDeclaration(classExpr); |
1248 } | 1291 } |
1249 | 1292 |
(...skipping 20 matching lines...) Expand all Loading... |
1270 class Method extends Property { | 1313 class Method extends Property { |
1271 final bool isGetter; | 1314 final bool isGetter; |
1272 final bool isSetter; | 1315 final bool isSetter; |
1273 final bool isStatic; | 1316 final bool isStatic; |
1274 | 1317 |
1275 Method(Expression name, Fun function, | 1318 Method(Expression name, Fun function, |
1276 {this.isGetter: false, this.isSetter: false, this.isStatic: false}) | 1319 {this.isGetter: false, this.isSetter: false, this.isStatic: false}) |
1277 : super(name, function) { | 1320 : super(name, function) { |
1278 assert(!isGetter || function.params.length == 0); | 1321 assert(!isGetter || function.params.length == 0); |
1279 assert(!isSetter || function.params.length == 1); | 1322 assert(!isSetter || function.params.length == 1); |
| 1323 assert(!isGetter && !isSetter || !function.isGenerator); |
1280 } | 1324 } |
1281 | 1325 |
1282 Fun get function => super.value; | 1326 Fun get function => super.value; |
1283 | 1327 |
1284 accept(NodeVisitor visitor) => visitor.visitMethod(this); | 1328 accept(NodeVisitor visitor) => visitor.visitMethod(this); |
1285 | 1329 |
1286 void visitChildren(NodeVisitor visitor) { | 1330 void visitChildren(NodeVisitor visitor) { |
1287 name.accept(visitor); | 1331 name.accept(visitor); |
1288 function.accept(visitor); | 1332 function.accept(visitor); |
1289 } | 1333 } |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 final Expression expression; | 1506 final Expression expression; |
1463 | 1507 |
1464 CommentExpression(this.comment, this.expression); | 1508 CommentExpression(this.comment, this.expression); |
1465 | 1509 |
1466 int get precedenceLevel => PRIMARY; | 1510 int get precedenceLevel => PRIMARY; |
1467 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); | 1511 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); |
1468 CommentExpression _clone() => new CommentExpression(comment, expression); | 1512 CommentExpression _clone() => new CommentExpression(comment, expression); |
1469 | 1513 |
1470 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); | 1514 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); |
1471 } | 1515 } |
OLD | NEW |