Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: frog/await/checker.dart

Issue 10548047: Remove frog from the repository. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move test and update apidoc.gyp. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/await/awaitc.dart ('k') | frog/await/nodeset.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
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.
4
5 /**
6 * Traverses the entire code of a function to find whether it contains awaits,
7 * ensuring they occur only in valid locations. This visitor will *not* recurse
8 * inside nested function declarations.
9 */
10 class AwaitChecker implements TreeVisitor {
11
12 /** Functions found within the body of the entry function. */
13 List<FunctionDefinition> nestedFunctions;
14
15 /** Helper bool to ensure that only the top-level function is analyzed. */
16 bool _entryFunction = true;
17
18 /** AST nodes that contain await expressions. */
19 NodeSet haveAwait;
20
21 // TODO: track haveExit (return/throw) and haveBreak (break/continue) to
22 // property transform nodes that don't contain await, but may be affected
23 AwaitChecker() : nestedFunctions = [], haveAwait = new NodeSet();
24
25 visitVariableDefinition(VariableDefinition node) {
26 bool awaitSeen = _visitList(node.values);
27 if (awaitSeen) haveAwait.add(node);
28 return awaitSeen;
29 }
30
31 visitFunctionDefinition(FunctionDefinition node) {
32 if (_entryFunction) {
33 _entryFunction = false;
34 if (node.initializers != null) {
35 for (Expression e in node.initializers) {
36 if (e.visit(this)) {
37 world.error('Await expressions are not allowed in initializers.',
38 e.span);
39 }
40 }
41 }
42 if (_visit(node.body)) {
43 haveAwait.add(node);
44 // TODO(sigmund) check that return type is Dynamic or a future.
45 return true;
46 }
47 return false;
48 } else {
49 // Do not analyze nested functions now, use a separate checker for that.
50 nestedFunctions.add(node);
51 return false;
52 }
53 }
54
55 _notSupportedStmt(name, node) {
56 world.error("Await is not supported in '$name' statements yet.", node.span);
57 }
58
59 _notSupported(name, node) {
60 world.error(
61 "Await is not supported in $name yet, try pulling into a tmp var.",
62 node.span);
63 }
64
65 visitReturnStatement(ReturnStatement node) {
66 bool awaitSeen = _visit(node.value);
67 if (awaitSeen) haveAwait.add(node);
68 return awaitSeen;
69 }
70
71 visitThrowStatement(ThrowStatement node) {
72 bool awaitSeen = _visit(node.value);
73 if (awaitSeen) haveAwait.add(node);
74 return awaitSeen;
75 }
76
77 visitAssertStatement(AssertStatement node) {
78 bool awaitSeen = node.test.visit(this);
79 if (awaitSeen) {
80 haveAwait.add(node);
81 _notSupportedStmt("assert", node);
82 }
83 return awaitSeen;
84 }
85
86 visitBreakStatement(BreakStatement node) {
87 return false;
88 }
89
90 visitContinueStatement(ContinueStatement node) {
91 return false;
92 }
93
94 visitIfStatement(IfStatement node) {
95 bool awaitSeen = node.test.visit(this);
96 if (node.trueBranch.visit(this)) {
97 awaitSeen = true;
98 }
99 if (_visit(node.falseBranch)) {
100 awaitSeen = true;
101 }
102 if (awaitSeen) haveAwait.add(node);
103 return awaitSeen;
104 }
105
106 visitWhileStatement(WhileStatement node) {
107 bool awaitSeen = node.test.visit(this);
108 if (_visit(node.body)) awaitSeen = true;
109 if (awaitSeen) haveAwait.add(node);
110 return awaitSeen;
111 }
112
113 visitDoStatement(DoStatement node) {
114 bool awaitSeen = node.test.visit(this);
115 if (_visit(node.body)) awaitSeen = true;
116 if (awaitSeen) {
117 haveAwait.add(node);
118 _notSupportedStmt("do while", node);
119 }
120 return awaitSeen;
121 }
122
123 visitForStatement(ForStatement node) {
124 bool awaitSeen = node.test.visit(this);
125 if (_visit(node.body)) awaitSeen = true;
126 if (_visit(node.init)) awaitSeen = true;
127 if (_visitList(node.step)) awaitSeen = true;
128 if (awaitSeen) {
129 haveAwait.add(node);
130 _notSupportedStmt("for", node);
131 }
132 return awaitSeen;
133 }
134
135 visitForInStatement(ForInStatement node) {
136 bool awaitSeen = node.list.visit(this);
137 if (_visit(node.body)) awaitSeen = true;
138 if (awaitSeen) {
139 haveAwait.add(node);
140 _notSupportedStmt("for-in", node);
141 }
142 return awaitSeen;
143 }
144
145 visitTryStatement(TryStatement node) {
146 bool awaitSeen = (_visit(node.body));
147 if (_visitList(node.catches)) awaitSeen = true;
148 if (_visit(node.finallyBlock)) {
149 awaitSeen = true;
150 }
151 if (awaitSeen) haveAwait.add(node);
152 return awaitSeen;
153 }
154
155 visitSwitchStatement(SwitchStatement node) {
156 bool awaitSeen = node.test.visit(this);
157 if (_visitList(node.cases)) awaitSeen = true;
158 if (awaitSeen) {
159 haveAwait.add(node);
160 _notSupportedStmt("switch", node);
161 }
162 return awaitSeen;
163 }
164
165 visitBlockStatement(BlockStatement node) {
166 bool awaitSeen = _visitList(node.body);
167 if (awaitSeen) haveAwait.add(node);
168 return awaitSeen;
169 }
170
171 visitLabeledStatement(LabeledStatement node) {
172 bool awaitSeen = node.body.visit(this);
173 if (awaitSeen) haveAwait.add(node);
174 return awaitSeen;
175 }
176
177 visitExpressionStatement(ExpressionStatement node) {
178 bool awaitSeen = node.body.visit(this);
179 if (awaitSeen) haveAwait.add(node);
180 return awaitSeen;
181 }
182
183 visitEmptyStatement(EmptyStatement node) {
184 return false;
185 }
186
187 visitLambdaExpression(LambdaExpression node) {
188 _entryFunction = false;
189 return node.func.visit(this);
190 }
191
192 visitCallExpression(CallExpression node) {
193 bool awaitSeen = node.target.visit(this);
194 if (_visitList(node.arguments)) awaitSeen = true;
195 if (awaitSeen) haveAwait.add(node);
196 return awaitSeen;
197 }
198
199 visitIndexExpression(IndexExpression node) {
200 bool awaitSeen = node.target.visit(this);
201 if (node.index.visit(this)) awaitSeen = true;
202 if (awaitSeen) haveAwait.add(node);
203 return awaitSeen;
204 }
205
206 visitBinaryExpression(BinaryExpression node) {
207 bool awaitSeen = node.x.visit(this);
208 if (node.y.visit(this)) awaitSeen = true;
209 if (awaitSeen) haveAwait.add(node);
210 return awaitSeen;
211 }
212
213 visitUnaryExpression(UnaryExpression node) {
214 // TODO(sigmund): issue errors for ++/-- cases where we expect an l-value.
215 bool awaitSeen = node.self.visit(this);
216 if (awaitSeen) {
217 haveAwait.add(node);
218 _notSupported("unary expressions", node);
219 }
220 return awaitSeen;
221 }
222
223 visitPostfixExpression(PostfixExpression node) {
224 // TODO(sigmund): issue errors for ++/-- cases where we expect an l-value.
225 bool awaitSeen = node.body.visit(this);
226 if (awaitSeen) {
227 haveAwait.add(node);
228 _notSupported("postfix expressions", node);
229 }
230 return awaitSeen;
231 }
232
233 visitNewExpression(NewExpression node) {
234 bool awaitSeen = _visitList(node.arguments);
235 if (awaitSeen) {
236 haveAwait.add(node);
237 _notSupported("new expressions", node);
238 }
239 return awaitSeen;
240 }
241
242 visitListExpression(ListExpression node) {
243 bool awaitSeen = _visitList(node.values);
244 if (awaitSeen) {
245 haveAwait.add(node);
246 _notSupported("list literals", node);
247 }
248 return awaitSeen;
249 }
250
251 visitMapExpression(MapExpression node) {
252 bool awaitSeen = _visitList(node.items);
253 if (awaitSeen) {
254 haveAwait.add(node);
255 _notSupported("map literals", node);
256 }
257 return awaitSeen;
258 }
259
260 visitConditionalExpression(ConditionalExpression node) {
261 bool awaitSeen = node.test.visit(this);
262 if (node.trueBranch.visit(this)) awaitSeen = true;
263 if (node.falseBranch.visit(this)) awaitSeen = true;
264 if (awaitSeen) {
265 haveAwait.add(node);
266 _notSupported("ternary expressions", node);
267 }
268 return awaitSeen;
269 }
270
271 visitIsExpression(IsExpression node) {
272 bool awaitSeen = node.x.visit(this);
273 if (awaitSeen) {
274 haveAwait.add(node);
275 _notSupported("'is' checks", node);
276 }
277 return awaitSeen;
278 }
279
280 visitParenExpression(ParenExpression node) {
281 bool awaitSeen = node.body.visit(this);
282 if (awaitSeen) haveAwait.add(node);
283 return awaitSeen;
284 }
285
286 visitAwaitExpression(AwaitExpression node) {
287 haveAwait.add(node);
288 return true;
289 }
290
291 visitDotExpression(DotExpression node) {
292 bool awaitSeen = node.self.visit(this);
293 if (awaitSeen) haveAwait.add(node);
294 return awaitSeen;
295 }
296
297 visitVarExpression(VarExpression node) {
298 return false;
299 }
300
301 visitThisExpression(ThisExpression node) {
302 return false;
303 }
304
305 visitSuperExpression(SuperExpression node) {
306 return false;
307 }
308
309 visitStringInterpExpression(StringInterpExpression node) {
310 return false;
311 }
312
313 visitLiteralExpression(LiteralExpression node) {
314 return false;
315 }
316
317 visitArgumentNode(ArgumentNode node) {
318 bool awaitSeen = node.value.visit(this);
319 if (awaitSeen) haveAwait.add(node);
320 return awaitSeen;
321 }
322
323 visitCatchNode(CatchNode node) {
324 bool awaitSeen = false;
325 if (_visit(node.body)) awaitSeen = true;
326 if (awaitSeen) {
327 haveAwait.add(node);
328 _notSupported("catch blocks", node);
329 }
330 return awaitSeen;
331 }
332
333 visitCaseNode(CaseNode node) {
334 bool awaitSeen = false;
335 for (Expression e in node.cases) {
336 if (_visit(e)) {
337 world.error(
338 'Await is not allowed in case expressions of switch statements.',
339 e.span);
340 awaitSeen = true;
341 }
342 }
343 if (_visitList(node.statements)) awaitSeen = true;
344 if (awaitSeen) {
345 haveAwait.add(node);
346 _notSupported("case blocks", node);
347 }
348 return awaitSeen;
349 }
350
351 /**
352 * Recurses on every element in the list, returns whether any of them has an
353 * await.
354 */
355 _visitList(List nodes) {
356 bool awaitSeen = false;
357 if (nodes != null) {
358 for (final n in nodes) {
359 if (_visit(n)) awaitSeen = true;
360 }
361 }
362 return awaitSeen;
363 }
364
365 _visit(node) {
366 if (node == null) return false;
367 return node.visit(this);
368 }
369 }
OLDNEW
« no previous file with comments | « frog/await/awaitc.dart ('k') | frog/await/nodeset.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698