[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc3c08bfdfd62: [SyntaxTree] Test the List API (authored by 
eduucaldas).

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,8 @@
 #include "clang/Tooling/Syntax/Tree.h"
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "llvm/ADT/STLExtras.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -122,4 +124,231 @@
   }
 }
 
+class ListTest : public SyntaxTreeTest {
+private:
+  std::string dumpQuotedTokensOrNull(const Node *N) {
+return N ? "'" +
+   StringRef(N->dumpTokens(Arena->getSourceManager()))
+   .trim()
+   .str() +
+   "'"
+ : "null";
+  }
+
+protected:
+  std::string
+  dumpElementsAndDelimiters(ArrayRef> EDs) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(
+EDs, OS, [, this](const List::ElementAndDelimiter ) {
+  OS << "(" << dumpQuotedTokensOrNull(ED.element) << ", "
+ << dumpQuotedTokensOrNull(ED.delimiter) << ")";
+});
+
+OS << "]";
+
+return OS.str();
+  }
+
+  std::string dumpNodes(ArrayRef Nodes) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(Nodes, OS, [, this](const Node *N) {
+  OS << dumpQuotedTokensOrNull(N);
+});
+
+OS << "]";
+
+return OS.str();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(TreeTests, ListTest,
+::testing::ValuesIn(allTestClangConfigs()), );
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", null)]
+TEST_P(ListTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']");
+}
+
+/// "a,  , c"  <=> [("a", ","), (null, ","), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), (null, ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', null, 'c']");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", null), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', null), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']");
+}
+
+/// "a, b,"<=> [("a", ","), ("b", ","), (null, null)]
+TEST_P(ListTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(syntax::createTree(
+  *Arena,
+  {
+  {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+  

[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas marked an inline comment as done.
eduucaldas added inline comments.



Comment at: clang/include/clang/Tooling/Syntax/Tree.h:224
+  /// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+  /// "a, b,"<=> [("a", ","), ("b", ","), (nul, nul)]
   ///

gribozavr2 wrote:
> I'd slightly prefer "null" b/c "nul" refers to the ASCII character. Feel free 
> to add more spaces to make columns line up :)
Thanks for providing my solution to my crazyness ^^


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87839

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 293490.
eduucaldas added a comment.

.


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,8 @@
 #include "clang/Tooling/Syntax/Tree.h"
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "llvm/ADT/STLExtras.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -122,4 +124,231 @@
   }
 }
 
+class ListTest : public SyntaxTreeTest {
+private:
+  std::string dumpQuotedTokensOrNull(const Node *N) {
+return N ? "'" +
+   StringRef(N->dumpTokens(Arena->getSourceManager()))
+   .trim()
+   .str() +
+   "'"
+ : "null";
+  }
+
+protected:
+  std::string
+  dumpElementsAndDelimiters(ArrayRef> EDs) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(
+EDs, OS, [, this](const List::ElementAndDelimiter ) {
+  OS << "(" << dumpQuotedTokensOrNull(ED.element) << ", "
+ << dumpQuotedTokensOrNull(ED.delimiter) << ")";
+});
+
+OS << "]";
+
+return OS.str();
+  }
+
+  std::string dumpNodes(ArrayRef Nodes) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(Nodes, OS, [, this](const Node *N) {
+  OS << dumpQuotedTokensOrNull(N);
+});
+
+OS << "]";
+
+return OS.str();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(TreeTests, ListTest,
+::testing::ValuesIn(allTestClangConfigs()), );
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", null)]
+TEST_P(ListTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']");
+}
+
+/// "a,  , c"  <=> [("a", ","), (null, ","), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), (null, ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', null, 'c']");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", null), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', null), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']");
+}
+
+/// "a, b,"<=> [("a", ","), ("b", ","), (null, null)]
+TEST_P(ListTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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},
+  },
+  

[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 293489.
eduucaldas marked 3 inline comments as done.
eduucaldas added a comment.

Answer code review.


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,8 @@
 #include "clang/Tooling/Syntax/Tree.h"
 #include "TreeTestBase.h"
 #include "clang/Tooling/Syntax/BuildTree.h"
+#include "clang/Tooling/Syntax/Nodes.h"
+#include "llvm/ADT/STLExtras.h"
 #include "gtest/gtest.h"
 
 using namespace clang;
@@ -122,4 +124,239 @@
   }
 }
 
