1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "prettyprinter.h"
41 PrettyPrinter::PrettyPrinter() {
48 PrettyPrinter::~PrettyPrinter() {
53 void PrettyPrinter::VisitBlock(Block* node) {
54 if (!node->is_initializer_block()) Print("{ ");
55 PrintStatements(node->statements());
56 if (node->statements()->length() > 0) Print(" ");
57 if (!node->is_initializer_block()) Print("}");
61 void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
63 PrintLiteral(node->proxy()->name(), false);
68 void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
70 PrintLiteral(node->proxy()->name(), false);
72 PrintFunctionLiteral(node->fun());
77 void PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
79 PrintLiteral(node->proxy()->name(), false);
81 Visit(node->module());
86 void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
88 PrintLiteral(node->proxy()->name(), false);
90 Visit(node->module());
95 void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
97 PrintLiteral(node->proxy()->name(), false);
102 void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
103 VisitBlock(node->body());
107 void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
108 Visit(node->proxy());
112 void PrettyPrinter::VisitModulePath(ModulePath* node) {
113 Visit(node->module());
115 PrintLiteral(node->name(), false);
119 void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
121 PrintLiteral(node->url(), true);
125 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
126 Visit(node->expression());
131 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
136 void PrettyPrinter::VisitIfStatement(IfStatement* node) {
138 Visit(node->condition());
140 Visit(node->then_statement());
141 if (node->HasElseStatement()) {
143 Visit(node->else_statement());
148 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
150 ZoneStringList* labels = node->target()->labels();
151 if (labels != NULL) {
153 ASSERT(labels->length() > 0); // guaranteed to have at least one entry
154 PrintLiteral(labels->at(0), false); // any label from the list is fine
160 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
162 ZoneStringList* labels = node->target()->labels();
163 if (labels != NULL) {
165 ASSERT(labels->length() > 0); // guaranteed to have at least one entry
166 PrintLiteral(labels->at(0), false); // any label from the list is fine
172 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
174 Visit(node->expression());
179 void PrettyPrinter::VisitWithStatement(WithStatement* node) {
181 Visit(node->expression());
183 Visit(node->statement());
187 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
188 PrintLabels(node->labels());
192 ZoneList<CaseClause*>* cases = node->cases();
193 for (int i = 0; i < cases->length(); i++)
194 PrintCaseClause(cases->at(i));
199 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
200 PrintLabels(node->labels());
209 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
210 PrintLabels(node->labels());
218 void PrettyPrinter::VisitForStatement(ForStatement* node) {
219 PrintLabels(node->labels());
221 if (node->init() != NULL) {
227 if (node->cond() != NULL) Visit(node->cond());
229 if (node->next() != NULL) {
230 Visit(node->next()); // prints extra ';', unfortunately
231 // to fix: should use Expression for next
238 void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
239 PrintLabels(node->labels());
243 Visit(node->enumerable());
249 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
251 Visit(node->try_block());
253 const bool quote = false;
254 PrintLiteral(node->variable()->name(), quote);
256 Visit(node->catch_block());
260 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
262 Visit(node->try_block());
264 Visit(node->finally_block());
268 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
273 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
275 PrintFunctionLiteral(node);
280 void PrettyPrinter::VisitSharedFunctionInfoLiteral(
281 SharedFunctionInfoLiteral* node) {
283 PrintLiteral(node->shared_function_info(), true);
288 void PrettyPrinter::VisitConditional(Conditional* node) {
289 Visit(node->condition());
291 Visit(node->then_expression());
293 Visit(node->else_expression());
297 void PrettyPrinter::VisitLiteral(Literal* node) {
298 PrintLiteral(node->handle(), true);
302 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
304 PrintLiteral(node->pattern(), false);
306 PrintLiteral(node->flags(), false);
311 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
313 for (int i = 0; i < node->properties()->length(); i++) {
314 if (i != 0) Print(",");
315 ObjectLiteral::Property* property = node->properties()->at(i);
317 Visit(property->key());
319 Visit(property->value());
325 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
327 for (int i = 0; i < node->values()->length(); i++) {
328 if (i != 0) Print(",");
329 Visit(node->values()->at(i));
335 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
336 PrintLiteral(node->name(), false);
340 void PrettyPrinter::VisitAssignment(Assignment* node) {
341 Visit(node->target());
342 Print(" %s ", Token::String(node->op()));
343 Visit(node->value());
347 void PrettyPrinter::VisitThrow(Throw* node) {
349 Visit(node->exception());
353 void PrettyPrinter::VisitProperty(Property* node) {
354 Expression* key = node->key();
355 Literal* literal = key->AsLiteral();
356 if (literal != NULL && literal->handle()->IsSymbol()) {
360 PrintLiteral(literal->handle(), false);
370 void PrettyPrinter::VisitCall(Call* node) {
371 Visit(node->expression());
372 PrintArguments(node->arguments());
376 void PrettyPrinter::VisitCallNew(CallNew* node) {
378 Visit(node->expression());
380 PrintArguments(node->arguments());
384 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
386 PrintLiteral(node->name(), false);
387 PrintArguments(node->arguments());
391 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
392 Token::Value op = node->op();
394 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
395 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
396 Visit(node->expression());
401 void PrettyPrinter::VisitCountOperation(CountOperation* node) {
403 if (node->is_prefix()) Print("%s", Token::String(node->op()));
404 Visit(node->expression());
405 if (node->is_postfix()) Print("%s", Token::String(node->op()));
410 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
413 Print(" %s ", Token::String(node->op()));
414 Visit(node->right());
419 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
422 Print(" %s ", Token::String(node->op()));
423 Visit(node->right());
428 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
429 Print("<this-function>");
433 const char* PrettyPrinter::Print(AstNode* node) {
440 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
442 ExpressionStatement* statement =
443 program->body()->at(0)->AsExpressionStatement();
444 Visit(statement->expression());
449 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
451 PrintStatements(program->body());
457 void PrettyPrinter::PrintOut(AstNode* node) {
458 PrettyPrinter printer;
459 PrintF("%s", printer.Print(node));
463 void PrettyPrinter::Init() {
465 ASSERT(output_ == NULL);
466 const int initial_size = 256;
467 output_ = NewArray<char>(initial_size);
468 size_ = initial_size;
475 void PrettyPrinter::Print(const char* format, ...) {
478 va_start(arguments, format);
479 int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
485 // there was enough space - we are done
489 // there was not enough space - allocate more and try again
490 const int slack = 32;
491 int new_size = size_ + (size_ >> 1) + slack;
492 char* new_output = NewArray<char>(new_size);
493 memcpy(new_output, output_, pos_);
494 DeleteArray(output_);
495 output_ = new_output;
502 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
503 if (statements == NULL) return;
504 for (int i = 0; i < statements->length(); i++) {
505 if (i != 0) Print(" ");
506 Visit(statements->at(i));
511 void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
512 if (labels != NULL) {
513 for (int i = 0; i < labels->length(); i++) {
514 PrintLiteral(labels->at(i), false);
521 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
523 for (int i = 0; i < arguments->length(); i++) {
524 if (i != 0) Print(", ");
525 Visit(arguments->at(i));
531 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
532 Object* object = *value;
533 if (object->IsString()) {
534 String* string = String::cast(object);
535 if (quote) Print("\"");
536 for (int i = 0; i < string->length(); i++) {
537 Print("%c", string->Get(i));
539 if (quote) Print("\"");
540 } else if (object->IsNull()) {
542 } else if (object->IsTrue()) {
544 } else if (object->IsFalse()) {
546 } else if (object->IsUndefined()) {
548 } else if (object->IsNumber()) {
549 Print("%g", object->Number());
550 } else if (object->IsJSObject()) {
551 // regular expression
552 if (object->IsJSFunction()) {
553 Print("JS-Function");
554 } else if (object->IsJSArray()) {
555 Print("JS-array[%u]", JSArray::cast(object)->length());
556 } else if (object->IsJSObject()) {
561 } else if (object->IsFixedArray()) {
564 Print("<unknown literal %p>", object);
569 void PrettyPrinter::PrintParameters(Scope* scope) {
571 for (int i = 0; i < scope->num_parameters(); i++) {
572 if (i > 0) Print(", ");
573 PrintLiteral(scope->parameter(i)->name(), false);
579 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
580 for (int i = 0; i < declarations->length(); i++) {
581 if (i > 0) Print(" ");
582 Visit(declarations->at(i));
587 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
589 PrintLiteral(function->name(), false);
590 PrintParameters(function->scope());
592 PrintDeclarations(function->scope()->declarations());
593 PrintStatements(function->body());
598 void PrettyPrinter::PrintCaseClause(CaseClause* clause) {
599 if (clause->is_default()) {
603 Visit(clause->label());
606 PrintStatements(clause->statements());
607 if (clause->statements()->length() > 0)
612 //-----------------------------------------------------------------------------
614 class IndentedScope BASE_EMBEDDED {
616 explicit IndentedScope(AstPrinter* printer) : ast_printer_(printer) {
617 ast_printer_->inc_indent();
620 IndentedScope(AstPrinter* printer, const char* txt, AstNode* node = NULL)
621 : ast_printer_(printer) {
622 ast_printer_->PrintIndented(txt);
623 ast_printer_->Print("\n");
624 ast_printer_->inc_indent();
627 virtual ~IndentedScope() {
628 ast_printer_->dec_indent();
632 AstPrinter* ast_printer_;
636 //-----------------------------------------------------------------------------
639 AstPrinter::AstPrinter() : indent_(0) {
643 AstPrinter::~AstPrinter() {
644 ASSERT(indent_ == 0);
648 void AstPrinter::PrintIndented(const char* txt) {
649 for (int i = 0; i < indent_; i++) {
656 void AstPrinter::PrintLiteralIndented(const char* info,
657 Handle<Object> value,
661 PrintLiteral(value, quote);
666 void AstPrinter::PrintLiteralWithModeIndented(const char* info,
668 Handle<Object> value) {
670 PrintLiteralIndented(info, value, true);
672 EmbeddedVector<char, 256> buf;
673 int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
674 Variable::Mode2String(var->mode()));
675 if (var->is_qml_global()) {
676 pos += OS::SNPrintF(buf + pos, ":QML");
678 OS::SNPrintF(buf + pos, ")");
679 PrintLiteralIndented(buf.start(), value, true);
684 void AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) {
685 if (labels != NULL && labels->length() > 0) {
686 PrintIndented(info == NULL ? "LABELS" : info);
690 } else if (info != NULL) {
697 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
698 IndentedScope indent(this, s, node);
703 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
705 { IndentedScope indent(this, "FUNC");
706 PrintLiteralIndented("NAME", program->name(), true);
707 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
708 PrintParameters(program->scope());
709 PrintDeclarations(program->scope()->declarations());
710 PrintStatements(program->body());
716 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
717 if (declarations->length() > 0) {
718 IndentedScope indent(this, "DECLS");
719 for (int i = 0; i < declarations->length(); i++) {
720 Visit(declarations->at(i));
726 void AstPrinter::PrintParameters(Scope* scope) {
727 if (scope->num_parameters() > 0) {
728 IndentedScope indent(this, "PARAMS");
729 for (int i = 0; i < scope->num_parameters(); i++) {
730 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
731 scope->parameter(i)->name());
737 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
738 for (int i = 0; i < statements->length(); i++) {
739 Visit(statements->at(i));
744 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
745 for (int i = 0; i < arguments->length(); i++) {
746 Visit(arguments->at(i));
751 void AstPrinter::PrintCaseClause(CaseClause* clause) {
752 if (clause->is_default()) {
753 IndentedScope indent(this, "DEFAULT");
754 PrintStatements(clause->statements());
756 IndentedScope indent(this, "CASE");
757 Visit(clause->label());
758 PrintStatements(clause->statements());
763 void AstPrinter::VisitBlock(Block* node) {
764 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
765 IndentedScope indent(this, block_txt);
766 PrintStatements(node->statements());
770 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
771 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
772 node->proxy()->var(),
773 node->proxy()->name());
777 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
778 PrintIndented("FUNCTION ");
779 PrintLiteral(node->proxy()->name(), true);
780 Print(" = function ");
781 PrintLiteral(node->fun()->name(), false);
786 void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
787 IndentedScope indent(this, "MODULE");
788 PrintLiteralIndented("NAME", node->proxy()->name(), true);
789 Visit(node->module());
793 void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
794 IndentedScope indent(this, "IMPORT");
795 PrintLiteralIndented("NAME", node->proxy()->name(), true);
796 Visit(node->module());
800 void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
801 IndentedScope indent(this, "EXPORT ");
802 PrintLiteral(node->proxy()->name(), true);
806 void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
807 VisitBlock(node->body());
811 void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
812 Visit(node->proxy());
816 void AstPrinter::VisitModulePath(ModulePath* node) {
817 IndentedScope indent(this, "PATH");
818 PrintIndentedVisit("MODULE", node->module());
819 PrintLiteralIndented("NAME", node->name(), false);
823 void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
824 PrintLiteralIndented("URL", node->url(), true);
828 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
829 Visit(node->expression());
833 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
834 PrintIndented("EMPTY\n");
838 void AstPrinter::VisitIfStatement(IfStatement* node) {
839 PrintIndentedVisit("IF", node->condition());
840 PrintIndentedVisit("THEN", node->then_statement());
841 if (node->HasElseStatement()) {
842 PrintIndentedVisit("ELSE", node->else_statement());
847 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
848 PrintLabelsIndented("CONTINUE", node->target()->labels());
852 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
853 PrintLabelsIndented("BREAK", node->target()->labels());
857 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
858 PrintIndentedVisit("RETURN", node->expression());
862 void AstPrinter::VisitWithStatement(WithStatement* node) {
863 IndentedScope indent(this, "WITH");
864 PrintIndentedVisit("OBJECT", node->expression());
865 PrintIndentedVisit("BODY", node->statement());
869 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
870 IndentedScope indent(this, "SWITCH");
871 PrintLabelsIndented(NULL, node->labels());
872 PrintIndentedVisit("TAG", node->tag());
873 for (int i = 0; i < node->cases()->length(); i++) {
874 PrintCaseClause(node->cases()->at(i));
879 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
880 IndentedScope indent(this, "DO");
881 PrintLabelsIndented(NULL, node->labels());
882 PrintIndentedVisit("BODY", node->body());
883 PrintIndentedVisit("COND", node->cond());
887 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
888 IndentedScope indent(this, "WHILE");
889 PrintLabelsIndented(NULL, node->labels());
890 PrintIndentedVisit("COND", node->cond());
891 PrintIndentedVisit("BODY", node->body());
895 void AstPrinter::VisitForStatement(ForStatement* node) {
896 IndentedScope indent(this, "FOR");
897 PrintLabelsIndented(NULL, node->labels());
898 if (node->init()) PrintIndentedVisit("INIT", node->init());
899 if (node->cond()) PrintIndentedVisit("COND", node->cond());
900 PrintIndentedVisit("BODY", node->body());
901 if (node->next()) PrintIndentedVisit("NEXT", node->next());
905 void AstPrinter::VisitForInStatement(ForInStatement* node) {
906 IndentedScope indent(this, "FOR IN");
907 PrintIndentedVisit("FOR", node->each());
908 PrintIndentedVisit("IN", node->enumerable());
909 PrintIndentedVisit("BODY", node->body());
913 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
914 IndentedScope indent(this, "TRY CATCH");
915 PrintIndentedVisit("TRY", node->try_block());
916 PrintLiteralWithModeIndented("CATCHVAR",
918 node->variable()->name());
919 PrintIndentedVisit("CATCH", node->catch_block());
923 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
924 IndentedScope indent(this, "TRY FINALLY");
925 PrintIndentedVisit("TRY", node->try_block());
926 PrintIndentedVisit("FINALLY", node->finally_block());
930 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
931 IndentedScope indent(this, "DEBUGGER");
935 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
936 IndentedScope indent(this, "FUNC LITERAL");
937 PrintLiteralIndented("NAME", node->name(), false);
938 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
939 PrintParameters(node->scope());
940 // We don't want to see the function literal in this case: it
941 // will be printed via PrintProgram when the code for it is
943 // PrintStatements(node->body());
947 void AstPrinter::VisitSharedFunctionInfoLiteral(
948 SharedFunctionInfoLiteral* node) {
949 IndentedScope indent(this, "FUNC LITERAL");
950 PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
954 void AstPrinter::VisitConditional(Conditional* node) {
955 IndentedScope indent(this, "CONDITIONAL");
956 PrintIndentedVisit("?", node->condition());
957 PrintIndentedVisit("THEN", node->then_expression());
958 PrintIndentedVisit("ELSE", node->else_expression());
962 void AstPrinter::VisitLiteral(Literal* node) {
963 PrintLiteralIndented("LITERAL", node->handle(), true);
967 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
968 IndentedScope indent(this, "REGEXP LITERAL");
969 PrintLiteralIndented("PATTERN", node->pattern(), false);
970 PrintLiteralIndented("FLAGS", node->flags(), false);
974 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
975 IndentedScope indent(this, "OBJ LITERAL");
976 for (int i = 0; i < node->properties()->length(); i++) {
977 const char* prop_kind = NULL;
978 switch (node->properties()->at(i)->kind()) {
979 case ObjectLiteral::Property::CONSTANT:
980 prop_kind = "PROPERTY - CONSTANT";
982 case ObjectLiteral::Property::COMPUTED:
983 prop_kind = "PROPERTY - COMPUTED";
985 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
986 prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
988 case ObjectLiteral::Property::PROTOTYPE:
989 prop_kind = "PROPERTY - PROTOTYPE";
991 case ObjectLiteral::Property::GETTER:
992 prop_kind = "PROPERTY - GETTER";
994 case ObjectLiteral::Property::SETTER:
995 prop_kind = "PROPERTY - SETTER";
1000 IndentedScope prop(this, prop_kind);
1001 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
1002 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1007 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1008 IndentedScope indent(this, "ARRAY LITERAL");
1009 if (node->values()->length() > 0) {
1010 IndentedScope indent(this, "VALUES");
1011 for (int i = 0; i < node->values()->length(); i++) {
1012 Visit(node->values()->at(i));
1018 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1019 Variable* var = node->var();
1020 EmbeddedVector<char, 128> buf;
1021 int pos = OS::SNPrintF(buf, "VAR PROXY");
1022 switch (var->location()) {
1023 case Variable::UNALLOCATED:
1025 case Variable::PARAMETER:
1026 OS::SNPrintF(buf + pos, " parameter[%d]", var->index());
1028 case Variable::LOCAL:
1029 OS::SNPrintF(buf + pos, " local[%d]", var->index());
1031 case Variable::CONTEXT:
1032 OS::SNPrintF(buf + pos, " context[%d]", var->index());
1034 case Variable::LOOKUP:
1035 OS::SNPrintF(buf + pos, " lookup");
1038 PrintLiteralWithModeIndented(buf.start(), var, node->name());
1042 void AstPrinter::VisitAssignment(Assignment* node) {
1043 IndentedScope indent(this, Token::Name(node->op()), node);
1044 Visit(node->target());
1045 Visit(node->value());
1049 void AstPrinter::VisitThrow(Throw* node) {
1050 PrintIndentedVisit("THROW", node->exception());
1054 void AstPrinter::VisitProperty(Property* node) {
1055 IndentedScope indent(this, "PROPERTY", node);
1057 Literal* literal = node->key()->AsLiteral();
1058 if (literal != NULL && literal->handle()->IsSymbol()) {
1059 PrintLiteralIndented("NAME", literal->handle(), false);
1061 PrintIndentedVisit("KEY", node->key());
1066 void AstPrinter::VisitCall(Call* node) {
1067 IndentedScope indent(this, "CALL");
1068 Visit(node->expression());
1069 PrintArguments(node->arguments());
1073 void AstPrinter::VisitCallNew(CallNew* node) {
1074 IndentedScope indent(this, "CALL NEW");
1075 Visit(node->expression());
1076 PrintArguments(node->arguments());
1080 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1081 PrintLiteralIndented("CALL RUNTIME ", node->name(), false);
1082 IndentedScope indent(this);
1083 PrintArguments(node->arguments());
1087 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1088 PrintIndentedVisit(Token::Name(node->op()), node->expression());
1092 void AstPrinter::VisitCountOperation(CountOperation* node) {
1093 EmbeddedVector<char, 128> buf;
1094 OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1095 Token::Name(node->op()));
1096 PrintIndentedVisit(buf.start(), node->expression());
1100 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1101 IndentedScope indent(this, Token::Name(node->op()), node);
1102 Visit(node->left());
1103 Visit(node->right());
1107 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1108 IndentedScope indent(this, Token::Name(node->op()), node);
1109 Visit(node->left());
1110 Visit(node->right());
1114 void AstPrinter::VisitThisFunction(ThisFunction* node) {
1115 IndentedScope indent(this, "THIS-FUNCTION");
1120 } } // namespace v8::internal