1 //===- SynthesisTest.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file tests synthesis API for syntax trees. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "TreeTestBase.h" 14 #include "clang/Tooling/Syntax/BuildTree.h" 15 #include "clang/Tooling/Syntax/Nodes.h" 16 #include "gtest/gtest.h" 17 18 using namespace clang; 19 using namespace clang::syntax; 20 21 namespace { 22 23 class SynthesisTest : public SyntaxTreeTest { 24 protected: 25 ::testing::AssertionResult treeDumpEqual(syntax::Node *Root, StringRef Dump) { 26 if (!Root) 27 return ::testing::AssertionFailure() 28 << "Root was not built successfully."; 29 30 auto Actual = StringRef(Root->dump(Arena->getSourceManager())).trim().str(); 31 auto Expected = Dump.trim().str(); 32 // EXPECT_EQ shows the diff between the two strings if they are different. 33 EXPECT_EQ(Expected, Actual); 34 if (Actual != Expected) { 35 return ::testing::AssertionFailure(); 36 } 37 return ::testing::AssertionSuccess(); 38 } 39 }; 40 41 INSTANTIATE_TEST_CASE_P(SynthesisTests, SynthesisTest, 42 ::testing::ValuesIn(allTestClangConfigs()), ); 43 44 TEST_P(SynthesisTest, Leaf_Punctuation) { 45 buildTree("", GetParam()); 46 47 auto *Leaf = createLeaf(*Arena, tok::comma); 48 49 EXPECT_TRUE(treeDumpEqual(Leaf, R"txt( 50 ',' Detached synthesized 51 )txt")); 52 } 53 54 TEST_P(SynthesisTest, Leaf_Keyword) { 55 buildTree("", GetParam()); 56 57 auto *Leaf = createLeaf(*Arena, tok::kw_if); 58 59 EXPECT_TRUE(treeDumpEqual(Leaf, R"txt( 60 'if' Detached synthesized 61 )txt")); 62 } 63 64 TEST_P(SynthesisTest, Leaf_Identifier) { 65 buildTree("", GetParam()); 66 67 auto *Leaf = createLeaf(*Arena, tok::identifier, "a"); 68 69 EXPECT_TRUE(treeDumpEqual(Leaf, R"txt( 70 'a' Detached synthesized 71 )txt")); 72 } 73 74 TEST_P(SynthesisTest, Leaf_Number) { 75 buildTree("", GetParam()); 76 77 auto *Leaf = createLeaf(*Arena, tok::numeric_constant, "1"); 78 79 EXPECT_TRUE(treeDumpEqual(Leaf, R"txt( 80 '1' Detached synthesized 81 )txt")); 82 } 83 84 TEST_P(SynthesisTest, Tree_Empty) { 85 buildTree("", GetParam()); 86 87 auto *Tree = createTree(*Arena, {}, NodeKind::UnknownExpression); 88 89 EXPECT_TRUE(treeDumpEqual(Tree, R"txt( 90 UnknownExpression Detached synthesized 91 )txt")); 92 } 93 94 TEST_P(SynthesisTest, Tree_Flat) { 95 buildTree("", GetParam()); 96 97 auto *LeafLParen = createLeaf(*Arena, tok::l_paren); 98 auto *LeafRParen = createLeaf(*Arena, tok::r_paren); 99 auto *TreeParen = createTree(*Arena, 100 {{LeafLParen, NodeRole::LeftHandSide}, 101 {LeafRParen, NodeRole::RightHandSide}}, 102 NodeKind::ParenExpression); 103 104 EXPECT_TRUE(treeDumpEqual(TreeParen, R"txt( 105 ParenExpression Detached synthesized 106 |-'(' LeftHandSide synthesized 107 `-')' RightHandSide synthesized 108 )txt")); 109 } 110 111 TEST_P(SynthesisTest, Tree_OfTree) { 112 buildTree("", GetParam()); 113 114 auto *Leaf1 = createLeaf(*Arena, tok::numeric_constant, "1"); 115 auto *Int1 = createTree(*Arena, {{Leaf1, NodeRole::LiteralToken}}, 116 NodeKind::IntegerLiteralExpression); 117 118 auto *LeafPlus = createLeaf(*Arena, tok::plus); 119 120 auto *Leaf2 = createLeaf(*Arena, tok::numeric_constant, "2"); 121 auto *Int2 = createTree(*Arena, {{Leaf2, NodeRole::LiteralToken}}, 122 NodeKind::IntegerLiteralExpression); 123 124 auto *TreeBinaryOperator = createTree(*Arena, 125 {{Int1, NodeRole::LeftHandSide}, 126 {LeafPlus, NodeRole::OperatorToken}, 127 {Int2, NodeRole::RightHandSide}}, 128 NodeKind::BinaryOperatorExpression); 129 130 EXPECT_TRUE(treeDumpEqual(TreeBinaryOperator, R"txt( 131 BinaryOperatorExpression Detached synthesized 132 |-IntegerLiteralExpression LeftHandSide synthesized 133 | `-'1' LiteralToken synthesized 134 |-'+' OperatorToken synthesized 135 `-IntegerLiteralExpression RightHandSide synthesized 136 `-'2' LiteralToken synthesized 137 )txt")); 138 } 139 140 TEST_P(SynthesisTest, Statement_EmptyStatement) { 141 buildTree("", GetParam()); 142 143 auto *S = createEmptyStatement(*Arena); 144 EXPECT_TRUE(treeDumpEqual(S, R"txt( 145 EmptyStatement Detached synthesized 146 `-';' synthesized 147 )txt")); 148 } 149 } // namespace 150