diff options
author | Eduardo Caldas <ecaldas@google.com> | 2020-09-17 15:31:30 +0000 |
---|---|---|
committer | Eduardo Caldas <ecaldas@google.com> | 2020-09-22 17:07:41 +0000 |
commit | c3c08bfdfd6244e0429753ee56df39c90187d772 (patch) | |
tree | 9768938067970f242a0af118d75c256c0d273421 /clang/unittests/Tooling/Syntax/TreeTest.cpp | |
parent | 2a6db92ca97da946307b559e63c6ac75caf4bbd6 (diff) | |
download | llvm-c3c08bfdfd6244e0429753ee56df39c90187d772.zip llvm-c3c08bfdfd6244e0429753ee56df39c90187d772.tar.gz llvm-c3c08bfdfd6244e0429753ee56df39c90187d772.tar.bz2 |
[SyntaxTree] Test the List API
Differential Revision: https://reviews.llvm.org/D87839
Diffstat (limited to 'clang/unittests/Tooling/Syntax/TreeTest.cpp')
-rw-r--r-- | clang/unittests/Tooling/Syntax/TreeTest.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp index 6e777b3..fba3164 100644 --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/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 @@ TEST_P(TreeTest, LastLeaf) { } } +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<List::ElementAndDelimiter<Node>> EDs) { + std::string Storage; + llvm::raw_string_ostream OS(Storage); + + OS << "["; + + llvm::interleaveComma( + EDs, OS, [&OS, this](const List::ElementAndDelimiter<Node> &ED) { + OS << "(" << dumpQuotedTokensOrNull(ED.element) << ", " + << dumpQuotedTokensOrNull(ED.delimiter) << ")"; + }); + + OS << "]"; + + return OS.str(); + } + + std::string dumpNodes(ArrayRef<Node *> Nodes) { + std::string Storage; + llvm::raw_string_ostream OS(Storage); + + OS << "["; + + llvm::interleaveComma(Nodes, OS, [&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::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(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::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(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::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(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::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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()), + "[('a', ','), ('b', ','), (null, null)]"); + EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', null]"); +} + +/// "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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()), + "[('a', '::'), ('b', '::'), ('c', '::')]"); + EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']"); +} + +/// "a:: :: c::" <=> [("a", "::"), (null, "::"), ("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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()), + "[('a', '::'), (null, '::'), ('c', '::')]"); + EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', null, 'c']"); +} + +/// "a:: b c::" <=> [("a", "::"), ("b", null), ("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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()), + "[('a', '::'), ('b', null), ('c', '::')]"); + EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']"); +} + +/// "a:: b:: c" <=> [("a", "::"), ("b", "::"), ("c", null)] +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(dumpElementsAndDelimiters(List->getElementsAsNodesAndDelimiters()), + "[('a', '::'), ('b', '::'), ('c', null)]"); + EXPECT_EQ(dumpNodes(List->getElementsAsNodes()), "['a', 'b', 'c']"); +} + } // namespace |