21 #include "clang/Index/IndexingAction.h" 22 #include "llvm/ADT/None.h" 23 #include "llvm/Support/Path.h" 24 #include "llvm/Support/ScopedPrinter.h" 25 #include "gmock/gmock.h" 26 #include "gtest/gtest.h" 33 using ::testing::ElementsAre;
34 using ::testing::IsEmpty;
35 using ::testing::Matcher;
36 using ::testing::UnorderedElementsAreArray;
38 class IgnoreDiagnostics :
public DiagnosticsConsumer {
40 std::vector<Diag> Diagnostics)
override {}
49 Matcher<const std::vector<DocumentHighlight> &>
50 HighlightsFrom(
const Annotations &Test) {
51 std::vector<DocumentHighlight>
Expected;
53 Expected.emplace_back();
54 Expected.back().range = R;
55 Expected.back().kind = K;
57 for (
const auto &
Range : Test.ranges())
59 for (
const auto &
Range : Test.ranges(
"read"))
61 for (
const auto &
Range : Test.ranges(
"write"))
63 return UnorderedElementsAreArray(Expected);
67 const char *Tests[] = {
68 R
"cpp(// Local variable 71 $write[[^bonjour]] = 2; 72 int test1 = $read[[bonjour]]; 79 static void foo([[MyClass]]*) {} 83 ns1::[[My^Class]]* Params; 95 R"cpp(// Function parameter in decl 96 void foo(int [[^bar]]); 99 for (
const char *Test : Tests) {
107 MATCHER_P3(Sym,
Name, Decl, DefOrNone,
"") {
108 llvm::Optional<Range> Def = DefOrNone;
109 if (
Name != arg.Name) {
110 *result_listener <<
"Name is " << arg.Name;
113 if (Decl != arg.PreferredDeclaration.range) {
114 *result_listener <<
"Declaration is " 115 << llvm::to_string(arg.PreferredDeclaration);
118 if (Def && !arg.Definition) {
119 *result_listener <<
"Has no definition";
122 if (Def && arg.Definition->range != *Def) {
123 *result_listener <<
"Definition is " << llvm::to_string(arg.Definition);
128 ::testing::Matcher<LocatedSymbol> Sym(std::string
Name,
Range Decl) {
133 MATCHER_P(RangeIs, R,
"") {
return arg.range == R; }
135 TEST(LocateSymbol, WithIndex) {
136 Annotations SymbolHeader(R
"cpp( 137 class $forward[[Forward]]; 138 class $foo[[Foo]] {}; 142 inline void $f2[[f2]]() {} 144 Annotations SymbolCpp(R"cpp( 145 class $forward[[forward]] {}; 150 TU.Code = SymbolCpp.code(); 151 TU.HeaderCode = SymbolHeader.code(); 152 auto Index = TU.index();
153 auto LocateWithIndex = [&
Index](
const Annotations &Main) {
158 Annotations Test(R
"cpp(// only declaration in AST. 164 EXPECT_THAT(LocateWithIndex(Test), 165 ElementsAre(Sym("f1", Test.range(), SymbolCpp.range(
"f1"))));
167 Test = Annotations(R
"cpp(// definition in AST. 173 EXPECT_THAT(LocateWithIndex(Test), 174 ElementsAre(Sym("f1", SymbolHeader.range(
"f1"), Test.range())));
176 Test = Annotations(R
"cpp(// forward declaration in AST. 180 EXPECT_THAT(LocateWithIndex(Test), 181 ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range(
"foo"))));
183 Test = Annotations(R
"cpp(// defintion in AST. 184 class [[Forward]] {}; 188 LocateWithIndex(Test), 189 ElementsAre(Sym("Forward", SymbolHeader.range(
"forward"), Test.range())));
192 TEST(LocateSymbol, WithIndexPreferredLocation) {
193 Annotations SymbolHeader(R
"cpp( 194 class $p[[Proto]] {}; 195 void $f[[func]]() {}; 198 TU.HeaderCode = SymbolHeader.code(); 199 TU.HeaderFilename = "x.proto";
200 auto Index = TU.index();
202 Annotations Test(R
"cpp(// only declaration in AST. 203 // Shift to make range different. 215 auto CodeGenLoc = SymbolHeader.range(
"p");
216 EXPECT_THAT(Locs, ElementsAre(Sym(
"Proto", CodeGenLoc, CodeGenLoc)));
220 auto CodeGenLoc = SymbolHeader.range(
"f");
221 EXPECT_THAT(Locs, ElementsAre(Sym(
"func", CodeGenLoc, CodeGenLoc)));
230 const char *Tests[] = {
231 R
"cpp(// Local variable 241 struct [[MyClass]] {}; 244 ns1::My^Class* Params; 248 R"cpp(// Function definition via pointer 255 R"cpp(// Function declaration via call 256 int $decl[[foo]](int); 263 struct Foo { int [[x]]; }; 270 R"cpp(// Field, member initializer 277 R"cpp(// Field, GNU old-style field designator 278 struct Foo { int [[x]]; }; 280 Foo bar = { ^x : 1 }; 284 R"cpp(// Field, field designator 285 struct Foo { int [[x]]; }; 287 Foo bar = { .^x = 2 }; 292 struct Foo { int $decl[[x]](); }; 300 typedef int $decl[[Foo]]; 306 R"cpp(// Template type parameter 307 template <typename [[T]]> 311 R"cpp(// Template template type parameter 312 template <template<typename> class [[T]]> 313 void foo() { ^T<int> t; } 317 namespace $decl[[ns]] { 318 struct Foo { static void bar(); } 320 int main() { ^ns::Foo::bar(); } 326 int main() { return ^MACRO; } 332 class TTT { public: int a; }; 333 #define [[FF]](S) if (int b = S.a) {} 340 R"cpp(// Macro argument 342 #define ADDRESSOF(X) &X; 343 int *j = ADDRESSOF(^i); 346 R"cpp(// Symbol concatenated inside macro (not supported) 348 #define POINTER(X) p # X; 349 int i = *POINTER(^i); 352 R"cpp(// Forward class declaration 358 R"cpp(// Function declaration 365 #define FF(name) class name##_Test {}; 367 void f() { my^_Test a; } 371 #define FF() class [[Test]] {}; 373 void f() { T^est a; } 376 R"cpp(// explicit template specialization 377 template <typename T> 378 struct Foo { void bar() {} }; 381 struct [[Foo]]<int> { void bar() {} }; 389 R"cpp(// implicit template specialization 390 template <typename T> 391 struct [[Foo]] { void bar() {} }; 393 struct Foo<int> { void bar() {} }; 400 R"cpp(// partial template specialization 401 template <typename T> 402 struct Foo { void bar() {} }; 403 template <typename T> 404 struct [[Foo]]<T*> { void bar() {} }; 408 R"cpp(// function template specializations 418 R"cpp(// variable template decls 423 double [[var]]<int> = 10; 425 double y = va^r<int>; 428 R"cpp(// No implicit constructors 438 for (
const char *Test : Tests) {
440 llvm::Optional<Range> WantDecl;
441 llvm::Optional<Range> WantDef;
442 if (!T.ranges().empty())
443 WantDecl = WantDef = T.range();
444 if (!T.ranges(
"decl").empty())
445 WantDecl = T.range(
"decl");
446 if (!T.ranges(
"def").empty())
447 WantDef = T.range(
"def");
453 EXPECT_THAT(
Results, IsEmpty()) << Test;
455 ASSERT_THAT(
Results, ::testing::SizeIs(1)) << Test;
456 EXPECT_EQ(
Results[0].PreferredDeclaration.range, *WantDecl) << Test;
457 llvm::Optional<Range> GotDef;
459 GotDef =
Results[0].Definition->range;
460 EXPECT_EQ(WantDef, GotDef) << Test;
465 TEST(LocateSymbol, Ambiguous) {
466 auto T = Annotations(R
"cpp( 478 const char* str = "123"; 486 Foo foox = Fo$9^o("asdf"); 499 ElementsAre(Sym(
"Foo"), Sym(
"abcd")));
502 ElementsAre(Sym(
"Foo"), Sym(
"Foo")));
505 TEST(LocateSymbol, TemplateTypedefs) {
506 auto T = Annotations(R
"cpp( 507 template <class T> struct function {}; 508 template <class T> using callback = function<T()>; 516 TEST(LocateSymbol, RelPathsInCompileCommand) {
520 Annotations SourceAnnotations(R
"cpp( 521 #include "header_in_preamble.h" 523 #include "header_not_in_preamble.h" 524 int baz = f$p1^oo + bar_pre$p2^amble + bar_not_pre$p3^amble; 527 Annotations HeaderInPreambleAnnotations(R"cpp( 528 int [[bar_preamble]]; 531 Annotations HeaderNotInPreambleAnnotations(R"cpp( 532 int [[bar_not_preamble]]; 537 SmallString<32> RelPathPrefix(
"..");
538 llvm::sys::path::append(RelPathPrefix,
"src");
539 std::string BuildDir =
testPath(
"build");
540 MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
547 auto FooCpp =
testPath(
"src/foo.cpp");
548 FS.Files[FooCpp] =
"";
549 auto HeaderInPreambleH =
testPath(
"src/header_in_preamble.h");
550 FS.Files[HeaderInPreambleH] = HeaderInPreambleAnnotations.code();
551 auto HeaderNotInPreambleH =
testPath(
"src/header_not_in_preamble.h");
552 FS.Files[HeaderNotInPreambleH] = HeaderNotInPreambleAnnotations.code();
559 EXPECT_TRUE(
bool(Locations)) <<
"findDefinitions returned an error";
560 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo", SourceAnnotations.range())));
564 EXPECT_TRUE(
bool(Locations)) <<
"findDefinitions returned an error";
567 ElementsAre(Sym(
"bar_preamble", HeaderInPreambleAnnotations.range())));
571 EXPECT_TRUE(
bool(Locations)) <<
"findDefinitions returned an error";
572 EXPECT_THAT(*Locations,
573 ElementsAre(Sym(
"bar_not_preamble",
574 HeaderNotInPreambleAnnotations.range())));
577 TEST(Hover, Structured) {
579 const char *
const Code;
580 const std::function<void(HoverInfo &)> ExpectedBuilder;
588 HI.NamespaceScope = "";
591 HI.Documentation =
"Best foo ever.";
592 HI.Definition =
"void foo()";
593 HI.ReturnType =
"void";
595 HI.Parameters.emplace();
599 namespace ns1 { namespace ns2 { 605 HI.NamespaceScope =
"ns1::ns2::";
608 HI.Documentation =
"Best foo ever.";
609 HI.Definition =
"void foo()";
610 HI.ReturnType =
"void";
612 HI.Parameters.emplace();
616 namespace ns1 { namespace ns2 { 623 HI.NamespaceScope = "ns1::ns2::";
624 HI.LocalScope =
"Foo::";
627 HI.Definition =
"int bar";
632 namespace ns1 { namespace ns2 { 641 HI.NamespaceScope = "ns1::ns2::";
642 HI.LocalScope =
"Foo::foo::";
645 HI.Definition =
"int bar";
650 namespace ns1 { namespace { 657 HI.NamespaceScope = "ns1::(anonymous)::";
658 HI.LocalScope =
"(anonymous struct)::";
661 HI.Definition =
"int bar";
666 template <typename T, class... Ts> class Foo { public: Foo(int); }; 667 Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5); 670 HI.NamespaceScope = "";
673 HI.Definition =
"Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
674 HI.Type =
"Foo<int, char, bool>";
678 template <typename T> class vector{}; 679 [[vec^tor]]<int> foo; 682 HI.NamespaceScope = "";
685 HI.Definition =
"template <typename T> class vector {}";
686 HI.TemplateParameters = {
687 {std::string(
"typename"), std::string(
"T"),
llvm::None},
692 template <template<typename, bool...> class C, 696 class... Ts> class Foo {}; 697 template <template<typename, bool...> class T> 701 HI.NamespaceScope = "";
705 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0, 706 bool Q = false, class... Ts> 708 HI.TemplateParameters = { 709 {std::string("template <typename, bool...> class"),
711 {std::string(
"typename"),
llvm::None, std::string(
"char")},
712 {std::string(
"int"),
llvm::None, std::string(
"0")},
713 {std::string(
"bool"), std::string(
"Q"), std::string(
"false")},
714 {std::string(
"class..."), std::string(
"Ts"),
llvm::None},
719 template <template<typename, bool...> class C, 723 class... Ts> void foo(); 724 template<typename, bool...> class Foo; 731 HI.NamespaceScope = "";
735 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0, 736 bool Q = false, class... Ts> 738 HI.ReturnType = "void";
740 HI.Parameters.emplace();
741 HI.TemplateParameters = {
742 {std::string(
"template <typename, bool...> class"),
744 {std::string(
"typename"),
llvm::None, std::string(
"char")},
745 {std::string(
"int"),
llvm::None, std::string(
"0")},
746 {std::string(
"bool"), std::string(
"Q"), std::string(
"false")},
747 {std::string(
"class..."), std::string(
"Ts"),
llvm::None},
752 template<typename, bool...> class Foo {}; 753 Foo<bool, true, false> foo(int, bool T = false); 760 HI.NamespaceScope = "";
763 HI.Definition =
"Foo<bool, true, false> foo(int, bool T = false)";
764 HI.ReturnType =
"Foo<bool, true, false>";
765 HI.Type =
"Foo<bool, true, false> (int, bool)";
768 {std::string(
"bool"), std::string(
"T"), std::string(
"false")},
774 auto lamb = [](int T, bool B) -> bool { return T && B; }; 780 HI.NamespaceScope = "";
781 HI.LocalScope =
"foo::";
784 HI.Definition =
"auto *c = &b";
785 HI.Type =
"class (lambda) **";
786 HI.ReturnType =
"bool";
788 {std::string(
"int"), std::string(
"T"),
llvm::None},
789 {std::string(
"bool"), std::string(
"B"),
llvm::None},
795 auto lamb = [](int T, bool B) -> bool { return T && B; }; 796 void foo(decltype(lamb)& bar) { 801 HI.NamespaceScope = "";
802 HI.LocalScope =
"foo::";
805 HI.Definition =
"decltype(lamb) &bar";
806 HI.Type =
"decltype(lamb) &";
807 HI.ReturnType =
"bool";
809 {std::string(
"int"), std::string(
"T"),
llvm::None},
810 {std::string(
"bool"), std::string(
"B"),
llvm::None},
816 auto lamb = [](int T, bool B) -> bool { return T && B; }; 817 void foo(decltype(lamb) bar) { 822 HI.NamespaceScope = "";
823 HI.LocalScope =
"foo::";
826 HI.Definition =
"decltype(lamb) bar";
827 HI.Type =
"class (lambda)";
828 HI.ReturnType =
"bool";
830 {std::string(
"int"), std::string(
"T"),
llvm::None},
831 {std::string(
"bool"), std::string(
"B"),
llvm::None},
839 auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; }; 840 bool res = [[lam^b]](bar, false); 844 HI.NamespaceScope = "";
845 HI.LocalScope =
"foo::";
848 HI.Definition =
"auto lamb = [&bar](int T, bool B) -> bool {}";
849 HI.Type =
"class (lambda)";
850 HI.ReturnType =
"bool";
852 {std::string(
"int"), std::string(
"T"),
llvm::None},
853 {std::string(
"bool"), std::string(
"B"),
llvm::None},
860 auto lamb = []{int [[te^st]];}; 864 HI.NamespaceScope = "";
865 HI.LocalScope =
"foo::(anonymous class)::operator()::";
868 HI.Definition =
"int test";
875 [[au^to]] lamb = []{}; 879 HI.Name = "class (lambda)";
884 template<typename T> class Foo{}; 886 [[au^to]] x = Foo<int>(); 890 HI.Name = "class Foo<int>";
895 template<typename T> class Foo{}; 896 template<> class Foo<int>{}; 898 [[au^to]] x = Foo<int>(); 902 HI.Name = "class Foo<int>";
909 #define MACRO(x,y,z) void foo(x, y, z); 910 [[MAC^RO]](int, double d, bool z = false); 914 HI.Definition =
"#define MACRO(x, y, z) void foo(x, y, z);";
919 constexpr int add(int a, int b) { return a + b; } 920 int [[b^ar]] = add(1, 2); 924 HI.Definition =
"int bar = add(1, 2)";
927 HI.NamespaceScope =
"";
931 int [[b^ar]] = sizeof(char); 935 HI.Definition =
"int bar = sizeof(char)";
938 HI.NamespaceScope =
"";
942 template<int a, int b> struct Add { 943 static constexpr int result = a + b; 945 int [[ba^r]] = Add<1, 2>::result; 949 HI.Definition =
"int bar = Add<1, 2>::result";
952 HI.NamespaceScope =
"";
958 template<int a, int b> struct Add { 959 static constexpr int result = a + b; 961 int bar = Add<1, 2>::[[resu^lt]]; 965 HI.Definition =
"static constexpr int result = a + b";
967 HI.Type =
"const int";
968 HI.NamespaceScope =
"";
969 HI.LocalScope =
"Add::";
972 const char *[[ba^r]] = "1234"; 976 HI.Definition =
"const char *bar = \"1234\"";
978 HI.Type =
"const char *";
979 HI.NamespaceScope =
"";
980 HI.Value =
"&\"1234\"[0]";
983 for (
const auto &Case : Cases) {
984 SCOPED_TRACE(Case.Code);
986 Annotations T(Case.Code);
989 auto AST = TU.build();
990 ASSERT_TRUE(
AST.getDiagnostics().empty());
992 auto H =
getHover(
AST, T.point(), format::getLLVMStyle(),
nullptr);
995 Expected.SymRange = T.range();
996 Case.ExpectedBuilder(Expected);
998 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
999 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1000 EXPECT_EQ(H->Name, Expected.Name);
1001 EXPECT_EQ(H->Kind, Expected.Kind);
1002 EXPECT_EQ(H->Documentation, Expected.Documentation);
1003 EXPECT_EQ(H->Definition, Expected.Definition);
1004 EXPECT_EQ(H->Type, Expected.Type);
1005 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1006 EXPECT_EQ(H->Parameters, Expected.Parameters);
1007 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1008 EXPECT_EQ(H->SymRange, Expected.SymRange);
1009 EXPECT_EQ(H->Value, Expected.Value);
1016 StringRef ExpectedHover;
1028 R
"cpp(// Local variable 1032 int test1 = bonjour; 1035 "text[Declared in]code[main]\n" 1036 "codeblock(cpp) [\n" 1041 R
"cpp(// Local variable in method 1049 "text[Declared in]code[s::method]\n" 1050 "codeblock(cpp) [\n" 1060 ns1::My^Class* Params; 1063 "text[Declared in]code[ns1]\n" 1064 "codeblock(cpp) [\n" 1065 "struct MyClass {}\n" 1074 ns1::My^Class* Params; 1077 "text[Declared in]code[ns1]\n" 1078 "codeblock(cpp) [\n" 1079 "class MyClass {}\n" 1085 union MyUnion { int x; int y; }; 1088 ns1::My^Union Params; 1091 "text[Declared in]code[ns1]\n" 1092 "codeblock(cpp) [\n" 1093 "union MyUnion {}\n" 1097 R
"cpp(// Function definition via pointer 1103 "text[Declared in]code[global namespace]\n" 1104 "codeblock(cpp) [\n" 1107 "text[Function definition via pointer]",
1110 R
"cpp(// Function declaration via call 1116 "text[Declared in]code[global namespace]\n" 1117 "codeblock(cpp) [\n" 1120 "text[Function declaration via call]",
1124 struct Foo { int x; }; 1130 "text[Declared in]code[Foo]\n" 1131 "codeblock(cpp) [\n" 1136 R
"cpp(// Field with initialization 1137 struct Foo { int x = 5; }; 1143 "text[Declared in]code[Foo]\n" 1144 "codeblock(cpp) [\n" 1149 R
"cpp(// Static field 1150 struct Foo { static int x; }; 1155 "text[Declared in]code[Foo]\n" 1156 "codeblock(cpp) [\n" 1161 R
"cpp(// Field, member initializer 1167 "text[Declared in]code[Foo]\n" 1168 "codeblock(cpp) [\n" 1173 R
"cpp(// Field, GNU old-style field designator 1174 struct Foo { int x; }; 1176 Foo bar = { ^x : 1 }; 1179 "text[Declared in]code[Foo]\n" 1180 "codeblock(cpp) [\n" 1185 R
"cpp(// Field, field designator 1186 struct Foo { int x; }; 1188 Foo bar = { .^x = 2 }; 1191 "text[Declared in]code[Foo]\n" 1192 "codeblock(cpp) [\n" 1197 R
"cpp(// Method call 1198 struct Foo { int x(); }; 1204 "text[Declared in]code[Foo]\n" 1205 "codeblock(cpp) [\n" 1210 R
"cpp(// Static method call 1211 struct Foo { static int x(); }; 1216 "text[Declared in]code[Foo]\n" 1217 "codeblock(cpp) [\n" 1228 "text[Declared in]code[global namespace]\n" 1229 "codeblock(cpp) [\n" 1237 struct Foo { static void bar(); } 1239 int main() { ^ns::Foo::bar(); } 1241 "text[Declared in]code[global namespace]\n" 1242 "codeblock(cpp) [\n" 1247 R
"cpp(// Anonymous namespace 1251 } // anonymous namespace 1253 int main() { ns::f^oo++; } 1255 "text[Declared in]code[ns::(anonymous)]\n" 1256 "codeblock(cpp) [\n" 1264 int main() { return ^MACRO; } 1268 "codeblock(cpp) [\n" 1275 #define MACRO2 ^MACRO 1277 "codeblock(cpp) [\n" 1288 R"cpp(codeblock(cpp) [ 1294 R"cpp(// Forward class declaration 1299 "text[Declared in]code[global namespace]\n" 1300 "codeblock(cpp) [\n" 1303 "text[Forward class declaration]",
1306 R
"cpp(// Function declaration 1308 void g() { f^oo(); } 1311 "text[Declared in]code[global namespace]\n" 1312 "codeblock(cpp) [\n" 1315 "text[Function declaration]",
1318 R
"cpp(// Enum declaration 1326 "text[Declared in]code[global namespace]\n" 1327 "codeblock(cpp) [\n" 1330 "text[Enum declaration]",
1341 "text[Declared in]code[Hello]\n" 1342 "codeblock(cpp) [\n" 1347 R
"cpp(// Enumerator in anonymous enum 1355 "text[Declared in]code[global namespace]\n" 1356 "codeblock(cpp) [\n" 1361 R
"cpp(// Global variable 1362 static int hey = 10; 1367 "text[Declared in]code[global namespace]\n" 1368 "codeblock(cpp) [\n" 1369 "static int hey = 10\n" 1371 "text[Global variable]",
1374 R
"cpp(// Global variable in namespace 1376 static int hey = 10; 1382 "text[Declared in]code[ns1]\n" 1383 "codeblock(cpp) [\n" 1384 "static int hey = 10\n" 1388 R
"cpp(// Field in anonymous struct 1396 "text[Declared in]code[(anonymous struct)]\n" 1397 "codeblock(cpp) [\n" 1402 R
"cpp(// Templated function 1403 template <typename T> 1407 void g() { auto x = f^oo<int>(); } 1409 "text[Declared in]code[global namespace]\n" 1410 "codeblock(cpp) [\n" 1411 "template <typename T> T foo()\n" 1413 "text[Templated function]",
1416 R
"cpp(// Anonymous union 1422 void g() { struct outer o; o.v.d^ef++; } 1424 "text[Declared in]code[outer::(anonymous union)]\n" 1425 "codeblock(cpp) [\n" 1430 R
"cpp(// documentation from index 1431 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs; 1433 void g() { ind^exSymbol(); } 1435 "text[Declared in]code[global namespace]\n" 1436 "codeblock(cpp) [\n" 1437 "void indexSymbol()\n" 1439 "text[comment from index]",
1450 R
"cpp(// Simple initialization with auto 1455 "codeblock(cpp) [\n" 1460 R
"cpp(// Simple initialization with const auto 1465 "codeblock(cpp) [\n" 1470 R
"cpp(// Simple initialization with const auto& 1475 "codeblock(cpp) [\n" 1480 R
"cpp(// Simple initialization with auto& 1485 "codeblock(cpp) [\n" 1490 R
"cpp(// Simple initialization with auto* 1496 "codeblock(cpp) [\n" 1501 R
"cpp(// Auto with initializer list. 1505 class initializer_list {}; 1511 "codeblock(cpp) [\n" 1512 "class std::initializer_list<int>\n" 1516 R
"cpp(// User defined conversion to auto 1518 operator ^auto() const { return 10; } 1521 "codeblock(cpp) [\n" 1526 R
"cpp(// Simple initialization with decltype(auto) 1528 ^decltype(auto) i = 1; 1531 "codeblock(cpp) [\n" 1536 R
"cpp(// Simple initialization with const decltype(auto) 1539 ^decltype(auto) i = j; 1542 "codeblock(cpp) [\n" 1547 R
"cpp(// Simple initialization with const& decltype(auto) 1551 ^decltype(auto) i = j; 1554 "codeblock(cpp) [\n" 1559 R
"cpp(// Simple initialization with & decltype(auto) 1563 ^decltype(auto) i = j; 1566 "codeblock(cpp) [\n" 1571 R
"cpp(// decltype with initializer list: nothing 1575 class initializer_list {}; 1578 ^decltype(auto) i = {1,2}; 1584 R
"cpp(// simple trailing return type 1585 ^auto main() -> int { 1589 "codeblock(cpp) [\n" 1594 R
"cpp(// auto function return with trailing type 1596 ^auto test() -> decltype(Bar()) { 1600 "codeblock(cpp) [\n" 1605 R
"cpp(// trailing return type 1607 auto test() -> ^decltype(Bar()) { 1611 "codeblock(cpp) [\n" 1616 R
"cpp(// auto in function return 1622 "codeblock(cpp) [\n" 1627 R
"cpp(// auto& in function return 1633 "codeblock(cpp) [\n" 1638 R
"cpp(// auto* in function return 1645 "codeblock(cpp) [\n" 1650 R
"cpp(// const auto& in function return 1652 const ^auto& test() { 1656 "codeblock(cpp) [\n" 1661 R
"cpp(// decltype(auto) in function return 1663 ^decltype(auto) test() { 1667 "codeblock(cpp) [\n" 1672 R
"cpp(// decltype(auto) reference in function return 1674 ^decltype(auto) test() { 1679 "codeblock(cpp) [\n" 1684 R
"cpp(// decltype lvalue reference 1690 "codeblock(cpp) [\n" 1695 R
"cpp(// decltype lvalue reference 1702 "codeblock(cpp) [\n" 1707 R
"cpp(// decltype lvalue reference parenthesis 1710 ^decltype((I)) J = I; 1713 "codeblock(cpp) [\n" 1718 R
"cpp(// decltype rvalue reference 1721 ^decltype(static_cast<int&&>(I)) J = static_cast<int&&>(I); 1724 "codeblock(cpp) [\n" 1729 R
"cpp(// decltype rvalue reference function call 1733 ^decltype(bar()) J = bar(); 1736 "codeblock(cpp) [\n" 1741 R
"cpp(// decltype of function with trailing return type. 1743 auto test() -> decltype(Bar()) { 1747 ^decltype(test()) i = test(); 1750 "codeblock(cpp) [\n" 1755 R
"cpp(// decltype of var with decltype. 1762 "codeblock(cpp) [\n" 1767 R
"cpp(// structured binding. Not supported yet 1777 R
"cpp(// Template auto parameter. Nothing (Not useful). 1788 R
"cpp(// More compilcated structured types. 1790 ^auto (*foo)() = bar; 1792 "codeblock(cpp) [\n" 1797 R
"cpp(// Should not crash when evaluating the initializer. 1799 void test() { Test && te^st = {}; } 1801 "text[Declared in]code[test]\n" 1802 "codeblock(cpp) [\n" 1803 "struct Test &&test = {}\n" 1809 Symbol IndexSym =
func(
"indexSymbol");
1810 IndexSym.Documentation =
"comment from index";
1812 Symbols.insert(IndexSym);
1814 MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1816 for (
const OneTest &Test : Tests) {
1817 Annotations T(Test.Input);
1820 auto AST = TU.build();
1823 EXPECT_NE(
"", Test.ExpectedHover) << Test.Input;
1824 EXPECT_EQ(H->present().renderForTests(), Test.ExpectedHover.str())
1827 EXPECT_EQ(
"", Test.ExpectedHover.str()) << Test.Input;
1834 MockCompilationDatabase CDB;
1838 const char *SourceContents = R
"cpp( 1839 #include ^"$2^foo.h$3^" 1840 #include "$4^invalid.h" 1844 #in$5^clude "$6^foo.h"$7^ 1846 Annotations SourceAnnotations(SourceContents); 1847 FS.Files[FooCpp] = SourceAnnotations.code(); 1853 Annotations HeaderAnnotations(HeaderContents); 1854 FS.Files[FooH] = HeaderAnnotations.code(); 1856 Server.addDocument(FooH, HeaderAnnotations.code()); 1857 Server.addDocument(FooCpp, SourceAnnotations.code()); 1861 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1862 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1866 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1867 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1870 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1871 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1875 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1876 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1880 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1881 EXPECT_THAT(*Locations, IsEmpty());
1884 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1885 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1888 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1889 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1892 Annotations ObjC(R
"objc( 1896 FS.Files[FooM] = ObjC.code();
1898 Server.addDocument(FooM, ObjC.code());
1900 ASSERT_TRUE(
bool(Locations)) <<
"locateSymbolAt returned an error";
1901 EXPECT_THAT(*Locations, ElementsAre(Sym(
"foo.h", HeaderAnnotations.range())));
1904 TEST(LocateSymbol, WithPreamble) {
1909 MockCompilationDatabase CDB;
1914 Annotations FooWithHeader(R
"cpp(#include "fo^o.h")cpp"); 1915 Annotations FooWithoutHeader(R"cpp(double [[fo^o]]();)cpp"); 1917 FS.Files[FooCpp] = FooWithHeader.code(); 1920 Annotations FooHeader(R
"cpp([[]])cpp"); 1921 FS.Files[FooH] = FooHeader.code(); 1927 ElementsAre(Sym(
"foo.h", FooHeader.range())));
1935 ElementsAre(Sym(
"foo", FooWithoutHeader.range())));
1944 ElementsAre(Sym(
"foo", FooWithoutHeader.range())));
1947 TEST(FindReferences, WithinAST) {
1948 const char *Tests[] = {
1949 R
"cpp(// Local variable 1953 int test1 = [[foo]]; 1962 ns1::[[Fo^o]]* Params; 1966 R"cpp(// Forward declaration 1977 auto *X = &[[^foo]]; 1985 Foo() : [[foo]](0) {} 1993 R"cpp(// Method call 1994 struct Foo { int [[foo]](); }; 1995 int Foo::[[foo]]() {} 2002 R"cpp(// Constructor 2007 Foo f = [[Foo]](42); 2012 typedef int [[Foo]]; 2022 int main() { [[^ns]]::Foo foo; } 2025 for (
const char *Test : Tests) {
2026 Annotations T(Test);
2028 std::vector<Matcher<Location>> ExpectedLocations;
2029 for (
const auto &R : T.ranges())
2030 ExpectedLocations.push_back(RangeIs(R));
2032 ElementsAreArray(ExpectedLocations))
2037 TEST(FindReferences, ExplicitSymbols) {
2038 const char *Tests[] = {
2040 struct Foo { Foo* [self]() const; }; 2042 if (Foo* T = foo.[^self]()) {} // Foo member call expr. 2047 struct Foo { Foo(int); }; 2050 return [^b]; // Foo constructor expr. 2059 g([^f]()); // Foo constructor expr. 2072 for (
const char *Test : Tests) {
2073 Annotations T(Test);
2075 std::vector<Matcher<Location>> ExpectedLocations;
2076 for (
const auto &R : T.ranges())
2077 ExpectedLocations.push_back(RangeIs(R));
2079 ElementsAreArray(ExpectedLocations))
2084 TEST(FindReferences, NeedsIndex) {
2085 const char *Header =
"int foo();";
2086 Annotations Main(
"int main() { [[f^oo]](); }");
2088 TU.Code = Main.code();
2089 TU.HeaderCode = Header;
2090 auto AST = TU.build();
2094 ElementsAre(RangeIs(Main.range())));
2095 Annotations IndexedMain(R
"cpp( 2096 int main() { [[f^oo]](); } 2101 IndexedTU.Code = IndexedMain.code();
2102 IndexedTU.Filename =
"Indexed.cpp";
2103 IndexedTU.HeaderCode = Header;
2105 ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
2108 IndexedTU.index().get())
2113 TU.Code = (
"\n\n" + Main.code()).str();
2115 ElementsAre(RangeIs(Main.range())));
2118 TEST(FindReferences, NoQueryForLocalSymbols) {
2119 struct RecordingIndex :
public MemIndex {
2120 mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
2121 void refs(
const RefsRequest &Req,
2122 llvm::function_ref<
void(
const Ref &)>)
const override {
2133 {
"namespace { int ^x; }",
true},
2134 {
"static int ^x;",
true},
2136 {
"void foo() { int ^x; }",
false},
2137 {
"void foo() { struct ^x{}; }",
false},
2138 {
"auto lambda = []{ int ^x; };",
false},
2140 for (Test T : Tests) {
2141 Annotations
File(T.AnnotatedCode);
2146 EXPECT_NE(Rec.RefIDs,
None) << T.AnnotatedCode;
2148 EXPECT_EQ(Rec.RefIDs,
None) << T.AnnotatedCode;
2152 TEST(GetDeducedType, KwAutoExpansion) {
2157 {
"^auto i = 0;",
"int"},
2158 {
"^auto f(){ return 1;};",
"int"}
2160 for (Test T : Tests) {
2161 Annotations
File(T.AnnotatedCode);
2163 ASSERT_TRUE(
AST.getDiagnostics().empty())
2164 <<
AST.getDiagnostics().begin()->Message;
2165 SourceManagerForFile SM(
"foo.cpp",
File.code());
2167 for (Position Pos :
File.points()) {
2171 EXPECT_EQ(DeducedType->getAsString(), T.DeducedType);
llvm::Optional< QualType > getDeducedType(ParsedAST &AST, SourceLocation SourceLocationBeg)
Retrieves the deduced type at a given location (auto, decltype).
const char * AnnotatedCode
Diagnostics must be generated for this snapshot.
llvm::Expected< std::vector< LocatedSymbol > > runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos)
llvm::StringRef PathRef
A typedef to represent a ref to file path.
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
std::vector< CodeCompletionResult > Results
static Options optsForTest()
Documents should not be synced at all.
llvm::Expected< SourceLocation > sourceLocationInMainFile(const SourceManager &SM, Position P)
Return the file location, corresponding to P.
std::vector< const char * > ExtraArgs
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
llvm::Optional< HoverInfo > getHover(ParsedAST &AST, Position Pos, format::FormatStyle Style, const SymbolIndex *Index)
Get the hover information when hovering at Pos.
TEST(BackgroundQueueTest, Priority)
std::string testPath(PathRef File)
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
static URIForFile canonicalize(llvm::StringRef AbsPath, llvm::StringRef TUPath)
Canonicalizes AbsPath via URI.
static constexpr llvm::StringLiteral Name
std::vector< DocumentHighlight > findDocumentHighlights(ParsedAST &AST, Position Pos)
Returns highlights for all usages of a symbol at Pos.
static TestTU withCode(llvm::StringRef Code)
CodeCompletionBuilder Builder
std::vector< Location > findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, const SymbolIndex *Index)
Returns reference locations of the symbol at a specified Pos.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
std::vector< const char * > Expected
IgnoreDiagnostics DiagConsumer
std::vector< LocatedSymbol > locateSymbolAt(ParsedAST &AST, Position Pos, const SymbolIndex *Index)
Get definition of symbol at a specified Pos.
std::vector< HeaderEntry > HeaderContents
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags)
const SymbolIndex * Index
Symbol func(llvm::StringRef Name)