+class ListTest : public SyntaxTreeTest {
+private:
+  std::string dumpQuotedTokensOrNull(const Node *N) {
+return N ? "'" +
+   StringRef(N->dumpTokens(Arena->getSourceManager()))
+   .trim()
+   .str() +
+   "'"
+ : "null";
+  }
+
+protected:
+  std::string
+  dumpElementsAndDelimiters(ArrayRef> EDs) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(
+EDs, OS, [, this](const List::ElementAndDelimiter ) {
+  OS << "(" << dumpQuotedTokensOrNull(ED.element) << ", "
+ << dumpQuotedTokensOrNull(ED.delimiter) << ")";
+});
+
+OS << "]";
+
+return OS.str();
+  }
+
+  std::string dumpNodes(ArrayRef Nodes) {
+std::string Storage;
+llvm::raw_string_ostream OS(Storage);
+
+OS << "[";
+
+llvm::interleaveComma(Nodes, OS, [, this](const Node *N) {
+  OS << dumpQuotedTokensOrNull(N);
+});
+
+OS << "]";
+
+return OS.str();
+  }
+};
+
+INSTANTIATE_TEST_CASE_P(TreeTests, ListTest,
+::testing::ValuesIn(allTestClangConfigs()), );
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", null)]
+TEST_P(ListTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()),
+"['a', 'b', 'c']");
+}
+
+/// "a,  , c"  <=> [("a", ","), (null, ","), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), (null, ','), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()),
+"['a', null, 'c']");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", null), ("c", null)]
+TEST_P(ListTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast(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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', null), ('c', null)]");
+  EXPECT_EQ(dumpNodes(List->getElementsAsNodes()),
+"['a', 'b', 'c']");
+}
+
+/// "a, b,"<=> [("a", ","), ("b", ","), (null, null)]
+TEST_P(ListTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(syntax::createTree(
+  *Arena,
+  {
+  {createLeaf(*Arena, tok::identifier, "a"), NodeRole::ListElement},
+  {createLeaf(*Arena, tok::comma), NodeRole::ListDelimiter},
+  {createLeaf(*Arena, tok::identifier, "b"), NodeRole::ListElement},
+ 

[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 added inline comments.



Comment at: clang/include/clang/Tooling/Syntax/Tree.h:224
+  /// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+  /// "a, b,"<=> [("a", ","), ("b", ","), (nul, nul)]
   ///

I'd slightly prefer "null" b/c "nul" refers to the ASCII character. Feel free 
to add more spaces to make columns line up :)



Comment at: clang/unittests/Tooling/Syntax/TreeTest.cpp:129
+  std::string dump(const List::ElementAndDelimiter ) {
+auto Format = [](StringRef s) { return "'" + s.trim().str() + "'"; };
+





Comment at: clang/unittests/Tooling/Syntax/TreeTest.cpp:154
+  OS << ", " << dump(*ED);
+OS << "]";
+return OS.str();

Would llvm::interleaveComma help?



Comment at: clang/unittests/Tooling/Syntax/TreeTest.cpp:330
+"[('a', '::'), ('b', '::'), ('c', nul)]");
+}
+

All of the tests above are testing getElementsAsNodesAndDelimiters -- could you 
put that into the test names? Or do you plan adding more assertions in the end? 
Or is that the only meaningful assertion? (I think not, we could also test the 
low-level non-typed function at least.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87839

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas added a reviewer: gribozavr2.
eduucaldas added a comment.

I made a separate class for the tests on Lists, as it didn't share any methods 
with the tests for Trees. What do you think about that?

Should I also put the tests for lists in a different file, even though 
`TreeTest.cpp` could mean test `Tree.h`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87839

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-22 Thread Eduardo Caldas via Phabricator via cfe-commits
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 ) {
+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> 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::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::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::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::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::createTree(
+  *Arena,
+  {
+  

[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-17 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas updated this revision to Diff 292547.
eduucaldas added a comment.

Apply arc lint patch


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
@@ -13,6 +13,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;
@@ -38,6 +39,7 @@
 return ::testing::AssertionSuccess();
   }
 
+private:
   Tree *createTree(ArrayRef Children) {
 auto ChildrenWithRoles = std::vector>();
 ChildrenWithRoles.reserve(Children.size());
@@ -76,6 +78,7 @@
 return AllForests;
   }
 
+public:
   // Generates all trees with a `Base` layer of `Node`s and `NodeCountPerLayer`
   // `Node`s per layer. An example of Tree with `Base` = {`(`, `)`} and
   // `NodeCountPerLayer` = {2, 2}:
@@ -138,4 +141,201 @@
   }
 }
 
+std::string dump(Arena , const List::ElementAndDelimiter ) {
+  auto Format = [](StringRef s) { return "'" + s.trim().str() + "'"; };
+
+  std::string Delimiter =
+  ED.delimiter ? Format(ED.delimiter->dumpTokens(A.getSourceManager()))
+   : "nul";
+
+  std::string Element =
+  ED.element ? Format(ED.element->dumpTokens(A.getSourceManager())) : "nul";
+
+  return "(" + Element + ", " + Delimiter + ")";
+}
+
+std::string dump(Arena , ArrayRef> EDs) {
+  if (EDs.empty())
+return "[]";
+
+  std::string Storage;
+  llvm::raw_string_ostream OS(Storage);
+
+  OS << "[" << dump(A, EDs.front());
+  for (auto ED = std::next(EDs.begin()), End = EDs.end(); ED != End; ++ED)
+OS << ", " << dump(A, *ED);
+  OS << "]";
+  return OS.str();
+}
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", nul)]
+TEST_P(TreeTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', nul)]");
+}
+
+/// "a,  , c"  <=> [("a", ","), (nul, ","), ("c", nul)]
+TEST_P(TreeTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), (nul, ','), ('c', nul)]");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+TEST_P(TreeTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', nul), ('c', nul)]");
+}
+
+/// "a, b,"<=> [("a", ","), ("b", ","), (nul, nul)]
+TEST_P(TreeTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), (nul, nul)]");
+}
+
+/// "a:: b:: c::" <=> [("a", "::"), ("b", "::"), ("c", "::")]
+TEST_P(TreeTest, 

[PATCH] D87839: [SyntaxTree] Test the List API

2020-09-17 Thread Eduardo Caldas via Phabricator via cfe-commits
eduucaldas created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
eduucaldas requested review of this revision.

Repository:
  rG LLVM Github Monorepo

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
@@ -13,6 +13,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;
@@ -38,6 +39,7 @@
 return ::testing::AssertionSuccess();
   }
 
