r219450 - Fix completion logic to allow for heterogeneous argument types in matcher overloads.
Samuel Benzaquen
sbenza at google.com
Thu Oct 9 15:08:52 PDT 2014
Author: sbenza
Date: Thu Oct 9 17:08:52 2014
New Revision: 219450
URL: http://llvm.org/viewvc/llvm-project?rev=219450&view=rev
Log:
Fix completion logic to allow for heterogeneous argument types in matcher overloads.
Summary:
There was an assumption that there were no matchers that were overloaded
on matchers and other types of arguments.
This assumption was broken recently with the addition of new matcher
overloads.
Fixes http://llvm.org/PR21226
Reviewers: pcc
Subscribers: klimek, cfe-commits
Differential Revision: http://reviews.llvm.org/D5711
Modified:
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=219450&r1=219449&r2=219450&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Thu Oct 9 17:08:52 2014
@@ -443,17 +443,22 @@ Registry::getMatcherCompletions(ArrayRef
for (const std::vector<ArgKind> &Arg : ArgsKinds) {
if (&Arg != &ArgsKinds[0])
OS << ", ";
- // This currently assumes that a matcher may not overload a
- // non-matcher, and all non-matcher overloads have identical
- // arguments.
- if (Arg[0].getArgKind() == ArgKind::AK_Matcher) {
- std::set<ASTNodeKind> MatcherKinds;
- std::transform(Arg.begin(), Arg.end(),
- std::inserter(MatcherKinds, MatcherKinds.end()),
- std::mem_fun_ref(&ArgKind::getMatcherKind));
+
+ 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 << ">";
- } else {
- OS << Arg[0].asString();
}
}
}
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=219450&r1=219449&r2=219450&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Thu Oct 9 17:08:52 2014
@@ -438,10 +438,18 @@ TEST_F(RegistryTest, Errors) {
TEST_F(RegistryTest, Completion) {
CompVector Comps = getCompletions();
+ // Overloaded
EXPECT_TRUE(hasCompletion(
Comps, "hasParent(", "Matcher<Decl|Stmt> hasParent(Matcher<Decl|Stmt>)"));
+ // Variadic.
EXPECT_TRUE(hasCompletion(Comps, "whileStmt(",
"Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)"));
+ // Polymorphic.
+ EXPECT_TRUE(hasCompletion(
+ Comps, "hasDescendant(",
+ "Matcher<NestedNameSpecifier|NestedNameSpecifierLoc|QualType|...> "
+ "hasDescendant(Matcher<CXXCtorInitializer|NestedNameSpecifier|"
+ "NestedNameSpecifierLoc|...>)"));
CompVector WhileComps = getCompletions("whileStmt", 0);
@@ -470,6 +478,12 @@ TEST_F(RegistryTest, Completion) {
hasCompletion(NamedDeclComps, "isPublic()", "Matcher<Decl> isPublic()"));
EXPECT_TRUE(hasCompletion(NamedDeclComps, "hasName(\"",
"Matcher<NamedDecl> hasName(string)"));
+
+ // Heterogeneous overloads.
+ Comps = getCompletions("classTemplateSpecializationDecl", 0);
+ EXPECT_TRUE(hasCompletion(
+ Comps, "isSameOrDerivedFrom(",
+ "Matcher<CXXRecordDecl> isSameOrDerivedFrom(string|Matcher<NamedDecl>)"));
}
TEST_F(RegistryTest, HasArgs) {
More information about the cfe-commits
mailing list