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) => new ConstantEmitter(this).v isit(exp); |
sigurdm
2014/10/01 07:46:47
Long line
Johnni Winther
2014/10/01 08:21:23
Done.
| |
668 | 668 |
669 } | 669 } |
670 | 670 |
671 class ConstantEmitter extends ConstExpVisitor<Expression> { | 671 class ConstantEmitter extends ConstantExpressionVisitor<Expression> { |
672 ASTEmitter parent; | 672 ASTEmitter parent; |
673 ConstantEmitter(this.parent); | 673 ConstantEmitter(this.parent); |
674 | 674 |
675 Expression handlePrimitiveConstant(values.PrimitiveConstant value) { | 675 Expression handlePrimitiveConstant(PrimitiveConstantValue 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 (value.isNum) { | 683 if (value.isNum) { |
684 values.NumConstant numConstant = value; | 684 NumConstantValue numConstant = value; |
685 if (numConstant.value.isNegative) { | 685 if (numConstant.primitiveValue.isNegative) { |
686 return negatedLiteral(numConstant); | 686 return negatedLiteral(numConstant); |
687 } | 687 } |
688 } | 688 } |
689 return new Literal(value); | 689 return new Literal(value); |
690 } | 690 } |
691 | 691 |
692 @override | 692 @override |
693 Expression visitPrimitive(PrimitiveConstExp exp) { | 693 Expression visitPrimitive(PrimitiveConstantExpression exp) { |
694 return handlePrimitiveConstant(exp.value); | 694 return handlePrimitiveConstant(exp.value); |
695 } | 695 } |
696 | 696 |
697 /// Given a negative num constant, returns the corresponding positive | 697 /// Given a negative num constant, returns the corresponding positive |
698 /// literal wrapped by a unary minus operator. | 698 /// literal wrapped by a unary minus operator. |
699 Expression negatedLiteral(values.NumConstant constant) { | 699 Expression negatedLiteral(NumConstantValue constant) { |
700 assert(constant.value.isNegative); | 700 assert(constant.primitiveValue.isNegative); |
701 values.NumConstant positiveConstant; | 701 NumConstantValue positiveConstant; |
702 if (constant.isInt) { | 702 if (constant.isInt) { |
703 positiveConstant = new values.IntConstant(-constant.value); | 703 positiveConstant = new IntConstantValue(-constant.primitiveValue); |
704 } else if (constant.isDouble) { | 704 } else if (constant.isDouble) { |
705 positiveConstant = new values.DoubleConstant(-constant.value); | 705 positiveConstant = new DoubleConstantValue(-constant.primitiveValue); |
706 } else { | 706 } else { |
707 throw "Unexpected type of NumConstant: $constant"; | 707 throw "Unexpected type of NumConstant: $constant"; |
708 } | 708 } |
709 return new UnaryOperator('-', new Literal(positiveConstant)); | 709 return new UnaryOperator('-', new Literal(positiveConstant)); |
710 } | 710 } |
711 | 711 |
712 @override | 712 @override |
713 Expression visitList(ListConstExp exp) { | 713 Expression visitList(ListConstantExpression exp) { |
714 return new LiteralList( | 714 return new LiteralList( |
715 exp.values.map(visit).toList(growable: false), | 715 exp.values.map(visit).toList(growable: false), |
716 isConst: true, | 716 isConst: true, |
717 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); | 717 typeArgument: parent.emitOptionalType(exp.type.typeArguments.single)); |
718 } | 718 } |
719 | 719 |
720 @override | 720 @override |
721 Expression visitMap(MapConstExp exp) { | 721 Expression visitMap(MapConstantExpression exp) { |
722 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( | 722 List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate( |
723 exp.values.length, | 723 exp.values.length, |
724 (i) => new LiteralMapEntry(visit(exp.keys[i]), | 724 (i) => new LiteralMapEntry(visit(exp.keys[i]), |
725 visit(exp.values[i]))); | 725 visit(exp.values[i]))); |
726 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw | 726 List<TypeAnnotation> typeArguments = exp.type.treatAsRaw |
727 ? null | 727 ? null |
728 : exp.type.typeArguments.map(parent.emitType).toList(); | 728 : exp.type.typeArguments.map(parent.emitType).toList(); |
729 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); | 729 return new LiteralMap(entries, isConst: true, typeArguments: typeArguments); |
730 } | 730 } |
731 | 731 |
732 @override | 732 @override |
733 Expression visitConstructor(ConstructorConstExp exp) { | 733 Expression visitConstructor(ConstructedConstantExpresssion exp) { |
734 int positionalArgumentCount = exp.selector.positionalArgumentCount; | 734 int positionalArgumentCount = exp.selector.positionalArgumentCount; |
735 List<Argument> args = new List<Argument>.generate( | 735 List<Argument> args = new List<Argument>.generate( |
736 positionalArgumentCount, | 736 positionalArgumentCount, |
737 (i) => visit(exp.arguments[i])); | 737 (i) => visit(exp.arguments[i])); |
738 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { | 738 for (int i = 0; i < exp.selector.namedArgumentCount; ++i) { |
739 args.add(new NamedArgument(exp.selector.namedArguments[i], | 739 args.add(new NamedArgument(exp.selector.namedArguments[i], |
740 visit(exp.arguments[positionalArgumentCount + i]))); | 740 visit(exp.arguments[positionalArgumentCount + i]))); |
741 } | 741 } |
742 | 742 |
743 FunctionElement constructor = exp.target; | 743 FunctionElement constructor = exp.target; |
744 String name = constructor.name.isEmpty ? null : constructor.name; | 744 String name = constructor.name.isEmpty ? null : constructor.name; |
745 return new CallNew(parent.emitType(exp.type), | 745 return new CallNew(parent.emitType(exp.type), |
746 args, | 746 args, |
747 constructorName: name, | 747 constructorName: name, |
748 isConst: true) | 748 isConst: true) |
749 ..constructor = constructor | 749 ..constructor = constructor |
750 ..dartType = exp.type; | 750 ..dartType = exp.type; |
751 } | 751 } |
752 | 752 |
753 @override | 753 @override |
754 Expression visitConcatenate(ConcatenateConstExp exp) { | 754 Expression visitConcatenate(ConcatenateConstantExpression exp) { |
755 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); | 755 return new StringConcat(exp.arguments.map(visit).toList(growable: false)); |
756 } | 756 } |
757 | 757 |
758 @override | 758 @override |
759 Expression visitSymbol(SymbolConstExp exp) { | 759 Expression visitSymbol(SymbolConstantExpression exp) { |
760 return new LiteralSymbol(exp.name); | 760 return new LiteralSymbol(exp.name); |
761 } | 761 } |
762 | 762 |
763 @override | 763 @override |
764 Expression visitType(TypeConstExp exp) { | 764 Expression visitType(TypeConstantExpression exp) { |
765 DartType type = exp.type; | 765 DartType type = exp.type; |
766 return new LiteralType(type.name) | 766 return new LiteralType(type.name) |
767 ..type = type; | 767 ..type = type; |
768 } | 768 } |
769 | 769 |
770 @override | 770 @override |
771 Expression visitVariable(VariableConstExp exp) { | 771 Expression visitVariable(VariableConstantExpression exp) { |
772 Element element = exp.element; | 772 Element element = exp.element; |
773 if (element.kind != ElementKind.VARIABLE) { | 773 if (element.kind != ElementKind.VARIABLE) { |
774 return new Identifier(element.name)..element = element; | 774 return new Identifier(element.name)..element = element; |
775 } | 775 } |
776 String name = parent.getConstantName(element); | 776 String name = parent.getConstantName(element); |
777 return new Identifier(name) | 777 return new Identifier(name) |
778 ..element = element; | 778 ..element = element; |
779 } | 779 } |
780 | 780 |
781 @override | 781 @override |
782 Expression visitFunction(FunctionConstExp exp) { | 782 Expression visitFunction(FunctionConstantExpression exp) { |
783 return new Identifier(exp.element.name) | 783 return new Identifier(exp.element.name) |
784 ..element = exp.element; | 784 ..element = exp.element; |
785 } | 785 } |
786 | 786 |
787 @override | 787 @override |
788 Expression visitBinary(BinaryConstExp exp) { | 788 Expression visitBinary(BinaryConstantExpression exp) { |
789 return handlePrimitiveConstant(exp.value); | 789 return handlePrimitiveConstant(exp.value); |
790 } | 790 } |
791 | 791 |
792 @override | 792 @override |
793 Expression visitConditional(ConditionalConstExp exp) { | 793 Expression visitConditional(ConditionalConstantExpression exp) { |
794 if (exp.condition.value.isTrue) { | 794 if (exp.condition.value.isTrue) { |
795 return exp.trueExp.accept(this); | 795 return exp.trueExp.accept(this); |
796 } else { | 796 } else { |
797 return exp.falseExp.accept(this); | 797 return exp.falseExp.accept(this); |
798 } | 798 } |
799 } | 799 } |
800 | 800 |
801 @override | 801 @override |
802 Expression visitUnary(UnaryConstExp exp) { | 802 Expression visitUnary(UnaryConstantExpression exp) { |
803 return handlePrimitiveConstant(exp.value); | 803 return handlePrimitiveConstant(exp.value); |
804 } | 804 } |
805 } | 805 } |
806 | 806 |
807 /// 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 |
808 /// shadowed by an inner function parameter. | 808 /// shadowed by an inner function parameter. |
809 /// This artifact is necessary because function parameters cannot be renamed. | 809 /// This artifact is necessary because function parameters cannot be renamed. |
810 class UnshadowParameters extends tree.RecursiveVisitor { | 810 class UnshadowParameters extends tree.RecursiveVisitor { |
811 | 811 |
812 /// Maps parameter names to their bindings. | 812 /// Maps parameter names to their bindings. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
851 } | 851 } |
852 } | 852 } |
853 | 853 |
854 visitVariable(tree.Variable variable) { | 854 visitVariable(tree.Variable variable) { |
855 if (shadowedParameters.contains(variable)) { | 855 if (shadowedParameters.contains(variable)) { |
856 hasShadowedUse.add(variable); | 856 hasShadowedUse.add(variable); |
857 } | 857 } |
858 } | 858 } |
859 | 859 |
860 } | 860 } |
OLD | NEW |