hokein updated this revision to Diff 120575.
hokein added a comment.

Add an assert for non-empty USRs.


https://reviews.llvm.org/D39332

Files:
  include/clang/Tooling/Refactoring/RefactoringActionRegistry.def
  lib/Tooling/Refactoring/Rename/RenamingAction.cpp
  test/Refactor/LocalQualifiedRename/QualifiedRename.cpp
  tools/clang-refactor/ClangRefactor.cpp

Index: tools/clang-refactor/ClangRefactor.cpp
===================================================================
--- tools/clang-refactor/ClangRefactor.cpp
+++ tools/clang-refactor/ClangRefactor.cpp
@@ -500,8 +500,6 @@
           auto InvokeRule = [&](RefactoringResultConsumer &Consumer) {
             logInvocation(Subcommand, Context);
             for (RefactoringActionRule *Rule : MatchingRules) {
-              if (!Rule->hasSelectionRequirement())
-                continue;
               Rule->invoke(Consumer, Context);
               return;
             }
@@ -529,6 +527,8 @@
               HasFailed = true;
             ActiveConsumer.endTU();
             return;
+          } else {
+            InvokeRule(ActiveConsumer);
           }
           // FIXME (Alex L): Implement non-selection based invocation path.
           ActiveConsumer.endTU();
Index: test/Refactor/LocalQualifiedRename/QualifiedRename.cpp
===================================================================
--- /dev/null
+++ test/Refactor/LocalQualifiedRename/QualifiedRename.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-refactor local-qualified-rename -old-qualified-name="foo::A" -new-name="bar::B" %s -- -std=c++11 2>&1 | grep -v CHECK | FileCheck %s
+
+namespace foo {
+class A {};
+}
+// CHECK: namespace foo {
+// CHECK-NEXT: class B {};
+// CHECK-NEXT: }
+
+namespace bar {
+void f(foo::A* a) {
+  foo::A b;
+}
+// CHECK: void f(B* a) {
+// CHECK-NEXT:   B b;
+// CHECK-NEXT: }
+}
+
+void f(foo::A* a) {
+  foo::A b;
+}
+// CHECK: void f(bar::B* a) {
+// CHECK-NEXT:   bar::B b;
+// CHECK-NEXT: }
Index: lib/Tooling/Refactoring/Rename/RenamingAction.cpp
===================================================================
--- lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ 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>
 
@@ -114,12 +116,73 @@
   }
 };
 
+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 QualifiedRenameOccurrences : public SourceChangeRefactoringRule {
+public:
+  QualifiedRenameOccurrences(std::string OldQualifiedName,
+                             std::string NewQualifiedName)
+      : OldQualifiedName(std::move(OldQualifiedName)),
+        NewQualifiedName(std::move(NewQualifiedName)) {}
+
+  Expected<AtomicChanges>
+  createSourceReplacements(RefactoringRuleContext &Context) override {
+    const NamedDecl *ND =
+        getNamedDeclFor(Context.getASTContext(), OldQualifiedName);
+    if (!ND) {
+      return llvm::make_error<llvm::StringError>("Could not find symbol " +
+                                                     OldQualifiedName,
+                                                 llvm::errc::invalid_argument);
+    }
+    auto USRs = getUSRsForDeclaration(ND, Context.getASTContext());
+    assert(!USRs.empty());
+    return tooling::createRenameAtomicChanges(
+        USRs, NewQualifiedName,
+        Context.getASTContext().getTranslationUnitDecl());
+  }
+
+private:
+  std::string OldQualifiedName;
+  std::string NewQualifiedName;
+};
+
+class LocalQualifiedRename final : public RefactoringAction {
+public:
+  StringRef getCommand() const override {
+    return "local-qualified-rename";
+  }
+
+  StringRef getDescription() const override {
+    return "Finds and rename qualified symbol in code with no indexer support";
+  }
+
+  /// Returns a set of refactoring actions rules that are defined by this
+  /// action.
+  RefactoringActionRules createActionRules() const override {
+    RefactoringActionRules Rules;
+    Rules.push_back(createRefactoringActionRule<QualifiedRenameOccurrences>(
+        OptionRequirement<OldQualifiedNameOption>(),
+        OptionRequirement<NewNameOption>()));
+    return Rules;
+  }
+};
+
 } // end anonymous namespace
 
 std::unique_ptr<RefactoringAction> createLocalRenameAction() {
   return llvm::make_unique<LocalRename>();
 }
 
+std::unique_ptr<RefactoringAction> createLocalQualifiedRenameAction() {
+  return llvm::make_unique<LocalQualifiedRename>();
+}
+
 Expected<std::vector<AtomicChange>>
 createRenameReplacements(const SymbolOccurrences &Occurrences,
                          const SourceManager &SM, const SymbolName &NewName) {
Index: include/clang/Tooling/Refactoring/RefactoringActionRegistry.def
===================================================================
--- include/clang/Tooling/Refactoring/RefactoringActionRegistry.def
+++ include/clang/Tooling/Refactoring/RefactoringActionRegistry.def
@@ -3,6 +3,7 @@
 #endif
 
 REFACTORING_ACTION(LocalRename)
+REFACTORING_ACTION(LocalQualifiedRename)
 REFACTORING_ACTION(Extract)
 
 #undef REFACTORING_ACTION
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to