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 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 parameter.accept(visitor); | 936 parameter.accept(visitor); |
937 } | 937 } |
938 int get precedenceLevel => PRIMARY; | 938 int get precedenceLevel => PRIMARY; |
939 } | 939 } |
940 | 940 |
941 class This extends Expression { | 941 class This extends Expression { |
942 accept(NodeVisitor visitor) => visitor.visitThis(this); | 942 accept(NodeVisitor visitor) => visitor.visitThis(this); |
943 This _clone() => new This(); | 943 This _clone() => new This(); |
944 int get precedenceLevel => PRIMARY; | 944 int get precedenceLevel => PRIMARY; |
945 void visitChildren(NodeVisitor visitor) {} | 945 void visitChildren(NodeVisitor visitor) {} |
| 946 |
| 947 static bool foundIn(Node node) { |
| 948 _thisFinder.found = false; |
| 949 node.accept(_thisFinder); |
| 950 return _thisFinder.found; |
| 951 } |
946 } | 952 } |
947 | 953 |
| 954 final _thisFinder = new _ThisFinder(); |
| 955 class _ThisFinder extends BaseVisitor { |
| 956 bool found = false; |
| 957 visitThis(This node) { |
| 958 found = true; |
| 959 } |
| 960 visitNode(Node node) { |
| 961 if (!found) super.visitNode(node); |
| 962 } |
| 963 } |
| 964 |
| 965 |
948 // `super` is more restricted in the ES6 spec, but for simplicity we accept | 966 // `super` is more restricted in the ES6 spec, but for simplicity we accept |
949 // it anywhere that `this` is accepted. | 967 // it anywhere that `this` is accepted. |
950 class Super extends Expression { | 968 class Super extends Expression { |
951 accept(NodeVisitor visitor) => visitor.visitSuper(this); | 969 accept(NodeVisitor visitor) => visitor.visitSuper(this); |
952 Super _clone() => new Super(); | 970 Super _clone() => new Super(); |
953 int get precedenceLevel => PRIMARY; | 971 int get precedenceLevel => PRIMARY; |
954 void visitChildren(NodeVisitor visitor) {} | 972 void visitChildren(NodeVisitor visitor) {} |
955 } | 973 } |
956 | 974 |
957 class NamedFunction extends Expression { | 975 class NamedFunction extends Expression { |
958 final Identifier name; | 976 final Identifier name; |
959 final Fun function; | 977 final Fun function; |
960 | 978 |
961 NamedFunction(this.name, this.function); | 979 NamedFunction(this.name, this.function); |
962 | 980 |
963 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); | 981 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); |
964 | 982 |
965 void visitChildren(NodeVisitor visitor) { | 983 void visitChildren(NodeVisitor visitor) { |
966 name.accept(visitor); | 984 name.accept(visitor); |
967 function.accept(visitor); | 985 function.accept(visitor); |
968 } | 986 } |
969 NamedFunction _clone() => new NamedFunction(name, function); | 987 NamedFunction _clone() => new NamedFunction(name, function); |
970 | 988 |
971 int get precedenceLevel => CALL; | 989 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
972 } | 990 } |
973 | 991 |
974 abstract class FunctionExpression extends Expression { | 992 abstract class FunctionExpression extends Expression { |
975 List<Parameter> get params; | 993 List<Parameter> get params; |
976 get body; // Expression or block | 994 get body; // Expression or block |
977 } | 995 } |
978 | 996 |
979 class Fun extends FunctionExpression { | 997 class Fun extends FunctionExpression { |
980 final List<Parameter> params; | 998 final List<Parameter> params; |
981 final Block body; | 999 final Block body; |
982 /** Whether this is a JS generator (`function*`) that may contain `yield`. */ | 1000 /** Whether this is a JS generator (`function*`) that may contain `yield`. */ |
983 final bool isGenerator; | 1001 final bool isGenerator; |
984 | 1002 |
985 final AsyncModifier asyncModifier; | 1003 final AsyncModifier asyncModifier; |
986 | 1004 |
987 Fun(this.params, this.body, {this.isGenerator: false, | 1005 Fun(this.params, this.body, {this.isGenerator: false, |
988 this.asyncModifier: const AsyncModifier.sync()}); | 1006 this.asyncModifier: const AsyncModifier.sync()}); |
989 | 1007 |
990 accept(NodeVisitor visitor) => visitor.visitFun(this); | 1008 accept(NodeVisitor visitor) => visitor.visitFun(this); |
991 | 1009 |
992 void visitChildren(NodeVisitor visitor) { | 1010 void visitChildren(NodeVisitor visitor) { |
993 for (Parameter param in params) param.accept(visitor); | 1011 for (Parameter param in params) param.accept(visitor); |
994 body.accept(visitor); | 1012 body.accept(visitor); |
995 } | 1013 } |
996 | 1014 |
997 Fun _clone() => new Fun(params, body, | 1015 Fun _clone() => new Fun(params, body, |
998 isGenerator: isGenerator, asyncModifier: asyncModifier); | 1016 isGenerator: isGenerator, asyncModifier: asyncModifier); |
999 | 1017 |
1000 int get precedenceLevel => ASSIGNMENT; | 1018 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
1001 } | 1019 } |
1002 | 1020 |
1003 class ArrowFun extends FunctionExpression { | 1021 class ArrowFun extends FunctionExpression { |
1004 final List<Parameter> params; | 1022 final List<Parameter> params; |
1005 final body; // Expression or Block | 1023 final body; // Expression or Block |
1006 | 1024 |
| 1025 bool _closesOverThis; // lazy initialized |
| 1026 |
1007 ArrowFun(this.params, this.body); | 1027 ArrowFun(this.params, this.body); |
1008 | 1028 |
1009 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); | 1029 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); |
1010 | 1030 |
1011 void visitChildren(NodeVisitor visitor) { | 1031 void visitChildren(NodeVisitor visitor) { |
1012 for (Parameter param in params) param.accept(visitor); | 1032 for (Parameter param in params) param.accept(visitor); |
1013 body.accept(visitor); | 1033 body.accept(visitor); |
1014 } | 1034 } |
| 1035 /// True if this function actually closes of `this`. We use this in some |
| 1036 /// situations to generate different code. |
| 1037 bool get closesOverThis { |
| 1038 if (_closesOverThis == null) _closesOverThis = This.foundIn(this); |
| 1039 return _closesOverThis; |
| 1040 } |
| 1041 |
| 1042 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
1015 | 1043 |
1016 ArrowFun _clone() => new ArrowFun(params, body); | 1044 ArrowFun _clone() => new ArrowFun(params, body); |
1017 | |
1018 /// Ensure parens always get generated if necessary. | |
1019 // TODO(jmesserly): I'm not sure the printer is handling this correctly for | |
1020 // function() { ... } either. | |
1021 int get precedenceLevel => ASSIGNMENT; | |
1022 } | 1045 } |
1023 | 1046 |
1024 /** | 1047 /** |
1025 * The Dart sync, sync*, async, and async* modifier. | 1048 * The Dart sync, sync*, async, and async* modifier. |
1026 * See [DartYield]. | 1049 * See [DartYield]. |
1027 * | 1050 * |
1028 * This is not used for JS functions. | 1051 * This is not used for JS functions. |
1029 */ | 1052 */ |
1030 class AsyncModifier { | 1053 class AsyncModifier { |
1031 final bool isAsync; | 1054 final bool isAsync; |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 accept(NodeVisitor visitor) => visitor.visitClassExpression(this); | 1323 accept(NodeVisitor visitor) => visitor.visitClassExpression(this); |
1301 | 1324 |
1302 void visitChildren(NodeVisitor visitor) { | 1325 void visitChildren(NodeVisitor visitor) { |
1303 name.accept(visitor); | 1326 name.accept(visitor); |
1304 if (heritage != null) heritage.accept(visitor); | 1327 if (heritage != null) heritage.accept(visitor); |
1305 for (Method element in methods) element.accept(visitor); | 1328 for (Method element in methods) element.accept(visitor); |
1306 } | 1329 } |
1307 | 1330 |
1308 ClassExpression _clone() => new ClassExpression(name, heritage, methods); | 1331 ClassExpression _clone() => new ClassExpression(name, heritage, methods); |
1309 | 1332 |
1310 int get precedenceLevel => PRIMARY; | 1333 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
1311 } | 1334 } |
1312 | 1335 |
1313 class Method extends Property { | 1336 class Method extends Property { |
1314 final bool isGetter; | 1337 final bool isGetter; |
1315 final bool isSetter; | 1338 final bool isSetter; |
1316 final bool isStatic; | 1339 final bool isStatic; |
1317 | 1340 |
1318 Method(Expression name, Fun function, | 1341 Method(Expression name, Fun function, |
1319 {this.isGetter: false, this.isSetter: false, this.isStatic: false}) | 1342 {this.isGetter: false, this.isSetter: false, this.isStatic: false}) |
1320 : super(name, function) { | 1343 : super(name, function) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 final Expression expression; | 1529 final Expression expression; |
1507 | 1530 |
1508 CommentExpression(this.comment, this.expression); | 1531 CommentExpression(this.comment, this.expression); |
1509 | 1532 |
1510 int get precedenceLevel => PRIMARY; | 1533 int get precedenceLevel => PRIMARY; |
1511 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); | 1534 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); |
1512 CommentExpression _clone() => new CommentExpression(comment, expression); | 1535 CommentExpression _clone() => new CommentExpression(comment, expression); |
1513 | 1536 |
1514 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); | 1537 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); |
1515 } | 1538 } |
OLD | NEW |