[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
//===-- ClangMove.h - Clang move -----------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H
|
|
|
|
|
|
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
|
|
#include "clang/Frontend/FrontendAction.h"
|
|
|
|
#include "clang/Tooling/Core/Replacement.h"
|
|
|
|
#include "clang/Tooling/Tooling.h"
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace move {
|
|
|
|
|
|
|
|
// FIXME: Make it support more types, e.g. function definitions.
|
|
|
|
// Currently only support moving class definition.
|
|
|
|
class ClangMoveTool : public ast_matchers::MatchFinder::MatchCallback {
|
|
|
|
public:
|
|
|
|
// Information about the declaration being moved.
|
|
|
|
struct MovedDecl {
|
2016-10-06 16:59:24 +08:00
|
|
|
// FIXME: Replace Decl with SourceRange to get rid of calculating range for
|
|
|
|
// the Decl duplicately.
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
const clang::NamedDecl *Decl = nullptr;
|
|
|
|
clang::SourceManager *SM = nullptr;
|
|
|
|
MovedDecl() = default;
|
|
|
|
MovedDecl(const clang::NamedDecl *Decl, clang::SourceManager *SM)
|
|
|
|
: Decl(Decl), SM(SM) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MoveDefinitionSpec {
|
2016-10-15 07:16:25 +08:00
|
|
|
// The list of fully qualified names, e.g. Foo, a::Foo, b::Foo.
|
|
|
|
SmallVector<std::string, 4> Names;
|
2016-10-04 17:05:31 +08:00
|
|
|
// The file path of old header, can be relative path and absolute path.
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
std::string OldHeader;
|
2016-10-04 17:05:31 +08:00
|
|
|
// The file path of old cc, can be relative path and absolute path.
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
std::string OldCC;
|
2016-10-04 17:05:31 +08:00
|
|
|
// The file path of new header, can be relative path and absolute path.
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
std::string NewHeader;
|
2016-10-04 17:05:31 +08:00
|
|
|
// The file path of new cc, can be relative path and absolute path.
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
std::string NewCC;
|
|
|
|
};
|
|
|
|
|
|
|
|
ClangMoveTool(
|
|
|
|
const MoveDefinitionSpec &MoveSpec,
|
2016-10-04 17:05:31 +08:00
|
|
|
std::map<std::string, tooling::Replacements> &FileToReplacements,
|
2016-10-06 16:29:32 +08:00
|
|
|
llvm::StringRef OriginalRunningDirectory, llvm::StringRef Style);
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
|
|
|
|
void registerMatchers(ast_matchers::MatchFinder *Finder);
|
|
|
|
|
|
|
|
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
|
|
|
|
|
|
|
void onEndOfTranslationUnit() override;
|
|
|
|
|
2016-10-04 17:05:31 +08:00
|
|
|
/// 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.
|
2016-10-04 18:40:52 +08:00
|
|
|
/// \param SM The SourceManager.
|
2016-10-04 17:05:31 +08:00
|
|
|
void addIncludes(llvm::StringRef IncludeHeader,
|
|
|
|
bool IsAngled,
|
|
|
|
llvm::StringRef SearchPath,
|
|
|
|
llvm::StringRef FileName,
|
|
|
|
const SourceManager& SM);
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
void removeClassDefinitionInOldFiles();
|
|
|
|
void moveClassDefinitionToNewFiles();
|
|
|
|
|
|
|
|
MoveDefinitionSpec Spec;
|
|
|
|
// The Key is file path, value is the replacements being applied to the file.
|
|
|
|
std::map<std::string, tooling::Replacements> &FileToReplacements;
|
|
|
|
// All declarations (the class decl being moved, forward decls) that need to
|
|
|
|
// be moved/copy to the new files, saving in an AST-visited order.
|
|
|
|
std::vector<MovedDecl> MovedDecls;
|
|
|
|
// The declarations that needs to be removed in old.cc/h.
|
|
|
|
std::vector<MovedDecl> RemovedDecls;
|
|
|
|
// The #includes in old_header.h.
|
|
|
|
std::vector<std::string> HeaderIncludes;
|
|
|
|
// The #includes in old_cc.cc.
|
|
|
|
std::vector<std::string> CCIncludes;
|
2016-10-04 17:05:31 +08:00
|
|
|
// 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;
|
2016-10-06 16:29:32 +08:00
|
|
|
// The name of a predefined code style.
|
|
|
|
std::string FallbackStyle;
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class ClangMoveAction : public clang::ASTFrontendAction {
|
|
|
|
public:
|
|
|
|
ClangMoveAction(
|
|
|
|
const ClangMoveTool::MoveDefinitionSpec &spec,
|
2016-10-04 17:05:31 +08:00
|
|
|
std::map<std::string, tooling::Replacements> &FileToReplacements,
|
2016-10-06 16:29:32 +08:00
|
|
|
llvm::StringRef OriginalRunningDirectory, llvm::StringRef FallbackStyle)
|
|
|
|
: MoveTool(spec, FileToReplacements, OriginalRunningDirectory,
|
|
|
|
FallbackStyle) {
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
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(
|
|
|
|
const ClangMoveTool::MoveDefinitionSpec &Spec,
|
2016-10-04 17:05:31 +08:00
|
|
|
std::map<std::string, tooling::Replacements> &FileToReplacements,
|
2016-10-06 16:29:32 +08:00
|
|
|
llvm::StringRef OriginalRunningDirectory, llvm::StringRef FallbackStyle)
|
2016-10-04 17:05:31 +08:00
|
|
|
: Spec(Spec), FileToReplacements(FileToReplacements),
|
2016-10-06 16:29:32 +08:00
|
|
|
OriginalRunningDirectory(OriginalRunningDirectory),
|
|
|
|
FallbackStyle(FallbackStyle) {}
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
|
|
|
|
clang::FrontendAction *create() override {
|
2016-10-06 16:29:32 +08:00
|
|
|
return new ClangMoveAction(Spec, FileToReplacements,
|
|
|
|
OriginalRunningDirectory, FallbackStyle);
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const ClangMoveTool::MoveDefinitionSpec &Spec;
|
|
|
|
std::map<std::string, tooling::Replacements> &FileToReplacements;
|
2016-10-04 17:05:31 +08:00
|
|
|
std::string OriginalRunningDirectory;
|
2016-10-06 16:29:32 +08:00
|
|
|
std::string FallbackStyle;
|
[clang-move] A prototype tool for moving class definition to new file.
Summary:
This patch introduces a new tool which moves a specific class definition
from files (.h, .cc) to new files (.h, .cc), which mostly acts like
"Extract class defintion". In the long term, this tool should be
merged in to clang-refactoring as a subtool.
clang-move not only moves class definition, but also moves all the
forward declarations, functions defined in anonymous namespace and #include
headers to new files, to make sure the new files are compliable as much
as possible.
To move `Foo` from old.[h/cc] to new.[h/cc], use:
```
clang-move -name=Foo -old_header=old.h -old_cc=old.cc -new_header=new.h
-new_cc=new.cc old.cc
```
To move `Foo` from old.h to new.h, use:
```
clang-move -name=Foo -old_header=old.h -new_header=new.h old.cc
```
Reviewers: klimek, djasper, ioeric
Subscribers: mgorny, beanz, Eugene.Zelenko, bkramer, omtcyfz, cfe-commits
Differential Revision: https://reviews.llvm.org/D24243
llvm-svn: 282070
2016-09-21 21:18:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace move
|
|
|
|
} // namespace clang
|
|
|
|
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_MOVE_CLANGMOVE_H
|