xref: /llvm-project/clang/unittests/Tooling/Syntax/SynthesisTest.cpp (revision 7c37b82f5ba5883b331608b0077c0b30bf301874)
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