// Copyright (c) 2012, 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.

part of dart_backend;

class CloningVisitor implements Visitor<Node> {
  final TreeElements originalTreeElements;
  final TreeElementMapping cloneTreeElements;

  CloningVisitor(originalTreeElements)
      : cloneTreeElements =
            new TreeElementMapping(originalTreeElements.currentElement),
        this.originalTreeElements = originalTreeElements;

  visit(Node node) {
    if (node == null) return null;
    final clone = node.accept(this);

    final originalElement = originalTreeElements[node];
    if (originalElement != null) cloneTreeElements[clone] = originalElement;

    final originalType = originalTreeElements.getType(node);
    if (originalType != null) cloneTreeElements.setType(clone, originalType);
    return clone;
  }

  visitBlock(Block node) => new Block(visit(node.statements));

  visitBreakStatement(BreakStatement node) => new BreakStatement(
      visit(node.target), node.keywordToken, node.semicolonToken);

  visitCascade(Cascade node) => new Cascade(visit(node.expression));

  visitCascadeReceiver(CascadeReceiver node) => new CascadeReceiver(
      visit(node.expression), node.cascadeOperator);

  visitCaseMatch(CaseMatch node) => new CaseMatch(
      node.caseKeyword, visit(node.expression), node.colonToken);

  visitCatchBlock(CatchBlock node) => new CatchBlock(
      visit(node.type), visit(node.formals), visit(node.block),
      node.onKeyword, node.catchKeyword);

  visitClassNode(ClassNode node) => new ClassNode(
      visit(node.modifiers), visit(node.name), visit(node.typeParameters),
      visit(node.superclass), visit(node.interfaces), visit(node.defaultClause),
      node.beginToken, node.extendsKeyword, visit(node.body), node.endToken);

  visitConditional(Conditional node) => new Conditional(
      visit(node.condition), visit(node.thenExpression),
      visit(node.elseExpression), node.questionToken, node.colonToken);

  visitContinueStatement(ContinueStatement node) => new ContinueStatement(
      visit(node.target), node.keywordToken, node.semicolonToken);

  visitDoWhile(DoWhile node) => new DoWhile(
      visit(node.body), visit(node.condition),
      node.doKeyword, node.whileKeyword, node.endToken);

  visitEmptyStatement(EmptyStatement node) => new EmptyStatement(
      node.semicolonToken);

  visitExpressionStatement(ExpressionStatement node) => new ExpressionStatement(
      visit(node.expression), node.endToken);

  visitFor(For node) => new For(
      visit(node.initializer), visit(node.conditionStatement),
      visit(node.update), visit(node.body), node.forToken);

  visitForIn(ForIn node) => new ForIn(
      visit(node.declaredIdentifier), visit(node.expression), visit(node.body),
      node.forToken, node.inToken);

  visitFunctionDeclaration(FunctionDeclaration node) => new FunctionDeclaration(
      visit(node.function));

  rewriteFunctionExpression(FunctionExpression node, Statement body) =>
      new FunctionExpression(
          visit(node.name), visit(node.parameters), body,
          visit(node.returnType), visit(node.modifiers),
          visit(node.initializers), node.getOrSet);

  visitFunctionExpression(FunctionExpression node) =>
      rewriteFunctionExpression(node, visit(node.body));

  visitIdentifier(Identifier node) => new Identifier(node.token);

  visitIf(If node) => new If(
      visit(node.condition), visit(node.thenPart), visit(node.elsePart),
      node.ifToken, node.elseToken);

  visitLabel(Label node) => new Label(visit(node.identifier), node.colonToken);

  visitLabeledStatement(LabeledStatement node) => new LabeledStatement(
      visit(node.labels), visit(node.statement));

  visitLiteralBool(LiteralBool node) => new LiteralBool(
      node.token, node.handler);

  visitLiteralDouble(LiteralDouble node) => new LiteralDouble(
      node.token, node.handler);

  visitLiteralInt(LiteralInt node) => new LiteralInt(node.token, node.handler);

  visitLiteralList(LiteralList node) => new LiteralList(
      visit(node.typeArguments), visit(node.elements), node.constKeyword);

  visitLiteralMap(LiteralMap node) => new LiteralMap(
      visit(node.typeArguments), visit(node.entries), node.constKeyword);

  visitLiteralMapEntry(LiteralMapEntry node) => new LiteralMapEntry(
      visit(node.key), node.colonToken, visit(node.value));

  visitLiteralNull(LiteralNull node) => new LiteralNull(node.token);

  visitLiteralString(LiteralString node) => new LiteralString(
      node.token, node.dartString);

  visitMixinApplication(MixinApplication node) => new MixinApplication(
      visit(node.superclass), visit(node.mixins));

  visitNamedMixinApplication(NamedMixinApplication node) =>
      new NamedMixinApplication(visit(node.name),
                                visit(node.typeParameters),
                                visit(node.modifiers),
                                visit(node.mixinApplication),
                                visit(node.interfaces),
                                node.typedefKeyword,
                                node.endToken);

  visitModifiers(Modifiers node) => new Modifiers(visit(node.nodes));

