1 //===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H
11 #define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H
13 #include "clang/Basic/LLVM.h"
14 #include "clang/Tooling/Refactoring/ASTSelection.h"
15 #include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
16 #include "clang/Tooling/Refactoring/RefactoringOption.h"
17 #include "clang/Tooling/Refactoring/RefactoringRuleContext.h"
18 #include "llvm/Support/Error.h"
19 #include <type_traits>
24 /// A refactoring action rule requirement determines when a refactoring action
25 /// rule can be invoked. The rule can be invoked only when all of the
26 /// requirements are satisfied.
28 /// Subclasses must implement the
29 /// 'Expected<T> evaluate(RefactoringRuleContext &) const' member function.
30 /// \c T is used to determine the return type that is passed to the
31 /// refactoring rule's constructor.
32 /// For example, the \c SourceRangeSelectionRequirement subclass defines
33 /// 'Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const'
34 /// function. When this function returns a non-error value, the resulting
35 /// source range is passed to the specific refactoring action rule
36 /// constructor (provided all other requirements are satisfied).
37 class RefactoringActionRuleRequirement {
38 // Expected<T> evaluate(RefactoringRuleContext &Context) const;
41 /// A base class for any requirement that expects some part of the source to be
42 /// selected in an editor (or the refactoring tool with the -selection option).
43 class SourceSelectionRequirement : public RefactoringActionRuleRequirement {};
45 /// A selection requirement that is satisfied when any portion of the source
47 class SourceRangeSelectionRequirement : public SourceSelectionRequirement {
49 Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const {
50 if (Context.getSelectionRange().isValid())
51 return Context.getSelectionRange();
52 return Context.createDiagnosticError(diag::err_refactor_no_selection);
56 /// An AST selection requirement is satisfied when any portion of the AST
57 /// overlaps with the selection range.
59 /// The requirement will be evaluated only once during the initiation and
60 /// search of matching refactoring action rules.
61 class ASTSelectionRequirement : public SourceRangeSelectionRequirement {
63 Expected<SelectedASTNode> evaluate(RefactoringRuleContext &Context) const;
66 /// A selection requirement that is satisfied when the selection range overlaps
67 /// with a number of neighbouring statements in the AST. The statemenst must be
68 /// contained in declaration like a function. The selection range must be a
69 /// non-empty source selection (i.e. cursors won't be accepted).
71 /// The requirement will be evaluated only once during the initiation and search
72 /// of matching refactoring action rules.
74 /// \see CodeRangeASTSelection
75 class CodeRangeASTSelectionRequirement : public ASTSelectionRequirement {
77 Expected<CodeRangeASTSelection>
78 evaluate(RefactoringRuleContext &Context) const;
81 /// A base class for any requirement that requires some refactoring options.
82 class RefactoringOptionsRequirement : public RefactoringActionRuleRequirement {
84 virtual ~RefactoringOptionsRequirement() {}
86 /// Returns the set of refactoring options that are used when evaluating this
88 virtual ArrayRef<std::shared_ptr<RefactoringOption>>
89 getRefactoringOptions() const = 0;
92 /// A requirement that evaluates to the value of the given \c OptionType when
93 /// the \c OptionType is a required option. When the \c OptionType is an
94 /// optional option, the requirement will evaluate to \c None if the option is
95 /// not specified or to an appropriate value otherwise.
96 template <typename OptionType>
97 class OptionRequirement : public RefactoringOptionsRequirement {
99 OptionRequirement() : Opt(createRefactoringOption<OptionType>()) {}
101 ArrayRef<std::shared_ptr<RefactoringOption>>
102 getRefactoringOptions() const final override {
106 Expected<typename OptionType::ValueType>
107 evaluate(RefactoringRuleContext &) const {
108 return static_cast<OptionType *>(Opt.get())->getValue();
112 /// The partially-owned option.
114 /// The ownership of the option is shared among the different requirements
115 /// because the same option can be used by multiple rules in one refactoring
117 std::shared_ptr<RefactoringOption> Opt;
120 } // end namespace tooling
121 } // end namespace clang
123 #endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_RULE_REQUIREMENTS_H