//===--- RenamingAction.cpp - Clang refactoring library -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Provides an action to rename every symbol at a point.
///
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Refactoring/RefactoringAction.h"
#include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
#include "clang/Tooling/Refactoring/RefactoringOptions.h"
#include "clang/Tooling/Refactoring/Rename/SymbolName.h"
#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "clang/Tooling/Refactoring/Rename/USRFindingAction.h"
#include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include <string>
#include <vector>

using namespace llvm;

namespace clang {
namespace tooling {

namespace {

Expected<SymbolOccurrences>
findSymbolOccurrences(const NamedDecl *ND, RefactoringRuleContext &Context) {
  std::vector<std::string> USRs =
      getUSRsForDeclaration(ND, Context.getASTContext());
  std::string PrevName = ND->getNameAsString();
  return getOccurrencesOfUSRs(USRs, PrevName,
                              Context.getASTContext().getTranslationUnitDecl());
}

} // end anonymous namespace

const RefactoringDescriptor &RenameOccurrences::describe() {
  static const RefactoringDescriptor Descriptor = {
      "local-rename",
      "Rename",
      "Finds and renames symbols in code with no indexer support",
  };
  return Descriptor;
}

Expected<RenameOccurrences>
RenameOccurrences::initiate(RefactoringRuleContext &Context,
                            SourceRange SelectionRange, std::string NewName) {
  const NamedDecl *ND =
      getNamedDeclAt(Context.getASTContext(), SelectionRange.getBegin());
  if (!ND)
    return Context.createDiagnosticError(
        SelectionRange.getBegin(), diag::err_refactor_selection_no_symbol);
  return RenameOccurrences(getCanonicalSymbolDeclaration(ND),
                           std::move(NewName));
}

Expected<AtomicChanges>
RenameOccurrences::createSourceReplacements(RefactoringRuleContext &Context) {
  Expected<SymbolOccurrences> Occurrences = findSymbolOccurrences(ND, Context);
  if (!Occurrences)
    return Occurrences.takeError();
  // FIXME: Verify that the new name is valid.
  SymbolName Name(NewName);
  return createRenameReplacements(
      *Occurrences, Context.getASTContext().getSourceManager(), Name);
}

Expected<QualifiedRenameRule>
QualifiedRenameRule::initiate(RefactoringRuleContext &Context,
                              std::string OldQualifiedName,
                              std::string NewQualifiedName) {
  const NamedDecl *ND =
      getNamedDeclFor(Context.getASTContext(), OldQualifiedName);
  if (!ND)
    return llvm::make_error<llvm::StringError>("Could not find symbol " +
                                                   OldQualifiedName,
                                               llvm::errc::invalid_argument);
  return QualifiedRenameRule(ND, std::move(NewQualifiedName));
}

const RefactoringDescriptor &QualifiedRenameRule::describe() {
  static const RefactoringDescriptor Descriptor = {
      /*Name=*/"local-qualified-rename",
      /*Title=*/"Qualified Rename",
      /*Description=*/
      R"(Finds and renames qualified symbols in code within a translation unit.
It is used to move/rename a symbol to a new namespace/name:
  * Supported symbols: classes, class members, functions, enums, and type alias.
  * Renames all symbol occurrences from the old qualified name to the new
    qualified name. All symbol references will be correctly qualified; For
    symbol definitions, only name will be changed.
For example, rename "A::Foo" to "B::Bar":
  Old code:
    namespace foo {
    class A {};
    }

    namespace bar {
    void f(foo::A a) {}
    }

  New code after rename:
    namespace foo {
    class B {};
    }

    namespace bar {
    void f(B b) {}
    })"
  };
  return Descriptor;
}

Expected<AtomicChanges>
QualifiedRenameRule::createSourceReplacements(RefactoringRuleContext &Context) {
  auto USRs = getUSRsForDeclaration(ND, Context.getASTContext());
  assert(!USRs.empty());
  return tooling::createRenameAtomicChanges(
      USRs, NewQualifiedName, Context.getASTContext().getTranslationUnitDecl());
}

Expected<std::vector<AtomicChange>>
createRenameReplacements(const SymbolOccurrences &Occurrences,
                         const SourceManager &SM, const SymbolName &NewName) {
  // FIXME: A true local rename can use just one AtomicChange.
  std::vector<AtomicChange> Changes;
  for (const auto &Occurrence : Occurrences) {
    ArrayRef<SourceRange> Ranges = Occurrence.getNameRanges();
    assert(NewName.getNamePieces().size() == Ranges.size() &&
           "Mismatching number of ranges and name pieces");
    AtomicChange Change(SM, Ranges[0].getBegin());
    for (const auto &Range : llvm::enumerate(Ranges)) {
      auto Error =
          Change.replace(SM, CharSourceRange::getCharRange(Range.value()),
                         NewName.getNamePieces()[Range.index()]);
      if (Error)
        return std::move(Error);
    }
    Changes.push_back(std::move(Change));
  }
  return std::move(Changes);
}

/// Takes each atomic change and inserts its replacements into the set of
/// replacements that belong to the appropriate file.
static void convertChangesToFileReplacements(
    ArrayRef<AtomicChange> AtomicChanges,
    std::map<std::string, tooling::Replacements> *FileToReplaces) {
  for (const auto &AtomicChange : AtomicChanges) {
    for (const auto &Replace : AtomicChange.getReplacements()) {
      llvm::Error Err = (*FileToReplaces)[Replace.getFilePath()].add(Replace);
      if (Err) {
        llvm::errs() << "Renaming failed in " << Replace.getFilePath() << "! "
                     << llvm::toString(std::move(Err)) << "\n";
      }
    }
  }
}

class RenamingASTConsumer : public ASTConsumer {
public:
  RenamingASTConsumer(
      const std::vector<std::string> &NewNames,
      const std::vector<std::string> &PrevNames,
      const std::vector<std::vector<std::string>> &USRList,
      std::map<std::string, tooling::Replacements> &FileToReplaces,
      bool PrintLocations)
      : NewNames(NewNames), PrevNames(PrevNames), USRList(USRList),
        FileToReplaces(FileToReplaces), PrintLocations(PrintLocations) {}

