1327952Sdim//===- Registry.h - Matcher registry ----------------------------*- C++ -*-===//
2259701Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6259701Sdim//
7259701Sdim//===----------------------------------------------------------------------===//
8327952Sdim//
9259701Sdim/// \file
10341825Sdim/// Registry of all known matchers.
11259701Sdim///
12259701Sdim/// The registry provides a generic interface to construct any matcher by name.
13327952Sdim//
14259701Sdim//===----------------------------------------------------------------------===//
15259701Sdim
16280031Sdim#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
17280031Sdim#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
18259701Sdim
19259701Sdim#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
20259701Sdim#include "clang/ASTMatchers/Dynamic/VariantValue.h"
21259701Sdim#include "llvm/ADT/ArrayRef.h"
22276479Sdim#include "llvm/ADT/Optional.h"
23259701Sdim#include "llvm/ADT/StringRef.h"
24314564Sdim#include <string>
25314564Sdim#include <utility>
26314564Sdim#include <vector>
27259701Sdim
28259701Sdimnamespace clang {
29259701Sdimnamespace ast_matchers {
30259701Sdimnamespace dynamic {
31259701Sdim
32276479Sdimnamespace internal {
33314564Sdim
34276479Sdimclass MatcherDescriptor;
35276479Sdim
36327952Sdim} // namespace internal
37314564Sdim
38327952Sdimusing MatcherCtor = const internal::MatcherDescriptor *;
39276479Sdim
40276479Sdimstruct MatcherCompletion {
41314564Sdim  MatcherCompletion() = default;
42280031Sdim  MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
43280031Sdim                    unsigned Specificity)
44280031Sdim      : TypedText(TypedText), MatcherDecl(MatcherDecl),
45280031Sdim        Specificity(Specificity) {}
46276479Sdim
47314564Sdim  bool operator==(const MatcherCompletion &Other) const {
48314564Sdim    return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
49314564Sdim  }
50314564Sdim
51341825Sdim  /// The text to type to select this matcher.
52276479Sdim  std::string TypedText;
53276479Sdim
54341825Sdim  /// The "declaration" of the matcher, with type information.
55276479Sdim  std::string MatcherDecl;
56276479Sdim
57341825Sdim  /// Value corresponding to the "specificity" of the converted matcher.
58280031Sdim  ///
59280031Sdim  /// Zero specificity indicates that this conversion would produce a trivial
60280031Sdim  /// matcher that will either always or never match.
61280031Sdim  /// Such matchers are excluded from code completion results.
62280031Sdim  unsigned Specificity;
63276479Sdim};
64276479Sdim
65259701Sdimclass Registry {
66259701Sdimpublic:
67314564Sdim  Registry() = delete;
68314564Sdim
69341825Sdim  /// Look up a matcher in the registry by name,
70259701Sdim  ///
71276479Sdim  /// \return An opaque value which may be used to refer to the matcher
72276479Sdim  /// constructor, or Optional<MatcherCtor>() if not found.
73276479Sdim  static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
74276479Sdim
75341825Sdim  /// Compute the list of completion types for \p Context.
76259701Sdim  ///
77276479Sdim  /// Each element of \p Context represents a matcher invocation, going from
78280031Sdim  /// outermost to innermost. Elements are pairs consisting of a reference to
79280031Sdim  /// the matcher constructor and the index of the next element in the
80280031Sdim  /// argument list of that matcher (or for the last element, the index of
81280031Sdim  /// the completion point in the argument list). An empty list requests
82280031Sdim  /// completion for the root matcher.
83280031Sdim  static std::vector<ArgKind> getAcceptedCompletionTypes(
84280031Sdim      llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
85280031Sdim
86341825Sdim  /// Compute the list of completions that match any of
87280031Sdim  /// \p AcceptedTypes.
88259701Sdim  ///
89280031Sdim  /// \param AcceptedTypes All types accepted for this completion.
90276479Sdim  ///
91280031Sdim  /// \return All completions for the specified types.
92280031Sdim  /// Completions should be valid when used in \c lookupMatcherCtor().
93280031Sdim  /// The matcher constructed from the return of \c lookupMatcherCtor()
94280031Sdim  /// should be convertible to some type in \p AcceptedTypes.
95276479Sdim  static std::vector<MatcherCompletion>
96280031Sdim  getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
97276479Sdim
98341825Sdim  /// Construct a matcher from the registry.
99276479Sdim  ///
100276479Sdim  /// \param Ctor The matcher constructor to instantiate.
101276479Sdim  ///
102259701Sdim  /// \param NameRange The location of the name in the matcher source.
103259701Sdim  ///   Useful for error reporting.
104259701Sdim  ///
105259701Sdim  /// \param Args The argument list for the matcher. The number and types of the
106259701Sdim  ///   values must be valid for the matcher requested. Otherwise, the function
107259701Sdim  ///   will return an error.
108259701Sdim  ///
109259701Sdim  /// \return The matcher object constructed if no error was found.
110276479Sdim  ///   A null matcher if the number of arguments or argument types do not match
111276479Sdim  ///   the signature.  In that case \c Error will contain the description of
112276479Sdim  ///   the error.
113276479Sdim  static VariantMatcher constructMatcher(MatcherCtor Ctor,
114296417Sdim                                         SourceRange NameRange,
115259701Sdim                                         ArrayRef<ParserValue> Args,
116259701Sdim                                         Diagnostics *Error);
117259701Sdim
118341825Sdim  /// Construct a matcher from the registry and bind it.
119259701Sdim  ///
120259701Sdim  /// Similar the \c constructMatcher() above, but it then tries to bind the
121259701Sdim  /// matcher to the specified \c BindID.
122259701Sdim  /// If the matcher is not bindable, it sets an error in \c Error and returns
123259701Sdim  /// a null matcher.
124276479Sdim  static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
125296417Sdim                                              SourceRange NameRange,
126259701Sdim                                              StringRef BindID,
127259701Sdim                                              ArrayRef<ParserValue> Args,
128259701Sdim                                              Diagnostics *Error);
129259701Sdim};
130259701Sdim
131327952Sdim} // namespace dynamic
132327952Sdim} // namespace ast_matchers
133327952Sdim} // namespace clang
134259701Sdim
135314564Sdim#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
136