Remove AstNode::PrettyPrint, --print-source, and --print-builtin-source

The PrettyPrinter may have been valuable once, but with all the desugaring
now done in the parser the output is far from readable, and for some nodes
it's next-to-impossible to recreate the source from the AST. --print-ast is a
much more sensible place to look for human-readable info on what the parser did.

Review-Url: https://codereview.chromium.org/1974623002
Cr-Commit-Position: refs/heads/master@{#37730}
This commit is contained in:
adamk 2016-07-13 14:13:32 -07:00 committed by Commit bot
parent aa91225289
commit efefadc6ca
9 changed files with 31 additions and 646 deletions

View File

@ -41,10 +41,6 @@ void AstNode::Print(Isolate* isolate) {
}
void AstNode::PrettyPrint(Isolate* isolate) {
PrettyPrinter::PrintOut(isolate, this);
}
#endif // DEBUG

View File

@ -197,7 +197,6 @@ class AstNode: public ZoneObject {
int position() const { return position_; }
#ifdef DEBUG
void PrettyPrint(Isolate* isolate);
void Print(Isolate* isolate);
#endif // DEBUG

View File

@ -475,514 +475,13 @@ static int FormatSlotNode(Vector<char>* buf, Expression* node,
return pos;
}
PrettyPrinter::PrettyPrinter(Isolate* isolate) {
isolate_ = isolate;
output_ = NULL;
size_ = 0;
pos_ = 0;
InitializeAstVisitor(isolate);
}
PrettyPrinter::~PrettyPrinter() {
DeleteArray(output_);
}
void PrettyPrinter::VisitBlock(Block* node) {
if (!node->ignore_completion_value()) Print("{ ");
PrintStatements(node->statements());
if (node->statements()->length() > 0) Print(" ");
if (!node->ignore_completion_value()) Print("}");
}
void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
Print("var ");
PrintLiteral(node->proxy()->name(), false);
Print(";");
}
void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
Print("function ");
PrintLiteral(node->proxy()->name(), false);
Print(" = ");
PrintFunctionLiteral(node->fun());
Print(";");
}
void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
Print("import ");
PrintLiteral(node->proxy()->name(), false);
Print(" from ");
PrintLiteral(node->module_specifier()->string(), true);
Print(";");
}
void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
Visit(node->expression());
Print(";");
}
void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
Print(";");
}
void PrettyPrinter::VisitSloppyBlockFunctionStatement(
SloppyBlockFunctionStatement* node) {
Visit(node->statement());
}
void PrettyPrinter::VisitIfStatement(IfStatement* node) {
Print("if (");
Visit(node->condition());
Print(") ");
Visit(node->then_statement());
if (node->HasElseStatement()) {
Print(" else ");
Visit(node->else_statement());
}
}
void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
Print("continue");
ZoneList<const AstRawString*>* labels = node->target()->labels();
if (labels != NULL) {
Print(" ");
DCHECK(labels->length() > 0); // guaranteed to have at least one entry
PrintLiteral(labels->at(0), false); // any label from the list is fine
}
Print(";");
}
void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
Print("break");
ZoneList<const AstRawString*>* labels = node->target()->labels();
if (labels != NULL) {
Print(" ");
DCHECK(labels->length() > 0); // guaranteed to have at least one entry
PrintLiteral(labels->at(0), false); // any label from the list is fine
}
Print(";");
}
void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
Print("return ");
Visit(node->expression());
Print(";");
}
void PrettyPrinter::VisitWithStatement(WithStatement* node) {
Print("with (");
Visit(node->expression());
Print(") ");
Visit(node->statement());
}
void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
PrintLabels(node->labels());
Print("switch (");
Visit(node->tag());
Print(") { ");
ZoneList<CaseClause*>* cases = node->cases();
for (int i = 0; i < cases->length(); i++)
Visit(cases->at(i));
Print("}");
}
void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
if (clause->is_default()) {
Print("default");
} else {
Print("case ");
Visit(clause->label());
}
Print(": ");
PrintStatements(clause->statements());
if (clause->statements()->length() > 0)
Print(" ");
}
void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
PrintLabels(node->labels());
Print("do ");
Visit(node->body());
Print(" while (");
Visit(node->cond());
Print(");");
}
void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
PrintLabels(node->labels());
Print("while (");
Visit(node->cond());
Print(") ");
Visit(node->body());
}
void PrettyPrinter::VisitForStatement(ForStatement* node) {
PrintLabels(node->labels());
Print("for (");
if (node->init() != NULL) {
Visit(node->init());
Print(" ");
} else {
Print("; ");
}
if (node->cond() != NULL) Visit(node->cond());
Print("; ");
if (node->next() != NULL) {
Visit(node->next()); // prints extra ';', unfortunately
// to fix: should use Expression for next
}
Print(") ");
Visit(node->body());
}
void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
PrintLabels(node->labels());
Print("for (");
Visit(node->each());
Print(" in ");
Visit(node->enumerable());
Print(") ");
Visit(node->body());
}
void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
// TODO(adamk): ForOf is largely desugared as part of parsing,
// so it's hard to display useful stuff here. Should likely
// either bite the bullet and display less or try harder
// to preserve more.
PrintLabels(node->labels());
// The <each> is embedded inside a do-expression by the time we get here.
Print("for (<each> of ");
if (node->assign_iterator()->IsAssignment() &&
node->assign_iterator()->AsAssignment()->value()->IsCall() &&
node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->IsProperty() &&
node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->IsProperty()) {
Visit(node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->AsProperty()
->obj());
} else {
Print("<iterable>");
}
Print(") ");
Visit(node->body());
}
void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Print("try ");
Visit(node->try_block());
Print(" catch (");
const bool quote = false;
PrintLiteral(node->variable()->name(), quote);
Print(") ");
Visit(node->catch_block());
}
void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Print("try ");
Visit(node->try_block());
Print(" finally ");
Visit(node->finally_block());
}
void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
Print("debugger ");
}
void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
Print("(");
PrintFunctionLiteral(node);
Print(")");
}
void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) {
Print("(class ");
PrintLiteral(node->constructor()->name(), false);
if (node->extends()) {
Print(" extends ");
Visit(node->extends());
}
Print(" { ");
for (int i = 0; i < node->properties()->length(); i++) {
PrintObjectLiteralProperty(node->properties()->at(i));
}
Print(" })");
}
void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
Print("(");
PrintLiteral(node->name(), false);
Print(")");
}
void PrettyPrinter::VisitDoExpression(DoExpression* node) {
Print("(do {");
PrintStatements(node->block()->statements());
Print("})");
}
void PrettyPrinter::VisitConditional(Conditional* node) {
Visit(node->condition());
Print(" ? ");
Visit(node->then_expression());
Print(" : ");
Visit(node->else_expression());
}
void PrettyPrinter::VisitLiteral(Literal* node) {
PrintLiteral(node->value(), true);
}
void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
Print(" RegExp(");
PrintLiteral(node->pattern(), false);
Print(",");
if (node->flags() & RegExp::kGlobal) Print("g");
if (node->flags() & RegExp::kIgnoreCase) Print("i");
if (node->flags() & RegExp::kMultiline) Print("m");
if (node->flags() & RegExp::kUnicode) Print("u");
if (node->flags() & RegExp::kSticky) Print("y");
Print(") ");
}
void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
Print("{ ");
for (int i = 0; i < node->properties()->length(); i++) {
if (i != 0) Print(",");
PrintObjectLiteralProperty(node->properties()->at(i));
}
Print(" }");
}
void PrettyPrinter::PrintObjectLiteralProperty(
ObjectLiteralProperty* property) {
// TODO(arv): Better printing of methods etc.
Print(" ");
Visit(property->key());
Print(": ");
Visit(property->value());
}
void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
Print("[ ");
Print(" literal_index = %d", node->literal_index());
for (int i = 0; i < node->values()->length(); i++) {
if (i != 0) Print(",");
Visit(node->values()->at(i));
}
Print(" ]");
}
void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
PrintLiteral(node->name(), false);
}
void PrettyPrinter::VisitAssignment(Assignment* node) {
Visit(node->target());
Print(" %s ", Token::String(node->op()));
Visit(node->value());
}
void PrettyPrinter::VisitYield(Yield* node) {
Print("yield ");
Visit(node->expression());
}
void PrettyPrinter::VisitThrow(Throw* node) {
Print("throw ");
Visit(node->exception());
}
void PrettyPrinter::VisitProperty(Property* node) {
Expression* key = node->key();
Literal* literal = key->AsLiteral();
if (literal != NULL && literal->value()->IsInternalizedString()) {
Print("(");
Visit(node->obj());
Print(").");
PrintLiteral(literal->value(), false);
} else {
Visit(node->obj());
Print("[");
Visit(key);
Print("]");
}
}
void PrettyPrinter::VisitCall(Call* node) {
Visit(node->expression());
PrintArguments(node->arguments());
}
void PrettyPrinter::VisitCallNew(CallNew* node) {
Print("new (");
Visit(node->expression());
Print(")");
PrintArguments(node->arguments());
}
void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
Print("%%%s\n", node->debug_name());
PrintArguments(node->arguments());
}
void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
Token::Value op = node->op();
bool needsSpace =
op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
Print("(%s%s", Token::String(op), needsSpace ? " " : "");
Visit(node->expression());
Print(")");
}
void PrettyPrinter::VisitCountOperation(CountOperation* node) {
Print("(");
if (node->is_prefix()) Print("%s", Token::String(node->op()));
Visit(node->expression());
if (node->is_postfix()) Print("%s", Token::String(node->op()));
Print(")");
}
void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
Print("(");
Visit(node->left());
Print(" %s ", Token::String(node->op()));
Visit(node->right());
Print(")");
}
void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
Print("(");
Visit(node->left());
Print(" %s ", Token::String(node->op()));
Visit(node->right());
Print(")");
}
void PrettyPrinter::VisitSpread(Spread* node) {
Print("(...");
Visit(node->expression());
Print(")");
}
void PrettyPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
Print("()");
}
void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
Print("<this-function>");
}
void PrettyPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
Print("<super-property-reference>");
}
void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) {
Print("<super-call-reference>");
}
void PrettyPrinter::VisitRewritableExpression(RewritableExpression* node) {
Visit(node->expression());
}
const char* PrettyPrinter::Print(AstNode* node) {
const char* AstPrinter::Print(AstNode* node) {
Init();
Visit(node);
return output_;
}
const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
Init();
ExpressionStatement* statement =
program->body()->at(0)->AsExpressionStatement();
Visit(statement->expression());
return output_;
}
const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
Init();
PrintStatements(program->body());
Print("\n");
return output_;
}
void PrettyPrinter::PrintOut(Isolate* isolate, AstNode* node) {
PrettyPrinter printer(isolate);
PrintF("%s\n", printer.Print(node));
}
void PrettyPrinter::Init() {
void AstPrinter::Init() {
if (size_ == 0) {
DCHECK(output_ == NULL);
const int initial_size = 256;
@ -993,8 +492,7 @@ void PrettyPrinter::Init() {
pos_ = 0;
}
void PrettyPrinter::Print(const char* format, ...) {
void AstPrinter::Print(const char* format, ...) {
for (;;) {
va_list arguments;
va_start(arguments, format);
@ -1020,17 +518,7 @@ void PrettyPrinter::Print(const char* format, ...) {
}
}
void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
if (statements == NULL) return;
for (int i = 0; i < statements->length(); i++) {
if (i != 0) Print(" ");
Visit(statements->at(i));
}
}
void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
void AstPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
if (labels != NULL) {
for (int i = 0; i < labels->length(); i++) {
PrintLiteral(labels->at(i), false);
@ -1039,18 +527,7 @@ void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
}
}
void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
Print("(");
for (int i = 0; i < arguments->length(); i++) {
if (i != 0) Print(", ");
Visit(arguments->at(i));
}
Print(")");
}
void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
void AstPrinter::PrintLiteral(Handle<Object> value, bool quote) {
Object* object = *value;
if (object->IsString()) {
String* string = String::cast(object);
@ -1088,41 +565,11 @@ void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
}
}
void PrettyPrinter::PrintLiteral(const AstRawString* value, bool quote) {
void AstPrinter::PrintLiteral(const AstRawString* value, bool quote) {
PrintLiteral(value->string(), quote);
}
void PrettyPrinter::PrintParameters(Scope* scope) {
Print("(");
for (int i = 0; i < scope->num_parameters(); i++) {
if (i > 0) Print(", ");
PrintLiteral(scope->parameter(i)->name(), false);
}
Print(")");
}
void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
for (int i = 0; i < declarations->length(); i++) {
if (i > 0) Print(" ");
Visit(declarations->at(i));
}
}
void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
Print("function ");
PrintLiteral(function->name(), false);
PrintParameters(function->scope());
Print(" { ");
PrintDeclarations(function->scope()->declarations());
PrintStatements(function->body());
Print(" }");
}
//-----------------------------------------------------------------------------
class IndentedScope BASE_EMBEDDED {
@ -1152,12 +599,14 @@ class IndentedScope BASE_EMBEDDED {
//-----------------------------------------------------------------------------
AstPrinter::AstPrinter(Isolate* isolate) : PrettyPrinter(isolate), indent_(0) {}
AstPrinter::AstPrinter(Isolate* isolate)
: output_(nullptr), size_(0), pos_(0), indent_(0) {
InitializeAstVisitor(isolate);
}
AstPrinter::~AstPrinter() {
DCHECK(indent_ == 0);
DeleteArray(output_);
}
@ -1221,7 +670,7 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
PrintDeclarations(program->scope()->declarations());
PrintStatements(program->body());
}
return Output();
return output_;
}
@ -1229,7 +678,7 @@ void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) {
AstPrinter printer(isolate);
printer.Init();
printer.Visit(node);
PrintF("%s", printer.Output());
PrintF("%s", printer.output_);
}

View File

@ -53,15 +53,15 @@ class CallPrinter : public AstVisitor {
#ifdef DEBUG
class PrettyPrinter: public AstVisitor {
// Prints the AST structure
class AstPrinter : public AstVisitor {
public:
explicit PrettyPrinter(Isolate* isolate);
virtual ~PrettyPrinter();
explicit AstPrinter(Isolate* isolate);
virtual ~AstPrinter();
// The following routines print a node into a string.
// The result string is alive as long as the PrettyPrinter is alive.
const char* Print(AstNode* node);
const char* PrintExpression(FunctionLiteral* program);
const char* PrintProgram(FunctionLiteral* program);
void PRINTF_FORMAT(2, 3) Print(const char* format, ...);
@ -74,49 +74,14 @@ class PrettyPrinter: public AstVisitor {
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
private:
Isolate* isolate_;
char* output_; // output string buffer
int size_; // output_ size
int pos_; // current printing position
protected:
void Init();
const char* Output() const { return output_; }
virtual void PrintStatements(ZoneList<Statement*>* statements);
void PrintLabels(ZoneList<const AstRawString*>* labels);
virtual void PrintArguments(ZoneList<Expression*>* arguments);
void PrintLiteral(Handle<Object> value, bool quote);
void PrintLiteral(const AstRawString* value, bool quote);
void PrintParameters(Scope* scope);
void PrintDeclarations(ZoneList<Declaration*>* declarations);
void PrintFunctionLiteral(FunctionLiteral* function);
void PrintCaseClause(CaseClause* clause);
void PrintObjectLiteralProperty(ObjectLiteralProperty* property);
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
};
// Prints the AST structure
class AstPrinter: public PrettyPrinter {
public:
explicit AstPrinter(Isolate* isolate);
virtual ~AstPrinter();
const char* PrintProgram(FunctionLiteral* program);
// Print a node to stdout.
static void PrintOut(Isolate* isolate, AstNode* node);
// Individual nodes
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
private:
friend class IndentedScope;
void Init();
void PrintLabels(ZoneList<const AstRawString*>* labels);
void PrintLiteral(const AstRawString* value, bool quote);
void PrintLiteral(Handle<Object> value, bool quote);
void PrintIndented(const char* txt);
void PrintIndentedVisit(const char* s, AstNode* node);
@ -136,6 +101,12 @@ class AstPrinter: public PrettyPrinter {
void inc_indent() { indent_++; }
void dec_indent() { indent_--; }
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
Isolate* isolate_;
char* output_; // output string buffer
int size_; // output_ size
int pos_; // current printing position
int indent_;
};

View File

@ -84,32 +84,24 @@ Comment::~Comment() {
void CodeGenerator::MakeCodePrologue(CompilationInfo* info, const char* kind) {
bool print_source = false;
bool print_ast = false;
const char* ftype;
if (info->isolate()->bootstrapper()->IsActive()) {
print_source = FLAG_print_builtin_source;
print_ast = FLAG_print_builtin_ast;
ftype = "builtin";
} else {
print_source = FLAG_print_source;
print_ast = FLAG_print_ast;
ftype = "user-defined";
}
if (FLAG_trace_codegen || print_source || print_ast) {
if (FLAG_trace_codegen || print_ast) {
base::SmartArrayPointer<char> name = info->GetDebugName();
PrintF("[generating %s code for %s function: %s]\n", kind, ftype,
name.get());
}
#ifdef DEBUG
if (info->parse_info() && print_source) {
PrintF("--- Source from AST ---\n%s\n",
PrettyPrinter(info->isolate()).PrintProgram(info->literal()));
}
if (info->parse_info() && print_ast) {
PrintF("--- AST ---\n%s\n",
AstPrinter(info->isolate()).PrintProgram(info->literal()));

View File

@ -236,13 +236,6 @@ bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
return is_sloppy(parse_info()->language_mode()) && !parse_info()->is_native();
}
#if DEBUG
void CompilationInfo::PrintAstForTesting() {
PrintF("--- Source from AST ---\n%s\n",
PrettyPrinter(isolate()).PrintProgram(literal()));
}
#endif
// ----------------------------------------------------------------------------
// Implementation of CompilationJob

View File

@ -397,10 +397,6 @@ class CompilationInfo final {
osr_expr_stack_height_ = height;
}
#if DEBUG
void PrintAstForTesting();
#endif
bool has_simple_parameters();
struct InlinedFunctionHolder {

View File

@ -967,9 +967,6 @@ DEFINE_BOOL(enable_slow_asserts, false,
#endif
// codegen-ia32.cc / codegen-arm.cc / macro-assembler-*.cc
DEFINE_BOOL(print_source, false, "pretty print source code")
DEFINE_BOOL(print_builtin_source, false,
"pretty print source code for builtins")
DEFINE_BOOL(print_ast, false, "print source AST")
DEFINE_BOOL(print_builtin_ast, false, "print source AST for builtins")
DEFINE_BOOL(trap_on_abort, false, "replace aborts by breakpoints")

View File

@ -138,7 +138,7 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
TimerEventScope<TimerEventCompileIgnition> timer(info->isolate());
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileIgnition");
if (FLAG_print_bytecode || FLAG_print_source || FLAG_print_ast) {
if (FLAG_print_bytecode || FLAG_print_ast) {
OFStream os(stdout);
base::SmartArrayPointer<char> name = info->GetDebugName();
os << "[generating bytecode for function: " << info->GetDebugName().get()
@ -147,14 +147,6 @@ bool Interpreter::MakeBytecode(CompilationInfo* info) {
}
#ifdef DEBUG
if (info->parse_info() && FLAG_print_source) {
OFStream os(stdout);
os << "--- Source from AST ---" << std::endl
<< PrettyPrinter(info->isolate()).PrintProgram(info->literal())
<< std::endl
<< std::flush;
}
if (info->parse_info() && FLAG_print_ast) {
OFStream os(stdout);
os << "--- AST ---" << std::endl