| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast/prettyprinter.h" | 5 #include "src/ast/prettyprinter.h" |
| 6 | 6 |
| 7 #include <stdarg.h> | 7 #include <stdarg.h> |
| 8 | 8 |
| 9 #include "src/ast/ast-value-factory.h" | 9 #include "src/ast/ast-value-factory.h" |
| 10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 // A helper for ast nodes that use FeedbackVectorSlots. | 468 // A helper for ast nodes that use FeedbackVectorSlots. |
| 469 static int FormatSlotNode(Vector<char>* buf, Expression* node, | 469 static int FormatSlotNode(Vector<char>* buf, Expression* node, |
| 470 const char* node_name, FeedbackVectorSlot slot) { | 470 const char* node_name, FeedbackVectorSlot slot) { |
| 471 int pos = SNPrintF(*buf, "%s", node_name); | 471 int pos = SNPrintF(*buf, "%s", node_name); |
| 472 if (!slot.IsInvalid()) { | 472 if (!slot.IsInvalid()) { |
| 473 pos += SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt()); | 473 pos += SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt()); |
| 474 } | 474 } |
| 475 return pos; | 475 return pos; |
| 476 } | 476 } |
| 477 | 477 |
| 478 | 478 const char* AstPrinter::Print(AstNode* node) { |
| 479 PrettyPrinter::PrettyPrinter(Isolate* isolate) { | |
| 480 isolate_ = isolate; | |
| 481 output_ = NULL; | |
| 482 size_ = 0; | |
| 483 pos_ = 0; | |
| 484 InitializeAstVisitor(isolate); | |
| 485 } | |
| 486 | |
| 487 | |
| 488 PrettyPrinter::~PrettyPrinter() { | |
| 489 DeleteArray(output_); | |
| 490 } | |
| 491 | |
| 492 | |
| 493 void PrettyPrinter::VisitBlock(Block* node) { | |
| 494 if (!node->ignore_completion_value()) Print("{ "); | |
| 495 PrintStatements(node->statements()); | |
| 496 if (node->statements()->length() > 0) Print(" "); | |
| 497 if (!node->ignore_completion_value()) Print("}"); | |
| 498 } | |
| 499 | |
| 500 | |
| 501 void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) { | |
| 502 Print("var "); | |
| 503 PrintLiteral(node->proxy()->name(), false); | |
| 504 Print(";"); | |
| 505 } | |
| 506 | |
| 507 | |
| 508 void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) { | |
| 509 Print("function "); | |
| 510 PrintLiteral(node->proxy()->name(), false); | |
| 511 Print(" = "); | |
| 512 PrintFunctionLiteral(node->fun()); | |
| 513 Print(";"); | |
| 514 } | |
| 515 | |
| 516 | |
| 517 void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) { | |
| 518 Print("import "); | |
| 519 PrintLiteral(node->proxy()->name(), false); | |
| 520 Print(" from "); | |
| 521 PrintLiteral(node->module_specifier()->string(), true); | |
| 522 Print(";"); | |
| 523 } | |
| 524 | |
| 525 | |
| 526 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) { | |
| 527 Visit(node->expression()); | |
| 528 Print(";"); | |
| 529 } | |
| 530 | |
| 531 | |
| 532 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) { | |
| 533 Print(";"); | |
| 534 } | |
| 535 | |
| 536 | |
| 537 void PrettyPrinter::VisitSloppyBlockFunctionStatement( | |
| 538 SloppyBlockFunctionStatement* node) { | |
| 539 Visit(node->statement()); | |
| 540 } | |
| 541 | |
| 542 | |
| 543 void PrettyPrinter::VisitIfStatement(IfStatement* node) { | |
| 544 Print("if ("); | |
| 545 Visit(node->condition()); | |
| 546 Print(") "); | |
| 547 Visit(node->then_statement()); | |
| 548 if (node->HasElseStatement()) { | |
| 549 Print(" else "); | |
| 550 Visit(node->else_statement()); | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 | |
| 555 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) { | |
| 556 Print("continue"); | |
| 557 ZoneList<const AstRawString*>* labels = node->target()->labels(); | |
| 558 if (labels != NULL) { | |
| 559 Print(" "); | |
| 560 DCHECK(labels->length() > 0); // guaranteed to have at least one entry | |
| 561 PrintLiteral(labels->at(0), false); // any label from the list is fine | |
| 562 } | |
| 563 Print(";"); | |
| 564 } | |
| 565 | |
| 566 | |
| 567 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) { | |
| 568 Print("break"); | |
| 569 ZoneList<const AstRawString*>* labels = node->target()->labels(); | |
| 570 if (labels != NULL) { | |
| 571 Print(" "); | |
| 572 DCHECK(labels->length() > 0); // guaranteed to have at least one entry | |
| 573 PrintLiteral(labels->at(0), false); // any label from the list is fine | |
| 574 } | |
| 575 Print(";"); | |
| 576 } | |
| 577 | |
| 578 | |
| 579 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) { | |
| 580 Print("return "); | |
| 581 Visit(node->expression()); | |
| 582 Print(";"); | |
| 583 } | |
| 584 | |
| 585 | |
| 586 void PrettyPrinter::VisitWithStatement(WithStatement* node) { | |
| 587 Print("with ("); | |
| 588 Visit(node->expression()); | |
| 589 Print(") "); | |
| 590 Visit(node->statement()); | |
| 591 } | |
| 592 | |
| 593 | |
| 594 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) { | |
| 595 PrintLabels(node->labels()); | |
| 596 Print("switch ("); | |
| 597 Visit(node->tag()); | |
| 598 Print(") { "); | |
| 599 ZoneList<CaseClause*>* cases = node->cases(); | |
| 600 for (int i = 0; i < cases->length(); i++) | |
| 601 Visit(cases->at(i)); | |
| 602 Print("}"); | |
| 603 } | |
| 604 | |
| 605 | |
| 606 void PrettyPrinter::VisitCaseClause(CaseClause* clause) { | |
| 607 if (clause->is_default()) { | |
| 608 Print("default"); | |
| 609 } else { | |
| 610 Print("case "); | |
| 611 Visit(clause->label()); | |
| 612 } | |
| 613 Print(": "); | |
| 614 PrintStatements(clause->statements()); | |
| 615 if (clause->statements()->length() > 0) | |
| 616 Print(" "); | |
| 617 } | |
| 618 | |
| 619 | |
| 620 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) { | |
| 621 PrintLabels(node->labels()); | |
| 622 Print("do "); | |
| 623 Visit(node->body()); | |
| 624 Print(" while ("); | |
| 625 Visit(node->cond()); | |
| 626 Print(");"); | |
| 627 } | |
| 628 | |
| 629 | |
| 630 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) { | |
| 631 PrintLabels(node->labels()); | |
| 632 Print("while ("); | |
| 633 Visit(node->cond()); | |
| 634 Print(") "); | |
| 635 Visit(node->body()); | |
| 636 } | |
| 637 | |
| 638 | |
| 639 void PrettyPrinter::VisitForStatement(ForStatement* node) { | |
| 640 PrintLabels(node->labels()); | |
| 641 Print("for ("); | |
| 642 if (node->init() != NULL) { | |
| 643 Visit(node->init()); | |
| 644 Print(" "); | |
| 645 } else { | |
| 646 Print("; "); | |
| 647 } | |
| 648 if (node->cond() != NULL) Visit(node->cond()); | |
| 649 Print("; "); | |
| 650 if (node->next() != NULL) { | |
| 651 Visit(node->next()); // prints extra ';', unfortunately | |
| 652 // to fix: should use Expression for next | |
| 653 } | |
| 654 Print(") "); | |
| 655 Visit(node->body()); | |
| 656 } | |
| 657 | |
| 658 | |
| 659 void PrettyPrinter::VisitForInStatement(ForInStatement* node) { | |
| 660 PrintLabels(node->labels()); | |
| 661 Print("for ("); | |
| 662 Visit(node->each()); | |
| 663 Print(" in "); | |
| 664 Visit(node->enumerable()); | |
| 665 Print(") "); | |
| 666 Visit(node->body()); | |
| 667 } | |
| 668 | |
| 669 | |
| 670 void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) { | |
| 671 // TODO(adamk): ForOf is largely desugared as part of parsing, | |
| 672 // so it's hard to display useful stuff here. Should likely | |
| 673 // either bite the bullet and display less or try harder | |
| 674 // to preserve more. | |
| 675 PrintLabels(node->labels()); | |
| 676 // The <each> is embedded inside a do-expression by the time we get here. | |
| 677 Print("for (<each> of "); | |
| 678 if (node->assign_iterator()->IsAssignment() && | |
| 679 node->assign_iterator()->AsAssignment()->value()->IsCall() && | |
| 680 node->assign_iterator() | |
| 681 ->AsAssignment() | |
| 682 ->value() | |
| 683 ->AsCall() | |
| 684 ->expression() | |
| 685 ->IsProperty() && | |
| 686 node->assign_iterator() | |
| 687 ->AsAssignment() | |
| 688 ->value() | |
| 689 ->AsCall() | |
| 690 ->expression() | |
| 691 ->IsProperty()) { | |
| 692 Visit(node->assign_iterator() | |
| 693 ->AsAssignment() | |
| 694 ->value() | |
| 695 ->AsCall() | |
| 696 ->expression() | |
| 697 ->AsProperty() | |
| 698 ->obj()); | |
| 699 } else { | |
| 700 Print("<iterable>"); | |
| 701 } | |
| 702 Print(") "); | |
| 703 Visit(node->body()); | |
| 704 } | |
| 705 | |
| 706 | |
| 707 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) { | |
| 708 Print("try "); | |
| 709 Visit(node->try_block()); | |
| 710 Print(" catch ("); | |
| 711 const bool quote = false; | |
| 712 PrintLiteral(node->variable()->name(), quote); | |
| 713 Print(") "); | |
| 714 Visit(node->catch_block()); | |
| 715 } | |
| 716 | |
| 717 | |
| 718 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) { | |
| 719 Print("try "); | |
| 720 Visit(node->try_block()); | |
| 721 Print(" finally "); | |
| 722 Visit(node->finally_block()); | |
| 723 } | |
| 724 | |
| 725 | |
| 726 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) { | |
| 727 Print("debugger "); | |
| 728 } | |
| 729 | |
| 730 | |
| 731 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) { | |
| 732 Print("("); | |
| 733 PrintFunctionLiteral(node); | |
| 734 Print(")"); | |
| 735 } | |
| 736 | |
| 737 | |
| 738 void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) { | |
| 739 Print("(class "); | |
| 740 PrintLiteral(node->constructor()->name(), false); | |
| 741 if (node->extends()) { | |
| 742 Print(" extends "); | |
| 743 Visit(node->extends()); | |
| 744 } | |
| 745 Print(" { "); | |
| 746 for (int i = 0; i < node->properties()->length(); i++) { | |
| 747 PrintObjectLiteralProperty(node->properties()->at(i)); | |
| 748 } | |
| 749 Print(" })"); | |
| 750 } | |
| 751 | |
| 752 | |
| 753 void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) { | |
| 754 Print("("); | |
| 755 PrintLiteral(node->name(), false); | |
| 756 Print(")"); | |
| 757 } | |
| 758 | |
| 759 | |
| 760 void PrettyPrinter::VisitDoExpression(DoExpression* node) { | |
| 761 Print("(do {"); | |
| 762 PrintStatements(node->block()->statements()); | |
| 763 Print("})"); | |
| 764 } | |
| 765 | |
| 766 | |
| 767 void PrettyPrinter::VisitConditional(Conditional* node) { | |
| 768 Visit(node->condition()); | |
| 769 Print(" ? "); | |
| 770 Visit(node->then_expression()); | |
| 771 Print(" : "); | |
| 772 Visit(node->else_expression()); | |
| 773 } | |
| 774 | |
| 775 | |
| 776 void PrettyPrinter::VisitLiteral(Literal* node) { | |
| 777 PrintLiteral(node->value(), true); | |
| 778 } | |
| 779 | |
| 780 | |
| 781 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) { | |
| 782 Print(" RegExp("); | |
| 783 PrintLiteral(node->pattern(), false); | |
| 784 Print(","); | |
| 785 if (node->flags() & RegExp::kGlobal) Print("g"); | |
| 786 if (node->flags() & RegExp::kIgnoreCase) Print("i"); | |
| 787 if (node->flags() & RegExp::kMultiline) Print("m"); | |
| 788 if (node->flags() & RegExp::kUnicode) Print("u"); | |
| 789 if (node->flags() & RegExp::kSticky) Print("y"); | |
| 790 Print(") "); | |
| 791 } | |
| 792 | |
| 793 | |
| 794 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) { | |
| 795 Print("{ "); | |
| 796 for (int i = 0; i < node->properties()->length(); i++) { | |
| 797 if (i != 0) Print(","); | |
| 798 PrintObjectLiteralProperty(node->properties()->at(i)); | |
| 799 } | |
| 800 Print(" }"); | |
| 801 } | |
| 802 | |
| 803 | |
| 804 void PrettyPrinter::PrintObjectLiteralProperty( | |
| 805 ObjectLiteralProperty* property) { | |
| 806 // TODO(arv): Better printing of methods etc. | |
| 807 Print(" "); | |
| 808 Visit(property->key()); | |
| 809 Print(": "); | |
| 810 Visit(property->value()); | |
| 811 } | |
| 812 | |
| 813 | |
| 814 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) { | |
| 815 Print("[ "); | |
| 816 Print(" literal_index = %d", node->literal_index()); | |
| 817 for (int i = 0; i < node->values()->length(); i++) { | |
| 818 if (i != 0) Print(","); | |
| 819 Visit(node->values()->at(i)); | |
| 820 } | |
| 821 Print(" ]"); | |
| 822 } | |
| 823 | |
| 824 | |
| 825 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) { | |
| 826 PrintLiteral(node->name(), false); | |
| 827 } | |
| 828 | |
| 829 | |
| 830 void PrettyPrinter::VisitAssignment(Assignment* node) { | |
| 831 Visit(node->target()); | |
| 832 Print(" %s ", Token::String(node->op())); | |
| 833 Visit(node->value()); | |
| 834 } | |
| 835 | |
| 836 | |
| 837 void PrettyPrinter::VisitYield(Yield* node) { | |
| 838 Print("yield "); | |
| 839 Visit(node->expression()); | |
| 840 } | |
| 841 | |
| 842 | |
| 843 void PrettyPrinter::VisitThrow(Throw* node) { | |
| 844 Print("throw "); | |
| 845 Visit(node->exception()); | |
| 846 } | |
| 847 | |
| 848 | |
| 849 void PrettyPrinter::VisitProperty(Property* node) { | |
| 850 Expression* key = node->key(); | |
| 851 Literal* literal = key->AsLiteral(); | |
| 852 if (literal != NULL && literal->value()->IsInternalizedString()) { | |
| 853 Print("("); | |
| 854 Visit(node->obj()); | |
| 855 Print(")."); | |
| 856 PrintLiteral(literal->value(), false); | |
| 857 } else { | |
| 858 Visit(node->obj()); | |
| 859 Print("["); | |
| 860 Visit(key); | |
| 861 Print("]"); | |
| 862 } | |
| 863 } | |
| 864 | |
| 865 | |
| 866 void PrettyPrinter::VisitCall(Call* node) { | |
| 867 Visit(node->expression()); | |
| 868 PrintArguments(node->arguments()); | |
| 869 } | |
| 870 | |
| 871 | |
| 872 void PrettyPrinter::VisitCallNew(CallNew* node) { | |
| 873 Print("new ("); | |
| 874 Visit(node->expression()); | |
| 875 Print(")"); | |
| 876 PrintArguments(node->arguments()); | |
| 877 } | |
| 878 | |
| 879 | |
| 880 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) { | |
| 881 Print("%%%s\n", node->debug_name()); | |
| 882 PrintArguments(node->arguments()); | |
| 883 } | |
| 884 | |
| 885 | |
| 886 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) { | |
| 887 Token::Value op = node->op(); | |
| 888 bool needsSpace = | |
| 889 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID; | |
| 890 Print("(%s%s", Token::String(op), needsSpace ? " " : ""); | |
| 891 Visit(node->expression()); | |
| 892 Print(")"); | |
| 893 } | |
| 894 | |
| 895 | |
| 896 void PrettyPrinter::VisitCountOperation(CountOperation* node) { | |
| 897 Print("("); | |
| 898 if (node->is_prefix()) Print("%s", Token::String(node->op())); | |
| 899 Visit(node->expression()); | |
| 900 if (node->is_postfix()) Print("%s", Token::String(node->op())); | |
| 901 Print(")"); | |
| 902 } | |
| 903 | |
| 904 | |
| 905 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) { | |
| 906 Print("("); | |
| 907 Visit(node->left()); | |
| 908 Print(" %s ", Token::String(node->op())); | |
| 909 Visit(node->right()); | |
| 910 Print(")"); | |
| 911 } | |
| 912 | |
| 913 | |
| 914 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) { | |
| 915 Print("("); | |
| 916 Visit(node->left()); | |
| 917 Print(" %s ", Token::String(node->op())); | |
| 918 Visit(node->right()); | |
| 919 Print(")"); | |
| 920 } | |
| 921 | |
| 922 | |
| 923 void PrettyPrinter::VisitSpread(Spread* node) { | |
| 924 Print("(..."); | |
| 925 Visit(node->expression()); | |
| 926 Print(")"); | |
| 927 } | |
| 928 | |
| 929 | |
| 930 void PrettyPrinter::VisitEmptyParentheses(EmptyParentheses* node) { | |
| 931 Print("()"); | |
| 932 } | |
| 933 | |
| 934 | |
| 935 void PrettyPrinter::VisitThisFunction(ThisFunction* node) { | |
| 936 Print("<this-function>"); | |
| 937 } | |
| 938 | |
| 939 | |
| 940 void PrettyPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) { | |
| 941 Print("<super-property-reference>"); | |
| 942 } | |
| 943 | |
| 944 | |
| 945 void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) { | |
| 946 Print("<super-call-reference>"); | |
| 947 } | |
| 948 | |
| 949 | |
| 950 void PrettyPrinter::VisitRewritableExpression(RewritableExpression* node) { | |
| 951 Visit(node->expression()); | |
| 952 } | |
| 953 | |
| 954 | |
| 955 const char* PrettyPrinter::Print(AstNode* node) { | |
| 956 Init(); | 479 Init(); |
| 957 Visit(node); | 480 Visit(node); |
| 958 return output_; | 481 return output_; |
| 959 } | 482 } |
| 960 | 483 |
| 961 | 484 void AstPrinter::Init() { |
| 962 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) { | |
| 963 Init(); | |
| 964 ExpressionStatement* statement = | |
| 965 program->body()->at(0)->AsExpressionStatement(); | |
| 966 Visit(statement->expression()); | |
| 967 return output_; | |
| 968 } | |
| 969 | |
| 970 | |
| 971 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) { | |
| 972 Init(); | |
| 973 PrintStatements(program->body()); | |
| 974 Print("\n"); | |
| 975 return output_; | |
| 976 } | |
| 977 | |
| 978 | |
| 979 void PrettyPrinter::PrintOut(Isolate* isolate, AstNode* node) { | |
| 980 PrettyPrinter printer(isolate); | |
| 981 PrintF("%s\n", printer.Print(node)); | |
| 982 } | |
| 983 | |
| 984 | |
| 985 void PrettyPrinter::Init() { | |
| 986 if (size_ == 0) { | 485 if (size_ == 0) { |
| 987 DCHECK(output_ == NULL); | 486 DCHECK(output_ == NULL); |
| 988 const int initial_size = 256; | 487 const int initial_size = 256; |
| 989 output_ = NewArray<char>(initial_size); | 488 output_ = NewArray<char>(initial_size); |
| 990 size_ = initial_size; | 489 size_ = initial_size; |
| 991 } | 490 } |
| 992 output_[0] = '\0'; | 491 output_[0] = '\0'; |
| 993 pos_ = 0; | 492 pos_ = 0; |
| 994 } | 493 } |
| 995 | 494 |
| 996 | 495 void AstPrinter::Print(const char* format, ...) { |
| 997 void PrettyPrinter::Print(const char* format, ...) { | |
| 998 for (;;) { | 496 for (;;) { |
| 999 va_list arguments; | 497 va_list arguments; |
| 1000 va_start(arguments, format); | 498 va_start(arguments, format); |
| 1001 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, | 499 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, |
| 1002 format, | 500 format, |
| 1003 arguments); | 501 arguments); |
| 1004 va_end(arguments); | 502 va_end(arguments); |
| 1005 | 503 |
| 1006 if (n >= 0) { | 504 if (n >= 0) { |
| 1007 // there was enough space - we are done | 505 // there was enough space - we are done |
| 1008 pos_ += n; | 506 pos_ += n; |
| 1009 return; | 507 return; |
| 1010 } else { | 508 } else { |
| 1011 // there was not enough space - allocate more and try again | 509 // there was not enough space - allocate more and try again |
| 1012 const int slack = 32; | 510 const int slack = 32; |
| 1013 int new_size = size_ + (size_ >> 1) + slack; | 511 int new_size = size_ + (size_ >> 1) + slack; |
| 1014 char* new_output = NewArray<char>(new_size); | 512 char* new_output = NewArray<char>(new_size); |
| 1015 MemCopy(new_output, output_, pos_); | 513 MemCopy(new_output, output_, pos_); |
| 1016 DeleteArray(output_); | 514 DeleteArray(output_); |
| 1017 output_ = new_output; | 515 output_ = new_output; |
| 1018 size_ = new_size; | 516 size_ = new_size; |
| 1019 } | 517 } |
| 1020 } | 518 } |
| 1021 } | 519 } |
| 1022 | 520 |
| 1023 | 521 void AstPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) { |
| 1024 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) { | |
| 1025 if (statements == NULL) return; | |
| 1026 for (int i = 0; i < statements->length(); i++) { | |
| 1027 if (i != 0) Print(" "); | |
| 1028 Visit(statements->at(i)); | |
| 1029 } | |
| 1030 } | |
| 1031 | |
| 1032 | |
| 1033 void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) { | |
| 1034 if (labels != NULL) { | 522 if (labels != NULL) { |
| 1035 for (int i = 0; i < labels->length(); i++) { | 523 for (int i = 0; i < labels->length(); i++) { |
| 1036 PrintLiteral(labels->at(i), false); | 524 PrintLiteral(labels->at(i), false); |
| 1037 Print(": "); | 525 Print(": "); |
| 1038 } | 526 } |
| 1039 } | 527 } |
| 1040 } | 528 } |
| 1041 | 529 |
| 1042 | 530 void AstPrinter::PrintLiteral(Handle<Object> value, bool quote) { |
| 1043 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) { | |
| 1044 Print("("); | |
| 1045 for (int i = 0; i < arguments->length(); i++) { | |
| 1046 if (i != 0) Print(", "); | |
| 1047 Visit(arguments->at(i)); | |
| 1048 } | |
| 1049 Print(")"); | |
| 1050 } | |
| 1051 | |
| 1052 | |
| 1053 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) { | |
| 1054 Object* object = *value; | 531 Object* object = *value; |
| 1055 if (object->IsString()) { | 532 if (object->IsString()) { |
| 1056 String* string = String::cast(object); | 533 String* string = String::cast(object); |
| 1057 if (quote) Print("\""); | 534 if (quote) Print("\""); |
| 1058 for (int i = 0; i < string->length(); i++) { | 535 for (int i = 0; i < string->length(); i++) { |
| 1059 Print("%c", string->Get(i)); | 536 Print("%c", string->Get(i)); |
| 1060 } | 537 } |
| 1061 if (quote) Print("\""); | 538 if (quote) Print("\""); |
| 1062 } else if (object->IsNull(isolate_)) { | 539 } else if (object->IsNull(isolate_)) { |
| 1063 Print("null"); | 540 Print("null"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1081 } else { | 558 } else { |
| 1082 Print("?UNKNOWN?"); | 559 Print("?UNKNOWN?"); |
| 1083 } | 560 } |
| 1084 } else if (object->IsFixedArray()) { | 561 } else if (object->IsFixedArray()) { |
| 1085 Print("FixedArray"); | 562 Print("FixedArray"); |
| 1086 } else { | 563 } else { |
| 1087 Print("<unknown literal %p>", static_cast<void*>(object)); | 564 Print("<unknown literal %p>", static_cast<void*>(object)); |
| 1088 } | 565 } |
| 1089 } | 566 } |
| 1090 | 567 |
| 1091 | 568 void AstPrinter::PrintLiteral(const AstRawString* value, bool quote) { |
| 1092 void PrettyPrinter::PrintLiteral(const AstRawString* value, bool quote) { | |
| 1093 PrintLiteral(value->string(), quote); | 569 PrintLiteral(value->string(), quote); |
| 1094 } | 570 } |
| 1095 | 571 |
| 1096 | 572 |
| 1097 void PrettyPrinter::PrintParameters(Scope* scope) { | |
| 1098 Print("("); | |
| 1099 for (int i = 0; i < scope->num_parameters(); i++) { | |
| 1100 if (i > 0) Print(", "); | |
| 1101 PrintLiteral(scope->parameter(i)->name(), false); | |
| 1102 } | |
| 1103 Print(")"); | |
| 1104 } | |
| 1105 | |
| 1106 | |
| 1107 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) { | |
| 1108 for (int i = 0; i < declarations->length(); i++) { | |
| 1109 if (i > 0) Print(" "); | |
| 1110 Visit(declarations->at(i)); | |
| 1111 } | |
| 1112 } | |
| 1113 | |
| 1114 | |
| 1115 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) { | |
| 1116 Print("function "); | |
| 1117 PrintLiteral(function->name(), false); | |
| 1118 PrintParameters(function->scope()); | |
| 1119 Print(" { "); | |
| 1120 PrintDeclarations(function->scope()->declarations()); | |
| 1121 PrintStatements(function->body()); | |
| 1122 Print(" }"); | |
| 1123 } | |
| 1124 | |
| 1125 | |
| 1126 //----------------------------------------------------------------------------- | 573 //----------------------------------------------------------------------------- |
| 1127 | 574 |
| 1128 class IndentedScope BASE_EMBEDDED { | 575 class IndentedScope BASE_EMBEDDED { |
| 1129 public: | 576 public: |
| 1130 IndentedScope(AstPrinter* printer, const char* txt) | 577 IndentedScope(AstPrinter* printer, const char* txt) |
| 1131 : ast_printer_(printer) { | 578 : ast_printer_(printer) { |
| 1132 ast_printer_->PrintIndented(txt); | 579 ast_printer_->PrintIndented(txt); |
| 1133 ast_printer_->Print("\n"); | 580 ast_printer_->Print("\n"); |
| 1134 ast_printer_->inc_indent(); | 581 ast_printer_->inc_indent(); |
| 1135 } | 582 } |
| 1136 | 583 |
| 1137 IndentedScope(AstPrinter* printer, const char* txt, int pos) | 584 IndentedScope(AstPrinter* printer, const char* txt, int pos) |
| 1138 : ast_printer_(printer) { | 585 : ast_printer_(printer) { |
| 1139 ast_printer_->PrintIndented(txt); | 586 ast_printer_->PrintIndented(txt); |
| 1140 ast_printer_->Print(" at %d\n", pos); | 587 ast_printer_->Print(" at %d\n", pos); |
| 1141 ast_printer_->inc_indent(); | 588 ast_printer_->inc_indent(); |
| 1142 } | 589 } |
| 1143 | 590 |
| 1144 virtual ~IndentedScope() { | 591 virtual ~IndentedScope() { |
| 1145 ast_printer_->dec_indent(); | 592 ast_printer_->dec_indent(); |
| 1146 } | 593 } |
| 1147 | 594 |
| 1148 private: | 595 private: |
| 1149 AstPrinter* ast_printer_; | 596 AstPrinter* ast_printer_; |
| 1150 }; | 597 }; |
| 1151 | 598 |
| 1152 | 599 |
| 1153 //----------------------------------------------------------------------------- | 600 //----------------------------------------------------------------------------- |
| 1154 | 601 |
| 1155 | 602 AstPrinter::AstPrinter(Isolate* isolate) |
| 1156 AstPrinter::AstPrinter(Isolate* isolate) : PrettyPrinter(isolate), indent_(0) {} | 603 : output_(nullptr), size_(0), pos_(0), indent_(0) { |
| 1157 | 604 InitializeAstVisitor(isolate); |
| 605 } |
| 1158 | 606 |
| 1159 AstPrinter::~AstPrinter() { | 607 AstPrinter::~AstPrinter() { |
| 1160 DCHECK(indent_ == 0); | 608 DCHECK(indent_ == 0); |
| 609 DeleteArray(output_); |
| 1161 } | 610 } |
| 1162 | 611 |
| 1163 | 612 |
| 1164 void AstPrinter::PrintIndented(const char* txt) { | 613 void AstPrinter::PrintIndented(const char* txt) { |
| 1165 for (int i = 0; i < indent_; i++) { | 614 for (int i = 0; i < indent_; i++) { |
| 1166 Print(". "); | 615 Print(". "); |
| 1167 } | 616 } |
| 1168 Print("%s", txt); | 617 Print("%s", txt); |
| 1169 } | 618 } |
| 1170 | 619 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 PrintIndented("KIND"); | 663 PrintIndented("KIND"); |
| 1215 Print(" %d\n", program->kind()); | 664 Print(" %d\n", program->kind()); |
| 1216 PrintIndented("YIELD COUNT"); | 665 PrintIndented("YIELD COUNT"); |
| 1217 Print(" %d\n", program->yield_count()); | 666 Print(" %d\n", program->yield_count()); |
| 1218 PrintLiteralIndented("NAME", program->name(), true); | 667 PrintLiteralIndented("NAME", program->name(), true); |
| 1219 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true); | 668 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true); |
| 1220 PrintParameters(program->scope()); | 669 PrintParameters(program->scope()); |
| 1221 PrintDeclarations(program->scope()->declarations()); | 670 PrintDeclarations(program->scope()->declarations()); |
| 1222 PrintStatements(program->body()); | 671 PrintStatements(program->body()); |
| 1223 } | 672 } |
| 1224 return Output(); | 673 return output_; |
| 1225 } | 674 } |
| 1226 | 675 |
| 1227 | 676 |
| 1228 void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) { | 677 void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) { |
| 1229 AstPrinter printer(isolate); | 678 AstPrinter printer(isolate); |
| 1230 printer.Init(); | 679 printer.Init(); |
| 1231 printer.Visit(node); | 680 printer.Visit(node); |
| 1232 PrintF("%s", printer.Output()); | 681 PrintF("%s", printer.output_); |
| 1233 } | 682 } |
| 1234 | 683 |
| 1235 | 684 |
| 1236 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) { | 685 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) { |
| 1237 if (declarations->length() > 0) { | 686 if (declarations->length() > 0) { |
| 1238 IndentedScope indent(this, "DECLS"); | 687 IndentedScope indent(this, "DECLS"); |
| 1239 for (int i = 0; i < declarations->length(); i++) { | 688 for (int i = 0; i < declarations->length(); i++) { |
| 1240 Visit(declarations->at(i)); | 689 Visit(declarations->at(i)); |
| 1241 } | 690 } |
| 1242 } | 691 } |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1732 | 1181 |
| 1733 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { | 1182 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { |
| 1734 Visit(node->expression()); | 1183 Visit(node->expression()); |
| 1735 } | 1184 } |
| 1736 | 1185 |
| 1737 | 1186 |
| 1738 #endif // DEBUG | 1187 #endif // DEBUG |
| 1739 | 1188 |
| 1740 } // namespace internal | 1189 } // namespace internal |
| 1741 } // namespace v8 | 1190 } // namespace v8 |
| OLD | NEW |