eduucaldas updated this revision to Diff 293386.
eduucaldas added a comment.

- [SyntaxTree] Split `TreeTest` and `ListTest` testing fixtures.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87839/new/

https://reviews.llvm.org/D87839

Files:
  clang/include/clang/Tooling/Syntax/Tree.h
  clang/unittests/Tooling/Syntax/TreeTest.cpp

Index: clang/unittests/Tooling/Syntax/TreeTest.cpp
===================================================================
--- clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -9,6 +9,7 @@
 #include "clang/Tooling/Syntax/Tree.h"
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -122,4 +123,210 @@
   }
 }
 
+class ListTest : public SyntaxTreeTest {
+private:
+  std::string dump(const List::ElementAndDelimiter<Node> &ED) {
+    auto Format = [](StringRef s) { return "'" + s.trim().str() + "'"; };
+
+    std::string Delimiter =
+        ED.delimiter
+            ? Format(ED.delimiter->dumpTokens(Arena->getSourceManager()))
+            : "nul";
+
+    std::string Element =
+        ED.element ? Format(ED.element->dumpTokens(Arena->getSourceManager()))
+                   : "nul";
+
+    return "(" + Element + ", " + Delimiter + ")";
+  }
+
+protected:
+  std::string dump(ArrayRef<List::ElementAndDelimiter<Node>> EDs) {
+    if (EDs.empty())
+      return "[]";
+
+    std::string Storage;
+    llvm::raw_string_ostream OS(Storage);
+
+    OS << "[" << dump(EDs.front());
+    for (auto ED = std::next(EDs.begin()), End = EDs.end(); ED != End; ++ED)
+      OS << ", " << dump(*ED);
+    OS << "]";
+    return OS.str();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(TreeTests, ListTest,
+                        ::testing::ValuesIn(allTestClangConfigs()), );
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", nul)]
+TEST_P(ListTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+      },
+      NodeKind::CallArguments));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', ','), ('b', ','), ('c', nul)]");
+}
+
+/// "a,  , c"  <=> [("a", ","), (nul, ","), ("c", nul)]
+TEST_P(ListTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+      },
+      NodeKind::CallArguments));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', ','), (nul, ','), ('c', nul)]");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+TEST_P(ListTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+      },
+      NodeKind::CallArguments));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', ','), ('b', nul), ('c', nul)]");
+}
+
+/// "a, b,"    <=> [("a", ","), ("b", ","), (nul, nul)]
+TEST_P(ListTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+      },
+      NodeKind::CallArguments));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', ','), ('b', ','), (nul, nul)]");
+}
+
+/// "a:: b:: c::" <=> [("a", "::"), ("b", "::"), ("c", "::")]
+TEST_P(ListTest, List_Terminated_WellFormed) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  buildTree("", GetParam());
+
+  // "a:: b:: c::"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+      },
+      NodeKind::NestedNameSpecifier));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', '::'), ('b', '::'), ('c', '::')]");
+}
+
+/// "a::  :: c::" <=> [("a", "::"), (nul, "::"), ("c", "::")]
+TEST_P(ListTest, List_Terminated_MissingElement) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  buildTree("", GetParam());
+
+  // "a:: b:: c::"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+      },
+      NodeKind::NestedNameSpecifier));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', '::'), (nul, '::'), ('c', '::')]");
+}
+
+/// "a:: b  c::" <=> [("a", "::"), ("b", nul), ("c", "::")]
+TEST_P(ListTest, List_Terminated_MissingDelimiter) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  buildTree("", GetParam());
+
+  // "a:: b  c::"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+      },
+      NodeKind::NestedNameSpecifier));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', '::'), ('b', nul), ('c', '::')]");
+}
+
+/// "a:: b:: c"  <=> [("a", "::"), ("b", "::"), ("c", nul)]
+TEST_P(ListTest, List_Terminated_MissingLastDelimiter) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  buildTree("", GetParam());
+
+  // "a:: b:: c"
+  auto *List = dyn_cast<syntax::List>(syntax::createTree(
+      *Arena,
+      {
+          {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+          {createLeaf(*Arena, tok::coloncolon), NodeRole::ListDelimiter},
+          {createLeaf(*Arena, tok::identifier, "c"), NodeRole::ListElement},
+      },
+      NodeKind::NestedNameSpecifier));
+
+  EXPECT_EQ(dump(List->getElementsAsNodesAndDelimiters()),
+            "[('a', '::'), ('b', '::'), ('c', nul)]");
+}
+
 } // namespace
Index: clang/include/clang/Tooling/Syntax/Tree.h
===================================================================
--- clang/include/clang/Tooling/Syntax/Tree.h
+++ clang/include/clang/Tooling/Syntax/Tree.h
@@ -218,12 +218,16 @@
   /// and delimiters are represented as null pointers.
   ///
   /// For example, in a separated list:
-  /// "a, b, c" <=> [("a", ","), ("b", ","), ("c", null)]
-  /// "a, , c" <=> [("a", ","), (null, ","), ("c", ",)]
-  /// "a, b," <=> [("a", ","), ("b", ","), (null, null)]
+  /// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", nul)]
+  /// "a,  , c"  <=> [("a", ","), (nul, ","), ("c", nul)]
+  /// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+  /// "a, b,"    <=> [("a", ","), ("b", ","), (nul, nul)]
   ///
   /// In a terminated or maybe-terminated list:
-  /// "a, b," <=> [("a", ","), ("b", ",")]
+  /// "a; b; c;" <=> [("a", ";"), ("b", ";"), ("c", ";")]
+  /// "a;  ; c;" <=> [("a", ";"), (nul, ";"), ("c", ";")]
+  /// "a; b  c;" <=> [("a", ";"), ("b", nul), ("c", ";")]
+  /// "a; b; c"  <=> [("a", ";"), ("b", ";"), ("c", nul)]
   std::vector<ElementAndDelimiter<Node>> getElementsAsNodesAndDelimiters();
 
   /// Returns the elements of the list. Missing elements are represented
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to