// 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),
      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.classKeyword,
                                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);

  visitRethrow(Rethrow node) => new Rethrow(
      node.throwToken, node.endToken);

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

  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);

  visitLiteralSymbol(LiteralSymbol node) => new LiteralSymbol(
      node.hashToken, visit(node.identifiers));

  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;
  }
}
