OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dev_compiler.src.codegen.js_metalet; | 5 library dev_compiler.src.codegen.js_metalet; |
6 | 6 |
7 // TODO(jmesserly): import from its own package | 7 // TODO(jmesserly): import from its own package |
8 import 'package:dev_compiler/src/js/js_ast.dart'; | 8 import 'package:dev_compiler/src/js/js_ast.dart'; |
9 import 'package:dev_compiler/src/js/precedence.dart'; | 9 import 'package:dev_compiler/src/js/precedence.dart'; |
10 | 10 |
11 import 'js_names.dart' show TemporaryId; | 11 import 'js_names.dart' show TemporaryId; |
12 | 12 |
13 /// A synthetic `let*` node, similar to that found in Scheme. | 13 /// A synthetic `let*` node, similar to that found in Scheme. |
14 /// | 14 /// |
15 /// For example, postfix increment can be desugared as: | 15 /// For example, postfix increment can be desugared as: |
16 /// | 16 /// |
17 /// // psuedocode mix of Scheme and JS: | 17 /// // psuedocode mix of Scheme and JS: |
18 /// (let* (x1=expr1, x2=expr2, t=x1[x2]) { x1[x2] = t + 1; t }) | 18 /// (let* (x1=expr1, x2=expr2, t=x1[x2]) { x1[x2] = t + 1; t }) |
19 /// | 19 /// |
20 /// [MetaLet] will simplify itself automatically when [toExpression], | 20 /// [MetaLet] will simplify itself automatically when [toExpression], |
21 /// [toStatement], or [toReturn] is called. | 21 /// [toStatement], [toReturn], or [toYieldStatement] is called. |
22 /// | 22 /// |
23 /// * variables used once will be inlined. | 23 /// * variables used once will be inlined. |
24 /// * if used in a statement context they can emit as blocks. | 24 /// * if used in a statement context they can emit as blocks. |
25 /// * if return value is not used it can be eliminated, see [statelessResult]. | 25 /// * if return value is not used it can be eliminated, see [statelessResult]. |
26 /// * if there are no variables, the codegen will be simplified. | 26 /// * if there are no variables, the codegen will be simplified. |
27 /// | 27 /// |
28 /// Because this deals with JS AST nodes, it is not aware of any Dart semantics | 28 /// Because this deals with JS AST nodes, it is not aware of any Dart semantics |
29 /// around statelessness (such as `final` variables). [variables] should not | 29 /// around statelessness (such as `final` variables). [variables] should not |
30 /// be created for these Dart expressions. | 30 /// be created for these Dart expressions. |
31 /// | 31 /// |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 return _finishStatement(statements); | 105 return _finishStatement(statements); |
106 } | 106 } |
107 | 107 |
108 Block toReturn() { | 108 Block toReturn() { |
109 var statements = body | 109 var statements = body |
110 .map((e) => e == body.last ? e.toReturn() : e.toStatement()) | 110 .map((e) => e == body.last ? e.toReturn() : e.toStatement()) |
111 .toList(); | 111 .toList(); |
112 return _finishStatement(statements); | 112 return _finishStatement(statements); |
113 } | 113 } |
114 | 114 |
| 115 Block toYieldStatement({bool star: false}) { |
| 116 var statements = body |
| 117 .map((e) => |
| 118 e == body.last ? e.toYieldStatement(star: star) : e.toStatement()) |
| 119 .toList(); |
| 120 return _finishStatement(statements); |
| 121 } |
| 122 |
115 accept(NodeVisitor visitor) => toExpression().accept(visitor); | 123 accept(NodeVisitor visitor) => toExpression().accept(visitor); |
116 | 124 |
117 void visitChildren(NodeVisitor visitor) { | 125 void visitChildren(NodeVisitor visitor) { |
118 toExpression().visitChildren(visitor); | 126 toExpression().visitChildren(visitor); |
119 } | 127 } |
120 | 128 |
121 /// This generates as either a comma expression or a call. | 129 /// This generates as either a comma expression or a call. |
122 int get precedenceLevel => variables.isEmpty ? EXPRESSION : CALL; | 130 int get precedenceLevel => variables.isEmpty ? EXPRESSION : CALL; |
123 | 131 |
124 Block _finishStatement(List<Statement> statements) { | 132 Block _finishStatement(List<Statement> statements) { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 bool found = false; | 241 bool found = false; |
234 _IdentFinder(this.name); | 242 _IdentFinder(this.name); |
235 | 243 |
236 visitIdentifier(Identifier node) { | 244 visitIdentifier(Identifier node) { |
237 if (node.name == name) found = true; | 245 if (node.name == name) found = true; |
238 } | 246 } |
239 visitNode(Node node) { | 247 visitNode(Node node) { |
240 if (!found) super.visitNode(node); | 248 if (!found) super.visitNode(node); |
241 } | 249 } |
242 } | 250 } |
OLD | NEW |