+private:
   Tree *createTree(ArrayRef Children) {
 auto ChildrenWithRoles = std::vector>();
 ChildrenWithRoles.reserve(Children.size());
@@ -76,6 +78,7 @@
 return AllForests;
   }
 
+public:
   // Generates all trees with a `Base` layer of `Node`s and `NodeCountPerLayer`
   // `Node`s per layer. An example of Tree with `Base` = {`(`, `)`} and
   // `NodeCountPerLayer` = {2, 2}:
@@ -138,4 +141,178 @@
   }
 }
 
+std::string dump(Arena , const List::ElementAndDelimiter ) {
+  auto Format = [](StringRef s) { return "'" + s.trim().str() + "'"; };
+
+  std::string Delimiter =
+  ED.delimiter ? Format(ED.delimiter->dumpTokens(A.getSourceManager()))
+   : "nul";
+
+  std::string Element =
+  ED.element ? Format(ED.element->dumpTokens(A.getSourceManager())) : "nul";
+
+  return "(" + Element + ", " + Delimiter + ")";
+}
+
+std::string dump(Arena , ArrayRef> EDs) {
+  if (EDs.empty())
+return "[]";
+
+  std::string Storage;
+  llvm::raw_string_ostream OS(Storage);
+
+  OS << "[" << dump(A, EDs.front());
+  for (auto ED = std::next(EDs.begin()), End = EDs.end(); ED != End; ++ED)
+OS << ", " << dump(A, *ED);
+  OS << "]";
+  return OS.str();
+}
+
+
+/// "a, b, c"  <=> [("a", ","), ("b", ","), ("c", nul)]
+TEST_P(TreeTest, List_Separated_WellFormed) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), ('c', nul)]");
+}
+
+/// "a,  , c"  <=> [("a", ","), (nul, ","), ("c", nul)]
+TEST_P(TreeTest, List_Separated_MissingElement) {
+  buildTree("", GetParam());
+
+  // "a,  , c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), (nul, ','), ('c', nul)]");
+}
+
+/// "a, b  c"  <=> [("a", ","), ("b", nul), ("c", nul)]
+TEST_P(TreeTest, List_Separated_MissingDelimiter) {
+  buildTree("", GetParam());
+
+  // "a, b  c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', nul), ('c', nul)]");
+}
+
+/// "a, b,"<=> [("a", ","), ("b", ","), (nul, nul)]
+TEST_P(TreeTest, List_Separated_MissingLastElement) {
+  buildTree("", GetParam());
+
+  // "a, b, c"
+  auto *List = dyn_cast(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(*Arena, List->getElementsAsNodesAndDelimiters()),
+"[('a', ','), ('b', ','), (nul, nul)]");
+}
+
+/// "a:: b:: c::" <=> [("a", "::"), ("b", "::"), ("c", "::")]
+TEST_P(TreeTest, List_Terminated_WellFormed) {
+  if (!GetParam().isCXX()) {
+return;
+  }
+  buildTree("", GetParam());
+
+  // "a:: b:: c::"
+  auto *List = dyn_cast(syntax::createTree(*Arena, {
+