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
28namespace clang {
29namespace ast_matchers {
30namespace dynamic {
31
32namespace internal {
33
34class MatcherDescriptor;
35
36/// A smart (owning) pointer for MatcherDescriptor. We can't use unique_ptr
37/// because MatcherDescriptor is forward declared
38class MatcherDescriptorPtr {
39public:
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
49private:
50 MatcherDescriptor *Ptr;
51};
52
53} // namespace internal
54
55using MatcherCtor = const internal::MatcherDescriptor *;
56
57struct 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
82class Registry {
83public:
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

source code of clang/include/clang/ASTMatchers/Dynamic/Registry.h