| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 backend_ast_emitter; | 5 library backend_ast_emitter; |
| 6 | 6 |
| 7 import 'tree_ir_nodes.dart' as tree; | 7 import 'tree_ir_nodes.dart' as tree; |
| 8 import 'backend_ast_nodes.dart'; | 8 import 'backend_ast_nodes.dart'; |
| 9 import '../dart2jslib.dart' as dart2js; | 9 import '../dart2jslib.dart' as dart2js; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| (...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 } | 665 } |
| 666 | 666 |
| 667 Expression emitConstant(ConstExp exp) => new ConstantEmitter(this).visit(exp); | 667 Expression emitConstant(ConstExp exp) => new ConstantEmitter(this).visit(exp); |
| 668 | 668 |
| 669 } | 669 } |
| 670 | 670 |
| 671 class ConstantEmitter extends ConstExpVisitor<Expression> { | 671 class ConstantEmitter extends ConstExpVisitor<Expression> { |
| 672 ASTEmitter parent; | 672 ASTEmitter parent; |
| 673 ConstantEmitter(this.parent); | 673 ConstantEmitter(this.parent); |
| 674 | 674 |
| 675 Expression visitPrimitive(PrimitiveConstExp exp) { | 675 Expression handlePrimitiveConstant(dart2js.PrimitiveConstant value) { |
| 676 // Num constants may be negative, while literals must be non-negative: | 676 // Num constants may be negative, while literals must be non-negative: |
| 677 // Literals are non-negative in the specification, and a negated literal | 677 // Literals are non-negative in the specification, and a negated literal |
| 678 // parses as a call to unary `-`. The AST unparser assumes literals are | 678 // parses as a call to unary `-`. The AST unparser assumes literals are |
| 679 // non-negative and relies on this to avoid incorrectly generating `--`, | 679 // non-negative and relies on this to avoid incorrectly generating `--`, |
| 680 // the predecrement operator. | 680 // the predecrement operator. |
| 681 // Translate such constants into their positive value wrapped by | 681 // Translate such constants into their positive value wrapped by |
| 682 // the unary minus operator. | 682 // the unary minus operator. |
| 683 if (exp.constant is dart2js.NumConstant) { | 683 if (value is dart2js.NumConstant) { |
| 684 dart2js.NumConstant numConstant = exp.constant; | 684 dart2js.NumConstant numConstant = value; |
| 685 if (numConstant.value.isNegative) { | 685 if (numConstant.value.isNegative) { |
| 686 return negatedLiteral(numConstant); | 686 return negatedLiteral(numConstant); |
| 687 } | 687 } |
| 688 } | 688 } |
| 689 return new Literal(exp.constant); | 689 return new Literal(value); |
| 690 } |
| 691 |
| 692 @override |
| 693 Expression visitPrimitive(PrimitiveConstExp exp) { |
| 694 return handlePrimitiveConstant(exp.value); |
| 690 } | 695 } |
| 691 | 696 |
| 692 /// Given a negative num constant, returns the corresponding positive | 697 /// Given a negative num constant, returns the corresponding positive |
| 693 /// literal wrapped by a unary minus operator. | 698 /// literal wrapped by a unary minus operator. |
| 694 Expression negatedLiteral(dart2js.NumConstant constant) { | 699 Expression negatedLiteral(dart2js.NumConstant constant) { |
| 695 assert(constant.value.isNegative); | 700 assert(constant.value.isNegative); |
| 696 dart2js.NumConstant positiveConstant; | 701 dart2js.NumConstant positiveConstant; |
| 697 if (constant.isInt) { | 702 if (constant.isInt) { |
| 698 positiveConstant = new dart2js.IntConstant(-constant.value); | 703 positiveConstant = new dart2js.IntConstant(-constant.value); |
| 699 } else if (constant.isDouble) { | 704 } else if (constant.isDouble) { |
| 700 positiveConstant = new dart2js.DoubleConstant(-constant.value); | 705 positiveConstant = new dart2js.DoubleConstant(-constant.value); |
| 701 } else { | 706 } else { |
| 702 throw "Unexpected type of NumConstant: $constant"; | 707 throw "Unexpected type of NumConstant: $constant"; |
| 703 } | 708 } |
| 704 return new UnaryOperator('-', new Literal(positiveConstant)); | 709 return new UnaryOperator('-', new Literal(positiveConstant)); |
| 705 } | 710 } |
| 706 | 711 |
| 712 @override |
| 707 Expression visitList(ListConstExp exp) { | 713 Expression visitList(ListConstExp exp) { |
| 708 return new LiteralList( | 714 return new LiteralList( |
| 709 exp.values.map(visit).toList(growable: false), | 715 exp.values.map(visit).toList(growable: false), |
| 710 isConst: true, | 716 isConst: true, |
| 711 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); | 717 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); |
| 712 } | 718 } |
| 713 | 719 |
| 720 @override |
| 714 Expression visitMap(MapConstExp exp) { | 721 Expression visitMap(MapConstExp exp) { |
| 715 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( | 722 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
| 716 exp.values.length, | 723 exp.values.length, |
| 717 (i) => new LiteralMapEntry(visit(exp.keys[i]), | 724 (i) => new LiteralMapEntry(visit(exp.keys[i]), |
| 718 visit(exp.values[i]))); | 725 visit(exp.values[i]))); |
| 719 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw | 726 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
| 720 ? null | 727 ? null |
| 721 : exp.type.typeArguments.map(parent.emitType).toList(); | 728 : exp.type.typeArguments.map(parent.emitType).toList(); |
| 722 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); | 729 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); |
| 723 } | 730 } |
| 724 | 731 |
| 732 @override |
| 725 Expression visitConstructor(ConstructorConstExp exp) { | 733 Expression visitConstructor(ConstructorConstExp exp) { |
| 726 int positionalArgumentCount = exp.selector.positionalArgumentCount; | 734 int positionalArgumentCount = exp.selector.positionalArgumentCount; |
| 727 List<Argument> args = new List<Argument>.generate( | 735 List<Argument> args = new List<Argument>.generate( |
| 728 positionalArgumentCount, | 736 positionalArgumentCount, |
| 729 (i) => visit(exp.arguments[i])); | 737 (i) => visit(exp.arguments[i])); |
| 730 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 738 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
| 731 args.add(new NamedArgument(exp.selector.namedArguments[i], | 739 args.add(new NamedArgument(exp.selector.namedArguments[i], |
| 732 visit(exp.arguments[positionalArgumentCount + i]))); | 740 visit(exp.arguments[positionalArgumentCount + i]))); |
| 733 } | 741 } |
| 734 | 742 |
| 735 FunctionElement constructor = exp.target; | 743 FunctionElement constructor = exp.target; |
| 736 String name = constructor.name.isEmpty ? null : constructor.name; | 744 String name = constructor.name.isEmpty ? null : constructor.name; |
| 737 return new CallNew(parent.emitType(exp.type), | 745 return new CallNew(parent.emitType(exp.type), |
| 738 args, | 746 args, |
| 739 constructorName: name, | 747 constructorName: name, |
| 740 isConst: true) | 748 isConst: true) |
| 741 ..constructor = constructor | 749 ..constructor = constructor |
| 742 ..dartType = exp.type; | 750 ..dartType = exp.type; |
| 743 } | 751 } |
| 744 | 752 |
| 753 @override |
| 745 Expression visitConcatenate(ConcatenateConstExp exp) { | 754 Expression visitConcatenate(ConcatenateConstExp exp) { |
| 746 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); | 755 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); |
| 747 } | 756 } |
| 748 | 757 |
| 758 @override |
| 749 Expression visitSymbol(SymbolConstExp exp) { | 759 Expression visitSymbol(SymbolConstExp exp) { |
| 750 return new LiteralSymbol(exp.name); | 760 return new LiteralSymbol(exp.name); |
| 751 } | 761 } |
| 752 | 762 |
| 763 @override |
| 753 Expression visitType(TypeConstExp exp) { | 764 Expression visitType(TypeConstExp exp) { |
| 754 DartType type = exp.type; | 765 DartType type = exp.type; |
| 755 return new LiteralType(type.name) | 766 return new LiteralType(type.name) |
| 756 ..type = type; | 767 ..type = type; |
| 757 } | 768 } |
| 758 | 769 |
| 770 @override |
| 759 Expression visitVariable(VariableConstExp exp) { | 771 Expression visitVariable(VariableConstExp exp) { |
| 760 Element element = exp.element; | 772 Element element = exp.element; |
| 761 if (element.kind != ElementKind.VARIABLE) { | 773 if (element.kind != ElementKind.VARIABLE) { |
| 762 return new Identifier(element.name)..element = element; | 774 return new Identifier(element.name)..element = element; |
| 763 } | 775 } |
| 764 String name = parent.getConstantName(element); | 776 String name = parent.getConstantName(element); |
| 765 return new Identifier(name) | 777 return new Identifier(name) |
| 766 ..element = element; | 778 ..element = element; |
| 767 } | 779 } |
| 768 | 780 |
| 781 @override |
| 769 Expression visitFunction(FunctionConstExp exp) { | 782 Expression visitFunction(FunctionConstExp exp) { |
| 770 return new Identifier(exp.element.name) | 783 return new Identifier(exp.element.name) |
| 771 ..element = exp.element; | 784 ..element = exp.element; |
| 772 } | 785 } |
| 773 | 786 |
| 787 @override |
| 788 Expression visitBinary(BinaryConstExp exp) { |
| 789 return handlePrimitiveConstant(exp.value); |
| 790 } |
| 791 |
| 792 @override |
| 793 Expression visitConditional(ConditionalConstExp exp) { |
| 794 if (exp.condition.value.isTrue) { |
| 795 return exp.trueExp.accept(this); |
| 796 } else { |
| 797 return exp.falseExp.accept(this); |
| 798 } |
| 799 } |
| 800 |
| 801 @override |
| 802 Expression visitUnary(UnaryConstExp exp) { |
| 803 return handlePrimitiveConstant(exp.value); |
| 804 } |
| 774 } | 805 } |
| 775 | 806 |
| 776 /// Moves function parameters into a separate variable if one of its uses is | 807 /// Moves function parameters into a separate variable if one of its uses is |
| 777 /// shadowed by an inner function parameter. | 808 /// shadowed by an inner function parameter. |
| 778 /// This artifact is necessary because function parameters cannot be renamed. | 809 /// This artifact is necessary because function parameters cannot be renamed. |
| 779 class UnshadowParameters extends tree.RecursiveVisitor { | 810 class UnshadowParameters extends tree.RecursiveVisitor { |
| 780 | 811 |
| 781 /// Maps parameter names to their bindings. | 812 /// Maps parameter names to their bindings. |
| 782 Map<String, tree.Variable> environment = <String, tree.Variable>{}; | 813 Map<String, tree.Variable> environment = <String, tree.Variable>{}; |
| 783 | 814 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 } | 851 } |
| 821 } | 852 } |
| 822 | 853 |
| 823 visitVariable(tree.Variable variable) { | 854 visitVariable(tree.Variable variable) { |
| 824 if (shadowedParameters.contains(variable)) { | 855 if (shadowedParameters.contains(variable)) { |
| 825 hasShadowedUse.add(variable); | 856 hasShadowedUse.add(variable); |
| 826 } | 857 } |
| 827 } | 858 } |
| 828 | 859 |
| 829 } | 860 } |
| OLD | NEW |