//===- unittest/ASTMatchers/Dynamic/RegistryTest.cpp - Registry unit tests -===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===-----------------------------------------------------------------------===// #include #include "../ASTMatchersTest.h" #include "clang/ASTMatchers/Dynamic/Registry.h" #include "gtest/gtest.h" namespace clang { namespace ast_matchers { namespace dynamic { namespace { using ast_matchers::internal::Matcher; DynTypedMatcher *constructMatcher(StringRef MatcherName, Diagnostics *Error) { const std::vector Args; return Registry::constructMatcher(MatcherName, SourceRange(), Args, Error); } DynTypedMatcher *constructMatcher(StringRef MatcherName, const VariantValue &Arg1, Diagnostics *Error) { std::vector Args(1); Args[0].Value = Arg1; return Registry::constructMatcher(MatcherName, SourceRange(), Args, Error); } DynTypedMatcher *constructMatcher(StringRef MatcherName, const VariantValue &Arg1, const VariantValue &Arg2, Diagnostics *Error) { std::vector Args(2); Args[0].Value = Arg1; Args[1].Value = Arg2; return Registry::constructMatcher(MatcherName, SourceRange(), Args, Error); } TEST(RegistryTest, CanConstructNoArgs) { OwningPtr IsArrowValue(constructMatcher("isArrow", NULL)); OwningPtr BoolValue(constructMatcher("boolLiteral", NULL)); const std::string ClassSnippet = "struct Foo { int x; };\n" "Foo *foo = new Foo;\n" "int i = foo->x;\n"; const std::string BoolSnippet = "bool Foo = true;\n"; EXPECT_TRUE(matchesDynamic(ClassSnippet, *IsArrowValue)); EXPECT_TRUE(matchesDynamic(BoolSnippet, *BoolValue)); EXPECT_FALSE(matchesDynamic(ClassSnippet, *BoolValue)); EXPECT_FALSE(matchesDynamic(BoolSnippet, *IsArrowValue)); } TEST(RegistryTest, ConstructWithSimpleArgs) { OwningPtr Value( constructMatcher("hasName", std::string("X"), NULL)); EXPECT_TRUE(matchesDynamic("class X {};", *Value)); EXPECT_FALSE(matchesDynamic("int x;", *Value)); } TEST(RegistryTest, ConstructWithMatcherArgs) { OwningPtr HasInitializerSimple( constructMatcher("hasInitializer", stmt(), NULL)); OwningPtr HasInitializerComplex( constructMatcher("hasInitializer", callExpr(), NULL)); std::string code = "int i;"; EXPECT_FALSE(matchesDynamic(code, *HasInitializerSimple)); EXPECT_FALSE(matchesDynamic(code, *HasInitializerComplex)); code = "int i = 1;"; EXPECT_TRUE(matchesDynamic(code, *HasInitializerSimple)); EXPECT_FALSE(matchesDynamic(code, *HasInitializerComplex)); code = "int y(); int i = y();"; EXPECT_TRUE(matchesDynamic(code, *HasInitializerSimple)); EXPECT_TRUE(matchesDynamic(code, *HasInitializerComplex)); } TEST(RegistryTest, Errors) { // Incorrect argument count. OwningPtr Error(new Diagnostics()); EXPECT_TRUE(NULL == constructMatcher("hasInitializer", Error.get())); EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)", Error->ToString()); Error.reset(new Diagnostics()); EXPECT_TRUE(NULL == constructMatcher("isArrow", std::string(), Error.get())); EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)", Error->ToString()); // Bad argument type Error.reset(new Diagnostics()); EXPECT_TRUE(NULL == constructMatcher("ofClass", std::string(), Error.get())); EXPECT_EQ("Incorrect type on function ofClass for arg 1.", Error->ToString()); Error.reset(new Diagnostics()); EXPECT_TRUE(NULL == constructMatcher("recordDecl", recordDecl(), ::std::string(), Error.get())); EXPECT_EQ("Incorrect type on function recordDecl for arg 2.", Error->ToString()); } } // end anonymous namespace } // end namespace dynamic } // end namespace ast_matchers } // end namespace clang