The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / prettyprinter.cc @ f230a1cf

History | View | Annotate | Download (29.1 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include <stdarg.h>
29

    
30
#include "v8.h"
31

    
32
#include "prettyprinter.h"
33
#include "scopes.h"
34
#include "platform.h"
35

    
36
namespace v8 {
37
namespace internal {
38

    
39
#ifdef DEBUG
40

    
41
PrettyPrinter::PrettyPrinter(Isolate* isolate) {
42
  output_ = NULL;
43
  size_ = 0;
44
  pos_ = 0;
45
  InitializeAstVisitor(isolate);
46
}
47

    
48

    
49
PrettyPrinter::~PrettyPrinter() {
50
  DeleteArray(output_);
51
}
52

    
53

    
54
void PrettyPrinter::VisitBlock(Block* node) {
55
  if (!node->is_initializer_block()) Print("{ ");
56
  PrintStatements(node->statements());
57
  if (node->statements()->length() > 0) Print(" ");
58
  if (!node->is_initializer_block()) Print("}");
59
}
60

    
61

    
62
void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
63
  Print("var ");
64
  PrintLiteral(node->proxy()->name(), false);
65
  Print(";");
66
}
67

    
68

    
69
void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
70
  Print("function ");
71
  PrintLiteral(node->proxy()->name(), false);
72
  Print(" = ");
73
  PrintFunctionLiteral(node->fun());
74
  Print(";");
75
}
76

    
77

    
78
void PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
79
  Print("module ");
80
  PrintLiteral(node->proxy()->name(), false);
81
  Print(" = ");
82
  Visit(node->module());
83
  Print(";");
84
}
85

    
86

    
87
void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
88
  Print("import ");
89
  PrintLiteral(node->proxy()->name(), false);
90
  Print(" from ");
91
  Visit(node->module());
92
  Print(";");
93
}
94

    
95

    
96
void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
97
  Print("export ");
98
  PrintLiteral(node->proxy()->name(), false);
99
  Print(";");
100
}
101

    
102

    
103
void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
104
  VisitBlock(node->body());
105
}
106

    
107

    
108
void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
109
  Visit(node->proxy());
110
}
111

    
112

    
113
void PrettyPrinter::VisitModulePath(ModulePath* node) {
114
  Visit(node->module());
115
  Print(".");
116
  PrintLiteral(node->name(), false);
117
}
118

    
119

    
120
void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
121
  Print("at ");
122
  PrintLiteral(node->url(), true);
123
}
124

    
125

    
126
void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
127
  Print("module ");
128
  PrintLiteral(node->proxy()->name(), false);
129
  Print(" ");
130
  Visit(node->body());
131
}
132

    
133

    
134
void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
135
  Visit(node->expression());
136
  Print(";");
137
}
138

    
139

    
140
void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
141
  Print(";");
142
}
143

    
144

    
145
void PrettyPrinter::VisitIfStatement(IfStatement* node) {
146
  Print("if (");
147
  Visit(node->condition());
148
  Print(") ");
149
  Visit(node->then_statement());
150
  if (node->HasElseStatement()) {
151
    Print(" else ");
152
    Visit(node->else_statement());
153
  }
154
}
155

    
156

    
157
void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
158
  Print("continue");
159
  ZoneStringList* labels = node->target()->labels();
160
  if (labels != NULL) {
161
    Print(" ");
162
    ASSERT(labels->length() > 0);  // guaranteed to have at least one entry
163
    PrintLiteral(labels->at(0), false);  // any label from the list is fine
164
  }
165
  Print(";");
166
}
167

    
168

    
169
void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
170
  Print("break");
171
  ZoneStringList* labels = node->target()->labels();
172
  if (labels != NULL) {
173
    Print(" ");
174
    ASSERT(labels->length() > 0);  // guaranteed to have at least one entry
175
    PrintLiteral(labels->at(0), false);  // any label from the list is fine
176
  }
177
  Print(";");
178
}
179

    
180

    
181
void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
182
  Print("return ");
183
  Visit(node->expression());
184
  Print(";");
185
}
186

    
187

    
188
void PrettyPrinter::VisitWithStatement(WithStatement* node) {
189
  Print("with (");
190
  Visit(node->expression());
191
  Print(") ");
192
  Visit(node->statement());
193
}
194

    
195

    
196
void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
197
  PrintLabels(node->labels());
