15 #include "clang/AST/Expr.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/DiagnosticIDs.h" 18 #include "clang/Basic/DiagnosticOptions.h" 19 #include "clang/Basic/FileManager.h" 20 #include "clang/Basic/FileSystemOptions.h" 21 #include "clang/Basic/LLVM.h" 22 #include "clang/Basic/SourceLocation.h" 23 #include "clang/Basic/SourceManager.h" 24 #include "clang/Rewrite/Core/Rewriter.h" 25 #include "clang/Tooling/Core/Replacement.h" 26 #include "llvm/ADT/IntrusiveRefCntPtr.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/ADT/StringMap.h" 29 #include "llvm/ADT/StringRef.h" 30 #include "llvm/Support/Error.h" 31 #include "llvm/Support/MemoryBuffer.h" 32 #include "llvm/Support/VirtualFileSystem.h" 33 #include "llvm/Testing/Support/Error.h" 34 #include "gmock/gmock-matchers.h" 35 #include "gmock/gmock.h" 36 #include "gtest/gtest.h" 42 using ::testing::AllOf;
43 using ::testing::ElementsAre;
44 using ::testing::HasSubstr;
45 using ::testing::StartsWith;
56 auto RelPaths = {
"a.h",
"foo.cpp",
"test/test.cpp"};
58 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
60 MemFS->setCurrentWorkingDirectory(
testRoot());
61 for (
auto Path : RelPaths)
62 MemFS->addFile(
Path, 0, llvm::MemoryBuffer::getMemBuffer(
"",
Path));
63 FileManager FM(FileSystemOptions(), MemFS);
64 DiagnosticsEngine DE(
new DiagnosticIDs,
new DiagnosticOptions);
65 SourceManager SM(DE, FM);
67 for (
auto Path : RelPaths) {
68 auto FID = SM.createFileID(*FM.getFile(
Path), SourceLocation(),
69 clang::SrcMgr::C_User);
71 ASSERT_THAT_EXPECTED(Res, llvm::Succeeded());
77 TEST_F(SwapIfBranchesTest, Test) {
79 EXPECT_EQ(apply(
"^if (true) {return 100;} else {continue;}"),
80 "if (true) {continue;} else {return 100;}");
81 EXPECT_EQ(apply(
"^if () {return 100;} else {continue;}"),
82 "if () {continue;} else {return 100;}")
83 <<
"broken condition";
84 EXPECT_AVAILABLE(
"^i^f^^(^t^r^u^e^) { return 100; } ^e^l^s^e^ { continue; }");
87 EXPECT_THAT(
"if(2 + [[2]] + 2) { return 2 + 2 + 2; } else {continue;}",
90 EXPECT_THAT(
"if(2 + 2 + 2) { return 2 + [[2]] + 2; } else { continue; }",
93 EXPECT_THAT(
"if(2 + 2 + 2) { return 2 + [[2 + 2; } else {continue;]]}",
97 "if([]{return [[true]];}()) { return 2 + 2 + 2; } else { continue; }",
100 EXPECT_THAT(
"^if (1) return; else { return; }", Not(isAvailable()));
102 EXPECT_THAT(
"[[if(1){}else{}if(2){}else{}]]", Not(isAvailable()));
106 TEST_F(RawStringLiteralTest, Test) {
107 Context = Expression;
116 const char *Input = R
"cpp(R"(multi 117 token)" "\nst^ring\n" "literal")cpp"; 118 const char *Output = R
"cpp(R"(multi 122 EXPECT_EQ(apply(Input), Output); 126 TEST_F(ObjCLocalizeStringLiteralTest, Test) { 127 ExtraArgs.push_back("-x");
128 ExtraArgs.push_back(
"objective-c");
139 const char *Input = R
"(id x = [[@"test"]];)"; 140 const char *Output = R
"(id x = NSLocalizedString(@"test", @"");)"; 141 EXPECT_EQ(apply(Input), Output); 145 TEST_F(DumpASTTest, Test) { 148 EXPECT_THAT(apply(
"int x = 2 ^+ 2;"),
149 AllOf(StartsWith(
"message:"), HasSubstr(
"BinaryOperator"),
150 HasSubstr(
"'+'"), HasSubstr(
"|-IntegerLiteral"),
151 HasSubstr(
"<col:9> 'int' 2\n`-IntegerLiteral"),
152 HasSubstr(
"<col:13> 'int' 2")));
156 TEST_F(DumpSymbolTest, Test) {
157 std::string ID = R
"("id":"CA2EBE44A1D76D2A")"; 158 std::string USR = R"("usr":"c:@F@foo#")"; 159 EXPECT_THAT(apply("void f^oo();"),
160 AllOf(StartsWith(
"message:"), testing::HasSubstr(ID),
161 testing::HasSubstr(USR)));
165 TEST_F(ShowSelectionTreeTest, Test) {
169 const char *Output = R
"(message: 171 VarDecl int x = fcall(2 + 2) 172 .CallExpr fcall(2 + 2) 173 ImplicitCastExpr fcall 175 .BinaryOperator 2 + 2 178 EXPECT_EQ(apply("int fcall(int); int x = fca[[ll(2 +]]2);"), Output);
182 TEST_F(DumpRecordLayoutTest, Test) {
184 EXPECT_THAT(
"struct X { int ^a; };", Not(isAvailable()));
185 EXPECT_THAT(
"struct ^X;", Not(isAvailable()));
186 EXPECT_THAT(
"template <typename T> struct ^X { T t; };", Not(isAvailable()));
187 EXPECT_THAT(
"enum ^X {};", Not(isAvailable()));
189 EXPECT_THAT(apply(
"struct ^X { int x; int y; }"),
190 AllOf(StartsWith(
"message:"), HasSubstr(
"0 | int x")));
194 TEST_F(ExtractVariableTest, Test) {
195 const char *AvailableCases = R
"cpp( 202 return [[[[t.b[[a]]r]](t.z)]]; 205 int a = [[5 +]] [[4 * [[[[xyz]]()]]]]; 206 // multivariable initialization 208 int x = [[1]], y = [[a + 1]], a = [[1]], z = a + 1; 223 for(a = [[1]]; a > [[[[3]] + [[4]]]]; a++) 236 const char *NoCrashCases = R
"cpp( 237 template<typename T, typename ...Args> 238 struct Test<T, Args...> { 239 Test(const T &v) :val[[(^]]) {} 245 const char *UnavailableCases = R
"cpp( 246 int xyz(int a = [[1]]) { 248 int bar(int a = [[1]]); 251 return [[t]].bar([[[[t]].z]]); 254 // function default argument 255 void f(int b = [[1]]) { 259 auto i = new int, j = new int; 260 [[[[delete i]], delete j]]; 264 int x = 1, y = a + 1, a = 1, z = [[a + 1]]; 269 for(int a = 1, b = 2, c = 3; a > [[b + c]]; [[a++]]) 272 auto lamb = [&[[a]], &[[b]]](int r = [[1]]) {return 1;} 276 // Variable DeclRefExpr 278 // statement expression 291 const std::vector<std::pair<std::string, std::string>>
294 {R
"cpp(void varDecl() { 295 int a = 5 * (4 + (3 [[- 1)]]); 297 R"cpp(void varDecl() { 298 auto dummy = (3 - 1); int a = 5 * (4 + dummy); 324 {R
"cpp(#define PLUS(x) x++ 326 int y = PLUS([[1+a]]); 333 R
"cpp(#define PLUS(x) x++ 335 auto dummy = PLUS(1+a); int y = dummy; 338 {R
"cpp(#define LOOP(x) while (1) {a = x;} 343 R"cpp(#define LOOP(x) while (1) {a = x;} 345 auto dummy = 3; if(1) 348 {R"cpp(#define LOOP(x) do {x;} while(1); 353 R"cpp(#define LOOP(x) do {x;} while(1); 355 auto dummy = 3; if(1) 359 {R
"cpp(void f(int a) { 360 [ [gsl::suppress("type")] ] for (;;) a = [[1]]; 362 R"cpp(void f(int a) { 363 auto dummy = 1; [ [gsl::suppress("type")] ] for (;;) a = dummy; 368 return [[T().f()]].f(); 373 auto dummy = T().f(); return dummy.f(); 381 auto dummy = f(); return dummy; 389 int x = 1 + [[2 + 3 + 4]] + 5; 392 auto dummy = 2 + 3 + 4; int x = 1 + dummy + 5; 395 int x = [[1 + 2 + 3]] + 4 + 5; 398 auto dummy = 1 + 2 + 3; int x = dummy + 4 + 5; 401 int x = 1 + 2 + [[3 + 4 + 5]]; 404 auto dummy = 3 + 4 + 5; int x = 1 + 2 + dummy; 408 int x = 1 - [[2 - 3 - 4]] - 5; 411 auto dummy = 1 - 2 - 3 - 4; int x = dummy - 5; 415 int x = 0 + 1 * [[2 + 3]] * 4 + 5; 418 auto dummy = 1 * 2 + 3 * 4; int x = 0 + dummy + 5; 428 S x = S(1) + [[S(2) + S(3) + S(4)]] + S(5); 436 auto dummy = S(2) + S(3) + S(4); S x = S(1) + dummy + S(5); 440 {R
"cpp(#define ECHO(X) X 442 int x = 1 + [[ECHO(2 + 3) + 4]] + 5; 444 R"cpp(#define ECHO(X) X 446 auto dummy = 1 + ECHO(2 + 3) + 4; int x = dummy + 5; 448 {R"cpp(#define ECHO(X) X 450 int x = 1 + [[ECHO(2) + ECHO(3) + 4]] + 5; 452 R"cpp(#define ECHO(X) X 454 auto dummy = 1 + ECHO(2) + ECHO(3) + 4; int x = dummy + 5; 457 for (
const auto &IO : InputOutputs) {
458 EXPECT_EQ(IO.second, apply(IO.first)) << IO.first;
463 TEST_F(AnnotateHighlightingsTest, Test) {
466 EXPECT_EQ(
"void /* entity.name.function.cpp */f() {}", apply(
"void ^f() {}"));
468 EXPECT_EQ(apply(
"[[void f1(); void f2();]]"),
469 "void /* entity.name.function.cpp */f1(); " 470 "void /* entity.name.function.cpp */f2();");
472 EXPECT_EQ(apply(
"void f1(); void f2() {^}"),
474 "void /* entity.name.function.cpp */f2() {}");
478 TEST_F(ExpandMacroTest, Test) {
481 #define FUNC(X) X+X+X 494 EXPECT_EQ(apply(
"^FOO BAR FOO"),
"1 2 3 BAR FOO");
495 EXPECT_EQ(apply(
"FOO BAR ^FOO"),
"FOO BAR 1 2 3");
497 EXPECT_EQ(apply(
"F^UNC(2)"),
"2 + 2 + 2");
500 EXPECT_EQ(apply(
"int a ^EMPTY;"),
"int a ;");
501 EXPECT_EQ(apply(
"int a ^EMPTY_FN(1 2 3);"),
"int a ;");
502 EXPECT_EQ(apply(
"int a = 123 ^EMPTY EMPTY_FN(1);"),
503 "int a = 123 EMPTY_FN(1);");
504 EXPECT_EQ(apply(
"int a = 123 ^EMPTY_FN(1) EMPTY;"),
"int a = 123 EMPTY;");
505 EXPECT_EQ(apply(
"int a = 123 EMPTY_FN(1) ^EMPTY;"),
506 "int a = 123 EMPTY_FN(1) ;");
510 TEST_F(ExpandAutoTypeTest, Test) {
519 inline namespace inl_ns { 530 EXPECT_EQ(apply(
"[[auto]] i = 0;"),
"int i = 0;");
531 EXPECT_EQ(apply(
"au^to i = 0;"),
"int i = 0;");
533 EXPECT_EQ(apply(
"^auto C = ns::Class::Nested();"),
534 "ns::Class::Nested C = ns::Class::Nested();");
536 EXPECT_EQ(apply(
"namespace ns { void f() { ^auto C = Class(); } }"),
537 "namespace ns { void f() { Class C = Class(); } }");
539 EXPECT_THAT(apply(
"au^to x = doesnt_exist();"),
540 StartsWith(
"fail: Could not deduce type for 'auto' type"));
542 EXPECT_THAT(apply(
"au^to x = &ns::Func;"),
543 StartsWith(
"fail: Could not expand type of function pointer"));
545 EXPECT_THAT(apply(
"au^to x = []{};"),
546 StartsWith(
"fail: Could not expand type of lambda expression"));
548 EXPECT_EQ(apply(
"au^to x = inl_ns::Visible();"),
549 "Visible x = inl_ns::Visible();");
551 EXPECT_EQ(apply(
"namespace x { void y() { struct S{}; ^auto z = S(); } }"),
552 "namespace x { void y() { struct S{}; S z = S(); } }");
554 EXPECT_EQ(apply(R
"cpp(au^to x = "test")cpp"), 555 R"cpp(const char * x = "test")cpp"); 561 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
563 EXPECT_THAT(apply(
"template <typename T> void x() { ^auto y = T::z(); }"),
564 StartsWith(
"fail: Could not deduce type for 'auto' type"));
568 TEST_F(ExtractFunctionTest, FunctionTest) {
572 EXPECT_EQ(apply(
"for(;;) [[1+2; 1+2;]]"),
"unavailable");
574 EXPECT_EQ(apply(
"int x = 0; [[x++;]]"),
"unavailable");
576 EXPECT_EQ(apply(
"auto lam = [](){ [[int x;]] }; "),
"unavailable");
578 EXPECT_THAT(apply(
"int [[x = 0]];"),
"unavailable");
582 EXPECT_THAT(apply(
"for(;;) { [[int x;]]break; }"), HasSubstr(
"extracted"));
585 EXPECT_THAT(apply(
" for([[int i = 0;]];);"), HasSubstr(
"extracted"));
587 EXPECT_THAT(apply(
" [[int a = 5;]] a++; "), StartsWith(
"fail"));
589 EXPECT_THAT(apply(
" if(true) [[{ return; }]] "), HasSubstr(
"extracted"));
591 EXPECT_THAT(apply(
" if(true) [[if (false) return;]] "), StartsWith(
"fail"));
594 TEST_F(ExtractFunctionTest, FileTest) {
596 std::string ParameterCheckInput = R
"cpp( 607 std::string ParameterCheckOutput = R"cpp( 611 void extracted(int &a, int &b, int * &ptr, Foo &foo) { 619 extracted(a, b, ptr, foo); 621 EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput); 624 std::string ConstCheckInput = R
"cpp( 625 void f(const int c) { 628 std::string ConstCheckOutput = R"cpp( 629 void extracted(const int &c) { 632 void f(const int c) { 635 EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput); 638 EXPECT_THAT(apply(
"void f() { [[int a; f();]] }"), StartsWith(
"fail"));
642 std::string MethodFailInput = R
"cpp( 649 EXPECT_EQ(apply(MethodFailInput), "unavailable");
653 std::string TemplateFailInput = R
"cpp( 659 EXPECT_EQ(apply(TemplateFailInput), "unavailable");
661 std::string MacroInput = R
"cpp( 662 #define F(BODY) void f() { BODY } 665 std::string MacroOutput = R"cpp( 666 #define F(BODY) void f() { BODY } 672 EXPECT_EQ(apply(MacroInput), MacroOutput); 675 EXPECT_EQ(apply(
"void f([[int a]]);"),
"unavailable");
677 std::string CompoundFailInput = R
"cpp( 682 EXPECT_EQ(apply(CompoundFailInput), "unavailable");
685 TEST_F(ExtractFunctionTest, ControlFlow) {
688 EXPECT_THAT(apply(
" [[for(;;) if(1) break;]] "), HasSubstr(
"extracted"));
689 EXPECT_THAT(apply(
" for(;;) [[while(1) break;]] "), HasSubstr(
"extracted"));
690 EXPECT_THAT(apply(
" [[switch(1) { break; }]]"), HasSubstr(
"extracted"));
691 EXPECT_THAT(apply(
" [[while(1) switch(1) { continue; }]]"),
692 HasSubstr(
"extracted"));
694 EXPECT_THAT(apply(
" for(;;) [[if(1) continue;]] "), StartsWith(
"fail"));
695 EXPECT_THAT(apply(
" while(1) [[if(1) break;]] "), StartsWith(
"fail"));
696 EXPECT_THAT(apply(
" switch(1) { [[break;]] }"), StartsWith(
"fail"));
697 EXPECT_THAT(apply(
" for(;;) { [[while(1) break; break;]] }"),
701 TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
703 const char* Before = R
"cpp( 705 int getNum(bool Superstitious, int Min, int Max) { 706 if (Superstitious) [[{ 707 for (int I = Min; I <= Max; ++I) 712 return (Min + Max) / 2; 718 const char* After = R
"cpp( 720 int extracted(int &Min, int &Max) { 722 for (int I = Min; I <= Max; ++I) 728 int getNum(bool Superstitious, int Min, int Max) { 729 if (Superstitious) return extracted(Min, Max); else { 730 return (Min + Max) / 2; 734 EXPECT_EQ(apply(Before), After); 738 TEST_F(RemoveUsingNamespaceTest, All) { 739 std::pair<llvm::StringRef , llvm::StringRef > Cases[] = {
742 namespace ns1 { struct vector {}; } 743 namespace ns2 { struct map {}; } 744 using namespace n^s1; 754 namespace ns1 { struct vector {}; } 755 namespace ns2 { struct map {}; } 767 #define DECLARE(x, y) x y 768 namespace ns { struct vector {}; } 771 DECLARE(ns::vector, v1); 776 #define DECLARE(x, y) x y 777 namespace ns { struct vector {}; } 780 DECLARE(ns::vector, v1); 781 DECLARE(ns::vector, v2); 786 namespace aa { namespace bb { struct map {}; }} 787 using namespace aa::b^b; 793 namespace aa { namespace bb { struct map {}; }} 801 namespace aa { namespace bb { struct map {}; }} 808 namespace aa { namespace bb { struct map {}; }} 816 namespace aa { namespace bb { struct map {}; }} 819 int main() { map M; } 822 namespace aa { namespace bb { struct map {}; }} 824 typedef aa::bb::map map; 825 int main() { map M; } 829 namespace aa { namespace bb { struct map {}; }} 830 using name[[space aa::b]]b; 837 namespace aa { namespace bb { struct map {}; }} 846 namespace aa { namespace bb { struct map {}; }} 847 using namespace aa::bb; 854 namespace aa { namespace bb { struct map {}; }} 855 using namespace aa::bb; 864 namespace bb { struct map {}; } 867 int main() { aa::map m; } 873 namespace bb { struct map {}; } 883 namespace a::b { struct Foo {}; } 885 using namespace a::[[b]]; 890 namespace a::b { struct Foo {}; } 894 int main() { a::b::Foo F;} 897 namespace a::b { struct Foo {}; } 899 using namespace a::b; 900 using namespace [[b]]; 904 namespace a::b { struct Foo {}; } 908 int main() { b::Foo F;} 914 comma, identifier, numeric 917 using namespace tok^ens; 925 comma, identifier, numeric 930 auto x = tokens::comma; 935 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} 936 using namespace st^d; 942 namespace std { inline namespace ns1 { inline namespace ns2 { struct vector {}; }}} 949 EXPECT_EQ(C.second, apply(C.first)) << C.first;
953 TEST_F(DefineInlineTest, TriggersOnFunctionDecl) {
960 [[void [[Bar::[[b^a^z]]]]() [[{ 965 [[void [[f^o^o]]() [[{ 974 [[vo^id ]]foo[[()]] {[[ 979 // Definition with no body. 980 class Bar { Bar() = def^ault; } 984 TEST_F(DefineInlineTest, NoForwardDecl) { 985 Header = "void bar();";
990 // FIXME: Generate a decl in the header. 996 TEST_F(DefineInlineTest, ReferencedDecls) { 1001 void fo^o(int baz) { 1007 Header =
"void foo(int test);";
1010 void fo^o(int baz) { 1016 Header =
"void bar();" + Header;
1018 void fo^o(int baz) { 1045 ExtraFiles[
"a.h"] =
"void bar();";
1046 Header =
"void foo(int test);";
1049 void fo^o(int baz) { 1055 TEST_F(DefineInlineTest, TemplateSpec) { 1057 template <typename T> void foo(); 1058 template<> void foo<char>(); 1060 template<> void f^oo<int>() { 1063 template <typename T> void foo(); 1065 template<> void f^oo<int>() { 1068 template <typename T> struct Foo { void foo(); }; 1070 template <typename T> void Foo<T>::f^oo() { 1073 template <typename T> void foo(); 1075 template <> void foo<int>(); 1077 template<> void f^oo<int>() { 1082 TEST_F(DefineInlineTest, CheckForCanonDecl) { 1088 // This bar normally refers to the definition just above, but it is not 1089 // visible from the forward declaration of foo. 1103 TEST_F(DefineInlineTest, UsingShadowDecls) { 1106 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1108 namespace ns1 { void foo(int); } 1109 namespace ns2 { void foo(int*); } 1110 template <typename T> 1116 template <typename T> 1122 TEST_F(DefineInlineTest, TransformNestedNamespaces) { 1182 TEST_F(DefineInlineTest, TransformUsings) { 1184 namespace a { namespace b { namespace c { void aux(); } } } 1195 namespace a { namespace b { namespace c { void aux(); } } } 1199 using namespace a::b; 1200 using namespace a::b::c; 1202 namespace d = a::b::c; 1208 TEST_F(DefineInlineTest, TransformDecls) { 1220 enum En { Zero, One }; 1223 enum class EnClass { Zero, One }; 1224 EnClass y = EnClass::Zero; 1236 enum En { Zero, One }; 1239 enum class EnClass { Zero, One }; 1240 EnClass y = EnClass::Zero; 1246 TEST_F(DefineInlineTest, TransformTemplDecls) { 1249 template <typename T> class Bar { 1253 template <typename T> T bar; 1254 template <typename T> void aux() {} 1261 bar<Bar<int>>.bar(); 1266 template <typename T> class Bar { 1270 template <typename T> T bar; 1271 template <typename T> void aux() {} 1275 a::bar<a::Bar<int>>.bar(); 1276 a::aux<a::Bar<int>>(); 1284 TEST_F(DefineInlineTest, TransformMembers) { 1303 ExtraFiles["a.h"] = R
"cpp( 1308 llvm::StringMap<std::string> EditedFiles; 1317 EXPECT_EQ(apply(Test, &EditedFiles), Expected); 1325 EXPECT_THAT(EditedFiles, 1329 TEST_F(DefineInlineTest, TransformDependentTypes) {
1332 template <typename T> class Bar {}; 1335 template <typename T> 1339 template <typename T> 1346 template <typename T> class Bar {}; 1349 template <typename T> 1352 a::Bar<a::Bar<T>> q; 1360 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1364 TEST_F(DefineInlineTest, TransformFunctionTempls) {
1366 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = {
1368 template <typename T> 1372 void foo<int>(int p); 1375 void foo<char>(char p); 1378 void fo^o<int>(int p) { 1382 template <typename T> 1386 void foo<int>(int p){ 1391 void foo<char>(char p); 1396 template <typename T> 1400 void foo<int>(int p); 1403 void foo<char>(char p); 1406 void fo^o<char>(char p) { 1410 template <typename T> 1414 void foo<int>(int p); 1417 void foo<char>(char p){ 1423 template <typename T> 1427 void foo<int>(int p); 1429 template <typename T> 1434 template <typename T> 1440 void foo<int>(int p); 1446 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
1447 for (
const auto &Case : Cases)
1448 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1451 TEST_F(DefineInlineTest, TransformTypeLocs) {
1454 template <typename T> class Bar { 1456 template <typename Q> class Baz {}; 1467 a::Bar<Bar<int>>::Baz<Bar<int>> q; 1471 template <typename T> class Bar { 1473 template <typename Q> class Baz {}; 1481 a::Bar<a::Bar<int>>::Baz<a::Bar<int>> q; 1489 TEST_F(DefineInlineTest, TransformDeclRefs) { 1492 template <typename T> class Bar { 1509 Bar<Bar<int>>::bar(); 1518 template <typename T> class Bar { 1533 a::Bar<a::Bar<int>>::bar(); 1535 B.x = a::Bar<int>::y; 1545 TEST_F(DefineInlineTest, StaticMembers) { 1547 namespace ns { class X { static void foo(); void bar(); }; } 1548 void ns::X::b^ar() { 1552 namespace ns { class X { static void foo(); void bar(){ 1559 TEST_F(DefineInlineTest, TransformParamNames) { 1560 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = { 1562 void foo(int, bool b, int T\ 1564 void ^foo(int f, bool x, int z) {})cpp", 1566 void foo(int f, bool x, int z){} 1572 void ^foo(int X) {})cpp", 1573 "fail: Cant rename parameter inside macro body."},
1576 #define PARAM TYPE Z 1577 #define BODY(x) 5 * (x) + 2 1579 void foo(PARAM, TYPE Q, TYPE, TYPE W = BODY(P)); 1581 void ^foo(int Z, int b, int c, int d) {})cpp", 1584 #define PARAM TYPE Z 1585 #define BODY(x) 5 * (x) + 2 1587 void foo(PARAM, TYPE b, TYPE c, TYPE d = BODY(x)){} 1590 ExtraArgs.push_back("-fno-delayed-template-parsing");
1591 for (
const auto &Case : Cases)
1592 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1595 TEST_F(DefineInlineTest, TransformTemplParamNames) {
1599 template <class, class X, 1600 template<typename> class, template<typename> class Y, 1602 void foo(X, Y<X>, int W = 5 * Z + 2); 1606 template <class T, class U, 1607 template<typename> class V, template<typename> class W, 1609 void Foo::Bar::f^oo(U, W<U>, int Q) {})cpp"; 1613 template <class T, class U, 1614 template<typename> class V, template<typename> class W, 1616 void foo(U, W<U>, int Q = 5 * Y + 2){} 1621 ExtraArgs.push_back("-fno-delayed-template-parsing");
1625 TEST_F(DefineInlineTest, TransformInlineNamespaces) {
1627 namespace a { inline namespace b { namespace { struct Foo{}; } } } 1631 void ^foo() {Foo foo;})cpp"; 1633 namespace a { inline namespace b { namespace { struct Foo{}; } } } 1634 void foo(){a::Foo foo;} 1641 TEST_F(DefineInlineTest, TokensBeforeSemicolon) { 1642 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = { 1644 void foo() /*Comment -_-*/ /*Com 2*/ ; 1645 void fo^o() { return ; })cpp", 1647 void foo() /*Comment -_-*/ /*Com 2*/ { return ; } 1652 void fo^o() { return ; })cpp", 1654 void foo(){ return ; } 1660 void fo^o() { return ; })cpp", 1661 "fail: Couldn't find semicolon for target declaration."},
1663 for (
const auto &Case : Cases)
1664 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1667 TEST_F(DefineInlineTest, HandleMacros) {
1669 #define BODY { return; } 1671 void f^oo()BODY)cpp"); 1674 #define BODY void foo(){ return; } 1678 std::pair<llvm::StringRef, llvm::StringRef> Cases[] = { 1682 namespace a { class Foo{}; } 1685 void f^oo(){BODY})cpp", 1688 namespace a { class Foo{}; } 1696 #define BODY return; 1697 void f^oo(){BODY})cpp", 1700 #define BODY return; 1704 #define TARGET void foo() 1706 void f^oo(){ return; })cpp", 1708 #define TARGET void foo() 1715 void f^oo(){ return; })cpp", 1718 void TARGET(){ return; } 1721 for (
const auto &Case : Cases)
1722 EXPECT_EQ(apply(Case.first), Case.second) << Case.first;
1725 TEST_F(DefineInlineTest, DropCommonNameSpecifiers) {
1727 llvm::StringRef Test;
1731 namespace a { namespace b { void aux(); } } 1734 namespace qq { void test(); } 1737 namespace ns3 { void baz(); } 1742 using namespace a::b; 1743 using namespace ns1::qq; 1744 void ns1::ns2::ns3::b^az() { 1748 ns1::ns2::ns3::baz(); 1753 namespace a { namespace b { void aux(); } } 1756 namespace qq { void test(); } 1759 namespace ns3 { void baz(){ 1763 ns1::ns2::ns3::baz(); 1771 using namespace a::b; 1772 using namespace ns1::qq; 1776 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; } 1777 namespace ns2 { void baz(); } 1780 using namespace ns1::qq; 1781 void ns1::ns2::b^az() { Foo f; B b; })cpp", 1784 namespace qq { struct Foo { struct Bar {}; }; using B = Foo::Bar; } 1785 namespace ns2 { void baz(){ qq::Foo f; qq::B b; } } 1788 using namespace ns1::qq; 1793 template<class T> struct Foo { template <class U> struct Bar {}; }; 1794 template<class T, class U> 1795 using B = typename Foo<T>::template Bar<U>; 1797 namespace ns2 { void baz(); } 1800 using namespace ns1::qq; 1801 void ns1::ns2::b^az() { B<int, bool> b; })cpp", 1805 template<class T> struct Foo { template <class U> struct Bar {}; }; 1806 template<class T, class U> 1807 using B = typename Foo<T>::template Bar<U>; 1809 namespace ns2 { void baz(){ qq::B<int, bool> b; } } 1812 using namespace ns1::qq; 1815 for (
const auto &Case : Cases)
1816 EXPECT_EQ(apply(Case.Test), Case.Expected) << Case.Test;
1819 TEST_F(DefineInlineTest, QualifyWithUsingDirectives) {
1820 llvm::StringRef Test = R
"cpp( 1823 namespace b { struct Foo{}; void aux(); } 1824 namespace c { void cux(); } 1838 // FIXME: The last reference to cux() in body of foo should not be 1839 // qualified, since there is a using directive inside the function body. 1845 namespace b { struct Foo{}; void aux(); } 1846 namespace c { void cux(); } 1856 // FIXME: The last reference to cux() in body of foo should not be 1857 // qualified, since there is a using directive inside the function body. 1864 EXPECT_EQ(apply(Test), Expected) << Test; 1867 TEST_F(DefineInlineTest, AddInline) { 1868 ExtraArgs.push_back("-fno-delayed-template-parsing");
1869 llvm::StringMap<std::string> EditedFiles;
1870 ExtraFiles[
"a.h"] =
"void foo();";
1871 apply(R
"cpp(#include "a.h" 1872 void fo^o() {})cpp", 1874 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents( 1875 testPath("a.h"),
"inline void foo(){}")));
1878 ExtraFiles[
"a.h"] =
"const int foo();";
1879 apply(R
"cpp(#include "a.h" 1880 const int fo^o() {})cpp", 1882 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents( 1883 testPath("a.h"),
"inline const int foo(){}")));
1886 ExtraFiles[
"a.h"] =
"inline void foo();";
1887 apply(R
"cpp(#include "a.h" 1888 inline void fo^o() {})cpp", 1890 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents( 1891 testPath("a.h"),
"inline void foo(){}")));
1894 ExtraFiles[
"a.h"] =
"constexpr void foo();";
1895 apply(R
"cpp(#include "a.h" 1896 constexpr void fo^o() {})cpp", 1898 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents( 1899 testPath("a.h"),
"constexpr void foo(){}")));
1902 ExtraFiles[
"a.h"] =
"struct Foo { void foo(); }";
1903 apply(R
"cpp(#include "a.h" 1904 void Foo::fo^o() {})cpp", 1906 EXPECT_THAT(EditedFiles, 1907 testing::ElementsAre(FileWithContents( 1908 testPath("a.h"),
"struct Foo { void foo(){} }")));
1911 ExtraFiles[
"a.h"] =
"template <typename T> void foo();";
1912 apply(R
"cpp(#include "a.h" 1913 template <typename T> 1914 void fo^o() {})cpp", 1916 EXPECT_THAT(EditedFiles, 1917 testing::ElementsAre(FileWithContents( 1918 testPath("a.h"),
"template <typename T> void foo(){}")));
1921 ExtraFiles[
"a.h"] = R
"cpp( 1922 template <typename T> void foo(); 1923 template <> void foo<int>();)cpp"; 1924 apply(R"cpp(#include "a.h" 1926 void fo^o<int>() {})cpp", 1928 EXPECT_THAT(EditedFiles, 1929 testing::ElementsAre(FileWithContents(testPath("a.h"),
1931 template <typename T> void foo(); 1932 template <> inline void foo<int>(){})cpp"))); 1936 TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) { 1940 [[void [[f^o^o]]() [[{ 1950 [[vo^id ]]foo[[()]] {[[ 1957 [[void [[f^o^o]]() [[{ 1967 [[void [[Bar::[[b^a^z]]]]() [[{ 1974 [[void [[f^o^o]]() [[{ return; }]]]] 1978 [[void [[f^o^o]]() [[{ 1986 F^oo(const Foo&) = delete; 1992 template <typename> struct Foo { void fo^o(){} }; 1996 TEST_F(DefineOutlineTest, FailsWithoutSource) { 1998 llvm::StringRef Test =
"void fo^o() { return; }";
1999 llvm::StringRef Expected =
2000 "fail: Couldn't find a suitable implementation file.";
2001 EXPECT_EQ(apply(Test), Expected);
2004 TEST_F(DefineOutlineTest, ApplyTest) {
2005 llvm::StringMap<std::string> EditedFiles;
2006 ExtraFiles[
"Test.cpp"] =
"";
2010 ExtraArgs.push_back(
"-fno-delayed-template-parsing");
2013 llvm::StringRef Test;
2014 llvm::StringRef ExpectedHeader;
2015 llvm::StringRef ExpectedSource;
2019 "void fo^o() { return; }",
2021 "void foo() { return; }",
2025 "template <typename T> void fo^o(T, T x) { return; }",
2026 "template <typename T> void foo(T, T x) ;",
2027 "template <typename T> void foo(T, T x) { return; }",
2030 "template <typename> void fo^o() { return; }",
2031 "template <typename> void foo() ;",
2032 "template <typename> void foo() { return; }",
2037 template <typename> void foo(); 2038 template <> void fo^o<int>() { return; })cpp", 2040 template <typename> void foo(); 2041 template <> void foo<int>() ;)cpp", 2042 "template <> void foo<int>() { return; }",
2046 "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
2047 "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
2048 "void foo(int x, int y , int , int (*foo)(int) ) {}",
2055 F^oo(int z) __attribute__((weak)) : bar(2){} 2062 Foo(int z) __attribute__((weak)) ; 2066 "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
2072 virtual void f^oo() {} 2076 virtual void foo() ; 2078 " void A::foo() {}\n",
2083 virtual virtual void virtual f^oo() {} 2087 virtual virtual void virtual foo() ; 2089 " void A::foo() {}\n",
2094 virtual void foo() = 0; 2097 void fo^o() override {} 2101 virtual void foo() = 0; 2104 void foo() override ; 2106 "void B::foo() {}\n",
2111 virtual void foo() = 0; 2114 void fo^o() final {} 2118 virtual void foo() = 0; 2123 "void B::foo() {}\n",
2128 virtual void foo() = 0; 2131 void fo^o() final override {} 2135 virtual void foo() = 0; 2138 void foo() final override ; 2140 "void B::foo() {}\n",
2143 for (
const auto &Case : Cases) {
2144 SCOPED_TRACE(Case.Test);
2145 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2146 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2147 testPath(
"Test.cpp"), Case.ExpectedSource)));
2151 TEST_F(DefineOutlineTest, HandleMacros) {
2152 llvm::StringMap<std::string> EditedFiles;
2153 ExtraFiles[
"Test.cpp"] =
"";
2155 ExtraArgs.push_back(
"-DVIRTUAL=virtual");
2156 ExtraArgs.push_back(
"-DOVER=override");
2159 llvm::StringRef Test;
2160 llvm::StringRef ExpectedHeader;
2161 llvm::StringRef ExpectedSource;
2164 #define BODY { return; } 2165 void f^oo()BODY)cpp", 2167 #define BODY { return; } 2172 #define BODY return; 2173 void f^oo(){BODY})cpp", 2175 #define BODY return; 2177 "void foo(){BODY}"},
2180 #define TARGET void foo() 2181 [[TARGET]]{ return; })cpp", 2183 #define TARGET void foo() 2185 "TARGET{ return; }"},
2189 void [[TARGET]](){ return; })cpp", 2192 void TARGET();)cpp", 2193 "void TARGET(){ return; }"},
2194 {R
"cpp(#define VIRT virtual 2198 R"cpp(#define VIRT virtual 2202 " void A::foo() {}\n"},
2205 VIRTUAL void f^oo() {} 2209 VIRTUAL void foo() ; 2211 " void A::foo() {}\n"},
2214 virtual void foo() = 0; 2221 virtual void foo() = 0; 2226 "void B::foo() {}\n"},
2227 {R
"cpp(#define STUPID_MACRO(X) virtual 2229 STUPID_MACRO(sizeof sizeof int) void f^oo() {} 2231 R"cpp(#define STUPID_MACRO(X) virtual 2233 STUPID_MACRO(sizeof sizeof int) void foo() ; 2235 " void A::foo() {}\n"},
2237 for (
const auto &Case : Cases) {
2238 SCOPED_TRACE(Case.Test);
2239 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2240 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2241 testPath(
"Test.cpp"), Case.ExpectedSource)));
2245 TEST_F(DefineOutlineTest, QualifyReturnValue) {
2247 ExtraFiles[
"Test.cpp"] =
"";
2250 llvm::StringRef Test;
2251 llvm::StringRef ExpectedHeader;
2252 llvm::StringRef ExpectedSource;
2255 namespace a { class Foo; } 2257 Foo fo^o() { return; })cpp", 2259 namespace a { class Foo; } 2262 "a::Foo foo() { return; }"},
2267 Bar fo^o() { return {}; } 2277 "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
2280 Foo fo^o() { return; })cpp", 2284 "Foo foo() { return; }"},
2286 llvm::StringMap<std::string> EditedFiles;
2287 for (
auto &Case : Cases) {
2288 apply(Case.Test, &EditedFiles);
2289 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
2290 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2291 testPath(
"Test.cpp"), Case.ExpectedSource)));
2295 TEST_F(DefineOutlineTest, QualifyFunctionName) {
2298 llvm::StringRef TestHeader;
2299 llvm::StringRef TestSource;
2300 llvm::StringRef ExpectedHeader;
2301 llvm::StringRef ExpectedSource;
2321 "void a::b::Foo::foo() {}\n",
2324 "namespace a { namespace b { void f^oo() {} } }",
2326 "namespace a { namespace b { void foo() ; } }",
2327 "namespace a{void b::foo() {} }",
2330 "namespace a { namespace b { void f^oo() {} } }",
2331 "using namespace a;",
2332 "namespace a { namespace b { void foo() ; } }",
2335 "using namespace a;void a::b::foo() {} ",
2338 llvm::StringMap<std::string> EditedFiles;
2339 for (
auto &Case : Cases) {
2340 ExtraFiles[
"Test.cpp"] = Case.TestSource;
2341 EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
2342 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
2343 testPath(
"Test.cpp"), Case.ExpectedSource)))
2348 TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
2350 ExtraFiles[
"Test.cpp"] =
"";
2351 ExtraArgs.push_back(
"-DFINALOVER=final override");
2353 std::pair<StringRef, StringRef> Cases[] = {
2356 #define VIRT virtual void 2360 "fail: define outline: Can't move out of line as function has a " 2361 "macro `virtual` specifier."},
2364 #define OVERFINAL final override 2366 virtual void foo() {} 2369 void fo^o() OVERFINAL {} 2371 "fail: define outline: Can't move out of line as function has a " 2372 "macro `override` specifier.\ndefine outline: Can't move out of line " 2373 "as function has a macro `final` specifier."},
2377 virtual void foo() {} 2380 void fo^o() FINALOVER {} 2382 "fail: define outline: Can't move out of line as function has a " 2383 "macro `override` specifier.\ndefine outline: Can't move out of line " 2384 "as function has a macro `final` specifier."},
2386 for (
const auto &Case : Cases) {
2387 EXPECT_EQ(apply(Case.first), Case.second);
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
#define TWEAK_TEST(TweakID)
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
#define EXPECT_UNAVAILABLE(MarkedCode)
TEST(BackgroundQueueTest, Priority)
std::string testPath(PathRef File)
std::string Path
A typedef to represent a file path.
llvm::StringMap< Edit > FileEdits
A mapping from absolute file path (the one used for accessing the underlying VFS) to edits...
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static llvm::Expected< std::pair< Path, Edit > > fileEdit(const SourceManager &SM, FileID FID, tooling::Replacements Replacements)
Path is the absolute, symlink-resolved path for the file pointed by FID in SM.
std::vector< const char * > Expected
#define EXPECT_AVAILABLE(MarkedCode)