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 |