RefactoringActionRuleRequirements.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H
  14. #define LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H
  15. #include "clang/Basic/LLVM.h"
  16. #include "clang/Tooling/Refactoring/ASTSelection.h"
  17. #include "clang/Tooling/Refactoring/RefactoringDiagnostic.h"
  18. #include "clang/Tooling/Refactoring/RefactoringOption.h"
  19. #include "clang/Tooling/Refactoring/RefactoringRuleContext.h"
  20. #include "llvm/Support/Error.h"
  21. #include <type_traits>
  22. namespace clang {
  23. namespace tooling {
  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.
  27. ///
  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;
  39. };
  40. /// A base class for any requirement that expects some part of the source to be
  41. /// selected in an editor (or the refactoring tool with the -selection option).
  42. class SourceSelectionRequirement : public RefactoringActionRuleRequirement {};
  43. /// A selection requirement that is satisfied when any portion of the source
  44. /// text is selected.
  45. class SourceRangeSelectionRequirement : public SourceSelectionRequirement {
  46. public:
  47. Expected<SourceRange> evaluate(RefactoringRuleContext &Context) const {
  48. if (Context.getSelectionRange().isValid())
  49. return Context.getSelectionRange();
  50. return Context.createDiagnosticError(diag::err_refactor_no_selection);
  51. }
  52. };
  53. /// An AST selection requirement is satisfied when any portion of the AST
  54. /// overlaps with the selection range.
  55. ///
  56. /// The requirement will be evaluated only once during the initiation and
  57. /// search of matching refactoring action rules.
  58. class ASTSelectionRequirement : public SourceRangeSelectionRequirement {
  59. public:
  60. Expected<SelectedASTNode> evaluate(RefactoringRuleContext &Context) const;
  61. };
  62. /// A selection requirement that is satisfied when the selection range overlaps
  63. /// with a number of neighbouring statements in the AST. The statemenst must be
  64. /// contained in declaration like a function. The selection range must be a
  65. /// non-empty source selection (i.e. cursors won't be accepted).
  66. ///
  67. /// The requirement will be evaluated only once during the initiation and search
  68. /// of matching refactoring action rules.
  69. ///
  70. /// \see CodeRangeASTSelection
  71. class CodeRangeASTSelectionRequirement : public ASTSelectionRequirement {
  72. public:
  73. Expected<CodeRangeASTSelection>
  74. evaluate(RefactoringRuleContext &Context) const;
  75. };
  76. /// A base class for any requirement that requires some refactoring options.
  77. class RefactoringOptionsRequirement : public RefactoringActionRuleRequirement {
  78. public:
  79. virtual ~RefactoringOptionsRequirement() {}
  80. /// Returns the set of refactoring options that are used when evaluating this
  81. /// requirement.
  82. virtual ArrayRef<std::shared_ptr<RefactoringOption>>
  83. getRefactoringOptions() const = 0;
  84. };
  85. /// A requirement that evaluates to the value of the given \c OptionType when
  86. /// the \c OptionType is a required option. When the \c OptionType is an
  87. /// optional option, the requirement will evaluate to \c None if the option is
  88. /// not specified or to an appropriate value otherwise.
  89. template <typename OptionType>
  90. class OptionRequirement : public RefactoringOptionsRequirement {
  91. public:
  92. OptionRequirement() : Opt(createRefactoringOption<OptionType>()) {}
  93. ArrayRef<std::shared_ptr<RefactoringOption>>
  94. getRefactoringOptions() const final {
  95. return Opt;
  96. }
  97. Expected<typename OptionType::ValueType>
  98. evaluate(RefactoringRuleContext &) const {
  99. return static_cast<OptionType *>(Opt.get())->getValue();
  100. }
  101. private:
  102. /// The partially-owned option.
  103. ///
  104. /// The ownership of the option is shared among the different requirements
  105. /// because the same option can be used by multiple rules in one refactoring
  106. /// action.
  107. std::shared_ptr<RefactoringOption> Opt;
  108. };
  109. } // end namespace tooling
  110. } // end namespace clang
  111. #endif // LLVM_CLANG_TOOLING_REFACTORING_REFACTORINGACTIONRULEREQUIREMENTS_H
  112. #ifdef __GNUC__
  113. #pragma GCC diagnostic pop
  114. #endif