summaryrefslogtreecommitdiffstats
path: root/lib/Tooling
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2017-11-08 08:56:56 +0000
committerHaojian Wu <hokein@google.com>2017-11-08 08:56:56 +0000
commiteb4212181c444e5b4cffc8bef6a6e974cd77db3c (patch)
treefa52e2c25fc426bc587240d896f7c4d66ae9b4bd /lib/Tooling
parent6fc97e7c1cf438a78d09c51f0aedac3847ace0b7 (diff)
[clang-refactor] Introduce a new rename rule for qualified symbols
Summary: Prototype of a new rename rule for renaming qualified symbol. Reviewers: arphaman, ioeric, sammccall Reviewed By: arphaman, sammccall Subscribers: jklaehn, cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D39332 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Tooling')
-rw-r--r--lib/Tooling/Refactoring/RefactoringActions.cpp20
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp56
2 files changed, 76 insertions, 0 deletions
diff --git a/lib/Tooling/Refactoring/RefactoringActions.cpp b/lib/Tooling/Refactoring/RefactoringActions.cpp
index 73a3118396..37a1639cb4 100644
--- a/lib/Tooling/Refactoring/RefactoringActions.cpp
+++ b/lib/Tooling/Refactoring/RefactoringActions.cpp
@@ -46,6 +46,22 @@ public:
}
};
+class OldQualifiedNameOption : public RequiredRefactoringOption<std::string> {
+public:
+ StringRef getName() const override { return "old-qualified-name"; }
+ StringRef getDescription() const override {
+ return "The old qualified name to be renamed";
+ }
+};
+
+class NewQualifiedNameOption : public RequiredRefactoringOption<std::string> {
+public:
+ StringRef getName() const override { return "new-qualified-name"; }
+ StringRef getDescription() const override {
+ return "The new qualified name to change the symbol to";
+ }
+};
+
class NewNameOption : public RequiredRefactoringOption<std::string> {
public:
StringRef getName() const override { return "new-name"; }
@@ -70,6 +86,10 @@ public:
RefactoringActionRules Rules;
Rules.push_back(createRefactoringActionRule<RenameOccurrences>(
SourceRangeSelectionRequirement(), OptionRequirement<NewNameOption>()));
+ // FIXME: Use NewNameOption.
+ Rules.push_back(createRefactoringActionRule<QualifiedRenameRule>(
+ OptionRequirement<OldQualifiedNameOption>(),
+ OptionRequirement<NewQualifiedNameOption>()));
return Rules;
}
};
diff --git a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
index 695fa553b4..e2d5d4c3d4 100644
--- a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -31,6 +31,8 @@
#include "clang/Tooling/Refactoring/Rename/USRLocFinder.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
#include <string>
#include <vector>
@@ -93,6 +95,60 @@ RenameOccurrences::createSourceReplacements(RefactoringRuleContext &Context) {
*Occurrences, Context.getASTContext().getSourceManager(), Name);
}
+Expected<QualifiedRenameRule>
+QualifiedRenameRule::initiate(RefactoringRuleContext &Context,
+ std::string OldQualifiedName,
+ std::string NewQualifiedName) {
+ const NamedDecl *ND =
+ getNamedDeclFor(Context.getASTContext(), OldQualifiedName);
+ if (!ND)
+ return llvm::make_error<llvm::StringError>("Could not find symbol " +
+ OldQualifiedName,
+ llvm::errc::invalid_argument);
+ return QualifiedRenameRule(ND, std::move(NewQualifiedName));
+}
+
+const RefactoringDescriptor &QualifiedRenameRule::describe() {
+ static const RefactoringDescriptor Descriptor = {
+ /*Name=*/"local-qualified-rename",
+ /*Title=*/"Qualified Rename",
+ /*Description=*/
+ R"(Finds and renames qualified symbols in code within a translation unit.
+It is used to move/rename a symbol to a new namespace/name:
+ * Supported symbols: classes, class members, functions, enums, and type alias.
+ * Renames all symbol occurrences from the old qualified name to the new
+ qualified name. All symbol references will be correctly qualified; For
+ symbol definitions, only name will be changed.
+For example, rename "A::Foo" to "B::Bar":
+ Old code:
+ namespace foo {
+ class A {};
+ }
+
+ namespace bar {
+ void f(foo::A a) {}
+ }
+
+ New code after rename:
+ namespace foo {
+ class B {};
+ }
+
+ namespace bar {
+ void f(B b) {}
+ })"
+ };
+ return Descriptor;
+}
+
+Expected<AtomicChanges>
+QualifiedRenameRule::createSourceReplacements(RefactoringRuleContext &Context) {
+ auto USRs = getUSRsForDeclaration(ND, Context.getASTContext());
+ assert(!USRs.empty());
+ return tooling::createRenameAtomicChanges(
+ USRs, NewQualifiedName, Context.getASTContext().getTranslationUnitDecl());
+}
+
Expected<std::vector<AtomicChange>>
createRenameReplacements(const SymbolOccurrences &Occurrences,
const SourceManager &SM, const SymbolName &NewName) {