//===--- Rename.cpp - Symbol-rename refactorings -----------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "refactor/Rename.h"
#include "AST.h"
#include "ClangdUnit.h"
#include "Logger.h"
#include "SourceCode.h"
#include "index/SymbolCollector.h"
#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "clang/Tooling/Refactoring/Rename/USRFindingAction.h"
#include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"

namespace clang {
namespace clangd {
namespace {

llvm::Optional<std::string> filePath(const SymbolLocation &Loc,
                                     llvm::StringRef HintFilePath) {
  if (!Loc)
    return None;
  auto Uri = URI::parse(Loc.FileURI);
  if (!Uri) {
    elog("Could not parse URI {0}: {1}", Loc.FileURI, Uri.takeError());
    return None;
  }
  auto U = URIForFile::fromURI(*Uri, HintFilePath);
  if (!U) {
    elog("Could not resolve URI {0}: {1}", Loc.FileURI, U.takeError());
    return None;
  }
  return U->file().str();
}

// Query the index to find some other files where the Decl is referenced.
llvm::Optional<std::string> getOtherRefFile(const Decl &D, StringRef MainFile,
                                            const SymbolIndex &Index) {
  RefsRequest Req;
  // We limit the number of results, this is a correctness/performance
  // tradeoff. We expect the number of symbol references in the current file
  // is smaller than the limit.
  Req.Limit = 100;
  if (auto ID = getSymbolID(&D))
    Req.IDs.insert(*ID);
  llvm::Optional<std::string> OtherFile;
  Index.refs(Req, [&](const Ref &R) {
    if (OtherFile)
      return;
    if (auto RefFilePath = filePath(R.Location, /*HintFilePath=*/MainFile)) {
      if (*RefFilePath != MainFile)
        OtherFile = *RefFilePath;
    }
  });
  return OtherFile;
}

enum ReasonToReject {
  NoSymbolFound,
  NoIndexProvided,
  NonIndexable,
  UsedOutsideFile,
  UnsupportedSymbol,
};

// Check the symbol Decl is renameable (per the index) within the file.
llvm::Optional<ReasonToReject> renamableWithinFile(const Decl &RenameDecl,
                                                   StringRef MainFile,
                                                   const SymbolIndex *Index) {
  if (llvm::isa<NamespaceDecl>(&RenameDecl))
    return ReasonToReject::UnsupportedSymbol;
  auto &ASTCtx = RenameDecl.getASTContext();
  const auto &SM = ASTCtx.getSourceManager();
  bool MainFileIsHeader = ASTCtx.getLangOpts().IsHeaderFile;
  bool DeclaredInMainFile = isInsideMainFile(RenameDecl.getBeginLoc(), SM);

  // If the symbol is declared in the main file (which is not a header), we
  // rename it.
  if (DeclaredInMainFile && !MainFileIsHeader)
    return None;

  // Below are cases where the symbol is declared in the header.
  // If the symbol is function-local, we rename it.
  if (RenameDecl.getParentFunctionOrMethod())
    return None;

  if (!Index)
    return ReasonToReject::NoIndexProvided;

  bool IsIndexable = isa<NamedDecl>(RenameDecl) &&
                     SymbolCollector::shouldCollectSymbol(
                         cast<NamedDecl>(RenameDecl), ASTCtx, {}, false);
  // If the symbol is not indexable, we disallow rename.
  if (!IsIndexable)
    return ReasonToReject::NonIndexable;
  auto OtherFile = getOtherRefFile(RenameDecl, MainFile, *Index);
  // If the symbol is indexable and has no refs from other files in the index,
  // we rename it.
  if (!OtherFile)
    return None;
  // If the symbol is indexable and has refs from other files in the index,
  // we disallow rename.
  return ReasonToReject::UsedOutsideFile;
}

llvm::Error makeError(ReasonToReject Reason) {
  auto Message = [](ReasonToReject Reason) {
    switch (Reason) {
    case NoSymbolFound:
      return "there is no symbol at the given location";
    case NoIndexProvided:
      return "symbol may be used in other files (no index available)";
    case UsedOutsideFile:
      return "the symbol is used outside main file";
    case NonIndexable:
      return "symbol may be used in other files (not eligible for indexing)";
    case UnsupportedSymbol:
      return "symbol is not a supported kind (e.g. namespace, macro)";
    }
    llvm_unreachable("unhandled reason kind");
  };
  return llvm::make_error<llvm::StringError>(
      llvm::formatv("Cannot rename symbol: {0}", Message(Reason)),
      llvm::inconvertibleErrorCode());
}

// Return all rename occurrences in the main file.
tooling::SymbolOccurrences
findOccurrencesWithinFile(ParsedAST &AST, const NamedDecl *RenameDecl) {
  const NamedDecl *CanonicalRenameDecl =
      tooling::getCanonicalSymbolDeclaration(RenameDecl);
  assert(CanonicalRenameDecl && "RenameDecl must be not null");
  std::vector<std::string> RenameUSRs =
      tooling::getUSRsForDeclaration(CanonicalRenameDecl, AST.getASTContext());
  std::string OldName = CanonicalRenameDecl->getNameAsString();
  tooling::SymbolOccurrences Result;
  for (Decl *TopLevelDecl : AST.getLocalTopLevelDecls()) {
    tooling::SymbolOccurrences RenameInDecl =
        tooling::getOccurrencesOfUSRs(RenameUSRs, OldName, TopLevelDecl);
    Result.insert(Result.end(), std::make_move_iterator(RenameInDecl.begin()),
                  std::make_move_iterator(RenameInDecl.end()));
  }
  return Result;
}

} // namespace

llvm::Expected<tooling::Replacements>
renameWithinFile(ParsedAST &AST, llvm::StringRef File, Position Pos,
                 llvm::StringRef NewName, const SymbolIndex *Index) {
  SourceLocation SourceLocationBeg = getBeginningOfIdentifier(
      Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
  // FIXME: renaming macros is not supported yet, the macro-handling code should
  // be moved to rename tooling library.
  if (locateMacroAt(SourceLocationBeg, AST.getPreprocessor()))
    return makeError(UnsupportedSymbol);

  const auto *RenameDecl =
      tooling::getNamedDeclAt(AST.getASTContext(), SourceLocationBeg);
  if (!RenameDecl)
    return makeError(NoSymbolFound);

  if (auto Reject =
          renamableWithinFile(*RenameDecl->getCanonicalDecl(), File, Index))
    return makeError(*Reject);

  // Rename sometimes returns duplicate edits (which is a bug). A side-effect of
  // adding them to a single Replacements object is these are deduplicated.
  tooling::Replacements FilteredChanges;
  for (const tooling::SymbolOccurrence &Rename :
       findOccurrencesWithinFile(AST, RenameDecl)) {
    // Currently, we only support normal rename (one range) for C/C++.
    // FIXME: support multiple-range rename for objective-c methods.
    if (Rename.getNameRanges().size() > 1)
      continue;
    // We shouldn't have conflicting replacements. If there are conflicts, it
    // means that we have bugs either in clangd or in Rename library, therefore
    // we refuse to perform the rename.
    if (auto Err = FilteredChanges.add(tooling::Replacement(
            AST.getASTContext().getSourceManager(),
            CharSourceRange::getCharRange(Rename.getNameRanges()[0]), NewName)))
      return std::move(Err);
  }
  return FilteredChanges;
}

} // namespace clangd
} // namespace clang
