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> implements TypeRefVisitor<T> { | 7 abstract class NodeVisitor<T> implements TypeRefVisitor<T> { |
8 T visitProgram(Program node); | 8 T visitProgram(Program node); |
9 | 9 |
10 T visitBlock(Block node); | 10 T visitBlock(Block node); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 return null; | 113 return null; |
114 } | 114 } |
115 | 115 |
116 T visitProgram(Program node) => visitNode(node); | 116 T visitProgram(Program node) => visitNode(node); |
117 | 117 |
118 T visitStatement(Statement node) => visitModuleItem(node); | 118 T visitStatement(Statement node) => visitModuleItem(node); |
119 T visitLoop(Loop node) => visitStatement(node); | 119 T visitLoop(Loop node) => visitStatement(node); |
120 T visitJump(Statement node) => visitStatement(node); | 120 T visitJump(Statement node) => visitStatement(node); |
121 | 121 |
122 T visitBlock(Block node) => visitStatement(node); | 122 T visitBlock(Block node) => visitStatement(node); |
123 T visitExpressionStatement(ExpressionStatement node) | 123 T visitExpressionStatement(ExpressionStatement node) => visitStatement(node); |
124 => visitStatement(node); | |
125 T visitEmptyStatement(EmptyStatement node) => visitStatement(node); | 124 T visitEmptyStatement(EmptyStatement node) => visitStatement(node); |
126 T visitIf(If node) => visitStatement(node); | 125 T visitIf(If node) => visitStatement(node); |
127 T visitFor(For node) => visitLoop(node); | 126 T visitFor(For node) => visitLoop(node); |
128 T visitForIn(ForIn node) => visitLoop(node); | 127 T visitForIn(ForIn node) => visitLoop(node); |
129 T visitForOf(ForOf node) => visitLoop(node); | 128 T visitForOf(ForOf node) => visitLoop(node); |
130 T visitWhile(While node) => visitLoop(node); | 129 T visitWhile(While node) => visitLoop(node); |
131 T visitDo(Do node) => visitLoop(node); | 130 T visitDo(Do node) => visitLoop(node); |
132 T visitContinue(Continue node) => visitJump(node); | 131 T visitContinue(Continue node) => visitJump(node); |
133 T visitBreak(Break node) => visitJump(node); | 132 T visitBreak(Break node) => visitJump(node); |
134 T visitReturn(Return node) => visitJump(node); | 133 T visitReturn(Return node) => visitJump(node); |
135 T visitThrow(Throw node) => visitJump(node); | 134 T visitThrow(Throw node) => visitJump(node); |
136 T visitTry(Try node) => visitStatement(node); | 135 T visitTry(Try node) => visitStatement(node); |
137 T visitSwitch(Switch node) => visitStatement(node); | 136 T visitSwitch(Switch node) => visitStatement(node); |
138 T visitFunctionDeclaration(FunctionDeclaration node) | 137 T visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node); |
139 => visitStatement(node); | |
140 T visitLabeledStatement(LabeledStatement node) => visitStatement(node); | 138 T visitLabeledStatement(LabeledStatement node) => visitStatement(node); |
141 T visitLiteralStatement(LiteralStatement node) => visitStatement(node); | 139 T visitLiteralStatement(LiteralStatement node) => visitStatement(node); |
142 | 140 |
143 T visitCatch(Catch node) => visitNode(node); | 141 T visitCatch(Catch node) => visitNode(node); |
144 T visitCase(Case node) => visitNode(node); | 142 T visitCase(Case node) => visitNode(node); |
145 T visitDefault(Default node) => visitNode(node); | 143 T visitDefault(Default node) => visitNode(node); |
146 | 144 |
147 T visitExpression(Expression node) => visitNode(node); | 145 T visitExpression(Expression node) => visitNode(node); |
148 | 146 |
149 T visitLiteralExpression(LiteralExpression node) => visitExpression(node); | 147 T visitLiteralExpression(LiteralExpression node) => visitExpression(node); |
150 T visitVariableDeclarationList(VariableDeclarationList node) | 148 T visitVariableDeclarationList(VariableDeclarationList node) => |
151 => visitExpression(node); | 149 visitExpression(node); |
152 T visitAssignment(Assignment node) => visitExpression(node); | 150 T visitAssignment(Assignment node) => visitExpression(node); |
153 T visitVariableInitialization(VariableInitialization node) { | 151 T visitVariableInitialization(VariableInitialization node) { |
154 if (node.value != null) { | 152 if (node.value != null) { |
155 return visitAssignment(node); | 153 return visitAssignment(node); |
156 } else { | 154 } else { |
157 return visitExpression(node); | 155 return visitExpression(node); |
158 } | 156 } |
159 } | 157 } |
| 158 |
160 T visitConditional(Conditional node) => visitExpression(node); | 159 T visitConditional(Conditional node) => visitExpression(node); |
161 T visitNew(New node) => visitExpression(node); | 160 T visitNew(New node) => visitExpression(node); |
162 T visitCall(Call node) => visitExpression(node); | 161 T visitCall(Call node) => visitExpression(node); |
163 T visitBinary(Binary node) => visitExpression(node); | 162 T visitBinary(Binary node) => visitExpression(node); |
164 T visitPrefix(Prefix node) => visitExpression(node); | 163 T visitPrefix(Prefix node) => visitExpression(node); |
165 T visitPostfix(Postfix node) => visitExpression(node); | 164 T visitPostfix(Postfix node) => visitExpression(node); |
166 T visitSpread(Spread node) => visitPrefix(node); | 165 T visitSpread(Spread node) => visitPrefix(node); |
167 T visitYield(Yield node) => visitExpression(node); | 166 T visitYield(Yield node) => visitExpression(node); |
168 T visitAccess(PropertyAccess node) => visitExpression(node); | 167 T visitAccess(PropertyAccess node) => visitExpression(node); |
169 | 168 |
(...skipping 29 matching lines...) Expand all Loading... |
199 | 198 |
200 T visitModuleItem(ModuleItem node) => visitNode(node); | 199 T visitModuleItem(ModuleItem node) => visitNode(node); |
201 T visitImportDeclaration(ImportDeclaration node) => visitModuleItem(node); | 200 T visitImportDeclaration(ImportDeclaration node) => visitModuleItem(node); |
202 T visitExportDeclaration(ExportDeclaration node) => visitModuleItem(node); | 201 T visitExportDeclaration(ExportDeclaration node) => visitModuleItem(node); |
203 T visitExportClause(ExportClause node) => visitNode(node); | 202 T visitExportClause(ExportClause node) => visitNode(node); |
204 T visitNameSpecifier(NameSpecifier node) => visitNode(node); | 203 T visitNameSpecifier(NameSpecifier node) => visitNode(node); |
205 T visitModule(Module node) => visitNode(node); | 204 T visitModule(Module node) => visitNode(node); |
206 | 205 |
207 T visitInterpolatedNode(InterpolatedNode node) => visitNode(node); | 206 T visitInterpolatedNode(InterpolatedNode node) => visitNode(node); |
208 | 207 |
209 T visitInterpolatedExpression(InterpolatedExpression node) | 208 T visitInterpolatedExpression(InterpolatedExpression node) => |
210 => visitInterpolatedNode(node); | 209 visitInterpolatedNode(node); |
211 T visitInterpolatedLiteral(InterpolatedLiteral node) | 210 T visitInterpolatedLiteral(InterpolatedLiteral node) => |
212 => visitInterpolatedNode(node); | 211 visitInterpolatedNode(node); |
213 T visitInterpolatedParameter(InterpolatedParameter node) | 212 T visitInterpolatedParameter(InterpolatedParameter node) => |
214 => visitInterpolatedNode(node); | 213 visitInterpolatedNode(node); |
215 T visitInterpolatedSelector(InterpolatedSelector node) | 214 T visitInterpolatedSelector(InterpolatedSelector node) => |
216 => visitInterpolatedNode(node); | 215 visitInterpolatedNode(node); |
217 T visitInterpolatedStatement(InterpolatedStatement node) | 216 T visitInterpolatedStatement(InterpolatedStatement node) => |
218 => visitInterpolatedNode(node); | 217 visitInterpolatedNode(node); |
219 T visitInterpolatedMethod(InterpolatedMethod node) | 218 T visitInterpolatedMethod(InterpolatedMethod node) => |
220 => visitInterpolatedNode(node); | 219 visitInterpolatedNode(node); |
221 T visitInterpolatedIdentifier(InterpolatedIdentifier node) | 220 T visitInterpolatedIdentifier(InterpolatedIdentifier node) => |
222 => visitInterpolatedNode(node); | 221 visitInterpolatedNode(node); |
223 | 222 |
224 // Ignore comments by default. | 223 // Ignore comments by default. |
225 T visitComment(Comment node) => null; | 224 T visitComment(Comment node) => null; |
226 T visitCommentExpression(CommentExpression node) => null; | 225 T visitCommentExpression(CommentExpression node) => null; |
227 | 226 |
228 T visitAwait(Await node) => visitExpression(node); | 227 T visitAwait(Await node) => visitExpression(node); |
229 T visitDartYield(DartYield node) => visitStatement(node); | 228 T visitDartYield(DartYield node) => visitStatement(node); |
230 | 229 |
231 T visitBindingPattern(BindingPattern node) => visitNode(node); | 230 T visitBindingPattern(BindingPattern node) => visitNode(node); |
232 T visitArrayBindingPattern(ArrayBindingPattern node) | 231 T visitArrayBindingPattern(ArrayBindingPattern node) => |
233 => visitBindingPattern(node); | 232 visitBindingPattern(node); |
234 T visitObjectBindingPattern(ObjectBindingPattern node) | 233 T visitObjectBindingPattern(ObjectBindingPattern node) => |
235 => visitBindingPattern(node); | 234 visitBindingPattern(node); |
236 T visitDestructuredVariable(DestructuredVariable node) => visitNode(node); | 235 T visitDestructuredVariable(DestructuredVariable node) => visitNode(node); |
237 T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node); | 236 T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node); |
238 | 237 |
239 T visitTypeRef(TypeRef node) => visitNode(node); | 238 T visitTypeRef(TypeRef node) => visitNode(node); |
240 T visitQualifiedTypeRef(QualifiedTypeRef node) => visitTypeRef(node); | 239 T visitQualifiedTypeRef(QualifiedTypeRef node) => visitTypeRef(node); |
241 T visitGenericTypeRef(GenericTypeRef node) => visitTypeRef(node); | 240 T visitGenericTypeRef(GenericTypeRef node) => visitTypeRef(node); |
242 T visitOptionalTypeRef(OptionalTypeRef node) => visitTypeRef(node); | 241 T visitOptionalTypeRef(OptionalTypeRef node) => visitTypeRef(node); |
243 T visitRecordTypeRef(RecordTypeRef node) => visitTypeRef(node); | 242 T visitRecordTypeRef(RecordTypeRef node) => visitTypeRef(node); |
244 T visitUnionTypeRef(UnionTypeRef node) => visitTypeRef(node); | 243 T visitUnionTypeRef(UnionTypeRef node) => visitTypeRef(node); |
245 T visitFunctionTypeRef(FunctionTypeRef node) => visitTypeRef(node); | 244 T visitFunctionTypeRef(FunctionTypeRef node) => visitTypeRef(node); |
246 T visitAnyTypeRef(AnyTypeRef node) => visitTypeRef(node); | 245 T visitAnyTypeRef(AnyTypeRef node) => visitTypeRef(node); |
247 T visitUnknownTypeRef(UnknownTypeRef node) => visitTypeRef(node); | 246 T visitUnknownTypeRef(UnknownTypeRef node) => visitTypeRef(node); |
248 T visitArrayTypeRef(ArrayTypeRef node) => visitTypeRef(node); | 247 T visitArrayTypeRef(ArrayTypeRef node) => visitTypeRef(node); |
249 } | 248 } |
250 | 249 |
251 abstract class Node { | 250 abstract class Node { |
252 /// Sets the source location of this node. For performance reasons, we allow | 251 /// Sets the source location of this node. For performance reasons, we allow |
253 /// setting this after construction. | 252 /// setting this after construction. |
254 Object sourceInformation; | 253 Object sourceInformation; |
255 | 254 |
256 ClosureAnnotation _closureAnnotation; | 255 ClosureAnnotation _closureAnnotation; |
| 256 |
257 /// Closure annotation of this node. | 257 /// Closure annotation of this node. |
258 ClosureAnnotation get closureAnnotation => _closureAnnotation; | 258 ClosureAnnotation get closureAnnotation => _closureAnnotation; |
259 | 259 |
260 accept(NodeVisitor visitor); | 260 accept(NodeVisitor visitor); |
261 void visitChildren(NodeVisitor visitor); | 261 void visitChildren(NodeVisitor visitor); |
262 | 262 |
263 // Shallow clone of node. Does not clone positions since the only use of this | 263 // Shallow clone of node. Does not clone positions since the only use of this |
264 // private method is create a copy with a new position. | 264 // private method is create a copy with a new position. |
265 Node _clone(); | 265 Node _clone(); |
266 | 266 |
267 withClosureAnnotation(ClosureAnnotation closureAnnotation) { | 267 withClosureAnnotation(ClosureAnnotation closureAnnotation) { |
268 if (this.closureAnnotation == closureAnnotation) return this; | 268 if (this.closureAnnotation == closureAnnotation) return this; |
269 | 269 |
270 return _clone() | 270 return _clone() |
271 ..sourceInformation = sourceInformation | 271 ..sourceInformation = sourceInformation |
272 .._closureAnnotation = closureAnnotation; | 272 .._closureAnnotation = closureAnnotation; |
273 } | 273 } |
| 274 |
274 // Returns a node equivalent to [this], but with new source position and end | 275 // Returns a node equivalent to [this], but with new source position and end |
275 // source position. | 276 // source position. |
276 Node withSourceInformation(sourceInformation) { | 277 Node withSourceInformation(sourceInformation) { |
277 if (sourceInformation == this.sourceInformation) { | 278 if (sourceInformation == this.sourceInformation) { |
278 return this; | 279 return this; |
279 } | 280 } |
280 Node clone = _clone(); | 281 Node clone = _clone(); |
281 // TODO(sra): Should existing data be 'sticky' if we try to overwrite with | 282 // TODO(sra): Should existing data be 'sticky' if we try to overwrite with |
282 // `null`? | 283 // `null`? |
283 clone.sourceInformation = sourceInformation; | 284 clone.sourceInformation = sourceInformation; |
284 return clone; | 285 return clone; |
285 } | 286 } |
286 | 287 |
287 bool get isCommaOperator => false; | 288 bool get isCommaOperator => false; |
288 | 289 |
289 Statement toStatement() { | 290 Statement toStatement() { |
290 throw new UnsupportedError('toStatement'); | 291 throw new UnsupportedError('toStatement'); |
291 } | 292 } |
| 293 |
292 Statement toReturn() { | 294 Statement toReturn() { |
293 throw new UnsupportedError('toReturn'); | 295 throw new UnsupportedError('toReturn'); |
294 } | 296 } |
295 | 297 |
296 // For debugging | 298 // For debugging |
297 String toString() { | 299 String toString() { |
298 var context = new SimpleJavaScriptPrintingContext(); | 300 var context = new SimpleJavaScriptPrintingContext(); |
299 var opts = new JavaScriptPrintingOptions(allowKeywordsInProperties: true); | 301 var opts = new JavaScriptPrintingOptions(allowKeywordsInProperties: true); |
300 context.buffer.write('js_ast `'); | 302 context.buffer.write('js_ast `'); |
301 accept(new Printer(opts, context)); | 303 accept(new Printer(opts, context)); |
(...skipping 14 matching lines...) Expand all Loading... |
316 /// | 318 /// |
317 /// This is not used in ES6, but is provided to allow module lowering. | 319 /// This is not used in ES6, but is provided to allow module lowering. |
318 final String name; | 320 final String name; |
319 | 321 |
320 Program(this.body, {this.scriptTag, this.name}); | 322 Program(this.body, {this.scriptTag, this.name}); |
321 | 323 |
322 accept(NodeVisitor visitor) => visitor.visitProgram(this); | 324 accept(NodeVisitor visitor) => visitor.visitProgram(this); |
323 void visitChildren(NodeVisitor visitor) { | 325 void visitChildren(NodeVisitor visitor) { |
324 for (ModuleItem statement in body) statement.accept(visitor); | 326 for (ModuleItem statement in body) statement.accept(visitor); |
325 } | 327 } |
| 328 |
326 Program _clone() => new Program(body); | 329 Program _clone() => new Program(body); |
327 } | 330 } |
328 | 331 |
329 abstract class Statement extends ModuleItem { | 332 abstract class Statement extends ModuleItem { |
330 Statement toStatement() => this; | 333 Statement toStatement() => this; |
331 Statement toReturn() => new Block([this, new Return()]); | 334 Statement toReturn() => new Block([this, new Return()]); |
332 } | 335 } |
333 | 336 |
334 class Block extends Statement { | 337 class Block extends Statement { |
335 final List<Statement> statements; | 338 final List<Statement> statements; |
336 | 339 |
337 /// True to preserve this [Block] for scoping reasons. | 340 /// True to preserve this [Block] for scoping reasons. |
338 final bool isScope; | 341 final bool isScope; |
339 | 342 |
340 Block(this.statements, {this.isScope: false}) { | 343 Block(this.statements, {this.isScope: false}) { |
341 assert(!statements.any((s) => s is! Statement)); | 344 assert(!statements.any((s) => s is! Statement)); |
342 } | 345 } |
343 Block.empty() : statements = <Statement>[], isScope = false; | 346 Block.empty() |
| 347 : statements = <Statement>[], |
| 348 isScope = false; |
344 | 349 |
345 accept(NodeVisitor visitor) => visitor.visitBlock(this); | 350 accept(NodeVisitor visitor) => visitor.visitBlock(this); |
346 void visitChildren(NodeVisitor visitor) { | 351 void visitChildren(NodeVisitor visitor) { |
347 for (Statement statement in statements) statement.accept(visitor); | 352 for (Statement statement in statements) statement.accept(visitor); |
348 } | 353 } |
| 354 |
349 Block _clone() => new Block(statements); | 355 Block _clone() => new Block(statements); |
350 } | 356 } |
351 | 357 |
352 class ExpressionStatement extends Statement { | 358 class ExpressionStatement extends Statement { |
353 final Expression expression; | 359 final Expression expression; |
354 ExpressionStatement(this.expression); | 360 ExpressionStatement(this.expression); |
355 | 361 |
356 accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this); | 362 accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this); |
357 void visitChildren(NodeVisitor visitor) { expression.accept(visitor); } | 363 void visitChildren(NodeVisitor visitor) { |
| 364 expression.accept(visitor); |
| 365 } |
| 366 |
358 ExpressionStatement _clone() => new ExpressionStatement(expression); | 367 ExpressionStatement _clone() => new ExpressionStatement(expression); |
359 } | 368 } |
360 | 369 |
361 class EmptyStatement extends Statement { | 370 class EmptyStatement extends Statement { |
362 EmptyStatement(); | 371 EmptyStatement(); |
363 | 372 |
364 accept(NodeVisitor visitor) => visitor.visitEmptyStatement(this); | 373 accept(NodeVisitor visitor) => visitor.visitEmptyStatement(this); |
365 void visitChildren(NodeVisitor visitor) {} | 374 void visitChildren(NodeVisitor visitor) {} |
366 EmptyStatement _clone() => new EmptyStatement(); | 375 EmptyStatement _clone() => new EmptyStatement(); |
367 } | 376 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 | 482 |
474 void visitChildren(NodeVisitor visitor) { | 483 void visitChildren(NodeVisitor visitor) { |
475 body.accept(visitor); | 484 body.accept(visitor); |
476 condition.accept(visitor); | 485 condition.accept(visitor); |
477 } | 486 } |
478 | 487 |
479 Do _clone() => new Do(body, condition); | 488 Do _clone() => new Do(body, condition); |
480 } | 489 } |
481 | 490 |
482 class Continue extends Statement { | 491 class Continue extends Statement { |
483 final String targetLabel; // Can be null. | 492 final String targetLabel; // Can be null. |
484 | 493 |
485 Continue(this.targetLabel); | 494 Continue(this.targetLabel); |
486 | 495 |
487 accept(NodeVisitor visitor) => visitor.visitContinue(this); | 496 accept(NodeVisitor visitor) => visitor.visitContinue(this); |
488 void visitChildren(NodeVisitor visitor) {} | 497 void visitChildren(NodeVisitor visitor) {} |
489 | 498 |
490 Continue _clone() => new Continue(targetLabel); | 499 Continue _clone() => new Continue(targetLabel); |
491 } | 500 } |
492 | 501 |
493 class Break extends Statement { | 502 class Break extends Statement { |
494 final String targetLabel; // Can be null. | 503 final String targetLabel; // Can be null. |
495 | 504 |
496 Break(this.targetLabel); | 505 Break(this.targetLabel); |
497 | 506 |
498 accept(NodeVisitor visitor) => visitor.visitBreak(this); | 507 accept(NodeVisitor visitor) => visitor.visitBreak(this); |
499 void visitChildren(NodeVisitor visitor) {} | 508 void visitChildren(NodeVisitor visitor) {} |
500 | 509 |
501 Break _clone() => new Break(targetLabel); | 510 Break _clone() => new Break(targetLabel); |
502 } | 511 } |
503 | 512 |
504 class Return extends Statement { | 513 class Return extends Statement { |
505 final Expression value; // Can be null. | 514 final Expression value; // Can be null. |
506 | 515 |
507 Return([this.value = null]); | 516 Return([this.value = null]); |
508 | 517 |
509 Statement toReturn() => this; | 518 Statement toReturn() => this; |
510 | 519 |
511 accept(NodeVisitor visitor) => visitor.visitReturn(this); | 520 accept(NodeVisitor visitor) => visitor.visitReturn(this); |
512 | 521 |
513 void visitChildren(NodeVisitor visitor) { | 522 void visitChildren(NodeVisitor visitor) { |
514 if (value != null) value.accept(visitor); | 523 if (value != null) value.accept(visitor); |
515 } | 524 } |
516 | 525 |
517 Return _clone() => new Return(value); | 526 Return _clone() => new Return(value); |
518 | 527 |
519 static bool foundIn(Node node) { | 528 static bool foundIn(Node node) { |
520 _returnFinder.found = false; | 529 _returnFinder.found = false; |
521 node.accept(_returnFinder); | 530 node.accept(_returnFinder); |
522 return _returnFinder.found; | 531 return _returnFinder.found; |
523 } | 532 } |
524 } | 533 } |
525 | 534 |
526 final _returnFinder = new _ReturnFinder(); | 535 final _returnFinder = new _ReturnFinder(); |
| 536 |
527 class _ReturnFinder extends BaseVisitor { | 537 class _ReturnFinder extends BaseVisitor { |
528 bool found = false; | 538 bool found = false; |
529 visitReturn(Return node) { | 539 visitReturn(Return node) { |
530 found = true; | 540 found = true; |
531 } | 541 } |
| 542 |
532 visitNode(Node node) { | 543 visitNode(Node node) { |
533 if (!found) super.visitNode(node); | 544 if (!found) super.visitNode(node); |
534 } | 545 } |
535 } | 546 } |
536 | 547 |
537 | |
538 class Throw extends Statement { | 548 class Throw extends Statement { |
539 final Expression expression; | 549 final Expression expression; |
540 | 550 |
541 Throw(this.expression); | 551 Throw(this.expression); |
542 | 552 |
543 accept(NodeVisitor visitor) => visitor.visitThrow(this); | 553 accept(NodeVisitor visitor) => visitor.visitThrow(this); |
544 | 554 |
545 void visitChildren(NodeVisitor visitor) { | 555 void visitChildren(NodeVisitor visitor) { |
546 expression.accept(visitor); | 556 expression.accept(visitor); |
547 } | 557 } |
548 | 558 |
549 Throw _clone() => new Throw(expression); | 559 Throw _clone() => new Throw(expression); |
550 } | 560 } |
551 | 561 |
552 class Try extends Statement { | 562 class Try extends Statement { |
553 final Block body; | 563 final Block body; |
554 final Catch catchPart; // Can be null if [finallyPart] is non-null. | 564 final Catch catchPart; // Can be null if [finallyPart] is non-null. |
555 final Block finallyPart; // Can be null if [catchPart] is non-null. | 565 final Block finallyPart; // Can be null if [catchPart] is non-null. |
556 | 566 |
557 Try(this.body, this.catchPart, this.finallyPart) { | 567 Try(this.body, this.catchPart, this.finallyPart) { |
558 assert(catchPart != null || finallyPart != null); | 568 assert(catchPart != null || finallyPart != null); |
559 } | 569 } |
560 | 570 |
561 accept(NodeVisitor visitor) => visitor.visitTry(this); | 571 accept(NodeVisitor visitor) => visitor.visitTry(this); |
562 | 572 |
563 void visitChildren(NodeVisitor visitor) { | 573 void visitChildren(NodeVisitor visitor) { |
564 body.accept(visitor); | 574 body.accept(visitor); |
565 if (catchPart != null) catchPart.accept(visitor); | 575 if (catchPart != null) catchPart.accept(visitor); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 | 674 |
665 LabeledStatement _clone() => new LabeledStatement(label, body); | 675 LabeledStatement _clone() => new LabeledStatement(label, body); |
666 } | 676 } |
667 | 677 |
668 class LiteralStatement extends Statement { | 678 class LiteralStatement extends Statement { |
669 final String code; | 679 final String code; |
670 | 680 |
671 LiteralStatement(this.code); | 681 LiteralStatement(this.code); |
672 | 682 |
673 accept(NodeVisitor visitor) => visitor.visitLiteralStatement(this); | 683 accept(NodeVisitor visitor) => visitor.visitLiteralStatement(this); |
674 void visitChildren(NodeVisitor visitor) { } | 684 void visitChildren(NodeVisitor visitor) {} |
675 | 685 |
676 LiteralStatement _clone() => new LiteralStatement(code); | 686 LiteralStatement _clone() => new LiteralStatement(code); |
677 } | 687 } |
678 | 688 |
679 // Not a real JavaScript node, but represents the yield statement from a dart | 689 // Not a real JavaScript node, but represents the yield statement from a dart |
680 // program translated to JavaScript. | 690 // program translated to JavaScript. |
681 class DartYield extends Statement { | 691 class DartYield extends Statement { |
682 final Expression expression; | 692 final Expression expression; |
683 | 693 |
684 final bool hasStar; | 694 final bool hasStar; |
(...skipping 23 matching lines...) Expand all Loading... |
708 int get precedenceLevel; | 718 int get precedenceLevel; |
709 | 719 |
710 Statement toStatement() => new ExpressionStatement(toVoidExpression()); | 720 Statement toStatement() => new ExpressionStatement(toVoidExpression()); |
711 Statement toReturn() => new Return(this); | 721 Statement toReturn() => new Return(this); |
712 Statement toYieldStatement({bool star: false}) => | 722 Statement toYieldStatement({bool star: false}) => |
713 new ExpressionStatement(new Yield(this, star: star)); | 723 new ExpressionStatement(new Yield(this, star: star)); |
714 | 724 |
715 Expression toVoidExpression() => this; | 725 Expression toVoidExpression() => this; |
716 Expression toAssignExpression(Expression left) => new Assignment(left, this); | 726 Expression toAssignExpression(Expression left) => new Assignment(left, this); |
717 Statement toVariableDeclaration(Identifier name) => | 727 Statement toVariableDeclaration(Identifier name) => |
718 new VariableDeclarationList('let', | 728 new VariableDeclarationList( |
719 [new VariableInitialization(name, this)]).toStatement(); | 729 'let', [new VariableInitialization(name, this)]).toStatement(); |
720 } | 730 } |
721 | 731 |
722 class LiteralExpression extends Expression { | 732 class LiteralExpression extends Expression { |
723 final String template; | 733 final String template; |
724 final List<Expression> inputs; | 734 final List<Expression> inputs; |
725 | 735 |
726 LiteralExpression(this.template) : inputs = const []; | 736 LiteralExpression(this.template) : inputs = const []; |
727 LiteralExpression.withData(this.template, this.inputs); | 737 LiteralExpression.withData(this.template, this.inputs); |
728 | 738 |
729 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this); | 739 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 } | 775 } |
766 | 776 |
767 VariableDeclarationList _clone() => | 777 VariableDeclarationList _clone() => |
768 new VariableDeclarationList(keyword, declarations); | 778 new VariableDeclarationList(keyword, declarations); |
769 | 779 |
770 int get precedenceLevel => EXPRESSION; | 780 int get precedenceLevel => EXPRESSION; |
771 } | 781 } |
772 | 782 |
773 class Assignment extends Expression { | 783 class Assignment extends Expression { |
774 final Expression leftHandSide; | 784 final Expression leftHandSide; |
775 final String op; // Null, if the assignment is not compound. | 785 final String op; // Null, if the assignment is not compound. |
776 final Expression value; // May be null, for [VariableInitialization]s. | 786 final Expression value; // May be null, for [VariableInitialization]s. |
777 | 787 |
778 Assignment(leftHandSide, value) | 788 Assignment(leftHandSide, value) : this.compound(leftHandSide, null, value); |
779 : this.compound(leftHandSide, null, value); | |
780 Assignment.compound(this.leftHandSide, this.op, this.value); | 789 Assignment.compound(this.leftHandSide, this.op, this.value); |
781 | 790 |
782 int get precedenceLevel => ASSIGNMENT; | 791 int get precedenceLevel => ASSIGNMENT; |
783 | 792 |
784 bool get isCompound => op != null; | 793 bool get isCompound => op != null; |
785 | 794 |
786 accept(NodeVisitor visitor) => visitor.visitAssignment(this); | 795 accept(NodeVisitor visitor) => visitor.visitAssignment(this); |
787 | 796 |
788 void visitChildren(NodeVisitor visitor) { | 797 void visitChildren(NodeVisitor visitor) { |
789 leftHandSide.accept(visitor); | 798 leftHandSide.accept(visitor); |
790 if (value != null) value.accept(visitor); | 799 if (value != null) value.accept(visitor); |
791 } | 800 } |
792 | 801 |
793 Assignment _clone() => | 802 Assignment _clone() => new Assignment.compound(leftHandSide, op, value); |
794 new Assignment.compound(leftHandSide, op, value); | |
795 } | 803 } |
796 | 804 |
797 class VariableInitialization extends Assignment { | 805 class VariableInitialization extends Assignment { |
798 /** [value] may be null. */ | 806 /** [value] may be null. */ |
799 VariableInitialization(VariableBinding declaration, Expression value) | 807 VariableInitialization(VariableBinding declaration, Expression value) |
800 : super(declaration, value); | 808 : super(declaration, value); |
801 | 809 |
802 VariableBinding get declaration => leftHandSide; | 810 VariableBinding get declaration => leftHandSide; |
803 | 811 |
804 accept(NodeVisitor visitor) => visitor.visitVariableInitialization(this); | 812 accept(NodeVisitor visitor) => visitor.visitVariableInitialization(this); |
805 | 813 |
806 VariableInitialization _clone() => | 814 VariableInitialization _clone() => |
807 new VariableInitialization(declaration, value); | 815 new VariableInitialization(declaration, value); |
808 } | 816 } |
809 | 817 |
810 abstract class VariableBinding extends Expression { | 818 abstract class VariableBinding extends Expression {} |
811 } | |
812 | 819 |
813 class DestructuredVariable extends Expression implements Parameter { | 820 class DestructuredVariable extends Expression implements Parameter { |
814 /// [LiteralString] or [Identifier]. | 821 /// [LiteralString] or [Identifier]. |
815 final Expression name; | 822 final Expression name; |
816 final BindingPattern structure; | 823 final BindingPattern structure; |
817 final Expression defaultValue; | 824 final Expression defaultValue; |
818 final TypeRef type; | 825 final TypeRef type; |
819 DestructuredVariable({this.name, this.structure, this.defaultValue, this.type}
) { | 826 DestructuredVariable( |
| 827 {this.name, this.structure, this.defaultValue, this.type}) { |
820 assert(name != null || structure != null); | 828 assert(name != null || structure != null); |
821 } | 829 } |
822 | 830 |
823 accept(NodeVisitor visitor) => visitor.visitDestructuredVariable(this); | 831 accept(NodeVisitor visitor) => visitor.visitDestructuredVariable(this); |
824 void visitChildren(NodeVisitor visitor) { | 832 void visitChildren(NodeVisitor visitor) { |
825 name?.accept(visitor); | 833 name?.accept(visitor); |
826 structure?.accept(visitor); | 834 structure?.accept(visitor); |
827 defaultValue?.accept(visitor); | 835 defaultValue?.accept(visitor); |
828 } | 836 } |
829 | 837 |
830 /// Avoid parenthesis when pretty-printing. | 838 /// Avoid parenthesis when pretty-printing. |
831 @override int get precedenceLevel => PRIMARY; | 839 @override |
832 @override Node _clone() => | 840 int get precedenceLevel => PRIMARY; |
833 new DestructuredVariable( | 841 @override |
834 name: name, structure: structure, defaultValue: defaultValue); | 842 Node _clone() => new DestructuredVariable( |
| 843 name: name, structure: structure, defaultValue: defaultValue); |
835 } | 844 } |
836 | 845 |
837 abstract class BindingPattern extends Expression implements VariableBinding { | 846 abstract class BindingPattern extends Expression implements VariableBinding { |
838 final List<DestructuredVariable> variables; | 847 final List<DestructuredVariable> variables; |
839 BindingPattern(this.variables); | 848 BindingPattern(this.variables); |
840 | 849 |
841 void visitChildren(NodeVisitor visitor) { | 850 void visitChildren(NodeVisitor visitor) { |
842 for (DestructuredVariable v in variables) v.accept(visitor); | 851 for (DestructuredVariable v in variables) v.accept(visitor); |
843 } | 852 } |
844 } | 853 } |
845 | 854 |
846 class SimpleBindingPattern extends BindingPattern { | 855 class SimpleBindingPattern extends BindingPattern { |
847 final Identifier name; | 856 final Identifier name; |
848 SimpleBindingPattern(Identifier name) | 857 SimpleBindingPattern(Identifier name) |
849 : name = name, | 858 : name = name, |
850 super([new DestructuredVariable(name: name)]); | 859 super([new DestructuredVariable(name: name)]); |
851 | 860 |
852 accept(NodeVisitor visitor) => visitor.visitSimpleBindingPattern(this); | 861 accept(NodeVisitor visitor) => visitor.visitSimpleBindingPattern(this); |
853 | 862 |
854 /// Avoid parenthesis when pretty-printing. | 863 /// Avoid parenthesis when pretty-printing. |
855 @override int get precedenceLevel => PRIMARY; | 864 @override |
856 @override Node _clone() => new SimpleBindingPattern(name); | 865 int get precedenceLevel => PRIMARY; |
| 866 @override |
| 867 Node _clone() => new SimpleBindingPattern(name); |
857 } | 868 } |
858 | 869 |
859 class ObjectBindingPattern extends BindingPattern { | 870 class ObjectBindingPattern extends BindingPattern { |
860 ObjectBindingPattern(List<DestructuredVariable> variables) | 871 ObjectBindingPattern(List<DestructuredVariable> variables) : super(variables); |
861 : super(variables); | |
862 accept(NodeVisitor visitor) => visitor.visitObjectBindingPattern(this); | 872 accept(NodeVisitor visitor) => visitor.visitObjectBindingPattern(this); |
863 | 873 |
864 /// Avoid parenthesis when pretty-printing. | 874 /// Avoid parenthesis when pretty-printing. |
865 @override int get precedenceLevel => PRIMARY; | 875 @override |
866 @override Node _clone() => new ObjectBindingPattern(variables); | 876 int get precedenceLevel => PRIMARY; |
| 877 @override |
| 878 Node _clone() => new ObjectBindingPattern(variables); |
867 } | 879 } |
868 | 880 |
869 class ArrayBindingPattern extends BindingPattern { | 881 class ArrayBindingPattern extends BindingPattern { |
870 ArrayBindingPattern(List<DestructuredVariable> variables) | 882 ArrayBindingPattern(List<DestructuredVariable> variables) : super(variables); |
871 : super(variables); | |
872 accept(NodeVisitor visitor) => visitor.visitArrayBindingPattern(this); | 883 accept(NodeVisitor visitor) => visitor.visitArrayBindingPattern(this); |
873 | 884 |
874 /// Avoid parenthesis when pretty-printing. | 885 /// Avoid parenthesis when pretty-printing. |
875 @override int get precedenceLevel => PRIMARY; | 886 @override |
876 @override Node _clone() => new ObjectBindingPattern(variables); | 887 int get precedenceLevel => PRIMARY; |
| 888 @override |
| 889 Node _clone() => new ObjectBindingPattern(variables); |
877 } | 890 } |
878 | 891 |
879 class Conditional extends Expression { | 892 class Conditional extends Expression { |
880 final Expression condition; | 893 final Expression condition; |
881 final Expression then; | 894 final Expression then; |
882 final Expression otherwise; | 895 final Expression otherwise; |
883 | 896 |
884 Conditional(this.condition, this.then, this.otherwise); | 897 Conditional(this.condition, this.then, this.otherwise); |
885 | 898 |
886 accept(NodeVisitor visitor) => visitor.visitConditional(this); | 899 accept(NodeVisitor visitor) => visitor.visitConditional(this); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1080 final bool allowRename; | 1093 final bool allowRename; |
1081 final TypeRef type; | 1094 final TypeRef type; |
1082 | 1095 |
1083 Identifier(this.name, {this.allowRename: true, this.type}) { | 1096 Identifier(this.name, {this.allowRename: true, this.type}) { |
1084 if (!_identifierRE.hasMatch(name)) { | 1097 if (!_identifierRE.hasMatch(name)) { |
1085 throw new ArgumentError.value(name, "name", "not a valid identifier"); | 1098 throw new ArgumentError.value(name, "name", "not a valid identifier"); |
1086 } | 1099 } |
1087 } | 1100 } |
1088 static RegExp _identifierRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$'); | 1101 static RegExp _identifierRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$'); |
1089 | 1102 |
1090 Identifier _clone() => | 1103 Identifier _clone() => new Identifier(name, allowRename: allowRename); |
1091 new Identifier(name, allowRename: allowRename); | |
1092 accept(NodeVisitor visitor) => visitor.visitIdentifier(this); | 1104 accept(NodeVisitor visitor) => visitor.visitIdentifier(this); |
1093 int get precedenceLevel => PRIMARY; | 1105 int get precedenceLevel => PRIMARY; |
1094 void visitChildren(NodeVisitor visitor) {} | 1106 void visitChildren(NodeVisitor visitor) {} |
1095 } | 1107 } |
1096 | 1108 |
1097 // This is an expression for convenience in the AST. | 1109 // This is an expression for convenience in the AST. |
1098 class RestParameter extends Expression implements Parameter { | 1110 class RestParameter extends Expression implements Parameter { |
1099 final Identifier parameter; | 1111 final Identifier parameter; |
1100 TypeRef get type => null; | 1112 TypeRef get type => null; |
1101 | 1113 |
1102 RestParameter(this.parameter); | 1114 RestParameter(this.parameter); |
1103 | 1115 |
1104 RestParameter _clone() => new RestParameter(parameter); | 1116 RestParameter _clone() => new RestParameter(parameter); |
1105 accept(NodeVisitor visitor) => visitor.visitRestParameter(this); | 1117 accept(NodeVisitor visitor) => visitor.visitRestParameter(this); |
1106 void visitChildren(NodeVisitor visitor) { | 1118 void visitChildren(NodeVisitor visitor) { |
1107 parameter.accept(visitor); | 1119 parameter.accept(visitor); |
1108 } | 1120 } |
| 1121 |
1109 int get precedenceLevel => PRIMARY; | 1122 int get precedenceLevel => PRIMARY; |
1110 } | 1123 } |
1111 | 1124 |
1112 class This extends Expression { | 1125 class This extends Expression { |
1113 accept(NodeVisitor visitor) => visitor.visitThis(this); | 1126 accept(NodeVisitor visitor) => visitor.visitThis(this); |
1114 This _clone() => new This(); | 1127 This _clone() => new This(); |
1115 int get precedenceLevel => PRIMARY; | 1128 int get precedenceLevel => PRIMARY; |
1116 void visitChildren(NodeVisitor visitor) {} | 1129 void visitChildren(NodeVisitor visitor) {} |
1117 | 1130 |
1118 static bool foundIn(Node node) { | 1131 static bool foundIn(Node node) { |
1119 _thisFinder.found = false; | 1132 _thisFinder.found = false; |
1120 node.accept(_thisFinder); | 1133 node.accept(_thisFinder); |
1121 return _thisFinder.found; | 1134 return _thisFinder.found; |
1122 } | 1135 } |
1123 } | 1136 } |
1124 | 1137 |
1125 final _thisFinder = new _ThisFinder(); | 1138 final _thisFinder = new _ThisFinder(); |
| 1139 |
1126 class _ThisFinder extends BaseVisitor { | 1140 class _ThisFinder extends BaseVisitor { |
1127 bool found = false; | 1141 bool found = false; |
1128 visitThis(This node) { | 1142 visitThis(This node) { |
1129 found = true; | 1143 found = true; |
1130 } | 1144 } |
| 1145 |
1131 visitNode(Node node) { | 1146 visitNode(Node node) { |
1132 if (!found) super.visitNode(node); | 1147 if (!found) super.visitNode(node); |
1133 } | 1148 } |
1134 } | 1149 } |
1135 | 1150 |
1136 | |
1137 // `super` is more restricted in the ES6 spec, but for simplicity we accept | 1151 // `super` is more restricted in the ES6 spec, but for simplicity we accept |
1138 // it anywhere that `this` is accepted. | 1152 // it anywhere that `this` is accepted. |
1139 class Super extends Expression { | 1153 class Super extends Expression { |
1140 accept(NodeVisitor visitor) => visitor.visitSuper(this); | 1154 accept(NodeVisitor visitor) => visitor.visitSuper(this); |
1141 Super _clone() => new Super(); | 1155 Super _clone() => new Super(); |
1142 int get precedenceLevel => PRIMARY; | 1156 int get precedenceLevel => PRIMARY; |
1143 void visitChildren(NodeVisitor visitor) {} | 1157 void visitChildren(NodeVisitor visitor) {} |
1144 } | 1158 } |
1145 | 1159 |
1146 class NamedFunction extends Expression { | 1160 class NamedFunction extends Expression { |
1147 final Identifier name; | 1161 final Identifier name; |
1148 final Fun function; | 1162 final Fun function; |
1149 // A heuristic to force extra parens around this function. V8 and other | 1163 // A heuristic to force extra parens around this function. V8 and other |
1150 // engines use this IIFE (immediately invoked function expression) heuristic | 1164 // engines use this IIFE (immediately invoked function expression) heuristic |
1151 // to eagerly parse a function. | 1165 // to eagerly parse a function. |
1152 final bool immediatelyInvoked; | 1166 final bool immediatelyInvoked; |
1153 | 1167 |
1154 NamedFunction(this.name, this.function, [this.immediatelyInvoked = false]); | 1168 NamedFunction(this.name, this.function, [this.immediatelyInvoked = false]); |
1155 | 1169 |
1156 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); | 1170 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); |
1157 | 1171 |
1158 void visitChildren(NodeVisitor visitor) { | 1172 void visitChildren(NodeVisitor visitor) { |
1159 name.accept(visitor); | 1173 name.accept(visitor); |
1160 function.accept(visitor); | 1174 function.accept(visitor); |
1161 } | 1175 } |
1162 NamedFunction _clone() => new NamedFunction(name, function, immediatelyInvoked
); | |
1163 | 1176 |
1164 int get precedenceLevel => immediatelyInvoked ? EXPRESSION : PRIMARY_LOW_PRECE
DENCE; | 1177 NamedFunction _clone() => |
| 1178 new NamedFunction(name, function, immediatelyInvoked); |
| 1179 |
| 1180 int get precedenceLevel => |
| 1181 immediatelyInvoked ? EXPRESSION : PRIMARY_LOW_PRECEDENCE; |
1165 } | 1182 } |
1166 | 1183 |
1167 abstract class FunctionExpression extends Expression { | 1184 abstract class FunctionExpression extends Expression { |
1168 List<Parameter> get params; | 1185 List<Parameter> get params; |
1169 | 1186 |
1170 get body; // Expression or block | 1187 get body; // Expression or block |
1171 /// Type parameters passed to this generic function, if any. `null` otherwise. | 1188 /// Type parameters passed to this generic function, if any. `null` otherwise. |
1172 // TODO(ochafik): Support type bounds. | 1189 // TODO(ochafik): Support type bounds. |
1173 List<Identifier> get typeParams; | 1190 List<Identifier> get typeParams; |
| 1191 |
1174 /// Return type of this function, if any. `null` otherwise. | 1192 /// Return type of this function, if any. `null` otherwise. |
1175 TypeRef get returnType; | 1193 TypeRef get returnType; |
1176 } | 1194 } |
1177 | 1195 |
1178 class Fun extends FunctionExpression { | 1196 class Fun extends FunctionExpression { |
1179 final List<Parameter> params; | 1197 final List<Parameter> params; |
1180 final Block body; | 1198 final Block body; |
1181 @override final List<Identifier> typeParams; | 1199 @override |
1182 @override final TypeRef returnType; | 1200 final List<Identifier> typeParams; |
| 1201 @override |
| 1202 final TypeRef returnType; |
1183 | 1203 |
1184 /** Whether this is a JS generator (`function*`) that may contain `yield`. */ | 1204 /** Whether this is a JS generator (`function*`) that may contain `yield`. */ |
1185 final bool isGenerator; | 1205 final bool isGenerator; |
1186 | 1206 |
1187 final AsyncModifier asyncModifier; | 1207 final AsyncModifier asyncModifier; |
1188 | 1208 |
1189 Fun(this.params, this.body, {this.isGenerator: false, | 1209 Fun(this.params, this.body, |
| 1210 {this.isGenerator: false, |
1190 this.asyncModifier: const AsyncModifier.sync(), | 1211 this.asyncModifier: const AsyncModifier.sync(), |
1191 this.typeParams, this.returnType}); | 1212 this.typeParams, |
| 1213 this.returnType}); |
1192 | 1214 |
1193 accept(NodeVisitor visitor) => visitor.visitFun(this); | 1215 accept(NodeVisitor visitor) => visitor.visitFun(this); |
1194 | 1216 |
1195 void visitChildren(NodeVisitor visitor) { | 1217 void visitChildren(NodeVisitor visitor) { |
1196 for (Parameter param in params) param.accept(visitor); | 1218 for (Parameter param in params) param.accept(visitor); |
1197 body.accept(visitor); | 1219 body.accept(visitor); |
1198 } | 1220 } |
1199 | 1221 |
1200 Fun _clone() => new Fun(params, body, | 1222 Fun _clone() => new Fun(params, body, |
1201 isGenerator: isGenerator, asyncModifier: asyncModifier); | 1223 isGenerator: isGenerator, asyncModifier: asyncModifier); |
1202 | 1224 |
1203 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; | 1225 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
1204 } | 1226 } |
1205 | 1227 |
1206 class ArrowFun extends FunctionExpression { | 1228 class ArrowFun extends FunctionExpression { |
1207 final List<Parameter> params; | 1229 final List<Parameter> params; |
1208 final body; // Expression or Block | 1230 final body; // Expression or Block |
1209 @override final List<Identifier> typeParams; | 1231 @override |
1210 @override final TypeRef returnType; | 1232 final List<Identifier> typeParams; |
| 1233 @override |
| 1234 final TypeRef returnType; |
1211 | 1235 |
1212 ArrowFun(this.params, this.body, {this.typeParams, this.returnType}); | 1236 ArrowFun(this.params, this.body, {this.typeParams, this.returnType}); |
1213 | 1237 |
1214 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); | 1238 accept(NodeVisitor visitor) => visitor.visitArrowFun(this); |
1215 | 1239 |
1216 void visitChildren(NodeVisitor visitor) { | 1240 void visitChildren(NodeVisitor visitor) { |
1217 for (Parameter param in params) param.accept(visitor); | 1241 for (Parameter param in params) param.accept(visitor); |
1218 body.accept(visitor); | 1242 body.accept(visitor); |
1219 } | 1243 } |
1220 | 1244 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 LiteralString(this.value); | 1338 LiteralString(this.value); |
1315 | 1339 |
1316 /// Gets the value inside the string without the beginning and end quotes. | 1340 /// Gets the value inside the string without the beginning and end quotes. |
1317 String get valueWithoutQuotes => value.substring(1, value.length - 1); | 1341 String get valueWithoutQuotes => value.substring(1, value.length - 1); |
1318 | 1342 |
1319 accept(NodeVisitor visitor) => visitor.visitLiteralString(this); | 1343 accept(NodeVisitor visitor) => visitor.visitLiteralString(this); |
1320 LiteralString _clone() => new LiteralString(value); | 1344 LiteralString _clone() => new LiteralString(value); |
1321 } | 1345 } |
1322 | 1346 |
1323 class LiteralNumber extends Literal { | 1347 class LiteralNumber extends Literal { |
1324 final String value; // Must be a valid JavaScript number literal. | 1348 final String value; // Must be a valid JavaScript number literal. |
1325 | 1349 |
1326 LiteralNumber(this.value); | 1350 LiteralNumber(this.value); |
1327 | 1351 |
1328 accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this); | 1352 accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this); |
1329 LiteralNumber _clone() => new LiteralNumber(value); | 1353 LiteralNumber _clone() => new LiteralNumber(value); |
1330 | 1354 |
1331 /** | 1355 /** |
1332 * Use a different precedence level depending on whether the value contains a | 1356 * Use a different precedence level depending on whether the value contains a |
1333 * dot to ensure we generate `(1).toString()` and `1.0.toString()`. | 1357 * dot to ensure we generate `(1).toString()` and `1.0.toString()`. |
1334 */ | 1358 */ |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 | 1513 |
1490 accept(NodeVisitor visitor) => visitor.visitClassDeclaration(this); | 1514 accept(NodeVisitor visitor) => visitor.visitClassDeclaration(this); |
1491 visitChildren(NodeVisitor visitor) => classExpr.accept(visitor); | 1515 visitChildren(NodeVisitor visitor) => classExpr.accept(visitor); |
1492 ClassDeclaration _clone() => new ClassDeclaration(classExpr); | 1516 ClassDeclaration _clone() => new ClassDeclaration(classExpr); |
1493 } | 1517 } |
1494 | 1518 |
1495 class ClassExpression extends Expression { | 1519 class ClassExpression extends Expression { |
1496 final Identifier name; | 1520 final Identifier name; |
1497 final Expression heritage; // Can be null. | 1521 final Expression heritage; // Can be null. |
1498 final List<Method> methods; | 1522 final List<Method> methods; |
| 1523 |
1499 /// Type parameters of this class, if any. `null` otherwise. | 1524 /// Type parameters of this class, if any. `null` otherwise. |
1500 // TODO(ochafik): Support type bounds. | 1525 // TODO(ochafik): Support type bounds. |
1501 final List<Identifier> typeParams; | 1526 final List<Identifier> typeParams; |
| 1527 |
1502 /// Field declarations of this class (TypeScript / ES6_TYPED). | 1528 /// Field declarations of this class (TypeScript / ES6_TYPED). |
1503 final List<VariableDeclarationList> fields; | 1529 final List<VariableDeclarationList> fields; |
1504 | 1530 |
1505 ClassExpression(this.name, this.heritage, this.methods, | 1531 ClassExpression(this.name, this.heritage, this.methods, |
1506 {this.typeParams, this.fields}); | 1532 {this.typeParams, this.fields}); |
1507 | 1533 |
1508 accept(NodeVisitor visitor) => visitor.visitClassExpression(this); | 1534 accept(NodeVisitor visitor) => visitor.visitClassExpression(this); |
1509 | 1535 |
1510 void visitChildren(NodeVisitor visitor) { | 1536 void visitChildren(NodeVisitor visitor) { |
1511 name.accept(visitor); | 1537 name.accept(visitor); |
1512 if (heritage != null) heritage.accept(visitor); | 1538 if (heritage != null) heritage.accept(visitor); |
1513 for (Method element in methods) element.accept(visitor); | 1539 for (Method element in methods) element.accept(visitor); |
1514 if (fields != null) { | 1540 if (fields != null) { |
1515 for (var field in fields) { | 1541 for (var field in fields) { |
1516 field.accept(visitor); | 1542 field.accept(visitor); |
1517 } | 1543 } |
1518 } | 1544 } |
1519 if (typeParams != null) { | 1545 if (typeParams != null) { |
1520 for (var typeParam in typeParams) { | 1546 for (var typeParam in typeParams) { |
1521 typeParam.accept(visitor); | 1547 typeParam.accept(visitor); |
1522 } | 1548 } |
1523 } | 1549 } |
1524 } | 1550 } |
1525 | 1551 |
1526 ClassExpression _clone() => new ClassExpression( | 1552 ClassExpression _clone() => new ClassExpression(name, heritage, methods, |
1527 name, heritage, methods, typeParams: typeParams, fields: fields); | 1553 typeParams: typeParams, fields: fields); |
1528 | 1554 |
1529 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; | 1555 int get precedenceLevel => PRIMARY_LOW_PRECEDENCE; |
1530 } | 1556 } |
1531 | 1557 |
1532 class Method extends Property { | 1558 class Method extends Property { |
1533 final bool isGetter; | 1559 final bool isGetter; |
1534 final bool isSetter; | 1560 final bool isSetter; |
1535 final bool isStatic; | 1561 final bool isStatic; |
1536 | 1562 |
1537 Method(Expression name, Fun function, | 1563 Method(Expression name, Fun function, |
(...skipping 25 matching lines...) Expand all Loading... |
1563 bool get isPositional => nameOrPosition is int; | 1589 bool get isPositional => nameOrPosition is int; |
1564 } | 1590 } |
1565 | 1591 |
1566 class InterpolatedExpression extends Expression with InterpolatedNode { | 1592 class InterpolatedExpression extends Expression with InterpolatedNode { |
1567 final nameOrPosition; | 1593 final nameOrPosition; |
1568 | 1594 |
1569 InterpolatedExpression(this.nameOrPosition); | 1595 InterpolatedExpression(this.nameOrPosition); |
1570 | 1596 |
1571 accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this); | 1597 accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this); |
1572 void visitChildren(NodeVisitor visitor) {} | 1598 void visitChildren(NodeVisitor visitor) {} |
1573 InterpolatedExpression _clone() => | 1599 InterpolatedExpression _clone() => new InterpolatedExpression(nameOrPosition); |
1574 new InterpolatedExpression(nameOrPosition); | |
1575 | 1600 |
1576 int get precedenceLevel => PRIMARY; | 1601 int get precedenceLevel => PRIMARY; |
1577 } | 1602 } |
1578 | 1603 |
1579 class InterpolatedLiteral extends Literal with InterpolatedNode { | 1604 class InterpolatedLiteral extends Literal with InterpolatedNode { |
1580 final nameOrPosition; | 1605 final nameOrPosition; |
1581 | 1606 |
1582 InterpolatedLiteral(this.nameOrPosition); | 1607 InterpolatedLiteral(this.nameOrPosition); |
1583 | 1608 |
1584 accept(NodeVisitor visitor) => visitor.visitInterpolatedLiteral(this); | 1609 accept(NodeVisitor visitor) => visitor.visitInterpolatedLiteral(this); |
1585 void visitChildren(NodeVisitor visitor) {} | 1610 void visitChildren(NodeVisitor visitor) {} |
1586 InterpolatedLiteral _clone() => new InterpolatedLiteral(nameOrPosition); | 1611 InterpolatedLiteral _clone() => new InterpolatedLiteral(nameOrPosition); |
1587 } | 1612 } |
1588 | 1613 |
1589 class InterpolatedParameter extends Expression with InterpolatedNode | 1614 class InterpolatedParameter extends Expression |
| 1615 with InterpolatedNode |
1590 implements Identifier { | 1616 implements Identifier { |
1591 final nameOrPosition; | 1617 final nameOrPosition; |
1592 TypeRef get type => null; | 1618 TypeRef get type => null; |
1593 | 1619 |
1594 String get name { throw "InterpolatedParameter.name must not be invoked"; } | 1620 String get name { |
| 1621 throw "InterpolatedParameter.name must not be invoked"; |
| 1622 } |
| 1623 |
1595 bool get allowRename => false; | 1624 bool get allowRename => false; |
1596 | 1625 |
1597 InterpolatedParameter(this.nameOrPosition); | 1626 InterpolatedParameter(this.nameOrPosition); |
1598 | 1627 |
1599 accept(NodeVisitor visitor) => visitor.visitInterpolatedParameter(this); | 1628 accept(NodeVisitor visitor) => visitor.visitInterpolatedParameter(this); |
1600 void visitChildren(NodeVisitor visitor) {} | 1629 void visitChildren(NodeVisitor visitor) {} |
1601 InterpolatedParameter _clone() => new InterpolatedParameter(nameOrPosition); | 1630 InterpolatedParameter _clone() => new InterpolatedParameter(nameOrPosition); |
1602 | 1631 |
1603 int get precedenceLevel => PRIMARY; | 1632 int get precedenceLevel => PRIMARY; |
1604 } | 1633 } |
(...skipping 14 matching lines...) Expand all Loading... |
1619 final nameOrPosition; | 1648 final nameOrPosition; |
1620 | 1649 |
1621 InterpolatedStatement(this.nameOrPosition); | 1650 InterpolatedStatement(this.nameOrPosition); |
1622 | 1651 |
1623 accept(NodeVisitor visitor) => visitor.visitInterpolatedStatement(this); | 1652 accept(NodeVisitor visitor) => visitor.visitInterpolatedStatement(this); |
1624 void visitChildren(NodeVisitor visitor) {} | 1653 void visitChildren(NodeVisitor visitor) {} |
1625 InterpolatedStatement _clone() => new InterpolatedStatement(nameOrPosition); | 1654 InterpolatedStatement _clone() => new InterpolatedStatement(nameOrPosition); |
1626 } | 1655 } |
1627 | 1656 |
1628 // TODO(jmesserly): generalize this to InterpolatedProperty? | 1657 // TODO(jmesserly): generalize this to InterpolatedProperty? |
1629 class InterpolatedMethod extends Expression with InterpolatedNode | 1658 class InterpolatedMethod extends Expression |
| 1659 with InterpolatedNode |
1630 implements Method { | 1660 implements Method { |
1631 final nameOrPosition; | 1661 final nameOrPosition; |
1632 | 1662 |
1633 InterpolatedMethod(this.nameOrPosition); | 1663 InterpolatedMethod(this.nameOrPosition); |
1634 | 1664 |
1635 accept(NodeVisitor visitor) => visitor.visitInterpolatedMethod(this); | 1665 accept(NodeVisitor visitor) => visitor.visitInterpolatedMethod(this); |
1636 void visitChildren(NodeVisitor visitor) {} | 1666 void visitChildren(NodeVisitor visitor) {} |
1637 InterpolatedMethod _clone() => new InterpolatedMethod(nameOrPosition); | 1667 InterpolatedMethod _clone() => new InterpolatedMethod(nameOrPosition); |
1638 | 1668 |
1639 int get precedenceLevel => PRIMARY; | 1669 int get precedenceLevel => PRIMARY; |
1640 Expression get name => _unsupported; | 1670 Expression get name => _unsupported; |
1641 Expression get value => _unsupported; | 1671 Expression get value => _unsupported; |
1642 bool get isGetter => _unsupported; | 1672 bool get isGetter => _unsupported; |
1643 bool get isSetter => _unsupported; | 1673 bool get isSetter => _unsupported; |
1644 bool get isStatic => _unsupported; | 1674 bool get isStatic => _unsupported; |
1645 Fun get function => _unsupported; | 1675 Fun get function => _unsupported; |
1646 get _unsupported => throw '$runtimeType does not support this member.'; | 1676 get _unsupported => throw '$runtimeType does not support this member.'; |
1647 } | 1677 } |
1648 | 1678 |
1649 class InterpolatedIdentifier extends Expression with InterpolatedNode | 1679 class InterpolatedIdentifier extends Expression |
| 1680 with InterpolatedNode |
1650 implements Identifier { | 1681 implements Identifier { |
1651 final nameOrPosition; | 1682 final nameOrPosition; |
1652 TypeRef get type => null; | 1683 TypeRef get type => null; |
1653 | 1684 |
1654 InterpolatedIdentifier(this.nameOrPosition); | 1685 InterpolatedIdentifier(this.nameOrPosition); |
1655 | 1686 |
1656 accept(NodeVisitor visitor) => | 1687 accept(NodeVisitor visitor) => visitor.visitInterpolatedIdentifier(this); |
1657 visitor.visitInterpolatedIdentifier(this); | |
1658 void visitChildren(NodeVisitor visitor) {} | 1688 void visitChildren(NodeVisitor visitor) {} |
1659 InterpolatedIdentifier _clone() => new InterpolatedIdentifier(nameOrPosition); | 1689 InterpolatedIdentifier _clone() => new InterpolatedIdentifier(nameOrPosition); |
1660 | 1690 |
1661 int get precedenceLevel => PRIMARY; | 1691 int get precedenceLevel => PRIMARY; |
1662 String get name => throw '$runtimeType does not support this member.'; | 1692 String get name => throw '$runtimeType does not support this member.'; |
1663 bool get allowRename => false; | 1693 bool get allowRename => false; |
1664 } | 1694 } |
1665 | 1695 |
1666 /** | 1696 /** |
1667 * [RegExpLiteral]s, despite being called "Literal", do not inherit from | 1697 * [RegExpLiteral]s, despite being called "Literal", do not inherit from |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 | 1781 |
1752 ImportDeclaration({this.defaultBinding, this.namedImports, this.from}) { | 1782 ImportDeclaration({this.defaultBinding, this.namedImports, this.from}) { |
1753 assert(from != null); | 1783 assert(from != null); |
1754 } | 1784 } |
1755 | 1785 |
1756 /** The `import "name.js"` form of import */ | 1786 /** The `import "name.js"` form of import */ |
1757 ImportDeclaration.all(LiteralString module) : this(from: module); | 1787 ImportDeclaration.all(LiteralString module) : this(from: module); |
1758 | 1788 |
1759 /** If this import has `* as name` returns the name, otherwise null. */ | 1789 /** If this import has `* as name` returns the name, otherwise null. */ |
1760 Identifier get importStarAs { | 1790 Identifier get importStarAs { |
1761 if (namedImports != null && namedImports.length == 1 && | 1791 if (namedImports != null && |
| 1792 namedImports.length == 1 && |
1762 namedImports[0].isStar) { | 1793 namedImports[0].isStar) { |
1763 return namedImports[0].asName; | 1794 return namedImports[0].asName; |
1764 } | 1795 } |
1765 return null; | 1796 return null; |
1766 } | 1797 } |
1767 | 1798 |
1768 accept(NodeVisitor visitor) => visitor.visitImportDeclaration(this); | 1799 accept(NodeVisitor visitor) => visitor.visitImportDeclaration(this); |
1769 void visitChildren(NodeVisitor visitor) { | 1800 void visitChildren(NodeVisitor visitor) { |
1770 if (namedImports != null) { | 1801 if (namedImports != null) { |
1771 for (NameSpecifier name in namedImports) name.accept(visitor); | 1802 for (NameSpecifier name in namedImports) name.accept(visitor); |
1772 } | 1803 } |
1773 from.accept(visitor); | 1804 from.accept(visitor); |
1774 } | 1805 } |
| 1806 |
1775 ImportDeclaration _clone() => new ImportDeclaration( | 1807 ImportDeclaration _clone() => new ImportDeclaration( |
1776 defaultBinding: defaultBinding, namedImports: namedImports, from: from); | 1808 defaultBinding: defaultBinding, namedImports: namedImports, from: from); |
1777 } | 1809 } |
1778 | 1810 |
1779 class ExportDeclaration extends ModuleItem { | 1811 class ExportDeclaration extends ModuleItem { |
1780 /** | 1812 /** |
1781 * Exports a name from this module. | 1813 * Exports a name from this module. |
1782 * | 1814 * |
1783 * This can be a [ClassDeclaration] or [FunctionDeclaration]. | 1815 * This can be a [ClassDeclaration] or [FunctionDeclaration]. |
1784 * If [isDefault] is true, it can also be an [Expression]. | 1816 * If [isDefault] is true, it can also be an [Expression]. |
1785 * Otherwise it can be a [VariableDeclarationList] or an [ExportClause]. | 1817 * Otherwise it can be a [VariableDeclarationList] or an [ExportClause]. |
1786 */ | 1818 */ |
1787 final Node exported; | 1819 final Node exported; |
1788 | 1820 |
1789 /** True if this is an `export default`. */ | 1821 /** True if this is an `export default`. */ |
1790 final bool isDefault; | 1822 final bool isDefault; |
1791 | 1823 |
1792 ExportDeclaration(this.exported, {this.isDefault: false}) { | 1824 ExportDeclaration(this.exported, {this.isDefault: false}) { |
1793 assert(exported is ClassDeclaration || | 1825 assert(exported is ClassDeclaration || |
1794 exported is FunctionDeclaration || | 1826 exported is FunctionDeclaration || |
1795 isDefault | 1827 isDefault |
1796 ? exported is Expression | 1828 ? exported is Expression |
1797 : exported is VariableDeclarationList || | 1829 : exported is VariableDeclarationList || exported is ExportClause); |
1798 exported is ExportClause); | |
1799 } | 1830 } |
1800 | 1831 |
1801 /// Gets the list of names exported by this export declaration, or `null` | 1832 /// Gets the list of names exported by this export declaration, or `null` |
1802 /// if this is an `export *`. | 1833 /// if this is an `export *`. |
1803 /// | 1834 /// |
1804 /// This can be useful for lowering to other module formats. | 1835 /// This can be useful for lowering to other module formats. |
1805 List<Identifier> get exportedNames { | 1836 List<Identifier> get exportedNames { |
1806 if (isDefault) return [new Identifier('default')]; | 1837 if (isDefault) return [new Identifier('default')]; |
1807 | 1838 |
1808 var exported = this.exported; | 1839 var exported = this.exported; |
(...skipping 26 matching lines...) Expand all Loading... |
1835 : this([new NameSpecifier.star()], from: from); | 1866 : this([new NameSpecifier.star()], from: from); |
1836 | 1867 |
1837 /** True if this is an `export *`. */ | 1868 /** True if this is an `export *`. */ |
1838 bool get exportStar => exports.length == 1 && exports[0].isStar; | 1869 bool get exportStar => exports.length == 1 && exports[0].isStar; |
1839 | 1870 |
1840 accept(NodeVisitor visitor) => visitor.visitExportClause(this); | 1871 accept(NodeVisitor visitor) => visitor.visitExportClause(this); |
1841 void visitChildren(NodeVisitor visitor) { | 1872 void visitChildren(NodeVisitor visitor) { |
1842 for (NameSpecifier name in exports) name.accept(visitor); | 1873 for (NameSpecifier name in exports) name.accept(visitor); |
1843 if (from != null) from.accept(visitor); | 1874 if (from != null) from.accept(visitor); |
1844 } | 1875 } |
| 1876 |
1845 ExportClause _clone() => new ExportClause(exports, from: from); | 1877 ExportClause _clone() => new ExportClause(exports, from: from); |
1846 } | 1878 } |
1847 | 1879 |
1848 /** An import or export specifier. */ | 1880 /** An import or export specifier. */ |
1849 class NameSpecifier extends Node { | 1881 class NameSpecifier extends Node { |
1850 final Identifier name; | 1882 final Identifier name; |
1851 final Identifier asName; // Can be null. | 1883 final Identifier asName; // Can be null. |
1852 | 1884 |
1853 NameSpecifier(this.name, {this.asName}); | 1885 NameSpecifier(this.name, {this.asName}); |
1854 NameSpecifier.star() : this(null); | 1886 NameSpecifier.star() : this(null); |
(...skipping 13 matching lines...) Expand all Loading... |
1868 // We use this because some ES5 desugarings require it. | 1900 // We use this because some ES5 desugarings require it. |
1869 final String name; | 1901 final String name; |
1870 | 1902 |
1871 final List<ModuleItem> body; | 1903 final List<ModuleItem> body; |
1872 Module(this.body, {this.name}); | 1904 Module(this.body, {this.name}); |
1873 | 1905 |
1874 accept(NodeVisitor visitor) => visitor.visitModule(this); | 1906 accept(NodeVisitor visitor) => visitor.visitModule(this); |
1875 void visitChildren(NodeVisitor visitor) { | 1907 void visitChildren(NodeVisitor visitor) { |
1876 for (ModuleItem item in body) item.accept(visitor); | 1908 for (ModuleItem item in body) item.accept(visitor); |
1877 } | 1909 } |
| 1910 |
1878 Module _clone() => new Module(body); | 1911 Module _clone() => new Module(body); |
1879 } | 1912 } |
OLD | NEW |