198
  Print("switch (");
199
  Visit(node->tag());
200
  Print(") { ");
201
  ZoneList<CaseClause*>* cases = node->cases();
202
  for (int i = 0; i < cases->length(); i++)
203
    Visit(cases->at(i));
204
  Print("}");
205
}
206

    
207

    
208
void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
209
  if (clause->is_default()) {
210
    Print("default");
211
  } else {
212
    Print("case ");
213
    Visit(clause->label());
214
  }
215
  Print(": ");
216
  PrintStatements(clause->statements());
217
  if (clause->statements()->length() > 0)
218
    Print(" ");
219
}
220

    
221

    
222
void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
223
  PrintLabels(node->labels());
224
  Print("do ");
225
  Visit(node->body());
226
  Print(" while (");
227
  Visit(node->cond());
228
  Print(");");
229
}
230

    
231

    
232
void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
233
  PrintLabels(node->labels());
234
  Print("while (");
235
  Visit(node->cond());
236
  Print(") ");
237
  Visit(node->body());
238
}
239

    
240

    
241
void PrettyPrinter::VisitForStatement(ForStatement* node) {
242
  PrintLabels(node->labels());
243
  Print("for (");
244
  if (node->init() != NULL) {
245
    Visit(node->init());
246
    Print(" ");
247
  } else {
248
    Print("; ");
249
  }
250
  if (node->cond() != NULL) Visit(node->cond());
251
  Print("; ");
252
  if (node->next() != NULL) {
253
    Visit(node->next());  // prints extra ';', unfortunately
254
    // to fix: should use Expression for next
255
  }
256
  Print(") ");
257
  Visit(node->body());
258
}
259

    
260

    
261
void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
262
  PrintLabels(node->labels());
263
  Print("for (");
264
  Visit(node->each());
265
  Print(" in ");
266
  Visit(node->enumerable());
267
  Print(") ");
268
  Visit(node->body());
269
}
270

    
271

    
272
void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
273
  PrintLabels(node->labels());
274
  Print("for (");
275
  Visit(node->each());
276
  Print(" of ");
277
  Visit(node->iterable());
278
  Print(") ");
279
  Visit(node->body());
280
}
281

    
282

    
283
void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
284
  Print("try ");
285
  Visit(node->try_block());
286
  Print(" catch (");
287
  const bool quote = false;
288
  PrintLiteral(node->variable()->name(), quote);
289
  Print(") ");
290
  Visit(node->catch_block());
291
}
292

    
293

    
294
void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
295
  Print("try ");
296
  Visit(node->try_block());
297
  Print(" finally ");
298
  Visit(node->finally_block());
299
}
300

    
301

    
302
void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
303
  Print("debugger ");
304
}
305

    
306

    
307
void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
308
  Print("(");
309
  PrintFunctionLiteral(node);
310
  Print(")");
311
}
312

    
313

    
314
void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
315
  Print("(");
316
  PrintLiteral(node->name(), false);
317
  Print(")");
318
}
319

    
320

    
321
void PrettyPrinter::VisitConditional(Conditional* node) {
322
  Visit(node->condition());
323
  Print(" ? ");
324
  Visit(node->then_expression());
325
  Print(" : ");
326
  Visit(node->else_expression());
327
}
328

    
329

    
330
void PrettyPrinter::VisitLiteral(Literal* node) {
331
  PrintLiteral(node->value(), true);
332
}
333

    
334

    
335
void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
336
  Print(" RegExp(");
337
  PrintLiteral(node->pattern(), false);
338
  Print(",");
339
  PrintLiteral(node->flags(), false);
340
  Print(") ");
341
}
342

    
343

    
344
void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
345
  Print("{ ");
346
  for (int i = 0; i < node->properties()->length(); i++) {
347
    if (i != 0) Print(",");
348
    ObjectLiteral::Property* property = node->properties()->at(i);
349
    Print(" ");
350
    Visit(property->key());
351
    Print(": ");
352
    Visit(property->value());
353
  }
354
  Print(" }");
355
}
356

    
357

    
358
void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
359
  Print("[ ");
