CleanupTest.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. //===- unittest/Format/CleanupTest.cpp - Code cleanup unit tests ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/Format/Format.h"
  10. #include "../Tooling/ReplacementTest.h"
  11. #include "../Tooling/RewriterTestContext.h"
  12. #include "clang/Tooling/Core/Replacement.h"
  13. #include "gtest/gtest.h"
  14. using clang::tooling::ReplacementTest;
  15. using clang::tooling::toReplacements;
  16. namespace clang {
  17. namespace format {
  18. namespace {
  19. class CleanupTest : public ::testing::Test {
  20. protected:
  21. std::string cleanup(llvm::StringRef Code,
  22. const std::vector<tooling::Range> &Ranges,
  23. const FormatStyle &Style = getLLVMStyle()) {
  24. tooling::Replacements Replaces = format::cleanup(Style, Code, Ranges);
  25. auto Result = applyAllReplacements(Code, Replaces);
  26. EXPECT_TRUE(static_cast<bool>(Result));
  27. return *Result;
  28. }
  29. // Returns code after cleanup around \p Offsets.
  30. std::string cleanupAroundOffsets(llvm::ArrayRef<unsigned> Offsets,
  31. llvm::StringRef Code) {
  32. std::vector<tooling::Range> Ranges;
  33. for (auto Offset : Offsets)
  34. Ranges.push_back(tooling::Range(Offset, 0));
  35. return cleanup(Code, Ranges);
  36. }
  37. };
  38. TEST_F(CleanupTest, DeleteEmptyNamespaces) {
  39. std::string Code = "namespace A {\n"
  40. "namespace B {\n"
  41. "} // namespace B\n"
  42. "} // namespace A\n\n"
  43. "namespace C {\n"
  44. "namespace D { int i; }\n"
  45. "inline namespace E { namespace { } }\n"
  46. "}";
  47. std::string Expected = "\n\n\n\n\nnamespace C {\n"
  48. "namespace D { int i; }\n \n"
  49. "}";
  50. EXPECT_EQ(Expected, cleanupAroundOffsets({28, 91, 132}, Code));
  51. }
  52. TEST_F(CleanupTest, NamespaceWithSyntaxError) {
  53. std::string Code = "namespace A {\n"
  54. "namespace B {\n" // missing r_brace
  55. "} // namespace A\n\n"
  56. "namespace C {\n"
  57. "namespace D int i; }\n"
  58. "inline namespace E { namespace { } }\n"
  59. "}";
  60. std::string Expected = "namespace A {\n"
  61. "\n\n\nnamespace C {\n"
  62. "namespace D int i; }\n \n"
  63. "}";
  64. std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
  65. EXPECT_EQ(Expected, cleanup(Code, Ranges));
  66. }
  67. TEST_F(CleanupTest, EmptyNamespaceNotAffected) {
  68. std::string Code = "namespace A {\n\n"
  69. "namespace {\n\n}}";
  70. // Even though the namespaces are empty, but the inner most empty namespace
  71. // block is not affected by the changed ranges.
  72. std::string Expected = "namespace A {\n\n"
  73. "namespace {\n\n}}";
  74. // Set the changed range to be the second "\n".
  75. EXPECT_EQ(Expected, cleanupAroundOffsets({14}, Code));
  76. }
  77. TEST_F(CleanupTest, EmptyNamespaceWithCommentsNoBreakBeforeBrace) {
  78. std::string Code = "namespace A {\n"
  79. "namespace B {\n"
  80. "// Yo\n"
  81. "} // namespace B\n"
  82. "} // namespace A\n"
  83. "namespace C { // Yo\n"
  84. "}";
  85. std::string Expected = "\n\n\n\n\n\n";
  86. std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
  87. std::string Result = cleanup(Code, Ranges);
  88. EXPECT_EQ(Expected, Result);
  89. }
  90. TEST_F(CleanupTest, EmptyNamespaceWithCommentsBreakBeforeBrace) {
  91. std::string Code = "namespace A\n"
  92. "/* Yo */ {\n"
  93. "namespace B\n"
  94. "{\n"
  95. "// Yo\n"
  96. "} // namespace B\n"
  97. "} // namespace A\n"
  98. "namespace C\n"
  99. "{ // Yo\n"
  100. "}\n";
  101. std::string Expected = "\n\n\n\n\n\n\n\n\n\n";
  102. std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
  103. FormatStyle Style = getLLVMStyle();
  104. Style.BraceWrapping.AfterNamespace = true;
  105. std::string Result = cleanup(Code, Ranges, Style);
  106. EXPECT_EQ(Expected, Result);
  107. }
  108. TEST_F(CleanupTest, EmptyNamespaceAroundConditionalCompilation) {
  109. std::string Code = "#ifdef A\n"
  110. "int a;\n"
  111. "int b;\n"
  112. "#else\n"
  113. "#endif\n"
  114. "namespace {}";
  115. std::string Expected = "#ifdef A\n"
  116. "int a;\n"
  117. "int b;\n"
  118. "#else\n"
  119. "#endif\n";
  120. std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
  121. FormatStyle Style = getLLVMStyle();
  122. std::string Result = cleanup(Code, Ranges, Style);
  123. EXPECT_EQ(Expected, Result);
  124. }
  125. TEST_F(CleanupTest, CtorInitializationSimpleRedundantComma) {
  126. std::string Code = "class A {\nA() : , {} };";
  127. std::string Expected = "class A {\nA() {} };";
  128. EXPECT_EQ(Expected, cleanupAroundOffsets({17, 19}, Code));
  129. Code = "class A {\nA() : x(1), {} };";
  130. Expected = "class A {\nA() : x(1) {} };";
  131. EXPECT_EQ(Expected, cleanupAroundOffsets({23}, Code));
  132. Code = "class A {\nA() :,,,,{} };";
  133. Expected = "class A {\nA() {} };";
  134. EXPECT_EQ(Expected, cleanupAroundOffsets({15}, Code));
  135. }
  136. TEST_F(CleanupTest, CtorInitializationSimpleRedundantColon) {
  137. std::string Code = "class A {\nA() : =default; };";
  138. std::string Expected = "class A {\nA() =default; };";
  139. EXPECT_EQ(Expected, cleanupAroundOffsets({15}, Code));
  140. Code = "class A {\nA() : , =default; };";
  141. Expected = "class A {\nA() =default; };";
  142. EXPECT_EQ(Expected, cleanupAroundOffsets({15}, Code));
  143. }
  144. TEST_F(CleanupTest, ListRedundantComma) {
  145. std::string Code = "void f() { std::vector<int> v = {1,2,,,3,{4,5}}; }";
  146. std::string Expected = "void f() { std::vector<int> v = {1,2,3,{4,5}}; }";
  147. EXPECT_EQ(Expected, cleanupAroundOffsets({40}, Code));
  148. Code = "int main() { f(1,,2,3,,4);}";
  149. Expected = "int main() { f(1,2,3,4);}";
  150. EXPECT_EQ(Expected, cleanupAroundOffsets({17, 22}, Code));
  151. }
  152. TEST_F(CleanupTest, TrailingCommaInParens) {
  153. std::string Code = "int main() { f(,1,,2,3,f(1,2,),4,,);}";
  154. std::string Expected = "int main() { f(1,2,3,f(1,2),4);}";
  155. EXPECT_EQ(Expected, cleanupAroundOffsets({15, 18, 29, 33}, Code));
  156. }
  157. TEST_F(CleanupTest, TrailingCommaInBraces) {
  158. // Trainling comma is allowed in brace list.
  159. // If there was trailing comma in the original code, then trailing comma is
  160. // preserved. In this example, element between the last two commas is deleted
  161. // causing the second-last comma to be redundant.
  162. std::string Code = "void f() { std::vector<int> v = {1,2,3,,}; }";
  163. std::string Expected = "void f() { std::vector<int> v = {1,2,3,}; }";
  164. EXPECT_EQ(Expected, cleanupAroundOffsets({39}, Code));
  165. // If there was no trailing comma in the original code, then trainling comma
  166. // introduced by replacements should be cleaned up. In this example, the
  167. // element after the last comma is deleted causing the last comma to be
  168. // redundant.
  169. Code = "void f() { std::vector<int> v = {1,2,3,}; }";
  170. // FIXME: redundant trailing comma should be removed.
  171. Expected = "void f() { std::vector<int> v = {1,2,3,}; }";
  172. EXPECT_EQ(Expected, cleanupAroundOffsets({39}, Code));
  173. // Still no trailing comma in the original code, but two elements are deleted,
  174. // which makes it seems like there was trailing comma.
  175. Code = "void f() { std::vector<int> v = {1, 2, 3, , }; }";
  176. // FIXME: redundant trailing comma should also be removed.
  177. Expected = "void f() { std::vector<int> v = {1, 2, 3, }; }";
  178. EXPECT_EQ(Expected, cleanupAroundOffsets({42, 44}, Code));
  179. }
  180. TEST_F(CleanupTest, CtorInitializationBracesInParens) {
  181. std::string Code = "class A {\nA() : x({1}),, {} };";
  182. std::string Expected = "class A {\nA() : x({1}) {} };";
  183. EXPECT_EQ(Expected, cleanupAroundOffsets({24, 26}, Code));
  184. }
  185. TEST_F(CleanupTest, RedundantCommaNotInAffectedRanges) {
  186. std::string Code =
  187. "class A {\nA() : x({1}), /* comment */, { int x = 0; } };";
  188. std::string Expected =
  189. "class A {\nA() : x({1}), /* comment */, { int x = 0; } };";
  190. // Set the affected range to be "int x = 0", which does not intercept the
  191. // constructor initialization list.
  192. std::vector<tooling::Range> Ranges(1, tooling::Range(42, 9));
  193. std::string Result = cleanup(Code, Ranges);
  194. EXPECT_EQ(Expected, Result);
  195. Code = "class A {\nA() : x(1), {} };";
  196. Expected = "class A {\nA() : x(1), {} };";
  197. // No range. Fixer should do nothing.
  198. Ranges.clear();
  199. Result = cleanup(Code, Ranges);
  200. EXPECT_EQ(Expected, Result);
  201. }
  202. TEST_F(CleanupTest, RemoveCommentsAroundDeleteCode) {
  203. std::string Code =
  204. "class A {\nA() : x({1}), /* comment */, /* comment */ {} };";
  205. std::string Expected = "class A {\nA() : x({1}) {} };";
  206. EXPECT_EQ(Expected, cleanupAroundOffsets({25, 40}, Code));
  207. Code = "class A {\nA() : x({1}), // comment\n {} };";
  208. Expected = "class A {\nA() : x({1})\n {} };";
  209. EXPECT_EQ(Expected, cleanupAroundOffsets({25}, Code));
  210. Code = "class A {\nA() : x({1}), // comment\n , y(1),{} };";
  211. Expected = "class A {\nA() : x({1}), y(1){} };";
  212. EXPECT_EQ(Expected, cleanupAroundOffsets({38}, Code));
  213. Code = "class A {\nA() : x({1}), \n/* comment */, y(1),{} };";
  214. Expected = "class A {\nA() : x({1}), \n y(1){} };";
  215. EXPECT_EQ(Expected, cleanupAroundOffsets({40}, Code));
  216. Code = "class A {\nA() : , // comment\n y(1),{} };";
  217. Expected = "class A {\nA() : // comment\n y(1){} };";
  218. EXPECT_EQ(Expected, cleanupAroundOffsets({17}, Code));
  219. Code = "class A {\nA() // comment\n : ,,{} };";
  220. Expected = "class A {\nA() // comment\n {} };";
  221. EXPECT_EQ(Expected, cleanupAroundOffsets({30}, Code));
  222. Code = "class A {\nA() // comment\n : ,,=default; };";
  223. Expected = "class A {\nA() // comment\n =default; };";
  224. EXPECT_EQ(Expected, cleanupAroundOffsets({30}, Code));
  225. }
  226. TEST_F(CleanupTest, CtorInitializerInNamespace) {
  227. std::string Code = "namespace A {\n"
  228. "namespace B {\n" // missing r_brace
  229. "} // namespace A\n\n"
  230. "namespace C {\n"
  231. "class A { A() : x(0),, {} };\n"
  232. "inline namespace E { namespace { } }\n"
  233. "}";
  234. std::string Expected = "namespace A {\n"
  235. "\n\n\nnamespace C {\n"
  236. "class A { A() : x(0) {} };\n \n"
  237. "}";
  238. std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
  239. std::string Result = cleanup(Code, Ranges);
  240. EXPECT_EQ(Expected, Result);
  241. }
  242. class CleanUpReplacementsTest : public ReplacementTest {
  243. protected:
  244. tooling::Replacement createReplacement(unsigned Offset, unsigned Length,
  245. StringRef Text) {
  246. return tooling::Replacement(FileName, Offset, Length, Text);
  247. }
  248. tooling::Replacement createInsertion(StringRef IncludeDirective) {
  249. return createReplacement(UINT_MAX, 0, IncludeDirective);
  250. }
  251. tooling::Replacement createDeletion(StringRef HeaderName) {
  252. return createReplacement(UINT_MAX, 1, HeaderName);
  253. }
  254. inline std::string apply(StringRef Code,
  255. const tooling::Replacements Replaces) {
  256. auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
  257. EXPECT_TRUE(static_cast<bool>(CleanReplaces))
  258. << llvm::toString(CleanReplaces.takeError()) << "\n";
  259. auto Result = applyAllReplacements(Code, *CleanReplaces);
  260. EXPECT_TRUE(static_cast<bool>(Result));
  261. return *Result;
  262. }
  263. inline std::string formatAndApply(StringRef Code,
  264. const tooling::Replacements Replaces) {
  265. auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style);
  266. EXPECT_TRUE(static_cast<bool>(CleanReplaces))
  267. << llvm::toString(CleanReplaces.takeError()) << "\n";
  268. auto FormattedReplaces = formatReplacements(Code, *CleanReplaces, Style);
  269. EXPECT_TRUE(static_cast<bool>(FormattedReplaces))
  270. << llvm::toString(FormattedReplaces.takeError()) << "\n";
  271. auto Result = applyAllReplacements(Code, *FormattedReplaces);
  272. EXPECT_TRUE(static_cast<bool>(Result));
  273. return *Result;
  274. }
  275. int getOffset(StringRef Code, int Line, int Column) {
  276. RewriterTestContext Context;
  277. FileID ID = Context.createInMemoryFile(FileName, Code);
  278. auto DecomposedLocation =
  279. Context.Sources.getDecomposedLoc(Context.getLocation(ID, Line, Column));
  280. return DecomposedLocation.second;
  281. }
  282. const std::string FileName = "fix.cpp";
  283. FormatStyle Style = getLLVMStyle();
  284. };
  285. TEST_F(CleanUpReplacementsTest, FixOnlyAffectedCodeAfterReplacements) {
  286. std::string Code = "namespace A {\n"
  287. "namespace B {\n"
  288. " int x;\n"
  289. "} // namespace B\n"
  290. "} // namespace A\n"
  291. "\n"
  292. "namespace C {\n"
  293. "namespace D { int i; }\n"
  294. "inline namespace E { namespace { int y; } }\n"
  295. "int x= 0;"
  296. "}";
  297. std::string Expected = "\n\nnamespace C {\n"
  298. "namespace D { int i; }\n\n"
  299. "int x= 0;"
  300. "}";
  301. tooling::Replacements Replaces =
  302. toReplacements({createReplacement(getOffset(Code, 3, 3), 6, ""),
  303. createReplacement(getOffset(Code, 9, 34), 6, "")});
  304. EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
  305. }
  306. TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithoutDefine) {
  307. std::string Code = "int main() {}";
  308. std::string Expected = "#include \"a.h\"\n"
  309. "int main() {}";
  310. tooling::Replacements Replaces =
  311. toReplacements({createInsertion("#include \"a.h\"")});
  312. EXPECT_EQ(Expected, apply(Code, Replaces));
  313. }
  314. TEST_F(CleanUpReplacementsTest, NoExistingIncludeWithDefine) {
  315. std::string Code = "#ifndef A_H\n"
  316. "#define A_H\n"
  317. "class A {};\n"
  318. "#define MMM 123\n"
  319. "#endif";
  320. std::string Expected = "#ifndef A_H\n"
  321. "#define A_H\n"
  322. "#include \"b.h\"\n"
  323. "class A {};\n"
  324. "#define MMM 123\n"
  325. "#endif";
  326. tooling::Replacements Replaces =
  327. toReplacements({createInsertion("#include \"b.h\"")});
  328. EXPECT_EQ(Expected, apply(Code, Replaces));
  329. }
  330. TEST_F(CleanUpReplacementsTest, InsertBeforeCategoryWithLowerPriority) {
  331. std::string Code = "#ifndef A_H\n"
  332. "#define A_H\n"
  333. "\n"
  334. "\n"
  335. "\n"
  336. "#include <vector>\n"
  337. "class A {};\n"
  338. "#define MMM 123\n"
  339. "#endif";
  340. std::string Expected = "#ifndef A_H\n"
  341. "#define A_H\n"
  342. "\n"
  343. "\n"
  344. "\n"
  345. "#include \"a.h\"\n"
  346. "#include <vector>\n"
  347. "class A {};\n"
  348. "#define MMM 123\n"
  349. "#endif";
  350. tooling::Replacements Replaces =
  351. toReplacements({createInsertion("#include \"a.h\"")});
  352. EXPECT_EQ(Expected, apply(Code, Replaces));
  353. }
  354. TEST_F(CleanUpReplacementsTest, InsertAfterMainHeader) {
  355. std::string Code = "#include \"fix.h\"\n"
  356. "\n"
  357. "int main() {}";
  358. std::string Expected = "#include \"fix.h\"\n"
  359. "#include <a>\n"
  360. "\n"
  361. "int main() {}";
  362. tooling::Replacements Replaces =
  363. toReplacements({createInsertion("#include <a>")});
  364. Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
  365. EXPECT_EQ(Expected, apply(Code, Replaces));
  366. }
  367. TEST_F(CleanUpReplacementsTest, InsertBeforeSystemHeaderLLVM) {
  368. std::string Code = "#include <memory>\n"
  369. "\n"
  370. "int main() {}";
  371. std::string Expected = "#include \"z.h\"\n"
  372. "#include <memory>\n"
  373. "\n"
  374. "int main() {}";
  375. tooling::Replacements Replaces =
  376. toReplacements({createInsertion("#include \"z.h\"")});
  377. EXPECT_EQ(Expected, apply(Code, Replaces));
  378. }
  379. TEST_F(CleanUpReplacementsTest, InsertAfterSystemHeaderGoogle) {
  380. std::string Code = "#include <memory>\n"
  381. "\n"
  382. "int main() {}";
  383. std::string Expected = "#include <memory>\n"
  384. "#include \"z.h\"\n"
  385. "\n"
  386. "int main() {}";
  387. tooling::Replacements Replaces =
  388. toReplacements({createInsertion("#include \"z.h\"")});
  389. Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
  390. EXPECT_EQ(Expected, apply(Code, Replaces));
  391. }
  392. TEST_F(CleanUpReplacementsTest, InsertOneIncludeLLVMStyle) {
  393. std::string Code = "#include \"x/fix.h\"\n"
  394. "#include \"a.h\"\n"
  395. "#include \"b.h\"\n"
  396. "#include \"clang/Format/Format.h\"\n"
  397. "#include <memory>\n";
  398. std::string Expected = "#include \"x/fix.h\"\n"
  399. "#include \"a.h\"\n"
  400. "#include \"b.h\"\n"
  401. "#include \"d.h\"\n"
  402. "#include \"clang/Format/Format.h\"\n"
  403. "#include \"llvm/x/y.h\"\n"
  404. "#include <memory>\n";
  405. tooling::Replacements Replaces =
  406. toReplacements({createInsertion("#include \"d.h\""),
  407. createInsertion("#include \"llvm/x/y.h\"")});
  408. EXPECT_EQ(Expected, apply(Code, Replaces));
  409. }
  410. TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesLLVMStyle) {
  411. std::string Code = "#include \"x/fix.h\"\n"
  412. "#include \"a.h\"\n"
  413. "#include \"b.h\"\n"
  414. "#include \"clang/Format/Format.h\"\n"
  415. "#include <memory>\n";
  416. std::string Expected = "#include \"x/fix.h\"\n"
  417. "#include \"a.h\"\n"
  418. "#include \"b.h\"\n"
  419. "#include \"new/new.h\"\n"
  420. "#include \"clang/Format/Format.h\"\n"
  421. "#include <memory>\n"
  422. "#include <list>\n";
  423. tooling::Replacements Replaces =
  424. toReplacements({createInsertion("#include <list>"),
  425. createInsertion("#include \"new/new.h\"")});
  426. EXPECT_EQ(Expected, apply(Code, Replaces));
  427. }
  428. TEST_F(CleanUpReplacementsTest, InsertNewSystemIncludeGoogleStyle) {
  429. std::string Code = "#include \"x/fix.h\"\n"
  430. "\n"
  431. "#include \"y/a.h\"\n"
  432. "#include \"z/b.h\"\n";
  433. // FIXME: inserting after the empty line following the main header might be
  434. // prefered.
  435. std::string Expected = "#include \"x/fix.h\"\n"
  436. "#include <vector>\n"
  437. "\n"
  438. "#include \"y/a.h\"\n"
  439. "#include \"z/b.h\"\n";
  440. tooling::Replacements Replaces =
  441. toReplacements({createInsertion("#include <vector>")});
  442. Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
  443. EXPECT_EQ(Expected, apply(Code, Replaces));
  444. }
  445. TEST_F(CleanUpReplacementsTest, InsertMultipleIncludesGoogleStyle) {
  446. std::string Code = "#include \"x/fix.h\"\n"
  447. "\n"
  448. "#include <vector>\n"
  449. "\n"
  450. "#include \"y/a.h\"\n"
  451. "#include \"z/b.h\"\n";
  452. std::string Expected = "#include \"x/fix.h\"\n"
  453. "\n"
  454. "#include <vector>\n"
  455. "#include <list>\n"
  456. "\n"
  457. "#include \"y/a.h\"\n"
  458. "#include \"z/b.h\"\n"
  459. "#include \"x/x.h\"\n";
  460. tooling::Replacements Replaces =
  461. toReplacements({createInsertion("#include <list>"),
  462. createInsertion("#include \"x/x.h\"")});
  463. Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
  464. EXPECT_EQ(Expected, apply(Code, Replaces));
  465. }
  466. TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortLLVM) {
  467. std::string Code = "\nint x;";
  468. std::string Expected = "\n#include \"fix.h\"\n"
  469. "#include \"a.h\"\n"
  470. "#include \"b.h\"\n"
  471. "#include \"c.h\"\n"
  472. "#include <list>\n"
  473. "#include <vector>\n"
  474. "int x;";
  475. tooling::Replacements Replaces = toReplacements(
  476. {createInsertion("#include \"a.h\""), createInsertion("#include \"c.h\""),
  477. createInsertion("#include \"b.h\""),
  478. createInsertion("#include <vector>"), createInsertion("#include <list>"),
  479. createInsertion("#include \"fix.h\"")});
  480. EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
  481. }
  482. TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortGoogle) {
  483. std::string Code = "\nint x;";
  484. std::string Expected = "\n#include \"fix.h\"\n"
  485. "#include <list>\n"
  486. "#include <vector>\n"
  487. "#include \"a.h\"\n"
  488. "#include \"b.h\"\n"
  489. "#include \"c.h\"\n"
  490. "int x;";
  491. tooling::Replacements Replaces = toReplacements(
  492. {createInsertion("#include \"a.h\""), createInsertion("#include \"c.h\""),
  493. createInsertion("#include \"b.h\""),
  494. createInsertion("#include <vector>"), createInsertion("#include <list>"),
  495. createInsertion("#include \"fix.h\"")});
  496. Style = format::getGoogleStyle(format::FormatStyle::LanguageKind::LK_Cpp);
  497. EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
  498. }
  499. TEST_F(CleanUpReplacementsTest, FormatCorrectLineWhenHeadersAreInserted) {
  500. std::string Code = "\n"
  501. "int x;\n"
  502. "int a;\n"
  503. "int a;\n"
  504. "int a;";
  505. std::string Expected = "\n#include \"x.h\"\n"
  506. "#include \"y.h\"\n"
  507. "#include \"clang/x/x.h\"\n"
  508. "#include <list>\n"
  509. "#include <vector>\n"
  510. "int x;\n"
  511. "int a;\n"
  512. "int b;\n"
  513. "int a;";
  514. tooling::Replacements Replaces = toReplacements(
  515. {createReplacement(getOffset(Code, 4, 8), 1, "b"),
  516. createInsertion("#include <vector>"), createInsertion("#include <list>"),
  517. createInsertion("#include \"clang/x/x.h\""),
  518. createInsertion("#include \"y.h\""),
  519. createInsertion("#include \"x.h\"")});
  520. EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
  521. }
  522. TEST_F(CleanUpReplacementsTest, NotConfusedByDefine) {
  523. std::string Code = "void f() {}\n"
  524. "#define A \\\n"
  525. " int i;";
  526. std::string Expected = "#include <vector>\n"
  527. "void f() {}\n"
  528. "#define A \\\n"
  529. " int i;";
  530. tooling::Replacements Replaces =
  531. toReplacements({createInsertion("#include <vector>")});
  532. EXPECT_EQ(Expected, formatAndApply(Code, Replaces));
  533. }
  534. TEST_F(CleanUpReplacementsTest, SkippedTopComment) {
  535. std::string Code = "// comment\n"
  536. "\n"
  537. " // comment\n";
  538. std::string Expected = "// comment\n"
  539. "\n"
  540. " // comment\n"
  541. "#include <vector>\n";
  542. tooling::Replacements Replaces =
  543. toReplacements({createInsertion("#include <vector>")});
  544. EXPECT_EQ(Expected, apply(Code, Replaces));
  545. }
  546. TEST_F(CleanUpReplacementsTest, SkippedMixedComments) {
  547. std::string Code = "// comment\n"
  548. "// comment \\\n"
  549. " comment continued\n"
  550. "/*\n"
  551. "* comment\n"
  552. "*/\n";
  553. std::string Expected = "// comment\n"
  554. "// comment \\\n"
  555. " comment continued\n"
  556. "/*\n"
  557. "* comment\n"
  558. "*/\n"
  559. "#include <vector>\n";
  560. tooling::Replacements Replaces =
  561. toReplacements({createInsertion("#include <vector>")});
  562. EXPECT_EQ(Expected, apply(Code, Replaces));
  563. }
  564. TEST_F(CleanUpReplacementsTest, MultipleBlockCommentsInOneLine) {
  565. std::string Code = "/*\n"
  566. "* comment\n"
  567. "*/ /* comment\n"
  568. "*/\n"
  569. "\n\n"
  570. "/* c1 */ /*c2 */\n";
  571. std::string Expected = "/*\n"
  572. "* comment\n"
  573. "*/ /* comment\n"
  574. "*/\n"
  575. "\n\n"
  576. "/* c1 */ /*c2 */\n"
  577. "#include <vector>\n";
  578. tooling::Replacements Replaces =
  579. toReplacements({createInsertion("#include <vector>")});
  580. EXPECT_EQ(Expected, apply(Code, Replaces));
  581. }
  582. TEST_F(CleanUpReplacementsTest, CodeAfterComments) {
  583. std::string Code = "/*\n"
  584. "* comment\n"
  585. "*/ /* comment\n"
  586. "*/\n"
  587. "\n\n"
  588. "/* c1 */ /*c2 */\n"
  589. "\n"
  590. "int x;\n";
  591. std::string Expected = "/*\n"
  592. "* comment\n"
  593. "*/ /* comment\n"
  594. "*/\n"
  595. "\n\n"
  596. "/* c1 */ /*c2 */\n"
  597. "\n"
  598. "#include <vector>\n"
  599. "int x;\n";
  600. tooling::Replacements Replaces =
  601. toReplacements({createInsertion("#include <vector>")});
  602. EXPECT_EQ(Expected, apply(Code, Replaces));
  603. }
  604. TEST_F(CleanUpReplacementsTest, FakeHeaderGuardIfDef) {
  605. std::string Code = "// comment \n"
  606. "#ifdef X\n"
  607. "#define X\n";
  608. std::string Expected = "// comment \n"
  609. "#include <vector>\n"
  610. "#ifdef X\n"
  611. "#define X\n";
  612. tooling::Replacements Replaces =
  613. toReplacements({createInsertion("#include <vector>")});
  614. EXPECT_EQ(Expected, apply(Code, Replaces));
  615. }
  616. TEST_F(CleanUpReplacementsTest, RealHeaderGuardAfterComments) {
  617. std::string Code = "// comment \n"
  618. "#ifndef X\n"
  619. "#define X\n"
  620. "int x;\n"
  621. "#define Y 1\n";
  622. std::string Expected = "// comment \n"
  623. "#ifndef X\n"
  624. "#define X\n"
  625. "#include <vector>\n"
  626. "int x;\n"
  627. "#define Y 1\n";
  628. tooling::Replacements Replaces =
  629. toReplacements({createInsertion("#include <vector>")});
  630. EXPECT_EQ(Expected, apply(Code, Replaces));
  631. }
  632. TEST_F(CleanUpReplacementsTest, IfNDefWithNoDefine) {
  633. std::string Code = "// comment \n"
  634. "#ifndef X\n"
  635. "int x;\n"
  636. "#define Y 1\n";
  637. std::string Expected = "// comment \n"
  638. "#include <vector>\n"
  639. "#ifndef X\n"
  640. "int x;\n"
  641. "#define Y 1\n";
  642. tooling::Replacements Replaces =
  643. toReplacements({createInsertion("#include <vector>")});
  644. EXPECT_EQ(Expected, apply(Code, Replaces));
  645. }
  646. TEST_F(CleanUpReplacementsTest, HeaderGuardWithComment) {
  647. std::string Code = "// comment \n"
  648. "#ifndef X // comment\n"
  649. "// comment\n"
  650. "/* comment\n"
  651. "*/\n"
  652. "/* comment */ #define X\n"
  653. "int x;\n"
  654. "#define Y 1\n";
  655. std::string Expected = "// comment \n"
  656. "#ifndef X // comment\n"
  657. "// comment\n"
  658. "/* comment\n"
  659. "*/\n"
  660. "/* comment */ #define X\n"
  661. "#include <vector>\n"
  662. "int x;\n"
  663. "#define Y 1\n";
  664. tooling::Replacements Replaces =
  665. toReplacements({createInsertion("#include <vector>")});
  666. EXPECT_EQ(Expected, apply(Code, Replaces));
  667. }
  668. TEST_F(CleanUpReplacementsTest, EmptyCode) {
  669. std::string Code = "";
  670. std::string Expected = "#include <vector>\n";
  671. tooling::Replacements Replaces =
  672. toReplacements({createInsertion("#include <vector>")});
  673. EXPECT_EQ(Expected, apply(Code, Replaces));
  674. }
  675. TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCode) {
  676. std::string Code = "#include <map>";
  677. std::string Expected = "#include <map>\n#include <vector>\n";
  678. tooling::Replacements Replaces =
  679. toReplacements({createInsertion("#include <vector>")});
  680. EXPECT_EQ(Expected, apply(Code, Replaces));
  681. }
  682. TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCodeMultipleInsertions) {
  683. std::string Code = "#include <map>";
  684. std::string Expected =
  685. "#include <map>\n#include <string>\n#include <vector>\n";
  686. tooling::Replacements Replaces =
  687. toReplacements({createInsertion("#include <string>"),
  688. createInsertion("#include <vector>")});
  689. EXPECT_EQ(Expected, apply(Code, Replaces));
  690. }
  691. TEST_F(CleanUpReplacementsTest, SkipExistingHeaders) {
  692. std::string Code = "#include \"a.h\"\n"
  693. "#include <vector>\n";
  694. std::string Expected = "#include \"a.h\"\n"
  695. "#include <vector>\n";
  696. tooling::Replacements Replaces =
  697. toReplacements({createInsertion("#include <vector>"),
  698. createInsertion("#include \"a.h\"")});
  699. EXPECT_EQ(Expected, apply(Code, Replaces));
  700. }
  701. TEST_F(CleanUpReplacementsTest, AddIncludesWithDifferentForms) {
  702. std::string Code = "#include \"a.h\"\n"
  703. "#include <vector>\n";
  704. // FIXME: this might not be the best behavior.
  705. std::string Expected = "#include \"a.h\"\n"
  706. "#include \"vector\"\n"
  707. "#include <vector>\n"
  708. "#include <a.h>\n";
  709. tooling::Replacements Replaces =
  710. toReplacements({createInsertion("#include \"vector\""),
  711. createInsertion("#include <a.h>")});
  712. EXPECT_EQ(Expected, apply(Code, Replaces));
  713. }
  714. TEST_F(CleanUpReplacementsTest, SimpleDeleteIncludes) {
  715. std::string Code = "#include \"abc.h\"\n"
  716. "#include \"xyz.h\" // comment\n"
  717. "#include \"xyz\"\n"
  718. "int x;\n";
  719. std::string Expected = "#include \"xyz\"\n"
  720. "int x;\n";
  721. tooling::Replacements Replaces =
  722. toReplacements({createDeletion("abc.h"), createDeletion("xyz.h")});
  723. EXPECT_EQ(Expected, apply(Code, Replaces));
  724. }
  725. TEST_F(CleanUpReplacementsTest, DeleteAllCode) {
  726. std::string Code = "#include \"xyz.h\"\n"
  727. "#include <xyz.h>";
  728. std::string Expected = "";
  729. tooling::Replacements Replaces = toReplacements({createDeletion("xyz.h")});
  730. EXPECT_EQ(Expected, apply(Code, Replaces));
  731. }
  732. TEST_F(CleanUpReplacementsTest, DeleteAllIncludesWithSameNameIfNoType) {
  733. std::string Code = "#include \"xyz.h\"\n"
  734. "#include \"xyz\"\n"
  735. "#include <xyz.h>\n";
  736. std::string Expected = "#include \"xyz\"\n";
  737. tooling::Replacements Replaces = toReplacements({createDeletion("xyz.h")});
  738. EXPECT_EQ(Expected, apply(Code, Replaces));
  739. }
  740. TEST_F(CleanUpReplacementsTest, OnlyDeleteHeaderWithType) {
  741. std::string Code = "#include \"xyz.h\"\n"
  742. "#include \"xyz\"\n"
  743. "#include <xyz.h>";
  744. std::string Expected = "#include \"xyz.h\"\n"
  745. "#include \"xyz\"\n";
  746. tooling::Replacements Replaces = toReplacements({createDeletion("<xyz.h>")});
  747. EXPECT_EQ(Expected, apply(Code, Replaces));
  748. }
  749. TEST_F(CleanUpReplacementsTest, InsertionAndDeleteHeader) {
  750. std::string Code = "#include \"a.h\"\n"
  751. "\n"
  752. "#include <vector>\n";
  753. std::string Expected = "#include \"a.h\"\n"
  754. "\n"
  755. "#include <map>\n";
  756. tooling::Replacements Replaces = toReplacements(
  757. {createDeletion("<vector>"), createInsertion("#include <map>")});
  758. EXPECT_EQ(Expected, apply(Code, Replaces));
  759. }
  760. } // end namespace
  761. } // end namespace format
  762. } // end namespace clang