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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits