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