diff options
Diffstat (limited to 'clang/lib/Tooling/Refactoring')
5 files changed, 112 insertions, 0 deletions
diff --git a/clang/lib/Tooling/Refactoring/AtomicChange.cpp b/clang/lib/Tooling/Refactoring/AtomicChange.cpp index 082bf5996df..e4cc6a5617b 100644 --- a/clang/lib/Tooling/Refactoring/AtomicChange.cpp +++ b/clang/lib/Tooling/Refactoring/AtomicChange.cpp @@ -215,6 +215,15 @@ AtomicChange::AtomicChange(std::string Key, std::string FilePath, RemovedHeaders(std::move(RemovedHeaders)), Replaces(std::move(Replaces)) { } +bool AtomicChange::operator==(const AtomicChange &Other) const { + if (Key != Other.Key || FilePath != Other.FilePath || Error != Other.Error) + return false; + if (!(Replaces == Other.Replaces)) + return false; + // FXIME: Compare header insertions/removals. + return true; +} + std::string AtomicChange::toYAMLString() { std::string YamlContent; llvm::raw_string_ostream YamlContentStream(YamlContent); diff --git a/clang/lib/Tooling/Refactoring/CMakeLists.txt b/clang/lib/Tooling/Refactoring/CMakeLists.txt index b0b66f16f6d..ff9cd1ff9e2 100644 --- a/clang/lib/Tooling/Refactoring/CMakeLists.txt +++ b/clang/lib/Tooling/Refactoring/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS Support) add_clang_library(clangToolingRefactor ASTSelection.cpp AtomicChange.cpp + RefactoringActions.cpp Rename/RenamingAction.cpp Rename/SymbolOccurrences.cpp Rename/USRFinder.cpp diff --git a/clang/lib/Tooling/Refactoring/RefactoringActions.cpp b/clang/lib/Tooling/Refactoring/RefactoringActions.cpp new file mode 100644 index 00000000000..25f055b7270 --- /dev/null +++ b/clang/lib/Tooling/Refactoring/RefactoringActions.cpp @@ -0,0 +1,35 @@ +//===--- RefactoringActions.cpp - Constructs refactoring actions ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/Refactoring/RefactoringAction.h" + +namespace clang { +namespace tooling { + +// Forward declare the individual create*Action functions. +#define REFACTORING_ACTION(Name) \ + std::unique_ptr<RefactoringAction> create##Name##Action(); +#include "clang/Tooling/Refactoring/RefactoringActionRegistry.def" + +std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions() { + std::vector<std::unique_ptr<RefactoringAction>> Actions; + +#define REFACTORING_ACTION(Name) Actions.push_back(create##Name##Action()); +#include "clang/Tooling/Refactoring/RefactoringActionRegistry.def" + + return Actions; +} + +RefactoringActionRules RefactoringAction::createActiveActionRules() { + // FIXME: Filter out rules that are not supported by a particular client. + return createActionRules(); +} + +} // end namespace tooling +} // end namespace clang 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, diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp index 43287acb95e..0c746bbbcb7 100644 --- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp @@ -154,6 +154,12 @@ private: }; } // namespace +std::vector<std::string> getUSRsForDeclaration(const NamedDecl *ND, + ASTContext &Context) { + AdditionalUSRFinder Finder(ND, Context); + return Finder.Find(); +} + class NamedDeclFindingConsumer : public ASTConsumer { public: NamedDeclFindingConsumer(ArrayRef<unsigned> SymbolOffsets, |