//===-- Move.h - Clang move  ----------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H

#include "HelperDeclRefGraph.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <map>
#include <memory>
#include <string>
#include <vector>

namespace clang {
namespace move {

// A reporter which collects and reports declarations in old header.
class DeclarationReporter {
public:
  DeclarationReporter() = default;
  ~DeclarationReporter() = default;

  void reportDeclaration(llvm::StringRef DeclarationName, llvm::StringRef Type,
                         bool Templated) {
    DeclarationList.emplace_back(DeclarationName, Type, Templated);
  };

  struct Declaration {
    Declaration(llvm::StringRef QName, llvm::StringRef Kind, bool Templated)
        : QualifiedName(QName), Kind(Kind), Templated(Templated) {}

    friend bool operator==(const Declaration &LHS, const Declaration &RHS) {
      return std::tie(LHS.QualifiedName, LHS.Kind, LHS.Templated) ==
             std::tie(RHS.QualifiedName, RHS.Kind, RHS.Templated);
    }
    std::string QualifiedName; // E.g. A::B::Foo.
    std::string Kind;          // E.g. Function, Class
    bool Templated = false;    // Whether the declaration is templated.
  };

  const std::vector<Declaration> getDeclarationList() const {
    return DeclarationList;
  }

private:
  std::vector<Declaration> DeclarationList;
};

// Specify declarations being moved. It contains all information of the moved
// declarations.
struct MoveDefinitionSpec {
  // The list of fully qualified names, e.g. Foo, a::Foo, b::Foo.
  SmallVector<std::string, 4> Names;
  // The file path of old header, can be relative path and absolute path.
  std::string OldHeader;
  // The file path of old cc, can be relative path and absolute path.
  std::string OldCC;
  // The file path of new header, can be relative path and absolute path.
  std::string NewHeader;
  // The file path of new cc, can be relative path and absolute path.
  std::string NewCC;
  // Whether old.h depends on new.h. If true, #include "new.h" will be added
  // in old.h.
  bool OldDependOnNew = false;
  // Whether new.h depends on old.h. If true, #include "old.h" will be added
  // in new.h.
  bool NewDependOnOld = false;
};

// A Context which contains extra options which are used in ClangMoveTool.
struct ClangMoveContext {
  MoveDefinitionSpec Spec;
  // The Key is file path, value is the replacements being applied to the file.
  std::map<std::string, tooling::Replacements> &FileToReplacements;
  // The original working directory where the local clang-move binary runs.
  //
  // clang-move will change its current working directory to the build
  // directory when analyzing the source file. We save the original working
  // directory in order to get the absolute file path for the fields in Spec.
  std::string OriginalRunningDirectory;
  // The name of a predefined code style.
  std::string FallbackStyle;
  // Whether dump all declarations in old header.
  bool DumpDeclarations;
};

// This tool is used to move class/function definitions from the given source
// files (old.h/cc) to new files (new.h/cc).
// The goal of this tool is to make the new/old files as compilable as possible.
//
// When moving a symbol,all used helper declarations (e.g. static
// functions/variables definitions in global/named namespace,
// functions/variables/classes definitions in anonymous namespace) used by the
// moved symbol in old.cc are moved to the new.cc. In addition, all
// using-declarations in old.cc are also moved to new.cc; forward class
// declarations in old.h are also moved to new.h.
//
// The remaining helper declarations which are unused by non-moved symbols in
// old.cc will be removed.
//
// Note: When all declarations in old header are being moved, all code in
// old.h/cc will be moved, which means old.h/cc are empty. This ignores symbols
// that are not supported (e.g. typedef and enum) so that we always move old
// files to new files when all symbols produced from dump_decls are moved.
class ClangMoveTool : public ast_matchers::MatchFinder::MatchCallback {
public:
  ClangMoveTool(ClangMoveContext *const Context,
                DeclarationReporter *const Reporter);

  void registerMatchers(ast_matchers::MatchFinder *Finder);

  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;

  void onEndOfTranslationUnit() override;

