Author: sbenza Date: Wed Apr 23 09:04:52 2014 New Revision: 206984 URL: http://llvm.org/viewvc/llvm-project?rev=206984&view=rev Log: Add new 'let' command to bind arbitrary values into constants.
Summary: Add new 'let' command to bind arbitrary values into constants. These constants can then be used in the matcher expressions. Reviewers: pcc CC: cfe-commits Differential Revision: http://reviews.llvm.org/D3383 Modified: clang-tools-extra/trunk/clang-query/Query.cpp clang-tools-extra/trunk/clang-query/Query.h clang-tools-extra/trunk/clang-query/QueryParser.cpp clang-tools-extra/trunk/clang-query/QueryParser.h clang-tools-extra/trunk/clang-query/QuerySession.h clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp Modified: clang-tools-extra/trunk/clang-query/Query.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.cpp?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/Query.cpp (original) +++ clang-tools-extra/trunk/clang-query/Query.cpp Wed Apr 23 09:04:52 2014 @@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder:: } }; -} +} // namespace bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { unsigned MatchCount = 0; @@ -124,6 +124,15 @@ bool MatchQuery::run(llvm::raw_ostream & return true; } +bool LetQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { + if (Value) { + QS.NamedValues[Name] = Value; + } else { + QS.NamedValues.erase(Name); + } + return true; +} + #ifndef _MSC_VER const QueryKind SetQueryKind<bool>::value; const QueryKind SetQueryKind<OutputKind>::value; Modified: clang-tools-extra/trunk/clang-query/Query.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.h?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/Query.h (original) +++ clang-tools-extra/trunk/clang-query/Query.h Wed Apr 23 09:04:52 2014 @@ -28,9 +28,10 @@ enum QueryKind { QK_Invalid, QK_NoOp, QK_Help, + QK_Let, QK_Match, QK_SetBool, - QK_SetOutputKind + QK_SetOutputKind, }; class QuerySession; @@ -86,6 +87,17 @@ struct MatchQuery : Query { static bool classof(const Query *Q) { return Q->Kind == QK_Match; } }; +struct LetQuery : Query { + LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value) + : Query(QK_Let), Name(Name), Value(Value) {} + bool run(llvm::raw_ostream &OS, QuerySession &QS) const override; + + std::string Name; + ast_matchers::dynamic::VariantValue Value; + + static bool classof(const Query *Q) { return Q->Kind == QK_Let; } +}; + template <typename T> struct SetQueryKind {}; template <> struct SetQueryKind<bool> { Modified: clang-tools-extra/trunk/clang-query/QueryParser.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.cpp?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/QueryParser.cpp (original) +++ clang-tools-extra/trunk/clang-query/QueryParser.cpp Wed Apr 23 09:04:52 2014 @@ -132,12 +132,16 @@ QueryRef QueryParser::endQuery(QueryRef return Q; } +namespace { + enum ParsedQueryKind { PQK_Invalid, PQK_NoOp, PQK_Help, + PQK_Let, PQK_Match, - PQK_Set + PQK_Set, + PQK_Unlet, }; enum ParsedQueryVariable { @@ -146,16 +150,52 @@ enum ParsedQueryVariable { PQV_BindRoot }; +QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) { + std::string ErrStr; + llvm::raw_string_ostream OS(ErrStr); + Diag.printToStreamFull(OS); + return new InvalidQuery(OS.str()); +} + +class QuerySessionSema : public Parser::RegistrySema { +public: + QuerySessionSema(const QuerySession &QS) : QS(QS) {} + + ast_matchers::dynamic::VariantValue getNamedValue(StringRef Name) override { + return QS.NamedValues.lookup(Name); + } + +private: + const QuerySession &QS; +}; + +} // namespace + +QueryRef QueryParser::completeMatcherExpression() { + std::vector<MatcherCompletion> Comps = Parser::completeExpression( + StringRef(Begin, End - Begin), CompletionPos - Begin); + for (std::vector<MatcherCompletion>::iterator I = Comps.begin(), + E = Comps.end(); + I != E; ++I) { + Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl)); + } + return QueryRef(); +} + QueryRef QueryParser::doParse() { StringRef CommandStr; ParsedQueryKind QKind = lexOrCompleteWord<ParsedQueryKind>(CommandStr) .Case("", PQK_NoOp) .Case("help", PQK_Help) .Case("m", PQK_Match, /*IsCompletion=*/false) + .Case("let", PQK_Let) .Case("match", PQK_Match) .Case("set", PQK_Set) + .Case("unlet", PQK_Unlet) .Default(PQK_Invalid); + QuerySessionSema S(QS); + switch (QKind) { case PQK_NoOp: return new NoOpQuery; @@ -163,29 +203,36 @@ QueryRef QueryParser::doParse() { case PQK_Help: return endQuery(new HelpQuery); + case PQK_Let: { + StringRef Name = lexWord(); + + if (Name.empty()) + return new InvalidQuery("expected variable name"); + + if (CompletionPos) + return completeMatcherExpression(); + + Diagnostics Diag; + ast_matchers::dynamic::VariantValue Value; + if (!Parser::parseExpression(StringRef(Begin, End - Begin), &S, &Value, + &Diag)) { + return makeInvalidQueryFromDiagnostics(Diag); + } + + return new LetQuery(Name, Value); + } + case PQK_Match: { - if (CompletionPos) { - std::vector<MatcherCompletion> Comps = Parser::completeExpression( - StringRef(Begin, End - Begin), CompletionPos - Begin); - for (std::vector<MatcherCompletion>::iterator I = Comps.begin(), - E = Comps.end(); - I != E; ++I) { - Completions.push_back( - LineEditor::Completion(I->TypedText, I->MatcherDecl)); - } - return QueryRef(); - } else { - Diagnostics Diag; - Optional<DynTypedMatcher> Matcher = - Parser::parseMatcherExpression(StringRef(Begin, End - Begin), &Diag); - if (!Matcher) { - std::string ErrStr; - llvm::raw_string_ostream OS(ErrStr); - Diag.printToStreamFull(OS); - return new InvalidQuery(OS.str()); - } - return new MatchQuery(*Matcher); + if (CompletionPos) + return completeMatcherExpression(); + + Diagnostics Diag; + Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression( + StringRef(Begin, End - Begin), &S, &Diag); + if (!Matcher) { + return makeInvalidQueryFromDiagnostics(Diag); } + return new MatchQuery(*Matcher); } case PQK_Set: { @@ -214,6 +261,15 @@ QueryRef QueryParser::doParse() { return endQuery(Q); } + case PQK_Unlet: { + StringRef Name = lexWord(); + + if (Name.empty()) + return new InvalidQuery("expected variable name"); + + return endQuery(new LetQuery(Name, {})); + } + case PQK_Invalid: return new InvalidQuery("unknown command: " + CommandStr); } @@ -221,13 +277,13 @@ QueryRef QueryParser::doParse() { llvm_unreachable("Invalid query kind"); } -QueryRef QueryParser::parse(StringRef Line) { - return QueryParser(Line).doParse(); +QueryRef QueryParser::parse(StringRef Line, const QuerySession &QS) { + return QueryParser(Line, QS).doParse(); } -std::vector<LineEditor::Completion> QueryParser::complete(StringRef Line, - size_t Pos) { - QueryParser P(Line); +std::vector<LineEditor::Completion> +QueryParser::complete(StringRef Line, size_t Pos, const QuerySession &QS) { + QueryParser P(Line, QS); P.CompletionPos = Line.data() + Pos; P.doParse(); Modified: clang-tools-extra/trunk/clang-query/QueryParser.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.h?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/QueryParser.h (original) +++ clang-tools-extra/trunk/clang-query/QueryParser.h Wed Apr 23 09:04:52 2014 @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PARSER_H #include "Query.h" +#include "QuerySession.h" #include "llvm/LineEditor/LineEditor.h" #include <stddef.h> @@ -24,19 +25,20 @@ public: /// Parse \a Line as a query. /// /// \return A QueryRef representing the query, which may be an InvalidQuery. - static QueryRef parse(StringRef Line); + static QueryRef parse(StringRef Line, const QuerySession &QS); /// Compute a list of completions for \a Line assuming a cursor at /// \param Pos characters past the start of \a Line, ordered from most /// likely to least likely. /// /// \return A vector of completions for \a Line. - static std::vector<llvm::LineEditor::Completion> complete(StringRef Line, - size_t Pos); + static std::vector<llvm::LineEditor::Completion> + complete(StringRef Line, size_t Pos, const QuerySession &QS); private: - QueryParser(StringRef Line) - : Begin(Line.data()), End(Line.data() + Line.size()), CompletionPos(0) {} + QueryParser(StringRef Line, const QuerySession &QS) + : Begin(Line.data()), End(Line.data() + Line.size()), CompletionPos(0), + QS(QS) {} StringRef lexWord(); @@ -45,6 +47,7 @@ private: QueryRef parseSetBool(bool QuerySession::*Var); QueryRef parseSetOutputKind(); + QueryRef completeMatcherExpression(); QueryRef endQuery(QueryRef Q); @@ -59,6 +62,8 @@ private: const char *CompletionPos; std::vector<llvm::LineEditor::Completion> Completions; + + const QuerySession &QS; }; } // namespace query Modified: clang-tools-extra/trunk/clang-query/QuerySession.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QuerySession.h?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/QuerySession.h (original) +++ clang-tools-extra/trunk/clang-query/QuerySession.h Wed Apr 23 09:04:52 2014 @@ -11,7 +11,9 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_SESSION_H #include "Query.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringMap.h" namespace clang { @@ -28,6 +30,7 @@ public: llvm::ArrayRef<ASTUnit *> ASTs; OutputKind OutKind; bool BindRoot; + llvm::StringMap<ast_matchers::dynamic::VariantValue> NamedValues; }; } // namespace query Modified: clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp (original) +++ clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp Wed Apr 23 09:04:52 2014 @@ -95,7 +95,7 @@ int main(int argc, const char **argv) { for (cl::list<std::string>::iterator I = Commands.begin(), E = Commands.end(); I != E; ++I) { - QueryRef Q = QueryParser::parse(I->c_str()); + QueryRef Q = QueryParser::parse(I->c_str(), QS); if (!Q->run(llvm::outs(), QS)) return 1; } @@ -112,16 +112,18 @@ int main(int argc, const char **argv) { std::string Line; std::getline(Input, Line); - QueryRef Q = QueryParser::parse(Line.c_str()); + QueryRef Q = QueryParser::parse(Line.c_str(), QS); if (!Q->run(llvm::outs(), QS)) return 1; } } } else { LineEditor LE("clang-query"); - LE.setListCompleter(QueryParser::complete); + LE.setListCompleter([&QS](StringRef Line, size_t Pos) { + return QueryParser::complete(Line, Pos, QS); + }); while (llvm::Optional<std::string> Line = LE.readLine()) { - QueryRef Q = QueryParser::parse(*Line); + QueryRef Q = QueryParser::parse(*Line, QS); Q->run(llvm::outs(), QS); } } Modified: clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp (original) +++ clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp Wed Apr 23 09:04:52 2014 @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "Query.h" +#include "QueryParser.h" #include "QuerySession.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/ASTMatchers/Dynamic/VariantValue.h" @@ -24,20 +25,22 @@ using namespace clang::ast_matchers::dyn using namespace clang::query; using namespace clang::tooling; -TEST(Query, Basic) { - std::unique_ptr<ASTUnit> FooAST( - buildASTFromCode("void foo1(void) {}\nvoid foo2(void) {}", "foo.cc")); - ASSERT_TRUE(FooAST.get()); - std::unique_ptr<ASTUnit> BarAST( - buildASTFromCode("void bar1(void) {}\nvoid bar2(void) {}", "bar.cc")); - ASSERT_TRUE(BarAST.get()); - - ASTUnit *ASTs[] = { FooAST.get(), BarAST.get() }; +class QueryEngineTest : public ::testing::Test { +protected: + QueryEngineTest() {} + + std::unique_ptr<ASTUnit> FooAST{ + buildASTFromCode("void foo1(void) {}\nvoid foo2(void) {}", "foo.cc")}; + std::unique_ptr<ASTUnit> BarAST{ + buildASTFromCode("void bar1(void) {}\nvoid bar2(void) {}", "bar.cc")}; + ASTUnit *ASTs[2]{FooAST.get(), BarAST.get()}; + QuerySession S{ASTs}; std::string Str; - llvm::raw_string_ostream OS(Str); - QuerySession S(ASTs); + llvm::raw_string_ostream OS{Str}; +}; +TEST_F(QueryEngineTest, Basic) { DynTypedMatcher FnMatcher = functionDecl(); DynTypedMatcher FooMatcher = functionDecl(hasName("foo1")); @@ -108,3 +111,28 @@ TEST(Query, Basic) { EXPECT_EQ("Not a valid top-level matcher.\n", OS.str()); } + +TEST_F(QueryEngineTest, LetAndMatch) { + EXPECT_TRUE(QueryParser::parse("let x \"foo1\"", S)->run(OS, S)); + EXPECT_EQ("", OS.str()); + Str.clear(); + + EXPECT_TRUE(QueryParser::parse("let y hasName(x)", S)->run(OS, S)); + EXPECT_EQ("", OS.str()); + Str.clear(); + + EXPECT_TRUE(QueryParser::parse("match functionDecl(y)", S)->run(OS, S)); + EXPECT_TRUE(OS.str().find("foo.cc:1:1: note: \"root\" binds here") != + std::string::npos); + EXPECT_TRUE(OS.str().find("1 match.") != std::string::npos); + Str.clear(); + + EXPECT_TRUE(QueryParser::parse("unlet x", S)->run(OS, S)); + EXPECT_EQ("", OS.str()); + Str.clear(); + + EXPECT_FALSE(QueryParser::parse("let y hasName(x)", S)->run(OS, S)); + EXPECT_EQ("1:2: Error parsing argument 1 for matcher hasName.\n" + "1:10: Value not found: x\n", OS.str()); + Str.clear(); +} Modified: clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp?rev=206984&r1=206983&r2=206984&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp (original) +++ clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp Wed Apr 23 09:04:52 2014 @@ -16,95 +16,139 @@ using namespace clang; using namespace clang::query; -TEST(QueryParser, NoOp) { - QueryRef Q = QueryParser::parse(""); +class QueryParserTest : public ::testing::Test { +protected: + QueryParserTest() {} + QueryRef parse(StringRef Code) { return QueryParser::parse(Code, QS); } + + QuerySession QS{llvm::ArrayRef<ASTUnit*>()}; +}; + +TEST_F(QueryParserTest, NoOp) { + QueryRef Q = parse(""); EXPECT_TRUE(isa<NoOpQuery>(Q)); - Q = QueryParser::parse("\n"); + Q = parse("\n"); EXPECT_TRUE(isa<NoOpQuery>(Q)); } -TEST(QueryParser, Invalid) { - QueryRef Q = QueryParser::parse("foo"); +TEST_F(QueryParserTest, Invalid) { + QueryRef Q = parse("foo"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("unknown command: foo", cast<InvalidQuery>(Q)->ErrStr); } -TEST(QueryParser, Help) { - QueryRef Q = QueryParser::parse("help"); +TEST_F(QueryParserTest, Help) { + QueryRef Q = parse("help"); ASSERT_TRUE(isa<HelpQuery>(Q)); - Q = QueryParser::parse("help me"); + Q = parse("help me"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr); } -TEST(QueryParser, Set) { - QueryRef Q = QueryParser::parse("set"); +TEST_F(QueryParserTest, Set) { + QueryRef Q = parse("set"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set foo bar"); + Q = parse("set foo bar"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("unknown variable: 'foo'", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set output"); + Q = parse("set output"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("expected 'diag', 'print' or 'dump', got ''", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set bind-root true foo"); + Q = parse("set bind-root true foo"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("unexpected extra input: ' foo'", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set output foo"); + Q = parse("set output foo"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("expected 'diag', 'print' or 'dump', got 'foo'", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set output dump"); + Q = parse("set output dump"); ASSERT_TRUE(isa<SetQuery<OutputKind> >(Q)); EXPECT_EQ(&QuerySession::OutKind, cast<SetQuery<OutputKind> >(Q)->Var); EXPECT_EQ(OK_Dump, cast<SetQuery<OutputKind> >(Q)->Value); - Q = QueryParser::parse("set bind-root foo"); + Q = parse("set bind-root foo"); ASSERT_TRUE(isa<InvalidQuery>(Q)); EXPECT_EQ("expected 'true' or 'false', got 'foo'", cast<InvalidQuery>(Q)->ErrStr); - Q = QueryParser::parse("set bind-root true"); + Q = parse("set bind-root true"); ASSERT_TRUE(isa<SetQuery<bool> >(Q)); EXPECT_EQ(&QuerySession::BindRoot, cast<SetQuery<bool> >(Q)->Var); EXPECT_EQ(true, cast<SetQuery<bool> >(Q)->Value); } -TEST(QueryParser, Match) { - QueryRef Q = QueryParser::parse("match decl()"); +TEST_F(QueryParserTest, Match) { + QueryRef Q = parse("match decl()"); ASSERT_TRUE(isa<MatchQuery>(Q)); EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Decl>()); - Q = QueryParser::parse("m stmt()"); + Q = parse("m stmt()"); ASSERT_TRUE(isa<MatchQuery>(Q)); EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Stmt>()); } -TEST(QueryParser, Complete) { +TEST_F(QueryParserTest, LetUnlet) { + QueryRef Q = parse("let foo decl()"); + ASSERT_TRUE(isa<LetQuery>(Q)); + EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); + EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); + EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); + + Q = parse("let bar \"str\""); + ASSERT_TRUE(isa<LetQuery>(Q)); + EXPECT_EQ("bar", cast<LetQuery>(Q)->Name); + EXPECT_TRUE(cast<LetQuery>(Q)->Value.isString()); + EXPECT_EQ("str", cast<LetQuery>(Q)->Value.getString()); + + Q = parse("let"); + ASSERT_TRUE(isa<InvalidQuery>(Q)); + EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); + + Q = parse("unlet x"); + ASSERT_TRUE(isa<LetQuery>(Q)); + EXPECT_EQ("x", cast<LetQuery>(Q)->Name); + EXPECT_FALSE(cast<LetQuery>(Q)->Value.hasValue()); + + Q = parse("unlet"); + ASSERT_TRUE(isa<InvalidQuery>(Q)); + EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); + + Q = parse("unlet x bad_data"); + ASSERT_TRUE(isa<InvalidQuery>(Q)); + EXPECT_EQ("unexpected extra input: ' bad_data'", + cast<InvalidQuery>(Q)->ErrStr); +} + +TEST_F(QueryParserTest, Complete) { std::vector<llvm::LineEditor::Completion> Comps = - QueryParser::complete("", 0); - ASSERT_EQ(3u, Comps.size()); + QueryParser::complete("", 0, QS); + ASSERT_EQ(5u, Comps.size()); EXPECT_EQ("help ", Comps[0].TypedText); EXPECT_EQ("help", Comps[0].DisplayText); - EXPECT_EQ("match ", Comps[1].TypedText); - EXPECT_EQ("match", Comps[1].DisplayText); - EXPECT_EQ("set ", Comps[2].TypedText); - EXPECT_EQ("set", Comps[2].DisplayText); + EXPECT_EQ("let ", Comps[1].TypedText); + EXPECT_EQ("let", Comps[1].DisplayText); + EXPECT_EQ("match ", Comps[2].TypedText); + EXPECT_EQ("match", Comps[2].DisplayText); + EXPECT_EQ("set ", Comps[3].TypedText); + EXPECT_EQ("set", Comps[3].DisplayText); + EXPECT_EQ("unlet ", Comps[4].TypedText); + EXPECT_EQ("unlet", Comps[4].DisplayText); - Comps = QueryParser::complete("set o", 5); + Comps = QueryParser::complete("set o", 5, QS); ASSERT_EQ(1u, Comps.size()); EXPECT_EQ("utput ", Comps[0].TypedText); EXPECT_EQ("output", Comps[0].DisplayText); - Comps = QueryParser::complete("match while", 11); + Comps = QueryParser::complete("match while", 11, QS); ASSERT_EQ(1u, Comps.size()); EXPECT_EQ("Stmt(", Comps[0].TypedText); EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)", _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
