Index: include/clang/Tooling/Refactoring/RefactoringActionRule.h =================================================================== --- include/clang/Tooling/Refactoring/RefactoringActionRule.h +++ include/clang/Tooling/Refactoring/RefactoringActionRule.h @@ -11,6 +11,8 @@ #define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include namespace clang { @@ -52,6 +54,12 @@ /// requirements that use options, the options from the first requirement /// are visited before the options in the second requirement. virtual void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) = 0; + + /// Returns the name and the title of an editor command that was + /// associated with this rule. + virtual Optional> getEditorCommandInfo() { + return None; + } }; } // end namespace tooling Index: include/clang/Tooling/Refactoring/RefactoringActionRules.h =================================================================== --- include/clang/Tooling/Refactoring/RefactoringActionRules.h +++ include/clang/Tooling/Refactoring/RefactoringActionRules.h @@ -40,6 +40,15 @@ std::unique_ptr createRefactoringActionRule(const RequirementTypes &... Requirements); +/// Creates a refactoring action rule that's accessible in an editor by +/// wrapping around the given rule. +/// +/// \param Name the name of the editor command. +/// \param Title the title (display string) of the editor command. +std::unique_ptr +createEditorBinding(std::unique_ptr Rule, StringRef Name, + StringRef Title); + /// A set of refactoring action rules that should have unique initiation /// requirements. using RefactoringActionRules = Index: lib/Tooling/Refactoring/CMakeLists.txt =================================================================== --- lib/Tooling/Refactoring/CMakeLists.txt +++ lib/Tooling/Refactoring/CMakeLists.txt @@ -4,6 +4,7 @@ ASTSelection.cpp ASTSelectionRequirements.cpp AtomicChange.cpp + EditorClient.cpp Extract.cpp RefactoringActions.cpp Rename/RenamingAction.cpp Index: lib/Tooling/Refactoring/EditorClient.cpp =================================================================== --- /dev/null +++ lib/Tooling/Refactoring/EditorClient.cpp @@ -0,0 +1,52 @@ +//===--- EditorClient.cpp - Refactoring editor integration support --------===// +// +// 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/RefactoringActionRules.h" + +namespace clang { +namespace tooling { + +std::unique_ptr +createEditorBinding(std::unique_ptr Rule, StringRef Name, + StringRef Title) { + class BoundEditorRefactoringActionRule : public RefactoringActionRule { + public: + BoundEditorRefactoringActionRule( + std::unique_ptr Rule, StringRef Name, + StringRef Title) + : Rule(std::move(Rule)), Name(Name), Title(Title) {} + + void invoke(RefactoringResultConsumer &Consumer, + RefactoringRuleContext &Context) override { + Rule->invoke(Consumer, Context); + } + + bool hasSelectionRequirement() override { + return Rule->hasSelectionRequirement(); + } + + void visitRefactoringOptions(RefactoringOptionVisitor &Visitor) override { + return Rule->visitRefactoringOptions(Visitor); + } + + Optional> getEditorCommandInfo() override { + return std::make_pair(Name, Title); + } + + private: + std::unique_ptr Rule; + StringRef Name; + StringRef Title; + }; + return llvm::make_unique(std::move(Rule), + Name, Title); +} + +} // end namespace tooling +} // end namespace clang Index: lib/Tooling/Refactoring/Extract.cpp =================================================================== --- lib/Tooling/Refactoring/Extract.cpp +++ lib/Tooling/Refactoring/Extract.cpp @@ -215,9 +215,11 @@ /// action. RefactoringActionRules createActionRules() const override { RefactoringActionRules Rules; - Rules.push_back(createRefactoringActionRule( - ExtractableCodeSelectionRequirement(), - OptionRequirement())); + Rules.push_back( + createEditorBinding(createRefactoringActionRule( + ExtractableCodeSelectionRequirement(), + OptionRequirement()), + "extract-function", "Extract Function")); return Rules; } }; Index: unittests/Tooling/RefactoringActionRulesTest.cpp =================================================================== --- unittests/Tooling/RefactoringActionRulesTest.cpp +++ unittests/Tooling/RefactoringActionRulesTest.cpp @@ -10,6 +10,7 @@ #include "ReplacementTest.h" #include "RewriterTestContext.h" #include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Refactoring/RefactoringAction.h" #include "clang/Tooling/Refactoring/RefactoringActionRules.h" #include "clang/Tooling/Refactoring/RefactoringDiagnostic.h" #include "clang/Tooling/Refactoring/Rename/SymbolName.h" @@ -219,4 +220,24 @@ SourceRange(Cursor, Cursor.getLocWithOffset(strlen("test")))); } +TEST_F(RefactoringActionRulesTest, EditorCommandBinding) { + std::vector> Actions = + createRefactoringActions(); + for (auto &Action : Actions) { + if (Action->getCommand() == "extract") { + std::vector> Rules = + Action->createActiveActionRules(); + ASSERT_FALSE(Rules.empty()); + Optional> Cmd = + Rules[0]->getEditorCommandInfo(); + ASSERT_TRUE(Cmd); + EXPECT_EQ(Cmd->first, "extract-function"); + EXPECT_EQ(Cmd->second, "Extract Function"); + return; + } + } + // Never found 'extract'? + ASSERT_TRUE(false); +} + } // end anonymous namespace