360
  for (int i = 0; i < node->values()->length(); i++) {
361
    if (i != 0) Print(",");
362
    Visit(node->values()->at(i));
363
  }
364
  Print(" ]");
365
}
366

    
367

    
368
void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
369
  PrintLiteral(node->name(), false);
370
}
371

    
372

    
373
void PrettyPrinter::VisitAssignment(Assignment* node) {
374
  Visit(node->target());
375
  Print(" %s ", Token::String(node->op()));
376
  Visit(node->value());
377
}
378

    
379

    
380
void PrettyPrinter::VisitYield(Yield* node) {
381
  Print("yield ");
382
  Visit(node->expression());
383
}
384

    
385

    
386
void PrettyPrinter::VisitThrow(Throw* node) {
387
  Print("throw ");
388
  Visit(node->exception());
389
}
390

    
391

    
392
void PrettyPrinter::VisitProperty(Property* node) {
393
  Expression* key = node->key();
394
  Literal* literal = key->AsLiteral();
395
  if (literal != NULL && literal->value()->IsInternalizedString()) {
396
    Print("(");
397
    Visit(node->obj());
398
    Print(").");
399
    PrintLiteral(literal->value(), false);
400
  } else {
401
    Visit(node->obj());
402
    Print("[");
403
    Visit(key);
404
    Print("]");
405
  }
406
}
407

    
408

    
409
void PrettyPrinter::VisitCall(Call* node) {
410
  Visit(node->expression());
411
  PrintArguments(node->arguments());
412
}
413

    
414

    
415
void PrettyPrinter::VisitCallNew(CallNew* node) {
416
  Print("new (");
417
  Visit(node->expression());
418
  Print(")");
419
  PrintArguments(node->arguments());
420
}
421

    
422

    
423
void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
424
  Print("%%");
425
  PrintLiteral(node->name(), false);
426
  PrintArguments(node->arguments());
427
}
428

    
429

    
430
void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
431
  Token::Value op = node->op();
432
  bool needsSpace =
433
      op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
434
  Print("(%s%s", Token::String(op), needsSpace ? " " : "");
435
  Visit(node->expression());
436
  Print(")");
437
}
438

    
439

    
440
void PrettyPrinter::VisitCountOperation(CountOperation* node) {
441
  Print("(");
442
  if (node->is_prefix()) Print("%s", Token::String(node->op()));
443
  Visit(node->expression());
444
  if (node->is_postfix()) Print("%s", Token::String(node->op()));
445
  Print(")");
446
}
447

    
448

    
449
void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
450
  Print("(");
451
  Visit(node->left());
452
  Print(" %s ", Token::String(node->op()));
453
  Visit(node->right());
454
  Print(")");
455
}
456

    
457

    
458
void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
459
  Print("(");
460
  Visit(node->left());
461
  Print(" %s ", Token::String(node->op()));
462
  Visit(node->right());
463
  Print(")");
464
}
465

    
466

    
467
void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
468
  Print("<this-function>");
469
}
470

    
471

    
472
const char* PrettyPrinter::Print(AstNode* node) {
473
  Init();
474
  Visit(node);
475
  return output_;
476
}
477

    
478

    
479
const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
480
  Init();
481
  ExpressionStatement* statement =
482
    program->body()->at(0)->AsExpressionStatement();
483
  Visit(statement->expression());
484
  return output_;
485
}
486

    
487

    
488
const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
489
  Init();
490
  PrintStatements(program->body());
491
  Print("\n");
492
  return output_;
493
}
494

    
495

    
496
void PrettyPrinter::PrintOut(Isolate* isolate, AstNode* node) {
497
  PrettyPrinter printer(isolate);
498
  PrintF("%s", printer.Print(node));
499
}
500

    
501

    
502
void PrettyPrinter::Init() {
503
  if (size_ == 0) {
504
    ASSERT(output_ == NULL);
505
    const int initial_size = 256;
506
    output_ = NewArray<char>(initial_size);
507
    size_ = initial_size;
508
  }
509
  output_[0] = '\0';
510
  pos_ = 0;
511
}
512

    
513

    
514
void PrettyPrinter::Print(const char* format, ...) {
515
  for (;;) {
516
    va_list arguments;
517
    va_start(arguments, format);
518
    int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
519
                          format,
520
                          arguments);
521
    va_end(arguments);
522

    
523
    if (n >= 0) {
524
      // there was enough space - we are done
525
      pos_ += n;
526
      return;
527
    } else {
528
      // there was not enough space - allocate more and try again
529
      const int slack = 32;
530
      int new_size = size_ + (size_ >> 1) + slack;
531
      char* new_output = NewArray<char>(new_size);
532
      OS::MemCopy(new_output, output_, pos_);
533
      DeleteArray(output_);
534
      output_ = new_output;
535
      size_ = new_size;
536
    }
537
  }
