steveire created this revision.
steveire added a reviewer: aaron.ballman.
Herald added a subscriber: cfe-commits.

The list of matchers which can be used with a top matcher can be used in
other contexts than code completion. It can be output as data in
clang-tidy.


Repository:
  rC Clang

https://reviews.llvm.org/D54402

Files:
  lib/ASTMatchers/Dynamic/Registry.cpp

Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -561,9 +561,8 @@
   return std::vector<ArgKind>(TypeSet.begin(), TypeSet.end());
 }
 
-std::vector<MatcherCompletion>
-Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
-  std::vector<MatcherCompletion> Completions;
+template <typename T>
+void processAcceptableMatchers(ArrayRef<ArgKind> AcceptedTypes, T func) {
 
   // Search the registry for acceptable matchers.
   for (const auto &M : RegistryData->constructors()) {
@@ -593,49 +592,65 @@
     }
 
     if (!RetKinds.empty() && MaxSpecificity > 0) {
-      std::string Decl;
-      llvm::raw_string_ostream OS(Decl);
-
-      if (IsPolymorphic) {
-        OS << "Matcher<T> " << Name << "(Matcher<T>";
-      } else {
-        OS << "Matcher<" << RetKinds << "> " << Name << "(";
-        for (const std::vector<ArgKind> &Arg : ArgsKinds) {
-          if (&Arg != &ArgsKinds[0])
-            OS << ", ";
-
-          bool FirstArgKind = true;
-          std::set<ASTNodeKind> MatcherKinds;
-          // Two steps. First all non-matchers, then matchers only.
-          for (const ArgKind &AK : Arg) {
-            if (AK.getArgKind() == ArgKind::AK_Matcher) {
-              MatcherKinds.insert(AK.getMatcherKind());
-            } else {
-              if (!FirstArgKind) OS << "|";
-              FirstArgKind = false;
-              OS << AK.asString();
+      func(Name, Matcher, RetKinds, ArgsKinds, MaxSpecificity);
+    }
+  }
+}
+
+std::vector<MatcherCompletion>
+Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
+  std::vector<MatcherCompletion> Completions;
+
+  processAcceptableMatchers(
+      AcceptedTypes,
+      [&Completions](StringRef Name, const MatcherDescriptor &Matcher,
+                     std::set<ASTNodeKind> &RetKinds,
+                     std::vector<std::vector<ArgKind>> ArgsKinds,
+                     unsigned MaxSpecificity) {
+        std::string Decl;
+        llvm::raw_string_ostream OS(Decl);
+
+        if (Matcher.isPolymorphic()) {
+          OS << "Matcher<T> " << Name << "(Matcher<T>";
+        } else {
+          OS << "Matcher<" << RetKinds << "> " << Name << "(";
+          for (const std::vector<ArgKind> &Arg : ArgsKinds) {
+            if (&Arg != &ArgsKinds[0])
+              OS << ", ";
+
+            bool FirstArgKind = true;
+            std::set<ASTNodeKind> MatcherKinds;
+            // Two steps. First all non-matchers, then matchers only.
+            for (const ArgKind &AK : Arg) {
+              if (AK.getArgKind() == ArgKind::AK_Matcher) {
+                MatcherKinds.insert(AK.getMatcherKind());
+              } else {
+                if (!FirstArgKind)
+                  OS << "|";
+                FirstArgKind = false;
+                OS << AK.asString();
+              }
+            }
+            if (!MatcherKinds.empty()) {
+              if (!FirstArgKind)
+                OS << "|";
+              OS << "Matcher<" << MatcherKinds << ">";
             }
-          }
-          if (!MatcherKinds.empty()) {
-            if (!FirstArgKind) OS << "|";
-            OS << "Matcher<" << MatcherKinds << ">";
           }
         }
-      }
-      if (Matcher.isVariadic())
-        OS << "...";
-      OS << ")";
-
-      std::string TypedText = Name;
-      TypedText += "(";
-      if (ArgsKinds.empty())
-        TypedText += ")";
-      else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String)
-        TypedText += "\"";
-
-      Completions.emplace_back(TypedText, OS.str(), MaxSpecificity);
-    }
-  }
+        if (Matcher.isVariadic())
+          OS << "...";
+        OS << ")";
+
+        std::string TypedText = Name;
+        TypedText += "(";
+        if (ArgsKinds.empty())
+          TypedText += ")";
+        else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String)
+          TypedText += "\"";
+
+        Completions.emplace_back(TypedText, OS.str(), MaxSpecificity);
+      });
 
   return Completions;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to