Chromium Code Reviews| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 // `null`? | 215 // `null`? |
| 216 clone.sourceInformation = sourceInformation; | 216 clone.sourceInformation = sourceInformation; |
| 217 return clone; | 217 return clone; |
| 218 } | 218 } |
| 219 | 219 |
| 220 bool get isCommaOperator => false; | 220 bool get isCommaOperator => false; |
| 221 | 221 |
| 222 Statement toStatement() { | 222 Statement toStatement() { |
| 223 throw new UnsupportedError('toStatement'); | 223 throw new UnsupportedError('toStatement'); |
| 224 } | 224 } |
| 225 Statement toReturn() { | |
| 226 throw new UnsupportedError('toReturn'); | |
| 227 } | |
| 228 | |
| 229 // For debugging | |
|
Jennifer Messerly
2015/04/07 22:00:29
it was hard to read js_ast nodes in debugger, comp
| |
| 230 String toString() { | |
| 231 var context = new SimpleJavaScriptPrintingContext(); | |
| 232 var opts = new JavaScriptPrintingOptions(allowKeywordsInProperties: true); | |
| 233 context.buffer.write('js_ast `'); | |
| 234 accept(new Printer(opts, context)); | |
| 235 context.buffer.write('`'); | |
| 236 return context.getText(); | |
| 237 } | |
| 225 } | 238 } |
| 226 | 239 |
| 227 class Program extends Node { | 240 class Program extends Node { |
| 228 final List<Statement> body; | 241 final List<Statement> body; |
| 229 Program(this.body); | 242 Program(this.body); |
| 230 | 243 |
| 231 accept(NodeVisitor visitor) => visitor.visitProgram(this); | 244 accept(NodeVisitor visitor) => visitor.visitProgram(this); |
| 232 void visitChildren(NodeVisitor visitor) { | 245 void visitChildren(NodeVisitor visitor) { |
| 233 for (Statement statement in body) statement.accept(visitor); | 246 for (Statement statement in body) statement.accept(visitor); |
| 234 } | 247 } |
| 235 Program _clone() => new Program(body); | 248 Program _clone() => new Program(body); |
| 236 } | 249 } |
| 237 | 250 |
| 238 abstract class Statement extends Node { | 251 abstract class Statement extends Node { |
| 239 Statement toStatement() => this; | 252 Statement toStatement() => this; |
| 253 Statement toReturn() => new Block([this, new Return()]); | |
| 240 } | 254 } |
| 241 | 255 |
| 242 class Block extends Statement { | 256 class Block extends Statement { |
| 243 final List<Statement> statements; | 257 final List<Statement> statements; |
| 244 Block(this.statements) { | 258 Block(this.statements) { |
| 245 assert(!statements.any((s) => s is! Statement)); | 259 assert(!statements.any((s) => s is! Statement)); |
| 246 } | 260 } |
| 247 Block.empty() : this.statements = <Statement>[]; | 261 Block.empty() : this.statements = <Statement>[]; |
| 248 | 262 |
| 249 accept(NodeVisitor visitor) => visitor.visitBlock(this); | 263 accept(NodeVisitor visitor) => visitor.visitBlock(this); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 void visitChildren(NodeVisitor visitor) {} | 417 void visitChildren(NodeVisitor visitor) {} |
| 404 | 418 |
| 405 Break _clone() => new Break(targetLabel); | 419 Break _clone() => new Break(targetLabel); |
| 406 } | 420 } |
| 407 | 421 |
| 408 class Return extends Statement { | 422 class Return extends Statement { |
| 409 final Expression value; // Can be null. | 423 final Expression value; // Can be null. |
| 410 | 424 |
| 411 Return([this.value = null]); | 425 Return([this.value = null]); |
| 412 | 426 |
| 427 Statement toReturn() => this; | |
| 428 | |
| 413 accept(NodeVisitor visitor) => visitor.visitReturn(this); | 429 accept(NodeVisitor visitor) => visitor.visitReturn(this); |
| 414 | 430 |
| 415 void visitChildren(NodeVisitor visitor) { | 431 void visitChildren(NodeVisitor visitor) { |
| 416 if (value != null) value.accept(visitor); | 432 if (value != null) value.accept(visitor); |
| 417 } | 433 } |
| 418 | 434 |
| 419 Return _clone() => new Return(value); | 435 Return _clone() => new Return(value); |
| 420 } | 436 } |
| 421 | 437 |
| 422 class Throw extends Statement { | 438 class Throw extends Statement { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 accept(NodeVisitor visitor) => visitor.visitDartYield(this); | 588 accept(NodeVisitor visitor) => visitor.visitDartYield(this); |
| 573 | 589 |
| 574 void visitChildren(NodeVisitor visitor) { | 590 void visitChildren(NodeVisitor visitor) { |
| 575 expression.accept(visitor); | 591 expression.accept(visitor); |
| 576 } | 592 } |
| 577 | 593 |
| 578 DartYield _clone() => new DartYield(expression, hasStar); | 594 DartYield _clone() => new DartYield(expression, hasStar); |
| 579 } | 595 } |
| 580 | 596 |
| 581 abstract class Expression extends Node { | 597 abstract class Expression extends Node { |
| 598 Expression(); | |
| 599 | |
| 600 factory Expression.binary(List<Expression> exprs, String op) { | |
| 601 Expression comma = null; | |
| 602 for (var node in exprs) { | |
| 603 comma = (comma == null) ? node : new Binary(op, comma, node); | |
| 604 } | |
| 605 return comma; | |
| 606 } | |
| 607 | |
| 582 int get precedenceLevel; | 608 int get precedenceLevel; |
| 583 | 609 |
| 584 Statement toStatement() => new ExpressionStatement(this); | 610 Statement toStatement() => new ExpressionStatement(toVoidExpression()); |
| 611 Statement toReturn() => new Return(this); | |
| 612 | |
| 613 Expression toVoidExpression() => this; | |
| 614 Expression toAssignExpression(Expression left) => new Assignment(left, this); | |
| 615 Statement toVariableDeclaration(Identifier name) => | |
| 616 new VariableDeclarationList('let', | |
| 617 [new VariableInitialization(name, this)]).toStatement(); | |
| 585 } | 618 } |
| 586 | 619 |
| 587 class LiteralExpression extends Expression { | 620 class LiteralExpression extends Expression { |
| 588 final String template; | 621 final String template; |
| 589 final List<Expression> inputs; | 622 final List<Expression> inputs; |
| 590 | 623 |
| 591 LiteralExpression(this.template) : inputs = const []; | 624 LiteralExpression(this.template) : inputs = const []; |
| 592 LiteralExpression.withData(this.template, this.inputs); | 625 LiteralExpression.withData(this.template, this.inputs); |
| 593 | 626 |
| 594 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this); | 627 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 728 | 761 |
| 729 Binary _clone() => new Binary(op, left, right); | 762 Binary _clone() => new Binary(op, left, right); |
| 730 | 763 |
| 731 void visitChildren(NodeVisitor visitor) { | 764 void visitChildren(NodeVisitor visitor) { |
| 732 left.accept(visitor); | 765 left.accept(visitor); |
| 733 right.accept(visitor); | 766 right.accept(visitor); |
| 734 } | 767 } |
| 735 | 768 |
| 736 bool get isCommaOperator => op == ','; | 769 bool get isCommaOperator => op == ','; |
| 737 | 770 |
| 771 Expression toVoidExpression() { | |
| 772 if (!isCommaOperator) return super.toVoidExpression(); | |
|
Leaf
2015/04/08 04:08:34
It almost feels like it would be worth having a Co
Jennifer Messerly
2015/04/08 16:35:46
Yeah, I agree. So far I was trying to maintain com
| |
| 773 var l = left.toVoidExpression(); | |
| 774 var r = right.toVoidExpression(); | |
| 775 if (l == left && r == right) return this; | |
| 776 return new Binary(',', l, r); | |
| 777 } | |
| 778 | |
| 779 Statement toStatement() { | |
| 780 if (!isCommaOperator) return super.toStatement(); | |
| 781 return new Block([left.toStatement(), right.toStatement()]); | |
| 782 } | |
| 783 | |
| 784 Statement toReturn() { | |
| 785 if (!isCommaOperator) return super.toReturn(); | |
| 786 return new Block([left.toStatement(), right.toReturn()]); | |
| 787 } | |
| 788 | |
| 789 List<Expression> commaToExpressionList() { | |
| 790 if (!isCommaOperator) throw new StateError('not a comma expression'); | |
| 791 var exprs = []; | |
| 792 _flattenComma(exprs, left); | |
| 793 _flattenComma(exprs, right); | |
| 794 return exprs; | |
| 795 } | |
| 796 | |
| 797 static void _flattenComma(List<Expression> exprs, Expression node) { | |
| 798 if (node is Binary && node.isCommaOperator) { | |
| 799 _flattenComma(exprs, node.left); | |
| 800 _flattenComma(exprs, node.right); | |
| 801 } else { | |
| 802 exprs.add(node); | |
| 803 } | |
| 804 } | |
| 805 | |
| 738 int get precedenceLevel { | 806 int get precedenceLevel { |
| 739 // TODO(floitsch): switch to constant map. | 807 // TODO(floitsch): switch to constant map. |
| 740 switch (op) { | 808 switch (op) { |
| 741 case "*": | 809 case "*": |
| 742 case "/": | 810 case "/": |
| 743 case "%": | 811 case "%": |
| 744 return MULTIPLICATIVE; | 812 return MULTIPLICATIVE; |
| 745 case "+": | 813 case "+": |
| 746 case "-": | 814 case "-": |
| 747 return ADDITIVE; | 815 return ADDITIVE; |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 final Expression expression; | 1431 final Expression expression; |
| 1364 | 1432 |
| 1365 CommentExpression(this.comment, this.expression); | 1433 CommentExpression(this.comment, this.expression); |
| 1366 | 1434 |
| 1367 int get precedenceLevel => PRIMARY; | 1435 int get precedenceLevel => PRIMARY; |
| 1368 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); | 1436 accept(NodeVisitor visitor) => visitor.visitCommentExpression(this); |
| 1369 CommentExpression _clone() => new CommentExpression(comment, expression); | 1437 CommentExpression _clone() => new CommentExpression(comment, expression); |
| 1370 | 1438 |
| 1371 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); | 1439 void visitChildren(NodeVisitor visitor) => expression.accept(visitor); |
| 1372 } | 1440 } |
| OLD | NEW |