538
}
539

    
540

    
541
void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
542
  if (statements == NULL) return;
543
  for (int i = 0; i < statements->length(); i++) {
544
    if (i != 0) Print(" ");
545
    Visit(statements->at(i));
546
  }
547
}
548

    
549

    
550
void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
551
  if (labels != NULL) {
552
    for (int i = 0; i < labels->length(); i++) {
553
      PrintLiteral(labels->at(i), false);
554
      Print(": ");
555
    }
556
  }
557
}
558

    
559

    
560
void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
561
  Print("(");
562
  for (int i = 0; i < arguments->length(); i++) {
563
    if (i != 0) Print(", ");
564
    Visit(arguments->at(i));
565
  }
566
  Print(")");
567
}
568

    
569

    
570
void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
571
  Object* object = *value;
572
  if (object->IsString()) {
573
    String* string = String::cast(object);
574
    if (quote) Print("\"");
575
    for (int i = 0; i < string->length(); i++) {
576
      Print("%c", string->Get(i));
577
    }
578
    if (quote) Print("\"");
579
  } else if (object->IsNull()) {
580
    Print("null");
581
  } else if (object->IsTrue()) {
582
    Print("true");
583
  } else if (object->IsFalse()) {
584
    Print("false");
585
  } else if (object->IsUndefined()) {
586
    Print("undefined");
587
  } else if (object->IsNumber()) {
588
    Print("%g", object->Number());
589
  } else if (object->IsJSObject()) {
590
    // regular expression
591
    if (object->IsJSFunction()) {
592
      Print("JS-Function");
593
    } else if (object->IsJSArray()) {
594
      Print("JS-array[%u]", JSArray::cast(object)->length());
595
    } else if (object->IsJSObject()) {
596
      Print("JS-Object");
597
    } else {
598
      Print("?UNKNOWN?");
599
    }
600
  } else if (object->IsFixedArray()) {
601
    Print("FixedArray");
602
  } else {
603
    Print("<unknown literal %p>", object);
604
  }
605
}
606

    
607

    
608
void PrettyPrinter::PrintParameters(Scope* scope) {
609
  Print("(");
610
  for (int i = 0; i < scope->num_parameters(); i++) {
611
    if (i  > 0) Print(", ");
612
    PrintLiteral(scope->parameter(i)->name(), false);
613
  }
614
  Print(")");
615
}
616

    
617

    
618
void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
619
  for (int i = 0; i < declarations->length(); i++) {
620
    if (i > 0) Print(" ");
621
    Visit(declarations->at(i));
622
  }
623
}
624

    
625

    
626
void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
627
  Print("function ");
628
  PrintLiteral(function->name(), false);
629
  PrintParameters(function->scope());
630
  Print(" { ");
631
  PrintDeclarations(function->scope()->declarations());
632
  PrintStatements(function->body());
633
  Print(" }");
