diff options
author | Alex Lorenz <arphaman@gmail.com> | 2017-09-14 10:06:52 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2017-09-14 10:06:52 +0000 |
commit | b54ef6a2a4c84293f64f90ea344b129eabbb0cd1 (patch) | |
tree | beea03e3a80eaf8bc338ebb66b247f3363562975 /clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp | |
parent | d7b3add7c4a25a558794bf1c1ca30f865b8c6dd7 (diff) | |
download | bcm5719-llvm-b54ef6a2a4c84293f64f90ea344b129eabbb0cd1.tar.gz bcm5719-llvm-b54ef6a2a4c84293f64f90ea344b129eabbb0cd1.zip |
[refactor] add clang-refactor tool with initial testing support and
local-rename action
This commit introduces the clang-refactor tool alongside the local-rename action
which uses the existing renaming engine used by clang-rename. The tool
doesn't actually perform the source transformations yet, it just provides
testing support. This commit also moves only one test from clang-rename over to
test/Refactor. I will continue to move the other tests throughout
development of clang-refactor.
The following options are supported by clang-refactor:
-v: use verbose output
-selection: The source range that corresponds to the portion of the source
that's selected (currently only special command test:<file> is supported).
Please note that a follow-up commit will migrate clang-refactor to
libTooling's common option parser, so clang-refactor will be able to use
the common interface with compilation database and options like -p, -extra-arg,
etc.
The testing support provided by clang-refactor is described below:
When -selection=test:<file> is given, clang-refactor will parse the selection
commands from that file. The selection commands are grouped and the specified
refactoring action invoked by the tool. Each command in a group is expected to
produce an identical result. The precise syntax for the selection commands is
described in a comment in TestSupport.h.
Differential Revision: https://reviews.llvm.org/D36574
llvm-svn: 313244
Diffstat (limited to 'clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp')
-rw-r--r-- | clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp index 0aed67f5324..384e4660154 100644 --- a/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/RenamingAction.cpp @@ -22,6 +22,10 @@ #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/RefactoringActionRules.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" @@ -33,6 +37,63 @@ using namespace llvm; namespace clang { namespace tooling { +namespace { + +class LocalRename : public RefactoringAction { +public: + StringRef getCommand() const override { return "local-rename"; } + + StringRef getDescription() const override { + return "Finds and renames symbols in code with no indexer support"; + } + + /// Returns a set of refactoring actions rules that are defined by this + /// action. + RefactoringActionRules createActionRules() const override { + using namespace refactoring_action_rules; + RefactoringActionRules Rules; + Rules.push_back(createRefactoringRule( + renameOccurrences, requiredSelection(SymbolSelectionRequirement()))); + return Rules; + } + +private: + static Expected<AtomicChanges> + renameOccurrences(const RefactoringRuleContext &Context, + const NamedDecl *ND) { + std::vector<std::string> USRs = + getUSRsForDeclaration(ND, Context.getASTContext()); + std::string PrevName = ND->getNameAsString(); + auto Occurrences = getOccurrencesOfUSRs( + USRs, PrevName, Context.getASTContext().getTranslationUnitDecl()); + + // FIXME: This is a temporary workaround that's needed until the refactoring + // options are implemented. + StringRef NewName = "Bar"; + return createRenameReplacements( + Occurrences, Context.getASTContext().getSourceManager(), NewName); + } + + class SymbolSelectionRequirement : public selection::Requirement { + public: + Expected<Optional<const NamedDecl *>> + evaluateSelection(const RefactoringRuleContext &Context, + selection::SourceSelectionRange Selection) const { + const NamedDecl *ND = getNamedDeclAt(Context.getASTContext(), + Selection.getRange().getBegin()); + if (!ND) + return None; + return getCanonicalSymbolDeclaration(ND); + } + }; +}; + +} // end anonymous namespace + +std::unique_ptr<RefactoringAction> createLocalRenameAction() { + return llvm::make_unique<LocalRename>(); +} + Expected<std::vector<AtomicChange>> createRenameReplacements(const SymbolOccurrences &Occurrences, const SourceManager &SM, |