  /// Add #includes from old.h/cc files.
  ///
  /// \param IncludeHeader The name of the file being included, as written in
  /// the source code.
  /// \param IsAngled Whether the file name was enclosed in angle brackets.
  /// \param SearchPath The search path which was used to find the IncludeHeader
  /// in the file system. It can be a relative path or an absolute path.
  /// \param FileName The name of file where the IncludeHeader comes from.
  /// \param IncludeFilenameRange The source range for the written file name in
  /// #include (i.e. "old.h" for #include "old.h") in old.cc.
  /// \param SM The SourceManager.
  void addIncludes(llvm::StringRef IncludeHeader, bool IsAngled,
                   llvm::StringRef SearchPath, llvm::StringRef FileName,
                   clang::CharSourceRange IncludeFilenameRange,
                   const SourceManager &SM);

  std::vector<const NamedDecl *> &getMovedDecls() { return MovedDecls; }

  /// Add declarations being removed from old.h/cc. For each declarations, the
  /// method also records the mapping relationship between the corresponding
  /// FilePath and its FileID.
  void addRemovedDecl(const NamedDecl *Decl);

  llvm::SmallPtrSet<const NamedDecl *, 8> &getUnremovedDeclsInOldHeader() {
    return UnremovedDeclsInOldHeader;
  }

private:
  // Make the Path absolute using the OrignalRunningDirectory if the Path is not
  // an absolute path. An empty Path will result in an empty string.
  std::string makeAbsolutePath(StringRef Path);

  void removeDeclsInOldFiles();
  void moveDeclsToNewFiles();
  void moveAll(SourceManager& SM, StringRef OldFile, StringRef NewFile);

  // Stores all MatchCallbacks created by this tool.
  std::vector<std::unique_ptr<ast_matchers::MatchFinder::MatchCallback>>
      MatchCallbacks;
  // Store all potential declarations (decls being moved, forward decls) that
  // might need to move to new.h/cc. It includes all helper declarations
  // (include unused ones) by default. The unused ones will be filtered out in
  // the last stage. Saving in an AST-visited order.
  std::vector<const NamedDecl *> MovedDecls;
  // The declarations that needs to be removed in old.cc/h.
  std::vector<const NamedDecl *> RemovedDecls;
  // The #includes in old_header.h.
  std::vector<std::string> HeaderIncludes;
  // The #includes in old_cc.cc.
  std::vector<std::string> CCIncludes;
  // Records all helper declarations (function/variable/class definitions in
  // anonymous namespaces, static function/variable definitions in global/named
  // namespaces) in old.cc. saving in an AST-visited order.
  std::vector<const NamedDecl *> HelperDeclarations;
  // The unmoved named declarations in old header.
  llvm::SmallPtrSet<const NamedDecl*, 8> UnremovedDeclsInOldHeader;
  /// The source range for the written file name in #include (i.e. "old.h" for
  /// #include "old.h") in old.cc,  including the enclosing quotes or angle
  /// brackets.
  clang::CharSourceRange OldHeaderIncludeRangeInCC;
  /// The source range for the written file name in #include (i.e. "old.h" for
  /// #include "old.h") in old.h,  including the enclosing quotes or angle
  /// brackets.
  clang::CharSourceRange OldHeaderIncludeRangeInHeader;
  /// Mapping from FilePath to FileID, which can be used in post processes like
  /// cleanup around replacements.
  llvm::StringMap<FileID> FilePathToFileID;
  /// A context contains all running options. It is not owned.
  ClangMoveContext *const Context;
  /// A reporter to report all declarations from old header. It is not owned.
  DeclarationReporter *const Reporter;
  /// Builder for helper declarations reference graph.
  HelperDeclRGBuilder RGBuilder;
};

class ClangMoveAction : public clang::ASTFrontendAction {
public:
  ClangMoveAction(ClangMoveContext *const Context,
                  DeclarationReporter *const Reporter)
      : MoveTool(Context, Reporter) {
    MoveTool.registerMatchers(&MatchFinder);
  }

  ~ClangMoveAction() override = default;

  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(clang::CompilerInstance &Compiler,
                    llvm::StringRef InFile) override;

private:
  ast_matchers::MatchFinder MatchFinder;
  ClangMoveTool MoveTool;
};

class ClangMoveActionFactory : public tooling::FrontendActionFactory {
public:
  ClangMoveActionFactory(ClangMoveContext *const Context,
                         DeclarationReporter *const Reporter = nullptr)
      : Context(Context), Reporter(Reporter) {}

  std::unique_ptr<clang::FrontendAction> create() override {
    return std::make_unique<ClangMoveAction>(Context, Reporter);
  }

private:
  // Not owned.
  ClangMoveContext *const Context;
  DeclarationReporter *const Reporter;
};

} // namespace move
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H