634
}
635

    
636

    
637
//-----------------------------------------------------------------------------
638

    
639
class IndentedScope BASE_EMBEDDED {
640
 public:
641
  IndentedScope(AstPrinter* printer, const char* txt)
642
      : ast_printer_(printer) {
643
    ast_printer_->PrintIndented(txt);
644
    ast_printer_->Print("\n");
645
    ast_printer_->inc_indent();
646
  }
647

    
648
  virtual ~IndentedScope() {
649
    ast_printer_->dec_indent();
650
  }
651

    
652
 private:
653
  AstPrinter* ast_printer_;
654
};
655

    
656

    
657
//-----------------------------------------------------------------------------
658

    
659

    
660
AstPrinter::AstPrinter(Isolate* isolate) : PrettyPrinter(isolate), indent_(0) {
661
}
662

    
663

    
664
AstPrinter::~AstPrinter() {
665
  ASSERT(indent_ == 0);
666
}
667

    
668

    
669
void AstPrinter::PrintIndented(const char* txt) {
670
  for (int i = 0; i < indent_; i++) {
671
    Print(". ");
672
  }
673
  Print(txt);
674
}
675

    
676

    
677
void AstPrinter::PrintLiteralIndented(const char* info,
678
                                      Handle<Object> value,
679
                                      bool quote) {
680
  PrintIndented(info);
681
  Print(" ");
682
  PrintLiteral(value, quote);
683
  Print("\n");
684
}
685

    
686

    
687
void AstPrinter::PrintLiteralWithModeIndented(const char* info,
688
                                              Variable* var,
689
                                              Handle<Object> value) {
690
  if (var == NULL) {
691
    PrintLiteralIndented(info, value, true);
692
  } else {
693
    EmbeddedVector<char, 256> buf;
694
    int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
695
                           Variable::Mode2String(var->mode()));
696
    OS::SNPrintF(buf + pos, ")");
697
    PrintLiteralIndented(buf.start(), value, true);
698
  }
699
}
700

    
701

    
702
void AstPrinter::PrintLabelsIndented(ZoneStringList* labels) {
703
  if (labels == NULL || labels->length() == 0) return;
704
  PrintIndented("LABELS ");
705
  PrintLabels(labels);
706
  Print("\n");
707
}
708

    
709

    
710
void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
711
  IndentedScope indent(this, s);
712
  Visit(node);
713
}
714

    
715

    
716
const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
717
  Init();
718
  { IndentedScope indent(this, "FUNC");
719
    PrintLiteralIndented("NAME", program->name(), true);
720
    PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
721
    PrintParameters(program->scope());
722
    PrintDeclarations(program->scope()->declarations());
723
    PrintStatements(program->body());
724
  }
725
  return Output();
726
}
727

    
728

    
729
void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
730
  if (declarations->length() > 0) {
731
    IndentedScope indent(this, "DECLS");
732
    for (int i = 0; i < declarations->length(); i++) {
733
      Visit(declarations->at(i));
734
    }
735
  }
736
}
737

    
738

    
739
void AstPrinter::PrintParameters(Scope* scope) {
740
  if (scope->num_parameters() > 0) {
741
    IndentedScope indent(this, "PARAMS");
742
    for (int i = 0; i < scope->num_parameters(); i++) {
743
      PrintLiteralWithModeIndented("VAR", scope->parameter(i),
744
                                   scope->parameter(i)->name());
745
    }
746
  }
747
}
748

    
749

    
750
void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
751
  for (int i = 0; i < statements->length(); i++) {
752
    Visit(statements->at(i));
753
  }
754
}
755

    
756

    
757
void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
758
  for (int i = 0; i < arguments->length(); i++) {
759
    Visit(arguments->at(i));
760
  }
761
}
762

    
763

    
764
void AstPrinter::VisitBlock(Block* node) {
765
  const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
766
  IndentedScope indent(this, block_txt);
767
  PrintStatements(node->statements());
768
}
769

    
770

    
771
// TODO(svenpanne) Start with IndentedScope.
772
void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
773
  PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
774
                               node->proxy()->var(),
775
                               node->proxy()->name());
776
}
777

    
778

    
779
// TODO(svenpanne) Start with IndentedScope.
780
void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
781
  PrintIndented("FUNCTION ");
782
  PrintLiteral(node->proxy()->name(), true);
783
  Print(" = function ");
784
  PrintLiteral(node->fun()->name(), false);
785
  Print("\n");
786
}
787

    
788

    
789
void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
790
  IndentedScope indent(this, "MODULE");
791
  PrintLiteralIndented("NAME", node->proxy()->name(), true);
792
  Visit(node->module());
793
}
794

    
795

    
796
void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
797
  IndentedScope indent(this, "IMPORT");
798
  PrintLiteralIndented("NAME", node->proxy()->name(), true);
799
  Visit(node->module());
800
}
801

    
802

    
803
void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
804
  IndentedScope indent(this, "EXPORT ");
