15 #include "clang/Index/IndexSymbol.h" 16 #include "llvm/ADT/None.h" 17 #include "llvm/ADT/StringRef.h" 19 #include "gmock/gmock.h" 20 #include "gtest/gtest.h" 28 TEST(Hover, Structured) {
30 const char *
const Code;
31 const std::function<void(HoverInfo &)> ExpectedBuilder;
39 HI.NamespaceScope = "";
41 HI.Kind = index::SymbolKind::Function;
42 HI.Documentation =
"Best foo ever.";
43 HI.Definition =
"void foo()";
44 HI.ReturnType =
"void";
46 HI.Parameters.emplace();
50 namespace ns1 { namespace ns2 { 56 HI.NamespaceScope =
"ns1::ns2::";
58 HI.Kind = index::SymbolKind::Function;
59 HI.Documentation =
"Best foo ever.";
60 HI.Definition =
"void foo()";
61 HI.ReturnType =
"void";
63 HI.Parameters.emplace();
67 namespace ns1 { namespace ns2 { 74 HI.NamespaceScope = "ns1::ns2::";
75 HI.LocalScope =
"Foo::";
77 HI.Kind = index::SymbolKind::Field;
78 HI.Definition =
"int bar";
83 namespace ns1 { namespace ns2 { 92 HI.NamespaceScope = "ns1::ns2::";
93 HI.LocalScope =
"Foo::foo::";
95 HI.Kind = index::SymbolKind::Variable;
96 HI.Definition =
"int bar";
101 namespace ns1 { namespace { 108 HI.NamespaceScope = "ns1::";
109 HI.LocalScope =
"(anonymous struct)::";
111 HI.Kind = index::SymbolKind::Field;
112 HI.Definition =
"int bar";
117 template <typename T, class... Ts> class Foo { public: Foo(int); }; 118 Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5); 121 HI.NamespaceScope = "";
123 HI.Kind = index::SymbolKind::Variable;
124 HI.Definition =
"Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
125 HI.Type =
"Foo<int, char, bool>";
129 template <typename T> class vector{}; 130 [[vec^tor]]<int> foo; 133 HI.NamespaceScope = "";
134 HI.Name =
"vector<int>";
135 HI.Kind = index::SymbolKind::Class;
136 HI.Definition =
"template <> class vector<int> {}";
140 template <template<typename, bool...> class C, 144 class... Ts> class Foo {}; 145 template <template<typename, bool...> class T> 149 HI.NamespaceScope = "";
151 HI.Kind = index::SymbolKind::Class;
153 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0, 154 bool Q = false, class... Ts> 156 HI.TemplateParameters = { 157 {std::string("template <typename, bool...> class"),
159 {std::string(
"typename"),
llvm::None, std::string(
"char")},
160 {std::string(
"int"),
llvm::None, std::string(
"0")},
161 {std::string(
"bool"), std::string(
"Q"), std::string(
"false")},
162 {std::string(
"class..."), std::string(
"Ts"),
llvm::None},
167 template <template<typename, bool...> class C, 171 class... Ts> void foo(); 172 template<typename, bool...> class Foo; 179 HI.NamespaceScope = "";
181 HI.Kind = index::SymbolKind::Function;
182 HI.Definition =
"template <> void foo<Foo, char, 0, false, <>>()";
183 HI.ReturnType =
"void";
185 HI.Parameters.emplace();
189 template<typename, bool...> class Foo {}; 190 Foo<bool, true, false> foo(int, bool T = false); 197 HI.NamespaceScope = "";
199 HI.Kind = index::SymbolKind::Function;
200 HI.Definition =
"Foo<bool, true, false> foo(int, bool T = false)";
201 HI.ReturnType =
"Foo<bool, true, false>";
202 HI.Type =
"Foo<bool, true, false> (int, bool)";
205 {std::string(
"bool"), std::string(
"T"), std::string(
"false")},
211 auto lamb = [](int T, bool B) -> bool { return T && B; }; 217 HI.NamespaceScope = "";
218 HI.LocalScope =
"foo::";
220 HI.Kind = index::SymbolKind::Variable;
221 HI.Definition =
"auto *c = &b";
222 HI.Type =
"class (lambda) **";
223 HI.ReturnType =
"bool";
225 {std::string(
"int"), std::string(
"T"),
llvm::None},
226 {std::string(
"bool"), std::string(
"B"),
llvm::None},
232 auto lamb = [](int T, bool B) -> bool { return T && B; }; 233 void foo(decltype(lamb)& bar) { 238 HI.NamespaceScope = "";
239 HI.LocalScope =
"foo::";
241 HI.Kind = index::SymbolKind::Parameter;
242 HI.Definition =
"decltype(lamb) &bar";
243 HI.Type =
"decltype(lamb) &";
244 HI.ReturnType =
"bool";
246 {std::string(
"int"), std::string(
"T"),
llvm::None},
247 {std::string(
"bool"), std::string(
"B"),
llvm::None},
253 auto lamb = [](int T, bool B) -> bool { return T && B; }; 254 void foo(decltype(lamb) bar) { 259 HI.NamespaceScope = "";
260 HI.LocalScope =
"foo::";
262 HI.Kind = index::SymbolKind::Parameter;
263 HI.Definition =
"decltype(lamb) bar";
264 HI.Type =
"class (lambda)";
265 HI.ReturnType =
"bool";
267 {std::string(
"int"), std::string(
"T"),
llvm::None},
268 {std::string(
"bool"), std::string(
"B"),
llvm::None},
277 auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; }; 278 bool res = [[lam^b]](bar, false); 282 HI.NamespaceScope = "";
283 HI.LocalScope =
"foo::";
285 HI.Kind = index::SymbolKind::Variable;
286 HI.Definition =
"auto lamb = [&bar](int T, bool B) -> bool {}";
287 HI.Type =
"class (lambda)";
288 HI.ReturnType =
"bool";
290 {std::string(
"int"), std::string(
"T"),
llvm::None},
291 {std::string(
"bool"), std::string(
"B"),
llvm::None},
298 auto lamb = []{int [[te^st]];}; 302 HI.NamespaceScope = "";
303 HI.LocalScope =
"foo::(anonymous class)::operator()::";
305 HI.Kind = index::SymbolKind::Variable;
306 HI.Definition =
"int test";
311 template <typename T> class X; 312 template <typename T> class [[^X]]<T*> {}; 316 HI.NamespaceScope =
"";
317 HI.Kind = index::SymbolKind::Class;
318 HI.Definition =
"template <typename T> class X<T *> {}";
322 template<typename, typename=void> struct X; 323 template<typename T> struct X<T*>{ [[^X]](); }; 326 HI.NamespaceScope = "";
328 HI.LocalScope =
"X<T *>::";
329 HI.Kind = index::SymbolKind::Constructor;
330 HI.Definition =
"X()";
331 HI.Parameters.emplace();
333 {
"class X { [[^~]]X(); };",
335 HI.NamespaceScope =
"";
337 HI.LocalScope =
"X::";
338 HI.Kind = index::SymbolKind::Destructor;
339 HI.Definition =
"~X()";
340 HI.Parameters.emplace();
342 {
"class X { operator [[in^t]](); };",
344 HI.NamespaceScope =
"";
345 HI.Name =
"operator int";
346 HI.LocalScope =
"X::";
347 HI.Kind = index::SymbolKind::ConversionFunction;
348 HI.Definition =
"operator int()";
349 HI.Parameters.emplace();
355 [[au^to]] lamb = []{}; 359 HI.Name = "(lambda)";
360 HI.Kind = index::SymbolKind::Class;
364 template<typename T> class Foo{}; 366 [[au^to]] x = Foo<int>(); 370 HI.Name = "Foo<int>";
371 HI.Kind = index::SymbolKind::Class;
375 template<typename T> class Foo{}; 376 template<> class Foo<int>{}; 378 [[au^to]] x = Foo<int>(); 382 HI.Name = "Foo<int>";
383 HI.Kind = index::SymbolKind::Class;
389 #define MACRO(x,y,z) void foo(x, y, z); 390 [[MAC^RO]](int, double d, bool z = false); 393 HI.Name = "MACRO", HI.Kind = index::SymbolKind::Macro,
394 HI.Definition =
"#define MACRO(x, y, z) void foo(x, y, z);";
399 constexpr int add(int a, int b) { return a + b; } 400 int [[b^ar]] = add(1, 2); 404 HI.Definition =
"int bar = add(1, 2)";
405 HI.Kind = index::SymbolKind::Variable;
407 HI.NamespaceScope =
"";
411 int [[b^ar]] = sizeof(char); 415 HI.Definition =
"int bar = sizeof(char)";
416 HI.Kind = index::SymbolKind::Variable;
418 HI.NamespaceScope =
"";
422 template<int a, int b> struct Add { 423 static constexpr int result = a + b; 425 int [[ba^r]] = Add<1, 2>::result; 429 HI.Definition =
"int bar = Add<1, 2>::result";
430 HI.Kind = index::SymbolKind::Variable;
432 HI.NamespaceScope =
"";
436 enum Color { RED, GREEN, }; 437 Color x = [[GR^EEN]]; 441 HI.NamespaceScope =
"";
442 HI.LocalScope =
"Color::";
443 HI.Definition =
"GREEN";
444 HI.Kind = index::SymbolKind::EnumConstant;
445 HI.Type =
"enum Color";
449 enum Color { RED, GREEN, }; 455 HI.NamespaceScope =
"";
456 HI.Definition =
"Color x = GREEN";
457 HI.Kind = index::SymbolKind::Variable;
458 HI.Type =
"enum Color";
459 HI.Value =
"GREEN (1)";
462 template<int a, int b> struct Add { 463 static constexpr int result = a + b; 465 int bar = Add<1, 2>::[[resu^lt]]; 469 HI.Definition =
"static constexpr int result = 1 + 2";
470 HI.Kind = index::SymbolKind::StaticProperty;
471 HI.Type =
"const int";
472 HI.NamespaceScope =
"";
473 HI.LocalScope =
"Add<1, 2>::";
477 constexpr int answer() { return 40 + 2; } 478 int x = [[ans^wer]](); 482 HI.Definition =
"constexpr int answer()";
483 HI.Kind = index::SymbolKind::Function;
485 HI.ReturnType =
"int";
486 HI.Parameters.emplace();
487 HI.NamespaceScope =
"";
491 const char *[[ba^r]] = "1234"; 495 HI.Definition =
"const char *bar = \"1234\"";
496 HI.Kind = index::SymbolKind::Variable;
497 HI.Type =
"const char *";
498 HI.NamespaceScope =
"";
499 HI.Value =
"&\"1234\"[0]";
501 {R
"cpp(// Should not crash 502 template <typename T> 507 template <typename A> 508 void boom(int name) { 509 new Tmpl<A>([[na^me]]); 513 HI.Definition =
"int name";
514 HI.Kind = index::SymbolKind::Parameter;
516 HI.NamespaceScope =
"";
517 HI.LocalScope =
"boom::";
520 R
"cpp(// Should not print inline or anon namespaces. 522 inline namespace in_ns { 526 inline namespace in_ns2 { 535 ns::a::b::[[F^oo]] x; 541 HI.Kind = index::SymbolKind::Class;
542 HI.NamespaceScope =
"ns::a::b::";
543 HI.Definition =
"class Foo {}";
547 template <typename T> class Foo {}; 550 [[^auto]] x = Foo<X>(); 555 HI.Kind = index::SymbolKind::Class;
559 // comment from primary 560 template <typename T> class Foo {}; 561 // comment from specialization 562 template <typename T> class Foo<T*> {}; 564 [[Fo^o]]<int*> *x = nullptr; 568 HI.Name = "Foo<int *>";
569 HI.Kind = index::SymbolKind::Class;
570 HI.NamespaceScope =
"";
571 HI.Definition =
"template <> class Foo<int *>";
574 HI.Documentation =
"comment from primary";
577 for (
const auto &Case : Cases) {
578 SCOPED_TRACE(Case.Code);
580 Annotations T(Case.Code);
585 TU.ExtraArgs.push_back(
"-fno-delayed-template-parsing");
588 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
589 auto AST = TU.
build();
592 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
nullptr);
595 Expected.SymRange = T.range();
596 Case.ExpectedBuilder(Expected);
598 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
599 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
600 EXPECT_EQ(H->Name, Expected.Name);
601 EXPECT_EQ(H->Kind, Expected.Kind);
602 EXPECT_EQ(H->Documentation, Expected.Documentation);
603 EXPECT_EQ(H->Definition, Expected.Definition);
604 EXPECT_EQ(H->Type, Expected.Type);
605 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
606 EXPECT_EQ(H->Parameters, Expected.Parameters);
607 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
608 EXPECT_EQ(H->SymRange, Expected.SymRange);
609 EXPECT_EQ(H->Value, Expected.Value);
613 TEST(Hover, NoHover) {
614 llvm::StringRef Tests[] = {
617 R
"cpp(// structured binding. Not supported yet 624 R"cpp(// Template auto parameter. Nothing (Not useful). 632 R"cpp(// non-named decls don't get hover. Don't crash! 633 ^static_assert(1, ""); 635 R"cpp(// non-evaluatable expr 636 template <typename T> void foo() { 637 (void)[[size^of]](T); 642 "auto x = ^(int){42};",
646 "auto x = ^nullptr;",
647 "auto x = ^\"asdf\";",
650 for (
const auto &Test : Tests) {
656 auto AST = TU.
build();
659 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
nullptr);
666 const char *
const Code;
667 const std::function<void(HoverInfo &)> ExpectedBuilder;
670 R
"cpp(// Local variable 679 HI.Kind = index::SymbolKind::Variable;
680 HI.NamespaceScope =
"";
681 HI.LocalScope =
"main::";
683 HI.Definition =
"int bonjour";
686 R
"cpp(// Local variable in method 696 HI.Kind = index::SymbolKind::Variable;
697 HI.NamespaceScope =
"";
698 HI.LocalScope =
"s::method::";
700 HI.Definition =
"int bonjour";
708 ns1::[[My^Class]]* Params; 713 HI.Kind = index::SymbolKind::Struct;
714 HI.NamespaceScope =
"ns1::";
715 HI.Definition =
"struct MyClass {}";
723 ns1::[[My^Class]]* Params; 728 HI.Kind = index::SymbolKind::Class;
729 HI.NamespaceScope =
"ns1::";
730 HI.Definition =
"class MyClass {}";
735 union MyUnion { int x; int y; }; 738 ns1::[[My^Union]] Params; 743 HI.Kind = index::SymbolKind::Union;
744 HI.NamespaceScope =
"ns1::";
745 HI.Definition =
"union MyUnion {}";
748 R
"cpp(// Function definition via pointer 756 HI.Kind = index::SymbolKind::Function;
757 HI.NamespaceScope =
"";
758 HI.Type =
"void (int)";
759 HI.Definition =
"void foo(int)";
760 HI.Documentation =
"Function definition via pointer";
761 HI.ReturnType =
"void";
767 R
"cpp(// Function declaration via call 775 HI.Kind = index::SymbolKind::Function;
776 HI.NamespaceScope =
"";
777 HI.Type =
"int (int)";
778 HI.Definition =
"int foo(int)";
779 HI.Documentation =
"Function declaration via call";
780 HI.ReturnType =
"int";
787 struct Foo { int x; }; 795 HI.Kind = index::SymbolKind::Field;
796 HI.NamespaceScope =
"";
797 HI.LocalScope =
"Foo::";
799 HI.Definition =
"int x";
802 R
"cpp(// Field with initialization 803 struct Foo { int x = 5; }; 811 HI.Kind = index::SymbolKind::Field;
812 HI.NamespaceScope =
"";
813 HI.LocalScope =
"Foo::";
815 HI.Definition =
"int x = 5";
818 R
"cpp(// Static field 819 struct Foo { static int x; }; 826 HI.Kind = index::SymbolKind::StaticProperty;
827 HI.NamespaceScope =
"";
828 HI.LocalScope =
"Foo::";
830 HI.Definition =
"static int x";
833 R
"cpp(// Field, member initializer 841 HI.Kind = index::SymbolKind::Field;
842 HI.NamespaceScope =
"";
843 HI.LocalScope =
"Foo::";
845 HI.Definition =
"int x";
848 R
"cpp(// Field, GNU old-style field designator 849 struct Foo { int x; }; 851 Foo bar = { ^[[x]] : 1 }; 856 HI.Kind = index::SymbolKind::Field;
857 HI.NamespaceScope =
"";
858 HI.LocalScope =
"Foo::";
860 HI.Definition =
"int x";
864 R
"cpp(// Field, field designator 865 struct Foo { int x; }; 867 Foo bar = { .^[[x]] = 2 }; 872 HI.Kind = index::SymbolKind::Field;
873 HI.NamespaceScope =
"";
874 HI.LocalScope =
"Foo::";
876 HI.Definition =
"int x";
881 struct Foo { int x(); }; 889 HI.Kind = index::SymbolKind::InstanceMethod;
890 HI.NamespaceScope =
"";
891 HI.LocalScope =
"Foo::";
893 HI.Definition =
"int x()";
894 HI.ReturnType =
"int";
895 HI.Parameters = std::vector<HoverInfo::Param>{};
898 R
"cpp(// Static method call 899 struct Foo { static int x(); }; 906 HI.Kind = index::SymbolKind::StaticMethod;
907 HI.NamespaceScope =
"";
908 HI.LocalScope =
"Foo::";
910 HI.Definition =
"static int x()";
911 HI.ReturnType =
"int";
912 HI.Parameters = std::vector<HoverInfo::Param>{};
923 HI.Kind = index::SymbolKind::TypeAlias;
924 HI.NamespaceScope =
"";
925 HI.Definition =
"typedef int Foo";
926 HI.Documentation =
"Typedef";
930 R
"cpp(// Typedef with embedded definition 931 typedef struct Bar {} Foo; 938 HI.Kind = index::SymbolKind::TypeAlias;
939 HI.NamespaceScope =
"";
940 HI.Definition =
"typedef struct Bar Foo";
941 HI.Documentation =
"Typedef with embedded definition";
946 struct Foo { static void bar(); }; 948 int main() { ^[[ns]]::Foo::bar(); } 952 HI.Kind = index::SymbolKind::Namespace;
953 HI.NamespaceScope =
"";
954 HI.Definition =
"namespace ns {}";
957 R
"cpp(// Anonymous namespace 961 } // anonymous namespace 963 int main() { ns::[[f^oo]]++; } 967 HI.Kind = index::SymbolKind::Variable;
968 HI.NamespaceScope =
"ns::";
970 HI.Definition =
"int foo";
975 int main() { return ^[[MACRO]]; } 979 HI.Kind = index::SymbolKind::Macro;
980 HI.Definition =
"#define MACRO 0";
985 #define MACRO2 ^[[MACRO]] 989 HI.Kind = index::SymbolKind::Macro;
990 HI.Definition =
"#define MACRO 0";
997 int main() ^[[MACRO]] 1001 HI.Kind = index::SymbolKind::Macro;
1003 R
"cpp(#define MACRO \ 1007 R"cpp(// Forward class declaration 1014 HI.Kind = index::SymbolKind::Class;
1015 HI.NamespaceScope =
"";
1016 HI.Definition =
"class Foo {}";
1017 HI.Documentation =
"Forward class declaration";
1020 R
"cpp(// Function declaration 1022 void g() { [[f^oo]](); } 1027 HI.Kind = index::SymbolKind::Function;
1028 HI.NamespaceScope =
"";
1029 HI.Type =
"void ()";
1030 HI.Definition =
"void foo()";
1031 HI.Documentation =
"Function declaration";
1032 HI.ReturnType =
"void";
1033 HI.Parameters = std::vector<HoverInfo::Param>{};
1036 R
"cpp(// Enum declaration 1041 [[Hel^lo]] hello = ONE; 1046 HI.Kind = index::SymbolKind::Enum;
1047 HI.NamespaceScope =
"";
1048 HI.Definition =
"enum Hello {}";
1049 HI.Documentation =
"Enum declaration";
1057 Hello hello = [[O^NE]]; 1062 HI.Kind = index::SymbolKind::EnumConstant;
1063 HI.NamespaceScope =
"";
1064 HI.LocalScope =
"Hello::";
1065 HI.Type =
"enum Hello";
1066 HI.Definition =
"ONE";
1070 R
"cpp(// Enumerator in anonymous enum 1075 int hello = [[O^NE]]; 1080 HI.Kind = index::SymbolKind::EnumConstant;
1081 HI.NamespaceScope =
"";
1084 HI.Type =
"enum (anonymous)";
1085 HI.Definition =
"ONE";
1089 R
"cpp(// Global variable 1090 static int hey = 10; 1097 HI.Kind = index::SymbolKind::Variable;
1098 HI.NamespaceScope =
"";
1100 HI.Definition =
"static int hey = 10";
1101 HI.Documentation =
"Global variable";
1106 R
"cpp(// Global variable in namespace 1108 static int hey = 10; 1116 HI.Kind = index::SymbolKind::Variable;
1117 HI.NamespaceScope =
"ns1::";
1119 HI.Definition =
"static int hey = 10";
1123 R
"cpp(// Field in anonymous struct 1133 HI.Kind = index::SymbolKind::Field;
1134 HI.NamespaceScope =
"";
1135 HI.LocalScope =
"(anonymous struct)::";
1137 HI.Definition =
"int hello";
1140 R
"cpp(// Templated function 1141 template <typename T> 1145 void g() { auto x = [[f^oo]]<int>(); } 1149 HI.Kind = index::SymbolKind::Function;
1150 HI.NamespaceScope =
"";
1152 HI.Definition =
"template <> int foo<int>()";
1153 HI.Documentation =
"Templated function";
1154 HI.ReturnType =
"int";
1155 HI.Parameters = std::vector<HoverInfo::Param>{};
1160 R
"cpp(// Anonymous union 1166 void g() { struct outer o; o.v.[[d^ef]]++; } 1170 HI.Kind = index::SymbolKind::Field;
1171 HI.NamespaceScope =
"";
1172 HI.LocalScope =
"outer::(anonymous union)::";
1174 HI.Definition =
"int def";
1177 R
"cpp(// documentation from index 1178 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs; 1180 void g() { [[ind^exSymbol]](); } 1183 HI.Name = "indexSymbol";
1184 HI.Kind = index::SymbolKind::Function;
1185 HI.NamespaceScope =
"";
1186 HI.Type =
"void ()";
1187 HI.Definition =
"void indexSymbol()";
1188 HI.ReturnType =
"void";
1189 HI.Parameters = std::vector<HoverInfo::Param>{};
1190 HI.Documentation =
"comment from index";
1193 R
"cpp(// Simple initialization with auto 1204 R
"cpp(// Simple initialization with const auto 1206 const ^[[auto]] i = 1; 1209 [](HoverInfo &HI) { HI.Name = "int"; }},
1211 R
"cpp(// Simple initialization with const auto& 1213 const ^[[auto]]& i = 1; 1216 [](HoverInfo &HI) { HI.Name = "int"; }},
1218 R
"cpp(// Simple initialization with auto& 1224 [](HoverInfo &HI) { HI.Name = "int"; }},
1226 R
"cpp(// Simple initialization with auto* 1232 [](HoverInfo &HI) { HI.Name = "int"; }},
1234 R
"cpp(// Auto with initializer list. 1238 class initializer_list {}; 1241 ^[[auto]] i = {1,2}; 1245 HI.Name = "initializer_list<int>";
1246 HI.Kind = index::SymbolKind::Class;
1249 R
"cpp(// User defined conversion to auto 1251 operator ^[[auto]]() const { return 10; } 1254 [](HoverInfo &HI) { HI.Name = "int"; }},
1256 R
"cpp(// Simple initialization with decltype(auto) 1258 ^[[decltype]](auto) i = 1; 1261 [](HoverInfo &HI) { HI.Name = "int"; }},
1263 R
"cpp(// Simple initialization with const decltype(auto) 1266 ^[[decltype]](auto) i = j; 1269 [](HoverInfo &HI) { HI.Name = "const int"; }},
1271 R
"cpp(// Simple initialization with const& decltype(auto) 1275 ^[[decltype]](auto) i = j; 1278 [](HoverInfo &HI) { HI.Name = "const int &"; }},
1280 R
"cpp(// Simple initialization with & decltype(auto) 1284 ^[[decltype]](auto) i = j; 1287 [](HoverInfo &HI) { HI.Name = "int &"; }},
1289 R
"cpp(// simple trailing return type 1290 ^[[auto]] main() -> int { 1294 [](HoverInfo &HI) { HI.Name = "int"; }},
1296 R
"cpp(// auto function return with trailing type 1298 ^[[auto]] test() -> decltype(Bar()) { 1304 HI.Kind = index::SymbolKind::Struct;
1305 HI.Documentation =
"auto function return with trailing type";
1308 R
"cpp(// trailing return type 1310 auto test() -> ^[[decltype]](Bar()) { 1316 HI.Kind = index::SymbolKind::Struct;
1317 HI.Documentation =
"trailing return type";
1320 R
"cpp(// auto in function return 1328 HI.Kind = index::SymbolKind::Struct;
1329 HI.Documentation =
"auto in function return";
1332 R
"cpp(// auto& in function return 1341 HI.Kind = index::SymbolKind::Struct;
1342 HI.Documentation =
"auto& in function return";
1345 R
"cpp(// auto* in function return 1354 HI.Kind = index::SymbolKind::Struct;
1355 HI.Documentation =
"auto* in function return";
1358 R
"cpp(// const auto& in function return 1360 const ^[[auto]]& test() { 1367 HI.Kind = index::SymbolKind::Struct;
1368 HI.Documentation =
"const auto& in function return";
1371 R
"cpp(// decltype(auto) in function return 1373 ^[[decltype]](auto) test() { 1379 HI.Kind = index::SymbolKind::Struct;
1380 HI.Documentation =
"decltype(auto) in function return";
1383 R
"cpp(// decltype(auto) reference in function return 1384 ^[[decltype]](auto) test() { 1389 [](HoverInfo &HI) { HI.Name = "int &"; }},
1391 R
"cpp(// decltype lvalue reference 1394 ^[[decltype]](I) J = I; 1397 [](HoverInfo &HI) { HI.Name = "int"; }},
1399 R
"cpp(// decltype lvalue reference 1403 ^[[decltype]](K) J = I; 1406 [](HoverInfo &HI) { HI.Name = "int &"; }},
1408 R
"cpp(// decltype lvalue reference parenthesis 1411 ^[[decltype]]((I)) J = I; 1414 [](HoverInfo &HI) { HI.Name = "int &"; }},
1416 R
"cpp(// decltype rvalue reference 1419 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I); 1422 [](HoverInfo &HI) { HI.Name = "int &&"; }},
1424 R
"cpp(// decltype rvalue reference function call 1428 ^[[decltype]](bar()) J = bar(); 1431 [](HoverInfo &HI) { HI.Name = "int &&"; }},
1433 R
"cpp(// decltype of function with trailing return type. 1435 auto test() -> decltype(Bar()) { 1439 ^[[decltype]](test()) i = test(); 1444 HI.Kind = index::SymbolKind::Struct;
1446 "decltype of function with trailing return type.";
1449 R
"cpp(// decltype of var with decltype. 1453 ^[[decltype]](J) K = J; 1456 [](HoverInfo &HI) { HI.Name = "int"; }},
1458 R
"cpp(// More complicated structured types. 1460 ^[[auto]] (*foo)() = bar; 1462 [](HoverInfo &HI) { HI.Name = "int"; }},
1464 R
"cpp(// Should not crash when evaluating the initializer. 1466 void test() { Test && [[te^st]] = {}; } 1470 HI.Kind = index::SymbolKind::Variable;
1471 HI.NamespaceScope =
"";
1472 HI.LocalScope =
"test::";
1473 HI.Type =
"struct Test &&";
1474 HI.Definition =
"Test &&test = {}";
1478 R
"cpp(// auto on alias 1479 typedef int int_type; 1480 ^[[auto]] x = int_type(); 1482 [](HoverInfo &HI) { HI.Name = "int"; }},
1484 R
"cpp(// auto on alias 1486 typedef cls cls_type; 1487 ^[[auto]] y = cls_type(); 1491 HI.Kind = index::SymbolKind::Struct;
1492 HI.Documentation =
"auto on alias";
1495 R
"cpp(// auto on alias 1498 ^[[auto]] z = templ<int>(); 1501 HI.Name = "templ<int>";
1502 HI.Kind = index::SymbolKind::Struct;
1503 HI.Documentation =
"auto on alias";
1506 R
"cpp(// should not crash. 1507 template <class T> struct cls { 1511 auto test = cls<int>().[[m^ethod]](); 1514 HI.Definition = "int method()";
1515 HI.Kind = index::SymbolKind::InstanceMethod;
1516 HI.NamespaceScope =
"";
1517 HI.LocalScope =
"cls<int>::";
1519 HI.Parameters.emplace();
1520 HI.ReturnType =
"int";
1524 R
"cpp(// type of nested templates. 1525 template <class T> struct cls {}; 1526 cls<cls<cls<int>>> [[fo^o]]; 1529 HI.Definition = "cls<cls<cls<int>>> foo";
1530 HI.Kind = index::SymbolKind::Variable;
1531 HI.NamespaceScope =
"";
1533 HI.Type =
"cls<cls<cls<int> > >";
1537 R
"cpp(// type of nested templates. 1538 template <class T> struct cls {}; 1539 [[cl^s]]<cls<cls<int>>> foo; 1542 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
1543 HI.Kind = index::SymbolKind::Struct;
1544 HI.NamespaceScope =
"";
1545 HI.Name =
"cls<cls<cls<int> > >";
1546 HI.Documentation =
"type of nested templates.";
1549 R
"cpp(// type with decltype 1551 decltype(a) [[b^]] = a;)cpp", 1553 HI.Definition = "decltype(a) b = a";
1554 HI.Kind = index::SymbolKind::Variable;
1555 HI.NamespaceScope =
"";
1560 R
"cpp(// type with decltype 1563 decltype(c) [[b^]] = a;)cpp", 1565 HI.Definition = "decltype(c) b = a";
1566 HI.Kind = index::SymbolKind::Variable;
1567 HI.NamespaceScope =
"";
1572 R
"cpp(// type with decltype 1574 const decltype(a) [[b^]] = a;)cpp", 1576 HI.Definition = "const decltype(a) b = a";
1577 HI.Kind = index::SymbolKind::Variable;
1578 HI.NamespaceScope =
"";
1583 R
"cpp(// type with decltype 1585 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp", 1587 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
1588 HI.Kind = index::SymbolKind::Function;
1589 HI.NamespaceScope =
"";
1593 HI.Type =
"auto (decltype(a)) -> decltype(a)";
1594 HI.ReturnType =
"int";
1596 {std::string(
"int"), std::string(
"x"),
llvm::None}};
1599 R
"cpp(// sizeof expr 1601 (void)[[size^of]](char); 1604 HI.Name = "expression";
1605 HI.Type =
"unsigned long";
1609 R
"cpp(// alignof expr 1611 (void)[[align^of]](char); 1614 HI.Name = "expression";
1615 HI.Type =
"unsigned long";
1621 Symbol IndexSym =
func(
"indexSymbol");
1622 IndexSym.Documentation =
"comment from index";
1624 Symbols.insert(IndexSym);
1626 MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1628 for (
const auto &Case : Cases) {
1629 SCOPED_TRACE(Case.Code);
1631 Annotations T(Case.Code);
1634 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
1637 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
1638 auto AST = TU.
build();
1643 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
Index.get());
1646 Expected.SymRange = T.range();
1647 Case.ExpectedBuilder(Expected);
1649 SCOPED_TRACE(H->present().asPlainText());
1650 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1651 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1652 EXPECT_EQ(H->Name, Expected.Name);
1653 EXPECT_EQ(H->Kind, Expected.Kind);
1654 EXPECT_EQ(H->Documentation, Expected.Documentation);
1655 EXPECT_EQ(H->Definition, Expected.Definition);
1656 EXPECT_EQ(H->Type, Expected.Type);
1657 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1658 EXPECT_EQ(H->Parameters, Expected.Parameters);
1659 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1660 EXPECT_EQ(H->SymRange, Expected.SymRange);
1661 EXPECT_EQ(H->Value, Expected.Value);
1665 TEST(Hover, DocsFromIndex) {
1666 Annotations T(R
"cpp( 1667 template <typename T> class X {}; 1675 auto AST = TU.
build();
1676 for (
const auto &D : AST.getDiagnostics())
1678 ASSERT_TRUE(AST.getDiagnostics().empty());
1682 IndexSym.Documentation =
"comment from index";
1684 Symbols.insert(IndexSym);
1686 MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1688 for (
const auto &P : T.points()) {
1689 auto H =
getHover(AST, P, format::getLLVMStyle(),
Index.get());
1691 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
1695 TEST(Hover, DocsFromAST) {
1696 Annotations T(R
"cpp( 1698 template <typename T> class X {}; 1700 template <typename T> void bar() {} 1702 template <typename T> T baz; 1707 au^to T = ba^z<X<int>>; 1712 auto AST = TU.
build();
1713 for (
const auto &D : AST.getDiagnostics())
1715 ASSERT_TRUE(AST.getDiagnostics().empty());
1717 for (
const auto &P : T.points()) {
1718 auto H =
getHover(AST, P, format::getLLVMStyle(),
nullptr);
1720 EXPECT_EQ(H->Documentation,
"doc");
1724 TEST(Hover, DocsFromMostSpecial) {
1725 Annotations T(R
"cpp( 1727 template <typename T> class $doc1^X {}; 1729 template <> class $doc2^X<int> {}; 1731 template <typename T> class $doc3^X<T*> {}; 1739 auto AST = TU.
build();
1740 for (
const auto &D : AST.getDiagnostics())
1742 ASSERT_TRUE(AST.getDiagnostics().empty());
1744 for (
auto Comment : {
"doc1",
"doc2",
"doc3"}) {
1745 for (
const auto &P : T.points(Comment)) {
1746 auto H =
getHover(AST, P, format::getLLVMStyle(),
nullptr);
1748 EXPECT_EQ(H->Documentation, Comment);
1753 TEST(Hover, Present) {
1755 const std::function<void(HoverInfo &)>
Builder;
1756 llvm::StringRef ExpectedRender;
1767 HI.Kind = index::SymbolKind::NamespaceAlias; 1770 R
"(namespace-alias foo)", 1774 HI.Kind = index::SymbolKind::Class; 1775 HI.TemplateParameters = { 1776 {std::string("typename"), std::string(
"T"),
llvm::None},
1777 {std::string(
"typename"), std::string(
"C"),
1778 std::string(
"bool")},
1780 HI.Documentation =
"documentation";
1782 "template <typename T, typename C = bool> class Foo {}";
1784 HI.NamespaceScope.emplace();
1790 template <typename T, typename C = bool> class Foo {})", 1794 HI.Kind = index::SymbolKind::Function; 1797 HI.ReturnType =
"ret_type";
1798 HI.Parameters.emplace();
1800 HI.Parameters->push_back(P);
1802 HI.Parameters->push_back(P);
1804 HI.Parameters->push_back(P);
1805 P.Default =
"default";
1806 HI.Parameters->push_back(P);
1807 HI.NamespaceScope =
"ns::";
1808 HI.Definition =
"ret_type foo(params) {}";
1817 - type foo = default 1820 ret_type foo(params) {})", 1824 HI.Kind = index::SymbolKind::Variable; 1825 HI.LocalScope = "test::bar::";
1829 HI.Definition =
"def";
1841 for (
const auto &C : Cases) {
1844 EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
1850 TEST(Hover, PresentHeadings) {
1852 HI.Kind = index::SymbolKind::Variable;
1855 EXPECT_EQ(HI.present().asMarkdown(),
"### variable `foo`");
1860 TEST(Hover, PresentRulers) {
1862 HI.Kind = index::SymbolKind::Variable;
1865 HI.Definition =
"def";
1867 llvm::StringRef ExpectedMarkdown = R
"md(### variable `foo` 1876 EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown); 1878 llvm::StringRef ExpectedPlaintext = R"pt(variable foo 1883 EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
Documents should not be synced at all.
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)
static TestTU withCode(llvm::StringRef Code)
CodeCompletionBuilder Builder
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< const char * > Expected
static llvm::Optional< ParsedAST > build(std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, const SymbolIndex *Index, const ParseOptions &Opts)
Attempts to run Clang and store parsed AST.
const std::vector< Diag > & getDiagnostics() const
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
const SymbolIndex * Index
Symbol func(llvm::StringRef Name)