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/Optional.h"
23 #include "llvm/ADT/StringRef.h"
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 
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;
59   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 Optional<MatcherCtor>() if not found.
98   static llvm::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