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
3 // found in the LICENSE file.
9 #include "src/ast-value-factory.h"
10 #include "src/base/platform/platform.h"
11 #include "src/prettyprinter.h"
12 #include "src/scopes.h"
17 CallPrinter::CallPrinter(Isolate* isolate, Zone* zone) {
24 InitializeAstVisitor(isolate, zone);
28 CallPrinter::~CallPrinter() { DeleteArray(output_); }
31 const char* CallPrinter::Print(FunctionLiteral* program, int position) {
39 void CallPrinter::Find(AstNode* node, bool print) {
45 if (start != pos_) return;
47 Print("(intermediate value)");
54 void CallPrinter::Init() {
56 DCHECK(output_ == NULL);
57 const int initial_size = 256;
58 output_ = NewArray<char>(initial_size);
66 void CallPrinter::Print(const char* format, ...) {
67 if (!found_ || done_) return;
70 va_start(arguments, format);
71 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, format, arguments);
75 // there was enough space - we are done
79 // there was not enough space - allocate more and try again
81 int new_size = size_ + (size_ >> 1) + slack;
82 char* new_output = NewArray<char>(new_size);
83 MemCopy(new_output, output_, pos_);
92 void CallPrinter::VisitBlock(Block* node) {
93 FindStatements(node->statements());
97 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
100 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
103 void CallPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
104 Find(node->module());
108 void CallPrinter::VisitImportDeclaration(ImportDeclaration* node) {
109 Find(node->module());
113 void CallPrinter::VisitExportDeclaration(ExportDeclaration* node) {}
116 void CallPrinter::VisitModuleLiteral(ModuleLiteral* node) {
117 VisitBlock(node->body());
121 void CallPrinter::VisitModulePath(ModulePath* node) { Find(node->module()); }
124 void CallPrinter::VisitModuleUrl(ModuleUrl* node) {}
127 void CallPrinter::VisitModuleStatement(ModuleStatement* node) {
132 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
133 Find(node->expression());
137 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
140 void CallPrinter::VisitIfStatement(IfStatement* node) {
141 Find(node->condition());
142 Find(node->then_statement());
143 if (node->HasElseStatement()) {
144 Find(node->else_statement());
149 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
152 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
155 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
156 Find(node->expression());
160 void CallPrinter::VisitWithStatement(WithStatement* node) {
161 Find(node->expression());
162 Find(node->statement());
166 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
168 ZoneList<CaseClause*>* cases = node->cases();
169 for (int i = 0; i < cases->length(); i++) Find(cases->at(i));
173 void CallPrinter::VisitCaseClause(CaseClause* clause) {
174 if (!clause->is_default()) {
175 Find(clause->label());
177 FindStatements(clause->statements());
181 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
187 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
193 void CallPrinter::VisitForStatement(ForStatement* node) {
194 if (node->init() != NULL) {
197 if (node->cond() != NULL) Find(node->cond());
198 if (node->next() != NULL) Find(node->next());
203 void CallPrinter::VisitForInStatement(ForInStatement* node) {
205 Find(node->enumerable());
210 void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
212 Find(node->iterable());
217 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
218 Find(node->try_block());
219 Find(node->catch_block());
223 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
224 Find(node->try_block());
225 Find(node->finally_block());
229 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
232 void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
233 FindStatements(node->body());
237 void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
238 if (node->extends()) Find(node->extends());
239 for (int i = 0; i < node->properties()->length(); i++) {
240 Find(node->properties()->at(i)->value());
245 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
248 void CallPrinter::VisitConditional(Conditional* node) {
249 Find(node->condition());
250 Find(node->then_expression());
251 Find(node->else_expression());
255 void CallPrinter::VisitLiteral(Literal* node) {
256 PrintLiteral(node->value(), true);
260 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
262 PrintLiteral(node->pattern(), false);
264 PrintLiteral(node->flags(), false);
268 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
269 for (int i = 0; i < node->properties()->length(); i++) {
270 Find(node->properties()->at(i)->value());
275 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
277 for (int i = 0; i < node->values()->length(); i++) {
278 if (i != 0) Print(",");
279 Find(node->values()->at(i), true);
285 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
286 PrintLiteral(node->name(), false);
290 void CallPrinter::VisitAssignment(Assignment* node) {
291 Find(node->target());
296 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
299 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
302 void CallPrinter::VisitProperty(Property* node) {
303 Expression* key = node->key();
304 Literal* literal = key->AsLiteral();
305 if (literal != NULL && literal->value()->IsInternalizedString()) {
306 Find(node->obj(), true);
308 PrintLiteral(literal->value(), false);
310 Find(node->obj(), true);
318 void CallPrinter::VisitCall(Call* node) {
319 bool was_found = !found_ && node->position() == position_;
320 if (was_found) found_ = true;
321 Find(node->expression(), true);
322 if (!was_found) Print("(...)");
323 FindArguments(node->arguments());
324 if (was_found) done_ = true;
328 void CallPrinter::VisitCallNew(CallNew* node) {
329 bool was_found = !found_ && node->expression()->position() == position_;
330 if (was_found) found_ = true;
331 Find(node->expression(), was_found);
332 FindArguments(node->arguments());
333 if (was_found) done_ = true;
337 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
338 FindArguments(node->arguments());
342 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
343 Token::Value op = node->op();
345 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
346 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
347 Find(node->expression(), true);
352 void CallPrinter::VisitCountOperation(CountOperation* node) {
354 if (node->is_prefix()) Print("%s", Token::String(node->op()));
355 Find(node->expression(), true);
356 if (node->is_postfix()) Print("%s", Token::String(node->op()));
361 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
363 Find(node->left(), true);
364 Print(" %s ", Token::String(node->op()));
365 Find(node->right(), true);
370 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
372 Find(node->left(), true);
373 Print(" %s ", Token::String(node->op()));
374 Find(node->right(), true);
379 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
382 void CallPrinter::VisitSuperReference(SuperReference* node) {}
385 void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
386 if (statements == NULL) return;
387 for (int i = 0; i < statements->length(); i++) {
388 Find(statements->at(i));
393 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) {
395 for (int i = 0; i < arguments->length(); i++) {
396 Find(arguments->at(i));
401 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
402 Object* object = *value;
403 if (object->IsString()) {
404 String* string = String::cast(object);
405 if (quote) Print("\"");
406 for (int i = 0; i < string->length(); i++) {
407 Print("%c", string->Get(i));
409 if (quote) Print("\"");
410 } else if (object->IsNull()) {
412 } else if (object->IsTrue()) {
414 } else if (object->IsFalse()) {
416 } else if (object->IsUndefined()) {
418 } else if (object->IsNumber()) {
419 Print("%g", object->Number());
424 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
425 PrintLiteral(value->string(), quote);
429 //-----------------------------------------------------------------------------
434 PrettyPrinter::PrettyPrinter(Isolate* isolate, Zone* zone) {
438 InitializeAstVisitor(isolate, zone);
442 PrettyPrinter::~PrettyPrinter() {
443 DeleteArray(output_);
447 void PrettyPrinter::VisitBlock(Block* node) {
448 if (!node->is_initializer_block()) Print("{ ");
449 PrintStatements(node->statements());
450 if (node->statements()->length() > 0) Print(" ");
451 if (!node->is_initializer_block()) Print("}");
455 void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
457 PrintLiteral(node->proxy()->name(), false);
462 void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
464 PrintLiteral(node->proxy()->name(), false);
466 PrintFunctionLiteral(node->fun());
471 void PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
473 PrintLiteral(node->proxy()->name(), false);
475 Visit(node->module());
480 void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
482 PrintLiteral(node->proxy()->name(), false);
484 Visit(node->module());
489 void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
491 PrintLiteral(node->proxy()->name(), false);
496 void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
497 VisitBlock(node->body());
501 void PrettyPrinter::VisitModulePath(ModulePath* node) {
502 Visit(node->module());
504 PrintLiteral(node->name(), false);
508 void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
510 PrintLiteral(node->url(), true);
514 void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
520 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
521 Visit(node->expression());
526 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
531 void PrettyPrinter::VisitIfStatement(IfStatement* node) {
533 Visit(node->condition());
535 Visit(node->then_statement());
536 if (node->HasElseStatement()) {
538 Visit(node->else_statement());
543 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
545 ZoneList<const AstRawString*>* labels = node->target()->labels();
546 if (labels != NULL) {
548 DCHECK(labels->length() > 0); // guaranteed to have at least one entry
549 PrintLiteral(labels->at(0), false); // any label from the list is fine
555 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
557 ZoneList<const AstRawString*>* labels = node->target()->labels();
558 if (labels != NULL) {
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
567 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
569 Visit(node->expression());
574 void PrettyPrinter::VisitWithStatement(WithStatement* node) {
576 Visit(node->expression());
578 Visit(node->statement());
582 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
583 PrintLabels(node->labels());
587 ZoneList<CaseClause*>* cases = node->cases();
588 for (int i = 0; i < cases->length(); i++)
594 void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
595 if (clause->is_default()) {
599 Visit(clause->label());
602 PrintStatements(clause->statements());
603 if (clause->statements()->length() > 0)
608 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
609 PrintLabels(node->labels());
618 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
619 PrintLabels(node->labels());
627 void PrettyPrinter::VisitForStatement(ForStatement* node) {
628 PrintLabels(node->labels());
630 if (node->init() != NULL) {
636 if (node->cond() != NULL) Visit(node->cond());
638 if (node->next() != NULL) {
639 Visit(node->next()); // prints extra ';', unfortunately
640 // to fix: should use Expression for next
647 void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
648 PrintLabels(node->labels());
652 Visit(node->enumerable());
658 void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
659 PrintLabels(node->labels());
663 Visit(node->iterable());
669 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
671 Visit(node->try_block());
673 const bool quote = false;
674 PrintLiteral(node->variable()->name(), quote);
676 Visit(node->catch_block());
680 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
682 Visit(node->try_block());
684 Visit(node->finally_block());
688 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
693 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
695 PrintFunctionLiteral(node);
700 void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) {
702 PrintLiteral(node->name(), false);
703 if (node->extends()) {
705 Visit(node->extends());
708 for (int i = 0; i < node->properties()->length(); i++) {
709 PrintObjectLiteralProperty(node->properties()->at(i));
715 void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
717 PrintLiteral(node->name(), false);
722 void PrettyPrinter::VisitConditional(Conditional* node) {
723 Visit(node->condition());
725 Visit(node->then_expression());
727 Visit(node->else_expression());
731 void PrettyPrinter::VisitLiteral(Literal* node) {
732 PrintLiteral(node->value(), true);
736 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
738 PrintLiteral(node->pattern(), false);
740 PrintLiteral(node->flags(), false);
745 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
747 for (int i = 0; i < node->properties()->length(); i++) {
748 if (i != 0) Print(",");
749 PrintObjectLiteralProperty(node->properties()->at(i));
755 void PrettyPrinter::PrintObjectLiteralProperty(
756 ObjectLiteralProperty* property) {
757 // TODO(arv): Better printing of methods etc.
759 Visit(property->key());
761 Visit(property->value());
765 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
767 for (int i = 0; i < node->values()->length(); i++) {
768 if (i != 0) Print(",");
769 Visit(node->values()->at(i));
775 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
776 PrintLiteral(node->name(), false);
780 void PrettyPrinter::VisitAssignment(Assignment* node) {
781 Visit(node->target());
782 Print(" %s ", Token::String(node->op()));
783 Visit(node->value());
787 void PrettyPrinter::VisitYield(Yield* node) {
789 Visit(node->expression());
793 void PrettyPrinter::VisitThrow(Throw* node) {
795 Visit(node->exception());
799 void PrettyPrinter::VisitProperty(Property* node) {
800 Expression* key = node->key();
801 Literal* literal = key->AsLiteral();
802 if (literal != NULL && literal->value()->IsInternalizedString()) {
806 PrintLiteral(literal->value(), false);
816 void PrettyPrinter::VisitCall(Call* node) {
817 Visit(node->expression());
818 PrintArguments(node->arguments());
822 void PrettyPrinter::VisitCallNew(CallNew* node) {
824 Visit(node->expression());
826 PrintArguments(node->arguments());
830 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
832 PrintLiteral(node->name(), false);
833 PrintArguments(node->arguments());
837 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
838 Token::Value op = node->op();
840 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
841 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
842 Visit(node->expression());
847 void PrettyPrinter::VisitCountOperation(CountOperation* node) {
849 if (node->is_prefix()) Print("%s", Token::String(node->op()));
850 Visit(node->expression());
851 if (node->is_postfix()) Print("%s", Token::String(node->op()));
856 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
859 Print(" %s ", Token::String(node->op()));
860 Visit(node->right());
865 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
868 Print(" %s ", Token::String(node->op()));
869 Visit(node->right());
874 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
875 Print("<this-function>");
879 void PrettyPrinter::VisitSuperReference(SuperReference* node) {
880 Print("<super-reference>");
884 const char* PrettyPrinter::Print(AstNode* node) {
891 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
893 ExpressionStatement* statement =
894 program->body()->at(0)->AsExpressionStatement();
895 Visit(statement->expression());
900 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
902 PrintStatements(program->body());
908 void PrettyPrinter::PrintOut(Isolate* isolate, Zone* zone, AstNode* node) {
909 PrettyPrinter printer(isolate, zone);
910 PrintF("%s", printer.Print(node));
914 void PrettyPrinter::Init() {
916 DCHECK(output_ == NULL);
917 const int initial_size = 256;
918 output_ = NewArray<char>(initial_size);
919 size_ = initial_size;
926 void PrettyPrinter::Print(const char* format, ...) {
929 va_start(arguments, format);
930 int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
936 // there was enough space - we are done
940 // there was not enough space - allocate more and try again
941 const int slack = 32;
942 int new_size = size_ + (size_ >> 1) + slack;
943 char* new_output = NewArray<char>(new_size);
944 MemCopy(new_output, output_, pos_);
945 DeleteArray(output_);
946 output_ = new_output;
953 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
954 if (statements == NULL) return;
955 for (int i = 0; i < statements->length(); i++) {
956 if (i != 0) Print(" ");
957 Visit(statements->at(i));
962 void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
963 if (labels != NULL) {
964 for (int i = 0; i < labels->length(); i++) {
965 PrintLiteral(labels->at(i), false);
972 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
974 for (int i = 0; i < arguments->length(); i++) {
975 if (i != 0) Print(", ");
976 Visit(arguments->at(i));
982 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
983 Object* object = *value;
984 if (object->IsString()) {
985 String* string = String::cast(object);
986 if (quote) Print("\"");
987 for (int i = 0; i < string->length(); i++) {
988 Print("%c", string->Get(i));
990 if (quote) Print("\"");
991 } else if (object->IsNull()) {
993 } else if (object->IsTrue()) {
995 } else if (object->IsFalse()) {
997 } else if (object->IsUndefined()) {
999 } else if (object->IsNumber()) {
1000 Print("%g", object->Number());
1001 } else if (object->IsJSObject()) {
1002 // regular expression
1003 if (object->IsJSFunction()) {
1004 Print("JS-Function");
1005 } else if (object->IsJSArray()) {
1006 Print("JS-array[%u]", JSArray::cast(object)->length());
1007 } else if (object->IsJSObject()) {
1012 } else if (object->IsFixedArray()) {
1013 Print("FixedArray");
1015 Print("<unknown literal %p>", object);
1020 void PrettyPrinter::PrintLiteral(const AstRawString* value, bool quote) {
1021 PrintLiteral(value->string(), quote);
1025 void PrettyPrinter::PrintParameters(Scope* scope) {
1027 for (int i = 0; i < scope->num_parameters(); i++) {
1028 if (i > 0) Print(", ");
1029 PrintLiteral(scope->parameter(i)->name(), false);
1035 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
1036 for (int i = 0; i < declarations->length(); i++) {
1037 if (i > 0) Print(" ");
1038 Visit(declarations->at(i));
1043 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
1045 PrintLiteral(function->name(), false);
1046 PrintParameters(function->scope());
1048 PrintDeclarations(function->scope()->declarations());
1049 PrintStatements(function->body());
1054 //-----------------------------------------------------------------------------
1056 class IndentedScope BASE_EMBEDDED {
1058 IndentedScope(AstPrinter* printer, const char* txt)
1059 : ast_printer_(printer) {
1060 ast_printer_->PrintIndented(txt);
1061 ast_printer_->Print("\n");
1062 ast_printer_->inc_indent();
1065 virtual ~IndentedScope() {
1066 ast_printer_->dec_indent();
1070 AstPrinter* ast_printer_;
1074 //-----------------------------------------------------------------------------
1077 AstPrinter::AstPrinter(Isolate* isolate, Zone* zone)
1078 : PrettyPrinter(isolate, zone), indent_(0) {}
1081 AstPrinter::~AstPrinter() {
1082 DCHECK(indent_ == 0);
1086 void AstPrinter::PrintIndented(const char* txt) {
1087 for (int i = 0; i < indent_; i++) {
1094 void AstPrinter::PrintLiteralIndented(const char* info,
1095 Handle<Object> value,
1097 PrintIndented(info);
1099 PrintLiteral(value, quote);
1104 void AstPrinter::PrintLiteralWithModeIndented(const char* info,
1106 Handle<Object> value) {
1108 PrintLiteralIndented(info, value, true);
1110 EmbeddedVector<char, 256> buf;
1111 int pos = SNPrintF(buf, "%s (mode = %s", info,
1112 Variable::Mode2String(var->mode()));
1113 SNPrintF(buf + pos, ")");
1114 PrintLiteralIndented(buf.start(), value, true);
1119 void AstPrinter::PrintLabelsIndented(ZoneList<const AstRawString*>* labels) {
1120 if (labels == NULL || labels->length() == 0) return;
1121 PrintIndented("LABELS ");
1122 PrintLabels(labels);
1127 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
1128 IndentedScope indent(this, s);
1133 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
1135 { IndentedScope indent(this, "FUNC");
1136 PrintLiteralIndented("NAME", program->name(), true);
1137 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
1138 PrintParameters(program->scope());
1139 PrintDeclarations(program->scope()->declarations());
1140 PrintStatements(program->body());
1146 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
1147 if (declarations->length() > 0) {
1148 IndentedScope indent(this, "DECLS");
1149 for (int i = 0; i < declarations->length(); i++) {
1150 Visit(declarations->at(i));
1156 void AstPrinter::PrintParameters(Scope* scope) {
1157 if (scope->num_parameters() > 0) {
1158 IndentedScope indent(this, "PARAMS");
1159 for (int i = 0; i < scope->num_parameters(); i++) {
1160 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
1161 scope->parameter(i)->name());
1167 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
1168 for (int i = 0; i < statements->length(); i++) {
1169 Visit(statements->at(i));
1174 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
1175 for (int i = 0; i < arguments->length(); i++) {
1176 Visit(arguments->at(i));
1181 void AstPrinter::VisitBlock(Block* node) {
1182 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
1183 IndentedScope indent(this, block_txt);
1184 PrintStatements(node->statements());
1188 // TODO(svenpanne) Start with IndentedScope.
1189 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
1190 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
1191 node->proxy()->var(),
1192 node->proxy()->name());
1196 // TODO(svenpanne) Start with IndentedScope.
1197 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
1198 PrintIndented("FUNCTION ");
1199 PrintLiteral(node->proxy()->name(), true);
1200 Print(" = function ");
1201 PrintLiteral(node->fun()->name(), false);
1206 void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
1207 IndentedScope indent(this, "MODULE");
1208 PrintLiteralIndented("NAME", node->proxy()->name(), true);
1209 Visit(node->module());
1213 void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
1214 IndentedScope indent(this, "IMPORT");
1215 PrintLiteralIndented("NAME", node->proxy()->name(), true);
1216 Visit(node->module());
1220 void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
1221 IndentedScope indent(this, "EXPORT ");
1222 PrintLiteral(node->proxy()->name(), true);
1226 void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
1227 IndentedScope indent(this, "MODULE LITERAL");
1228 VisitBlock(node->body());
1232 void AstPrinter::VisitModulePath(ModulePath* node) {
1233 IndentedScope indent(this, "MODULE PATH");
1234 PrintIndentedVisit("MODULE PATH PARENT", node->module());
1235 PrintLiteralIndented("NAME", node->name(), true);
1239 void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
1240 PrintLiteralIndented("URL", node->url(), true);
1244 void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
1245 IndentedScope indent(this, "MODULE STATEMENT");
1246 PrintStatements(node->body()->statements());
1250 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
1251 IndentedScope indent(this, "EXPRESSION STATEMENT");
1252 Visit(node->expression());
1256 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
1257 IndentedScope indent(this, "EMPTY");
1261 void AstPrinter::VisitIfStatement(IfStatement* node) {
1262 IndentedScope indent(this, "IF");
1263 PrintIndentedVisit("CONDITION", node->condition());
1264 PrintIndentedVisit("THEN", node->then_statement());
1265 if (node->HasElseStatement()) {
1266 PrintIndentedVisit("ELSE", node->else_statement());
1271 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
1272 IndentedScope indent(this, "CONTINUE");
1273 PrintLabelsIndented(node->target()->labels());
1277 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
1278 IndentedScope indent(this, "BREAK");
1279 PrintLabelsIndented(node->target()->labels());
1283 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
1284 IndentedScope indent(this, "RETURN");
1285 Visit(node->expression());
1289 void AstPrinter::VisitWithStatement(WithStatement* node) {
1290 IndentedScope indent(this, "WITH");
1291 PrintIndentedVisit("OBJECT", node->expression());
1292 PrintIndentedVisit("BODY", node->statement());
1296 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
1297 IndentedScope indent(this, "SWITCH");
1298 PrintLabelsIndented(node->labels());
1299 PrintIndentedVisit("TAG", node->tag());
1300 for (int i = 0; i < node->cases()->length(); i++) {
1301 Visit(node->cases()->at(i));
1306 void AstPrinter::VisitCaseClause(CaseClause* clause) {
1307 if (clause->is_default()) {
1308 IndentedScope indent(this, "DEFAULT");
1309 PrintStatements(clause->statements());
1311 IndentedScope indent(this, "CASE");
1312 Visit(clause->label());
1313 PrintStatements(clause->statements());
1318 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
1319 IndentedScope indent(this, "DO");
1320 PrintLabelsIndented(node->labels());
1321 PrintIndentedVisit("BODY", node->body());
1322 PrintIndentedVisit("COND", node->cond());
1326 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
1327 IndentedScope indent(this, "WHILE");
1328 PrintLabelsIndented(node->labels());
1329 PrintIndentedVisit("COND", node->cond());
1330 PrintIndentedVisit("BODY", node->body());
1334 void AstPrinter::VisitForStatement(ForStatement* node) {
1335 IndentedScope indent(this, "FOR");
1336 PrintLabelsIndented(node->labels());
1337 if (node->init()) PrintIndentedVisit("INIT", node->init());
1338 if (node->cond()) PrintIndentedVisit("COND", node->cond());
1339 PrintIndentedVisit("BODY", node->body());
1340 if (node->next()) PrintIndentedVisit("NEXT", node->next());
1344 void AstPrinter::VisitForInStatement(ForInStatement* node) {
1345 IndentedScope indent(this, "FOR IN");
1346 PrintIndentedVisit("FOR", node->each());
1347 PrintIndentedVisit("IN", node->enumerable());
1348 PrintIndentedVisit("BODY", node->body());
1352 void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
1353 IndentedScope indent(this, "FOR OF");
1354 PrintIndentedVisit("FOR", node->each());
1355 PrintIndentedVisit("OF", node->iterable());
1356 PrintIndentedVisit("BODY", node->body());
1360 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
1361 IndentedScope indent(this, "TRY CATCH");
1362 PrintIndentedVisit("TRY", node->try_block());
1363 PrintLiteralWithModeIndented("CATCHVAR",
1365 node->variable()->name());
1366 PrintIndentedVisit("CATCH", node->catch_block());
1370 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
1371 IndentedScope indent(this, "TRY FINALLY");
1372 PrintIndentedVisit("TRY", node->try_block());
1373 PrintIndentedVisit("FINALLY", node->finally_block());
1377 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
1378 IndentedScope indent(this, "DEBUGGER");
1382 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
1383 IndentedScope indent(this, "FUNC LITERAL");
1384 PrintLiteralIndented("NAME", node->name(), false);
1385 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
1386 PrintParameters(node->scope());
1387 // We don't want to see the function literal in this case: it
1388 // will be printed via PrintProgram when the code for it is
1390 // PrintStatements(node->body());
1394 void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
1395 IndentedScope indent(this, "CLASS LITERAL");
1396 PrintLiteralIndented("NAME", node->name(), false);
1400 void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
1401 IndentedScope indent(this, "NATIVE FUNC LITERAL");
1402 PrintLiteralIndented("NAME", node->name(), false);
1406 void AstPrinter::VisitConditional(Conditional* node) {
1407 IndentedScope indent(this, "CONDITIONAL");
1408 PrintIndentedVisit("CONDITION", node->condition());
1409 PrintIndentedVisit("THEN", node->then_expression());
1410 PrintIndentedVisit("ELSE", node->else_expression());
1414 // TODO(svenpanne) Start with IndentedScope.
1415 void AstPrinter::VisitLiteral(Literal* node) {
1416 PrintLiteralIndented("LITERAL", node->value(), true);
1420 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1421 IndentedScope indent(this, "REGEXP LITERAL");
1422 PrintLiteralIndented("PATTERN", node->pattern(), false);
1423 PrintLiteralIndented("FLAGS", node->flags(), false);
1427 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1428 IndentedScope indent(this, "OBJ LITERAL");
1429 for (int i = 0; i < node->properties()->length(); i++) {
1430 const char* prop_kind = NULL;
1431 switch (node->properties()->at(i)->kind()) {
1432 case ObjectLiteral::Property::CONSTANT:
1433 prop_kind = "PROPERTY - CONSTANT";
1435 case ObjectLiteral::Property::COMPUTED:
1436 prop_kind = "PROPERTY - COMPUTED";
1438 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1439 prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
1441 case ObjectLiteral::Property::PROTOTYPE:
1442 prop_kind = "PROPERTY - PROTOTYPE";
1444 case ObjectLiteral::Property::GETTER:
1445 prop_kind = "PROPERTY - GETTER";
1447 case ObjectLiteral::Property::SETTER:
1448 prop_kind = "PROPERTY - SETTER";
1453 IndentedScope prop(this, prop_kind);
1454 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
1455 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1460 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1461 IndentedScope indent(this, "ARRAY LITERAL");
1462 if (node->values()->length() > 0) {
1463 IndentedScope indent(this, "VALUES");
1464 for (int i = 0; i < node->values()->length(); i++) {
1465 Visit(node->values()->at(i));
1471 // TODO(svenpanne) Start with IndentedScope.
1472 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1473 Variable* var = node->var();
1474 EmbeddedVector<char, 128> buf;
1475 int pos = SNPrintF(buf, "VAR PROXY");
1476 switch (var->location()) {
1477 case Variable::UNALLOCATED:
1479 case Variable::PARAMETER:
1480 SNPrintF(buf + pos, " parameter[%d]", var->index());
1482 case Variable::LOCAL:
1483 SNPrintF(buf + pos, " local[%d]", var->index());
1485 case Variable::CONTEXT:
1486 SNPrintF(buf + pos, " context[%d]", var->index());
1488 case Variable::LOOKUP:
1489 SNPrintF(buf + pos, " lookup");
1492 PrintLiteralWithModeIndented(buf.start(), var, node->name());
1496 void AstPrinter::VisitAssignment(Assignment* node) {
1497 IndentedScope indent(this, Token::Name(node->op()));
1498 Visit(node->target());
1499 Visit(node->value());
1503 void AstPrinter::VisitYield(Yield* node) {
1504 IndentedScope indent(this, "YIELD");
1505 Visit(node->expression());
1509 void AstPrinter::VisitThrow(Throw* node) {
1510 IndentedScope indent(this, "THROW");
1511 Visit(node->exception());
1515 void AstPrinter::VisitProperty(Property* node) {
1516 IndentedScope indent(this, "PROPERTY");
1518 Literal* literal = node->key()->AsLiteral();
1519 if (literal != NULL && literal->value()->IsInternalizedString()) {
1520 PrintLiteralIndented("NAME", literal->value(), false);
1522 PrintIndentedVisit("KEY", node->key());
1527 void AstPrinter::VisitCall(Call* node) {
1528 IndentedScope indent(this, "CALL");
1529 Visit(node->expression());
1530 PrintArguments(node->arguments());
1534 void AstPrinter::VisitCallNew(CallNew* node) {
1535 IndentedScope indent(this, "CALL NEW");
1536 Visit(node->expression());
1537 PrintArguments(node->arguments());
1541 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1542 IndentedScope indent(this, "CALL RUNTIME");
1543 PrintLiteralIndented("NAME", node->name(), false);
1544 PrintArguments(node->arguments());
1548 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1549 IndentedScope indent(this, Token::Name(node->op()));
1550 Visit(node->expression());
1554 void AstPrinter::VisitCountOperation(CountOperation* node) {
1555 EmbeddedVector<char, 128> buf;
1556 SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1557 Token::Name(node->op()));
1558 IndentedScope indent(this, buf.start());
1559 Visit(node->expression());
1563 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1564 IndentedScope indent(this, Token::Name(node->op()));
1565 Visit(node->left());
1566 Visit(node->right());
1570 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1571 IndentedScope indent(this, Token::Name(node->op()));
1572 Visit(node->left());
1573 Visit(node->right());
1577 void AstPrinter::VisitThisFunction(ThisFunction* node) {
1578 IndentedScope indent(this, "THIS-FUNCTION");
1582 void AstPrinter::VisitSuperReference(SuperReference* node) {
1583 IndentedScope indent(this, "SUPER-REFERENCE");
1588 } } // namespace v8::internal