5 #include "src/ast/prettyprinter.h" 9 #include "src/ast/ast-value-factory.h" 10 #include "src/ast/scopes.h" 11 #include "src/base/platform/platform.h" 12 #include "src/globals.h" 13 #include "src/objects-inl.h" 14 #include "src/string-builder-inl.h" 19 CallPrinter::CallPrinter(Isolate* isolate,
bool is_user_js)
20 : builder_(new IncrementalStringBuilder(isolate)) {
26 is_call_error_ =
false;
27 is_iterator_error_ =
false;
28 is_async_iterator_error_ =
false;
29 is_user_js_ = is_user_js;
30 function_kind_ = kNormalFunction;
31 InitializeAstVisitor(isolate);
34 CallPrinter::~CallPrinter() =
default;
36 CallPrinter::ErrorHint CallPrinter::GetErrorHint()
const {
38 if (is_iterator_error_)
return ErrorHint::kCallAndNormalIterator;
39 if (is_async_iterator_error_)
return ErrorHint::kCallAndAsyncIterator;
41 if (is_iterator_error_)
return ErrorHint::kNormalIterator;
42 if (is_async_iterator_error_)
return ErrorHint::kAsyncIterator;
44 return ErrorHint::kNone;
47 Handle<String> CallPrinter::Print(FunctionLiteral* program,
int position) {
51 return builder_->Finish().ToHandleChecked();
55 void CallPrinter::Find(AstNode* node,
bool print) {
58 int prev_num_prints = num_prints_;
60 if (prev_num_prints != num_prints_)
return;
62 Print(
"(intermediate value)");
68 void CallPrinter::Print(
const char* str) {
69 if (!found_ || done_)
return;
71 builder_->AppendCString(str);
74 void CallPrinter::Print(Handle<String> str) {
75 if (!found_ || done_)
return;
77 builder_->AppendString(str);
80 void CallPrinter::VisitBlock(Block* node) {
81 FindStatements(node->statements());
85 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
88 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
91 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
92 Find(node->expression());
96 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
99 void CallPrinter::VisitSloppyBlockFunctionStatement(
100 SloppyBlockFunctionStatement* node) {
101 Find(node->statement());
105 void CallPrinter::VisitIfStatement(IfStatement* node) {
106 Find(node->condition());
107 Find(node->then_statement());
108 if (node->HasElseStatement()) {
109 Find(node->else_statement());
114 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
117 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
120 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
121 Find(node->expression());
125 void CallPrinter::VisitWithStatement(WithStatement* node) {
126 Find(node->expression());
127 Find(node->statement());
131 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
133 for (CaseClause* clause : *node->cases()) {
134 if (!clause->is_default()) Find(clause->label());
135 FindStatements(clause->statements());
140 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
146 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
152 void CallPrinter::VisitForStatement(ForStatement* node) {
153 if (node->init() !=
nullptr) {
156 if (node->cond() !=
nullptr) Find(node->cond());
157 if (node->next() !=
nullptr) Find(node->next());
162 void CallPrinter::VisitForInStatement(ForInStatement* node) {
164 Find(node->enumerable());
169 void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
170 Find(node->assign_iterator());
171 Find(node->next_result());
172 Find(node->result_done());
173 Find(node->assign_each());
178 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
179 Find(node->try_block());
180 Find(node->catch_block());
184 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
185 Find(node->try_block());
186 Find(node->finally_block());
190 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
193 void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
194 FunctionKind last_function_kind = function_kind_;
195 function_kind_ = node->kind();
196 FindStatements(node->body());
197 function_kind_ = last_function_kind;
201 void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
202 if (node->extends()) Find(node->extends());
203 for (
int i = 0;
i < node->properties()->length();
i++) {
204 Find(node->properties()->at(
i)->value());
208 void CallPrinter::VisitInitializeClassMembersStatement(
209 InitializeClassMembersStatement* node) {
210 for (
int i = 0;
i < node->fields()->length();
i++) {
211 Find(node->fields()->at(
i)->value());
215 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
218 void CallPrinter::VisitDoExpression(DoExpression* node) { Find(node->block()); }
221 void CallPrinter::VisitConditional(Conditional* node) {
222 Find(node->condition());
223 Find(node->then_expression());
224 Find(node->else_expression());
228 void CallPrinter::VisitLiteral(Literal* node) {
231 PrintLiteral(node->BuildValue(isolate_),
true);
235 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
237 PrintLiteral(node->pattern(),
false);
239 if (node->flags() & RegExp::kGlobal) Print(
"g");
240 if (node->flags() & RegExp::kIgnoreCase) Print(
"i");
241 if (node->flags() & RegExp::kMultiline) Print(
"m");
242 if (node->flags() & RegExp::kUnicode) Print(
"u");
243 if (node->flags() & RegExp::kSticky) Print(
"y");
247 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
249 for (
int i = 0;
i < node->properties()->length();
i++) {
250 Find(node->properties()->at(
i)->value());
256 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
258 for (
int i = 0;
i < node->values()->length();
i++) {
259 if (
i != 0) Print(
",");
260 Expression* subexpr = node->values()->at(
i);
261 Spread* spread = subexpr->AsSpread();
262 if (spread !=
nullptr && !found_ &&
263 position_ == spread->expression()->position()) {
265 is_iterator_error_ =
true;
266 Find(spread->expression(),
true);
276 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
278 PrintLiteral(node->name(),
false);
286 void CallPrinter::VisitAssignment(Assignment* node) {
287 Find(node->target());
291 void CallPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
292 VisitAssignment(node);
295 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
297 void CallPrinter::VisitYieldStar(YieldStar* node) {
298 if (!found_ && position_ == node->expression()->position()) {
300 if (IsAsyncFunction(function_kind_))
301 is_async_iterator_error_ =
true;
303 is_iterator_error_ =
true;
306 Find(node->expression());
309 void CallPrinter::VisitAwait(Await* node) { Find(node->expression()); }
311 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
314 void CallPrinter::VisitProperty(Property* node) {
315 Expression* key = node->key();
316 Literal* literal = key->AsLiteral();
317 if (literal !=
nullptr &&
318 literal->BuildValue(isolate_)->IsInternalizedString()) {
319 Find(node->obj(),
true);
323 PrintLiteral(literal->BuildValue(isolate_),
false);
325 Find(node->obj(),
true);
332 void CallPrinter::VisitResolvedProperty(ResolvedProperty* node) {}
334 void CallPrinter::VisitCall(Call* node) {
335 bool was_found =
false;
336 if (node->position() == position_) {
337 is_call_error_ =
true;
343 if (!is_user_js_ && node->expression()->IsVariableProxy()) {
349 Find(node->expression(),
true);
350 if (!was_found) Print(
"(...)");
351 FindArguments(node->arguments());
359 void CallPrinter::VisitCallNew(CallNew* node) {
360 bool was_found =
false;
361 if (node->position() == position_) {
362 is_call_error_ =
true;
368 if (!is_user_js_ && node->expression()->IsVariableProxy()) {
374 Find(node->expression(), was_found);
375 FindArguments(node->arguments());
383 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
384 FindArguments(node->arguments());
388 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
389 Token::Value op = node->op();
391 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
393 Print(Token::String(op));
394 if (needsSpace) Print(
" ");
395 Find(node->expression(),
true);
400 void CallPrinter::VisitCountOperation(CountOperation* node) {
402 if (node->is_prefix()) Print(Token::String(node->op()));
403 Find(node->expression(),
true);
404 if (node->is_postfix()) Print(Token::String(node->op()));
409 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
411 Find(node->left(),
true);
413 Print(Token::String(node->op()));
415 Find(node->right(),
true);
419 void CallPrinter::VisitNaryOperation(NaryOperation* node) {
421 Find(node->first(),
true);
422 for (
size_t i = 0;
i < node->subsequent_length(); ++
i) {
424 Print(Token::String(node->op()));
426 Find(node->subsequent(
i),
true);
431 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
433 Find(node->left(),
true);
435 Print(Token::String(node->op()));
437 Find(node->right(),
true);
442 void CallPrinter::VisitSpread(Spread* node) {
444 Find(node->expression(),
true);
448 void CallPrinter::VisitStoreInArrayLiteral(StoreInArrayLiteral* node) {
454 void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
458 void CallPrinter::VisitGetIterator(GetIterator* node) {
459 bool was_found =
false;
460 if (node->position() == position_) {
461 is_async_iterator_error_ = node->hint() == IteratorType::kAsync;
462 is_iterator_error_ = !is_async_iterator_error_;
468 Find(node->iterable_for_call_printer(),
true);
475 void CallPrinter::VisitGetTemplateObject(GetTemplateObject* node) {}
477 void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
478 for (Expression* substitution : *node->substitutions()) {
479 Find(substitution,
true);
483 void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
484 Print(
"ImportCall(");
485 Find(node->argument(),
true);
489 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
492 void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
495 void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
500 void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
501 Find(node->expression());
504 void CallPrinter::FindStatements(
const ZonePtrList<Statement>* statements) {
505 if (statements ==
nullptr)
return;
506 for (
int i = 0;
i < statements->length();
i++) {
507 Find(statements->at(
i));
511 void CallPrinter::FindArguments(
const ZonePtrList<Expression>* arguments) {
513 for (
int i = 0;
i < arguments->length();
i++) {
514 Find(arguments->at(
i));
518 void CallPrinter::PrintLiteral(Handle<Object> value,
bool quote) {
519 if (value->IsString()) {
520 if (quote) Print(
"\"");
521 Print(Handle<String>::cast(value));
522 if (quote) Print(
"\"");
523 }
else if (value->IsNull(isolate_)) {
525 }
else if (value->IsTrue(isolate_)) {
527 }
else if (value->IsFalse(isolate_)) {
529 }
else if (value->IsUndefined(isolate_)) {
531 }
else if (value->IsNumber()) {
532 Print(isolate_->factory()->NumberToString(value));
533 }
else if (value->IsSymbol()) {
535 PrintLiteral(handle(Handle<Symbol>::cast(value)->name(), isolate_),
false);
540 void CallPrinter::PrintLiteral(
const AstRawString* value,
bool quote) {
541 PrintLiteral(value->string(), quote);
550 const char* AstPrinter::Print(AstNode* node) {
556 void AstPrinter::Init() {
558 DCHECK_NULL(output_);
559 const int initial_size = 256;
560 output_ = NewArray<char>(initial_size);
561 size_ = initial_size;
567 void AstPrinter::Print(
const char* format, ...) {
570 va_start(arguments, format);
571 int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
582 const int slack = 32;
583 int new_size = size_ + (size_ >> 1) + slack;
584 char* new_output = NewArray<char>(new_size);
585 MemCopy(new_output, output_, pos_);
586 DeleteArray(output_);
587 output_ = new_output;
593 void AstPrinter::PrintLabels(ZonePtrList<const AstRawString>* labels) {
594 if (labels !=
nullptr) {
595 for (
int i = 0;
i < labels->length();
i++) {
596 PrintLiteral(labels->at(
i),
false);
602 void AstPrinter::PrintLiteral(Literal* literal,
bool quote) {
603 switch (literal->type()) {
604 case Literal::kString:
605 PrintLiteral(literal->AsRawString(), quote);
607 case Literal::kSymbol:
609 switch (literal->AsSymbol()) {
610 case AstSymbol::kHomeObjectSymbol:
611 symbol =
"HomeObjectSymbol";
616 Print(
"%d", Smi::ToInt(literal->AsSmiLiteral()));
618 case Literal::kHeapNumber:
619 Print(
"%g", literal->AsNumber());
621 case Literal::kBigInt:
622 Print(
"%sn", literal->AsBigInt().c_str());
627 case Literal::kUndefined:
630 case Literal::kTheHole:
633 case Literal::kBoolean:
634 if (literal->ToBooleanIsTrue()) {
643 void AstPrinter::PrintLiteral(
const AstRawString* value,
bool quote) {
644 if (quote) Print(
"\"");
645 if (value !=
nullptr) {
646 const char* format = value->is_one_byte() ?
"%c" :
"%lc";
647 const int increment = value->is_one_byte() ? 1 : 2;
648 const unsigned char* raw_bytes = value->raw_data();
649 for (
int i = 0;
i < value->length();
i += increment) {
650 Print(format, raw_bytes[
i]);
653 if (quote) Print(
"\"");
656 void AstPrinter::PrintLiteral(
const AstConsString* value,
bool quote) {
657 if (quote) Print(
"\"");
658 if (value !=
nullptr) {
659 std::forward_list<const AstRawString*> strings = value->ToRawStrings();
660 for (
const AstRawString*
string : strings) {
661 PrintLiteral(
string,
false);
664 if (quote) Print(
"\"");
669 class IndentedScope {
671 IndentedScope(AstPrinter* printer,
const char* txt)
672 : ast_printer_(printer) {
673 ast_printer_->PrintIndented(txt);
674 ast_printer_->Print(
"\n");
675 ast_printer_->inc_indent();
678 IndentedScope(AstPrinter* printer,
const char* txt,
int pos)
679 : ast_printer_(printer) {
680 ast_printer_->PrintIndented(txt);
681 ast_printer_->Print(
" at %d\n", pos);
682 ast_printer_->inc_indent();
685 virtual ~IndentedScope() {
686 ast_printer_->dec_indent();
690 AstPrinter* ast_printer_;
696 AstPrinter::AstPrinter(
uintptr_t stack_limit)
697 : output_(nullptr), size_(0), pos_(0), indent_(0) {
698 InitializeAstVisitor(stack_limit);
701 AstPrinter::~AstPrinter() {
702 DCHECK_EQ(indent_, 0);
703 DeleteArray(output_);
707 void AstPrinter::PrintIndented(
const char* txt) {
708 for (
int i = 0;
i < indent_;
i++) {
714 void AstPrinter::PrintLiteralIndented(
const char* info, Literal* literal,
718 PrintLiteral(literal, quote);
722 void AstPrinter::PrintLiteralIndented(
const char* info,
723 const AstRawString* value,
bool quote) {
726 PrintLiteral(value, quote);
730 void AstPrinter::PrintLiteralIndented(
const char* info,
731 const AstConsString* value,
bool quote) {
734 PrintLiteral(value, quote);
738 void AstPrinter::PrintLiteralWithModeIndented(
const char* info, Variable* var,
739 const AstRawString* value) {
740 if (var ==
nullptr) {
741 PrintLiteralIndented(info, value,
true);
743 EmbeddedVector<char, 256> buf;
745 SNPrintF(buf,
"%s (%p) (mode = %s", info, reinterpret_cast<void*>(var),
746 VariableMode2String(var->mode()));
747 SNPrintF(buf + pos,
")");
748 PrintLiteralIndented(buf.start(), value,
true);
752 void AstPrinter::PrintLabelsIndented(ZonePtrList<const AstRawString>* labels,
753 const char* prefix) {
754 if (labels ==
nullptr || labels->length() == 0)
return;
755 PrintIndented(prefix);
762 void AstPrinter::PrintIndentedVisit(
const char* s, AstNode* node) {
763 if (node !=
nullptr) {
764 IndentedScope indent(
this, s, node->position());
770 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
772 { IndentedScope indent(
this,
"FUNC", program->position());
773 PrintIndented(
"KIND");
774 Print(
" %d\n", program->kind());
775 PrintIndented(
"SUSPEND COUNT");
776 Print(
" %d\n", program->suspend_count());
777 PrintLiteralIndented(
"NAME", program->raw_name(),
true);
778 if (program->raw_inferred_name()) {
779 PrintLiteralIndented(
"INFERRED NAME", program->raw_inferred_name(),
true);
781 if (program->requires_instance_members_initializer()) {
782 Print(
" REQUIRES INSTANCE FIELDS INITIALIZER\n");
784 PrintParameters(program->scope());
785 PrintDeclarations(program->scope()->declarations());
786 PrintStatements(program->body());
792 void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) {
793 AstPrinter printer(isolate->stack_guard()->real_climit());
796 PrintF(
"%s", printer.output_);
799 void AstPrinter::PrintDeclarations(Declaration::List* declarations) {
800 if (!declarations->is_empty()) {
801 IndentedScope indent(
this,
"DECLS");
802 for (Declaration* decl : *declarations) Visit(decl);
806 void AstPrinter::PrintParameters(DeclarationScope* scope) {
807 if (scope->num_parameters() > 0) {
808 IndentedScope indent(
this,
"PARAMS");
809 for (
int i = 0;
i < scope->num_parameters();
i++) {
810 PrintLiteralWithModeIndented(
"VAR", scope->parameter(
i),
811 scope->parameter(
i)->raw_name());
816 void AstPrinter::PrintStatements(
const ZonePtrList<Statement>* statements) {
817 for (
int i = 0;
i < statements->length();
i++) {
818 Visit(statements->at(
i));
822 void AstPrinter::PrintArguments(
const ZonePtrList<Expression>* arguments) {
823 for (
int i = 0;
i < arguments->length();
i++) {
824 Visit(arguments->at(
i));
829 void AstPrinter::VisitBlock(Block* node) {
830 const char* block_txt =
831 node->ignore_completion_value() ?
"BLOCK NOCOMPLETIONS" :
"BLOCK";
832 IndentedScope indent(
this, block_txt, node->position());
833 PrintLabelsIndented(node->labels());
834 PrintStatements(node->statements());
839 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
840 PrintLiteralWithModeIndented(
"VARIABLE", node->proxy()->var(),
841 node->proxy()->raw_name());
846 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
847 PrintIndented(
"FUNCTION ");
848 PrintLiteral(node->proxy()->raw_name(),
true);
849 Print(
" = function ");
850 PrintLiteral(node->fun()->raw_name(),
false);
855 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
856 IndentedScope indent(
this,
"EXPRESSION STATEMENT", node->position());
857 Visit(node->expression());
861 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
862 IndentedScope indent(
this,
"EMPTY", node->position());
866 void AstPrinter::VisitSloppyBlockFunctionStatement(
867 SloppyBlockFunctionStatement* node) {
868 Visit(node->statement());
872 void AstPrinter::VisitIfStatement(IfStatement* node) {
873 IndentedScope indent(
this,
"IF", node->position());
874 PrintIndentedVisit(
"CONDITION", node->condition());
875 PrintIndentedVisit(
"THEN", node->then_statement());
876 if (node->HasElseStatement()) {
877 PrintIndentedVisit(
"ELSE", node->else_statement());
882 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
883 IndentedScope indent(
this,
"CONTINUE", node->position());
884 PrintLabelsIndented(node->target()->labels());
888 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
889 IndentedScope indent(
this,
"BREAK", node->position());
890 PrintLabelsIndented(node->target()->labels());
894 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
895 IndentedScope indent(
this,
"RETURN", node->position());
896 Visit(node->expression());
900 void AstPrinter::VisitWithStatement(WithStatement* node) {
901 IndentedScope indent(
this,
"WITH", node->position());
902 PrintIndentedVisit(
"OBJECT", node->expression());
903 PrintIndentedVisit(
"BODY", node->statement());
907 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
908 IndentedScope indent(
this,
"SWITCH", node->position());
909 PrintLabelsIndented(node->labels());
910 PrintIndentedVisit(
"TAG", node->tag());
911 for (CaseClause* clause : *node->cases()) {
912 if (clause->is_default()) {
913 IndentedScope indent(
this,
"DEFAULT");
914 PrintStatements(clause->statements());
916 IndentedScope indent(
this,
"CASE");
917 Visit(clause->label());
918 PrintStatements(clause->statements());
924 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
925 IndentedScope indent(
this,
"DO", node->position());
926 PrintLabelsIndented(node->labels());
927 PrintLabelsIndented(node->own_labels(),
"OWN ");
928 PrintIndentedVisit(
"BODY", node->body());
929 PrintIndentedVisit(
"COND", node->cond());
933 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
934 IndentedScope indent(
this,
"WHILE", node->position());
935 PrintLabelsIndented(node->labels());
936 PrintLabelsIndented(node->own_labels(),
"OWN ");
937 PrintIndentedVisit(
"COND", node->cond());
938 PrintIndentedVisit(
"BODY", node->body());
942 void AstPrinter::VisitForStatement(ForStatement* node) {
943 IndentedScope indent(
this,
"FOR", node->position());
944 PrintLabelsIndented(node->labels());
945 PrintLabelsIndented(node->own_labels(),
"OWN ");
946 if (node->init()) PrintIndentedVisit(
"INIT", node->init());
947 if (node->cond()) PrintIndentedVisit(
"COND", node->cond());
948 PrintIndentedVisit(
"BODY", node->body());
949 if (node->next()) PrintIndentedVisit(
"NEXT", node->next());
953 void AstPrinter::VisitForInStatement(ForInStatement* node) {
954 IndentedScope indent(
this,
"FOR IN", node->position());
955 PrintLabelsIndented(node->labels());
956 PrintLabelsIndented(node->own_labels(),
"OWN ");
957 PrintIndentedVisit(
"FOR", node->each());
958 PrintIndentedVisit(
"IN", node->enumerable());
959 PrintIndentedVisit(
"BODY", node->body());
963 void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
964 IndentedScope indent(
this,
"FOR OF", node->position());
965 PrintLabelsIndented(node->labels());
966 PrintLabelsIndented(node->own_labels(),
"OWN ");
967 PrintIndentedVisit(
"INIT", node->assign_iterator());
968 PrintIndentedVisit(
"NEXT", node->next_result());
969 PrintIndentedVisit(
"DONE", node->result_done());
970 PrintIndentedVisit(
"EACH", node->assign_each());
971 PrintIndentedVisit(
"BODY", node->body());
975 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
976 IndentedScope indent(
this,
"TRY CATCH", node->position());
977 PrintIndentedVisit(
"TRY", node->try_block());
978 PrintIndented(
"CATCH PREDICTION");
979 const char* prediction =
"";
980 switch (node->GetCatchPrediction(HandlerTable::UNCAUGHT)) {
981 case HandlerTable::UNCAUGHT:
982 prediction =
"UNCAUGHT";
984 case HandlerTable::CAUGHT:
985 prediction =
"CAUGHT";
987 case HandlerTable::DESUGARING:
988 prediction =
"DESUGARING";
990 case HandlerTable::ASYNC_AWAIT:
991 prediction =
"ASYNC_AWAIT";
993 case HandlerTable::PROMISE:
998 Print(
" %s\n", prediction);
1000 PrintLiteralWithModeIndented(
"CATCHVAR", node->scope()->catch_variable(),
1001 node->scope()->catch_variable()->raw_name());
1003 PrintIndentedVisit(
"CATCH", node->catch_block());
1006 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
1007 IndentedScope indent(
this,
"TRY FINALLY", node->position());
1008 PrintIndentedVisit(
"TRY", node->try_block());
1009 PrintIndentedVisit(
"FINALLY", node->finally_block());
1012 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
1013 IndentedScope indent(
this,
"DEBUGGER", node->position());
1017 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
1018 IndentedScope indent(
this,
"FUNC LITERAL", node->position());
1019 PrintLiteralIndented(
"NAME", node->raw_name(),
false);
1020 PrintLiteralIndented(
"INFERRED NAME", node->raw_inferred_name(),
false);
1021 PrintParameters(node->scope());
1029 void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
1030 IndentedScope indent(
this,
"CLASS LITERAL", node->position());
1031 PrintLiteralIndented(
"NAME", node->constructor()->raw_name(),
false);
1032 if (node->extends() !=
nullptr) {
1033 PrintIndentedVisit(
"EXTENDS", node->extends());
1035 if (node->static_fields_initializer() !=
nullptr) {
1036 PrintIndentedVisit(
"STATIC FIELDS INITIALIZER",
1037 node->static_fields_initializer());
1039 if (node->instance_members_initializer_function() !=
nullptr) {
1040 PrintIndentedVisit(
"INSTANCE ELEMENTS INITIALIZER",
1041 node->instance_members_initializer_function());
1043 PrintClassProperties(node->properties());
1046 void AstPrinter::VisitInitializeClassMembersStatement(
1047 InitializeClassMembersStatement* node) {
1048 IndentedScope indent(
this,
"INITIALIZE CLASS ELEMENTS", node->position());
1049 PrintClassProperties(node->fields());
1052 void AstPrinter::PrintClassProperties(
1053 const ZonePtrList<ClassLiteral::Property>* properties) {
1054 for (
int i = 0;
i < properties->length();
i++) {
1055 ClassLiteral::Property*
property = properties->at(
i);
1056 const char* prop_kind =
nullptr;
1057 switch (property->kind()) {
1058 case ClassLiteral::Property::METHOD:
1059 prop_kind =
"METHOD";
1061 case ClassLiteral::Property::GETTER:
1062 prop_kind =
"GETTER";
1064 case ClassLiteral::Property::SETTER:
1065 prop_kind =
"SETTER";
1067 case ClassLiteral::Property::FIELD:
1068 prop_kind =
"FIELD";
1071 EmbeddedVector<char, 128> buf;
1072 SNPrintF(buf,
"PROPERTY%s%s - %s", property->is_static() ?
" - STATIC" :
"",
1073 property->is_private() ?
" - PRIVATE" :
" - PUBLIC", prop_kind);
1074 IndentedScope prop(
this, buf.start());
1075 PrintIndentedVisit(
"KEY", properties->at(
i)->key());
1076 PrintIndentedVisit(
"VALUE", properties->at(
i)->value());
1081 void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
1082 IndentedScope indent(
this,
"NATIVE FUNC LITERAL", node->position());
1083 PrintLiteralIndented(
"NAME", node->raw_name(),
false);
1087 void AstPrinter::VisitDoExpression(DoExpression* node) {
1088 IndentedScope indent(
this,
"DO EXPRESSION", node->position());
1089 PrintStatements(node->block()->statements());
1093 void AstPrinter::VisitConditional(Conditional* node) {
1094 IndentedScope indent(
this,
"CONDITIONAL", node->position());
1095 PrintIndentedVisit(
"CONDITION", node->condition());
1096 PrintIndentedVisit(
"THEN", node->then_expression());
1097 PrintIndentedVisit(
"ELSE", node->else_expression());
1101 void AstPrinter::VisitLiteral(Literal* node) {
1102 PrintLiteralIndented(
"LITERAL", node,
true);
1106 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1107 IndentedScope indent(
this,
"REGEXP LITERAL", node->position());
1108 PrintLiteralIndented(
"PATTERN", node->raw_pattern(),
false);
1110 EmbeddedVector<char, 128> buf;
1111 if (node->flags() & RegExp::kGlobal) buf[
i++] =
'g';
1112 if (node->flags() & RegExp::kIgnoreCase) buf[
i++] =
'i';
1113 if (node->flags() & RegExp::kMultiline) buf[
i++] =
'm';
1114 if (node->flags() & RegExp::kUnicode) buf[
i++] =
'u';
1115 if (node->flags() & RegExp::kSticky) buf[
i++] =
'y';
1117 PrintIndented(
"FLAGS ");
1118 Print(
"%s", buf.start());
1123 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1124 IndentedScope indent(
this,
"OBJ LITERAL", node->position());
1125 PrintObjectProperties(node->properties());
1128 void AstPrinter::PrintObjectProperties(
1129 const ZonePtrList<ObjectLiteral::Property>* properties) {
1130 for (
int i = 0;
i < properties->length();
i++) {
1131 ObjectLiteral::Property*
property = properties->at(
i);
1132 const char* prop_kind =
nullptr;
1133 switch (property->kind()) {
1134 case ObjectLiteral::Property::CONSTANT:
1135 prop_kind =
"CONSTANT";
1137 case ObjectLiteral::Property::COMPUTED:
1138 prop_kind =
"COMPUTED";
1140 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1141 prop_kind =
"MATERIALIZED_LITERAL";
1143 case ObjectLiteral::Property::PROTOTYPE:
1144 prop_kind =
"PROTOTYPE";
1146 case ObjectLiteral::Property::GETTER:
1147 prop_kind =
"GETTER";
1149 case ObjectLiteral::Property::SETTER:
1150 prop_kind =
"SETTER";
1152 case ObjectLiteral::Property::SPREAD:
1153 prop_kind =
"SPREAD";
1156 EmbeddedVector<char, 128> buf;
1157 SNPrintF(buf,
"PROPERTY - %s", prop_kind);
1158 IndentedScope prop(
this, buf.start());
1159 PrintIndentedVisit(
"KEY", properties->at(
i)->key());
1160 PrintIndentedVisit(
"VALUE", properties->at(
i)->value());
1165 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1166 IndentedScope indent(
this,
"ARRAY LITERAL", node->position());
1167 if (node->values()->length() > 0) {
1168 IndentedScope indent(
this,
"VALUES", node->position());
1169 for (
int i = 0;
i < node->values()->length();
i++) {
1170 Visit(node->values()->at(
i));
1176 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1177 EmbeddedVector<char, 128> buf;
1178 int pos = SNPrintF(buf,
"VAR PROXY");
1180 if (!node->is_resolved()) {
1181 SNPrintF(buf + pos,
" unresolved");
1182 PrintLiteralWithModeIndented(buf.start(),
nullptr, node->raw_name());
1184 Variable* var = node->var();
1185 switch (var->location()) {
1186 case VariableLocation::UNALLOCATED:
1187 SNPrintF(buf + pos,
" unallocated");
1189 case VariableLocation::PARAMETER:
1190 SNPrintF(buf + pos,
" parameter[%d]", var->index());
1192 case VariableLocation::LOCAL:
1193 SNPrintF(buf + pos,
" local[%d]", var->index());
1195 case VariableLocation::CONTEXT:
1196 SNPrintF(buf + pos,
" context[%d]", var->index());
1198 case VariableLocation::LOOKUP:
1199 SNPrintF(buf + pos,
" lookup");
1201 case VariableLocation::MODULE:
1202 SNPrintF(buf + pos,
" module");
1205 PrintLiteralWithModeIndented(buf.start(), var, node->raw_name());
1210 void AstPrinter::VisitAssignment(Assignment* node) {
1211 IndentedScope indent(
this, Token::Name(node->op()), node->position());
1212 Visit(node->target());
1213 Visit(node->value());
1216 void AstPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
1217 VisitAssignment(node);
1220 void AstPrinter::VisitYield(Yield* node) {
1221 EmbeddedVector<char, 128> buf;
1222 SNPrintF(buf,
"YIELD");
1223 IndentedScope indent(
this, buf.start(), node->position());
1224 Visit(node->expression());
1227 void AstPrinter::VisitYieldStar(YieldStar* node) {
1228 EmbeddedVector<char, 128> buf;
1229 SNPrintF(buf,
"YIELD_STAR");
1230 IndentedScope indent(
this, buf.start(), node->position());
1231 Visit(node->expression());
1234 void AstPrinter::VisitAwait(Await* node) {
1235 EmbeddedVector<char, 128> buf;
1236 SNPrintF(buf,
"AWAIT");
1237 IndentedScope indent(
this, buf.start(), node->position());
1238 Visit(node->expression());
1241 void AstPrinter::VisitThrow(Throw* node) {
1242 IndentedScope indent(
this,
"THROW", node->position());
1243 Visit(node->exception());
1246 void AstPrinter::VisitProperty(Property* node) {
1247 EmbeddedVector<char, 128> buf;
1248 SNPrintF(buf,
"PROPERTY");
1249 IndentedScope indent(
this, buf.start(), node->position());
1252 LhsKind property_kind = Property::GetAssignType(node);
1253 if (property_kind == NAMED_PROPERTY ||
1254 property_kind == NAMED_SUPER_PROPERTY) {
1255 PrintLiteralIndented(
"NAME", node->key()->AsLiteral(),
false);
1257 DCHECK(property_kind == KEYED_PROPERTY ||
1258 property_kind == KEYED_SUPER_PROPERTY);
1259 PrintIndentedVisit(
"KEY", node->key());
1263 void AstPrinter::VisitResolvedProperty(ResolvedProperty* node) {
1264 EmbeddedVector<char, 128> buf;
1265 SNPrintF(buf,
"RESOLVED-PROPERTY");
1266 IndentedScope indent(
this, buf.start(), node->position());
1268 PrintIndentedVisit(
"RECEIVER", node->object());
1269 PrintIndentedVisit(
"PROPERTY", node->property());
1272 void AstPrinter::VisitCall(Call* node) {
1273 EmbeddedVector<char, 128> buf;
1274 SNPrintF(buf,
"CALL");
1275 IndentedScope indent(
this, buf.start());
1277 Visit(node->expression());
1278 PrintArguments(node->arguments());
1282 void AstPrinter::VisitCallNew(CallNew* node) {
1283 IndentedScope indent(
this,
"CALL NEW", node->position());
1284 Visit(node->expression());
1285 PrintArguments(node->arguments());
1289 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1290 EmbeddedVector<char, 128> buf;
1291 SNPrintF(buf,
"CALL RUNTIME %s%s", node->debug_name(),
1292 node->is_jsruntime() ?
" (JS function)" :
"");
1293 IndentedScope indent(
this, buf.start(), node->position());
1294 PrintArguments(node->arguments());
1298 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1299 IndentedScope indent(
this, Token::Name(node->op()), node->position());
1300 Visit(node->expression());
1304 void AstPrinter::VisitCountOperation(CountOperation* node) {
1305 EmbeddedVector<char, 128> buf;
1306 SNPrintF(buf,
"%s %s", (node->is_prefix() ?
"PRE" :
"POST"),
1307 Token::Name(node->op()));
1308 IndentedScope indent(
this, buf.start(), node->position());
1309 Visit(node->expression());
1313 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1314 IndentedScope indent(
this, Token::Name(node->op()), node->position());
1315 Visit(node->left());
1316 Visit(node->right());
1319 void AstPrinter::VisitNaryOperation(NaryOperation* node) {
1320 IndentedScope indent(
this, Token::Name(node->op()), node->position());
1321 Visit(node->first());
1322 for (
size_t i = 0;
i < node->subsequent_length(); ++
i) {
1323 Visit(node->subsequent(
i));
1327 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1328 IndentedScope indent(
this, Token::Name(node->op()), node->position());
1329 Visit(node->left());
1330 Visit(node->right());
1334 void AstPrinter::VisitSpread(Spread* node) {
1335 IndentedScope indent(
this,
"SPREAD", node->position());
1336 Visit(node->expression());
1339 void AstPrinter::VisitStoreInArrayLiteral(StoreInArrayLiteral* node) {
1340 IndentedScope indent(
this,
"STORE IN ARRAY LITERAL", node->position());
1341 PrintIndentedVisit(
"ARRAY", node->array());
1342 PrintIndentedVisit(
"INDEX", node->index());
1343 PrintIndentedVisit(
"VALUE", node->value());
1346 void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
1347 IndentedScope indent(
this,
"()", node->position());
1350 void AstPrinter::VisitGetIterator(GetIterator* node) {
1351 IndentedScope indent(
this,
"GET-ITERATOR", node->position());
1352 Visit(node->iterable());
1355 void AstPrinter::VisitGetTemplateObject(GetTemplateObject* node) {
1356 IndentedScope indent(
this,
"GET-TEMPLATE-OBJECT", node->position());
1359 void AstPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
1360 IndentedScope indent(
this,
"TEMPLATE-LITERAL", node->position());
1361 const AstRawString*
string = node->string_parts()->first();
1362 if (!string->IsEmpty()) PrintLiteralIndented(
"SPAN",
string,
true);
1363 for (
int i = 0;
i < node->substitutions()->length();) {
1364 PrintIndentedVisit(
"EXPR", node->substitutions()->at(
i++));
1365 if (i < node->string_parts()->length()) {
1366 string = node->string_parts()->at(
i);
1367 if (!string->IsEmpty()) PrintLiteralIndented(
"SPAN",
string,
true);
1372 void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
1373 IndentedScope indent(
this,
"IMPORT-CALL", node->position());
1374 Visit(node->argument());
1377 void AstPrinter::VisitThisFunction(ThisFunction* node) {
1378 IndentedScope indent(
this,
"THIS-FUNCTION", node->position());
1382 void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
1383 IndentedScope indent(
this,
"SUPER-PROPERTY-REFERENCE", node->position());
1387 void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
1388 IndentedScope indent(
this,
"SUPER-CALL-REFERENCE", node->position());
1392 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
1393 Visit(node->expression());