  void HandleTranslationUnit(ASTContext &Context) override {
    for (unsigned I = 0; I < NewNames.size(); ++I) {
      // If the previous name was not found, ignore this rename request.
      if (PrevNames[I].empty())
        continue;

      HandleOneRename(Context, NewNames[I], PrevNames[I], USRList[I]);
    }
  }

  void HandleOneRename(ASTContext &Context, const std::string &NewName,
                       const std::string &PrevName,
                       const std::vector<std::string> &USRs) {
    const SourceManager &SourceMgr = Context.getSourceManager();

    SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(
        USRs, PrevName, Context.getTranslationUnitDecl());
    if (PrintLocations) {
      for (const auto &Occurrence : Occurrences) {
        FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
                              SourceMgr);
        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)
               << ":" << FullLoc.getSpellingLineNumber() << ":"
               << FullLoc.getSpellingColumnNumber() << "\n";
      }
    }
    // FIXME: Support multi-piece names.
    // FIXME: better error handling (propagate error out).
    SymbolName NewNameRef(NewName);
    Expected<std::vector<AtomicChange>> Change =
        createRenameReplacements(Occurrences, SourceMgr, NewNameRef);
    if (!Change) {
      llvm::errs() << "Failed to create renaming replacements for '" << PrevName
                   << "'! " << llvm::toString(Change.takeError()) << "\n";
      return;
    }
    convertChangesToFileReplacements(*Change, &FileToReplaces);
  }

private:
  const std::vector<std::string> &NewNames, &PrevNames;
  const std::vector<std::vector<std::string>> &USRList;
  std::map<std::string, tooling::Replacements> &FileToReplaces;
  bool PrintLocations;
};

// A renamer to rename symbols which are identified by a give USRList to
// new name.
//
// FIXME: Merge with the above RenamingASTConsumer.
class USRSymbolRenamer : public ASTConsumer {
public:
  USRSymbolRenamer(const std::vector<std::string> &NewNames,
                   const std::vector<std::vector<std::string>> &USRList,
                   std::map<std::string, tooling::Replacements> &FileToReplaces)
      : NewNames(NewNames), USRList(USRList), FileToReplaces(FileToReplaces) {
    assert(USRList.size() == NewNames.size());
  }

  void HandleTranslationUnit(ASTContext &Context) override {
    for (unsigned I = 0; I < NewNames.size(); ++I) {
      // FIXME: Apply AtomicChanges directly once the refactoring APIs are
      // ready.
      auto AtomicChanges = tooling::createRenameAtomicChanges(
          USRList[I], NewNames[I], Context.getTranslationUnitDecl());
      convertChangesToFileReplacements(AtomicChanges, &FileToReplaces);
    }
  }

private:
  const std::vector<std::string> &NewNames;
  const std::vector<std::vector<std::string>> &USRList;
  std::map<std::string, tooling::Replacements> &FileToReplaces;
};

std::unique_ptr<ASTConsumer> RenamingAction::newASTConsumer() {
  return llvm::make_unique<RenamingASTConsumer>(NewNames, PrevNames, USRList,
                                                FileToReplaces, PrintLocations);
}

std::unique_ptr<ASTConsumer> QualifiedRenamingAction::newASTConsumer() {
  return llvm::make_unique<USRSymbolRenamer>(NewNames, USRList, FileToReplaces);
}

} // end namespace tooling
} // end namespace clang
