| Index: src/prettyprinter.cc
 | 
| ===================================================================
 | 
| --- src/prettyprinter.cc	(revision 3048)
 | 
| +++ src/prettyprinter.cc	(working copy)
 | 
| @@ -1100,7 +1100,415 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +TagScope::TagScope(JsonAstBuilder* builder, const char* name)
 | 
| +    : builder_(builder), next_(builder->tag()), has_body_(false) {
 | 
| +  if (next_ != NULL) {
 | 
| +    next_->use();
 | 
| +    builder->Print(",\n");
 | 
| +  }
 | 
| +  builder->set_tag(this);
 | 
| +  builder->PrintIndented("[");
 | 
| +  builder->Print("\"%s\"", name);
 | 
| +  builder->increase_indent(JsonAstBuilder::kTagIndentSize);
 | 
| +}
 | 
|  
 | 
| +
 | 
| +TagScope::~TagScope() {
 | 
| +  builder_->decrease_indent(JsonAstBuilder::kTagIndentSize);
 | 
| +  if (has_body_) {
 | 
| +    builder_->Print("\n");
 | 
| +    builder_->PrintIndented("]");
 | 
| +  } else {
 | 
| +    builder_->Print("]");
 | 
| +  }
 | 
| +  builder_->set_tag(next_);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +AttributesScope::AttributesScope(JsonAstBuilder* builder)
 | 
| +    : builder_(builder), attribute_count_(0) {
 | 
| +  builder->set_attributes(this);
 | 
| +  builder->tag()->use();
 | 
| +  builder->Print(",\n");
 | 
| +  builder->PrintIndented("{");
 | 
| +  builder->increase_indent(JsonAstBuilder::kAttributesIndentSize);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +AttributesScope::~AttributesScope() {
 | 
| +  builder_->decrease_indent(JsonAstBuilder::kAttributesIndentSize);
 | 
| +  if (attribute_count_ > 1) {
 | 
| +    builder_->Print("\n");
 | 
| +    builder_->PrintIndented("}");
 | 
| +  } else {
 | 
| +    builder_->Print("}");
 | 
| +  }
 | 
| +  builder_->set_attributes(NULL);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +const char* JsonAstBuilder::BuildProgram(FunctionLiteral* program) {
 | 
| +  Init();
 | 
| +  Visit(program);
 | 
| +  Print("\n");
 | 
| +  return Output();
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::AddAttributePrefix(const char* name) {
 | 
| +  if (attributes()->is_used()) {
 | 
| +    Print(",\n");
 | 
| +    PrintIndented("\"");
 | 
| +  } else {
 | 
| +    Print("\"");
 | 
| +  }
 | 
| +  Print("%s\":", name);
 | 
| +  attributes()->use();
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::AddAttribute(const char* name, Handle<String> value) {
 | 
| +  SmartPointer<char> value_string = value->ToCString();
 | 
| +  AddAttributePrefix(name);
 | 
| +  Print("\"%s\"", *value_string);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::AddAttribute(const char* name, const char* value) {
 | 
| +  AddAttributePrefix(name);
 | 
| +  Print("\"%s\"", value);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::AddAttribute(const char* name, int value) {
 | 
| +  AddAttributePrefix(name);
 | 
| +  Print("%d", value);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::AddAttribute(const char* name, bool value) {
 | 
| +  AddAttributePrefix(name);
 | 
| +  Print(value ? "true" : "false");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitBlock(Block* stmt) {
 | 
| +  TagScope tag(this, "Block");
 | 
| +  VisitStatements(stmt->statements());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
 | 
| +  TagScope tag(this, "ExpressionStatement");
 | 
| +  Visit(stmt->expression());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
 | 
| +  TagScope tag(this, "EmptyStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitIfStatement(IfStatement* stmt) {
 | 
| +  TagScope tag(this, "IfStatement");
 | 
| +  Visit(stmt->condition());
 | 
| +  Visit(stmt->then_statement());
 | 
| +  Visit(stmt->else_statement());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitContinueStatement(ContinueStatement* stmt) {
 | 
| +  TagScope tag(this, "ContinueStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitBreakStatement(BreakStatement* stmt) {
 | 
| +  TagScope tag(this, "BreakStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitReturnStatement(ReturnStatement* stmt) {
 | 
| +  TagScope tag(this, "ReturnStatement");
 | 
| +  Visit(stmt->expression());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
 | 
| +  TagScope tag(this, "WithEnterStatement");
 | 
| +  Visit(stmt->expression());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
 | 
| +  TagScope tag(this, "WithExitStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
 | 
| +  TagScope tag(this, "SwitchStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
 | 
| +  TagScope tag(this, "DoWhileStatement");
 | 
| +  Visit(stmt->body());
 | 
| +  Visit(stmt->cond());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitWhileStatement(WhileStatement* stmt) {
 | 
| +  TagScope tag(this, "WhileStatement");
 | 
| +  Visit(stmt->cond());
 | 
| +  Visit(stmt->body());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitForStatement(ForStatement* stmt) {
 | 
| +  TagScope tag(this, "ForStatement");
 | 
| +  if (stmt->init() != NULL) Visit(stmt->init());
 | 
| +  if (stmt->cond() != NULL) Visit(stmt->cond());
 | 
| +  Visit(stmt->body());
 | 
| +  if (stmt->next() != NULL) Visit(stmt->next());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitForInStatement(ForInStatement* stmt) {
 | 
| +  TagScope tag(this, "ForInStatement");
 | 
| +  Visit(stmt->each());
 | 
| +  Visit(stmt->enumerable());
 | 
| +  Visit(stmt->body());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
 | 
| +  TagScope tag(this, "TryCatchStatement");
 | 
| +  Visit(stmt->try_block());
 | 
| +  Visit(stmt->catch_var());
 | 
| +  Visit(stmt->catch_block());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
 | 
| +  TagScope tag(this, "TryFinallyStatement");
 | 
| +  Visit(stmt->try_block());
 | 
| +  Visit(stmt->finally_block());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
 | 
| +  TagScope tag(this, "DebuggerStatement");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
 | 
| +  TagScope tag(this, "FunctionLiteral");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("name", expr->name());
 | 
| +  }
 | 
| +  VisitDeclarations(expr->scope()->declarations());
 | 
| +  VisitStatements(expr->body());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitFunctionBoilerplateLiteral(
 | 
| +    FunctionBoilerplateLiteral* expr) {
 | 
| +  TagScope tag(this, "FunctionBoilerplateLiteral");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitConditional(Conditional* expr) {
 | 
| +  TagScope tag(this, "Conditional");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitSlot(Slot* expr) {
 | 
| +  TagScope tag(this, "Slot");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    switch (expr->type()) {
 | 
| +      case Slot::PARAMETER:
 | 
| +        AddAttribute("type", "PARAMETER");
 | 
| +        break;
 | 
| +      case Slot::LOCAL:
 | 
| +        AddAttribute("type", "LOCAL");
 | 
| +        break;
 | 
| +      case Slot::CONTEXT:
 | 
| +        AddAttribute("type", "CONTEXT");
 | 
| +        break;
 | 
| +      case Slot::LOOKUP:
 | 
| +        AddAttribute("type", "LOOKUP");
 | 
| +        break;
 | 
| +      case Slot::GLOBAL:
 | 
| +        AddAttribute("type", "GLOBAL");
 | 
| +        break;
 | 
| +    }
 | 
| +    AddAttribute("index", expr->index());
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitVariableProxy(VariableProxy* expr) {
 | 
| +  if (expr->var()->rewrite() == NULL) {
 | 
| +    TagScope tag(this, "VariableProxy");
 | 
| +    {
 | 
| +      AttributesScope attributes(this);
 | 
| +      AddAttribute("name", expr->name());
 | 
| +      AddAttribute("mode", Variable::Mode2String(expr->var()->mode()));
 | 
| +    }
 | 
| +  } else {
 | 
| +    Visit(expr->var()->rewrite());
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitLiteral(Literal* expr) {
 | 
| +  TagScope tag(this, "Literal");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    Handle<Object> handle = expr->handle();
 | 
| +    if (handle->IsString()) {
 | 
| +      AddAttribute("handle", Handle<String>(String::cast(*handle)));
 | 
| +    } else if (handle->IsSmi()) {
 | 
| +      AddAttribute("handle", Smi::cast(*handle)->value());
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
 | 
| +  TagScope tag(this, "RegExpLiteral");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
 | 
| +  TagScope tag(this, "ObjectLiteral");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
 | 
| +  TagScope tag(this, "ArrayLiteral");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
 | 
| +  TagScope tag(this, "CatchExtensionObject");
 | 
| +  Visit(expr->key());
 | 
| +  Visit(expr->value());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitAssignment(Assignment* expr) {
 | 
| +  TagScope tag(this, "Assignment");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("op", Token::Name(expr->op()));
 | 
| +  }
 | 
| +  Visit(expr->target());
 | 
| +  Visit(expr->value());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitThrow(Throw* expr) {
 | 
| +  TagScope tag(this, "Throw");
 | 
| +  Visit(expr->exception());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitProperty(Property* expr) {
 | 
| +  TagScope tag(this, "Property");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("type", expr->is_synthetic() ? "SYNTHETIC" : "NORMAL");
 | 
| +  }
 | 
| +  Visit(expr->obj());
 | 
| +  Visit(expr->key());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCall(Call* expr) {
 | 
| +  TagScope tag(this, "Call");
 | 
| +  Visit(expr->expression());
 | 
| +  VisitExpressions(expr->arguments());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCallNew(CallNew* expr) {
 | 
| +  TagScope tag(this, "CallNew");
 | 
| +  Visit(expr->expression());
 | 
| +  VisitExpressions(expr->arguments());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCallRuntime(CallRuntime* expr) {
 | 
| +  TagScope tag(this, "CallRuntime");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("name", expr->name());
 | 
| +  }
 | 
| +  VisitExpressions(expr->arguments());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitUnaryOperation(UnaryOperation* expr) {
 | 
| +  TagScope tag(this, "UnaryOperation");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("op", Token::Name(expr->op()));
 | 
| +  }
 | 
| +  Visit(expr->expression());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCountOperation(CountOperation* expr) {
 | 
| +  TagScope tag(this, "CountOperation");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("is_prefix", expr->is_prefix());
 | 
| +    AddAttribute("op", Token::Name(expr->op()));
 | 
| +  }
 | 
| +  Visit(expr->expression());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitBinaryOperation(BinaryOperation* expr) {
 | 
| +  TagScope tag(this, "BinaryOperation");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("op", Token::Name(expr->op()));
 | 
| +  }
 | 
| +  Visit(expr->left());
 | 
| +  Visit(expr->right());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitCompareOperation(CompareOperation* expr) {
 | 
| +  TagScope tag(this, "CompareOperation");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("op", Token::Name(expr->op()));
 | 
| +  }
 | 
| +  Visit(expr->left());
 | 
| +  Visit(expr->right());
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitThisFunction(ThisFunction* expr) {
 | 
| +  TagScope tag(this, "ThisFunction");
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void JsonAstBuilder::VisitDeclaration(Declaration* decl) {
 | 
| +  TagScope tag(this, "Declaration");
 | 
| +  {
 | 
| +    AttributesScope attributes(this);
 | 
| +    AddAttribute("mode", Variable::Mode2String(decl->mode()));
 | 
| +  }
 | 
| +  Visit(decl->proxy());
 | 
| +  if (decl->fun() != NULL) Visit(decl->fun());
 | 
| +}
 | 
| +
 | 
| +
 | 
|  #endif  // DEBUG
 | 
|  
 | 
|  } }  // namespace v8::internal
 | 
| 
 |