1 //===-- FormatTests.cpp - Automatic code formatting tests -----------------===//
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 #include "Format.h"
10 #include "Annotations.h"
11 #include "SourceCode.h"
12 #include "TestFS.h"
13 #include "clang/Format/Format.h"
14 #include "clang/Tooling/Core/Replacement.h"
15 #include "llvm/Support/Error.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 
19 namespace clang {
20 namespace clangd {
21 namespace {
22 
afterTyped(llvm::StringRef CodeWithCursor,llvm::StringRef Typed)23 std::string afterTyped(llvm::StringRef CodeWithCursor,
24                            llvm::StringRef Typed) {
25   Annotations Code(CodeWithCursor);
26   unsigned Cursor = llvm::cantFail(positionToOffset(Code.code(), Code.point()));
27   auto Changes =
28       formatIncremental(Code.code(), Cursor, Typed,
29                         format::getGoogleStyle(format::FormatStyle::LK_Cpp));
30   tooling::Replacements Merged;
31   for (const auto& R : Changes)
32     if (llvm::Error E = Merged.add(R))
33       ADD_FAILURE() << llvm::toString(std::move(E));
34   auto NewCode = tooling::applyAllReplacements(Code.code(), Merged);
35   EXPECT_TRUE(bool(NewCode))
36       << "Bad replacements: " << llvm::toString(NewCode.takeError());
37   NewCode->insert(transformCursorPosition(Cursor, Changes), "^");
38   return *NewCode;
39 }
40 
41 // We can't pass raw strings directly to EXPECT_EQ because of gcc bugs.
expectAfterNewline(const char * Before,const char * After)42 void expectAfterNewline(const char *Before, const char *After) {
43   EXPECT_EQ(After, afterTyped(Before, "\n")) << Before;
44 }
expectAfter(const char * Typed,const char * Before,const char * After)45 void expectAfter(const char *Typed, const char *Before, const char *After) {
46   EXPECT_EQ(After, afterTyped(Before, Typed)) << Before;
47 }
48 
TEST(FormatIncremental,SplitComment)49 TEST(FormatIncremental, SplitComment) {
50   expectAfterNewline(R"cpp(
51 // this comment was
52 ^split
53 )cpp",
54    R"cpp(
55 // this comment was
56 // ^split
57 )cpp");
58 
59   expectAfterNewline(R"cpp(
60 // trailing whitespace is not a split
61 ^
62 )cpp",
63    R"cpp(
64 // trailing whitespace is not a split
65 ^
66 )cpp");
67 
68   expectAfterNewline(R"cpp(
69 // splitting a
70 ^
71 // multiline comment
72 )cpp",
73                      R"cpp(
74 // splitting a
75 // ^
76 // multiline comment
77 )cpp");
78 
79   expectAfterNewline(R"cpp(
80 // extra
81     ^     whitespace
82 )cpp",
83    R"cpp(
84 // extra
85 // ^whitespace
86 )cpp");
87 
88   expectAfterNewline(R"cpp(
89 /// triple
90 ^slash
91 )cpp",
92    R"cpp(
93 /// triple
94 /// ^slash
95 )cpp");
96 
97   expectAfterNewline(R"cpp(
98 /// editor continuation
99 //^
100 )cpp",
101    R"cpp(
102 /// editor continuation
103 /// ^
104 )cpp");
105 
106   expectAfterNewline(R"cpp(
107 // break before
108 ^ // slashes
109 )cpp",
110    R"cpp(
111 // break before
112 ^// slashes
113 )cpp");
114 
115 
116   expectAfterNewline(R"cpp(
117 int x;  // aligned
118 ^comment
119 )cpp",
120    R"cpp(
121 int x;  // aligned
122         // ^comment
123 )cpp");
124 
125   // Fixed bug: the second line of the aligned comment shouldn't be "attached"
126   // to the cursor and outdented.
127   expectAfterNewline(R"cpp(
128 void foo() {
129   if (x)
130     return; // All spelled tokens are accounted for.
131             // that takes two lines
132             ^
133 }
134 )cpp",
135    R"cpp(
136 void foo() {
137   if (x)
138     return;  // All spelled tokens are accounted for.
139              // that takes two lines
140   ^
141 }
142 )cpp");
143 }
144 
TEST(FormatIncremental,Indentation)145 TEST(FormatIncremental, Indentation) {
146   expectAfterNewline(R"cpp(
147 void foo() {
148   if (bar)
149 ^
150 )cpp",
151    R"cpp(
152 void foo() {
153   if (bar)
154     ^
155 )cpp");
156 
157   expectAfterNewline(R"cpp(
158 void foo() {
159   bar(baz(
160 ^
161 )cpp",
162    R"cpp(
163 void foo() {
164   bar(baz(
165       ^
166 )cpp");
167 
168   expectAfterNewline(R"cpp(
169 void foo() {
170 ^}
171 )cpp",
172    R"cpp(
173 void foo() {
174   ^
175 }
176 )cpp");
177 
178   expectAfterNewline(R"cpp(
179 class X {
180 protected:
181 ^
182 )cpp",
183    R"cpp(
184 class X {
185  protected:
186   ^
187 )cpp");
188 
189 // Mismatched brackets (1)
190   expectAfterNewline(R"cpp(
191 void foo() {
192   foo{bar(
193 ^}
194 }
195 )cpp",
196    R"cpp(
197 void foo() {
198   foo {
199     bar(
200         ^}
201 }
202 )cpp");
203 // Mismatched brackets (2)
204   expectAfterNewline(R"cpp(
205 void foo() {
206   foo{bar(
207 ^text}
208 }
209 )cpp",
210    R"cpp(
211 void foo() {
212   foo {
213     bar(
214         ^text}
215 }
216 )cpp");
217 // Matched brackets
218   expectAfterNewline(R"cpp(
219 void foo() {
220   foo{bar(
221 ^)
222 }
223 )cpp",
224    R"cpp(
225 void foo() {
226   foo {
227     bar(
228         ^)
229 }
230 )cpp");
231 }
232 
TEST(FormatIncremental,FormatPreviousLine)233 TEST(FormatIncremental, FormatPreviousLine) {
234   expectAfterNewline(R"cpp(
235 void foo() {
236    untouched( );
237 int x=2;
238 ^
239 )cpp",
240                      R"cpp(
241 void foo() {
242    untouched( );
243    int x = 2;
244    ^
245 )cpp");
246 
247   expectAfterNewline(R"cpp(
248 int x=untouched( );
249 auto L = []{return;return;};
250 ^
251 )cpp",
252    R"cpp(
253 int x=untouched( );
254 auto L = [] {
255   return;
256   return;
257 };
258 ^
259 )cpp");
260 }
261 
TEST(FormatIncremental,Annoyances)262 TEST(FormatIncremental, Annoyances) {
263   // Don't remove newlines the user typed!
264   expectAfterNewline(R"cpp(
265 int x(){
266 
267 
268 ^
269 }
270 )cpp",
271    R"cpp(
272 int x(){
273 
274 
275   ^
276 }
277 )cpp");
278   // FIXME: we should not remove newlines here, either.
279   expectAfterNewline(R"cpp(
280 class x{
281  public:
282 
283 ^
284 }
285 )cpp",
286    R"cpp(
287 class x{
288  public:
289   ^
290 }
291 )cpp");
292 }
293 
TEST(FormatIncremental,FormatBrace)294 TEST(FormatIncremental, FormatBrace) {
295   expectAfter("}", R"cpp(
296 vector<int> x= {
297   1,
298   2,
299   3}^
300 )cpp",
301               R"cpp(
302 vector<int> x = {1, 2, 3}^
303 )cpp");
304 }
305 
306 } // namespace
307 } // namespace clangd
308 } // namespace clang
309