[PATCH] D87839: [SyntaxTree] Test the List API
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
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
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
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
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
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
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
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
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, { +