Add support for eachOf/allOf/anyOf variadic matchers in the dynamic layer.
Summary:
Add support for eachOf/allOf/anyOf variadic matchers in the dynamic layer.
These function require some late binding behavior for the type conversions, thus changes in VariadicValue's MatcherList.
Second try. This time with a fix for C++11 builds.
Reviewers: klimek
CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D1536
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189500 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index 71b0f87..9116ab8 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -137,9 +137,9 @@
Range.Start.Column == StartColumn && Range.End.Column == EndColumn;
}
-const DynTypedMatcher *getSingleMatcher(const VariantValue &value) {
+const DynTypedMatcher *getSingleMatcher(const VariantValue &Value) {
const DynTypedMatcher *Out;
- EXPECT_TRUE(value.getMatcher().getSingleMatcher(Out));
+ EXPECT_TRUE(Value.getMatcher().getSingleMatcher(Out));
return Out;
}
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index 55490a5..874a4f3 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -261,6 +261,33 @@
EXPECT_FALSE(matches("void foo() { if (true) return; }", S));
}
+TEST_F(RegistryTest, VariadicOp) {
+ Matcher<Decl> D = constructMatcher(
+ "anyOf", constructMatcher("recordDecl"),
+ constructMatcher("namedDecl",
+ constructMatcher("hasName", std::string("foo"))))
+ .getTypedMatcher<Decl>();
+
+ EXPECT_TRUE(matches("void foo(){}", D));
+ EXPECT_TRUE(matches("struct Foo{};", D));
+ EXPECT_FALSE(matches("int i = 0;", D));
+
+ D = constructMatcher(
+ "allOf", constructMatcher("recordDecl"),
+ constructMatcher(
+ "namedDecl",
+ constructMatcher("anyOf",
+ constructMatcher("hasName", std::string("Foo")),
+ constructMatcher("hasName", std::string("Bar")))))
+ .getTypedMatcher<Decl>();
+
+ EXPECT_FALSE(matches("void foo(){}", D));
+ EXPECT_TRUE(matches("struct Foo{};", D));
+ EXPECT_FALSE(matches("int i = 0;", D));
+ EXPECT_TRUE(matches("class Bar{};", D));
+ EXPECT_FALSE(matches("class OtherBar{};", D));
+}
+
TEST_F(RegistryTest, Errors) {
// Incorrect argument count.
OwningPtr<Diagnostics> Error(new Diagnostics());
@@ -285,6 +312,24 @@
EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
"(Actual = Matcher<FunctionDecl>)",
Error->toString());
+
+ // Bad argument type with variadic.
+ Error.reset(new Diagnostics());
+ EXPECT_TRUE(constructMatcher("anyOf", std::string(), Error.get()).isNull());
+ EXPECT_EQ(
+ "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
+ Error->toString());
+ Error.reset(new Diagnostics());
+ EXPECT_TRUE(constructMatcher(
+ "recordDecl",
+ constructMatcher("allOf",
+ constructMatcher("isDerivedFrom", std::string("FOO")),
+ constructMatcher("isArrow")),
+ Error.get()).isNull());
+ EXPECT_EQ("Incorrect type for arg 1. "
+ "(Expected = Matcher<CXXRecordDecl>) != "
+ "(Actual = Matcher<CXXRecordDecl>&Matcher<MemberExpr>)",
+ Error->toString());
}
} // end anonymous namespace