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(
"(unnamed 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 enum)")))),
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")))),
666 children(AllOf(withName(
"(anonymous enum)"), withDetail(
"enum"),
667 children(AllOf(withName(
"Black"),
668 withDetail(
"(unnamed enum)"))))))));
674 testing::Matcher<DocumentSymbol> Matcher;
678 // Basic macro that generates symbols.
679 #define DEFINE_FLAG(X) bool FLAGS_##X; bool FLAGS_no##X
682 AllOf(withName("DEFINE_FLAG"), withDetail(
"(pretty)"),
683 children(withName(
"FLAGS_pretty"), withName(
"FLAGS_nopretty"))),
687 // Hierarchy is determined by primary (name) location.
689 namespace ID(ns) { int ID(y); }
691 AllOf(withName("ID"), withDetail(
"(ns)"),
692 children(AllOf(withName(
"ns"),
693 children(AllOf(withName(
"ID"), withDetail(
"(y)"),
694 children(withName(
"y"))))))),
698 // More typical example where macro only generates part of a decl.
699 #define TEST(A, B) class A##_##B { void go(); }; void A##_##B::go()
700 TEST(DocumentSymbols, Macro) { }
702 AllOf(withName("TEST"), withDetail(
"(DocumentSymbols, Macro)"),
703 children(AllOf(withName(
"DocumentSymbols_Macro"),
704 children(withName(
"go"))),
705 withName(
"DocumentSymbols_Macro::go"))),
710 #define NAMESPACE(NS, BODY) namespace NS { BODY }
711 NAMESPACE(a, NAMESPACE(b, int x;))
714 withName("NAMESPACE"), withDetail(
"(a, NAMESPACE(b, int x;))"),
717 children(AllOf(withName(
"NAMESPACE"),
720 children(AllOf(withName(
"b"),
721 children(withName(
"x"))))))))),
725 // Macro invoked from body is not exposed.
726 #define INNER(X) int X
727 #define OUTER(X) INNER(X)
730 AllOf(withName("OUTER"), withDetail(
"(foo)"),
731 children(withName(
"foo"))),
734 for (
const Test &T : Tests) {
736 EXPECT_THAT(getSymbols(TU.build()), ElementsAre(
T.Matcher)) <<
T.Code;
740TEST(DocumentSymbols, RangeFromMacro) {
744 class name##_Test {};
746 $expansion1[[FF]](abc);
751 $expansion2parens[[$expansion2[[FF2]]()]];
760 #define FF4(name) int name = 0
761 $FooRange[[FF4($FooSelectionRange[[foo]])]];
763 TU.Code = Main.code().str();
765 getSymbols(TU.build()),
767 AllOf(withName("FF"), withDetail(
"(abc)"),
768 children(AllOf(withName(
"abc_Test"), withDetail(
"class"),
769 symNameRange(Main.range(
"expansion1"))))),
770 AllOf(withName(
"FF2"), withDetail(
"()"),
771 symNameRange(Main.range(
"expansion2")),
772 symRange(Main.range(
"expansion2parens")),
773 children(AllOf(withName(
"Test"), withDetail(
"class"),
774 symNameRange(Main.range(
"expansion2"))))),
775 AllOf(withName(
"FF3"), withDetail(
"()"),
776 symRange(Main.range(
"fullDef")),
777 children(AllOf(withName(
"waldo"), withDetail(
"void ()"),
778 symRange(Main.range(
"fullDef"))))),
780 withName(
"FF4"), withDetail(
"(foo)"),
781 children(AllOf(withName(
"foo"), symRange(Main.range(
"FooRange")),
782 symNameRange(Main.range(
"FooSelectionRange")))))));
785TEST(DocumentSymbols, FuncTemplates) {
789 T foo() { return T{}; }
792 auto y = foo<double>();
794 TU.Code = Source.code().str();
796 EXPECT_THAT(getSymbols(TU.build()),
797 ElementsAre(AllOf(withName(
"foo"), withDetail(
"template T ()")),
798 AllOf(withName(
"x"), withDetail(
"int")),
799 AllOf(withName(
"y"), withDetail(
"double"))));
802TEST(DocumentSymbols, UsingDirectives) {
809 namespace ns_alias = ns;
811 using namespace ::ns; // check we don't loose qualifiers.
812 using namespace ns_alias; // and namespace aliases.
814 TU.Code = Source.code().str();
815 EXPECT_THAT(getSymbols(TU.build()),
816 ElementsAre(withName("ns"), withName(
"ns_alias"),
817 withName(
"using namespace ::ns"),
818 withName(
"using namespace ns_alias")));
821TEST(DocumentSymbols, TempSpecs) {
824 template <typename T, typename U, int X = 5> class Foo {};
825 template <typename T> class Foo<int, T> {};
826 template <> class Foo<bool, int> {};
827 template <> class Foo<bool, int, 3> {};
830 EXPECT_THAT(getSymbols(TU.build()),
831 UnorderedElementsAre(
832 AllOf(withName(
"Foo"), withKind(SymbolKind::Class),
833 withDetail(
"template class")),
834 AllOf(withName(
"Foo<int, T>"), withKind(SymbolKind::Class),
835 withDetail(
"template class")),
836 AllOf(withName(
"Foo<bool, int>"), withKind(SymbolKind::Class),
837 withDetail(
"class")),
838 AllOf(withName(
"Foo<bool, int, 3>"),
839 withKind(SymbolKind::Class), withDetail(
"class"))));
842TEST(DocumentSymbols, Qualifiers) {
845 namespace foo { namespace bar {
854 struct foo::bar::Cls { };
856 int foo::bar::func1() { return 10; }
857 int ::foo::bar::func2() { return 20; }
860 int bar::func3() { return 30; }
862 namespace alias = foo::bar;
863 int ::alias::func4() { return 40; }
867 EXPECT_THAT(getSymbols(TU.build()),
868 UnorderedElementsAre(
869 withName(
"foo"), withName(
"foo::bar::Cls"),
870 withName(
"foo::bar::func1"), withName(
"::foo::bar::func2"),
871 withName(
"using namespace foo"), withName(
"bar::func3"),
872 withName(
"alias"), withName(
"::alias::func4")));
875TEST(DocumentSymbols, QualifiersWithTemplateArgs) {
878 template <typename T, typename U = double> class Foo;
881 class Foo<int, double> {
887 using int_type = int;
889 // Typedefs should be preserved!
890 int Foo<int_type, double>::method1() { return 10; }
892 // Default arguments should not be shown!
893 int Foo<int>::method2() { return 20; }
895 using Foo_type = Foo<int>;
896 // If the whole type is aliased, this should be preserved too!
897 int Foo_type::method3() { return 30; }
899 EXPECT_THAT(getSymbols(TU.build()),
900 UnorderedElementsAre(
901 AllOf(withName("Foo"), withDetail(
"template class")),
902 AllOf(withName(
"Foo<int, double>"), withDetail(
"class")),
903 AllOf(withName(
"int_type"), withDetail(
"type alias")),
904 AllOf(withName(
"Foo<int_type, double>::method1"),
905 withDetail(
"int ()")),
906 AllOf(withName(
"Foo<int>::method2"), withDetail(
"int ()")),
907 AllOf(withName(
"Foo_type"), withDetail(
"type alias")),
908 AllOf(withName(
"Foo_type::method3"), withDetail(
"int ()"))));
911TEST(DocumentSymbolsTest, Ranges) {
914 $foo[[int foo(bool Argument) {
918 $variable[[char GLOBAL_VARIABLE]];
927 $field[[unsigned Baz]];
929 $getbaz[[unsigned getBaz() { return Baz; }]]
933 $forwardclass[[class ForwardClassDecl]];
935 $struct[[struct StructDefinition {
936 $structfield[[int *Pointer = nullptr]];
938 $forwardstruct[[struct StructDeclaration]];
940 $forwardfunc[[void forwardFunctionDecl(int Something)]];
942 TU.Code = Main.code().str();
944 getSymbols(TU.build()),
945 UnorderedElementsAre(
946 AllOf(withName("foo"), withKind(SymbolKind::Function),
947 withDetail(
"int (bool)"), symRange(Main.range(
"foo"))),
948 AllOf(withName(
"GLOBAL_VARIABLE"), withKind(SymbolKind::Variable),
949 withDetail(
"char"), symRange(Main.range(
"variable"))),
951 withName(
"ns"), withKind(SymbolKind::Namespace),
952 symRange(Main.range(
"ns")),
954 withName(
"Bar"), withKind(SymbolKind::Class),
955 withDetail(
"class"), symRange(Main.range(
"bar")),
957 AllOf(withName(
"Bar"), withKind(SymbolKind::Constructor),
958 withDetail(
"()"), symRange(Main.range(
"ctor"))),
959 AllOf(withName(
"~Bar"), withKind(SymbolKind::Constructor),
960 withDetail(
""), symRange(Main.range(
"dtor"))),
961 AllOf(withName(
"Baz"), withKind(SymbolKind::Field),
962 withDetail(
"unsigned int"),
963 symRange(Main.range(
"field"))),
964 AllOf(withName(
"getBaz"), withKind(SymbolKind::Method),
965 withDetail(
"unsigned int ()"),
966 symRange(Main.range(
"getbaz"))))))),
967 AllOf(withName(
"ForwardClassDecl"), withKind(SymbolKind::Class),
968 withDetail(
"class"), symRange(Main.range(
"forwardclass"))),
969 AllOf(withName(
"StructDefinition"), withKind(SymbolKind::Struct),
970 withDetail(
"struct"), symRange(Main.range(
"struct")),
971 children(AllOf(withName(
"Pointer"), withKind(SymbolKind::Field),
973 symRange(Main.range(
"structfield"))))),
974 AllOf(withName(
"StructDeclaration"), withKind(SymbolKind::Struct),
975 withDetail(
"struct"), symRange(Main.range(
"forwardstruct"))),
976 AllOf(withName(
"forwardFunctionDecl"), withKind(SymbolKind::Function),
977 withDetail(
"void (int)"),
978 symRange(Main.range(
"forwardfunc")))));
981TEST(DocumentSymbolsTest, DependentType) {
984 template <typename T> auto plus(T x, T y) -> decltype(x + y) { return x + y; }
986 template <typename Key, typename Value> class Pair {};
988 template <typename Key, typename Value>
989 struct Context : public Pair<Key, Value> {
990 using Pair<Key, Value>::Pair;
994 getSymbols(TU.build()),
996 AllOf(withName("plus"),
997 withDetail(
"template auto (T, T) -> decltype(x + y)")),
998 AllOf(withName(
"Pair"), withDetail(
"template class")),
999 AllOf(withName(
"Context"), withDetail(
"template struct"),
1001 withName(
"Pair<type-parameter-0-0, type-parameter-0-1>"),
1002 withDetail(
"<dependent type>"))))));
1005TEST(DocumentSymbolsTest, ObjCCategoriesAndClassExtensions) {
1007 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1009 $Cat[[@interface Cat
1012 $SneakyCat[[@interface Cat (Sneaky)
1013 - (id)sneak:(id)behavior;
1016 $MeowCat[[@interface Cat ()
1019 $PurCat[[@interface Cat ()
1023 TU.Code = Main.code().str();
1025 getSymbols(TU.build()),
1027 AllOf(withName("Cat"), symRange(Main.range(
"Cat")),
1028 children(AllOf(withName(
"+sharedCat"),
1029 withKind(SymbolKind::Method)))),
1030 AllOf(withName(
"Cat(Sneaky)"), symRange(Main.range(
"SneakyCat")),
1032 AllOf(withName(
"-sneak:"), withKind(SymbolKind::Method)))),
1034 withName(
"Cat()"), symRange(Main.range(
"MeowCat")),
1035 children(AllOf(withName(
"-meow"), withKind(SymbolKind::Method)))),
1036 AllOf(withName(
"Cat()"), symRange(Main.range(
"PurCat")),
1038 AllOf(withName(
"-pur"), withKind(SymbolKind::Method))))));
1041TEST(DocumentSymbolsTest, PragmaMarkGroups) {
1043 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1045 $DogDef[[@interface Dog
1048 $DogImpl[[@implementation Dog
1050 + (id)sharedDoggo { return 0; }
1052 #pragma $Overrides[[mark - Overrides
1059 #pragma $Specifics[[mark - Dog Specifics
1064 @]]end // FIXME: Why doesn't this include the 'end'?
1066 #pragma $End[[mark - End
1069 TU.Code = Main.code().str();
1071 getSymbols(TU.build()),
1072 UnorderedElementsAre(
1073 AllOf(withName("Dog"), symRange(Main.range(
"DogDef"))),
1074 AllOf(withName(
"Dog"), symRange(Main.range(
"DogImpl")),
1075 children(AllOf(withName(
"+sharedDoggo"),
1076 withKind(SymbolKind::Method)),
1077 AllOf(withName(
"Overrides"),
1078 symRange(Main.range(
"Overrides")),
1079 children(AllOf(withName(
"-init"),
1080 withKind(SymbolKind::Method)),
1081 AllOf(withName(
"-bark"),
1082 withKind(SymbolKind::Method)))),
1083 AllOf(withName(
"Dog Specifics"),
1084 symRange(Main.range(
"Specifics")),
1085 children(AllOf(withName(
"-isAGoodBoy"),
1086 withKind(SymbolKind::Method)))))),
1087 AllOf(withName(
"End"), symRange(Main.range(
"End")))));
1090TEST(DocumentSymbolsTest, PragmaMarkGroupsNesting) {
1092 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1098 #pragma mark - NotTopDecl
1103 TU.Code = Main.code().str();
1105 getSymbols(TU.build()),
1106 UnorderedElementsAre(AllOf(
1108 children(AllOf(withName(
"Foo"),
1109 children(AllOf(withName(
"Bar"),
1110 children(AllOf(withName(
"bar"),
1112 "NotTopDecl"))))))),
1113 withName(
"bar")))));
1116TEST(DocumentSymbolsTest, PragmaMarkGroupsNoNesting) {
1118 TU.
ExtraArgs = {
"-xobjective-c++",
"-Wno-objc-root-class"};
1120 #pragma mark Helpers
1121 void helpA(id obj) {}
1126 void coreMethod() {}
1128 TU.Code = Main.code().str();
1129 EXPECT_THAT(getSymbols(TU.build()),
1130 UnorderedElementsAre(withName("Helpers"), withName(
"helpA"),
1131 withName(
"(unnamed group)"),
1132 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