805
  PrintLiteral(node->proxy()->name(), true);
806
}
807

    
808

    
809
void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
810
  IndentedScope indent(this, "MODULE LITERAL");
811
  VisitBlock(node->body());
812
}
813

    
814

    
815
void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
816
  IndentedScope indent(this, "MODULE VARIABLE");
817
  Visit(node->proxy());
818
}
819

    
820

    
821
void AstPrinter::VisitModulePath(ModulePath* node) {
822
  IndentedScope indent(this, "MODULE PATH");
823
  PrintIndentedVisit("MODULE PATH PARENT", node->module());
824
  PrintLiteralIndented("NAME", node->name(), true);
825
}
826

    
827

    
828
void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
829
  PrintLiteralIndented("URL", node->url(), true);
830
}
831

    
832

    
833
void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
834
  IndentedScope indent(this, "MODULE STATEMENT");
835
  PrintLiteralIndented("NAME", node->proxy()->name(), true);
836
  PrintStatements(node->body()->statements());
837
}
838

    
839

    
840
void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
841
  IndentedScope indent(this, "EXPRESSION STATEMENT");
842
  Visit(node->expression());
843
}
844

    
845

    
846
void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
847
  IndentedScope indent(this, "EMPTY");
848
}
849

    
850

    
851
void AstPrinter::VisitIfStatement(IfStatement* node) {
852
  IndentedScope indent(this, "IF");
853
  PrintIndentedVisit("CONDITION", node->condition());
854
  PrintIndentedVisit("THEN", node->then_statement());
855
  if (node->HasElseStatement()) {
856
    PrintIndentedVisit("ELSE", node->else_statement());
857
  }
858
}
859

    
860

    
861
void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
862
  IndentedScope indent(this, "CONTINUE");
863
  PrintLabelsIndented(node->target()->labels());
864
}
865

    
866

    
867
void AstPrinter::VisitBreakStatement(BreakStatement* node) {
868
  IndentedScope indent(this, "BREAK");
869
  PrintLabelsIndented(node->target()->labels());
870
}
871

    
872

    
873
void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
874
  IndentedScope indent(this, "RETURN");
875
  Visit(node->expression());
876
}
877

    
878

    
879
void AstPrinter::VisitWithStatement(WithStatement* node) {
880
  IndentedScope indent(this, "WITH");
881
  PrintIndentedVisit("OBJECT", node->expression());
882
  PrintIndentedVisit("BODY", node->statement());
883
}
884

    
885

    
886
void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
887
  IndentedScope indent(this, "SWITCH");
888
  PrintLabelsIndented(node->labels());
889
  PrintIndentedVisit("TAG", node->tag());
890
  for (int i = 0; i < node->cases()->length(); i++) {
891
    Visit(node->cases()->at(i));
892
  }
893
}
894

    
895

    
896
void AstPrinter::VisitCaseClause(CaseClause* clause) {
897
  if (clause->is_default()) {
898
    IndentedScope indent(this, "DEFAULT");
899
    PrintStatements(clause->statements());
900
  } else {
901
    IndentedScope indent(this, "CASE");
902
    Visit(clause->label());
903
    PrintStatements(clause->statements());
904
  }
905
}
906

    
907

    
908
void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
909
  IndentedScope indent(this, "DO");
910
  PrintLabelsIndented(node->labels());
911
  PrintIndentedVisit("BODY", node->body());
912
  PrintIndentedVisit("COND", node->cond());
913
}
914

    
915

    
916
void AstPrinter::VisitWhileStatement(WhileStatement* node) {
917
  IndentedScope indent(this, "WHILE");
918
  PrintLabelsIndented(node->labels());
919
  PrintIndentedVisit("COND", node->cond());
920
  PrintIndentedVisit("BODY", node->body());
921
}
922

    
923

    
924
void AstPrinter::VisitForStatement(ForStatement* node) {
925
  IndentedScope indent(this, "FOR");
926
  PrintLabelsIndented(node->labels());
927
  if (node->init()) PrintIndentedVisit("INIT", node->init());
928
  if (node->cond()) PrintIndentedVisit("COND", node->cond());
929
  PrintIndentedVisit("BODY", node->body());
930
  if (node->next()) PrintIndentedVisit("NEXT", node->next());
931
}
932

    
933

    
934
void AstPrinter::VisitForInStatement(ForInStatement* node) {
935
  IndentedScope indent(this, "FOR IN");
936
  PrintIndentedVisit("FOR", node->each());
937
  PrintIndentedVisit("IN", node->enumerable());
938
  PrintIndentedVisit("BODY", node->body());
939
}
940

    
941

    
942
void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
943
  IndentedScope indent(this, "FOR OF");
