arphaman created this revision.

This patch adds a second kind of refactoring action rule that produces symbol 
occurrences. It will be used by the updated `clang-refactor` patch at 
https://reviews.llvm.org/D36574.


Repository:
  rL LLVM

https://reviews.llvm.org/D37210

Files:
  include/clang/Tooling/Refactoring/RefactoringActionRule.h
  include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
  unittests/Tooling/RefactoringActionRulesTest.cpp

Index: unittests/Tooling/RefactoringActionRulesTest.cpp
===================================================================
--- unittests/Tooling/RefactoringActionRulesTest.cpp
+++ unittests/Tooling/RefactoringActionRulesTest.cpp
@@ -11,6 +11,7 @@
 #include "RewriterTestContext.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Refactoring/RefactoringActionRules.h"
+#include "clang/Tooling/Refactoring/Rename/SymbolName.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/Errc.h"
 #include "gtest/gtest.h"
@@ -162,4 +163,41 @@
   EXPECT_EQ(Message, "bad selection");
 }
 
+Expected<Optional<SymbolOccurrences>>
+findOccurrences(const std::unique_ptr<RefactoringActionRule> &Rule,
+                RefactoringRuleContext &Context) {
+  return cast<FindSymbolOccurrencesRefactoringRule>(*Rule)
+      .findSymbolOccurrences(Context);
+}
+
+TEST_F(RefactoringActionRulesTest, ReturnSymbolOccurrences) {
+  auto Rule = createRefactoringRule(
+      [](selection::SourceSelectionRange Selection)
+          -> Expected<SymbolOccurrences> {
+        SymbolOccurrences Occurrences;
+        Occurrences.push_back(SymbolOccurrence(
+            SymbolName("test"), SymbolOccurrence::MatchingSymbol,
+            Selection.getRange().getBegin()));
+        return Occurrences;
+      },
+      requiredSelection(
+          selection::identity<selection::SourceSelectionRange>()));
+
+  RefactoringRuleContext RefContext(Context.Sources);
+  SourceLocation Cursor =
+      Context.Sources.getLocForStartOfFile(Context.Sources.getMainFileID());
+  RefContext.setSelectionRange({Cursor, Cursor});
+  Expected<Optional<SymbolOccurrences>> Result =
+      findOccurrences(Rule, RefContext);
+
+  ASSERT_FALSE(!Result);
+  ASSERT_FALSE(!*Result);
+  SymbolOccurrences Occurrences = std::move(**Result);
+  EXPECT_EQ(Occurrences.size(), 1u);
+  EXPECT_EQ(Occurrences[0].getKind(), SymbolOccurrence::MatchingSymbol);
+  EXPECT_EQ(Occurrences[0].getNameRanges().size(), 1u);
+  EXPECT_EQ(Occurrences[0].getNameRanges()[0],
+            SourceRange(Cursor, Cursor.getLocWithOffset(strlen("test"))));
+}
+
 } // end anonymous namespace
Index: include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
===================================================================
--- include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
+++ include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
@@ -26,18 +26,26 @@
 /// 'perform' method from the specific refactoring method.
 template <typename T> struct SpecificRefactoringRuleAdapter {};
 
-template <>
-class SpecificRefactoringRuleAdapter<AtomicChanges>
-    : public SourceChangeRefactoringRule {
-public:
-  virtual Expected<Optional<AtomicChanges>>
-  perform(RefactoringRuleContext &Context) = 0;
-
-  Expected<Optional<AtomicChanges>>
-  createSourceReplacements(RefactoringRuleContext &Context) final override {
-    return perform(Context);
-  }
-};
+#define CLANG_REFACTOR_DEFINE_RULE_ADAPTER(ResultType, RuleType, OverrideName) \
+  template <>                                                                  \
+  class SpecificRefactoringRuleAdapter<ResultType> : public RuleType {         \
+  public:                                                                      \
+    virtual Expected<Optional<ResultType>>                                     \
+    perform(RefactoringRuleContext &Context) = 0;                              \
+                                                                               \
+    Expected<Optional<ResultType>>                                             \
+    OverrideName(RefactoringRuleContext &Context) final override {             \
+      return perform(Context);                                                 \
+    }                                                                          \
+  };
+
+CLANG_REFACTOR_DEFINE_RULE_ADAPTER(AtomicChanges, SourceChangeRefactoringRule,
+                                   createSourceReplacements)
+CLANG_REFACTOR_DEFINE_RULE_ADAPTER(SymbolOccurrences,
+                                   FindSymbolOccurrencesRefactoringRule,
+                                   findSymbolOccurrences)
+
+#undef CLANG_REFACTOR_DEFINE_RULE_ADAPTER
 
 /// A specialized refactoring action rule that calls the stored function once
 /// all the of the requirements are fullfilled. The values produced during the
Index: include/clang/Tooling/Refactoring/RefactoringActionRule.h
===================================================================
--- include/clang/Tooling/Refactoring/RefactoringActionRule.h
+++ include/clang/Tooling/Refactoring/RefactoringActionRule.h
@@ -12,6 +12,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/Rename/SymbolOccurrences.h"
 #include "llvm/Support/Error.h"
 #include <vector>
 
@@ -23,7 +24,10 @@
 /// A common refactoring action rule interface.
 class RefactoringActionRule {
 public:
-  enum RuleKind { SourceChangeRefactoringRuleKind };
+  enum RuleKind {
+    SourceChangeRefactoringRuleKind,
+    FindSymbolOccurrencesRefactoringRuleKind
+  };
 
   RuleKind getRuleKind() const { return Kind; }
 
@@ -59,6 +63,30 @@
   }
 };
 
+/// An interactive refactoring action that produces symbol occurrences. The
+/// consumer is able to let the user decide which occurrences should be used
+/// and how the replacements shall be constructed when performing actions
+/// like rename.
+class FindSymbolOccurrencesRefactoringRule : public RefactoringActionRule {
+public:
+  FindSymbolOccurrencesRefactoringRule()
+      : RefactoringActionRule(FindSymbolOccurrencesRefactoringRuleKind) {}
+
+  /// Initiates and performs an interactive refactoring action that searches
+  /// for symbol occurrences.
+  ///
+  /// The specific rule must return an llvm::Error with a DiagnosticError
+  /// payload or None when the refactoring action couldn't be initiated/
+  /// performed, or \c SymbolOccurrences when the action was performed
+  /// successfully.
+  virtual Expected<Optional<SymbolOccurrences>>
+  findSymbolOccurrences(RefactoringRuleContext &Context) = 0;
+
+  static bool classof(const RefactoringActionRule *Rule) {
+    return Rule->getRuleKind() == FindSymbolOccurrencesRefactoringRuleKind;
+  }
+};
+
 /// A set of refactoring action rules that should have unique initiation
 /// requirements.
 using RefactoringActionRules =
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to