1 //===- Registry.h - Matcher registry ----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// Registry of all known matchers. 11 /// 12 /// The registry provides a generic interface to construct any matcher by name. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H 17 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H 18 19 #include "clang/ASTMatchers/Dynamic/Diagnostics.h" 20 #include "clang/ASTMatchers/Dynamic/VariantValue.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/StringRef.h" 23 #include <optional> 24 #include <string> 25 #include <utility> 26 #include <vector> 27 28 namespace clang { 29 namespace ast_matchers { 30 namespace dynamic { 31 32 namespace internal { 33 34 class MatcherDescriptor; 35 36 /// A smart (owning) pointer for MatcherDescriptor. We can't use unique_ptr 37 /// because MatcherDescriptor is forward declared 38 class MatcherDescriptorPtr { 39 public: 40 explicit MatcherDescriptorPtr(MatcherDescriptor *); 41 ~MatcherDescriptorPtr(); 42 MatcherDescriptorPtr(MatcherDescriptorPtr &&) = default; 43 MatcherDescriptorPtr &operator=(MatcherDescriptorPtr &&) = default; 44 MatcherDescriptorPtr(const MatcherDescriptorPtr &) = delete; 45 MatcherDescriptorPtr &operator=(const MatcherDescriptorPtr &) = delete; 46 get()47 MatcherDescriptor *get() { return Ptr; } 48 49 private: 50 MatcherDescriptor *Ptr; 51 }; 52 53 } // namespace internal 54 55 using MatcherCtor = const internal::MatcherDescriptor *; 56 57 struct MatcherCompletion { 58 MatcherCompletion() = default; MatcherCompletionMatcherCompletion59 MatcherCompletion(StringRef TypedText, StringRef MatcherDecl, 60 unsigned Specificity) 61 : TypedText(TypedText), MatcherDecl(MatcherDecl), 62 Specificity(Specificity) {} 63 64 bool operator==(const MatcherCompletion &Other) const { 65 return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl; 66 } 67 68 /// The text to type to select this matcher. 69 std::string TypedText; 70 71 /// The "declaration" of the matcher, with type information. 72 std::string MatcherDecl; 73 74 /// Value corresponding to the "specificity" of the converted matcher. 75 /// 76 /// Zero specificity indicates that this conversion would produce a trivial 77 /// matcher that will either always or never match. 78 /// Such matchers are excluded from code completion results. 79 unsigned Specificity; 80 }; 81 82 class Registry { 83 public: 84 Registry() = delete; 85 86 static ASTNodeKind nodeMatcherType(MatcherCtor); 87 88 static bool isBuilderMatcher(MatcherCtor Ctor); 89 90 static internal::MatcherDescriptorPtr 91 buildMatcherCtor(MatcherCtor, SourceRange NameRange, 92 ArrayRef<ParserValue> Args, Diagnostics *Error); 93 94 /// Look up a matcher in the registry by name, 95 /// 96 /// \return An opaque value which may be used to refer to the matcher 97 /// constructor, or std::optional<MatcherCtor>() if not found. 98 static std::optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName); 99 100 /// Compute the list of completion types for \p Context. 101 /// 102 /// Each element of \p Context represents a matcher invocation, going from 103 /// outermost to innermost. Elements are pairs consisting of a reference to 104 /// the matcher constructor and the index of the next element in the 105 /// argument list of that matcher (or for the last element, the index of 106 /// the completion point in the argument list). An empty list requests 107 /// completion for the root matcher. 108 static std::vector<ArgKind> getAcceptedCompletionTypes( 109 llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context); 110 111 /// Compute the list of completions that match any of 112 /// \p AcceptedTypes. 113 /// 114 /// \param AcceptedTypes All types accepted for this completion. 115 /// 116 /// \return All completions for the specified types. 117 /// Completions should be valid when used in \c lookupMatcherCtor(). 118 /// The matcher constructed from the return of \c lookupMatcherCtor() 119 /// should be convertible to some type in \p AcceptedTypes. 120 static std::vector<MatcherCompletion> 121 getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes); 122 123 /// Construct a matcher from the registry. 124 /// 125 /// \param Ctor The matcher constructor to instantiate. 126 /// 127 /// \param NameRange The location of the name in the matcher source. 128 /// Useful for error reporting. 129 /// 130 /// \param Args The argument list for the matcher. The number and types of the 131 /// values must be valid for the matcher requested. Otherwise, the function 132 /// will return an error. 133 /// 134 /// \return The matcher object constructed if no error was found. 135 /// A null matcher if the number of arguments or argument types do not match 136 /// the signature. In that case \c Error will contain the description of 137 /// the error. 138 static VariantMatcher constructMatcher(MatcherCtor Ctor, 139 SourceRange NameRange, 140 ArrayRef<ParserValue> Args, 141 Diagnostics *Error); 142 143 /// Construct a matcher from the registry and bind it. 144 /// 145 /// Similar the \c constructMatcher() above, but it then tries to bind the 146 /// matcher to the specified \c BindID. 147 /// If the matcher is not bindable, it sets an error in \c Error and returns 148 /// a null matcher. 149 static VariantMatcher constructBoundMatcher(MatcherCtor Ctor, 150 SourceRange NameRange, 151 StringRef BindID, 152 ArrayRef<ParserValue> Args, 153 Diagnostics *Error); 154 }; 155 156 } // namespace dynamic 157 } // namespace ast_matchers 158 } // namespace clang 159 160 #endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H 161