944
  PrintIndentedVisit("FOR", node->each());
945
  PrintIndentedVisit("OF", node->iterable());
946
  PrintIndentedVisit("BODY", node->body());
947
}
948

    
949

    
950
void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
951
  IndentedScope indent(this, "TRY CATCH");
952
  PrintIndentedVisit("TRY", node->try_block());
953
  PrintLiteralWithModeIndented("CATCHVAR",
954
                               node->variable(),
955
                               node->variable()->name());
956
  PrintIndentedVisit("CATCH", node->catch_block());
957
}
958

    
959

    
960
void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
961
  IndentedScope indent(this, "TRY FINALLY");
962
  PrintIndentedVisit("TRY", node->try_block());
963
  PrintIndentedVisit("FINALLY", node->finally_block());
964
}
965

    
966

    
967
void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
968
  IndentedScope indent(this, "DEBUGGER");
969
}
970

    
971

    
972
void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
973
  IndentedScope indent(this, "FUNC LITERAL");
974
  PrintLiteralIndented("NAME", node->name(), false);
975
  PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
976
  PrintParameters(node->scope());
977
  // We don't want to see the function literal in this case: it
978
  // will be printed via PrintProgram when the code for it is
979
  // generated.
980
  // PrintStatements(node->body());
981
}
982

    
983

    
984
void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
985
  IndentedScope indent(this, "NATIVE FUNC LITERAL");
986
  PrintLiteralIndented("NAME", node->name(), false);
987
}
988

    
989

    
990
void AstPrinter::VisitConditional(Conditional* node) {
991
  IndentedScope indent(this, "CONDITIONAL");
992
  PrintIndentedVisit("CONDITION", node->condition());
993
  PrintIndentedVisit("THEN", node->then_expression());
994
  PrintIndentedVisit("ELSE", node->else_expression());
995
}
996

    
997

    
998
// TODO(svenpanne) Start with IndentedScope.
999
void AstPrinter::VisitLiteral(Literal* node) {
1000
  PrintLiteralIndented("LITERAL", node->value(), true);
1001
}
1002

    
1003

    
1004
void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1005
  IndentedScope indent(this, "REGEXP LITERAL");
1006
  PrintLiteralIndented("PATTERN", node->pattern(), false);
1007
  PrintLiteralIndented("FLAGS", node->flags(), false);
1008
}
1009

    
1010

    
1011
void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1012
  IndentedScope indent(this, "OBJ LITERAL");
1013
  for (int i = 0; i < node->properties()->length(); i++) {
1014
    const char* prop_kind = NULL;
1015
    switch (node->properties()->at(i)->kind()) {
1016
      case ObjectLiteral::Property::CONSTANT:
1017
        prop_kind = "PROPERTY - CONSTANT";
1018
        break;
1019
      case ObjectLiteral::Property::COMPUTED:
1020
        prop_kind = "PROPERTY - COMPUTED";
1021
        break;
1022
      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1023
        prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
1024
        break;
1025
      case ObjectLiteral::Property::PROTOTYPE:
1026
        prop_kind = "PROPERTY - PROTOTYPE";
1027
        break;
1028
      case ObjectLiteral::Property::GETTER:
1029
        prop_kind = "PROPERTY - GETTER";
1030
        break;
1031
      case ObjectLiteral::Property::SETTER:
1032
        prop_kind = "PROPERTY - SETTER";
1033
        break;
1034
      default:
1035
        UNREACHABLE();
1036
    }
1037
    IndentedScope prop(this, prop_kind);
1038
    PrintIndentedVisit("KEY", node->properties()->at(i)->key());
1039
    PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1040
  }
1041
}
1042

    
1043

    
1044
void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1045
  IndentedScope indent(this, "ARRAY LITERAL");
