blob: 1ff2edd2854adbdeab29b753bc3ba1c0119dba60 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#include <stdarg.h>
6
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/v8.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/ast-value-factory.h"
10#include "src/base/platform/platform.h"
11#include "src/prettyprinter.h"
12#include "src/scopes.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000013
14namespace v8 {
15namespace internal {
16
17#ifdef DEBUG
18
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019PrettyPrinter::PrettyPrinter(Zone* zone) {
Steve Blocka7e24c12009-10-30 11:49:00 +000020 output_ = NULL;
21 size_ = 0;
22 pos_ = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023 InitializeAstVisitor(zone);
Steve Blocka7e24c12009-10-30 11:49:00 +000024}
25
26
27PrettyPrinter::~PrettyPrinter() {
28 DeleteArray(output_);
29}
30
31
32void PrettyPrinter::VisitBlock(Block* node) {
33 if (!node->is_initializer_block()) Print("{ ");
34 PrintStatements(node->statements());
35 if (node->statements()->length() > 0) Print(" ");
36 if (!node->is_initializer_block()) Print("}");
37}
38
39
Ben Murdoch3ef787d2012-04-12 10:51:47 +010040void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +000041 Print("var ");
42 PrintLiteral(node->proxy()->name(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +000043 Print(";");
44}
45
46
Ben Murdoch3ef787d2012-04-12 10:51:47 +010047void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
48 Print("function ");
49 PrintLiteral(node->proxy()->name(), false);
50 Print(" = ");
51 PrintFunctionLiteral(node->fun());
52 Print(";");
53}
54
55
56void PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
57 Print("module ");
58 PrintLiteral(node->proxy()->name(), false);
59 Print(" = ");
60 Visit(node->module());
61 Print(";");
62}
63
64
65void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
66 Print("import ");
67 PrintLiteral(node->proxy()->name(), false);
68 Print(" from ");
69 Visit(node->module());
70 Print(";");
71}
72
73
74void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
75 Print("export ");
76 PrintLiteral(node->proxy()->name(), false);
77 Print(";");
78}
79
80
81void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
82 VisitBlock(node->body());
83}
84
85
86void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
87 Visit(node->proxy());
88}
89
90
91void PrettyPrinter::VisitModulePath(ModulePath* node) {
92 Visit(node->module());
93 Print(".");
94 PrintLiteral(node->name(), false);
95}
96
97
98void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
99 Print("at ");
100 PrintLiteral(node->url(), true);
101}
102
103
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
105 Print("module ");
106 PrintLiteral(node->proxy()->name(), false);
107 Print(" ");
108 Visit(node->body());
109}
110
111
Steve Blocka7e24c12009-10-30 11:49:00 +0000112void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
113 Visit(node->expression());
114 Print(";");
115}
116
117
118void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
119 Print(";");
120}
121
122
123void PrettyPrinter::VisitIfStatement(IfStatement* node) {
124 Print("if (");
125 Visit(node->condition());
126 Print(") ");
127 Visit(node->then_statement());
128 if (node->HasElseStatement()) {
129 Print(" else ");
130 Visit(node->else_statement());
131 }
132}
133
134
135void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
136 Print("continue");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 ZoneList<const AstRawString*>* labels = node->target()->labels();
Steve Blocka7e24c12009-10-30 11:49:00 +0000138 if (labels != NULL) {
139 Print(" ");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 DCHECK(labels->length() > 0); // guaranteed to have at least one entry
Steve Blocka7e24c12009-10-30 11:49:00 +0000141 PrintLiteral(labels->at(0), false); // any label from the list is fine
142 }
143 Print(";");
144}
145
146
147void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
148 Print("break");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 ZoneList<const AstRawString*>* labels = node->target()->labels();
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 if (labels != NULL) {
151 Print(" ");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000152 DCHECK(labels->length() > 0); // guaranteed to have at least one entry
Steve Blocka7e24c12009-10-30 11:49:00 +0000153 PrintLiteral(labels->at(0), false); // any label from the list is fine
154 }
155 Print(";");
156}
157
158
159void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
160 Print("return ");
161 Visit(node->expression());
162 Print(";");
163}
164
165
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000166void PrettyPrinter::VisitWithStatement(WithStatement* node) {
167 Print("with (");
Steve Blocka7e24c12009-10-30 11:49:00 +0000168 Visit(node->expression());
169 Print(") ");
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000170 Visit(node->statement());
Steve Blocka7e24c12009-10-30 11:49:00 +0000171}
172
173
Steve Blocka7e24c12009-10-30 11:49:00 +0000174void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
175 PrintLabels(node->labels());
176 Print("switch (");
177 Visit(node->tag());
178 Print(") { ");
179 ZoneList<CaseClause*>* cases = node->cases();
180 for (int i = 0; i < cases->length(); i++)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 Visit(cases->at(i));
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 Print("}");
183}
184
185
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
187 if (clause->is_default()) {
188 Print("default");
189 } else {
190 Print("case ");
191 Visit(clause->label());
192 }
193 Print(": ");
194 PrintStatements(clause->statements());
195 if (clause->statements()->length() > 0)
196 Print(" ");
197}
198
199
Steve Block3ce2e202009-11-05 08:53:23 +0000200void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000201 PrintLabels(node->labels());
Steve Block3ce2e202009-11-05 08:53:23 +0000202 Print("do ");
203 Visit(node->body());
204 Print(" while (");
205 Visit(node->cond());
206 Print(");");
207}
Steve Blocka7e24c12009-10-30 11:49:00 +0000208
Steve Blocka7e24c12009-10-30 11:49:00 +0000209
Steve Block3ce2e202009-11-05 08:53:23 +0000210void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
211 PrintLabels(node->labels());
212 Print("while (");
213 Visit(node->cond());
214 Print(") ");
215 Visit(node->body());
216}
217
218
219void PrettyPrinter::VisitForStatement(ForStatement* node) {
220 PrintLabels(node->labels());
221 Print("for (");
222 if (node->init() != NULL) {
223 Visit(node->init());
224 Print(" ");
225 } else {
226 Print("; ");
Steve Blocka7e24c12009-10-30 11:49:00 +0000227 }
Steve Block3ce2e202009-11-05 08:53:23 +0000228 if (node->cond() != NULL) Visit(node->cond());
229 Print("; ");
230 if (node->next() != NULL) {
231 Visit(node->next()); // prints extra ';', unfortunately
232 // to fix: should use Expression for next
233 }
234 Print(") ");
235 Visit(node->body());
Steve Blocka7e24c12009-10-30 11:49:00 +0000236}
237
238
239void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
240 PrintLabels(node->labels());
241 Print("for (");
242 Visit(node->each());
243 Print(" in ");
244 Visit(node->enumerable());
245 Print(") ");
246 Visit(node->body());
247}
248
249
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
251 PrintLabels(node->labels());
252 Print("for (");
253 Visit(node->each());
254 Print(" of ");
255 Visit(node->iterable());
256 Print(") ");
257 Visit(node->body());
258}
259
260
Steve Block3ce2e202009-11-05 08:53:23 +0000261void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 Print("try ");
263 Visit(node->try_block());
264 Print(" catch (");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000265 const bool quote = false;
266 PrintLiteral(node->variable()->name(), quote);
Steve Blocka7e24c12009-10-30 11:49:00 +0000267 Print(") ");
268 Visit(node->catch_block());
269}
270
271
Steve Block3ce2e202009-11-05 08:53:23 +0000272void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000273 Print("try ");
274 Visit(node->try_block());
275 Print(" finally ");
276 Visit(node->finally_block());
277}
278
279
280void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
281 Print("debugger ");
282}
283
284
285void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
286 Print("(");
287 PrintFunctionLiteral(node);
288 Print(")");
289}
290
291
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) {
293 Print("(class ");
294 PrintLiteral(node->name(), false);
295 if (node->extends()) {
296 Print(" extends ");
297 Visit(node->extends());
298 }
299 Print(" { ");
300 for (int i = 0; i < node->properties()->length(); i++) {
301 PrintObjectLiteralProperty(node->properties()->at(i));
302 }
303 Print(" })");
304}
305
306
307void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000308 Print("(");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309 PrintLiteral(node->name(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 Print(")");
311}
312
313
314void PrettyPrinter::VisitConditional(Conditional* node) {
315 Visit(node->condition());
316 Print(" ? ");
317 Visit(node->then_expression());
318 Print(" : ");
319 Visit(node->else_expression());
320}
321
322
323void PrettyPrinter::VisitLiteral(Literal* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324 PrintLiteral(node->value(), true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000325}
326
327
328void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
329 Print(" RegExp(");
330 PrintLiteral(node->pattern(), false);
331 Print(",");
332 PrintLiteral(node->flags(), false);
333 Print(") ");
334}
335
336
337void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
338 Print("{ ");
339 for (int i = 0; i < node->properties()->length(); i++) {
340 if (i != 0) Print(",");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 PrintObjectLiteralProperty(node->properties()->at(i));
Steve Blocka7e24c12009-10-30 11:49:00 +0000342 }
343 Print(" }");
344}
345
346
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000347void PrettyPrinter::PrintObjectLiteralProperty(
348 ObjectLiteralProperty* property) {
349 // TODO(arv): Better printing of methods etc.
350 Print(" ");
351 Visit(property->key());
352 Print(": ");
353 Visit(property->value());
354}
355
356
Steve Blocka7e24c12009-10-30 11:49:00 +0000357void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
358 Print("[ ");
359 for (int i = 0; i < node->values()->length(); i++) {
360 if (i != 0) Print(",");
361 Visit(node->values()->at(i));
362 }
363 Print(" ]");
364}
365
366
Steve Blocka7e24c12009-10-30 11:49:00 +0000367void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
368 PrintLiteral(node->name(), false);
369}
370
371
372void PrettyPrinter::VisitAssignment(Assignment* node) {
373 Visit(node->target());
374 Print(" %s ", Token::String(node->op()));
375 Visit(node->value());
376}
377
378
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000379void PrettyPrinter::VisitYield(Yield* node) {
380 Print("yield ");
381 Visit(node->expression());
382}
383
384
Steve Blocka7e24c12009-10-30 11:49:00 +0000385void PrettyPrinter::VisitThrow(Throw* node) {
386 Print("throw ");
387 Visit(node->exception());
388}
389
390
391void PrettyPrinter::VisitProperty(Property* node) {
392 Expression* key = node->key();
393 Literal* literal = key->AsLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000394 if (literal != NULL && literal->value()->IsInternalizedString()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000395 Print("(");
396 Visit(node->obj());
397 Print(").");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398 PrintLiteral(literal->value(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 } else {
400 Visit(node->obj());
401 Print("[");
402 Visit(key);
403 Print("]");
404 }
405}
406
407
408void PrettyPrinter::VisitCall(Call* node) {
409 Visit(node->expression());
410 PrintArguments(node->arguments());
411}
412
413
414void PrettyPrinter::VisitCallNew(CallNew* node) {
415 Print("new (");
416 Visit(node->expression());
417 Print(")");
418 PrintArguments(node->arguments());
419}
420
421
422void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
423 Print("%%");
424 PrintLiteral(node->name(), false);
425 PrintArguments(node->arguments());
426}
427
428
429void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000430 Token::Value op = node->op();
431 bool needsSpace =
432 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
433 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
Steve Blocka7e24c12009-10-30 11:49:00 +0000434 Visit(node->expression());
435 Print(")");
436}
437
438
439void PrettyPrinter::VisitCountOperation(CountOperation* node) {
440 Print("(");
441 if (node->is_prefix()) Print("%s", Token::String(node->op()));
442 Visit(node->expression());
443 if (node->is_postfix()) Print("%s", Token::String(node->op()));
444 Print(")");
445}
446
447
448void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
449 Print("(");
450 Visit(node->left());
Ben Murdoch257744e2011-11-30 15:57:28 +0000451 Print(" %s ", Token::String(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 Visit(node->right());
453 Print(")");
454}
455
456
457void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
458 Print("(");
459 Visit(node->left());
Ben Murdoch257744e2011-11-30 15:57:28 +0000460 Print(" %s ", Token::String(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000461 Visit(node->right());
462 Print(")");
463}
464
465
466void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
467 Print("<this-function>");
468}
469
470
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000471void PrettyPrinter::VisitSuperReference(SuperReference* node) {
472 Print("<super-reference>");
473}
474
475
Steve Blocka7e24c12009-10-30 11:49:00 +0000476const char* PrettyPrinter::Print(AstNode* node) {
477 Init();
478 Visit(node);
479 return output_;
480}
481
482
483const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
484 Init();
485 ExpressionStatement* statement =
486 program->body()->at(0)->AsExpressionStatement();
487 Visit(statement->expression());
488 return output_;
489}
490
491
492const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
493 Init();
494 PrintStatements(program->body());
495 Print("\n");
496 return output_;
497}
498
499
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000500void PrettyPrinter::PrintOut(Zone* zone, AstNode* node) {
501 PrettyPrinter printer(zone);
Steve Blocka7e24c12009-10-30 11:49:00 +0000502 PrintF("%s", printer.Print(node));
503}
504
505
506void PrettyPrinter::Init() {
507 if (size_ == 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000508 DCHECK(output_ == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000509 const int initial_size = 256;
510 output_ = NewArray<char>(initial_size);
511 size_ = initial_size;
512 }
513 output_[0] = '\0';
514 pos_ = 0;
515}
516
517
518void PrettyPrinter::Print(const char* format, ...) {
519 for (;;) {
520 va_list arguments;
521 va_start(arguments, format);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000522 int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
523 format,
524 arguments);
Steve Blocka7e24c12009-10-30 11:49:00 +0000525 va_end(arguments);
526
527 if (n >= 0) {
528 // there was enough space - we are done
529 pos_ += n;
530 return;
531 } else {
532 // there was not enough space - allocate more and try again
533 const int slack = 32;
534 int new_size = size_ + (size_ >> 1) + slack;
535 char* new_output = NewArray<char>(new_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000536 MemCopy(new_output, output_, pos_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000537 DeleteArray(output_);
538 output_ = new_output;
539 size_ = new_size;
540 }
541 }
542}
543
544
545void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100546 if (statements == NULL) return;
Steve Blocka7e24c12009-10-30 11:49:00 +0000547 for (int i = 0; i < statements->length(); i++) {
548 if (i != 0) Print(" ");
549 Visit(statements->at(i));
550 }
551}
552
553
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000554void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000555 if (labels != NULL) {
556 for (int i = 0; i < labels->length(); i++) {
557 PrintLiteral(labels->at(i), false);
558 Print(": ");
559 }
560 }
561}
562
563
564void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
565 Print("(");
566 for (int i = 0; i < arguments->length(); i++) {
567 if (i != 0) Print(", ");
568 Visit(arguments->at(i));
569 }
570 Print(")");
571}
572
573
574void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
575 Object* object = *value;
576 if (object->IsString()) {
577 String* string = String::cast(object);
578 if (quote) Print("\"");
579 for (int i = 0; i < string->length(); i++) {
580 Print("%c", string->Get(i));
581 }
582 if (quote) Print("\"");
Steve Block44f0eee2011-05-26 01:26:41 +0100583 } else if (object->IsNull()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 Print("null");
Steve Block44f0eee2011-05-26 01:26:41 +0100585 } else if (object->IsTrue()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 Print("true");
Steve Block44f0eee2011-05-26 01:26:41 +0100587 } else if (object->IsFalse()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000588 Print("false");
Steve Block44f0eee2011-05-26 01:26:41 +0100589 } else if (object->IsUndefined()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000590 Print("undefined");
591 } else if (object->IsNumber()) {
592 Print("%g", object->Number());
593 } else if (object->IsJSObject()) {
594 // regular expression
595 if (object->IsJSFunction()) {
596 Print("JS-Function");
597 } else if (object->IsJSArray()) {
598 Print("JS-array[%u]", JSArray::cast(object)->length());
599 } else if (object->IsJSObject()) {
600 Print("JS-Object");
601 } else {
602 Print("?UNKNOWN?");
603 }
604 } else if (object->IsFixedArray()) {
605 Print("FixedArray");
606 } else {
607 Print("<unknown literal %p>", object);
608 }
609}
610
611
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000612void PrettyPrinter::PrintLiteral(const AstRawString* value, bool quote) {
613 PrintLiteral(value->string(), quote);
614}
615
616
Steve Blocka7e24c12009-10-30 11:49:00 +0000617void PrettyPrinter::PrintParameters(Scope* scope) {
618 Print("(");
619 for (int i = 0; i < scope->num_parameters(); i++) {
620 if (i > 0) Print(", ");
621 PrintLiteral(scope->parameter(i)->name(), false);
622 }
623 Print(")");
624}
625
626
627void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
628 for (int i = 0; i < declarations->length(); i++) {
629 if (i > 0) Print(" ");
630 Visit(declarations->at(i));
631 }
632}
633
634
635void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
636 Print("function ");
637 PrintLiteral(function->name(), false);
638 PrintParameters(function->scope());
639 Print(" { ");
640 PrintDeclarations(function->scope()->declarations());
641 PrintStatements(function->body());
642 Print(" }");
643}
644
645
Steve Blocka7e24c12009-10-30 11:49:00 +0000646//-----------------------------------------------------------------------------
647
648class IndentedScope BASE_EMBEDDED {
649 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000650 IndentedScope(AstPrinter* printer, const char* txt)
Steve Block44f0eee2011-05-26 01:26:41 +0100651 : ast_printer_(printer) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000652 ast_printer_->PrintIndented(txt);
Steve Blocka7e24c12009-10-30 11:49:00 +0000653 ast_printer_->Print("\n");
654 ast_printer_->inc_indent();
655 }
656
657 virtual ~IndentedScope() {
658 ast_printer_->dec_indent();
659 }
660
Steve Blocka7e24c12009-10-30 11:49:00 +0000661 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100662 AstPrinter* ast_printer_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000663};
664
665
Steve Blocka7e24c12009-10-30 11:49:00 +0000666//-----------------------------------------------------------------------------
667
Steve Blocka7e24c12009-10-30 11:49:00 +0000668
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000669AstPrinter::AstPrinter(Zone* zone) : PrettyPrinter(zone), indent_(0) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000670}
671
672
673AstPrinter::~AstPrinter() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000674 DCHECK(indent_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000675}
676
677
678void AstPrinter::PrintIndented(const char* txt) {
679 for (int i = 0; i < indent_; i++) {
680 Print(". ");
681 }
682 Print(txt);
683}
684
685
686void AstPrinter::PrintLiteralIndented(const char* info,
687 Handle<Object> value,
688 bool quote) {
689 PrintIndented(info);
690 Print(" ");
691 PrintLiteral(value, quote);
692 Print("\n");
693}
694
695
696void AstPrinter::PrintLiteralWithModeIndented(const char* info,
697 Variable* var,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100698 Handle<Object> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000699 if (var == NULL) {
700 PrintLiteralIndented(info, value, true);
701 } else {
702 EmbeddedVector<char, 256> buf;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000703 int pos = SNPrintF(buf, "%s (mode = %s", info,
704 Variable::Mode2String(var->mode()));
705 SNPrintF(buf + pos, ")");
Steve Blocka7e24c12009-10-30 11:49:00 +0000706 PrintLiteralIndented(buf.start(), value, true);
707 }
708}
709
710
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000711void AstPrinter::PrintLabelsIndented(ZoneList<const AstRawString*>* labels) {
712 if (labels == NULL || labels->length() == 0) return;
713 PrintIndented("LABELS ");
714 PrintLabels(labels);
715 Print("\n");
Steve Blocka7e24c12009-10-30 11:49:00 +0000716}
717
718
719void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000720 IndentedScope indent(this, s);
Steve Blocka7e24c12009-10-30 11:49:00 +0000721 Visit(node);
722}
723
724
725const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
726 Init();
Steve Block44f0eee2011-05-26 01:26:41 +0100727 { IndentedScope indent(this, "FUNC");
Steve Blocka7e24c12009-10-30 11:49:00 +0000728 PrintLiteralIndented("NAME", program->name(), true);
729 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
730 PrintParameters(program->scope());
731 PrintDeclarations(program->scope()->declarations());
732 PrintStatements(program->body());
733 }
734 return Output();
735}
736
737
738void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
739 if (declarations->length() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100740 IndentedScope indent(this, "DECLS");
Steve Blocka7e24c12009-10-30 11:49:00 +0000741 for (int i = 0; i < declarations->length(); i++) {
742 Visit(declarations->at(i));
743 }
744 }
745}
746
747
748void AstPrinter::PrintParameters(Scope* scope) {
749 if (scope->num_parameters() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100750 IndentedScope indent(this, "PARAMS");
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 for (int i = 0; i < scope->num_parameters(); i++) {
752 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100753 scope->parameter(i)->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000754 }
755 }
756}
757
758
759void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
760 for (int i = 0; i < statements->length(); i++) {
761 Visit(statements->at(i));
762 }
763}
764
765
766void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
767 for (int i = 0; i < arguments->length(); i++) {
768 Visit(arguments->at(i));
769 }
770}
771
772
Steve Blocka7e24c12009-10-30 11:49:00 +0000773void AstPrinter::VisitBlock(Block* node) {
774 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
Steve Block44f0eee2011-05-26 01:26:41 +0100775 IndentedScope indent(this, block_txt);
Steve Blocka7e24c12009-10-30 11:49:00 +0000776 PrintStatements(node->statements());
777}
778
779
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000780// TODO(svenpanne) Start with IndentedScope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100781void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
782 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
783 node->proxy()->var(),
784 node->proxy()->name());
785}
786
787
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000788// TODO(svenpanne) Start with IndentedScope.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100789void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
790 PrintIndented("FUNCTION ");
791 PrintLiteral(node->proxy()->name(), true);
792 Print(" = function ");
793 PrintLiteral(node->fun()->name(), false);
794 Print("\n");
795}
796
797
798void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
799 IndentedScope indent(this, "MODULE");
800 PrintLiteralIndented("NAME", node->proxy()->name(), true);
801 Visit(node->module());
802}
803
804
805void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
806 IndentedScope indent(this, "IMPORT");
807 PrintLiteralIndented("NAME", node->proxy()->name(), true);
808 Visit(node->module());
809}
810
811
812void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
813 IndentedScope indent(this, "EXPORT ");
814 PrintLiteral(node->proxy()->name(), true);
815}
816
817
818void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000819 IndentedScope indent(this, "MODULE LITERAL");
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100820 VisitBlock(node->body());
821}
822
823
824void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 IndentedScope indent(this, "MODULE VARIABLE");
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100826 Visit(node->proxy());
827}
828
829
830void AstPrinter::VisitModulePath(ModulePath* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831 IndentedScope indent(this, "MODULE PATH");
832 PrintIndentedVisit("MODULE PATH PARENT", node->module());
833 PrintLiteralIndented("NAME", node->name(), true);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100834}
835
836
837void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
838 PrintLiteralIndented("URL", node->url(), true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000839}
840
841
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000842void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
843 IndentedScope indent(this, "MODULE STATEMENT");
844 PrintLiteralIndented("NAME", node->proxy()->name(), true);
845 PrintStatements(node->body()->statements());
846}
847
848
Steve Blocka7e24c12009-10-30 11:49:00 +0000849void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000850 IndentedScope indent(this, "EXPRESSION STATEMENT");
Steve Blocka7e24c12009-10-30 11:49:00 +0000851 Visit(node->expression());
852}
853
854
855void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 IndentedScope indent(this, "EMPTY");
Steve Blocka7e24c12009-10-30 11:49:00 +0000857}
858
859
860void AstPrinter::VisitIfStatement(IfStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861 IndentedScope indent(this, "IF");
862 PrintIndentedVisit("CONDITION", node->condition());
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 PrintIndentedVisit("THEN", node->then_statement());
864 if (node->HasElseStatement()) {
865 PrintIndentedVisit("ELSE", node->else_statement());
866 }
867}
868
869
870void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000871 IndentedScope indent(this, "CONTINUE");
872 PrintLabelsIndented(node->target()->labels());
Steve Blocka7e24c12009-10-30 11:49:00 +0000873}
874
875
876void AstPrinter::VisitBreakStatement(BreakStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000877 IndentedScope indent(this, "BREAK");
878 PrintLabelsIndented(node->target()->labels());
Steve Blocka7e24c12009-10-30 11:49:00 +0000879}
880
881
882void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883 IndentedScope indent(this, "RETURN");
884 Visit(node->expression());
Steve Blocka7e24c12009-10-30 11:49:00 +0000885}
886
887
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000888void AstPrinter::VisitWithStatement(WithStatement* node) {
889 IndentedScope indent(this, "WITH");
890 PrintIndentedVisit("OBJECT", node->expression());
891 PrintIndentedVisit("BODY", node->statement());
Steve Blocka7e24c12009-10-30 11:49:00 +0000892}
893
894
Steve Blocka7e24c12009-10-30 11:49:00 +0000895void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100896 IndentedScope indent(this, "SWITCH");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000897 PrintLabelsIndented(node->labels());
Steve Blocka7e24c12009-10-30 11:49:00 +0000898 PrintIndentedVisit("TAG", node->tag());
899 for (int i = 0; i < node->cases()->length(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000900 Visit(node->cases()->at(i));
901 }
902}
903
904
905void AstPrinter::VisitCaseClause(CaseClause* clause) {
906 if (clause->is_default()) {
907 IndentedScope indent(this, "DEFAULT");
908 PrintStatements(clause->statements());
909 } else {
910 IndentedScope indent(this, "CASE");
911 Visit(clause->label());
912 PrintStatements(clause->statements());
Steve Blocka7e24c12009-10-30 11:49:00 +0000913 }
914}
915
916
Steve Block3ce2e202009-11-05 08:53:23 +0000917void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100918 IndentedScope indent(this, "DO");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 PrintLabelsIndented(node->labels());
Steve Block3ce2e202009-11-05 08:53:23 +0000920 PrintIndentedVisit("BODY", node->body());
921 PrintIndentedVisit("COND", node->cond());
922}
923
924
925void AstPrinter::VisitWhileStatement(WhileStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100926 IndentedScope indent(this, "WHILE");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927 PrintLabelsIndented(node->labels());
Steve Block3ce2e202009-11-05 08:53:23 +0000928 PrintIndentedVisit("COND", node->cond());
929 PrintIndentedVisit("BODY", node->body());
930}
931
932
933void AstPrinter::VisitForStatement(ForStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100934 IndentedScope indent(this, "FOR");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935 PrintLabelsIndented(node->labels());
Steve Blocka7e24c12009-10-30 11:49:00 +0000936 if (node->init()) PrintIndentedVisit("INIT", node->init());
937 if (node->cond()) PrintIndentedVisit("COND", node->cond());
Steve Block3ce2e202009-11-05 08:53:23 +0000938 PrintIndentedVisit("BODY", node->body());
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 if (node->next()) PrintIndentedVisit("NEXT", node->next());
940}
941
942
943void AstPrinter::VisitForInStatement(ForInStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100944 IndentedScope indent(this, "FOR IN");
Steve Blocka7e24c12009-10-30 11:49:00 +0000945 PrintIndentedVisit("FOR", node->each());
946 PrintIndentedVisit("IN", node->enumerable());
947 PrintIndentedVisit("BODY", node->body());
948}
949
950
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
952 IndentedScope indent(this, "FOR OF");
953 PrintIndentedVisit("FOR", node->each());
954 PrintIndentedVisit("OF", node->iterable());
955 PrintIndentedVisit("BODY", node->body());
956}
957
958
Steve Block3ce2e202009-11-05 08:53:23 +0000959void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100960 IndentedScope indent(this, "TRY CATCH");
Steve Blocka7e24c12009-10-30 11:49:00 +0000961 PrintIndentedVisit("TRY", node->try_block());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000962 PrintLiteralWithModeIndented("CATCHVAR",
963 node->variable(),
964 node->variable()->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000965 PrintIndentedVisit("CATCH", node->catch_block());
966}
967
968
Steve Block3ce2e202009-11-05 08:53:23 +0000969void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100970 IndentedScope indent(this, "TRY FINALLY");
Steve Blocka7e24c12009-10-30 11:49:00 +0000971 PrintIndentedVisit("TRY", node->try_block());
972 PrintIndentedVisit("FINALLY", node->finally_block());
973}
974
975
976void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100977 IndentedScope indent(this, "DEBUGGER");
Steve Blocka7e24c12009-10-30 11:49:00 +0000978}
979
980
981void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100982 IndentedScope indent(this, "FUNC LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000983 PrintLiteralIndented("NAME", node->name(), false);
984 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
985 PrintParameters(node->scope());
986 // We don't want to see the function literal in this case: it
987 // will be printed via PrintProgram when the code for it is
988 // generated.
989 // PrintStatements(node->body());
990}
991
992
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000993void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
994 IndentedScope indent(this, "CLASS LITERAL");
995 PrintLiteralIndented("NAME", node->name(), false);
996}
997
998
999void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
1000 IndentedScope indent(this, "NATIVE FUNC LITERAL");
1001 PrintLiteralIndented("NAME", node->name(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001002}
1003
1004
1005void AstPrinter::VisitConditional(Conditional* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001006 IndentedScope indent(this, "CONDITIONAL");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001007 PrintIndentedVisit("CONDITION", node->condition());
Steve Blocka7e24c12009-10-30 11:49:00 +00001008 PrintIndentedVisit("THEN", node->then_expression());
1009 PrintIndentedVisit("ELSE", node->else_expression());
1010}
1011
1012
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013// TODO(svenpanne) Start with IndentedScope.
Steve Blocka7e24c12009-10-30 11:49:00 +00001014void AstPrinter::VisitLiteral(Literal* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001015 PrintLiteralIndented("LITERAL", node->value(), true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001016}
1017
1018
1019void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001020 IndentedScope indent(this, "REGEXP LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +00001021 PrintLiteralIndented("PATTERN", node->pattern(), false);
1022 PrintLiteralIndented("FLAGS", node->flags(), false);
1023}
1024
1025
1026void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001027 IndentedScope indent(this, "OBJ LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +00001028 for (int i = 0; i < node->properties()->length(); i++) {
1029 const char* prop_kind = NULL;
1030 switch (node->properties()->at(i)->kind()) {
1031 case ObjectLiteral::Property::CONSTANT:
1032 prop_kind = "PROPERTY - CONSTANT";
1033 break;
1034 case ObjectLiteral::Property::COMPUTED:
1035 prop_kind = "PROPERTY - COMPUTED";
1036 break;
1037 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1038 prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
1039 break;
1040 case ObjectLiteral::Property::PROTOTYPE:
1041 prop_kind = "PROPERTY - PROTOTYPE";
1042 break;
1043 case ObjectLiteral::Property::GETTER:
1044 prop_kind = "PROPERTY - GETTER";
1045 break;
1046 case ObjectLiteral::Property::SETTER:
1047 prop_kind = "PROPERTY - SETTER";
1048 break;
1049 default:
1050 UNREACHABLE();
1051 }
Steve Block44f0eee2011-05-26 01:26:41 +01001052 IndentedScope prop(this, prop_kind);
Steve Blocka7e24c12009-10-30 11:49:00 +00001053 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
1054 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1055 }
1056}
1057
1058
1059void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001060 IndentedScope indent(this, "ARRAY LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +00001061 if (node->values()->length() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01001062 IndentedScope indent(this, "VALUES");
Steve Blocka7e24c12009-10-30 11:49:00 +00001063 for (int i = 0; i < node->values()->length(); i++) {
1064 Visit(node->values()->at(i));
1065 }
1066 }
1067}
1068
1069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070// TODO(svenpanne) Start with IndentedScope.
Steve Blocka7e24c12009-10-30 11:49:00 +00001071void AstPrinter::VisitVariableProxy(VariableProxy* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001072 Variable* var = node->var();
Ben Murdoch589d6972011-11-30 16:04:58 +00001073 EmbeddedVector<char, 128> buf;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001074 int pos = SNPrintF(buf, "VAR PROXY");
Ben Murdoch589d6972011-11-30 16:04:58 +00001075 switch (var->location()) {
1076 case Variable::UNALLOCATED:
1077 break;
1078 case Variable::PARAMETER:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 SNPrintF(buf + pos, " parameter[%d]", var->index());
Ben Murdoch589d6972011-11-30 16:04:58 +00001080 break;
1081 case Variable::LOCAL:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082 SNPrintF(buf + pos, " local[%d]", var->index());
Ben Murdoch589d6972011-11-30 16:04:58 +00001083 break;
1084 case Variable::CONTEXT:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001085 SNPrintF(buf + pos, " context[%d]", var->index());
Ben Murdoch589d6972011-11-30 16:04:58 +00001086 break;
1087 case Variable::LOOKUP:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088 SNPrintF(buf + pos, " lookup");
Ben Murdoch589d6972011-11-30 16:04:58 +00001089 break;
Steve Blocka7e24c12009-10-30 11:49:00 +00001090 }
Ben Murdoch589d6972011-11-30 16:04:58 +00001091 PrintLiteralWithModeIndented(buf.start(), var, node->name());
Steve Blocka7e24c12009-10-30 11:49:00 +00001092}
1093
1094
1095void AstPrinter::VisitAssignment(Assignment* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001096 IndentedScope indent(this, Token::Name(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001097 Visit(node->target());
1098 Visit(node->value());
1099}
1100
1101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001102void AstPrinter::VisitYield(Yield* node) {
1103 IndentedScope indent(this, "YIELD");
1104 Visit(node->expression());
1105}
1106
1107
Steve Blocka7e24c12009-10-30 11:49:00 +00001108void AstPrinter::VisitThrow(Throw* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001109 IndentedScope indent(this, "THROW");
1110 Visit(node->exception());
Steve Blocka7e24c12009-10-30 11:49:00 +00001111}
1112
1113
1114void AstPrinter::VisitProperty(Property* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001115 IndentedScope indent(this, "PROPERTY");
Steve Blocka7e24c12009-10-30 11:49:00 +00001116 Visit(node->obj());
1117 Literal* literal = node->key()->AsLiteral();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001118 if (literal != NULL && literal->value()->IsInternalizedString()) {
1119 PrintLiteralIndented("NAME", literal->value(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001120 } else {
1121 PrintIndentedVisit("KEY", node->key());
1122 }
1123}
1124
1125
1126void AstPrinter::VisitCall(Call* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001127 IndentedScope indent(this, "CALL");
Steve Blocka7e24c12009-10-30 11:49:00 +00001128 Visit(node->expression());
1129 PrintArguments(node->arguments());
1130}
1131
1132
1133void AstPrinter::VisitCallNew(CallNew* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001134 IndentedScope indent(this, "CALL NEW");
Steve Blocka7e24c12009-10-30 11:49:00 +00001135 Visit(node->expression());
1136 PrintArguments(node->arguments());
1137}
1138
1139
1140void AstPrinter::VisitCallRuntime(CallRuntime* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001141 IndentedScope indent(this, "CALL RUNTIME");
1142 PrintLiteralIndented("NAME", node->name(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001143 PrintArguments(node->arguments());
1144}
1145
1146
1147void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001148 IndentedScope indent(this, Token::Name(node->op()));
1149 Visit(node->expression());
Steve Blocka7e24c12009-10-30 11:49:00 +00001150}
1151
1152
1153void AstPrinter::VisitCountOperation(CountOperation* node) {
1154 EmbeddedVector<char, 128> buf;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001155 SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1156 Token::Name(node->op()));
1157 IndentedScope indent(this, buf.start());
1158 Visit(node->expression());
Steve Blocka7e24c12009-10-30 11:49:00 +00001159}
1160
1161
1162void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163 IndentedScope indent(this, Token::Name(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 Visit(node->left());
1165 Visit(node->right());
1166}
1167
1168
1169void AstPrinter::VisitCompareOperation(CompareOperation* node) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170 IndentedScope indent(this, Token::Name(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001171 Visit(node->left());
1172 Visit(node->right());
1173}
1174
1175
1176void AstPrinter::VisitThisFunction(ThisFunction* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001177 IndentedScope indent(this, "THIS-FUNCTION");
Steve Blocka7e24c12009-10-30 11:49:00 +00001178}
1179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180
1181void AstPrinter::VisitSuperReference(SuperReference* node) {
1182 IndentedScope indent(this, "SUPER-REFERENCE");
1183}
1184
Steve Blocka7e24c12009-10-30 11:49:00 +00001185#endif // DEBUG
1186
1187} } // namespace v8::internal