steveire updated this revision to Diff 171046.
steveire added a comment.

New command design


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52857

Files:
  clang-query/Query.cpp
  clang-query/Query.h
  clang-query/QueryParser.cpp
  clang-query/QueryParser.h
  unittests/clang-query/QueryEngineTest.cpp
  unittests/clang-query/QueryParserTest.cpp

Index: unittests/clang-query/QueryParserTest.cpp
===================================================================
--- unittests/clang-query/QueryParserTest.cpp
+++ unittests/clang-query/QueryParserTest.cpp
@@ -90,6 +90,14 @@
   ASSERT_TRUE(isa<SetExclusiveOutputQuery>(Q));
   EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<SetExclusiveOutputQuery>(Q)->Var);
 
+  Q = parse("enable output detailed-ast");
+  ASSERT_TRUE(isa<EnableOutputQuery>(Q));
+  EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<EnableOutputQuery>(Q)->Var);
+
+  Q = parse("disable output detailed-ast");
+  ASSERT_TRUE(isa<DisableOutputQuery>(Q));
+  EXPECT_EQ(&QuerySession::DetailedASTOutput, cast<DisableOutputQuery>(Q)->Var);
+
   Q = parse("set bind-root foo");
   ASSERT_TRUE(isa<InvalidQuery>(Q));
   EXPECT_EQ("expected 'true' or 'false', got 'foo'",
@@ -163,7 +171,7 @@
 TEST_F(QueryParserTest, Complete) {
   std::vector<llvm::LineEditor::Completion> Comps =
       QueryParser::complete("", 0, QS);
-  ASSERT_EQ(6u, Comps.size());
+  ASSERT_EQ(8u, Comps.size());
   EXPECT_EQ("help ", Comps[0].TypedText);
   EXPECT_EQ("help", Comps[0].DisplayText);
   EXPECT_EQ("let ", Comps[1].TypedText);
@@ -174,14 +182,35 @@
   EXPECT_EQ("quit", Comps[3].DisplayText);
   EXPECT_EQ("set ", Comps[4].TypedText);
   EXPECT_EQ("set", Comps[4].DisplayText);
-  EXPECT_EQ("unlet ", Comps[5].TypedText);
-  EXPECT_EQ("unlet", Comps[5].DisplayText);
+  EXPECT_EQ("enable ", Comps[5].TypedText);
+  EXPECT_EQ("enable", Comps[5].DisplayText);
+  EXPECT_EQ("disable ", Comps[6].TypedText);
+  EXPECT_EQ("disable", Comps[6].DisplayText);
+  EXPECT_EQ("unlet ", Comps[7].TypedText);
+  EXPECT_EQ("unlet", Comps[7].DisplayText);
 
   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("enable ", 7, QS);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("output ", Comps[0].TypedText);
+  EXPECT_EQ("output", Comps[0].DisplayText);
+
+  Comps = QueryParser::complete("enable output ", 14, QS);
+  ASSERT_EQ(4u, Comps.size());
+
+  EXPECT_EQ("diag ", Comps[0].TypedText);
+  EXPECT_EQ("diag", Comps[0].DisplayText);
+  EXPECT_EQ("print ", Comps[1].TypedText);
+  EXPECT_EQ("print", Comps[1].DisplayText);
+  EXPECT_EQ("detailed-ast ", Comps[2].TypedText);
+  EXPECT_EQ("detailed-ast", Comps[2].DisplayText);
+  EXPECT_EQ("dump ", Comps[3].TypedText);
+  EXPECT_EQ("dump", Comps[3].DisplayText);
+
   Comps = QueryParser::complete("match while", 11, QS);
   ASSERT_EQ(1u, Comps.size());
   EXPECT_EQ("Stmt(", Comps[0].TypedText);
Index: unittests/clang-query/QueryEngineTest.cpp
===================================================================
--- unittests/clang-query/QueryEngineTest.cpp
+++ unittests/clang-query/QueryEngineTest.cpp
@@ -111,6 +111,19 @@
 
   Str.clear();
 
+  EXPECT_TRUE(EnableOutputQuery(&QuerySession::DiagOutput).run(OS, S));
+  EXPECT_TRUE(EnableOutputQuery(&QuerySession::DetailedASTOutput).run(OS, S));
+  EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
+
+  {
+    auto Output = OS.str();
+    EXPECT_TRUE(Output.find("FunctionDecl") != std::string::npos);
+    EXPECT_TRUE(Output.find("foo.cc:1:1: note: \"root\" binds here") !=
+                std::string::npos);
+  }
+
+  Str.clear();
+
   EXPECT_TRUE(SetQuery<bool>(&QuerySession::BindRoot, false).run(OS, S));
   EXPECT_TRUE(MatchQuery(FooMatcherString, FooMatcher).run(OS, S));
 
Index: clang-query/QueryParser.h
===================================================================
--- clang-query/QueryParser.h
+++ clang-query/QueryParser.h
@@ -44,7 +44,7 @@
   template <typename T> struct LexOrCompleteWord;
 
   QueryRef parseSetBool(bool QuerySession::*Var);
-  QueryRef parseSetOutputKind();
+  template <typename QueryType> QueryRef parseSetOutputKind();
   QueryRef completeMatcherExpression();
 
   QueryRef endQuery(QueryRef Q);
Index: clang-query/QueryParser.cpp
===================================================================
--- clang-query/QueryParser.cpp
+++ clang-query/QueryParser.cpp
@@ -106,7 +106,7 @@
   return new SetQuery<bool>(Var, Value);
 }
 
-QueryRef QueryParser::parseSetOutputKind() {
+template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
   StringRef ValStr;
   unsigned OutKind = LexOrCompleteWord<unsigned>(this, ValStr)
                          .Case("diag", OK_Diag)
@@ -122,11 +122,11 @@
 
   switch (OutKind) {
   case OK_DetailedAST:
-    return new SetExclusiveOutputQuery(&QuerySession::DetailedASTOutput);
+    return new QueryType(&QuerySession::DetailedASTOutput);
   case OK_Diag:
-    return new SetExclusiveOutputQuery(&QuerySession::DiagOutput);
+    return new QueryType(&QuerySession::DiagOutput);
   case OK_Print:
-    return new SetExclusiveOutputQuery(&QuerySession::PrintOutput);
+    return new QueryType(&QuerySession::PrintOutput);
   }
 
   llvm_unreachable("Invalid output kind");
@@ -151,7 +151,9 @@
   PQK_Match,
   PQK_Set,
   PQK_Unlet,
-  PQK_Quit
+  PQK_Quit,
+  PQK_Enable,
+  PQK_Disable
 };
 
 enum ParsedQueryVariable {
@@ -193,6 +195,8 @@
                               .Case("q", PQK_Quit,  /*IsCompletion=*/false)
                               .Case("quit", PQK_Quit)
                               .Case("set", PQK_Set)
+                              .Case("enable", PQK_Enable)
+                              .Case("disable", PQK_Disable)
                               .Case("unlet", PQK_Unlet)
                               .Default(PQK_Invalid);
 
@@ -256,7 +260,7 @@
     QueryRef Q;
     switch (Var) {
     case PQV_Output:
-      Q = parseSetOutputKind();
+      Q = parseSetOutputKind<SetExclusiveOutputQuery>();
       break;
     case PQV_BindRoot:
       Q = parseSetBool(&QuerySession::BindRoot);
@@ -270,6 +274,29 @@
 
     return endQuery(Q);
   }
+  case PQK_Enable:
+  case PQK_Disable: {
+    StringRef VarStr;
+    ParsedQueryVariable Var =
+        LexOrCompleteWord<ParsedQueryVariable>(this, VarStr)
+            .Case("output", PQV_Output)
+            .Default(PQV_Invalid);
+    if (VarStr.empty())
+      return new InvalidQuery("expected variable name");
+    if (Var == PQV_Invalid)
+      return new InvalidQuery("unknown variable: '" + VarStr + "'");
+
+    QueryRef Q;
+
+    if (QKind == PQK_Enable) {
+      Q = parseSetOutputKind<EnableOutputQuery>();
+    } else if (QKind == PQK_Disable) {
+      Q = parseSetOutputKind<DisableOutputQuery>();
+    } else {
+      llvm_unreachable("Invalid query kind");
+    }
+    return endQuery(Q);
+  }
 
   case PQK_Unlet: {
     StringRef Name = lexWord();
Index: clang-query/Query.h
===================================================================
--- clang-query/Query.h
+++ clang-query/Query.h
@@ -29,6 +29,8 @@
   QK_Match,
   QK_SetBool,
   QK_SetOutputKind,
+  QK_EnableOutputKind,
+  QK_DisableOutputKind,
   QK_Quit
 };
 
@@ -151,6 +153,36 @@
   bool QuerySession::*Var;
 };
 
+// Implements the non-exclusive 'set output dump|diag|print' options.
+struct SetNonExclusiveOutputQuery : Query {
+  SetNonExclusiveOutputQuery(QueryKind Kind, bool QuerySession::*Var,
+                             bool Value)
+      : Query(Kind), Var(Var), Value(Value) {}
+  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
+    QS.*Var = Value;
+    return true;
+  }
+
+  bool QuerySession::*Var;
+  bool Value;
+};
+
+struct EnableOutputQuery : SetNonExclusiveOutputQuery {
+  EnableOutputQuery(bool QuerySession::*Var)
+      : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}
+
+  static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }
+};
+
+struct DisableOutputQuery : SetNonExclusiveOutputQuery {
+  DisableOutputQuery(bool QuerySession::*Var)
+      : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}
+
+  static bool classof(const Query *Q) {
+    return Q->Kind == QK_DisableOutputKind;
+  }
+};
+
 } // namespace query
 } // namespace clang
 
Index: clang-query/Query.cpp
===================================================================
--- clang-query/Query.cpp
+++ clang-query/Query.cpp
@@ -45,6 +45,10 @@
         "Set whether to print the current matcher,\n"
         "  set output <feature>              "
         "Set whether to output only <feature> content.\n"
+        "  enable output <feature>           "
+        "Enable <feature> content non-exclusively.\n"
+        "  disable output <feature>          "
+        "Disable <feature> content non-exclusively.\n"
         "  quit, q                           "
         "Terminates the query session.\n\n"
         "Several commands accept a <feature> parameter. The available features "
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to