1046
  if (node->values()->length() > 0) {
1047
    IndentedScope indent(this, "VALUES");
1048
    for (int i = 0; i < node->values()->length(); i++) {
1049
      Visit(node->values()->at(i));
1050
    }
1051
  }
1052
}
1053

    
1054

    
1055
// TODO(svenpanne) Start with IndentedScope.
1056
void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1057
  Variable* var = node->var();
1058
  EmbeddedVector<char, 128> buf;
1059
  int pos = OS::SNPrintF(buf, "VAR PROXY");
1060
  switch (var->location()) {
1061
    case Variable::UNALLOCATED:
1062
      break;
1063
    case Variable::PARAMETER:
1064
      OS::SNPrintF(buf + pos, " parameter[%d]", var->index());
1065
      break;
1066
    case Variable::LOCAL:
1067
      OS::SNPrintF(buf + pos, " local[%d]", var->index());
1068
      break;
1069
    case Variable::CONTEXT:
1070
      OS::SNPrintF(buf + pos, " context[%d]", var->index());
1071
      break;
1072
    case Variable::LOOKUP:
1073
      OS::SNPrintF(buf + pos, " lookup");
1074
      break;
1075
  }
1076
  PrintLiteralWithModeIndented(buf.start(), var, node->name());
1077
}
1078

    
1079

    
1080
void AstPrinter::VisitAssignment(Assignment* node) {
1081
  IndentedScope indent(this, Token::Name(node->op()));
1082
  Visit(node->target());
1083
  Visit(node->value());
1084
}
1085

    
1086

    
1087
void AstPrinter::VisitYield(Yield* node) {
1088
  IndentedScope indent(this, "YIELD");
1089
  Visit(node->expression());
1090
}
1091

    
1092

    
1093
void AstPrinter::VisitThrow(Throw* node) {
1094
  IndentedScope indent(this, "THROW");
1095
  Visit(node->exception());
1096
}
1097

    
1098

    
1099
void AstPrinter::VisitProperty(Property* node) {
1100
  IndentedScope indent(this, "PROPERTY");
1101
  Visit(node->obj());
1102
  Literal* literal = node->key()->AsLiteral();
1103
  if (literal != NULL && literal->value()->IsInternalizedString()) {
1104
    PrintLiteralIndented("NAME", literal->value(), false);
1105
  } else {
1106
    PrintIndentedVisit("KEY", node->key());
1107
  }
1108
}
1109

    
1110

    
1111
void AstPrinter::VisitCall(Call* node) {
1112
  IndentedScope indent(this, "CALL");
1113
  Visit(node->expression());
1114
  PrintArguments(node->arguments());
1115
}
1116

    
1117

    
1118
void AstPrinter::VisitCallNew(CallNew* node) {
1119
  IndentedScope indent(this, "CALL NEW");
1120
  Visit(node->expression());
1121
  PrintArguments(node->arguments());
1122
}
1123

    
1124

    
1125
void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1126
  IndentedScope indent(this, "CALL RUNTIME");
1127
  PrintLiteralIndented("NAME", node->name(), false);
1128
  PrintArguments(node->arguments());
1129
}
1130

    
1131

    
1132
void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1133
  IndentedScope indent(this, Token::Name(node->op()));
1134
  Visit(node->expression());
1135
}
1136

    
1137

    
1138
void AstPrinter::VisitCountOperation(CountOperation* node) {
1139
  EmbeddedVector<char, 128> buf;
1140
  OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1141
               Token::Name(node->op()));
1142
  IndentedScope indent(this, buf.start());
1143
  Visit(node->expression());
1144
}
1145

    
1146

    
1147
void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1148
  IndentedScope indent(this, Token::Name(node->op()));
1149
  Visit(node->left());
1150
  Visit(node->right());
1151
}
1152

    
1153

    
1154
void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1155
  IndentedScope indent(this, Token::Name(node->op()));
1156
  Visit(node->left());
1157
  Visit(node->right());
1158
}
1159

    
1160

    
1161
void AstPrinter::VisitThisFunction(ThisFunction* node) {
1162
  IndentedScope indent(this, "THIS-FUNCTION");
1163
}
1164

    
1165
#endif  // DEBUG
1166

    
1167
} }  // namespace v8::internal