Home | History | Annotate | Download | only in ast
      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.
      4 
      5 #include "src/ast/prettyprinter.h"
      6 
      7 #include <stdarg.h>
      8 
      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"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 
     19 CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js)
     20     : builder_(new IncrementalStringBuilder(isolate)) {
     21   isolate_ = isolate;
     22   position_ = 0;
     23   num_prints_ = 0;
     24   found_ = false;
     25   done_ = false;
     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);
     32 }
     33 
     34 CallPrinter::~CallPrinter() {}
     35 
     36 CallPrinter::ErrorHint CallPrinter::GetErrorHint() const {
     37   if (is_call_error_) {
     38     if (is_iterator_error_) return ErrorHint::kCallAndNormalIterator;
     39     if (is_async_iterator_error_) return ErrorHint::kCallAndAsyncIterator;
     40   } else {
     41     if (is_iterator_error_) return ErrorHint::kNormalIterator;
     42     if (is_async_iterator_error_) return ErrorHint::kAsyncIterator;
     43   }
     44   return ErrorHint::kNone;
     45 }
     46 
     47 Handle<String> CallPrinter::Print(FunctionLiteral* program, int position) {
     48   num_prints_ = 0;
     49   position_ = position;
     50   Find(program);
     51   return builder_->Finish().ToHandleChecked();
     52 }
     53 
     54 
     55 void CallPrinter::Find(AstNode* node, bool print) {
     56   if (found_) {
     57     if (print) {
     58       int prev_num_prints = num_prints_;
     59       Visit(node);
     60       if (prev_num_prints != num_prints_) return;
     61     }
     62     Print("(intermediate value)");
     63   } else {
     64     Visit(node);
     65   }
     66 }
     67 
     68 void CallPrinter::Print(const char* str) {
     69   if (!found_ || done_) return;
     70   num_prints_++;
     71   builder_->AppendCString(str);
     72 }
     73 
     74 void CallPrinter::Print(Handle<String> str) {
     75   if (!found_ || done_) return;
     76   num_prints_++;
     77   builder_->AppendString(str);
     78 }
     79 
     80 void CallPrinter::VisitBlock(Block* node) {
     81   FindStatements(node->statements());
     82 }
     83 
     84 
     85 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
     86 
     87 
     88 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
     89 
     90 
     91 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
     92   Find(node->expression());
     93 }
     94 
     95 
     96 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
     97 
     98 
     99 void CallPrinter::VisitSloppyBlockFunctionStatement(
    100     SloppyBlockFunctionStatement* node) {
    101   Find(node->statement());
    102 }
    103 
    104 
    105 void CallPrinter::VisitIfStatement(IfStatement* node) {
    106   Find(node->condition());
    107   Find(node->then_statement());
    108   if (node->HasElseStatement()) {
    109     Find(node->else_statement());
    110   }
    111 }
    112 
    113 
    114 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
    115 
    116 
    117 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
    118 
    119 
    120 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
    121   Find(node->expression());
    122 }
    123 
    124 
    125 void CallPrinter::VisitWithStatement(WithStatement* node) {
    126   Find(node->expression());
    127   Find(node->statement());
    128 }
    129 
    130 
    131 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
    132   Find(node->tag());
    133   for (CaseClause* clause : *node->cases()) {
    134     if (!clause->is_default()) Find(clause->label());
    135     FindStatements(clause->statements());
    136   }
    137 }
    138 
    139 
    140 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
    141   Find(node->body());
    142   Find(node->cond());
    143 }
    144 
    145 
    146 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
    147   Find(node->cond());
    148   Find(node->body());
    149 }
    150 
    151 
    152 void CallPrinter::VisitForStatement(ForStatement* node) {
    153   if (node->init() != nullptr) {
    154     Find(node->init());
    155   }
    156   if (node->cond() != nullptr) Find(node->cond());
    157   if (node->next() != nullptr) Find(node->next());
    158   Find(node->body());
    159 }
    160 
    161 
    162 void CallPrinter::VisitForInStatement(ForInStatement* node) {
    163   Find(node->each());
    164   Find(node->enumerable());
    165   Find(node->body());
    166 }
    167 
    168 
    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());
    174   Find(node->body());
    175 }
    176 
    177 
    178 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
    179   Find(node->try_block());
    180   Find(node->catch_block());
    181 }
    182 
    183 
    184 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
    185   Find(node->try_block());
    186   Find(node->finally_block());
    187 }
    188 
    189 
    190 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
    191 
    192 
    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;
    198 }
    199 
    200 
    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());
    205   }
    206 }
    207 
    208 void CallPrinter::VisitInitializeClassFieldsStatement(
    209     InitializeClassFieldsStatement* node) {
    210   for (int i = 0; i < node->fields()->length(); i++) {
    211     Find(node->fields()->at(i)->value());
    212   }
    213 }
    214 
    215 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
    216 
    217 
    218 void CallPrinter::VisitDoExpression(DoExpression* node) { Find(node->block()); }
    219 
    220 
    221 void CallPrinter::VisitConditional(Conditional* node) {
    222   Find(node->condition());
    223   Find(node->then_expression());
    224   Find(node->else_expression());
    225 }
    226 
    227 
    228 void CallPrinter::VisitLiteral(Literal* node) {
    229   // TODO(adamk): Teach Literal how to print its values without
    230   // allocating on the heap.
    231   PrintLiteral(node->BuildValue(isolate_), true);
    232 }
    233 
    234 
    235 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
    236   Print("/");
    237   PrintLiteral(node->pattern(), false);
    238   Print("/");
    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");
    244 }
    245 
    246 
    247 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
    248   Print("{");
    249   for (int i = 0; i < node->properties()->length(); i++) {
    250     Find(node->properties()->at(i)->value());
    251   }
    252   Print("}");
    253 }
    254 
    255 
    256 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
    257   Print("[");
    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()) {
    264       found_ = true;
    265       is_iterator_error_ = true;
    266       Find(spread->expression(), true);
    267       done_ = true;
    268       return;
    269     }
    270     Find(subexpr, true);
    271   }
    272   Print("]");
    273 }
    274 
    275 
    276 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
    277   if (is_user_js_) {
    278     PrintLiteral(node->name(), false);
    279   } else {
    280     // Variable names of non-user code are meaningless due to minification.
    281     Print("(var)");
    282   }
    283 }
    284 
    285 
    286 void CallPrinter::VisitAssignment(Assignment* node) {
    287   Find(node->target());
    288   Find(node->value());
    289 }
    290 
    291 void CallPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
    292   VisitAssignment(node);
    293 }
    294 
    295 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
    296 
    297 void CallPrinter::VisitYieldStar(YieldStar* node) {
    298   if (!found_ && position_ == node->expression()->position()) {
    299     found_ = true;
    300     if (IsAsyncFunction(function_kind_))
    301       is_async_iterator_error_ = true;
    302     else
    303       is_iterator_error_ = true;
    304     Print("yield* ");
    305   }
    306   Find(node->expression());
    307 }
    308 
    309 void CallPrinter::VisitAwait(Await* node) { Find(node->expression()); }
    310 
    311 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
    312 
    313 
    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);
    320     Print(".");
    321     // TODO(adamk): Teach Literal how to print its values without
    322     // allocating on the heap.
    323     PrintLiteral(literal->BuildValue(isolate_), false);
    324   } else {
    325     Find(node->obj(), true);
    326     Print("[");
    327     Find(key, true);
    328     Print("]");
    329   }
    330 }
    331 
    332 void CallPrinter::VisitResolvedProperty(ResolvedProperty* node) {}
    333 
    334 void CallPrinter::VisitCall(Call* node) {
    335   bool was_found = false;
    336   if (node->position() == position_) {
    337     is_call_error_ = true;
    338     was_found = !found_;
    339   }
    340   if (was_found) {
    341     // Bail out if the error is caused by a direct call to a variable in
    342     // non-user JS code. The variable name is meaningless due to minification.
    343     if (!is_user_js_ && node->expression()->IsVariableProxy()) {
    344       done_ = true;
    345       return;
    346     }
    347     found_ = true;
    348   }
    349   Find(node->expression(), true);
    350   if (!was_found) Print("(...)");
    351   FindArguments(node->arguments());
    352   if (was_found) {
    353     done_ = true;
    354     found_ = false;
    355   }
    356 }
    357 
    358 
    359 void CallPrinter::VisitCallNew(CallNew* node) {
    360   bool was_found = false;
    361   if (node->position() == position_) {
    362     is_call_error_ = true;
    363     was_found = !found_;
    364   }
    365   if (was_found) {
    366     // Bail out if the error is caused by a direct call to a variable in
    367     // non-user JS code. The variable name is meaningless due to minification.
    368     if (!is_user_js_ && node->expression()->IsVariableProxy()) {
    369       done_ = true;
    370       return;
    371     }
    372     found_ = true;
    373   }
    374   Find(node->expression(), was_found);
    375   FindArguments(node->arguments());
    376   if (was_found) {
    377     done_ = true;
    378     found_ = false;
    379   }
    380 }
    381 
    382 
    383 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
    384   FindArguments(node->arguments());
    385 }
    386 
    387 
    388 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
    389   Token::Value op = node->op();
    390   bool needsSpace =
    391       op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
    392   Print("(");
    393   Print(Token::String(op));
    394   if (needsSpace) Print(" ");
    395   Find(node->expression(), true);
    396   Print(")");
    397 }
    398 
    399 
    400 void CallPrinter::VisitCountOperation(CountOperation* node) {
    401   Print("(");
    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()));
    405   Print(")");
    406 }
    407 
    408 
    409 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
    410   Print("(");
    411   Find(node->left(), true);
    412   Print(" ");
    413   Print(Token::String(node->op()));
    414   Print(" ");
    415   Find(node->right(), true);
    416   Print(")");
    417 }
    418 
    419 void CallPrinter::VisitNaryOperation(NaryOperation* node) {
    420   Print("(");
    421   Find(node->first(), true);
    422   for (size_t i = 0; i < node->subsequent_length(); ++i) {
    423     Print(" ");
    424     Print(Token::String(node->op()));
    425     Print(" ");
    426     Find(node->subsequent(i), true);
    427   }
    428   Print(")");
    429 }
    430 
    431 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
    432   Print("(");
    433   Find(node->left(), true);
    434   Print(" ");
    435   Print(Token::String(node->op()));
    436   Print(" ");
    437   Find(node->right(), true);
    438   Print(")");
    439 }
    440 
    441 
    442 void CallPrinter::VisitSpread(Spread* node) {
    443   Print("(...");
    444   Find(node->expression(), true);
    445   Print(")");
    446 }
    447 
    448 void CallPrinter::VisitStoreInArrayLiteral(StoreInArrayLiteral* node) {
    449   Find(node->array());
    450   Find(node->index());
    451   Find(node->value());
    452 }
    453 
    454 void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
    455   UNREACHABLE();
    456 }
    457 
    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_;
    463     was_found = !found_;
    464     if (was_found) {
    465       found_ = true;
    466     }
    467   }
    468   Find(node->iterable_for_call_printer(), true);
    469   if (was_found) {
    470     done_ = true;
    471     found_ = false;
    472   }
    473 }
    474 
    475 void CallPrinter::VisitGetTemplateObject(GetTemplateObject* node) {}
    476 
    477 void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
    478   for (Expression* substitution : *node->substitutions()) {
    479     Find(substitution, true);
    480   }
    481 }
    482 
    483 void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
    484   Print("ImportCall(");
    485   Find(node->argument(), true);
    486   Print(")");
    487 }
    488 
    489 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
    490 
    491 
    492 void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
    493 
    494 
    495 void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
    496   Print("super");
    497 }
    498 
    499 
    500 void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
    501   Find(node->expression());
    502 }
    503 
    504 void CallPrinter::FindStatements(ZonePtrList<Statement>* statements) {
    505   if (statements == nullptr) return;
    506   for (int i = 0; i < statements->length(); i++) {
    507     Find(statements->at(i));
    508   }
    509 }
    510 
    511 void CallPrinter::FindArguments(ZonePtrList<Expression>* arguments) {
    512   if (found_) return;
    513   for (int i = 0; i < arguments->length(); i++) {
    514     Find(arguments->at(i));
    515   }
    516 }
    517 
    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_)) {
    524     Print("null");
    525   } else if (value->IsTrue(isolate_)) {
    526     Print("true");
    527   } else if (value->IsFalse(isolate_)) {
    528     Print("false");
    529   } else if (value->IsUndefined(isolate_)) {
    530     Print("undefined");
    531   } else if (value->IsNumber()) {
    532     Print(isolate_->factory()->NumberToString(value));
    533   } else if (value->IsSymbol()) {
    534     // Symbols can only occur as literals if they were inserted by the parser.
    535     PrintLiteral(handle(Handle<Symbol>::cast(value)->name(), isolate_), false);
    536   }
    537 }
    538 
    539 
    540 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
    541   PrintLiteral(value->string(), quote);
    542 }
    543 
    544 
    545 //-----------------------------------------------------------------------------
    546 
    547 
    548 #ifdef DEBUG
    549 
    550 const char* AstPrinter::Print(AstNode* node) {
    551   Init();
    552   Visit(node);
    553   return output_;
    554 }
    555 
    556 void AstPrinter::Init() {
    557   if (size_ == 0) {
    558     DCHECK_NULL(output_);
    559     const int initial_size = 256;
    560     output_ = NewArray<char>(initial_size);
    561     size_ = initial_size;
    562   }
    563   output_[0] = '\0';
    564   pos_ = 0;
    565 }
    566 
    567 void AstPrinter::Print(const char* format, ...) {
    568   for (;;) {
    569     va_list arguments;
    570     va_start(arguments, format);
    571     int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
    572                       format,
    573                       arguments);
    574     va_end(arguments);
    575 
    576     if (n >= 0) {
    577       // there was enough space - we are done
    578       pos_ += n;
    579       return;
    580     } else {
    581       // there was not enough space - allocate more and try again
    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;
    588       size_ = new_size;
    589     }
    590   }
    591 }
    592 
    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);
    597       Print(": ");
    598     }
    599   }
    600 }
    601 
    602 void AstPrinter::PrintLiteral(Literal* literal, bool quote) {
    603   switch (literal->type()) {
    604     case Literal::kString:
    605       PrintLiteral(literal->AsRawString(), quote);
    606       break;
    607     case Literal::kSymbol:
    608       const char* symbol;
    609       switch (literal->AsSymbol()) {
    610         case AstSymbol::kHomeObjectSymbol:
    611           symbol = "HomeObjectSymbol";
    612       }
    613       Print("%s", symbol);
    614       break;
    615     case Literal::kSmi:
    616       Print("%d", Smi::ToInt(literal->AsSmiLiteral()));
    617       break;
    618     case Literal::kHeapNumber:
    619       Print("%g", literal->AsNumber());
    620       break;
    621     case Literal::kBigInt:
    622       Print("%sn", literal->AsBigInt().c_str());
    623       break;
    624     case Literal::kNull:
    625       Print("null");
    626       break;
    627     case Literal::kUndefined:
    628       Print("undefined");
    629       break;
    630     case Literal::kTheHole:
    631       Print("the hole");
    632       break;
    633     case Literal::kBoolean:
    634       if (literal->ToBooleanIsTrue()) {
    635         Print("true");
    636       } else {
    637         Print("false");
    638       }
    639       break;
    640   }
    641 }
    642 
    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]);
    651     }
    652   }
    653   if (quote) Print("\"");
    654 }
    655 
    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);
    662     }
    663   }
    664   if (quote) Print("\"");
    665 }
    666 
    667 //-----------------------------------------------------------------------------
    668 
    669 class IndentedScope BASE_EMBEDDED {
    670  public:
    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();
    676   }
    677 
    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();
    683   }
    684 
    685   virtual ~IndentedScope() {
    686     ast_printer_->dec_indent();
    687   }
    688 
    689  private:
    690   AstPrinter* ast_printer_;
    691 };
    692 
    693 
    694 //-----------------------------------------------------------------------------
    695 
    696 AstPrinter::AstPrinter(uintptr_t stack_limit)
    697     : output_(nullptr), size_(0), pos_(0), indent_(0) {
    698   InitializeAstVisitor(stack_limit);
    699 }
    700 
    701 AstPrinter::~AstPrinter() {
    702   DCHECK_EQ(indent_, 0);
    703   DeleteArray(output_);
    704 }
    705 
    706 
    707 void AstPrinter::PrintIndented(const char* txt) {
    708   for (int i = 0; i < indent_; i++) {
    709     Print(". ");
    710   }
    711   Print("%s", txt);
    712 }
    713 
    714 void AstPrinter::PrintLiteralIndented(const char* info, Literal* literal,
    715                                       bool quote) {
    716   PrintIndented(info);
    717   Print(" ");
    718   PrintLiteral(literal, quote);
    719   Print("\n");
    720 }
    721 
    722 void AstPrinter::PrintLiteralIndented(const char* info,
    723                                       const AstRawString* value, bool quote) {
    724   PrintIndented(info);
    725   Print(" ");
    726   PrintLiteral(value, quote);
    727   Print("\n");
    728 }
    729 
    730 void AstPrinter::PrintLiteralIndented(const char* info,
    731                                       const AstConsString* value, bool quote) {
    732   PrintIndented(info);
    733   Print(" ");
    734   PrintLiteral(value, quote);
    735   Print("\n");
    736 }
    737 
    738 void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var,
    739                                               const AstRawString* value) {
    740   if (var == nullptr) {
    741     PrintLiteralIndented(info, value, true);
    742   } else {
    743     EmbeddedVector<char, 256> buf;
    744     int pos =
    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);
    749   }
    750 }
    751 
    752 void AstPrinter::PrintLabelsIndented(ZonePtrList<const AstRawString>* labels,
    753                                      const char* prefix) {
    754   if (labels == nullptr || labels->length() == 0) return;
    755   PrintIndented(prefix);
    756   Print("LABELS ");
    757   PrintLabels(labels);
    758   Print("\n");
    759 }
    760 
    761 
    762 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
    763   if (node != nullptr) {
    764     IndentedScope indent(this, s, node->position());
    765     Visit(node);
    766   }
    767 }
    768 
    769 
    770 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
    771   Init();
    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);
    780     }
    781     if (program->requires_instance_fields_initializer()) {
    782       Print(" REQUIRES INSTANCE FIELDS INITIALIZER\n");
    783     }
    784     PrintParameters(program->scope());
    785     PrintDeclarations(program->scope()->declarations());
    786     PrintStatements(program->body());
    787   }
    788   return output_;
    789 }
    790 
    791 
    792 void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) {
    793   AstPrinter printer(isolate->stack_guard()->real_climit());
    794   printer.Init();
    795   printer.Visit(node);
    796   PrintF("%s", printer.output_);
    797 }
    798 
    799 void AstPrinter::PrintDeclarations(Declaration::List* declarations) {
    800   if (!declarations->is_empty()) {
    801     IndentedScope indent(this, "DECLS");
    802     for (Declaration* decl : *declarations) Visit(decl);
    803   }
    804 }
    805 
    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());
    812     }
    813   }
    814 }
    815 
    816 void AstPrinter::PrintStatements(ZonePtrList<Statement>* statements) {
    817   for (int i = 0; i < statements->length(); i++) {
    818     Visit(statements->at(i));
    819   }
    820 }
    821 
    822 void AstPrinter::PrintArguments(ZonePtrList<Expression>* arguments) {
    823   for (int i = 0; i < arguments->length(); i++) {
    824     Visit(arguments->at(i));
    825   }
    826 }
    827 
    828 
    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());
    835 }
    836 
    837 
    838 // TODO(svenpanne) Start with IndentedScope.
    839 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
    840   PrintLiteralWithModeIndented("VARIABLE", node->proxy()->var(),
    841                                node->proxy()->raw_name());
    842 }
    843 
    844 
    845 // TODO(svenpanne) Start with IndentedScope.
    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);
    851   Print("\n");
    852 }
    853 
    854 
    855 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
    856   IndentedScope indent(this, "EXPRESSION STATEMENT", node->position());
    857   Visit(node->expression());
    858 }
    859 
    860 
    861 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
    862   IndentedScope indent(this, "EMPTY", node->position());
    863 }
    864 
    865 
    866 void AstPrinter::VisitSloppyBlockFunctionStatement(
    867     SloppyBlockFunctionStatement* node) {
    868   Visit(node->statement());
    869 }
    870 
    871 
    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());
    878   }
    879 }
    880 
    881 
    882 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
    883   IndentedScope indent(this, "CONTINUE", node->position());
    884   PrintLabelsIndented(node->target()->labels());
    885 }
    886 
    887 
    888 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
    889   IndentedScope indent(this, "BREAK", node->position());
    890   PrintLabelsIndented(node->target()->labels());
    891 }
    892 
    893 
    894 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
    895   IndentedScope indent(this, "RETURN", node->position());
    896   Visit(node->expression());
    897 }
    898 
    899 
    900 void AstPrinter::VisitWithStatement(WithStatement* node) {
    901   IndentedScope indent(this, "WITH", node->position());
    902   PrintIndentedVisit("OBJECT", node->expression());
    903   PrintIndentedVisit("BODY", node->statement());
    904 }
    905 
    906 
    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());
    915     } else {
    916       IndentedScope indent(this, "CASE");
    917       Visit(clause->label());
    918       PrintStatements(clause->statements());
    919     }
    920   }
    921 }
    922 
    923 
    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());
    930 }
    931 
    932 
    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());
    939 }
    940 
    941 
    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());
    950 }
    951 
    952 
    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());
    960 }
    961 
    962 
    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());
    972 }
    973 
    974 
    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";
    983       break;
    984     case HandlerTable::CAUGHT:
    985       prediction = "CAUGHT";
    986       break;
    987     case HandlerTable::DESUGARING:
    988       prediction = "DESUGARING";
    989       break;
    990     case HandlerTable::ASYNC_AWAIT:
    991       prediction = "ASYNC_AWAIT";
    992       break;
    993     case HandlerTable::PROMISE:
    994       // Catch prediction resulting in promise rejections aren't
    995       // parsed by the parser.
    996       UNREACHABLE();
    997   }
    998   Print(" %s\n", prediction);
    999   if (node->scope()) {
   1000     PrintLiteralWithModeIndented("CATCHVAR", node->scope()->catch_variable(),
   1001                                  node->scope()->catch_variable()->raw_name());
   1002   }
   1003   PrintIndentedVisit("CATCH", node->catch_block());
   1004 }
   1005 
   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());
   1010 }
   1011 
   1012 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
   1013   IndentedScope indent(this, "DEBUGGER", node->position());
   1014 }
   1015 
   1016 
   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());
   1022   // We don't want to see the function literal in this case: it
   1023   // will be printed via PrintProgram when the code for it is
   1024   // generated.
   1025   // PrintStatements(node->body());
   1026 }
   1027 
   1028 
   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());
   1034   }
   1035   if (node->static_fields_initializer() != nullptr) {
   1036     PrintIndentedVisit("STATIC FIELDS INITIALIZER",
   1037                        node->static_fields_initializer());
   1038   }
   1039   if (node->instance_fields_initializer_function() != nullptr) {
   1040     PrintIndentedVisit("INSTANCE FIELDS INITIALIZER",
   1041                        node->instance_fields_initializer_function());
   1042   }
   1043   PrintClassProperties(node->properties());
   1044 }
   1045 
   1046 void AstPrinter::VisitInitializeClassFieldsStatement(
   1047     InitializeClassFieldsStatement* node) {
   1048   IndentedScope indent(this, "INITIALIZE CLASS FIELDS", node->position());
   1049   PrintClassProperties(node->fields());
   1050 }
   1051 
   1052 void AstPrinter::PrintClassProperties(
   1053     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";
   1060         break;
   1061       case ClassLiteral::Property::GETTER:
   1062         prop_kind = "GETTER";
   1063         break;
   1064       case ClassLiteral::Property::SETTER:
   1065         prop_kind = "SETTER";
   1066         break;
   1067       case ClassLiteral::Property::PUBLIC_FIELD:
   1068         prop_kind = "PUBLIC FIELD";
   1069         break;
   1070       case ClassLiteral::Property::PRIVATE_FIELD:
   1071         prop_kind = "PRIVATE FIELD";
   1072         break;
   1073     }
   1074     EmbeddedVector<char, 128> buf;
   1075     SNPrintF(buf, "PROPERTY%s - %s", property->is_static() ? " - STATIC" : "",
   1076              prop_kind);
   1077     IndentedScope prop(this, buf.start());
   1078     PrintIndentedVisit("KEY", properties->at(i)->key());
   1079     PrintIndentedVisit("VALUE", properties->at(i)->value());
   1080   }
   1081 }
   1082 
   1083 
   1084 void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
   1085   IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position());
   1086   PrintLiteralIndented("NAME", node->raw_name(), false);
   1087 }
   1088 
   1089 
   1090 void AstPrinter::VisitDoExpression(DoExpression* node) {
   1091   IndentedScope indent(this, "DO EXPRESSION", node->position());
   1092   PrintStatements(node->block()->statements());
   1093 }
   1094 
   1095 
   1096 void AstPrinter::VisitConditional(Conditional* node) {
   1097   IndentedScope indent(this, "CONDITIONAL", node->position());
   1098   PrintIndentedVisit("CONDITION", node->condition());
   1099   PrintIndentedVisit("THEN", node->then_expression());
   1100   PrintIndentedVisit("ELSE", node->else_expression());
   1101 }
   1102 
   1103 
   1104 void AstPrinter::VisitLiteral(Literal* node) {
   1105   PrintLiteralIndented("LITERAL", node, true);
   1106 }
   1107 
   1108 
   1109 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
   1110   IndentedScope indent(this, "REGEXP LITERAL", node->position());
   1111   PrintLiteralIndented("PATTERN", node->raw_pattern(), false);
   1112   int i = 0;
   1113   EmbeddedVector<char, 128> buf;
   1114   if (node->flags() & RegExp::kGlobal) buf[i++] = 'g';
   1115   if (node->flags() & RegExp::kIgnoreCase) buf[i++] = 'i';
   1116   if (node->flags() & RegExp::kMultiline) buf[i++] = 'm';
   1117   if (node->flags() & RegExp::kUnicode) buf[i++] = 'u';
   1118   if (node->flags() & RegExp::kSticky) buf[i++] = 'y';
   1119   buf[i] = '\0';
   1120   PrintIndented("FLAGS ");
   1121   Print("%s", buf.start());
   1122   Print("\n");
   1123 }
   1124 
   1125 
   1126 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
   1127   IndentedScope indent(this, "OBJ LITERAL", node->position());
   1128   PrintObjectProperties(node->properties());
   1129 }
   1130 
   1131 void AstPrinter::PrintObjectProperties(
   1132     ZonePtrList<ObjectLiteral::Property>* properties) {
   1133   for (int i = 0; i < properties->length(); i++) {
   1134     ObjectLiteral::Property* property = properties->at(i);
   1135     const char* prop_kind = nullptr;
   1136     switch (property->kind()) {
   1137       case ObjectLiteral::Property::CONSTANT:
   1138         prop_kind = "CONSTANT";
   1139         break;
   1140       case ObjectLiteral::Property::COMPUTED:
   1141         prop_kind = "COMPUTED";
   1142         break;
   1143       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1144         prop_kind = "MATERIALIZED_LITERAL";
   1145         break;
   1146       case ObjectLiteral::Property::PROTOTYPE:
   1147         prop_kind = "PROTOTYPE";
   1148         break;
   1149       case ObjectLiteral::Property::GETTER:
   1150         prop_kind = "GETTER";
   1151         break;
   1152       case ObjectLiteral::Property::SETTER:
   1153         prop_kind = "SETTER";
   1154         break;
   1155       case ObjectLiteral::Property::SPREAD:
   1156         prop_kind = "SPREAD";
   1157         break;
   1158     }
   1159     EmbeddedVector<char, 128> buf;
   1160     SNPrintF(buf, "PROPERTY - %s", prop_kind);
   1161     IndentedScope prop(this, buf.start());
   1162     PrintIndentedVisit("KEY", properties->at(i)->key());
   1163     PrintIndentedVisit("VALUE", properties->at(i)->value());
   1164   }
   1165 }
   1166 
   1167 
   1168 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
   1169   IndentedScope indent(this, "ARRAY LITERAL", node->position());
   1170   if (node->values()->length() > 0) {
   1171     IndentedScope indent(this, "VALUES", node->position());
   1172     for (int i = 0; i < node->values()->length(); i++) {
   1173       Visit(node->values()->at(i));
   1174     }
   1175   }
   1176 }
   1177 
   1178 
   1179 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
   1180   EmbeddedVector<char, 128> buf;
   1181   int pos = SNPrintF(buf, "VAR PROXY");
   1182 
   1183   if (!node->is_resolved()) {
   1184     SNPrintF(buf + pos, " unresolved");
   1185     PrintLiteralWithModeIndented(buf.start(), nullptr, node->raw_name());
   1186   } else {
   1187     Variable* var = node->var();
   1188     switch (var->location()) {
   1189       case VariableLocation::UNALLOCATED:
   1190         SNPrintF(buf + pos, " unallocated");
   1191         break;
   1192       case VariableLocation::PARAMETER:
   1193         SNPrintF(buf + pos, " parameter[%d]", var->index());
   1194         break;
   1195       case VariableLocation::LOCAL:
   1196         SNPrintF(buf + pos, " local[%d]", var->index());
   1197         break;
   1198       case VariableLocation::CONTEXT:
   1199         SNPrintF(buf + pos, " context[%d]", var->index());
   1200         break;
   1201       case VariableLocation::LOOKUP:
   1202         SNPrintF(buf + pos, " lookup");
   1203         break;
   1204       case VariableLocation::MODULE:
   1205         SNPrintF(buf + pos, " module");
   1206         break;
   1207     }
   1208     PrintLiteralWithModeIndented(buf.start(), var, node->raw_name());
   1209   }
   1210 }
   1211 
   1212 
   1213 void AstPrinter::VisitAssignment(Assignment* node) {
   1214   IndentedScope indent(this, Token::Name(node->op()), node->position());
   1215   Visit(node->target());
   1216   Visit(node->value());
   1217 }
   1218 
   1219 void AstPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
   1220   VisitAssignment(node);
   1221 }
   1222 
   1223 void AstPrinter::VisitYield(Yield* node) {
   1224   EmbeddedVector<char, 128> buf;
   1225   SNPrintF(buf, "YIELD");
   1226   IndentedScope indent(this, buf.start(), node->position());
   1227   Visit(node->expression());
   1228 }
   1229 
   1230 void AstPrinter::VisitYieldStar(YieldStar* node) {
   1231   EmbeddedVector<char, 128> buf;
   1232   SNPrintF(buf, "YIELD_STAR");
   1233   IndentedScope indent(this, buf.start(), node->position());
   1234   Visit(node->expression());
   1235 }
   1236 
   1237 void AstPrinter::VisitAwait(Await* node) {
   1238   EmbeddedVector<char, 128> buf;
   1239   SNPrintF(buf, "AWAIT");
   1240   IndentedScope indent(this, buf.start(), node->position());
   1241   Visit(node->expression());
   1242 }
   1243 
   1244 void AstPrinter::VisitThrow(Throw* node) {
   1245   IndentedScope indent(this, "THROW", node->position());
   1246   Visit(node->exception());
   1247 }
   1248 
   1249 void AstPrinter::VisitProperty(Property* node) {
   1250   EmbeddedVector<char, 128> buf;
   1251   SNPrintF(buf, "PROPERTY");
   1252   IndentedScope indent(this, buf.start(), node->position());
   1253 
   1254   Visit(node->obj());
   1255   LhsKind property_kind = Property::GetAssignType(node);
   1256   if (property_kind == NAMED_PROPERTY ||
   1257       property_kind == NAMED_SUPER_PROPERTY) {
   1258     PrintLiteralIndented("NAME", node->key()->AsLiteral(), false);
   1259   } else {
   1260     DCHECK(property_kind == KEYED_PROPERTY ||
   1261            property_kind == KEYED_SUPER_PROPERTY);
   1262     PrintIndentedVisit("KEY", node->key());
   1263   }
   1264 }
   1265 
   1266 void AstPrinter::VisitResolvedProperty(ResolvedProperty* node) {
   1267   EmbeddedVector<char, 128> buf;
   1268   SNPrintF(buf, "RESOLVED-PROPERTY");
   1269   IndentedScope indent(this, buf.start(), node->position());
   1270 
   1271   PrintIndentedVisit("RECEIVER", node->object());
   1272   PrintIndentedVisit("PROPERTY", node->property());
   1273 }
   1274 
   1275 void AstPrinter::VisitCall(Call* node) {
   1276   EmbeddedVector<char, 128> buf;
   1277   SNPrintF(buf, "CALL");
   1278   IndentedScope indent(this, buf.start());
   1279 
   1280   Visit(node->expression());
   1281   PrintArguments(node->arguments());
   1282 }
   1283 
   1284 
   1285 void AstPrinter::VisitCallNew(CallNew* node) {
   1286   IndentedScope indent(this, "CALL NEW", node->position());
   1287   Visit(node->expression());
   1288   PrintArguments(node->arguments());
   1289 }
   1290 
   1291 
   1292 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
   1293   EmbeddedVector<char, 128> buf;
   1294   SNPrintF(buf, "CALL RUNTIME %s%s", node->debug_name(),
   1295            node->is_jsruntime() ? " (JS function)" : "");
   1296   IndentedScope indent(this, buf.start(), node->position());
   1297   PrintArguments(node->arguments());
   1298 }
   1299 
   1300 
   1301 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
   1302   IndentedScope indent(this, Token::Name(node->op()), node->position());
   1303   Visit(node->expression());
   1304 }
   1305 
   1306 
   1307 void AstPrinter::VisitCountOperation(CountOperation* node) {
   1308   EmbeddedVector<char, 128> buf;
   1309   SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
   1310            Token::Name(node->op()));
   1311   IndentedScope indent(this, buf.start(), node->position());
   1312   Visit(node->expression());
   1313 }
   1314 
   1315 
   1316 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
   1317   IndentedScope indent(this, Token::Name(node->op()), node->position());
   1318   Visit(node->left());
   1319   Visit(node->right());
   1320 }
   1321 
   1322 void AstPrinter::VisitNaryOperation(NaryOperation* node) {
   1323   IndentedScope indent(this, Token::Name(node->op()), node->position());
   1324   Visit(node->first());
   1325   for (size_t i = 0; i < node->subsequent_length(); ++i) {
   1326     Visit(node->subsequent(i));
   1327   }
   1328 }
   1329 
   1330 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
   1331   IndentedScope indent(this, Token::Name(node->op()), node->position());
   1332   Visit(node->left());
   1333   Visit(node->right());
   1334 }
   1335 
   1336 
   1337 void AstPrinter::VisitSpread(Spread* node) {
   1338   IndentedScope indent(this, "SPREAD", node->position());
   1339   Visit(node->expression());
   1340 }
   1341 
   1342 void AstPrinter::VisitStoreInArrayLiteral(StoreInArrayLiteral* node) {
   1343   IndentedScope indent(this, "STORE IN ARRAY LITERAL", node->position());
   1344   PrintIndentedVisit("ARRAY", node->array());
   1345   PrintIndentedVisit("INDEX", node->index());
   1346   PrintIndentedVisit("VALUE", node->value());
   1347 }
   1348 
   1349 void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
   1350   IndentedScope indent(this, "()", node->position());
   1351 }
   1352 
   1353 void AstPrinter::VisitGetIterator(GetIterator* node) {
   1354   IndentedScope indent(this, "GET-ITERATOR", node->position());
   1355   Visit(node->iterable());
   1356 }
   1357 
   1358 void AstPrinter::VisitGetTemplateObject(GetTemplateObject* node) {
   1359   IndentedScope indent(this, "GET-TEMPLATE-OBJECT", node->position());
   1360 }
   1361 
   1362 void AstPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
   1363   IndentedScope indent(this, "TEMPLATE-LITERAL", node->position());
   1364   const AstRawString* string = node->string_parts()->first();
   1365   if (!string->IsEmpty()) PrintLiteralIndented("SPAN", string, true);
   1366   for (int i = 0; i < node->substitutions()->length();) {
   1367     PrintIndentedVisit("EXPR", node->substitutions()->at(i++));
   1368     if (i < node->string_parts()->length()) {
   1369       string = node->string_parts()->at(i);
   1370       if (!string->IsEmpty()) PrintLiteralIndented("SPAN", string, true);
   1371     }
   1372   }
   1373 }
   1374 
   1375 void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
   1376   IndentedScope indent(this, "IMPORT-CALL", node->position());
   1377   Visit(node->argument());
   1378 }
   1379 
   1380 void AstPrinter::VisitThisFunction(ThisFunction* node) {
   1381   IndentedScope indent(this, "THIS-FUNCTION", node->position());
   1382 }
   1383 
   1384 
   1385 void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
   1386   IndentedScope indent(this, "SUPER-PROPERTY-REFERENCE", node->position());
   1387 }
   1388 
   1389 
   1390 void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
   1391   IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position());
   1392 }
   1393 
   1394 
   1395 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
   1396   Visit(node->expression());
   1397 }
   1398 
   1399 
   1400 #endif  // DEBUG
   1401 
   1402 }  // namespace internal
   1403 }  // namespace v8
   1404