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 '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../constants/values.dart' as values; | 10 import '../constants/values.dart'; |
11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../elements/modelx.dart' as modelx; | 13 import '../elements/modelx.dart' as modelx; |
14 import '../universe/universe.dart'; | 14 import '../universe/universe.dart'; |
15 import '../tree/tree.dart' as tree show Modifiers; | 15 import '../tree/tree.dart' as tree show Modifiers; |
16 | 16 |
17 /// Translates the dart_tree IR to Dart backend AST. | 17 /// Translates the dart_tree IR to Dart backend AST. |
18 Expression emit(tree.FunctionDefinition definition) { | 18 Expression emit(tree.FunctionDefinition definition) { |
19 return new ASTEmitter().emit(definition); | 19 return new ASTEmitter().emit(definition); |
20 } | 20 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 return new Parameters( | 175 return new Parameters( |
176 signature.requiredParameters.mapToList(emitParameterFromElement), | 176 signature.requiredParameters.mapToList(emitParameterFromElement), |
177 signature.optionalParameters.mapToList(emitParameterFromElement), | 177 signature.optionalParameters.mapToList(emitParameterFromElement), |
178 signature.optionalParametersAreNamed); | 178 signature.optionalParametersAreNamed); |
179 } | 179 } |
180 | 180 |
181 /// Emits parameters that are not nested inside other parameters. | 181 /// Emits parameters that are not nested inside other parameters. |
182 /// Root parameters can have default values, while inner parameters cannot. | 182 /// Root parameters can have default values, while inner parameters cannot. |
183 Parameters emitRootParameters(tree.FunctionDefinition function) { | 183 Parameters emitRootParameters(tree.FunctionDefinition function) { |
184 FunctionSignature signature = function.element.functionSignature; | 184 FunctionSignature signature = function.element.functionSignature; |
185 List<ConstExp> defaults = function.defaultParameterValues; | 185 List<ConstantExpression> defaults = function.defaultParameterValues; |
186 List<Parameter> required = | 186 List<Parameter> required = |
187 signature.requiredParameters.mapToList(emitParameterFromElement); | 187 signature.requiredParameters.mapToList(emitParameterFromElement); |
188 List<Parameter> optional = new List<Parameter>(defaults.length); | 188 List<Parameter> optional = new List<Parameter>(defaults.length); |
189 for (int i = 0; i < defaults.length; i++) { | 189 for (int i = 0; i < defaults.length; i++) { |
190 ParameterElement element = signature.orderedOptionalParameters[i]; | 190 ParameterElement element = signature.orderedOptionalParameters[i]; |
191 optional[i] = emitParameterFromElement(element); | 191 optional[i] = emitParameterFromElement(element); |
192 Expression constant = emitConstant(defaults[i]); | 192 Expression constant = emitConstant(defaults[i]); |
193 if (!isNullLiteral(constant)) { | 193 if (!isNullLiteral(constant)) { |
194 optional[i].defaultValue = constant; | 194 optional[i].defaultValue = constant; |
195 } | 195 } |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 } | 414 } |
415 | 415 |
416 void visitWhileTrue(tree.WhileTrue stmt) { | 416 void visitWhileTrue(tree.WhileTrue stmt) { |
417 List<Statement> savedBuffer = statementBuffer; | 417 List<Statement> savedBuffer = statementBuffer; |
418 tree.Statement savedFallthrough = fallthrough; | 418 tree.Statement savedFallthrough = fallthrough; |
419 statementBuffer = <Statement>[]; | 419 statementBuffer = <Statement>[]; |
420 fallthrough = stmt; | 420 fallthrough = stmt; |
421 | 421 |
422 visitStatement(stmt.body); | 422 visitStatement(stmt.body); |
423 Statement body = new Block(statementBuffer); | 423 Statement body = new Block(statementBuffer); |
424 Statement statement = new While(new Literal(new values.TrueConstant()), | 424 Statement statement = new While(new Literal(new TrueConstantValue()), |
425 body); | 425 body); |
426 if (usedLabels.remove(stmt.label)) { | 426 if (usedLabels.remove(stmt.label)) { |
427 statement = new LabeledStatement(stmt.label.name, statement); | 427 statement = new LabeledStatement(stmt.label.name, statement); |
428 } | 428 } |
429 savedBuffer.add(statement); | 429 savedBuffer.add(statement); |
430 | 430 |
431 statementBuffer = savedBuffer; | 431 statementBuffer = savedBuffer; |
432 fallthrough = savedFallthrough; | 432 fallthrough = savedFallthrough; |
433 } | 433 } |
434 | 434 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 | 657 |
658 /// Like [emitType] except the dynamic type is converted to null. | 658 /// Like [emitType] except the dynamic type is converted to null. |
659 TypeAnnotation emitOptionalType(DartType type) { | 659 TypeAnnotation emitOptionalType(DartType type) { |
660 if (type.treatAsDynamic) { | 660 if (type.treatAsDynamic) { |
661 return null; | 661 return null; |
662 } else { | 662 } else { |
663 return emitType(type); | 663 return emitType(type); |
664 } | 664 } |
665 } | 665 } |
666 | 666 |
667 Expression emitConstant(ConstExp exp) => new ConstantEmitter(this).visit(exp); | 667 Expression emitConstant(ConstantExpression exp) { |
668 | 668 return new ConstantEmitter(this).visit(exp); |
| 669 } |
669 } | 670 } |
670 | 671 |
671 class ConstantEmitter extends ConstExpVisitor<Expression> { | 672 class ConstantEmitter extends ConstantExpressionVisitor<Expression> { |
672 ASTEmitter parent; | 673 ASTEmitter parent; |
673 ConstantEmitter(this.parent); | 674 ConstantEmitter(this.parent); |
674 | 675 |
675 Expression handlePrimitiveConstant(values.PrimitiveConstant value) { | 676 Expression handlePrimitiveConstant(PrimitiveConstantValue value) { |
676 // Num constants may be negative, while literals must be non-negative: | 677 // Num constants may be negative, while literals must be non-negative: |
677 // Literals are non-negative in the specification, and a negated literal | 678 // Literals are non-negative in the specification, and a negated literal |
678 // parses as a call to unary `-`. The AST unparser assumes literals are | 679 // parses as a call to unary `-`. The AST unparser assumes literals are |
679 // non-negative and relies on this to avoid incorrectly generating `--`, | 680 // non-negative and relies on this to avoid incorrectly generating `--`, |
680 // the predecrement operator. | 681 // the predecrement operator. |
681 // Translate such constants into their positive value wrapped by | 682 // Translate such constants into their positive value wrapped by |
682 // the unary minus operator. | 683 // the unary minus operator. |
683 if (value.isNum) { | 684 if (value.isNum) { |
684 values.NumConstant numConstant = value; | 685 NumConstantValue numConstant = value; |
685 if (numConstant.value.isNegative) { | 686 if (numConstant.primitiveValue.isNegative) { |
686 return negatedLiteral(numConstant); | 687 return negatedLiteral(numConstant); |
687 } | 688 } |
688 } | 689 } |
689 return new Literal(value); | 690 return new Literal(value); |
690 } | 691 } |
691 | 692 |
692 @override | 693 @override |
693 Expression visitPrimitive(PrimitiveConstExp exp) { | 694 Expression visitPrimitive(PrimitiveConstantExpression exp) { |
694 return handlePrimitiveConstant(exp.value); | 695 return handlePrimitiveConstant(exp.value); |
695 } | 696 } |
696 | 697 |
697 /// Given a negative num constant, returns the corresponding positive | 698 /// Given a negative num constant, returns the corresponding positive |
698 /// literal wrapped by a unary minus operator. | 699 /// literal wrapped by a unary minus operator. |
699 Expression negatedLiteral(values.NumConstant constant) { | 700 Expression negatedLiteral(NumConstantValue constant) { |
700 assert(constant.value.isNegative); | 701 assert(constant.primitiveValue.isNegative); |
701 values.NumConstant positiveConstant; | 702 NumConstantValue positiveConstant; |
702 if (constant.isInt) { | 703 if (constant.isInt) { |
703 positiveConstant = new values.IntConstant(-constant.value); | 704 positiveConstant = new IntConstantValue(-constant.primitiveValue); |
704 } else if (constant.isDouble) { | 705 } else if (constant.isDouble) { |
705 positiveConstant = new values.DoubleConstant(-constant.value); | 706 positiveConstant = new DoubleConstantValue(-constant.primitiveValue); |
706 } else { | 707 } else { |
707 throw "Unexpected type of NumConstant: $constant"; | 708 throw "Unexpected type of NumConstant: $constant"; |
708 } | 709 } |
709 return new UnaryOperator('-', new Literal(positiveConstant)); | 710 return new UnaryOperator('-', new Literal(positiveConstant)); |
710 } | 711 } |
711 | 712 |
712 @override | 713 @override |
713 Expression visitList(ListConstExp exp) { | 714 Expression visitList(ListConstantExpression exp) { |
714 return new LiteralList( | 715 return new LiteralList( |
715 exp.values.map(visit).toList(growable: false), | 716 exp.values.map(visit).toList(growable: false), |
716 isConst: true, | 717 isConst: true, |
717 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); | 718 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); |
718 } | 719 } |
719 | 720 |
720 @override | 721 @override |
721 Expression visitMap(MapConstExp exp) { | 722 Expression visitMap(MapConstantExpression exp) { |
722 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( | 723 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
723 exp.values.length, | 724 exp.values.length, |
724 (i) => new LiteralMapEntry(visit(exp.keys[i]), | 725 (i) => new LiteralMapEntry(visit(exp.keys[i]), |
725 visit(exp.values[i]))); | 726 visit(exp.values[i]))); |
726 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw | 727 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
727 ? null | 728 ? null |
728 : exp.type.typeArguments.map(parent.emitType).toList(); | 729 : exp.type.typeArguments.map(parent.emitType).toList(); |
729 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); | 730 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); |
730 } | 731 } |
731 | 732 |
732 @override | 733 @override |
733 Expression visitConstructor(ConstructorConstExp exp) { | 734 Expression visitConstructor(ConstructedConstantExpresssion exp) { |
734 int positionalArgumentCount = exp.selector.positionalArgumentCount; | 735 int positionalArgumentCount = exp.selector.positionalArgumentCount; |
735 List<Argument> args = new List<Argument>.generate( | 736 List<Argument> args = new List<Argument>.generate( |
736 positionalArgumentCount, | 737 positionalArgumentCount, |
737 (i) => visit(exp.arguments[i])); | 738 (i) => visit(exp.arguments[i])); |
738 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 739 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
739 args.add(new NamedArgument(exp.selector.namedArguments[i], | 740 args.add(new NamedArgument(exp.selector.namedArguments[i], |
740 visit(exp.arguments[positionalArgumentCount + i]))); | 741 visit(exp.arguments[positionalArgumentCount + i]))); |
741 } | 742 } |
742 | 743 |
743 FunctionElement constructor = exp.target; | 744 FunctionElement constructor = exp.target; |
744 String name = constructor.name.isEmpty ? null : constructor.name; | 745 String name = constructor.name.isEmpty ? null : constructor.name; |
745 return new CallNew(parent.emitType(exp.type), | 746 return new CallNew(parent.emitType(exp.type), |
746 args, | 747 args, |
747 constructorName: name, | 748 constructorName: name, |
748 isConst: true) | 749 isConst: true) |
749 ..constructor = constructor | 750 ..constructor = constructor |
750 ..dartType = exp.type; | 751 ..dartType = exp.type; |
751 } | 752 } |
752 | 753 |
753 @override | 754 @override |
754 Expression visitConcatenate(ConcatenateConstExp exp) { | 755 Expression visitConcatenate(ConcatenateConstantExpression exp) { |
755 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); | 756 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); |
756 } | 757 } |
757 | 758 |
758 @override | 759 @override |
759 Expression visitSymbol(SymbolConstExp exp) { | 760 Expression visitSymbol(SymbolConstantExpression exp) { |
760 return new LiteralSymbol(exp.name); | 761 return new LiteralSymbol(exp.name); |
761 } | 762 } |
762 | 763 |
763 @override | 764 @override |
764 Expression visitType(TypeConstExp exp) { | 765 Expression visitType(TypeConstantExpression exp) { |
765 DartType type = exp.type; | 766 DartType type = exp.type; |
766 return new LiteralType(type.name) | 767 return new LiteralType(type.name) |
767 ..type = type; | 768 ..type = type; |
768 } | 769 } |
769 | 770 |
770 @override | 771 @override |
771 Expression visitVariable(VariableConstExp exp) { | 772 Expression visitVariable(VariableConstantExpression exp) { |
772 Element element = exp.element; | 773 Element element = exp.element; |
773 if (element.kind != ElementKind.VARIABLE) { | 774 if (element.kind != ElementKind.VARIABLE) { |
774 return new Identifier(element.name)..element = element; | 775 return new Identifier(element.name)..element = element; |
775 } | 776 } |
776 String name = parent.getConstantName(element); | 777 String name = parent.getConstantName(element); |
777 return new Identifier(name) | 778 return new Identifier(name) |
778 ..element = element; | 779 ..element = element; |
779 } | 780 } |
780 | 781 |
781 @override | 782 @override |
782 Expression visitFunction(FunctionConstExp exp) { | 783 Expression visitFunction(FunctionConstantExpression exp) { |
783 return new Identifier(exp.element.name) | 784 return new Identifier(exp.element.name) |
784 ..element = exp.element; | 785 ..element = exp.element; |
785 } | 786 } |
786 | 787 |
787 @override | 788 @override |
788 Expression visitBinary(BinaryConstExp exp) { | 789 Expression visitBinary(BinaryConstantExpression exp) { |
789 return handlePrimitiveConstant(exp.value); | 790 return handlePrimitiveConstant(exp.value); |
790 } | 791 } |
791 | 792 |
792 @override | 793 @override |
793 Expression visitConditional(ConditionalConstExp exp) { | 794 Expression visitConditional(ConditionalConstantExpression exp) { |
794 if (exp.condition.value.isTrue) { | 795 if (exp.condition.value.isTrue) { |
795 return exp.trueExp.accept(this); | 796 return exp.trueExp.accept(this); |
796 } else { | 797 } else { |
797 return exp.falseExp.accept(this); | 798 return exp.falseExp.accept(this); |
798 } | 799 } |
799 } | 800 } |
800 | 801 |
801 @override | 802 @override |
802 Expression visitUnary(UnaryConstExp exp) { | 803 Expression visitUnary(UnaryConstantExpression exp) { |
803 return handlePrimitiveConstant(exp.value); | 804 return handlePrimitiveConstant(exp.value); |
804 } | 805 } |
805 } | 806 } |
806 | 807 |
807 /// Moves function parameters into a separate variable if one of its uses is | 808 /// Moves function parameters into a separate variable if one of its uses is |
808 /// shadowed by an inner function parameter. | 809 /// shadowed by an inner function parameter. |
809 /// This artifact is necessary because function parameters cannot be renamed. | 810 /// This artifact is necessary because function parameters cannot be renamed. |
810 class UnshadowParameters extends tree.RecursiveVisitor { | 811 class UnshadowParameters extends tree.RecursiveVisitor { |
811 | 812 |
812 /// Maps parameter names to their bindings. | 813 /// Maps parameter names to their bindings. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 } | 852 } |
852 } | 853 } |
853 | 854 |
854 visitVariable(tree.Variable variable) { | 855 visitVariable(tree.Variable variable) { |
855 if (shadowedParameters.contains(variable)) { | 856 if (shadowedParameters.contains(variable)) { |
856 hasShadowedUse.add(variable); | 857 hasShadowedUse.add(variable); |
857 } | 858 } |
858 } | 859 } |
859 | 860 |
860 } | 861 } |
OLD | NEW |