12#include "llvm/ADT/StringRef.h"
13#include "gmock/gmock.h"
14#include "gtest/gtest.h"
21using ::testing::AllOf;
22using ::testing::ElementsAre;
23using ::testing::ElementsAreArray;
24using ::testing::Field;
25using ::testing::IsEmpty;
26using ::testing::UnorderedElementsAre;
30 if (arg.containerName.empty())
31 return arg.name == Name;
32 return (arg.containerName +
"::" + arg.name) == Name;
34MATCHER_P(withName, N,
"") {
return arg.name == N; }
35MATCHER_P(withKind, Kind,
"") {
return arg.kind == Kind; }
41template <
class... ChildMatchers>
42::testing::Matcher<DocumentSymbol> children(ChildMatchers... ChildrenM) {
46std::vector<SymbolInformation> getSymbols(
TestTU &TU, llvm::StringRef Query,
50 EXPECT_TRUE(
bool(SymbolInfos)) <<
"workspaceSymbols returned an error";
54TEST(WorkspaceSymbols, Macros) {
63 EXPECT_THAT(getSymbols(TU,
"macro"),
64 ElementsAre(AllOf(qName(
"MACRO"), withKind(SymbolKind::String))));
67TEST(WorkspaceSymbols, NoLocals) {
70 void test(int FirstParam, int SecondParam) {
74 EXPECT_THAT(getSymbols(TU, "l"), ElementsAre(qName(
"LocalClass")));
75 EXPECT_THAT(getSymbols(TU,
"p"), IsEmpty());
78TEST(WorkspaceSymbols, Globals) {
85 struct GlobalStruct {};)cpp";
89 EXPECT_THAT(getSymbols(TU, "global"),
91 AllOf(qName(
"GlobalStruct"), withKind(SymbolKind::Struct)),
92 AllOf(qName(
"global_func"), withKind(SymbolKind::Function)),
93 AllOf(qName(
"global_var"), withKind(SymbolKind::Variable))));
96TEST(WorkspaceSymbols, Unnamed) {
101 } UnnamedStruct;)cpp";
105 EXPECT_THAT(getSymbols(TU, "UnnamedStruct"),
106 ElementsAre(AllOf(qName(
"UnnamedStruct"),
107 withKind(SymbolKind::Variable))));
108 EXPECT_THAT(getSymbols(TU,
"InUnnamed"),
109 ElementsAre(AllOf(qName(
"(anonymous struct)::InUnnamed"),
110 withKind(SymbolKind::Field))));
113TEST(WorkspaceSymbols, InMainFile) {
116 int test() { return 0; }
117 static void test2() {}
119 EXPECT_THAT(getSymbols(TU, "test"),
120 ElementsAre(qName(
"test"), qName(
"test2")));
123TEST(WorkspaceSymbols, Namespaces) {
139 EXPECT_THAT(getSymbols(TU, "a"),
140 UnorderedElementsAre(
141 qName(
"ans1"), qName(
"ans1::ai1"), qName(
"ans1::ans2"),
142 qName(
"ans1::ans2::ai2"), qName(
"ans1::ans2::ans3"),
143 qName(
"ans1::ans2::ans3::ai3")));
144 EXPECT_THAT(getSymbols(TU,
"::"), ElementsAre(qName(
"ans1")));
145 EXPECT_THAT(getSymbols(TU,
"::a"), ElementsAre(qName(
"ans1")));
146 EXPECT_THAT(getSymbols(TU,
"ans1::"),
147 UnorderedElementsAre(qName(
"ans1::ai1"), qName(
"ans1::ans2"),
148 qName(
"ans1::ans2::ai2"),
149 qName(
"ans1::ans2::ans3"),
150 qName(
"ans1::ans2::ans3::ai3")));
151 EXPECT_THAT(getSymbols(TU,
"ans2::"),
152 UnorderedElementsAre(qName(
"ans1::ans2::ai2"),
153 qName(
"ans1::ans2::ans3"),
154 qName(
"ans1::ans2::ans3::ai3")));
155 EXPECT_THAT(getSymbols(TU,
"::ans1"), ElementsAre(qName(
"ans1")));
156 EXPECT_THAT(getSymbols(TU,
"::ans1::"),
157 UnorderedElementsAre(qName(
"ans1::ai1"), qName(
"ans1::ans2")));
158 EXPECT_THAT(getSymbols(TU,
"::ans1::ans2"), ElementsAre(qName(
"ans1::ans2")));
159 EXPECT_THAT(getSymbols(TU,
"::ans1::ans2::"),
160 ElementsAre(qName(
"ans1::ans2::ai2"), qName(
"ans1::ans2::ans3")));
163 EXPECT_THAT(getSymbols(TU,
"ans1::ans3::ai"),
164 UnorderedElementsAre(qName(
"ans1::ans2::ans3::ai3")));
167TEST(WorkspaceSymbols, AnonymousNamespace) {
174 EXPECT_THAT(getSymbols(TU, "test"), ElementsAre(qName(
"test")));
177TEST(WorkspaceSymbols, MultiFile) {
183 TU.AdditionalFiles["foo2.h"] = R
"cpp(
191 EXPECT_THAT(getSymbols(TU, "foo"),
192 UnorderedElementsAre(qName(
"foo"), qName(
"foo2")));
195TEST(WorkspaceSymbols, GlobalNamespaceQueries) {
211 EXPECT_THAT(getSymbols(TU, "::"),
212 UnorderedElementsAre(
213 AllOf(qName(
"Foo"), withKind(SymbolKind::Class)),
214 AllOf(qName(
"foo"), withKind(SymbolKind::Function)),
215 AllOf(qName(
"ns"), withKind(SymbolKind::Namespace))));
216 EXPECT_THAT(getSymbols(TU,
":"), IsEmpty());
217 EXPECT_THAT(getSymbols(TU,
""),
218 UnorderedElementsAre(qName(
"foo"), qName(
"Foo"), qName(
"Foo::a"),
219 qName(
"ns"), qName(
"ns::foo2")));
222TEST(WorkspaceSymbols, Enums) {
249 EXPECT_THAT(getSymbols(TU, "Red"), ElementsAre(qName(
"Red")));
250 EXPECT_THAT(getSymbols(TU,
"::Red"), ElementsAre(qName(
"Red")));
251 EXPECT_THAT(getSymbols(TU,
"Green"), ElementsAre(qName(
"Green")));
252 EXPECT_THAT(getSymbols(TU,
"Green"), ElementsAre(qName(
"Green")));
253 EXPECT_THAT(getSymbols(TU,
"Color2::Yellow"),
254 ElementsAre(qName(
"Color2::Yellow")));
255 EXPECT_THAT(getSymbols(TU,
"Yellow"), ElementsAre(qName(
"Color2::Yellow")));
257 EXPECT_THAT(getSymbols(TU,
"ns::Black"), ElementsAre(qName(
"ns::Black")));
258 EXPECT_THAT(getSymbols(TU,
"ns::Blue"), ElementsAre(qName(
"ns::Blue")));
259 EXPECT_THAT(getSymbols(TU,
"ns::Color4::White"),
260 ElementsAre(qName(
"ns::Color4::White")));
263TEST(WorkspaceSymbols, Ranking) {
272 EXPECT_THAT(getSymbols(TU, "::"), ElementsAre(qName(
"func"), qName(
"ns")));
275TEST(WorkspaceSymbols, RankingPartialNamespace) {
279 namespace ns2 { struct Foo {}; }
281 namespace ns2 { struct FooB {}; })cpp";
282 EXPECT_THAT(getSymbols(TU, "ns2::f"),
283 ElementsAre(qName(
"ns2::FooB"), qName(
"ns1::ns2::Foo")));
286TEST(WorkspaceSymbols, WithLimit) {
296 EXPECT_THAT(getSymbols(TU,
"foo"),
297 UnorderedElementsAre(
298 AllOf(qName(
"foo"), withKind(SymbolKind::Variable)),
299 AllOf(qName(
"foo2"), withKind(SymbolKind::Variable))));
301 EXPECT_THAT(getSymbols(TU,
"foo", 1), ElementsAre(qName(
"foo")));
304TEST(WorkspaceSymbols, TempSpecs) {
308 template <typename T, typename U, int X = 5> class Foo {};
309 template <typename T> class Foo<int, T> {};
310 template <> class Foo<bool, int> {};
311 template <> class Foo<bool, int, 3> {};
315 getSymbols(TU,
"Foo"),
316 UnorderedElementsAre(
317 AllOf(qName(
"Foo"), withKind(SymbolKind::Class)),
318 AllOf(qName(
"Foo<int, T>"), withKind(SymbolKind::Class)),
319 AllOf(qName(
"Foo<bool, int>"), withKind(SymbolKind::Class)),
320 AllOf(qName(
"Foo<bool, int, 3>"), withKind(SymbolKind::Class))));
325 EXPECT_TRUE(
bool(SymbolInfos)) <<
"documentSymbols returned an error";
329TEST(DocumentSymbols, BasicSymbols) {
340 Foo& operator=(const Foo&);
351 static const int KInt = 2;
352 const char* kStr = "123";
359 using int32_t = int32;
375 TU.Code = Main.code().str();
377 getSymbols(TU.build()),
379 {AllOf(withName("Foo"), withKind(SymbolKind::Class),
380 withDetail(
"class"), children()),
381 AllOf(withName(
"Foo"), withKind(SymbolKind::Class),
384 AllOf(withName(
"Foo"), withKind(SymbolKind::Constructor),
385 withDetail(
"()"), children()),
386 AllOf(withName(
"Foo"), withKind(SymbolKind::Constructor),
387 withDetail(
"(int)"), children()),
388 AllOf(withName(
"f"), withKind(SymbolKind::Method),
389 withDetail(
"void ()"), children()),
390 AllOf(withName(
"f2"), withKind(SymbolKind::Function),
391 withDetail(
"void ()"), children()),
392 AllOf(withName(
"operator="), withKind(SymbolKind::Method),
393 withDetail(
"Foo &(const Foo &)"), children()),
394 AllOf(withName(
"~Foo"), withKind(SymbolKind::Constructor),
395 withDetail(
""), children()),
396 AllOf(withName(
"Nested"), withKind(SymbolKind::Class),
399 withName(
"f"), withKind(SymbolKind::Method),
400 withDetail(
"void ()"), children()))))),
401 AllOf(withName(
"Friend"), withKind(SymbolKind::Class),
402 withDetail(
"class"), children()),
403 AllOf(withName(
"f1"), withKind(SymbolKind::Function),
404 withDetail(
"void ()"), children()),
405 AllOf(withName(
"f2"), withKind(SymbolKind::Function),
406 withDetail(
"void ()"), children()),
407 AllOf(withName(
"KInt"), withKind(SymbolKind::Variable),
408 withDetail(
"const int"), children()),
409 AllOf(withName(
"kStr"), withKind(SymbolKind::Variable),
410 withDetail(
"const char *"), children()),
411 AllOf(withName(
"f1"), withKind(SymbolKind::Function),
412 withDetail(
"void ()"), children()),
414 withName(
"foo"), withKind(SymbolKind::Namespace), withDetail(
""),
415 children(AllOf(withName(
"int32"), withKind(SymbolKind::Class),
416 withDetail(
"type alias"), children()),
417 AllOf(withName(
"int32_t"), withKind(SymbolKind::Class),
418 withDetail(
"type alias"), children()),
419 AllOf(withName(
"v1"), withKind(SymbolKind::Variable),
420 withDetail(
"int"), children()),
421 AllOf(withName(
"bar"), withKind(SymbolKind::Namespace),
423 children(AllOf(withName(
"v2"),
424 withKind(SymbolKind::Variable),
425 withDetail(
"int"), children()))),
426 AllOf(withName(
"baz"), withKind(SymbolKind::Namespace),
427 withDetail(
""), children()),
428 AllOf(withName(
"v2"), withKind(SymbolKind::Namespace),
429 withDetail(
""))))}));
432TEST(DocumentSymbols, DeclarationDefinition) {
438 void Foo::$def[[f]]() {
442 TU.Code = Main.code().str();
444 getSymbols(TU.build()),
446 AllOf(withName("Foo"), withKind(SymbolKind::Class),
448 children(AllOf(withName(
"f"), withKind(SymbolKind::Method),
449 withDetail(
"void ()"),
450 symNameRange(Main.range(
"decl"))))),
451 AllOf(withName(
"Foo::f"), withKind(SymbolKind::Method),
452 withDetail(
"void ()"), symNameRange(Main.range(
"def")))));
455TEST(DocumentSymbols, Concepts) {
458 TU.Code =
"template <typename T> concept C = requires(T t) { t.foo(); };";
460 EXPECT_THAT(getSymbols(TU.build()),
461 ElementsAre(AllOf(withName(
"C"), withDetail(
"concept"))));
464TEST(DocumentSymbols, ExternSymbol) {
473 EXPECT_THAT(getSymbols(TU.build()), IsEmpty());
476TEST(DocumentSymbols, ExternContext) {
490 EXPECT_THAT(getSymbols(TU.build()),
491 ElementsAre(withName("foo"), withName(
"Foo"),
492 AllOf(withName(
"ns"),
493 children(withName(
"bar"), withName(
"Bar")))));
496TEST(DocumentSymbols, ExportContext) {
506 EXPECT_THAT(getSymbols(TU.build()),
507 ElementsAre(withName("foo"), withName(
"Foo")));
510TEST(DocumentSymbols, NoLocals) {
513 void test(int FirstParam, int SecondParam) {
514 struct LocalClass {};
517 EXPECT_THAT(getSymbols(TU.build()), ElementsAre(withName("test")));
520TEST(DocumentSymbols, Unnamed) {
528 getSymbols(TU.build()),
529 ElementsAre(AllOf(withName("(anonymous struct)"),
530 withKind(SymbolKind::Struct), withDetail(
"struct"),
531 children(AllOf(withName(
"InUnnamed"),
532 withKind(SymbolKind::Field),
533 withDetail(
"int"), children()))),
534 AllOf(withName(
"UnnamedStruct"),
535 withKind(SymbolKind::Variable),
536 withDetail(
"struct (unnamed)"), children())));
539TEST(DocumentSymbols, InHeaderFile) {
547 int i; // declaration to finish preamble
553 EXPECT_THAT(getSymbols(TU.build()),
554 ElementsAre(withName("i"), withName(
"test")));
557TEST(DocumentSymbols, Template) {
560 template <class T> struct Tmpl {T x = 0;};
561 template <> struct Tmpl<int> {
564 extern template struct Tmpl<float>;
565 template struct Tmpl<double>;
567 template <class T, class U, class Z = float>
570 int funcTmpl<int>(double a);
572 template <class T, class U = double>
575 double varTmpl<int> = 10.0;
578 getSymbols(TU.build()),
580 AllOf(withName("Tmpl"), withKind(SymbolKind::Struct),
581 withDetail(
"template struct"),
582 children(AllOf(withName(
"x"), withKind(SymbolKind::Field),
584 AllOf(withName(
"Tmpl<int>"), withKind(SymbolKind::Struct),
585 withDetail(
"struct"),
586 children(AllOf(withName(
"y"), withDetail(
"int")))),
587 AllOf(withName(
"Tmpl<float>"), withKind(SymbolKind::Struct),
588 withDetail(
"struct"), children()),
589 AllOf(withName(
"Tmpl<double>"), withKind(SymbolKind::Struct),
590 withDetail(
"struct"), children()),
591 AllOf(withName(
"funcTmpl"), withDetail(
"template int (U)"),
593 AllOf(withName(
"funcTmpl<int>"), withDetail(
"int (double)"),
595 AllOf(withName(
"varTmpl"), withDetail(
"template int"), children()),
596 AllOf(withName(
"varTmpl<int>"), withDetail(
"double"), children())));
599TEST(DocumentSymbols, Namespaces) {
613 inline namespace nb {
618 // This is still inlined.
625 getSymbols(TU.build()),
626 ElementsAreArray<::testing::Matcher<DocumentSymbol>>(
627 {AllOf(withName("ans1"),
628 children(AllOf(withName(
"ai1"), children()),
629 AllOf(withName(
"ans2"), children(withName(
"ai2"))))),
630 AllOf(withName(
"(anonymous namespace)"), children(withName(
"test"))),
631 AllOf(withName(
"na"),
632 children(AllOf(withName(
"nb"), children(withName(
"Foo"))))),
633 AllOf(withName(
"na"),
634 children(AllOf(withName(
"nb"), children(withName(
"Bar")))))}));
637TEST(DocumentSymbols, Enums) {
656 getSymbols(TU.build()),
658 AllOf(withName("(anonymous enum)"), withDetail(
"enum"),
659 children(AllOf(withName(
"Red"), withDetail(
"(unnamed)")))),
660 AllOf(withName(
"Color"), withDetail(
"enum"),
661 children(AllOf(withName(
"Green"), withDetail(
"Color")))),
662 AllOf(withName(
"Color2"), withDetail(
"enum"),
663 children(AllOf(withName(
"Yellow"), withDetail(
"Color2")))),
664 AllOf(withName(
"ns"),
665 children(AllOf(withName(
"(anonymous enum)"), withDetail(
"enum"),
666 children(AllOf(withName(
"Black"),
667 withDetail(
"(unnamed)"))))))));
673 testing::Matcher<DocumentSymbol> Matcher;
677 // Basic macro that generates symbols.
678 #define DEFINE_FLAG(X) bool FLAGS_##X; bool FLAGS_no##X
681 AllOf(withName("DEFINE_FLAG"), withDetail(
"(pretty)"),
682 children(withName(
"FLAGS_pretty"), withName(
"FLAGS_nopretty"))),
686 // Hierarchy is determined by primary (name) location.
688 namespace ID(ns) { int ID(y); }
690 AllOf(withName("ID"), withDetail(
"(ns)"),
691 children(AllOf(withName(
"ns"),
692 children(AllOf(withName(
"ID"), withDetail(
"(y)"),
693 children(withName(
"y"))))))),
697 // More typical example where macro only generates part of a decl.
698 #define TEST(A, B) class A##_##B { void go(); }; void A##_##B::go()
699 TEST(DocumentSymbols, Macro) { }
701 AllOf(withName("TEST"), withDetail(
"(DocumentSymbols, Macro)"),
702 children(AllOf(withName(
"DocumentSymbols_Macro"),
703 children(withName(
"go"))),
704 withName(
"DocumentSymbols_Macro::go"))),
709 #define NAMESPACE(NS, BODY) namespace NS { BODY }
710 NAMESPACE(a, NAMESPACE(b, int x;))
713 withName("NAMESPACE"), withDetail(
"(a, NAMESPACE(b, int x;))"),
716 children(AllOf(withName(
"NAMESPACE"),
719 children(AllOf(withName(
"b"),
720 children(withName(
"x"))))))))),
724 // Macro invoked from body is not exposed.
725 #define INNER(X) int X
726 #define OUTER(X) INNER(X)
729 AllOf(withName("OUTER"), withDetail(
"(foo)"),
730 children(withName(
"foo"))),
733 for (
const Test &T : Tests) {
735 EXPECT_THAT(getSymbols(TU.build()), ElementsAre(
T.Matcher)) <<
T.Code;
739TEST(DocumentSymbols, RangeFromMacro) {
743 class name##_Test {};
745 $expansion1[[FF]](abc);
750 $expansion2parens[[$expansion2[[FF2]]()]];
759 #define FF4(name) int name = 0
760 $FooRange[[FF4($FooSelectionRange[[foo]])]];
762 TU.Code = Main.code().str();
764 getSymbols(TU.build()),
766 AllOf(withName("FF"), withDetail(
"(abc)"),
767 children(AllOf(withName(
"abc_Test"), withDetail(
"class"),
768 symNameRange(Main.range(
"expansion1"))))),
769 AllOf(withName(
"FF2"), withDetail(
"()"),
770 symNameRange(Main.range(
"expansion2")),
771 symRange(Main.range(
"expansion2parens")),
772 children(AllOf(withName(
"Test"), withDetail(
"class"),
773 symNameRange(Main.range(
"expansion2"))))),
774 AllOf(withName(
"FF3"), withDetail(
"()"),
775 symRange(Main.range(
"fullDef")),
776 children(AllOf(withName(
"waldo"), withDetail(
"void ()"),
777 symRange(Main.range(
"fullDef"))))),
779 withName(
"FF4"), withDetail(
"(foo)"),
780 children(AllOf(withName(
"foo"), symRange(Main.range(
"FooRange")),
781 symNameRange(Main.range(
"FooSelectionRange")))))));
784TEST(DocumentSymbols, FuncTemplates) {
788 T foo() { return T{}; }
791 auto y = foo<double>();
793 TU.Code = Source.code().str();
795 EXPECT_THAT(getSymbols(TU.build()),
796 ElementsAre(AllOf(withName(
"foo"), withDetail(
"template T ()")),
797 AllOf(withName(
"x"), withDetail(
"int")),
798 AllOf(withName(
"y"), withDetail(
"double"))));
801TEST(DocumentSymbols, UsingDirectives) {
808 namespace ns_alias = ns;
810 using namespace ::ns; // check we don't loose qualifiers.
811 using namespace ns_alias; // and namespace aliases.
813 TU.Code = Source.code().str();
814 EXPECT_THAT(getSymbols(TU.build()),
815 ElementsAre(withName("ns"), withName(
"ns_alias"),
816 withName(
"using namespace ::ns"),
817 withName(
"using namespace ns_alias")));
820TEST(DocumentSymbols, TempSpecs) {
823 template <typename T, typename U, int X = 5> class Foo {};
824 template <typename T> class Foo<int, T> {};
825 template <> class Foo<bool, int> {};
826 template <> class Foo<bool, int, 3> {};
829 EXPECT_THAT(getSymbols(TU.build()),
830 UnorderedElementsAre(
831 AllOf(withName(
"Foo"), withKind(SymbolKind::Class),
832 withDetail(
"template class")),
833 AllOf(withName(
"Foo<int, T>"), withKind(SymbolKind::Class),
834 withDetail(
"template class")),
835 AllOf(withName(
"Foo<bool, int>"), withKind(SymbolKind::Class),
836 withDetail(
"class")),
837 AllOf(withName(
"Foo<bool, int, 3>"),
838 withKind(SymbolKind::Class), withDetail(
"class"))));
841TEST(DocumentSymbols, Qualifiers) {
844 namespace foo { namespace bar {
853 struct foo::bar::Cls { };
855 int foo::bar::func1() { return 10; }
856 int ::foo::bar::func2() { return 20; }
859 int bar::func3() { return 30; }
861 namespace alias = foo::bar;
862 int ::alias::func4() { return 40; }
866 EXPECT_THAT(getSymbols(TU.build()),
867 UnorderedElementsAre(
868 withName(
"foo"), withName(
"foo::bar::Cls"),
869 withName(
"foo::bar::func1"), withName(
"::foo::bar::func2"),
870 withName(
"using namespace foo"), withName(
"bar::func3"),
871 withName(
"alias"), withName(
"::alias::func4")));
874TEST(DocumentSymbols, QualifiersWithTemplateArgs) {
877 template <typename T, typename U = double> class Foo;
880 class Foo<int, double> {
886 using int_type = int;
888 // Typedefs should be preserved!
889 int Foo<int_type, double>::method1() { return 10; }
891 // Default arguments should not be shown!
892 int Foo<int>::method2() { return 20; }
894 using Foo_type = Foo<int>;
895 // If the whole type is aliased, this should be preserved too!
896 int Foo_type::method3() { return 30; }
898 EXPECT_THAT(getSymbols(TU.build()),
899 UnorderedElementsAre(
900 AllOf(withName("Foo"), withDetail(
"template class")),
901 AllOf(withName(
"Foo<int, double>"), withDetail(
"class")),
902 AllOf(withName(
"int_type"), withDetail(
"type alias")),
903 AllOf(withName(
"Foo<int_type, double>::method1"),
904 withDetail(
"int ()")),
905 AllOf(withName(
"Foo<int>::method2"), withDetail(
"int ()")),
906 AllOf(withName(
"Foo_type"), withDetail(
"type alias")),
907 AllOf(withName(
"Foo_type::method3"), withDetail(
"int ()"))));
910TEST(DocumentSymbolsTest, Ranges) {
913 $foo[[int foo(bool Argument) {
917 $variable[[char GLOBAL_VARIABLE]];
926 $field[[unsigned Baz]];
928 $getbaz[[unsigned getBaz() { return Baz; }]]
932 $forwardclass[[class ForwardClassDecl]];
934 $struct[[struct StructDefinition {
935 $structfield[[int *Pointer = nullptr]];
937 $forwardstruct[[struct StructDeclaration]];
939 $forwardfunc[[void forwardFunctionDecl(int Something)]];
941 TU.Code = Main.code().str();
943 getSymbols(TU.build()),
944 UnorderedElementsAre(
945 AllOf(withName("foo"), withKind(SymbolKind::Function),
946 withDetail(
"int (bool)"), symRange(Main.range(
"foo"))),
947 AllOf(withName(
"GLOBAL_VARIABLE"), withKind(SymbolKind::Variable),
948 withDetail(
"char"), symRange(Main.range(
"variable"))),
950 withName(
"ns"), withKind(SymbolKind::Namespace),
951 symRange(Main.range(
"ns")),
953 withName(
"Bar"), withKind(SymbolKind::Class),
954 withDetail(
"class"), symRange(Main.range(
"bar")),
956 AllOf(withName(
"Bar"), withKind(SymbolKind::Constructor),
957 withDetail(
"()"), symRange(Main.range(
"ctor"))),
958 AllOf(withName(
"~Bar"), withKind(SymbolKind::Constructor),
959 withDetail(
""), symRange(Main.range(
"dtor"))),
960 AllOf(withName(
"Baz"), withKind(SymbolKind::Field),
961 withDetail(
"unsigned int"),
962 symRange(Main.range(
"field"))),
963 AllOf(withName(
"getBaz"), withKind(SymbolKind::Method),
964 withDetail(
"unsigned int ()"),
965 symRange(Main.range(
"getbaz"))))))),
966 AllOf(withName(
"ForwardClassDecl"), withKind(SymbolKind::Class),
967 withDetail(
"class"), symRange(Main.range(
"forwardclass"))),
968 AllOf(withName(
"StructDefinition"), withKind(SymbolKind::Struct),
969 withDetail(
"struct"), symRange(Main.range(
"struct")),
970 children(AllOf(withName(
"Pointer"), withKind(SymbolKind::Field),
972 symRange(Main.range(
"structfield"))))),
973 AllOf(withName(
"StructDeclaration"), withKind(SymbolKind::Struct),
974 withDetail(
"struct"), symRange(Main.range(
"forwardstruct"))),
975 AllOf(withName(
"forwardFunctionDecl"), withKind(SymbolKind::Function),
976 withDetail(
"void (int)"),
977 symRange(Main.range(
"forwardfunc")))));
980TEST(DocumentSymbolsTest, DependentType) {
983 template <typename T> auto plus(T x, T y) -> decltype(x + y) { return x + y; }
985 template <typename Key, typename Value> class Pair {};
987 template <typename Key, typename Value>
988 struct Context : public Pair<Key, Value> {
989 using Pair<Key, Value>::Pair;
993 getSymbols(TU.build()),
995 AllOf(withName("plus"),
996 withDetail(
"template auto (T, T) -> decltype(x + y)")),
997 AllOf(withName(
"Pair"), withDetail(
"template class")),
998 AllOf(withName(
"Context"), withDetail(
"template struct"),
1000 withName(
"Pair<type-parameter-0-0, type-parameter-0-1>"),
1001 withDetail(
"<dependent type>"))))));
1004TEST(DocumentSymbolsTest, ObjCCategoriesAndClassExtensions) {
1006 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1008 $Cat[[@interface Cat
1011 $SneakyCat[[@interface Cat (Sneaky)
1012 - (id)sneak:(id)behavior;
1015 $MeowCat[[@interface Cat ()
1018 $PurCat[[@interface Cat ()
1022 TU.Code = Main.code().str();
1024 getSymbols(TU.build()),
1026 AllOf(withName("Cat"), symRange(Main.range(
"Cat")),
1027 children(AllOf(withName(
"+sharedCat"),
1028 withKind(SymbolKind::Method)))),
1029 AllOf(withName(
"Cat(Sneaky)"), symRange(Main.range(
"SneakyCat")),
1031 AllOf(withName(
"-sneak:"), withKind(SymbolKind::Method)))),
1033 withName(
"Cat()"), symRange(Main.range(
"MeowCat")),
1034 children(AllOf(withName(
"-meow"), withKind(SymbolKind::Method)))),
1035 AllOf(withName(
"Cat()"), symRange(Main.range(
"PurCat")),
1037 AllOf(withName(
"-pur"), withKind(SymbolKind::Method))))));
1040TEST(DocumentSymbolsTest, PragmaMarkGroups) {
1042 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1044 $DogDef[[@interface Dog
1047 $DogImpl[[@implementation Dog
1049 + (id)sharedDoggo { return 0; }
1051 #pragma $Overrides[[mark - Overrides
1058 #pragma $Specifics[[mark - Dog Specifics
1063 @]]end // FIXME: Why doesn't this include the 'end'?
1065 #pragma $End[[mark - End
1068 TU.Code = Main.code().str();
1070 getSymbols(TU.build()),
1071 UnorderedElementsAre(
1072 AllOf(withName("Dog"), symRange(Main.range(
"DogDef"))),
1073 AllOf(withName(
"Dog"), symRange(Main.range(
"DogImpl")),
1074 children(AllOf(withName(
"+sharedDoggo"),
1075 withKind(SymbolKind::Method)),
1076 AllOf(withName(
"Overrides"),
1077 symRange(Main.range(
"Overrides")),
1078 children(AllOf(withName(
"-init"),
1079 withKind(SymbolKind::Method)),
1080 AllOf(withName(
"-bark"),
1081 withKind(SymbolKind::Method)))),
1082 AllOf(withName(
"Dog Specifics"),
1083 symRange(Main.range(
"Specifics")),
1084 children(AllOf(withName(
"-isAGoodBoy"),
1085 withKind(SymbolKind::Method)))))),
1086 AllOf(withName(
"End"), symRange(Main.range(
"End")))));
1089TEST(DocumentSymbolsTest, PragmaMarkGroupsNesting) {
1091 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1097 #pragma mark - NotTopDecl
1102 TU.Code = Main.code().str();
1104 getSymbols(TU.build()),
1105 UnorderedElementsAre(AllOf(
1107 children(AllOf(withName(
"Foo"),
1108 children(AllOf(withName(
"Bar"),
1109 children(AllOf(withName(
"bar"),
1111 "NotTopDecl"))))))),
1112 withName(
"bar")))));
1115TEST(DocumentSymbolsTest, PragmaMarkGroupsNoNesting) {
1117 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1119 #pragma mark Helpers
1120 void helpA(id obj) {}
1125 void coreMethod() {}
1127 TU.Code = Main.code().str();
1128 EXPECT_THAT(getSymbols(TU.build()),
1129 UnorderedElementsAre(withName("Helpers"), withName(
"helpA"),
1130 withName(
"(unnamed group)"),
1131 withName(
"Core"), withName(
"coreMethod")));
Same as llvm::Annotations, but adjusts functions to LSP-specific types for positions and ranges.
Stores and provides access to parsed AST.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
std::string testPath(PathRef File, llvm::sys::path::Style Style)
TEST(BackgroundQueueTest, Priority)
llvm::Expected< std::vector< DocumentSymbol > > getDocumentSymbols(ParsedAST &AST)
Retrieves the symbols contained in the "main file" section of an AST in the same order that they appe...
llvm::Expected< std::vector< SymbolInformation > > getWorkspaceSymbols(llvm::StringRef Query, int Limit, const SymbolIndex *const Index, llvm::StringRef HintPath)
Searches for the symbols matching Query.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< DocumentSymbol > children
Children of this symbol, e.g. properties of a class.
std::vector< std::string > ExtraArgs
static TestTU withCode(llvm::StringRef Code)
llvm::StringMap< std::string > AdditionalFiles