1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "clang/Tooling/Inclusions/HeaderIncludes.h" |
10 | #include "../Tooling/ReplacementTest.h" |
11 | #include "../Tooling/RewriterTestContext.h" |
12 | #include "clang/Format/Format.h" |
13 | #include "clang/Tooling/Core/Replacement.h" |
14 | |
15 | #include "gtest/gtest.h" |
16 | |
17 | namespace clang { |
18 | namespace tooling { |
19 | namespace { |
20 | |
21 | class : public ::testing::Test { |
22 | protected: |
23 | std::string (llvm::StringRef Code, llvm::StringRef ) { |
24 | HeaderIncludes Includes(FileName, Code, Style); |
25 | (0) . __assert_fail ("Header.startswith(\"\\\"\") || Header.startswith(\"<\")", "/home/seafit/code_projects/clang_source/clang/unittests/Tooling/HeaderIncludesTest.cpp", 25, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Header.startswith("\"") || Header.startswith("<")); |
26 | auto R = Includes.insert(Header.trim("\"<>"), Header.startswith("<")); |
27 | if (!R) |
28 | return Code; |
29 | auto Result = applyAllReplacements(Code, Replacements(*R)); |
30 | EXPECT_TRUE(static_cast<bool>(Result)); |
31 | return *Result; |
32 | } |
33 | |
34 | std::string (llvm::StringRef Code, llvm::StringRef ) { |
35 | HeaderIncludes Includes(FileName, Code, Style); |
36 | (0) . __assert_fail ("Header.startswith(\"\\\"\") || Header.startswith(\"<\")", "/home/seafit/code_projects/clang_source/clang/unittests/Tooling/HeaderIncludesTest.cpp", 36, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Header.startswith("\"") || Header.startswith("<")); |
37 | auto Replaces = Includes.remove(Header.trim("\"<>"), Header.startswith("<")); |
38 | auto Result = applyAllReplacements(Code, Replaces); |
39 | EXPECT_TRUE(static_cast<bool>(Result)); |
40 | return *Result; |
41 | } |
42 | |
43 | const std::string = "fix.cpp"; |
44 | IncludeStyle = format::getLLVMStyle().IncludeStyle; |
45 | }; |
46 | |
47 | (HeaderIncludesTest, NoExistingIncludeWithoutDefine) { |
48 | std::string Code = "int main() {}"; |
49 | std::string Expected = "#include \"a.h\"\n" |
50 | "int main() {}"; |
51 | EXPECT_EQ(Expected, insert(Code, "\"a.h\"")); |
52 | } |
53 | |
54 | (HeaderIncludesTest, NoExistingIncludeWithDefine) { |
55 | std::string Code = "#ifndef A_H\n" |
56 | "#define A_H\n" |
57 | "class A {};\n" |
58 | "#define MMM 123\n" |
59 | "#endif"; |
60 | std::string Expected = "#ifndef A_H\n" |
61 | "#define A_H\n" |
62 | "#include \"b.h\"\n" |
63 | "class A {};\n" |
64 | "#define MMM 123\n" |
65 | "#endif"; |
66 | |
67 | EXPECT_EQ(Expected, insert(Code, "\"b.h\"")); |
68 | } |
69 | |
70 | (HeaderIncludesTest, InsertBeforeCategoryWithLowerPriority) { |
71 | std::string Code = "#ifndef A_H\n" |
72 | "#define A_H\n" |
73 | "\n" |
74 | "\n" |
75 | "\n" |
76 | "#include <vector>\n" |
77 | "class A {};\n" |
78 | "#define MMM 123\n" |
79 | "#endif"; |
80 | std::string Expected = "#ifndef A_H\n" |
81 | "#define A_H\n" |
82 | "\n" |
83 | "\n" |
84 | "\n" |
85 | "#include \"a.h\"\n" |
86 | "#include <vector>\n" |
87 | "class A {};\n" |
88 | "#define MMM 123\n" |
89 | "#endif"; |
90 | |
91 | EXPECT_EQ(Expected, insert(Code, "\"a.h\"")); |
92 | } |
93 | |
94 | (HeaderIncludesTest, InsertAfterMainHeader) { |
95 | std::string Code = "#include \"fix.h\"\n" |
96 | "\n" |
97 | "int main() {}"; |
98 | std::string Expected = "#include \"fix.h\"\n" |
99 | "#include <a>\n" |
100 | "\n" |
101 | "int main() {}"; |
102 | Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp) |
103 | .IncludeStyle; |
104 | EXPECT_EQ(Expected, insert(Code, "<a>")); |
105 | } |
106 | |
107 | (HeaderIncludesTest, InsertBeforeSystemHeaderLLVM) { |
108 | std::string Code = "#include <memory>\n" |
109 | "\n" |
110 | "int main() {}"; |
111 | std::string Expected = "#include \"z.h\"\n" |
112 | "#include <memory>\n" |
113 | "\n" |
114 | "int main() {}"; |
115 | EXPECT_EQ(Expected, insert(Code, "\"z.h\"")); |
116 | } |
117 | |
118 | (HeaderIncludesTest, InsertAfterSystemHeaderGoogle) { |
119 | std::string Code = "#include <memory>\n" |
120 | "\n" |
121 | "int main() {}"; |
122 | std::string Expected = "#include <memory>\n" |
123 | "#include \"z.h\"\n" |
124 | "\n" |
125 | "int main() {}"; |
126 | Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp) |
127 | .IncludeStyle; |
128 | EXPECT_EQ(Expected, insert(Code, "\"z.h\"")); |
129 | } |
130 | |
131 | (HeaderIncludesTest, InsertOneIncludeLLVMStyle) { |
132 | std::string Code = "#include \"x/fix.h\"\n" |
133 | "#include \"a.h\"\n" |
134 | "#include \"b.h\"\n" |
135 | "#include \"clang/Format/Format.h\"\n" |
136 | "#include <memory>\n"; |
137 | std::string Expected = "#include \"x/fix.h\"\n" |
138 | "#include \"a.h\"\n" |
139 | "#include \"b.h\"\n" |
140 | "#include \"clang/Format/Format.h\"\n" |
141 | "#include \"llvm/x/y.h\"\n" |
142 | "#include <memory>\n"; |
143 | EXPECT_EQ(Expected, insert(Code, "\"llvm/x/y.h\"")); |
144 | } |
145 | |
146 | (HeaderIncludesTest, InsertIntoBlockSorted) { |
147 | std::string Code = "#include \"x/fix.h\"\n" |
148 | "#include \"a.h\"\n" |
149 | "#include \"c.h\"\n" |
150 | "#include <memory>\n"; |
151 | std::string Expected = "#include \"x/fix.h\"\n" |
152 | "#include \"a.h\"\n" |
153 | "#include \"b.h\"\n" |
154 | "#include \"c.h\"\n" |
155 | "#include <memory>\n"; |
156 | EXPECT_EQ(Expected, insert(Code, "\"b.h\"")); |
157 | } |
158 | |
159 | (HeaderIncludesTest, InsertIntoFirstBlockOfSameKind) { |
160 | std::string Code = "#include \"x/fix.h\"\n" |
161 | "#include \"c.h\"\n" |
162 | "#include \"e.h\"\n" |
163 | "#include \"f.h\"\n" |
164 | "#include <memory>\n" |
165 | "#include <vector>\n" |
166 | "#include \"m.h\"\n" |
167 | "#include \"n.h\"\n"; |
168 | std::string Expected = "#include \"x/fix.h\"\n" |
169 | "#include \"c.h\"\n" |
170 | "#include \"d.h\"\n" |
171 | "#include \"e.h\"\n" |
172 | "#include \"f.h\"\n" |
173 | "#include <memory>\n" |
174 | "#include <vector>\n" |
175 | "#include \"m.h\"\n" |
176 | "#include \"n.h\"\n"; |
177 | EXPECT_EQ(Expected, insert(Code, "\"d.h\"")); |
178 | } |
179 | |
180 | (HeaderIncludesTest, InsertIntoSystemBlockSorted) { |
181 | std::string Code = "#include \"x/fix.h\"\n" |
182 | "#include \"a.h\"\n" |
183 | "#include \"c.h\"\n" |
184 | "#include <a>\n" |
185 | "#include <z>\n"; |
186 | std::string Expected = "#include \"x/fix.h\"\n" |
187 | "#include \"a.h\"\n" |
188 | "#include \"c.h\"\n" |
189 | "#include <a>\n" |
190 | "#include <vector>\n" |
191 | "#include <z>\n"; |
192 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
193 | } |
194 | |
195 | (HeaderIncludesTest, InsertNewSystemIncludeGoogleStyle) { |
196 | std::string Code = "#include \"x/fix.h\"\n" |
197 | "\n" |
198 | "#include \"y/a.h\"\n" |
199 | "#include \"z/b.h\"\n"; |
200 | |
201 | |
202 | std::string Expected = "#include \"x/fix.h\"\n" |
203 | "#include <vector>\n" |
204 | "\n" |
205 | "#include \"y/a.h\"\n" |
206 | "#include \"z/b.h\"\n"; |
207 | Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp) |
208 | .IncludeStyle; |
209 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
210 | } |
211 | |
212 | (HeaderIncludesTest, NotConfusedByDefine) { |
213 | std::string Code = "void f() {}\n" |
214 | "#define A \\\n" |
215 | " int i;"; |
216 | std::string Expected = "#include <vector>\n" |
217 | "void f() {}\n" |
218 | "#define A \\\n" |
219 | " int i;"; |
220 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
221 | } |
222 | |
223 | (HeaderIncludesTest, SkippedTopComment) { |
224 | std::string Code = "// comment\n" |
225 | "\n" |
226 | " // comment\n"; |
227 | std::string Expected = "// comment\n" |
228 | "\n" |
229 | " // comment\n" |
230 | "#include <vector>\n"; |
231 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
232 | } |
233 | |
234 | (HeaderIncludesTest, SkippedMixedComments) { |
235 | std::string Code = "// comment\n" |
236 | "// comment \\\n" |
237 | " comment continued\n" |
238 | "/*\n" |
239 | "* comment\n" |
240 | "*/\n"; |
241 | std::string Expected = "// comment\n" |
242 | "// comment \\\n" |
243 | " comment continued\n" |
244 | "/*\n" |
245 | "* comment\n" |
246 | "*/\n" |
247 | "#include <vector>\n"; |
248 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
249 | } |
250 | |
251 | (HeaderIncludesTest, MultipleBlockCommentsInOneLine) { |
252 | std::string Code = "/*\n" |
253 | "* comment\n" |
254 | "*/ /* comment\n" |
255 | "*/\n" |
256 | "\n\n" |
257 | "/* c1 */ /*c2 */\n"; |
258 | std::string Expected = "/*\n" |
259 | "* comment\n" |
260 | "*/ /* comment\n" |
261 | "*/\n" |
262 | "\n\n" |
263 | "/* c1 */ /*c2 */\n" |
264 | "#include <vector>\n"; |
265 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
266 | } |
267 | |
268 | (HeaderIncludesTest, CodeAfterComments) { |
269 | std::string Code = "/*\n" |
270 | "* comment\n" |
271 | "*/ /* comment\n" |
272 | "*/\n" |
273 | "\n\n" |
274 | "/* c1 */ /*c2 */\n" |
275 | "\n" |
276 | "int x;\n"; |
277 | std::string Expected = "/*\n" |
278 | "* comment\n" |
279 | "*/ /* comment\n" |
280 | "*/\n" |
281 | "\n\n" |
282 | "/* c1 */ /*c2 */\n" |
283 | "\n" |
284 | "#include <vector>\n" |
285 | "int x;\n"; |
286 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
287 | } |
288 | |
289 | (HeaderIncludesTest, FakeHeaderGuardIfDef) { |
290 | std::string Code = "// comment \n" |
291 | "#ifdef X\n" |
292 | "#define X\n"; |
293 | std::string Expected = "// comment \n" |
294 | "#include <vector>\n" |
295 | "#ifdef X\n" |
296 | "#define X\n"; |
297 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
298 | } |
299 | |
300 | (HeaderIncludesTest, RealHeaderGuardAfterComments) { |
301 | std::string Code = "// comment \n" |
302 | "#ifndef X\n" |
303 | "#define X\n" |
304 | "int x;\n" |
305 | "#define Y 1\n"; |
306 | std::string Expected = "// comment \n" |
307 | "#ifndef X\n" |
308 | "#define X\n" |
309 | "#include <vector>\n" |
310 | "int x;\n" |
311 | "#define Y 1\n"; |
312 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
313 | } |
314 | |
315 | (HeaderIncludesTest, PragmaOnce) { |
316 | std::string Code = "// comment \n" |
317 | "#pragma once\n" |
318 | "int x;\n"; |
319 | std::string Expected = "// comment \n" |
320 | "#pragma once\n" |
321 | "#include <vector>\n" |
322 | "int x;\n"; |
323 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
324 | } |
325 | |
326 | (HeaderIncludesTest, IfNDefWithNoDefine) { |
327 | std::string Code = "// comment \n" |
328 | "#ifndef X\n" |
329 | "int x;\n" |
330 | "#define Y 1\n"; |
331 | std::string Expected = "// comment \n" |
332 | "#include <vector>\n" |
333 | "#ifndef X\n" |
334 | "int x;\n" |
335 | "#define Y 1\n"; |
336 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
337 | } |
338 | |
339 | (HeaderIncludesTest, FakeHeaderGuard) { |
340 | std::string Code = "// comment \n" |
341 | "#ifndef X\n" |
342 | "#define 1\n"; |
343 | std::string Expected = "// comment \n" |
344 | "#include <vector>\n" |
345 | "#ifndef X\n" |
346 | "#define 1\n"; |
347 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
348 | } |
349 | |
350 | (HeaderIncludesTest, HeaderGuardWithComment) { |
351 | std::string Code = "// comment \n" |
352 | "#ifndef X // comment\n" |
353 | "// comment\n" |
354 | "/* comment\n" |
355 | "*/\n" |
356 | "/* comment */ #define X\n" |
357 | "int x;\n" |
358 | "#define Y 1\n"; |
359 | std::string Expected = "// comment \n" |
360 | "#ifndef X // comment\n" |
361 | "// comment\n" |
362 | "/* comment\n" |
363 | "*/\n" |
364 | "/* comment */ #define X\n" |
365 | "#include <vector>\n" |
366 | "int x;\n" |
367 | "#define Y 1\n"; |
368 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
369 | } |
370 | |
371 | (HeaderIncludesTest, EmptyCode) { |
372 | std::string Code = ""; |
373 | std::string Expected = "#include <vector>\n"; |
374 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
375 | } |
376 | |
377 | (HeaderIncludesTest, NoNewLineAtTheEndOfCode) { |
378 | std::string Code = "#include <map>"; |
379 | std::string Expected = "#include <map>\n#include <vector>\n"; |
380 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
381 | } |
382 | |
383 | (HeaderIncludesTest, SkipExistingHeaders) { |
384 | std::string Code = "#include \"a.h\"\n" |
385 | "#include <vector>\n"; |
386 | std::string Expected = "#include \"a.h\"\n" |
387 | "#include <vector>\n"; |
388 | EXPECT_EQ(Expected, insert(Code, "<vector>")); |
389 | EXPECT_EQ(Expected, insert(Code, "\"a.h\"")); |
390 | } |
391 | |
392 | (HeaderIncludesTest, AddIncludesWithDifferentForms) { |
393 | std::string Code = "#include <vector>\n"; |
394 | |
395 | std::string Expected = "#include \"vector\"\n" |
396 | "#include <vector>\n"; |
397 | EXPECT_EQ(Expected, insert(Code, "\"vector\"")); |
398 | } |
399 | |
400 | (HeaderIncludesTest, NoInsertionAfterCode) { |
401 | std::string Code = "#include \"a.h\"\n" |
402 | "void f() {}\n" |
403 | "#include \"b.h\"\n"; |
404 | std::string Expected = "#include \"a.h\"\n" |
405 | "#include \"c.h\"\n" |
406 | "void f() {}\n" |
407 | "#include \"b.h\"\n"; |
408 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); |
409 | } |
410 | |
411 | (HeaderIncludesTest, NoInsertionInStringLiteral) { |
412 | std::string Code = "#include \"a.h\"\n" |
413 | "const char[] = R\"(\n" |
414 | "#include \"b.h\"\n" |
415 | ")\";\n"; |
416 | std::string Expected = "#include \"a.h\"\n" |
417 | "#include \"c.h\"\n" |
418 | "const char[] = R\"(\n" |
419 | "#include \"b.h\"\n" |
420 | ")\";\n"; |
421 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); |
422 | } |
423 | |
424 | (HeaderIncludesTest, NoInsertionAfterOtherDirective) { |
425 | std::string Code = "#include \"a.h\"\n" |
426 | "#ifdef X\n" |
427 | "#include \"b.h\"\n" |
428 | "#endif\n"; |
429 | std::string Expected = "#include \"a.h\"\n" |
430 | "#include \"c.h\"\n" |
431 | "#ifdef X\n" |
432 | "#include \"b.h\"\n" |
433 | "#endif\n"; |
434 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); |
435 | } |
436 | |
437 | (HeaderIncludesTest, CanInsertAfterLongSystemInclude) { |
438 | std::string Code = "#include \"a.h\"\n" |
439 | "// comment\n\n" |
440 | "#include <a/b/c/d/e.h>\n"; |
441 | std::string Expected = "#include \"a.h\"\n" |
442 | "// comment\n\n" |
443 | "#include <a/b/c/d/e.h>\n" |
444 | "#include <x.h>\n"; |
445 | EXPECT_EQ(Expected, insert(Code, "<x.h>")); |
446 | } |
447 | |
448 | (HeaderIncludesTest, CanInsertAfterComment) { |
449 | std::string Code = "#include \"a.h\"\n" |
450 | "// Comment\n" |
451 | "\n" |
452 | "/* Comment */\n" |
453 | "// Comment\n" |
454 | "\n" |
455 | "#include \"b.h\"\n"; |
456 | std::string Expected = "#include \"a.h\"\n" |
457 | "// Comment\n" |
458 | "\n" |
459 | "/* Comment */\n" |
460 | "// Comment\n" |
461 | "\n" |
462 | "#include \"b.h\"\n" |
463 | "#include \"c.h\"\n"; |
464 | EXPECT_EQ(Expected, insert(Code, "\"c.h\"")); |
465 | } |
466 | |
467 | (HeaderIncludesTest, LongCommentsInTheBeginningOfFile) { |
468 | std::string Code = "// Loooooooooooooooooooooooooong comment\n" |
469 | "// Loooooooooooooooooooooooooong comment\n" |
470 | "// Loooooooooooooooooooooooooong comment\n" |
471 | "#include <string>\n" |
472 | "#include <vector>\n" |
473 | "\n" |
474 | "#include \"a.h\"\n" |
475 | "#include \"b.h\"\n"; |
476 | std::string Expected = "// Loooooooooooooooooooooooooong comment\n" |
477 | "// Loooooooooooooooooooooooooong comment\n" |
478 | "// Loooooooooooooooooooooooooong comment\n" |
479 | "#include <string>\n" |
480 | "#include <vector>\n" |
481 | "\n" |
482 | "#include \"a.h\"\n" |
483 | "#include \"b.h\"\n" |
484 | "#include \"third.h\"\n"; |
485 | Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp) |
486 | .IncludeStyle; |
487 | EXPECT_EQ(Expected, insert(Code, "\"third.h\"")); |
488 | } |
489 | |
490 | (HeaderIncludesTest, SimpleDeleteInclude) { |
491 | std::string Code = "#include \"abc.h\"\n" |
492 | "#include \"xyz.h\" // comment\n" |
493 | "int x;\n"; |
494 | std::string Expected = "#include \"abc.h\"\n" |
495 | "int x;\n"; |
496 | EXPECT_EQ(Expected, remove(Code, "\"xyz.h\"")); |
497 | } |
498 | |
499 | (HeaderIncludesTest, DeleteQuotedOnly) { |
500 | std::string Code = "#include \"abc.h\"\n" |
501 | "#include <abc.h>\n" |
502 | "int x;\n"; |
503 | std::string Expected = "#include <abc.h>\n" |
504 | "int x;\n"; |
505 | EXPECT_EQ(Expected, remove(Code, "\"abc.h\"")); |
506 | } |
507 | |
508 | (HeaderIncludesTest, DeleteAllCode) { |
509 | std::string Code = "#include \"xyz.h\"\n"; |
510 | std::string Expected = ""; |
511 | EXPECT_EQ(Expected, remove(Code, "\"xyz.h\"")); |
512 | } |
513 | |
514 | (HeaderIncludesTest, DeleteOnlyIncludesWithSameQuote) { |
515 | std::string Code = "#include \"xyz.h\"\n" |
516 | "#include \"xyz\"\n" |
517 | "#include <xyz.h>\n"; |
518 | std::string Expected = "#include \"xyz.h\"\n" |
519 | "#include \"xyz\"\n"; |
520 | EXPECT_EQ(Expected, remove(Code, "<xyz.h>")); |
521 | } |
522 | |
523 | (HeaderIncludesTest, CanDeleteAfterCode) { |
524 | std::string Code = "#include \"a.h\"\n" |
525 | "void f() {}\n" |
526 | "#include \"b.h\"\n"; |
527 | std::string Expected = "#include \"a.h\"\n" |
528 | "void f() {}\n"; |
529 | EXPECT_EQ(Expected, remove(Code, "\"b.h\"")); |
530 | } |
531 | |
532 | } |
533 | } |
534 | } |
535 | |