Chromium Code Reviews| 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 |