[clang] ddca007 - Add code complete support for mapAnyOf

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 7 08:08:51 PST 2021


Author: Stephen Kelly
Date: 2021-02-07T16:03:05Z
New Revision: ddca007a291b0e224fe5a492ae8d78c6a933b4fe

URL: https://github.com/llvm/llvm-project/commit/ddca007a291b0e224fe5a492ae8d78c6a933b4fe
DIFF: https://github.com/llvm/llvm-project/commit/ddca007a291b0e224fe5a492ae8d78c6a933b4fe.diff

LOG: Add code complete support for mapAnyOf

Added: 
    

Modified: 
    clang/lib/ASTMatchers/Dynamic/Registry.cpp
    clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index ef5fd64a36667..4300eb8d8b983 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -656,20 +656,40 @@ Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
     bool IsPolymorphic = Matcher.isPolymorphic();
     std::vector<std::vector<ArgKind>> ArgsKinds(NumArgs);
     unsigned MaxSpecificity = 0;
+    bool NodeArgs = false;
     for (const ArgKind& Kind : AcceptedTypes) {
-      if (Kind.getArgKind() != Kind.AK_Matcher)
+      if (Kind.getArgKind() != Kind.AK_Matcher &&
+          Kind.getArgKind() != Kind.AK_Node) {
         continue;
-      unsigned Specificity;
-      ASTNodeKind LeastDerivedKind;
-      if (Matcher.isConvertibleTo(Kind.getMatcherKind(), &Specificity,
-                                  &LeastDerivedKind)) {
-        if (MaxSpecificity < Specificity)
-          MaxSpecificity = Specificity;
-        RetKinds.insert(LeastDerivedKind);
-        for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
-          Matcher.getArgKinds(Kind.getMatcherKind(), Arg, ArgsKinds[Arg]);
-        if (IsPolymorphic)
-          break;
+      }
+
+      if (Kind.getArgKind() == Kind.AK_Node) {
+        NodeArgs = true;
+        unsigned Specificity;
+        ASTNodeKind LeastDerivedKind;
+        if (Matcher.isConvertibleTo(Kind.getNodeKind(), &Specificity,
+                                    &LeastDerivedKind)) {
+          if (MaxSpecificity < Specificity)
+            MaxSpecificity = Specificity;
+          RetKinds.insert(LeastDerivedKind);
+          for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
+            Matcher.getArgKinds(Kind.getNodeKind(), Arg, ArgsKinds[Arg]);
+          if (IsPolymorphic)
+            break;
+        }
+      } else {
+        unsigned Specificity;
+        ASTNodeKind LeastDerivedKind;
+        if (Matcher.isConvertibleTo(Kind.getMatcherKind(), &Specificity,
+                                    &LeastDerivedKind)) {
+          if (MaxSpecificity < Specificity)
+            MaxSpecificity = Specificity;
+          RetKinds.insert(LeastDerivedKind);
+          for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
+            Matcher.getArgKinds(Kind.getMatcherKind(), Arg, ArgsKinds[Arg]);
+          if (IsPolymorphic)
+            break;
+        }
       }
     }
 
@@ -677,42 +697,49 @@ Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
       std::string Decl;
       llvm::raw_string_ostream OS(Decl);
 
-      if (IsPolymorphic) {
-        OS << "Matcher<T> " << Name << "(Matcher<T>";
+      std::string TypedText = std::string(Name);
+
+      if (NodeArgs) {
+        OS << Name;
       } 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 (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 << "|";
-              FirstArgKind = false;
-              OS << AK.asString();
+              OS << "Matcher<" << MatcherKinds << ">";
             }
           }
-          if (!MatcherKinds.empty()) {
-            if (!FirstArgKind) OS << "|";
-            OS << "Matcher<" << MatcherKinds << ">";
-          }
         }
+        if (Matcher.isVariadic())
+          OS << "...";
+        OS << ")";
+
+        TypedText += "(";
+        if (ArgsKinds.empty())
+          TypedText += ")";
+        else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String)
+          TypedText += "\"";
       }
-      if (Matcher.isVariadic())
-        OS << "...";
-      OS << ")";
-
-      std::string TypedText = std::string(Name);
-      TypedText += "(";
-      if (ArgsKinds.empty())
-        TypedText += ")";
-      else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String)
-        TypedText += "\"";
 
       Completions.emplace_back(TypedText, OS.str(), MaxSpecificity);
     }

diff  --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index 744be79d87ff4..255432dc3862a 100644
--- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -541,6 +541,29 @@ TEST(ParserTest, CompletionRegistry) {
   ASSERT_EQ(1u, Comps.size());
   EXPECT_EQ("bind(\"", Comps[0].TypedText);
   EXPECT_EQ("bind", Comps[0].MatcherDecl);
+
+  Code = "mapAny";
+  Comps = Parser::completeExpression(Code, 6);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("Of(", Comps[0].TypedText);
+  EXPECT_EQ("Matcher<NestedNameSpecifierLoc|QualType|TypeLoc|...> "
+            "mapAnyOf(NestedNameSpecifierLoc|QualType|TypeLoc|"
+            "NestedNameSpecifier|Decl|Stmt|Type...)",
+            Comps[0].MatcherDecl);
+
+  Code = "mapAnyOf(ifStmt).";
+  Comps = Parser::completeExpression(Code, 17);
+  ASSERT_EQ(2u, Comps.size());
+  EXPECT_EQ("bind(\"", Comps[0].TypedText);
+  EXPECT_EQ("bind", Comps[0].MatcherDecl);
+  EXPECT_EQ("with(", Comps[1].TypedText);
+  EXPECT_EQ("with", Comps[1].MatcherDecl);
+
+  Code = "mapAnyOf(ifS";
+  Comps = Parser::completeExpression(Code, 12);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("tmt", Comps[0].TypedText);
+  EXPECT_EQ("ifStmt", Comps[0].MatcherDecl);
 }
 
 TEST(ParserTest, CompletionNamedValues) {


        


More information about the cfe-commits mailing list