// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/ast_printer.h"

#include "vm/handles.h"
#include "vm/log.h"
#include "vm/object.h"
#include "vm/os.h"
#include "vm/parser.h"

#if !defined(PRODUCT)

namespace dart {

AstPrinter::AstPrinter(bool log)
    : indent_(0),
      logger_(log ? Log::Current() : Log::NoOpLog()) { }


AstPrinter::~AstPrinter() { }


void AstPrinter::VisitGenericAstNode(AstNode* node) {
  logger_->Print("(%s ", node->Name());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitSequenceNode(SequenceNode* node) {
  indent_++;
  LocalScope* scope = node->scope();
  logger_->Print("(%s (scope \"%p\"", node->Name(), scope);
  if (scope != NULL) {
    logger_->Print(" (%s-%s) loop %d",
              scope->begin_token_pos().ToCString(),
              scope->end_token_pos().ToCString(),
              scope->loop_level());
    if (scope->HasContextLevel()) {
      logger_->Print(" context %d captures %d",
                scope->context_level(),
                scope->num_context_variables());
    } else {
      ASSERT(scope->num_context_variables() == 0);
    }
  }
  logger_->Print(")");
  for (int i = 0; i < node->length(); ++i) {
    logger_->Print("\n");
    for (intptr_t p = 0; p < indent_; p++) {
      logger_->Print("  ");
    }
    node->NodeAt(i)->Visit(this);
  }
  logger_->Print(")");
  indent_--;
}


void AstPrinter::VisitCloneContextNode(CloneContextNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitArgumentListNode(ArgumentListNode* arguments) {
  VisitGenericAstNode(arguments);
}


void AstPrinter::VisitReturnNode(ReturnNode* node) {
  const char* kind;
  switch (node->return_type()) {
    case ReturnNode::kContinuation:
      kind = "continuation ";
      break;
    case ReturnNode::kContinuationTarget:
      kind = "continuation-target ";
      break;
    case ReturnNode::kRegular:
      kind = "";
      break;
    default:
      kind = "";
      UNREACHABLE();
  }
  logger_->Print("(%s %s", node->Name(), kind);
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitGenericLocalNode(AstNode* node,
                                       const LocalVariable& var) {
  logger_->Print("(%s %s%s \"%s\"",
            node->Name(),
            var.is_final() ? "final " : "",
            String::Handle(var.type().Name()).ToCString(),
            var.name().ToCString());
  if (var.HasIndex()) {
    if (var.is_captured()) {
      logger_->Print(" (context %d %d)",
                     var.owner()->context_level(),
                     var.index());
    } else {
      logger_->Print(" (stack %d)", var.index());
    }
  }
  logger_->Print(" ");
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitLoadLocalNode(LoadLocalNode* node) {
  VisitGenericLocalNode(node, node->local());
}


void AstPrinter::VisitStoreLocalNode(StoreLocalNode* node) {
  VisitGenericLocalNode(node, node->local());
}


void AstPrinter::VisitGenericFieldNode(AstNode* node, const Field& field) {
  logger_->Print("(%s %s%s \"%s\" ",
            node->Name(),
            field.is_final() ? "final " : "",
            String::Handle(AbstractType::Handle(field.type()).Name()).
                ToCString(),
            String::Handle(field.name()).ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) {
  VisitGenericFieldNode(node, node->field());
}


void AstPrinter::VisitStoreInstanceFieldNode(StoreInstanceFieldNode* node) {
  VisitGenericFieldNode(node, Field::ZoneHandle(node->field().Original()));
}


void AstPrinter::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
  VisitGenericFieldNode(node, node->field());
}


void AstPrinter::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
  VisitGenericFieldNode(node, node->field());
}


void AstPrinter::VisitLetNode(LetNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitArrayNode(ArrayNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitStringInterpolateNode(StringInterpolateNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitLiteralNode(LiteralNode* node) {
  const Instance& literal = node->literal();
  logger_->Print("(%s \"%s\")", node->Name(), literal.ToCString());
}


void AstPrinter::VisitTypeNode(TypeNode* node) {
  const AbstractType& type = node->type();
  logger_->Print("(%s \"%s\")",
            node->Name(),
            String::Handle(type.Name()).ToCString());
}


void AstPrinter::VisitAssignableNode(AssignableNode* node) {
  const AbstractType& type = node->type();
  const String& dst_name = node->dst_name();
  logger_->Print("(%s (type \"%s\") (of \"%s\") ",
            node->Name(),
            String::Handle(type.Name()).ToCString(),
            dst_name.ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitAwaitNode(AwaitNode* node) {
  logger_->Print("(*****%s***** (scope \"%p\") ", node->Name(), node->scope());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitAwaitMarkerNode(AwaitMarkerNode* node) {
  logger_->Print("(%s (async_scope \"%p\" await_scope \"%p\"))",
            node->Name(),
            node->async_scope(),
            node->await_scope());
}


void AstPrinter::VisitPrimaryNode(PrimaryNode* node) {
  logger_->Print("(*****%s***** \"%s\")",
            node->Name(),
            node->primary().ToCString());
}


void AstPrinter::VisitComparisonNode(ComparisonNode* node) {
  logger_->Print("(%s %s ", node->Name(), node->TokenName());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitBinaryOpNode(BinaryOpNode* node) {
  logger_->Print("(%s %s ", node->Name(), node->TokenName());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitUnaryOpNode(UnaryOpNode* node) {
  logger_->Print("(%s %s ", node->Name(), node->TokenName());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitConditionalExprNode(ConditionalExprNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitIfNode(IfNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitCaseNode(CaseNode* node) {
  logger_->Print("(%s (", node->Name());
  for (int i = 0; i < node->case_expressions()->length(); i++) {
    node->case_expressions()->NodeAt(i)->Visit(this);
  }
  if (node->contains_default()) {
    logger_->Print(" default");
  }
  logger_->Print(")");
  node->statements()->Visit(this);
  logger_->Print(")");
}


void AstPrinter::VisitSwitchNode(SwitchNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitWhileNode(WhileNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitForNode(ForNode* node) {
  // Complicated because the condition is optional and so we clearly want to
  // indicate the subparts.
  logger_->Print("(%s (init ", node->Name());
  node->initializer()->Visit(this);
  if (node->condition() != NULL) {
    logger_->Print(") (cond ");
    node->condition()->Visit(this);
  }
  logger_->Print(") (update ");
  node->increment()->Visit(this);
  logger_->Print(") ");
  node->body()->Visit(this);
  logger_->Print(")");
}


void AstPrinter::VisitDoWhileNode(DoWhileNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitJumpNode(JumpNode* node) {
  logger_->Print("(%s %s %s (scope \"%p\"))",
            node->Name(),
            node->TokenName(),
            node->label()->name().ToCString(),
            node->label()->owner());
}


void AstPrinter::VisitInstanceCallNode(InstanceCallNode* node) {
  logger_->Print("(%s \"%s\" ",
            node->Name(),
            node->function_name().ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitStaticCallNode(StaticCallNode* node) {
  const char* function_fullname = node->function().ToFullyQualifiedCString();
  logger_->Print("(%s \"%s\" ", node->Name(), function_fullname);
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitClosureNode(ClosureNode* node) {
  const char* function_fullname = node->function().ToFullyQualifiedCString();
  logger_->Print("(%s \"%s\")", node->Name(), function_fullname);
}


void AstPrinter::VisitClosureCallNode(ClosureCallNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitConstructorCallNode(ConstructorCallNode* node) {
  const char* kind = node->constructor().IsFactory() ? "factory " : "";
  const char* constructor_name = node->constructor().ToFullyQualifiedCString();
  logger_->Print("(%s %s \"%s\" ", node->Name(), kind, constructor_name);
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitInstanceGetterNode(InstanceGetterNode* node) {
  logger_->Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitInstanceSetterNode(InstanceSetterNode* node) {
  logger_->Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
  logger_->Print("(%s \"%s\")",
            node->Name(),
            String::Handle(node->field().name()).ToCString());
}


void AstPrinter::VisitStaticGetterNode(StaticGetterNode* node) {
  String& class_name = String::Handle(node->cls().Name());
  logger_->Print("(%s \"%s.%s\")",
            node->Name(),
            class_name.ToCString(),
            node->field_name().ToCString());
}


void AstPrinter::VisitStaticSetterNode(StaticSetterNode* node) {
  String& class_name = String::Handle(node->cls().Name());
  logger_->Print("(%s \"%s.%s\" ",
            node->Name(),
            class_name.ToCString(),
            node->field_name().ToCString());
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitLoadIndexedNode(LoadIndexedNode* node) {
  logger_->Print("(%s%s ", node->Name(), node->IsSuperLoad() ? " super" : "");
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitStoreIndexedNode(StoreIndexedNode* node) {
  logger_->Print("(%s%s ", node->Name(), node->IsSuperStore() ? " super" : "");
  node->VisitChildren(this);
  logger_->Print(")");
}


void AstPrinter::VisitNativeBodyNode(NativeBodyNode* node) {
  logger_->Print("(%s \"%s\" (%" Pd " args))",
            node->Name(),
            node->native_c_function_name().ToCString(),
            NativeArguments::ParameterCountForResolution(node->function()));
}


void AstPrinter::VisitCatchClauseNode(CatchClauseNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitTryCatchNode(TryCatchNode* node) {
  logger_->Print("(%s ", node->Name());
  node->try_block()->Visit(this);
  node->catch_block()->Visit(this);
  if (node->finally_block() != NULL) {
    logger_->Print("(finally ");
    node->finally_block()->Visit(this);
    logger_->Print(")");
  }
  logger_->Print(")");
}


void AstPrinter::VisitThrowNode(ThrowNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::VisitStopNode(StopNode* node) {
  logger_->Print("(%s %s)", node->Name(), node->message());
}


void AstPrinter::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
  VisitGenericAstNode(node);
}


void AstPrinter::PrintNode(AstNode* node) {
  ASSERT(node != NULL);
  AstPrinter ast_printer;
  node->Visit(&ast_printer);
  logger_->Print("\n");
}


void AstPrinter::IndentN(int count) {
  for (int i = 0; i < count; i++) {
    logger_->Print(" ");
  }
}


void AstPrinter::PrintLocalScopeVariable(const LocalScope* scope,
                                         LocalVariable* var,
                                         int indent) {
  ASSERT(scope != NULL);
  ASSERT(var != NULL);
  IndentN(indent);
  logger_->Print("(%s%s '%s'",
            var->is_final() ? "final " : "",
            String::Handle(var->type().Name()).ToCString(),
            var->name().ToCString());
  if (var->owner() != scope) {
    logger_->Print(" alias");
  }
  if (var->HasIndex()) {
    logger_->Print(" @%d", var->index());
    if (var->is_captured()) {
      logger_->Print(" ctx %d", var->owner()->context_level());
    }
  } else if (var->owner()->function_level() != 0) {
    logger_->Print(" lev %d", var->owner()->function_level());
  }
  logger_->Print(" valid %s-%s)\n",
            var->token_pos().ToCString(),
            scope->end_token_pos().ToCString());
}


void AstPrinter::PrintLocalScope(const LocalScope* scope,
                                 int start_index,
                                 int indent) {
  ASSERT(scope != NULL);
  for (int i = start_index; i < scope->num_variables(); i++) {
    LocalVariable* var = scope->VariableAt(i);
    PrintLocalScopeVariable(scope, var, indent);
  }
  const LocalScope* child = scope->child();
  while (child != NULL) {
    IndentN(indent);
    logger_->Print("{scope %p ", child);
    if (child->HasContextLevel()) {
      logger_->Print("ctx %d numctxvar %d ",
                child->context_level(),
                child->num_context_variables());
    }
    logger_->Print("llev %d\n", child->loop_level());
    PrintLocalScope(child, 0, indent + kScopeIndent);
    IndentN(indent);
    logger_->Print("}\n");
    child = child->sibling();
  }
}


void AstPrinter::PrintFunctionScope(const ParsedFunction& parsed_function) {
  HANDLESCOPE(parsed_function.thread());
  const Function& function = parsed_function.function();
  SequenceNode* node_sequence = parsed_function.node_sequence();
  ASSERT(node_sequence != NULL);
  const LocalScope* scope = node_sequence->scope();
  ASSERT(scope != NULL);
  const char* function_name = function.ToFullyQualifiedCString();
  logger_->Print("Scope for function '%s'\n{scope %p ", function_name, scope);
  if (scope->HasContextLevel()) {
    logger_->Print("ctx %d numctxvar %d ",
              scope->context_level(),
              scope->num_context_variables());
  }
  logger_->Print("llev %d\n", scope->loop_level());
  const int num_fixed_params = function.num_fixed_parameters();
  const int num_params = num_fixed_params + function.NumOptionalParameters();
  // Parameters must be listed first and must all appear in the top scope.
  ASSERT(num_params <= scope->num_variables());
  int pos = 0;  // Current position of variable in scope.
  int indent = kScopeIndent;
  while (pos < num_params) {
    LocalVariable* param = scope->VariableAt(pos);
    ASSERT(param->owner() == scope);  // No aliases should precede parameters.
    IndentN(indent);
    logger_->Print("(param %s%s '%s'",
              param->is_final() ? "final " : "",
              String::Handle(param->type().Name()).ToCString(),
              param->name().ToCString());
    // Print the default value if the parameter is optional.
    if (pos >= num_fixed_params && pos < num_params) {
      const Instance& default_parameter_value =
          parsed_function.DefaultParameterValueAt(pos - num_fixed_params);
      logger_->Print(" =%s", default_parameter_value.ToCString());
    }
    if (param->HasIndex()) {
      logger_->Print(" @%d", param->index());
      if (param->is_captured()) {
        logger_->Print(" ctx %d", param->owner()->context_level());
      }
    }
    logger_->Print(" valid %s-%s)\n",
              param->token_pos().ToCString(),
              scope->end_token_pos().ToCString());
    pos++;
  }
  // Visit remaining non-parameter variables and children scopes.
  PrintLocalScope(scope, pos, indent);
  logger_->Print("}\n");
}


void AstPrinter::PrintFunctionNodes(const ParsedFunction& parsed_function) {
  HANDLESCOPE(parsed_function.thread());
  SequenceNode* node_sequence = parsed_function.node_sequence();
  ASSERT(node_sequence != NULL);
  const char* function_name =
      parsed_function.function().ToFullyQualifiedCString();
  logger_->Print("Ast for function '%s' {\n", function_name);
  node_sequence->Visit(this);
  logger_->Print("}\n");
}

}  // namespace dart

#endif  // !defined(PRODUCT)