  visitNamedArgument(NamedArgument node) => new NamedArgument(
      visit(node.name), node.colonToken, visit(node.expression));

  visitNewExpression(NewExpression node) => new NewExpression(
      node.newToken, visit(node.send));

  rewriteNodeList(NodeList node, Link link) =>
      new NodeList(node.beginToken, link, node.endToken, node.delimiter);

  visitNodeList(NodeList node) {
    // Special case for classes which exist in hierarchy, but not
    // in the visitor.
    if (node is Prefix) {
      return node.nodes.isEmpty ?
          new Prefix() : new Prefix.singleton(visit(node.nodes.head));
    }
    if (node is Postfix) {
      return node.nodes.isEmpty ?
          new Postfix() : new Postfix.singleton(visit(node.nodes.head));
    }
    LinkBuilder<Node> builder = new LinkBuilder<Node>();
    for (Node n in node.nodes) {
      builder.addLast(visit(n));
    }
    return rewriteNodeList(node, builder.toLink());
  }

  visitOperator(Operator node) => new Operator(node.token);

  visitParenthesizedExpression(ParenthesizedExpression node) =>
      new ParenthesizedExpression(visit(node.expression), node.beginToken);

  visitReturn(Return node) => new Return(
      node.beginToken, node.endToken, visit(node.expression));

  visitScriptTag(ScriptTag node) => new ScriptTag(
      visit(node.tag), visit(node.argument),
      visit(node.prefixIdentifier), visit(node.prefix),
      node.beginToken, node.endToken);

  visitSend(Send node) => new Send(
      visit(node.receiver), visit(node.selector), visit(node.argumentsNode));

  visitSendSet(SendSet node) => new SendSet(
      visit(node.receiver), visit(node.selector),
      visit(node.assignmentOperator), visit(node.argumentsNode));

  visitStringInterpolation(StringInterpolation node) =>
      new StringInterpolation(visit(node.string), visit(node.parts));

  visitStringInterpolationPart(StringInterpolationPart node) =>
      new StringInterpolationPart(visit(node.expression), visit(node.string));

  visitStringJuxtaposition(StringJuxtaposition node) =>
      new StringJuxtaposition(visit(node.first), visit(node.second));

  visitSwitchCase(SwitchCase node) => new SwitchCase(
      visit(node.labelsAndCases), node.defaultKeyword, visit(node.statements),
      node.startToken);

  visitSwitchStatement(SwitchStatement node) => new SwitchStatement(
      visit(node.parenthesizedExpression), visit(node.cases),
      node.switchKeyword);

  visitThrow(Throw node) => new Throw(
      visit(node.expression), node.throwToken, node.endToken);

  visitTryStatement(TryStatement node) => new TryStatement(
      visit(node.tryBlock), visit(node.catchBlocks), visit(node.finallyBlock),
      node.tryKeyword, node.finallyKeyword);

  visitTypeAnnotation(TypeAnnotation node) => new TypeAnnotation(
      visit(node.typeName), visit(node.typeArguments));

  visitTypedef(Typedef node) => new Typedef(
      visit(node.returnType), visit(node.name), visit(node.typeParameters),
      visit(node.formals), node.typedefKeyword, node.endToken);

  visitTypeVariable(TypeVariable node) => new TypeVariable(
      visit(node.name), visit(node.bound));

  visitVariableDefinitions(VariableDefinitions node) => new VariableDefinitions(
      visit(node.type), visit(node.modifiers), visit(node.definitions));

  visitWhile(While node) => new While(
      visit(node.condition), visit(node.body), node.whileKeyword);

  Node visitNode(Node node) {
    unimplemented('visitNode', node: node);
  }

  Node visitCombinator(Combinator node) {
    unimplemented('visitNode', node: node);
  }

  Node visitExport(Export node) {
    unimplemented('visitNode', node: node);
  }

  Node visitExpression(Expression node) {
    unimplemented('visitNode', node: node);
  }

  Node visitGotoStatement(GotoStatement node) {
    unimplemented('visitNode', node: node);
  }

  Node visitImport(Import node) {
    unimplemented('visitNode', node: node);
  }

  Node visitLibraryDependency(LibraryTag node) {
    unimplemented('visitNode', node: node);
  }

  Node visitLibraryName(LibraryName node) {
    unimplemented('visitNode', node: node);
  }

  Node visitLibraryTag(LibraryTag node) {
    unimplemented('visitNode', node: node);
  }

  Node visitLiteral(Literal node) {
    unimplemented('visitNode', node: node);
  }

  Node visitLoop(Loop node) {
    unimplemented('visitNode', node: node);
  }

  Node visitPart(Part node) {
    unimplemented('visitNode', node: node);
  }

  Node visitPartOf(PartOf node) {
    unimplemented('visitNode', node: node);
  }

  Node visitPostfix(Postfix node) {
    unimplemented('visitNode', node: node);
  }

  Node visitPrefix(Prefix node) {
    unimplemented('visitNode', node: node);
  }

  Node visitStatement(Statement node) {
    unimplemented('visitNode', node: node);
  }

  Node visitStringNode(StringNode node) {
    unimplemented('visitNode', node: node);
  }

  unimplemented(String message, {Node node}) {
    throw message;
  }
}
