1f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===--- Registry.h - Matcher registry -----*- C++ -*-===//
2f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
3f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//                     The LLVM Compiler Infrastructure
4f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
5f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// This file is distributed under the University of Illinois Open Source
6f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// License. See LICENSE.TXT for details.
7f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
8f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===//
9f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
10f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \file
11f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Registry of all known matchers.
12f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
13f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// The registry provides a generic interface to construct any matcher by name.
14f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
15f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===//
16f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
17176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
18176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
19f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
20f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
21f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/VariantValue.h"
22f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/Basic/LLVM.h"
23f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/ADT/ArrayRef.h"
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/Optional.h"
25f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/ADT/StringRef.h"
26f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
27f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace clang {
28f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace ast_matchers {
29f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace dynamic {
30f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace internal {
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass MatcherDescriptor;
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef const internal::MatcherDescriptor *MatcherCtor;
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct MatcherCompletion {
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MatcherCompletion() {}
39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                    unsigned Specificity)
41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      : TypedText(TypedText), MatcherDecl(MatcherDecl),
42176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Specificity(Specificity) {}
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief The text to type to select this matcher.
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string TypedText;
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief The "declaration" of the matcher, with type information.
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string MatcherDecl;
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Value corresponding to the "specificity" of the converted matcher.
51176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ///
52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Zero specificity indicates that this conversion would produce a trivial
53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// matcher that will either always or never match.
54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Such matchers are excluded from code completion results.
55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  unsigned Specificity;
56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool operator==(const MatcherCompletion &Other) const {
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
62f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekclass Registry {
63f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic:
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Look up a matcher in the registry by name,
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \return An opaque value which may be used to refer to the matcher
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /// constructor, or Optional<MatcherCtor>() if not found.
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Compute the list of completion types for \p Context.
71f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Each element of \p Context represents a matcher invocation, going from
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// outermost to innermost. Elements are pairs consisting of a reference to
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// the matcher constructor and the index of the next element in the
75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// argument list of that matcher (or for the last element, the index of
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// the completion point in the argument list). An empty list requests
77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// completion for the root matcher.
78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static std::vector<ArgKind> getAcceptedCompletionTypes(
79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \brief Compute the list of completions that match any of
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \p AcceptedTypes.
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \param AcceptedTypes All types accepted for this completion.
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// \return All completions for the specified types.
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// Completions should be valid when used in \c lookupMatcherCtor().
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// The matcher constructed from the return of \c lookupMatcherCtor()
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  /// should be convertible to some type in \p AcceptedTypes.
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static std::vector<MatcherCompletion>
91176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Construct a matcher from the registry.
94f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \param Ctor The matcher constructor to instantiate.
96f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///
97f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  /// \param NameRange The location of the name in the matcher source.
98f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///   Useful for error reporting.
99f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///
100f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  /// \param Args The argument list for the matcher. The number and types of the
101f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///   values must be valid for the matcher requested. Otherwise, the function
102f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///   will return an error.
103f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ///
1049d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen  /// \return The matcher object constructed if no error was found.
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///   A null matcher if the number of arguments or argument types do not match
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///   the signature.  In that case \c Error will contain the description of
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ///   the error.
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static VariantMatcher constructMatcher(MatcherCtor Ctor,
1099d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                         const SourceRange &NameRange,
1109d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                         ArrayRef<ParserValue> Args,
1119d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                         Diagnostics *Error);
112f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
1134f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  /// \brief Construct a matcher from the registry and bind it.
1144f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  ///
1154f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  /// Similar the \c constructMatcher() above, but it then tries to bind the
1164f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  /// matcher to the specified \c BindID.
1174f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  /// If the matcher is not bindable, it sets an error in \c Error and returns
1189d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen  /// a null matcher.
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
1209d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                              const SourceRange &NameRange,
1219d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                              StringRef BindID,
1229d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                              ArrayRef<ParserValue> Args,
1239d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                              Diagnostics *Error);
1244f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen
125f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate:
1260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Registry() = delete;
127f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
128f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
129f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace dynamic
130f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace ast_matchers
131f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace clang
132f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
133f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
134