clang-tools  14.0.0git
HoverTests.cpp
Go to the documentation of this file.
1 //===-- HoverTests.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "AST.h"
10 #include "Annotations.h"
11 #include "Hover.h"
12 #include "TestIndex.h"
13 #include "TestTU.h"
14 #include "index/MemIndex.h"
15 #include "clang/AST/Attr.h"
16 #include "clang/Basic/Specifiers.h"
17 #include "clang/Index/IndexSymbol.h"
18 #include "llvm/ADT/None.h"
19 #include "llvm/ADT/StringRef.h"
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include <string>
24 #include <vector>
25 
26 namespace clang {
27 namespace clangd {
28 namespace {
29 
30 using PassMode = HoverInfo::PassType::PassMode;
31 
32 TEST(Hover, Structured) {
33  struct {
34  const char *const Code;
35  const std::function<void(HoverInfo &)> ExpectedBuilder;
36  } Cases[] = {
37  // Global scope.
38  {R"cpp(
39  // Best foo ever.
40  void [[fo^o]]() {}
41  )cpp",
42  [](HoverInfo &HI) {
43  HI.NamespaceScope = "";
44  HI.Name = "foo";
45  HI.Kind = index::SymbolKind::Function;
46  HI.Documentation = "Best foo ever.";
47  HI.Definition = "void foo()";
48  HI.ReturnType = "void";
49  HI.Type = "void ()";
50  HI.Parameters.emplace();
51  }},
52  // Inside namespace
53  {R"cpp(
54  namespace ns1 { namespace ns2 {
55  /// Best foo ever.
56  void [[fo^o]]() {}
57  }}
58  )cpp",
59  [](HoverInfo &HI) {
60  HI.NamespaceScope = "ns1::ns2::";
61  HI.Name = "foo";
62  HI.Kind = index::SymbolKind::Function;
63  HI.Documentation = "Best foo ever.";
64  HI.Definition = "void foo()";
65  HI.ReturnType = "void";
66  HI.Type = "void ()";
67  HI.Parameters.emplace();
68  }},
69  // Field
70  {R"cpp(
71  namespace ns1 { namespace ns2 {
72  class Foo {
73  char [[b^ar]];
74  double y[2];
75  };
76  }}
77  )cpp",
78  [](HoverInfo &HI) {
79  HI.NamespaceScope = "ns1::ns2::";
80  HI.LocalScope = "Foo::";
81  HI.Name = "bar";
82  HI.Kind = index::SymbolKind::Field;
83  HI.Definition = "char bar";
84  HI.Type = "char";
85  HI.Offset = 0;
86  HI.Size = 1;
87  HI.Padding = 7;
88  HI.AccessSpecifier = "private";
89  }},
90  // Union field
91  {R"cpp(
92  union Foo {
93  char [[b^ar]];
94  double y[2];
95  };
96  )cpp",
97  [](HoverInfo &HI) {
98  HI.NamespaceScope = "";
99  HI.LocalScope = "Foo::";
100  HI.Name = "bar";
101  HI.Kind = index::SymbolKind::Field;
102  HI.Definition = "char bar";
103  HI.Type = "char";
104  HI.Size = 1;
105  HI.Padding = 15;
106  HI.AccessSpecifier = "public";
107  }},
108  // Bitfield
109  {R"cpp(
110  struct Foo {
111  int [[^x]] : 1;
112  int y : 1;
113  };
114  )cpp",
115  [](HoverInfo &HI) {
116  HI.NamespaceScope = "";
117  HI.LocalScope = "Foo::";
118  HI.Name = "x";
119  HI.Kind = index::SymbolKind::Field;
120  HI.Definition = "int x : 1";
121  HI.Type = "int";
122  HI.AccessSpecifier = "public";
123  }},
124  // Local to class method.
125  {R"cpp(
126  namespace ns1 { namespace ns2 {
127  struct Foo {
128  void foo() {
129  int [[b^ar]];
130  }
131  };
132  }}
133  )cpp",
134  [](HoverInfo &HI) {
135  HI.NamespaceScope = "ns1::ns2::";
136  HI.LocalScope = "Foo::foo::";
137  HI.Name = "bar";
138  HI.Kind = index::SymbolKind::Variable;
139  HI.Definition = "int bar";
140  HI.Type = "int";
141  }},
142  // Anon namespace and local scope.
143  {R"cpp(
144  namespace ns1 { namespace {
145  struct {
146  char [[b^ar]];
147  } T;
148  }}
149  )cpp",
150  [](HoverInfo &HI) {
151  HI.NamespaceScope = "ns1::";
152  HI.LocalScope = "(anonymous struct)::";
153  HI.Name = "bar";
154  HI.Kind = index::SymbolKind::Field;
155  HI.Definition = "char bar";
156  HI.Type = "char";
157  HI.Offset = 0;
158  HI.Size = 1;
159  HI.AccessSpecifier = "public";
160  }},
161  // Struct definition shows size.
162  {R"cpp(
163  struct [[^X]]{};
164  )cpp",
165  [](HoverInfo &HI) {
166  HI.NamespaceScope = "";
167  HI.Name = "X";
168  HI.Kind = index::SymbolKind::Struct;
169  HI.Definition = "struct X {}";
170  HI.Size = 1;
171  }},
172  // Variable with template type
173  {R"cpp(
174  template <typename T, class... Ts> class Foo { public: Foo(int); };
175  Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
176  )cpp",
177  [](HoverInfo &HI) {
178  HI.NamespaceScope = "";
179  HI.Name = "foo";
180  HI.Kind = index::SymbolKind::Variable;
181  HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
182  HI.Type = "Foo<int, char, bool>";
183  }},
184  // Implicit template instantiation
185  {R"cpp(
186  template <typename T> class vector{};
187  [[vec^tor]]<int> foo;
188  )cpp",
189  [](HoverInfo &HI) {
190  HI.NamespaceScope = "";
191  HI.Name = "vector<int>";
192  HI.Kind = index::SymbolKind::Class;
193  HI.Definition = "template <> class vector<int> {}";
194  }},
195  // Class template
196  {R"cpp(
197  template <template<typename, bool...> class C,
198  typename = char,
199  int = 0,
200  bool Q = false,
201  class... Ts> class Foo {};
202  template <template<typename, bool...> class T>
203  [[F^oo]]<T> foo;
204  )cpp",
205  [](HoverInfo &HI) {
206  HI.NamespaceScope = "";
207  HI.Name = "Foo";
208  HI.Kind = index::SymbolKind::Class;
209  HI.Definition =
210  R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
211  bool Q = false, class... Ts>
212 class Foo {})cpp";
213  HI.TemplateParameters = {
214  {std::string("template <typename, bool...> class"),
215  std::string("C"), llvm::None},
216  {std::string("typename"), llvm::None, std::string("char")},
217  {std::string("int"), llvm::None, std::string("0")},
218  {std::string("bool"), std::string("Q"), std::string("false")},
219  {std::string("class..."), std::string("Ts"), llvm::None},
220  };
221  }},
222  // Function template
223  {R"cpp(
224  template <template<typename, bool...> class C,
225  typename = char,
226  int = 0,
227  bool Q = false,
228  class... Ts> void foo();
229  template<typename, bool...> class Foo;
230 
231  void bar() {
232  [[fo^o]]<Foo>();
233  }
234  )cpp",
235  [](HoverInfo &HI) {
236  HI.NamespaceScope = "";
237  HI.Name = "foo";
238  HI.Kind = index::SymbolKind::Function;
239  HI.Definition = "template <> void foo<Foo, char, 0, false, <>>()";
240  HI.ReturnType = "void";
241  HI.Type = "void ()";
242  HI.Parameters.emplace();
243  }},
244  // Function decl
245  {R"cpp(
246  template<typename, bool...> class Foo {};
247  Foo<bool, true, false> foo(int, bool T = false);
248 
249  void bar() {
250  [[fo^o]](3);
251  }
252  )cpp",
253  [](HoverInfo &HI) {
254  HI.NamespaceScope = "";
255  HI.Name = "foo";
256  HI.Kind = index::SymbolKind::Function;
257  HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)";
258  HI.ReturnType = "Foo<bool, true, false>";
259  HI.Type = "Foo<bool, true, false> (int, bool)";
260  HI.Parameters = {
261  {std::string("int"), llvm::None, llvm::None},
262  {std::string("bool"), std::string("T"), std::string("false")},
263  };
264  }},
265  // Pointers to lambdas
266  {R"cpp(
267  void foo() {
268  auto lamb = [](int T, bool B) -> bool { return T && B; };
269  auto *b = &lamb;
270  auto *[[^c]] = &b;
271  }
272  )cpp",
273  [](HoverInfo &HI) {
274  HI.NamespaceScope = "";
275  HI.LocalScope = "foo::";
276  HI.Name = "c";
277  HI.Kind = index::SymbolKind::Variable;
278  HI.Definition = "auto *c = &b";
279  HI.Type = "(lambda) **";
280  HI.ReturnType = "bool";
281  HI.Parameters = {
282  {std::string("int"), std::string("T"), llvm::None},
283  {std::string("bool"), std::string("B"), llvm::None},
284  };
285  return HI;
286  }},
287  // Lambda parameter with decltype reference
288  {R"cpp(
289  auto lamb = [](int T, bool B) -> bool { return T && B; };
290  void foo(decltype(lamb)& bar) {
291  [[ba^r]](0, false);
292  }
293  )cpp",
294  [](HoverInfo &HI) {
295  HI.NamespaceScope = "";
296  HI.LocalScope = "foo::";
297  HI.Name = "bar";
298  HI.Kind = index::SymbolKind::Parameter;
299  HI.Definition = "decltype(lamb) &bar";
300  HI.Type = "decltype(lamb) &";
301  HI.ReturnType = "bool";
302  HI.Parameters = {
303  {std::string("int"), std::string("T"), llvm::None},
304  {std::string("bool"), std::string("B"), llvm::None},
305  };
306  return HI;
307  }},
308  // Lambda parameter with decltype
309  {R"cpp(
310  auto lamb = [](int T, bool B) -> bool { return T && B; };
311  void foo(decltype(lamb) bar) {
312  [[ba^r]](0, false);
313  }
314  )cpp",
315  [](HoverInfo &HI) {
316  HI.NamespaceScope = "";
317  HI.LocalScope = "foo::";
318  HI.Name = "bar";
319  HI.Kind = index::SymbolKind::Parameter;
320  HI.Definition = "decltype(lamb) bar";
321  HI.Type = "class (lambda)";
322  HI.ReturnType = "bool";
323  HI.Parameters = {
324  {std::string("int"), std::string("T"), llvm::None},
325  {std::string("bool"), std::string("B"), llvm::None},
326  };
327  HI.Value = "false";
328  return HI;
329  }},
330  // Lambda variable
331  {R"cpp(
332  void foo() {
333  int bar = 5;
334  auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
335  bool res = [[lam^b]](bar, false);
336  }
337  )cpp",
338  [](HoverInfo &HI) {
339  HI.NamespaceScope = "";
340  HI.LocalScope = "foo::";
341  HI.Name = "lamb";
342  HI.Kind = index::SymbolKind::Variable;
343  HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
344  HI.Type = "class (lambda)";
345  HI.ReturnType = "bool";
346  HI.Parameters = {
347  {std::string("int"), std::string("T"), llvm::None},
348  {std::string("bool"), std::string("B"), llvm::None},
349  };
350  return HI;
351  }},
352  // Local variable in lambda
353  {R"cpp(
354  void foo() {
355  auto lamb = []{int [[te^st]];};
356  }
357  )cpp",
358  [](HoverInfo &HI) {
359  HI.NamespaceScope = "";
360  HI.LocalScope = "foo::(anonymous class)::operator()::";
361  HI.Name = "test";
362  HI.Kind = index::SymbolKind::Variable;
363  HI.Definition = "int test";
364  HI.Type = "int";
365  }},
366  // Partially-specialized class template. (formerly type-parameter-0-0)
367  {R"cpp(
368  template <typename T> class X;
369  template <typename T> class [[^X]]<T*> {};
370  )cpp",
371  [](HoverInfo &HI) {
372  HI.Name = "X<T *>";
373  HI.NamespaceScope = "";
374  HI.Kind = index::SymbolKind::Class;
375  HI.Definition = "template <typename T> class X<T *> {}";
376  }},
377  // Constructor of partially-specialized class template
378  {R"cpp(
379  template<typename, typename=void> struct X;
380  template<typename T> struct X<T*>{ [[^X]](); };
381  )cpp",
382  [](HoverInfo &HI) {
383  HI.NamespaceScope = "";
384  HI.Name = "X";
385  HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>::
386  HI.Kind = index::SymbolKind::Constructor;
387  HI.Definition = "X()";
388  HI.Parameters.emplace();
389  HI.AccessSpecifier = "public";
390  }},
391  {"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]()
392  [](HoverInfo &HI) {
393  HI.NamespaceScope = "";
394  HI.Name = "~X";
395  HI.LocalScope = "X::";
396  HI.Kind = index::SymbolKind::Destructor;
397  HI.Definition = "~X()";
398  HI.Parameters.emplace();
399  HI.AccessSpecifier = "private";
400  }},
401  {"class X { [[op^erator]] int(); };",
402  [](HoverInfo &HI) {
403  HI.NamespaceScope = "";
404  HI.Name = "operator int";
405  HI.LocalScope = "X::";
406  HI.Kind = index::SymbolKind::ConversionFunction;
407  HI.Definition = "operator int()";
408  HI.Parameters.emplace();
409  HI.AccessSpecifier = "private";
410  }},
411  {"class X { operator [[^X]](); };",
412  [](HoverInfo &HI) {
413  HI.NamespaceScope = "";
414  HI.Name = "X";
415  HI.Kind = index::SymbolKind::Class;
416  HI.Definition = "class X {}";
417  }},
418 
419  // auto on structured bindings
420  {R"cpp(
421  void foo() {
422  struct S { int x; float y; };
423  [[au^to]] [x, y] = S();
424  }
425  )cpp",
426  [](HoverInfo &HI) {
427  HI.Name = "auto";
428  HI.Kind = index::SymbolKind::TypeAlias;
429  HI.Definition = "struct S";
430  }},
431  // undeduced auto
432  {R"cpp(
433  template<typename T>
434  void foo() {
435  [[au^to]] x = T{};
436  }
437  )cpp",
438  [](HoverInfo &HI) {
439  HI.Name = "auto";
440  HI.Kind = index::SymbolKind::TypeAlias;
441  HI.Definition = "/* not deduced */";
442  }},
443  // auto on lambda
444  {R"cpp(
445  void foo() {
446  [[au^to]] lamb = []{};
447  }
448  )cpp",
449  [](HoverInfo &HI) {
450  HI.Name = "auto";
451  HI.Kind = index::SymbolKind::TypeAlias;
452  HI.Definition = "class(lambda)";
453  }},
454  // auto on template instantiation
455  {R"cpp(
456  template<typename T> class Foo{};
457  void foo() {
458  [[au^to]] x = Foo<int>();
459  }
460  )cpp",
461  [](HoverInfo &HI) {
462  HI.Name = "auto";
463  HI.Kind = index::SymbolKind::TypeAlias;
464  HI.Definition = "class Foo<int>";
465  }},
466  // auto on specialized template
467  {R"cpp(
468  template<typename T> class Foo{};
469  template<> class Foo<int>{};
470  void foo() {
471  [[au^to]] x = Foo<int>();
472  }
473  )cpp",
474  [](HoverInfo &HI) {
475  HI.Name = "auto";
476  HI.Kind = index::SymbolKind::TypeAlias;
477  HI.Definition = "class Foo<int>";
478  }},
479 
480  // macro
481  {R"cpp(
482  // Best MACRO ever.
483  #define MACRO(x,y,z) void foo(x, y, z);
484  [[MAC^RO]](int, double d, bool z = false);
485  )cpp",
486  [](HoverInfo &HI) {
487  HI.Name = "MACRO", HI.Kind = index::SymbolKind::Macro,
488  HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);";
489  }},
490 
491  // constexprs
492  {R"cpp(
493  constexpr int add(int a, int b) { return a + b; }
494  int [[b^ar]] = add(1, 2);
495  )cpp",
496  [](HoverInfo &HI) {
497  HI.Name = "bar";
498  HI.Definition = "int bar = add(1, 2)";
499  HI.Kind = index::SymbolKind::Variable;
500  HI.Type = "int";
501  HI.NamespaceScope = "";
502  HI.Value = "3";
503  }},
504  {R"cpp(
505  int [[b^ar]] = sizeof(char);
506  )cpp",
507  [](HoverInfo &HI) {
508  HI.Name = "bar";
509  HI.Definition = "int bar = sizeof(char)";
510  HI.Kind = index::SymbolKind::Variable;
511  HI.Type = "int";
512  HI.NamespaceScope = "";
513  HI.Value = "1";
514  }},
515  {R"cpp(
516  template<int a, int b> struct Add {
517  static constexpr int result = a + b;
518  };
519  int [[ba^r]] = Add<1, 2>::result;
520  )cpp",
521  [](HoverInfo &HI) {
522  HI.Name = "bar";
523  HI.Definition = "int bar = Add<1, 2>::result";
524  HI.Kind = index::SymbolKind::Variable;
525  HI.Type = "int";
526  HI.NamespaceScope = "";
527  HI.Value = "3";
528  }},
529  {R"cpp(
530  enum Color { RED = -123, GREEN = 5, };
531  Color x = [[GR^EEN]];
532  )cpp",
533  [](HoverInfo &HI) {
534  HI.Name = "GREEN";
535  HI.NamespaceScope = "";
536  HI.LocalScope = "Color::";
537  HI.Definition = "GREEN = 5";
538  HI.Kind = index::SymbolKind::EnumConstant;
539  HI.Type = "enum Color";
540  HI.Value = "5"; // Numeric on the enumerator name, no hex as small.
541  }},
542  {R"cpp(
543  enum Color { RED = -123, GREEN = 5, };
544  Color x = RED;
545  Color y = [[^x]];
546  )cpp",
547  [](HoverInfo &HI) {
548  HI.Name = "x";
549  HI.NamespaceScope = "";
550  HI.Definition = "Color x = RED";
551  HI.Kind = index::SymbolKind::Variable;
552  HI.Type = "enum Color";
553  HI.Value = "RED (0xffffff85)"; // Symbolic on an expression.
554  }},
555  {R"cpp(
556  template<int a, int b> struct Add {
557  static constexpr int result = a + b;
558  };
559  int bar = Add<1, 2>::[[resu^lt]];
560  )cpp",
561  [](HoverInfo &HI) {
562  HI.Name = "result";
563  HI.Definition = "static constexpr int result = a + b";
564  HI.Kind = index::SymbolKind::StaticProperty;
565  HI.Type = "const int";
566  HI.NamespaceScope = "";
567  HI.LocalScope = "Add<1, 2>::";
568  HI.Value = "3";
569  HI.AccessSpecifier = "public";
570  }},
571  {R"cpp(
572  constexpr int answer() { return 40 + 2; }
573  int x = [[ans^wer]]();
574  )cpp",
575  [](HoverInfo &HI) {
576  HI.Name = "answer";
577  HI.Definition = "constexpr int answer()";
578  HI.Kind = index::SymbolKind::Function;
579  HI.Type = "int ()";
580  HI.ReturnType = "int";
581  HI.Parameters.emplace();
582  HI.NamespaceScope = "";
583  HI.Value = "42 (0x2a)";
584  }},
585  {R"cpp(
586  const char *[[ba^r]] = "1234";
587  )cpp",
588  [](HoverInfo &HI) {
589  HI.Name = "bar";
590  HI.Definition = "const char *bar = \"1234\"";
591  HI.Kind = index::SymbolKind::Variable;
592  HI.Type = "const char *";
593  HI.NamespaceScope = "";
594  HI.Value = "&\"1234\"[0]";
595  }},
596  {R"cpp(// Should not crash
597  template <typename T>
598  struct Tmpl {
599  Tmpl(int name);
600  };
601 
602  template <typename A>
603  void boom(int name) {
604  new Tmpl<A>([[na^me]]);
605  })cpp",
606  [](HoverInfo &HI) {
607  HI.Name = "name";
608  HI.Definition = "int name";
609  HI.Kind = index::SymbolKind::Parameter;
610  HI.Type = "int";
611  HI.NamespaceScope = "";
612  HI.LocalScope = "boom::";
613  }},
614  {
615  R"cpp(// Should not print inline or anon namespaces.
616  namespace ns {
617  inline namespace in_ns {
618  namespace a {
619  namespace {
620  namespace b {
621  inline namespace in_ns2 {
622  class Foo {};
623  } // in_ns2
624  } // b
625  } // anon
626  } // a
627  } // in_ns
628  } // ns
629  void foo() {
630  ns::a::b::[[F^oo]] x;
631  (void)x;
632  }
633  )cpp",
634  [](HoverInfo &HI) {
635  HI.Name = "Foo";
636  HI.Kind = index::SymbolKind::Class;
637  HI.NamespaceScope = "ns::a::b::";
638  HI.Definition = "class Foo {}";
639  }},
640  {
641  R"cpp(
642  template <typename T> class Foo {};
643  class X;
644  void foo() {
645  [[^auto]] x = Foo<X>();
646  }
647  )cpp",
648  [](HoverInfo &HI) {
649  HI.Name = "auto";
650  HI.Kind = index::SymbolKind::TypeAlias;
651  HI.Definition = "class Foo<X>";
652  }},
653  {// Falls back to primary template, when the type is not instantiated.
654  R"cpp(
655  // comment from primary
656  template <typename T> class Foo {};
657  // comment from specialization
658  template <typename T> class Foo<T*> {};
659  void foo() {
660  [[Fo^o]]<int*> *x = nullptr;
661  }
662  )cpp",
663  [](HoverInfo &HI) {
664  HI.Name = "Foo<int *>";
665  HI.Kind = index::SymbolKind::Class;
666  HI.NamespaceScope = "";
667  HI.Definition = "template <> class Foo<int *>";
668  // FIXME: Maybe force instantiation to make use of real template
669  // pattern.
670  HI.Documentation = "comment from primary";
671  }},
672  {// Template Type Parameter
673  R"cpp(
674  template <typename [[^T]] = int> void foo();
675  )cpp",
676  [](HoverInfo &HI) {
677  HI.Name = "T";
678  HI.Kind = index::SymbolKind::TemplateTypeParm;
679  HI.NamespaceScope = "";
680  HI.Definition = "typename T = int";
681  HI.LocalScope = "foo::";
682  HI.Type = "typename";
683  HI.AccessSpecifier = "public";
684  }},
685  {// TemplateTemplate Type Parameter
686  R"cpp(
687  template <template<typename> class [[^T]]> void foo();
688  )cpp",
689  [](HoverInfo &HI) {
690  HI.Name = "T";
691  HI.Kind = index::SymbolKind::TemplateTemplateParm;
692  HI.NamespaceScope = "";
693  HI.Definition = "template <typename> class T";
694  HI.LocalScope = "foo::";
695  HI.Type = "template <typename> class";
696  HI.AccessSpecifier = "public";
697  }},
698  {// NonType Template Parameter
699  R"cpp(
700  template <int [[^T]] = 5> void foo();
701  )cpp",
702  [](HoverInfo &HI) {
703  HI.Name = "T";
704  HI.Kind = index::SymbolKind::NonTypeTemplateParm;
705  HI.NamespaceScope = "";
706  HI.Definition = "int T = 5";
707  HI.LocalScope = "foo::";
708  HI.Type = "int";
709  HI.AccessSpecifier = "public";
710  }},
711 
712  {// Getter
713  R"cpp(
714  struct X { int Y; float [[^y]]() { return Y; } };
715  )cpp",
716  [](HoverInfo &HI) {
717  HI.Name = "y";
718  HI.Kind = index::SymbolKind::InstanceMethod;
719  HI.NamespaceScope = "";
720  HI.Definition = "float y()";
721  HI.LocalScope = "X::";
722  HI.Documentation = "Trivial accessor for `Y`.";
723  HI.Type = "float ()";
724  HI.ReturnType = "float";
725  HI.Parameters.emplace();
726  HI.AccessSpecifier = "public";
727  }},
728  {// Setter
729  R"cpp(
730  struct X { int Y; void [[^setY]](float v) { Y = v; } };
731  )cpp",
732  [](HoverInfo &HI) {
733  HI.Name = "setY";
734  HI.Kind = index::SymbolKind::InstanceMethod;
735  HI.NamespaceScope = "";
736  HI.Definition = "void setY(float v)";
737  HI.LocalScope = "X::";
738  HI.Documentation = "Trivial setter for `Y`.";
739  HI.Type = "void (float)";
740  HI.ReturnType = "void";
741  HI.Parameters.emplace();
742  HI.Parameters->emplace_back();
743  HI.Parameters->back().Type = "float";
744  HI.Parameters->back().Name = "v";
745  HI.AccessSpecifier = "public";
746  }},
747  {// Setter (builder)
748  R"cpp(
749  struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
750  )cpp",
751  [](HoverInfo &HI) {
752  HI.Name = "setY";
753  HI.Kind = index::SymbolKind::InstanceMethod;
754  HI.NamespaceScope = "";
755  HI.Definition = "X &setY(float v)";
756  HI.LocalScope = "X::";
757  HI.Documentation = "Trivial setter for `Y`.";
758  HI.Type = "X &(float)";
759  HI.ReturnType = "X &";
760  HI.Parameters.emplace();
761  HI.Parameters->emplace_back();
762  HI.Parameters->back().Type = "float";
763  HI.Parameters->back().Name = "v";
764  HI.AccessSpecifier = "public";
765  }},
766  {// Setter (move)
767  R"cpp(
768  namespace std { template<typename T> T&& move(T&& t); }
769  struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
770  )cpp",
771  [](HoverInfo &HI) {
772  HI.Name = "setY";
773  HI.Kind = index::SymbolKind::InstanceMethod;
774  HI.NamespaceScope = "";
775  HI.Definition = "void setY(float v)";
776  HI.LocalScope = "X::";
777  HI.Documentation = "Trivial setter for `Y`.";
778  HI.Type = "void (float)";
779  HI.ReturnType = "void";
780  HI.Parameters.emplace();
781  HI.Parameters->emplace_back();
782  HI.Parameters->back().Type = "float";
783  HI.Parameters->back().Name = "v";
784  HI.AccessSpecifier = "public";
785  }},
786  {// Field type initializer.
787  R"cpp(
788  struct X { int x = 2; };
789  X ^[[x]];
790  )cpp",
791  [](HoverInfo &HI) {
792  HI.Name = "x";
793  HI.Kind = index::SymbolKind::Variable;
794  HI.NamespaceScope = "";
795  HI.Definition = "X x";
796  HI.Type = "struct X";
797  }},
798  {// Don't crash on null types.
799  R"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
800  [](HoverInfo &HI) {
801  HI.Name = "x";
802  HI.Kind = index::SymbolKind::Variable;
803  HI.NamespaceScope = "";
804  HI.Definition = "";
805  HI.Type = "NULL TYPE";
806  // Bindings are in theory public members of an anonymous struct.
807  HI.AccessSpecifier = "public";
808  }},
809  {// Extra info for function call.
810  R"cpp(
811  void fun(int arg_a, int &arg_b) {};
812  void code() {
813  int a = 1, b = 2;
814  fun(a, [[^b]]);
815  }
816  )cpp",
817  [](HoverInfo &HI) {
818  HI.Name = "b";
819  HI.Kind = index::SymbolKind::Variable;
820  HI.NamespaceScope = "";
821  HI.Definition = "int b = 2";
822  HI.LocalScope = "code::";
823  HI.Value = "2";
824  HI.Type = "int";
825  HI.CalleeArgInfo.emplace();
826  HI.CalleeArgInfo->Name = "arg_b";
827  HI.CalleeArgInfo->Type = "int &";
828  HI.CallPassType.emplace();
829  HI.CallPassType->PassBy = PassMode::Ref;
830  HI.CallPassType->Converted = false;
831  }},
832  {// Extra info for method call.
833  R"cpp(
834  class C {
835  public:
836  void fun(int arg_a = 3, int arg_b = 4) {}
837  };
838  void code() {
839  int a = 1, b = 2;
840  C c;
841  c.fun([[^a]], b);
842  }
843  )cpp",
844  [](HoverInfo &HI) {
845  HI.Name = "a";
846  HI.Kind = index::SymbolKind::Variable;
847  HI.NamespaceScope = "";
848  HI.Definition = "int a = 1";
849  HI.LocalScope = "code::";
850  HI.Value = "1";
851  HI.Type = "int";
852  HI.CalleeArgInfo.emplace();
853  HI.CalleeArgInfo->Name = "arg_a";
854  HI.CalleeArgInfo->Type = "int";
855  HI.CalleeArgInfo->Default = "3";
856  HI.CallPassType.emplace();
857  HI.CallPassType->PassBy = PassMode::Value;
858  HI.CallPassType->Converted = false;
859  }},
860  {// Dont crash on invalid decl
861  R"cpp(
862  // error-ok
863  struct Foo {
864  Bar [[x^x]];
865  };)cpp",
866  [](HoverInfo &HI) {
867  HI.Name = "xx";
868  HI.Kind = index::SymbolKind::Field;
869  HI.NamespaceScope = "";
870  HI.Definition = "int xx";
871  HI.LocalScope = "Foo::";
872  HI.Type = "int";
873  HI.AccessSpecifier = "public";
874  }},
875  {R"cpp(
876  // error-ok
877  struct Foo {
878  Bar xx;
879  int [[y^y]];
880  };)cpp",
881  [](HoverInfo &HI) {
882  HI.Name = "yy";
883  HI.Kind = index::SymbolKind::Field;
884  HI.NamespaceScope = "";
885  HI.Definition = "int yy";
886  HI.LocalScope = "Foo::";
887  HI.Type = "int";
888  HI.AccessSpecifier = "public";
889  }},
890  {// No crash on InitListExpr.
891  R"cpp(
892  struct Foo {
893  int a[10];
894  };
895  constexpr Foo k2 = {
896  ^[[{]]1} // FIXME: why the hover range is 1 character?
897  };
898  )cpp",
899  [](HoverInfo &HI) {
900  HI.Name = "expression";
901  HI.Kind = index::SymbolKind::Unknown;
902  HI.Type = "int [10]";
903  HI.Value = "{1}";
904  }}};
905  for (const auto &Case : Cases) {
906  SCOPED_TRACE(Case.Code);
907 
908  Annotations T(Case.Code);
909  TestTU TU = TestTU::withCode(T.code());
910  TU.ExtraArgs.push_back("-std=c++17");
911  // Types might be different depending on the target triplet, we chose a
912  // fixed one to make sure tests passes on different platform.
913  TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
914  auto AST = TU.build();
915 
916  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
917  ASSERT_TRUE(H);
918  HoverInfo Expected;
919  Expected.SymRange = T.range();
920  Case.ExpectedBuilder(Expected);
921 
922  EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
923  EXPECT_EQ(H->LocalScope, Expected.LocalScope);
924  EXPECT_EQ(H->Name, Expected.Name);
925  EXPECT_EQ(H->Kind, Expected.Kind);
926  EXPECT_EQ(H->Documentation, Expected.Documentation);
927  EXPECT_EQ(H->Definition, Expected.Definition);
928  EXPECT_EQ(H->Type, Expected.Type);
929  EXPECT_EQ(H->ReturnType, Expected.ReturnType);
930  EXPECT_EQ(H->Parameters, Expected.Parameters);
931  EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
932  EXPECT_EQ(H->SymRange, Expected.SymRange);
933  EXPECT_EQ(H->Value, Expected.Value);
934  EXPECT_EQ(H->Size, Expected.Size);
935  EXPECT_EQ(H->Offset, Expected.Offset);
936  EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
937  EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
938  EXPECT_EQ(H->CallPassType, Expected.CallPassType);
939  }
940 }
941 
942 TEST(Hover, DefinitionLanuage) {
943  struct {
944  const char *const Code;
945  const std::string ClangLanguageFlag;
946  const char *const ExpectedDefinitionLanguage;
947  } Cases[] = {{R"cpp(
948  void [[some^Global]]() {}
949  )cpp",
950  "", "cpp"},
951  {R"cpp(
952  void [[some^Global]]() {}
953  )cpp",
954  "-xobjective-c++", "objective-cpp"},
955  {R"cpp(
956  void [[some^Global]]() {}
957  )cpp",
958  "-xobjective-c", "objective-c"}};
959  for (const auto &Case : Cases) {
960  SCOPED_TRACE(Case.Code);
961 
962  Annotations T(Case.Code);
963  TestTU TU = TestTU::withCode(T.code());
964  if (!Case.ClangLanguageFlag.empty())
965  TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
966  auto AST = TU.build();
967 
968  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
969  ASSERT_TRUE(H);
970 
971  EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
972  }
973 }
974 
975 TEST(Hover, CallPassType) {
976  const llvm::StringRef CodePrefix = R"cpp(
977 class Base {};
978 class Derived : public Base {};
979 class CustomClass {
980  public:
981  CustomClass() {}
982  CustomClass(const Base &x) {}
983  CustomClass(int &x) {}
984  CustomClass(float x) {}
985 };
986 
987 void int_by_ref(int &x) {}
988 void int_by_const_ref(const int &x) {}
989 void int_by_value(int x) {}
990 void base_by_ref(Base &x) {}
991 void base_by_const_ref(const Base &x) {}
992 void base_by_value(Base x) {}
993 void float_by_value(float x) {}
994 void custom_by_value(CustomClass x) {}
995 
996 void fun() {
997  int int_x;
998  int &int_ref = int_x;
999  const int &int_const_ref = int_x;
1000  Base base;
1001  const Base &base_const_ref = base;
1002  Derived derived;
1003  float float_x;
1004 )cpp";
1005  const llvm::StringRef CodeSuffix = "}";
1006 
1007  struct {
1008  const char *const Code;
1010  bool Converted;
1011  } Tests[] = {
1012  // Integer tests
1013  {"int_by_value([[^int_x]]);", PassMode::Value, false},
1014  {"int_by_ref([[^int_x]]);", PassMode::Ref, false},
1015  {"int_by_const_ref([[^int_x]]);", PassMode::ConstRef, false},
1016  {"int_by_value([[^int_ref]]);", PassMode::Value, false},
1017  {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
1018  {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
1019  {"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef, false},
1020  // Custom class tests
1021  {"base_by_ref([[^base]]);", PassMode::Ref, false},
1022  {"base_by_const_ref([[^base]]);", PassMode::ConstRef, false},
1023  {"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef, false},
1024  {"base_by_value([[^base]]);", PassMode::Value, false},
1025  {"base_by_value([[^base_const_ref]]);", PassMode::Value, false},
1026  {"base_by_ref([[^derived]]);", PassMode::Ref, false},
1027  {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false},
1028  {"base_by_value([[^derived]]);", PassMode::Value, false},
1029  // Converted tests
1030  {"float_by_value([[^int_x]]);", PassMode::Value, true},
1031  {"float_by_value([[^int_ref]]);", PassMode::Value, true},
1032  {"float_by_value([[^int_const_ref]]);", PassMode::Value, true},
1033  {"custom_by_value([[^int_x]]);", PassMode::Ref, true},
1034  {"custom_by_value([[^float_x]]);", PassMode::Value, true},
1035  {"custom_by_value([[^base]]);", PassMode::ConstRef, true},
1036  };
1037  for (const auto &Test : Tests) {
1038  SCOPED_TRACE(Test.Code);
1039 
1040  const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
1041  Annotations T(Code);
1042  TestTU TU = TestTU::withCode(T.code());
1043  TU.ExtraArgs.push_back("-std=c++17");
1044  auto AST = TU.build();
1045  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1046  ASSERT_TRUE(H);
1047  EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
1048  EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
1049  }
1050 }
1051 
1052 TEST(Hover, NoHover) {
1053  llvm::StringRef Tests[] = {
1054  "^int main() {}",
1055  "void foo() {^}",
1056  // FIXME: "decltype(auto)" should be a single hover
1057  "decltype(au^to) x = 0;",
1058  // FIXME: not supported yet
1059  R"cpp(// Lambda auto parameter
1060  auto lamb = [](a^uto){};
1061  )cpp",
1062  R"cpp(// non-named decls don't get hover. Don't crash!
1063  ^static_assert(1, "");
1064  )cpp",
1065  R"cpp(// non-evaluatable expr
1066  template <typename T> void foo() {
1067  (void)[[size^of]](T);
1068  })cpp",
1069  R"cpp(// should not crash on invalid semantic form of init-list-expr.
1070  /*error-ok*/
1071  struct Foo {
1072  int xyz = 0;
1073  };
1074  class Bar {};
1075  constexpr Foo s = ^{
1076  .xyz = Bar(),
1077  };
1078  )cpp",
1079  // literals
1080  "auto x = t^rue;",
1081  "auto x = '^A';",
1082  "auto x = ^(int){42};",
1083  "auto x = ^42.;",
1084  "auto x = ^42.0i;",
1085  "auto x = ^42;",
1086  "auto x = ^nullptr;",
1087  "auto x = ^\"asdf\";",
1088  };
1089 
1090  for (const auto &Test : Tests) {
1091  SCOPED_TRACE(Test);
1092 
1093  Annotations T(Test);
1094  TestTU TU = TestTU::withCode(T.code());
1095  TU.ExtraArgs.push_back("-std=c++17");
1096  auto AST = TU.build();
1097  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1098  ASSERT_FALSE(H);
1099  }
1100 }
1101 
1102 TEST(Hover, All) {
1103  struct {
1104  const char *const Code;
1105  const std::function<void(HoverInfo &)> ExpectedBuilder;
1106  } Cases[] = {
1107  {
1108  R"cpp(// Local variable
1109  int main() {
1110  int bonjour;
1111  ^[[bonjour]] = 2;
1112  int test1 = bonjour;
1113  }
1114  )cpp",
1115  [](HoverInfo &HI) {
1116  HI.Name = "bonjour";
1117  HI.Kind = index::SymbolKind::Variable;
1118  HI.NamespaceScope = "";
1119  HI.LocalScope = "main::";
1120  HI.Type = "int";
1121  HI.Definition = "int bonjour";
1122  }},
1123  {
1124  R"cpp(// Local variable in method
1125  struct s {
1126  void method() {
1127  int bonjour;
1128  ^[[bonjour]] = 2;
1129  }
1130  };
1131  )cpp",
1132  [](HoverInfo &HI) {
1133  HI.Name = "bonjour";
1134  HI.Kind = index::SymbolKind::Variable;
1135  HI.NamespaceScope = "";
1136  HI.LocalScope = "s::method::";
1137  HI.Type = "int";
1138  HI.Definition = "int bonjour";
1139  }},
1140  {
1141  R"cpp(// Struct
1142  namespace ns1 {
1143  struct MyClass {};
1144  } // namespace ns1
1145  int main() {
1146  ns1::[[My^Class]]* Params;
1147  }
1148  )cpp",
1149  [](HoverInfo &HI) {
1150  HI.Name = "MyClass";
1151  HI.Kind = index::SymbolKind::Struct;
1152  HI.NamespaceScope = "ns1::";
1153  HI.Definition = "struct MyClass {}";
1154  }},
1155  {
1156  R"cpp(// Class
1157  namespace ns1 {
1158  class MyClass {};
1159  } // namespace ns1
1160  int main() {
1161  ns1::[[My^Class]]* Params;
1162  }
1163  )cpp",
1164  [](HoverInfo &HI) {
1165  HI.Name = "MyClass";
1166  HI.Kind = index::SymbolKind::Class;
1167  HI.NamespaceScope = "ns1::";
1168  HI.Definition = "class MyClass {}";
1169  }},
1170  {
1171  R"cpp(// Union
1172  namespace ns1 {
1173  union MyUnion { int x; int y; };
1174  } // namespace ns1
1175  int main() {
1176  ns1::[[My^Union]] Params;
1177  }
1178  )cpp",
1179  [](HoverInfo &HI) {
1180  HI.Name = "MyUnion";
1181  HI.Kind = index::SymbolKind::Union;
1182  HI.NamespaceScope = "ns1::";
1183  HI.Definition = "union MyUnion {}";
1184  }},
1185  {
1186  R"cpp(// Function definition via pointer
1187  void foo(int) {}
1188  int main() {
1189  auto *X = &^[[foo]];
1190  }
1191  )cpp",
1192  [](HoverInfo &HI) {
1193  HI.Name = "foo";
1194  HI.Kind = index::SymbolKind::Function;
1195  HI.NamespaceScope = "";
1196  HI.Type = "void (int)";
1197  HI.Definition = "void foo(int)";
1198  HI.Documentation = "Function definition via pointer";
1199  HI.ReturnType = "void";
1200  HI.Parameters = {
1201  {std::string("int"), llvm::None, llvm::None},
1202  };
1203  }},
1204  {
1205  R"cpp(// Function declaration via call
1206  int foo(int);
1207  int main() {
1208  return ^[[foo]](42);
1209  }
1210  )cpp",
1211  [](HoverInfo &HI) {
1212  HI.Name = "foo";
1213  HI.Kind = index::SymbolKind::Function;
1214  HI.NamespaceScope = "";
1215  HI.Type = "int (int)";
1216  HI.Definition = "int foo(int)";
1217  HI.Documentation = "Function declaration via call";
1218  HI.ReturnType = "int";
1219  HI.Parameters = {
1220  {std::string("int"), llvm::None, llvm::None},
1221  };
1222  }},
1223  {
1224  R"cpp(// Field
1225  struct Foo { int x; };
1226  int main() {
1227  Foo bar;
1228  (void)bar.^[[x]];
1229  }
1230  )cpp",
1231  [](HoverInfo &HI) {
1232  HI.Name = "x";
1233  HI.Kind = index::SymbolKind::Field;
1234  HI.NamespaceScope = "";
1235  HI.LocalScope = "Foo::";
1236  HI.Type = "int";
1237  HI.Definition = "int x";
1238  }},
1239  {
1240  R"cpp(// Field with initialization
1241  struct Foo { int x = 5; };
1242  int main() {
1243  Foo bar;
1244  (void)bar.^[[x]];
1245  }
1246  )cpp",
1247  [](HoverInfo &HI) {
1248  HI.Name = "x";
1249  HI.Kind = index::SymbolKind::Field;
1250  HI.NamespaceScope = "";
1251  HI.LocalScope = "Foo::";
1252  HI.Type = "int";
1253  HI.Definition = "int x = 5";
1254  }},
1255  {
1256  R"cpp(// Static field
1257  struct Foo { static int x; };
1258  int main() {
1259  (void)Foo::^[[x]];
1260  }
1261  )cpp",
1262  [](HoverInfo &HI) {
1263  HI.Name = "x";
1264  HI.Kind = index::SymbolKind::StaticProperty;
1265  HI.NamespaceScope = "";
1266  HI.LocalScope = "Foo::";
1267  HI.Type = "int";
1268  HI.Definition = "static int x";
1269  }},
1270  {
1271  R"cpp(// Field, member initializer
1272  struct Foo {
1273  int x;
1274  Foo() : ^[[x]](0) {}
1275  };
1276  )cpp",
1277  [](HoverInfo &HI) {
1278  HI.Name = "x";
1279  HI.Kind = index::SymbolKind::Field;
1280  HI.NamespaceScope = "";
1281  HI.LocalScope = "Foo::";
1282  HI.Type = "int";
1283  HI.Definition = "int x";
1284  }},
1285  {
1286  R"cpp(// Field, GNU old-style field designator
1287  struct Foo { int x; };
1288  int main() {
1289  Foo bar = { ^[[x]] : 1 };
1290  }
1291  )cpp",
1292  [](HoverInfo &HI) {
1293  HI.Name = "x";
1294  HI.Kind = index::SymbolKind::Field;
1295  HI.NamespaceScope = "";
1296  HI.LocalScope = "Foo::";
1297  HI.Type = "int";
1298  HI.Definition = "int x";
1299  // FIXME: Initializer for x is a DesignatedInitListExpr, hence it is
1300  // of struct type and omitted.
1301  }},
1302  {
1303  R"cpp(// Field, field designator
1304  struct Foo { int x; int y; };
1305  int main() {
1306  Foo bar = { .^[[x]] = 2, .y = 2 };
1307  }
1308  )cpp",
1309  [](HoverInfo &HI) {
1310  HI.Name = "x";
1311  HI.Kind = index::SymbolKind::Field;
1312  HI.NamespaceScope = "";
1313  HI.LocalScope = "Foo::";
1314  HI.Type = "int";
1315  HI.Definition = "int x";
1316  }},
1317  {
1318  R"cpp(// Method call
1319  struct Foo { int x(); };
1320  int main() {
1321  Foo bar;
1322  bar.^[[x]]();
1323  }
1324  )cpp",
1325  [](HoverInfo &HI) {
1326  HI.Name = "x";
1327  HI.Kind = index::SymbolKind::InstanceMethod;
1328  HI.NamespaceScope = "";
1329  HI.LocalScope = "Foo::";
1330  HI.Type = "int ()";
1331  HI.Definition = "int x()";
1332  HI.ReturnType = "int";
1333  HI.Parameters = std::vector<HoverInfo::Param>{};
1334  }},
1335  {
1336  R"cpp(// Static method call
1337  struct Foo { static int x(); };
1338  int main() {
1339  Foo::^[[x]]();
1340  }
1341  )cpp",
1342  [](HoverInfo &HI) {
1343  HI.Name = "x";
1344  HI.Kind = index::SymbolKind::StaticMethod;
1345  HI.NamespaceScope = "";
1346  HI.LocalScope = "Foo::";
1347  HI.Type = "int ()";
1348  HI.Definition = "static int x()";
1349  HI.ReturnType = "int";
1350  HI.Parameters = std::vector<HoverInfo::Param>{};
1351  }},
1352  {
1353  R"cpp(// Typedef
1354  typedef int Foo;
1355  int main() {
1356  ^[[Foo]] bar;
1357  }
1358  )cpp",
1359  [](HoverInfo &HI) {
1360  HI.Name = "Foo";
1361  HI.Kind = index::SymbolKind::TypeAlias;
1362  HI.NamespaceScope = "";
1363  HI.Definition = "typedef int Foo";
1364  HI.Documentation = "Typedef";
1365  // FIXME: Maybe put underlying type into HI.Type for aliases?
1366  }},
1367  {
1368  R"cpp(// Typedef with embedded definition
1369  typedef struct Bar {} Foo;
1370  int main() {
1371  ^[[Foo]] bar;
1372  }
1373  )cpp",
1374  [](HoverInfo &HI) {
1375  HI.Name = "Foo";
1376  HI.Kind = index::SymbolKind::TypeAlias;
1377  HI.NamespaceScope = "";
1378  HI.Definition = "typedef struct Bar Foo";
1379  HI.Documentation = "Typedef with embedded definition";
1380  }},
1381  {
1382  R"cpp(// Namespace
1383  namespace ns {
1384  struct Foo { static void bar(); };
1385  } // namespace ns
1386  int main() { ^[[ns]]::Foo::bar(); }
1387  )cpp",
1388  [](HoverInfo &HI) {
1389  HI.Name = "ns";
1390  HI.Kind = index::SymbolKind::Namespace;
1391  HI.NamespaceScope = "";
1392  HI.Definition = "namespace ns {}";
1393  }},
1394  {
1395  R"cpp(// Anonymous namespace
1396  namespace ns {
1397  namespace {
1398  int foo;
1399  } // anonymous namespace
1400  } // namespace ns
1401  int main() { ns::[[f^oo]]++; }
1402  )cpp",
1403  [](HoverInfo &HI) {
1404  HI.Name = "foo";
1405  HI.Kind = index::SymbolKind::Variable;
1406  HI.NamespaceScope = "ns::";
1407  HI.Type = "int";
1408  HI.Definition = "int foo";
1409  }},
1410  {
1411  R"cpp(// Macro
1412  #define MACRO 0
1413  int main() { return ^[[MACRO]]; }
1414  )cpp",
1415  [](HoverInfo &HI) {
1416  HI.Name = "MACRO";
1417  HI.Kind = index::SymbolKind::Macro;
1418  HI.Definition = "#define MACRO 0";
1419  }},
1420  {
1421  R"cpp(// Macro
1422  #define MACRO 0
1423  #define MACRO2 ^[[MACRO]]
1424  )cpp",
1425  [](HoverInfo &HI) {
1426  HI.Name = "MACRO";
1427  HI.Kind = index::SymbolKind::Macro;
1428  HI.Definition = "#define MACRO 0";
1429  }},
1430  {
1431  R"cpp(// Macro
1432  #define MACRO {\
1433  return 0;\
1434  }
1435  int main() ^[[MACRO]]
1436  )cpp",
1437  [](HoverInfo &HI) {
1438  HI.Name = "MACRO";
1439  HI.Kind = index::SymbolKind::Macro;
1440  HI.Definition =
1441  R"cpp(#define MACRO \
1442  { return 0; })cpp";
1443  }},
1444  {
1445  R"cpp(// Forward class declaration
1446  class Foo;
1447  class Foo {};
1448  [[F^oo]]* foo();
1449  )cpp",
1450  [](HoverInfo &HI) {
1451  HI.Name = "Foo";
1452  HI.Kind = index::SymbolKind::Class;
1453  HI.NamespaceScope = "";
1454  HI.Definition = "class Foo {}";
1455  HI.Documentation = "Forward class declaration";
1456  }},
1457  {
1458  R"cpp(// Function declaration
1459  void foo();
1460  void g() { [[f^oo]](); }
1461  void foo() {}
1462  )cpp",
1463  [](HoverInfo &HI) {
1464  HI.Name = "foo";
1465  HI.Kind = index::SymbolKind::Function;
1466  HI.NamespaceScope = "";
1467  HI.Type = "void ()";
1468  HI.Definition = "void foo()";
1469  HI.Documentation = "Function declaration";
1470  HI.ReturnType = "void";
1471  HI.Parameters = std::vector<HoverInfo::Param>{};
1472  }},
1473  {
1474  R"cpp(// Enum declaration
1475  enum Hello {
1476  ONE, TWO, THREE,
1477  };
1478  void foo() {
1479  [[Hel^lo]] hello = ONE;
1480  }
1481  )cpp",
1482  [](HoverInfo &HI) {
1483  HI.Name = "Hello";
1484  HI.Kind = index::SymbolKind::Enum;
1485  HI.NamespaceScope = "";
1486  HI.Definition = "enum Hello {}";
1487  HI.Documentation = "Enum declaration";
1488  }},
1489  {
1490  R"cpp(// Enumerator
1491  enum Hello {
1492  ONE, TWO, THREE,
1493  };
1494  void foo() {
1495  Hello hello = [[O^NE]];
1496  }
1497  )cpp",
1498  [](HoverInfo &HI) {
1499  HI.Name = "ONE";
1500  HI.Kind = index::SymbolKind::EnumConstant;
1501  HI.NamespaceScope = "";
1502  HI.LocalScope = "Hello::";
1503  HI.Type = "enum Hello";
1504  HI.Definition = "ONE";
1505  HI.Value = "0";
1506  }},
1507  {
1508  R"cpp(// Enumerator in anonymous enum
1509  enum {
1510  ONE, TWO, THREE,
1511  };
1512  void foo() {
1513  int hello = [[O^NE]];
1514  }
1515  )cpp",
1516  [](HoverInfo &HI) {
1517  HI.Name = "ONE";
1518  HI.Kind = index::SymbolKind::EnumConstant;
1519  HI.NamespaceScope = "";
1520  // FIXME: This should be `(anon enum)::`
1521  HI.LocalScope = "";
1522  HI.Type = "enum (unnamed)";
1523  HI.Definition = "ONE";
1524  HI.Value = "0";
1525  }},
1526  {
1527  R"cpp(// Global variable
1528  static int hey = 10;
1529  void foo() {
1530  [[he^y]]++;
1531  }
1532  )cpp",
1533  [](HoverInfo &HI) {
1534  HI.Name = "hey";
1535  HI.Kind = index::SymbolKind::Variable;
1536  HI.NamespaceScope = "";
1537  HI.Type = "int";
1538  HI.Definition = "static int hey = 10";
1539  HI.Documentation = "Global variable";
1540  // FIXME: Value shouldn't be set in this case
1541  HI.Value = "10 (0xa)";
1542  }},
1543  {
1544  R"cpp(// Global variable in namespace
1545  namespace ns1 {
1546  static long long hey = -36637162602497;
1547  }
1548  void foo() {
1549  ns1::[[he^y]]++;
1550  }
1551  )cpp",
1552  [](HoverInfo &HI) {
1553  HI.Name = "hey";
1554  HI.Kind = index::SymbolKind::Variable;
1555  HI.NamespaceScope = "ns1::";
1556  HI.Type = "long long";
1557  HI.Definition = "static long long hey = -36637162602497";
1558  HI.Value = "-36637162602497 (0xffffdeadbeefffff)"; // needs 64 bits
1559  }},
1560  {
1561  R"cpp(// Field in anonymous struct
1562  static struct {
1563  int hello;
1564  } s;
1565  void foo() {
1566  s.[[he^llo]]++;
1567  }
1568  )cpp",
1569  [](HoverInfo &HI) {
1570  HI.Name = "hello";
1571  HI.Kind = index::SymbolKind::Field;
1572  HI.NamespaceScope = "";
1573  HI.LocalScope = "(anonymous struct)::";
1574  HI.Type = "int";
1575  HI.Definition = "int hello";
1576  }},
1577  {
1578  R"cpp(// Templated function
1579  template <typename T>
1580  T foo() {
1581  return 17;
1582  }
1583  void g() { auto x = [[f^oo]]<int>(); }
1584  )cpp",
1585  [](HoverInfo &HI) {
1586  HI.Name = "foo";
1587  HI.Kind = index::SymbolKind::Function;
1588  HI.NamespaceScope = "";
1589  HI.Type = "int ()";
1590  HI.Definition = "template <> int foo<int>()";
1591  HI.Documentation = "Templated function";
1592  HI.ReturnType = "int";
1593  HI.Parameters = std::vector<HoverInfo::Param>{};
1594  // FIXME: We should populate template parameters with arguments in
1595  // case of instantiations.
1596  }},
1597  {
1598  R"cpp(// Anonymous union
1599  struct outer {
1600  union {
1601  int abc, def;
1602  } v;
1603  };
1604  void g() { struct outer o; o.v.[[d^ef]]++; }
1605  )cpp",
1606  [](HoverInfo &HI) {
1607  HI.Name = "def";
1608  HI.Kind = index::SymbolKind::Field;
1609  HI.NamespaceScope = "";
1610  HI.LocalScope = "outer::(anonymous union)::";
1611  HI.Type = "int";
1612  HI.Definition = "int def";
1613  }},
1614  {
1615  R"cpp(// documentation from index
1616  int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
1617  void indexSymbol();
1618  void g() { [[ind^exSymbol]](); }
1619  )cpp",
1620  [](HoverInfo &HI) {
1621  HI.Name = "indexSymbol";
1622  HI.Kind = index::SymbolKind::Function;
1623  HI.NamespaceScope = "";
1624  HI.Type = "void ()";
1625  HI.Definition = "void indexSymbol()";
1626  HI.ReturnType = "void";
1627  HI.Parameters = std::vector<HoverInfo::Param>{};
1628  HI.Documentation = "comment from index";
1629  }},
1630  {
1631  R"cpp(// Simple initialization with auto
1632  void foo() {
1633  ^[[auto]] i = 1;
1634  }
1635  )cpp",
1636  [](HoverInfo &HI) {
1637  HI.Name = "auto";
1638  HI.Kind = index::SymbolKind::TypeAlias;
1639  HI.Definition = "int";
1640  }},
1641  {
1642  R"cpp(// Simple initialization with const auto
1643  void foo() {
1644  const ^[[auto]] i = 1;
1645  }
1646  )cpp",
1647  [](HoverInfo &HI) {
1648  HI.Name = "auto";
1649  HI.Kind = index::SymbolKind::TypeAlias;
1650  HI.Definition = "int";
1651  }},
1652  {
1653  R"cpp(// Simple initialization with const auto&
1654  void foo() {
1655  const ^[[auto]]& i = 1;
1656  }
1657  )cpp",
1658  [](HoverInfo &HI) {
1659  HI.Name = "auto";
1660  HI.Kind = index::SymbolKind::TypeAlias;
1661  HI.Definition = "int";
1662  }},
1663  {
1664  R"cpp(// Simple initialization with auto&
1665  void foo() {
1666  int x;
1667  ^[[auto]]& i = x;
1668  }
1669  )cpp",
1670  [](HoverInfo &HI) {
1671  HI.Name = "auto";
1672  HI.Kind = index::SymbolKind::TypeAlias;
1673  HI.Definition = "int";
1674  }},
1675  {
1676  R"cpp(// Simple initialization with auto*
1677  void foo() {
1678  int a = 1;
1679  ^[[auto]]* i = &a;
1680  }
1681  )cpp",
1682  [](HoverInfo &HI) {
1683  HI.Name = "auto";
1684  HI.Kind = index::SymbolKind::TypeAlias;
1685  HI.Definition = "int";
1686  }},
1687  {
1688  R"cpp(// Simple initialization with auto from pointer
1689  void foo() {
1690  int a = 1;
1691  ^[[auto]] i = &a;
1692  }
1693  )cpp",
1694  [](HoverInfo &HI) {
1695  HI.Name = "auto";
1696  HI.Kind = index::SymbolKind::TypeAlias;
1697  HI.Definition = "int *";
1698  }},
1699  {
1700  R"cpp(// Auto with initializer list.
1701  namespace std
1702  {
1703  template<class _E>
1704  class initializer_list {};
1705  }
1706  void foo() {
1707  ^[[auto]] i = {1,2};
1708  }
1709  )cpp",
1710  [](HoverInfo &HI) {
1711  HI.Name = "auto";
1712  HI.Kind = index::SymbolKind::TypeAlias;
1713  HI.Definition = "class std::initializer_list<int>";
1714  }},
1715  {
1716  R"cpp(// User defined conversion to auto
1717  struct Bar {
1718  operator ^[[auto]]() const { return 10; }
1719  };
1720  )cpp",
1721  [](HoverInfo &HI) {
1722  HI.Name = "auto";
1723  HI.Kind = index::SymbolKind::TypeAlias;
1724  HI.Definition = "int";
1725  }},
1726  {
1727  R"cpp(// Simple initialization with decltype(auto)
1728  void foo() {
1729  ^[[decltype]](auto) i = 1;
1730  }
1731  )cpp",
1732  [](HoverInfo &HI) {
1733  HI.Name = "decltype";
1734  HI.Kind = index::SymbolKind::TypeAlias;
1735  HI.Definition = "int";
1736  }},
1737  {
1738  R"cpp(// Simple initialization with const decltype(auto)
1739  void foo() {
1740  const int j = 0;
1741  ^[[decltype]](auto) i = j;
1742  }
1743  )cpp",
1744  [](HoverInfo &HI) {
1745  HI.Name = "decltype";
1746  HI.Kind = index::SymbolKind::TypeAlias;
1747  HI.Definition = "const int";
1748  }},
1749  {
1750  R"cpp(// Simple initialization with const& decltype(auto)
1751  void foo() {
1752  int k = 0;
1753  const int& j = k;
1754  ^[[decltype]](auto) i = j;
1755  }
1756  )cpp",
1757  [](HoverInfo &HI) {
1758  HI.Name = "decltype";
1759  HI.Kind = index::SymbolKind::TypeAlias;
1760  HI.Definition = "const int &";
1761  }},
1762  {
1763  R"cpp(// Simple initialization with & decltype(auto)
1764  void foo() {
1765  int k = 0;
1766  int& j = k;
1767  ^[[decltype]](auto) i = j;
1768  }
1769  )cpp",
1770  [](HoverInfo &HI) {
1771  HI.Name = "decltype";
1772  HI.Kind = index::SymbolKind::TypeAlias;
1773  HI.Definition = "int &";
1774  }},
1775  {
1776  R"cpp(// simple trailing return type
1777  ^[[auto]] main() -> int {
1778  return 0;
1779  }
1780  )cpp",
1781  [](HoverInfo &HI) {
1782  HI.Name = "auto";
1783  HI.Kind = index::SymbolKind::TypeAlias;
1784  HI.Definition = "int";
1785  }},
1786  {
1787  R"cpp(// auto function return with trailing type
1788  struct Bar {};
1789  ^[[auto]] test() -> decltype(Bar()) {
1790  return Bar();
1791  }
1792  )cpp",
1793  [](HoverInfo &HI) {
1794  HI.Name = "auto";
1795  HI.Kind = index::SymbolKind::TypeAlias;
1796  HI.Definition = "struct Bar";
1797  HI.Documentation = "auto function return with trailing type";
1798  }},
1799  {
1800  R"cpp(// trailing return type
1801  struct Bar {};
1802  auto test() -> ^[[decltype]](Bar()) {
1803  return Bar();
1804  }
1805  )cpp",
1806  [](HoverInfo &HI) {
1807  HI.Name = "decltype";
1808  HI.Kind = index::SymbolKind::TypeAlias;
1809  HI.Definition = "struct Bar";
1810  HI.Documentation = "trailing return type";
1811  }},
1812  {
1813  R"cpp(// auto in function return
1814  struct Bar {};
1815  ^[[auto]] test() {
1816  return Bar();
1817  }
1818  )cpp",
1819  [](HoverInfo &HI) {
1820  HI.Name = "auto";
1821  HI.Kind = index::SymbolKind::TypeAlias;
1822  HI.Definition = "struct Bar";
1823  HI.Documentation = "auto in function return";
1824  }},
1825  {
1826  R"cpp(// auto& in function return
1827  struct Bar {};
1828  ^[[auto]]& test() {
1829  static Bar x;
1830  return x;
1831  }
1832  )cpp",
1833  [](HoverInfo &HI) {
1834  HI.Name = "auto";
1835  HI.Kind = index::SymbolKind::TypeAlias;
1836  HI.Definition = "struct Bar";
1837  HI.Documentation = "auto& in function return";
1838  }},
1839  {
1840  R"cpp(// auto* in function return
1841  struct Bar {};
1842  ^[[auto]]* test() {
1843  Bar* bar;
1844  return bar;
1845  }
1846  )cpp",
1847  [](HoverInfo &HI) {
1848  HI.Name = "auto";
1849  HI.Kind = index::SymbolKind::TypeAlias;
1850  HI.Definition = "struct Bar";
1851  HI.Documentation = "auto* in function return";
1852  }},
1853  {
1854  R"cpp(// const auto& in function return
1855  struct Bar {};
1856  const ^[[auto]]& test() {
1857  static Bar x;
1858  return x;
1859  }
1860  )cpp",
1861  [](HoverInfo &HI) {
1862  HI.Name = "auto";
1863  HI.Kind = index::SymbolKind::TypeAlias;
1864  HI.Definition = "struct Bar";
1865  HI.Documentation = "const auto& in function return";
1866  }},
1867  {
1868  R"cpp(// decltype(auto) in function return
1869  struct Bar {};
1870  ^[[decltype]](auto) test() {
1871  return Bar();
1872  }
1873  )cpp",
1874  [](HoverInfo &HI) {
1875  HI.Name = "decltype";
1876  HI.Kind = index::SymbolKind::TypeAlias;
1877  HI.Definition = "struct Bar";
1878  HI.Documentation = "decltype(auto) in function return";
1879  }},
1880  {
1881  R"cpp(// decltype(auto) reference in function return
1882  ^[[decltype]](auto) test() {
1883  static int a;
1884  return (a);
1885  }
1886  )cpp",
1887  [](HoverInfo &HI) {
1888  HI.Name = "decltype";
1889  HI.Kind = index::SymbolKind::TypeAlias;
1890  HI.Definition = "int &";
1891  }},
1892  {
1893  R"cpp(// decltype lvalue reference
1894  void foo() {
1895  int I = 0;
1896  ^[[decltype]](I) J = I;
1897  }
1898  )cpp",
1899  [](HoverInfo &HI) {
1900  HI.Name = "decltype";
1901  HI.Kind = index::SymbolKind::TypeAlias;
1902  HI.Definition = "int";
1903  }},
1904  {
1905  R"cpp(// decltype lvalue reference
1906  void foo() {
1907  int I= 0;
1908  int &K = I;
1909  ^[[decltype]](K) J = I;
1910  }
1911  )cpp",
1912  [](HoverInfo &HI) {
1913  HI.Name = "decltype";
1914  HI.Kind = index::SymbolKind::TypeAlias;
1915  HI.Definition = "int &";
1916  }},
1917  {
1918  R"cpp(// decltype lvalue reference parenthesis
1919  void foo() {
1920  int I = 0;
1921  ^[[decltype]]((I)) J = I;
1922  }
1923  )cpp",
1924  [](HoverInfo &HI) {
1925  HI.Name = "decltype";
1926  HI.Kind = index::SymbolKind::TypeAlias;
1927  HI.Definition = "int &";
1928  }},
1929  {
1930  R"cpp(// decltype rvalue reference
1931  void foo() {
1932  int I = 0;
1933  ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
1934  }
1935  )cpp",
1936  [](HoverInfo &HI) {
1937  HI.Name = "decltype";
1938  HI.Kind = index::SymbolKind::TypeAlias;
1939  HI.Definition = "int &&";
1940  }},
1941  {
1942  R"cpp(// decltype rvalue reference function call
1943  int && bar();
1944  void foo() {
1945  int I = 0;
1946  ^[[decltype]](bar()) J = bar();
1947  }
1948  )cpp",
1949  [](HoverInfo &HI) {
1950  HI.Name = "decltype";
1951  HI.Kind = index::SymbolKind::TypeAlias;
1952  HI.Definition = "int &&";
1953  }},
1954  {
1955  R"cpp(// decltype of function with trailing return type.
1956  struct Bar {};
1957  auto test() -> decltype(Bar()) {
1958  return Bar();
1959  }
1960  void foo() {
1961  ^[[decltype]](test()) i = test();
1962  }
1963  )cpp",
1964  [](HoverInfo &HI) {
1965  HI.Name = "decltype";
1966  HI.Kind = index::SymbolKind::TypeAlias;
1967  HI.Definition = "struct Bar";
1968  HI.Documentation =
1969  "decltype of function with trailing return type.";
1970  }},
1971  {
1972  R"cpp(// decltype of var with decltype.
1973  void foo() {
1974  int I = 0;
1975  decltype(I) J = I;
1976  ^[[decltype]](J) K = J;
1977  }
1978  )cpp",
1979  [](HoverInfo &HI) {
1980  HI.Name = "decltype";
1981  HI.Kind = index::SymbolKind::TypeAlias;
1982  HI.Definition = "int";
1983  }},
1984  {
1985  R"cpp(// decltype of dependent type
1986  template <typename T>
1987  struct X {
1988  using Y = ^[[decltype]](T::Z);
1989  };
1990  )cpp",
1991  [](HoverInfo &HI) {
1992  HI.Name = "decltype";
1993  HI.Kind = index::SymbolKind::TypeAlias;
1994  HI.Definition = "<dependent type>";
1995  }},
1996  {
1997  R"cpp(// More complicated structured types.
1998  int bar();
1999  ^[[auto]] (*foo)() = bar;
2000  )cpp",
2001  [](HoverInfo &HI) {
2002  HI.Name = "auto";
2003  HI.Kind = index::SymbolKind::TypeAlias;
2004  HI.Definition = "int";
2005  }},
2006  {
2007  R"cpp(// Should not crash when evaluating the initializer.
2008  struct Test {};
2009  void test() { Test && [[te^st]] = {}; }
2010  )cpp",
2011  [](HoverInfo &HI) {
2012  HI.Name = "test";
2013  HI.Kind = index::SymbolKind::Variable;
2014  HI.NamespaceScope = "";
2015  HI.LocalScope = "test::";
2016  HI.Type = "Test &&";
2017  HI.Definition = "Test &&test = {}";
2018  }},
2019  {
2020  R"cpp(// auto on alias
2021  typedef int int_type;
2022  ^[[auto]] x = int_type();
2023  )cpp",
2024  [](HoverInfo &HI) {
2025  HI.Name = "auto";
2026  HI.Kind = index::SymbolKind::TypeAlias;
2027  HI.Definition = "int";
2028  }},
2029  {
2030  R"cpp(// auto on alias
2031  struct cls {};
2032  typedef cls cls_type;
2033  ^[[auto]] y = cls_type();
2034  )cpp",
2035  [](HoverInfo &HI) {
2036  HI.Name = "auto";
2037  HI.Kind = index::SymbolKind::TypeAlias;
2038  HI.Definition = "struct cls";
2039  HI.Documentation = "auto on alias";
2040  }},
2041  {
2042  R"cpp(// auto on alias
2043  template <class>
2044  struct templ {};
2045  ^[[auto]] z = templ<int>();
2046  )cpp",
2047  [](HoverInfo &HI) {
2048  HI.Name = "auto";
2049  HI.Kind = index::SymbolKind::TypeAlias;
2050  HI.Definition = "struct templ<int>";
2051  HI.Documentation = "auto on alias";
2052  }},
2053  {
2054  R"cpp(// Undeduced auto declaration
2055  template<typename T>
2056  void foo() {
2057  ^[[auto]] x = T();
2058  }
2059  )cpp",
2060  [](HoverInfo &HI) {
2061  HI.Name = "auto";
2062  HI.Kind = index::SymbolKind::TypeAlias;
2063  HI.Definition = "/* not deduced */";
2064  }},
2065  {
2066  R"cpp(// Undeduced auto return type
2067  template<typename T>
2068  ^[[auto]] foo() {
2069  return T();
2070  }
2071  )cpp",
2072  [](HoverInfo &HI) {
2073  HI.Name = "auto";
2074  HI.Kind = index::SymbolKind::TypeAlias;
2075  HI.Definition = "/* not deduced */";
2076  }},
2077  {
2078  R"cpp(// Template auto parameter
2079  template<[[a^uto]] T>
2080  void func() {
2081  }
2082  )cpp",
2083  [](HoverInfo &HI) {
2084  // FIXME: not sure this is what we want, but this
2085  // is what we currently get with getDeducedType
2086  HI.Name = "auto";
2087  HI.Kind = index::SymbolKind::TypeAlias;
2088  HI.Definition = "/* not deduced */";
2089  }},
2090  {
2091  R"cpp(// Undeduced decltype(auto) return type
2092  template<typename T>
2093  ^[[decltype]](auto) foo() {
2094  return T();
2095  }
2096  )cpp",
2097  [](HoverInfo &HI) {
2098  HI.Name = "decltype";
2099  HI.Kind = index::SymbolKind::TypeAlias;
2100  HI.Definition = "/* not deduced */";
2101  }},
2102  {
2103  R"cpp(// should not crash.
2104  template <class T> struct cls {
2105  int method();
2106  };
2107 
2108  auto test = cls<int>().[[m^ethod]]();
2109  )cpp",
2110  [](HoverInfo &HI) {
2111  HI.Definition = "int method()";
2112  HI.Kind = index::SymbolKind::InstanceMethod;
2113  HI.NamespaceScope = "";
2114  HI.LocalScope = "cls<int>::";
2115  HI.Name = "method";
2116  HI.Parameters.emplace();
2117  HI.ReturnType = "int";
2118  HI.Type = "int ()";
2119  }},
2120  {
2121  R"cpp(// type of nested templates.
2122  template <class T> struct cls {};
2123  cls<cls<cls<int>>> [[fo^o]];
2124  )cpp",
2125  [](HoverInfo &HI) {
2126  HI.Definition = "cls<cls<cls<int>>> foo";
2127  HI.Kind = index::SymbolKind::Variable;
2128  HI.NamespaceScope = "";
2129  HI.Name = "foo";
2130  HI.Type = "cls<cls<cls<int>>>";
2131  }},
2132  {
2133  R"cpp(// type of nested templates.
2134  template <class T> struct cls {};
2135  [[cl^s]]<cls<cls<int>>> foo;
2136  )cpp",
2137  [](HoverInfo &HI) {
2138  HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2139  HI.Kind = index::SymbolKind::Struct;
2140  HI.NamespaceScope = "";
2141  HI.Name = "cls<cls<cls<int>>>";
2142  HI.Documentation = "type of nested templates.";
2143  }},
2144  {
2145  R"cpp(// type with decltype
2146  int a;
2147  decltype(a) [[b^]] = a;)cpp",
2148  [](HoverInfo &HI) {
2149  HI.Definition = "decltype(a) b = a";
2150  HI.Kind = index::SymbolKind::Variable;
2151  HI.NamespaceScope = "";
2152  HI.Name = "b";
2153  HI.Type = "int";
2154  }},
2155  {
2156  R"cpp(// type with decltype
2157  int a;
2158  decltype(a) c;
2159  decltype(c) [[b^]] = a;)cpp",
2160  [](HoverInfo &HI) {
2161  HI.Definition = "decltype(c) b = a";
2162  HI.Kind = index::SymbolKind::Variable;
2163  HI.NamespaceScope = "";
2164  HI.Name = "b";
2165  HI.Type = "int";
2166  }},
2167  {
2168  R"cpp(// type with decltype
2169  int a;
2170  const decltype(a) [[b^]] = a;)cpp",
2171  [](HoverInfo &HI) {
2172  HI.Definition = "const decltype(a) b = a";
2173  HI.Kind = index::SymbolKind::Variable;
2174  HI.NamespaceScope = "";
2175  HI.Name = "b";
2176  HI.Type = "int";
2177  }},
2178  {
2179  R"cpp(// type with decltype
2180  int a;
2181  auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2182  [](HoverInfo &HI) {
2183  HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2184  HI.Kind = index::SymbolKind::Function;
2185  HI.NamespaceScope = "";
2186  HI.Name = "foo";
2187  // FIXME: Handle composite types with decltype with a printing
2188  // policy.
2189  HI.Type = "auto (decltype(a)) -> decltype(a)";
2190  HI.ReturnType = "int";
2191  HI.Parameters = {
2192  {std::string("int"), std::string("x"), llvm::None}};
2193  }},
2194  {
2195  R"cpp(// sizeof expr
2196  void foo() {
2197  (void)[[size^of]](char);
2198  })cpp",
2199  [](HoverInfo &HI) {
2200  HI.Name = "expression";
2201  HI.Type = "unsigned long";
2202  HI.Value = "1";
2203  }},
2204  {
2205  R"cpp(// alignof expr
2206  void foo() {
2207  (void)[[align^of]](char);
2208  })cpp",
2209  [](HoverInfo &HI) {
2210  HI.Name = "expression";
2211  HI.Type = "unsigned long";
2212  HI.Value = "1";
2213  }},
2214  {
2215  R"cpp(
2216  template <typename T = int>
2217  void foo(const T& = T()) {
2218  [[f^oo]]<>(3);
2219  })cpp",
2220  [](HoverInfo &HI) {
2221  HI.Name = "foo";
2222  HI.Kind = index::SymbolKind::Function;
2223  HI.Type = "void (const int &)";
2224  HI.ReturnType = "void";
2225  HI.Parameters = {
2226  {std::string("const int &"), llvm::None, std::string("T()")}};
2227  HI.Definition = "template <> void foo<int>(const int &)";
2228  HI.NamespaceScope = "";
2229  }},
2230  {
2231  R"cpp(// should not crash
2232  @interface ObjC {
2233  char [[da^ta]];
2234  }@end
2235  )cpp",
2236  [](HoverInfo &HI) {
2237  HI.Name = "data";
2238  HI.Type = "char";
2239  HI.Kind = index::SymbolKind::Field;
2240  HI.LocalScope = "ObjC::";
2241  HI.NamespaceScope = "";
2242  HI.Definition = "char data";
2243  }},
2244  {
2245  R"cpp(
2246  @interface MYObject
2247  @end
2248  @interface Interface
2249  @property(retain) [[MYOb^ject]] *x;
2250  @end
2251  )cpp",
2252  [](HoverInfo &HI) {
2253  HI.Name = "MYObject";
2254  HI.Kind = index::SymbolKind::Class;
2255  HI.NamespaceScope = "";
2256  HI.Definition = "@interface MYObject\n@end";
2257  }},
2258  {
2259  R"cpp(
2260  @interface MYObject
2261  @end
2262  @interface Interface
2263  - (void)doWith:([[MYOb^ject]] *)object;
2264  @end
2265  )cpp",
2266  [](HoverInfo &HI) {
2267  HI.Name = "MYObject";
2268  HI.Kind = index::SymbolKind::Class;
2269  HI.NamespaceScope = "";
2270  HI.Definition = "@interface MYObject\n@end";
2271  }},
2272  {
2273  R"cpp(// this expr
2274  // comment
2275  namespace ns {
2276  class Foo {
2277  Foo* bar() {
2278  return [[t^his]];
2279  }
2280  };
2281  }
2282  )cpp",
2283  [](HoverInfo &HI) {
2284  HI.Name = "this";
2285  HI.Definition = "ns::Foo *";
2286  }},
2287  {
2288  R"cpp(// this expr for template class
2289  namespace ns {
2290  template <typename T>
2291  class Foo {
2292  Foo* bar() const {
2293  return [[t^his]];
2294  }
2295  };
2296  }
2297  )cpp",
2298  [](HoverInfo &HI) {
2299  HI.Name = "this";
2300  HI.Definition = "const Foo<T> *";
2301  }},
2302  {
2303  R"cpp(// this expr for specialization class
2304  namespace ns {
2305  template <typename T> class Foo {};
2306  template <>
2307  struct Foo<int> {
2308  Foo* bar() {
2309  return [[thi^s]];
2310  }
2311  };
2312  }
2313  )cpp",
2314  [](HoverInfo &HI) {
2315  HI.Name = "this";
2316  HI.Definition = "Foo<int> *";
2317  }},
2318  {
2319  R"cpp(// this expr for partial specialization struct
2320  namespace ns {
2321  template <typename T, typename F> struct Foo {};
2322  template <typename F>
2323  struct Foo<int, F> {
2324  Foo* bar() const {
2325  return [[thi^s]];
2326  }
2327  };
2328  }
2329  )cpp",
2330  [](HoverInfo &HI) {
2331  HI.Name = "this";
2332  HI.Definition = "const Foo<int, F> *";
2333  }},
2334  {
2335  R"cpp(
2336  @interface MYObject
2337  @end
2338  @interface MYObject (Private)
2339  @property(nonatomic, assign) int privateField;
2340  @end
2341 
2342  int someFunction() {
2343  MYObject *obj = [MYObject sharedInstance];
2344  return obj.[[private^Field]];
2345  }
2346  )cpp",
2347  [](HoverInfo &HI) {
2348  HI.Name = "privateField";
2349  HI.Kind = index::SymbolKind::InstanceProperty;
2350  HI.LocalScope = "MYObject(Private)::";
2351  HI.NamespaceScope = "";
2352  HI.Definition = "@property(nonatomic, assign, unsafe_unretained, "
2353  "readwrite) int privateField;";
2354  }},
2355  {
2356  R"cpp(
2357  @protocol MYProtocol
2358  @property(nonatomic, assign) int prop1;
2359  @end
2360 
2361  int someFunction() {
2362  id<MYProtocol> obj = 0;
2363  return obj.[[pro^p1]];
2364  }
2365  )cpp",
2366  [](HoverInfo &HI) {
2367  HI.Name = "prop1";
2368  HI.Kind = index::SymbolKind::InstanceProperty;
2369  HI.LocalScope = "MYProtocol::";
2370  HI.NamespaceScope = "";
2371  HI.Definition = "@property(nonatomic, assign, unsafe_unretained, "
2372  "readwrite) int prop1;";
2373  }},
2374  {R"objc(
2375  @interface Foo
2376  @end
2377 
2378  @implementation Foo(Private)
2379  + (int)somePrivateMethod {
2380  int [[res^ult]] = 2;
2381  return result;
2382  }
2383  @end
2384  )objc",
2385  [](HoverInfo &HI) {
2386  HI.Name = "result";
2387  HI.Definition = "int result = 2";
2388  HI.Kind = index::SymbolKind::Variable;
2389  HI.Type = "int";
2390  HI.LocalScope = "+[Foo(Private) somePrivateMethod]::";
2391  HI.NamespaceScope = "";
2392  HI.Value = "2";
2393  }},
2394  {R"objc(
2395  @interface Foo
2396  @end
2397 
2398  @implementation Foo
2399  - (int)variadicArgMethod:(id)first, ... {
2400  int [[res^ult]] = 0;
2401  return result;
2402  }
2403  @end
2404  )objc",
2405  [](HoverInfo &HI) {
2406  HI.Name = "result";
2407  HI.Definition = "int result = 0";
2408  HI.Kind = index::SymbolKind::Variable;
2409  HI.Type = "int";
2410  HI.LocalScope = "-[Foo variadicArgMethod:, ...]::";
2411  HI.NamespaceScope = "";
2412  HI.Value = "0";
2413  }},
2414  {R"cpp(
2415  void foo(int * __attribute__(([[non^null]], noescape)) );
2416  )cpp",
2417  [](HoverInfo &HI) {
2418  HI.Name = "nonnull";
2419  HI.Kind = index::SymbolKind::Unknown; // FIXME: no suitable value
2420  HI.Definition = "__attribute__((nonnull))";
2421  HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
2422  }},
2423  };
2424 
2425  // Create a tiny index, so tests above can verify documentation is fetched.
2426  Symbol IndexSym = func("indexSymbol");
2427  IndexSym.Documentation = "comment from index";
2428  SymbolSlab::Builder Symbols;
2429  Symbols.insert(IndexSym);
2430  auto Index =
2431  MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
2432 
2433  for (const auto &Case : Cases) {
2434  SCOPED_TRACE(Case.Code);
2435 
2436  Annotations T(Case.Code);
2437  TestTU TU = TestTU::withCode(T.code());
2438  TU.ExtraArgs.push_back("-std=c++17");
2439  TU.ExtraArgs.push_back("-xobjective-c++");
2440 
2441  TU.ExtraArgs.push_back("-Wno-gnu-designator");
2442  // Types might be different depending on the target triplet, we chose a
2443  // fixed one to make sure tests passes on different platform.
2444  TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
2445  auto AST = TU.build();
2446 
2447  auto H = getHover(AST, T.point(), format::getLLVMStyle(), Index.get());
2448  ASSERT_TRUE(H);
2449  HoverInfo Expected;
2450  Expected.SymRange = T.range();
2451  Case.ExpectedBuilder(Expected);
2452 
2453  SCOPED_TRACE(H->present().asPlainText());
2454  EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
2455  EXPECT_EQ(H->LocalScope, Expected.LocalScope);
2456  EXPECT_EQ(H->Name, Expected.Name);
2457  EXPECT_EQ(H->Kind, Expected.Kind);
2458  EXPECT_EQ(H->Documentation, Expected.Documentation);
2459  EXPECT_EQ(H->Definition, Expected.Definition);
2460  EXPECT_EQ(H->Type, Expected.Type);
2461  EXPECT_EQ(H->ReturnType, Expected.ReturnType);
2462  EXPECT_EQ(H->Parameters, Expected.Parameters);
2463  EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
2464  EXPECT_EQ(H->SymRange, Expected.SymRange);
2465  EXPECT_EQ(H->Value, Expected.Value);
2466  }
2467 }
2468 
2469 TEST(Hover, DocsFromIndex) {
2470  Annotations T(R"cpp(
2471  template <typename T> class X {};
2472  void foo() {
2473  auto t = X<int>();
2474  X^<int> w;
2475  (void)w;
2476  })cpp");
2477 
2478  TestTU TU = TestTU::withCode(T.code());
2479  auto AST = TU.build();
2480  Symbol IndexSym;
2481  IndexSym.ID = getSymbolID(&findDecl(AST, "X"));
2482  IndexSym.Documentation = "comment from index";
2483  SymbolSlab::Builder Symbols;
2484  Symbols.insert(IndexSym);
2485  auto Index =
2486  MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
2487 
2488  for (const auto &P : T.points()) {
2489  auto H = getHover(AST, P, format::getLLVMStyle(), Index.get());
2490  ASSERT_TRUE(H);
2491  EXPECT_EQ(H->Documentation, IndexSym.Documentation);
2492  }
2493 }
2494 
2495 TEST(Hover, DocsFromAST) {
2496  Annotations T(R"cpp(
2497  // doc
2498  template <typename T> class X {};
2499  // doc
2500  template <typename T> void bar() {}
2501  // doc
2502  template <typename T> T baz;
2503  void foo() {
2504  au^to t = X<int>();
2505  X^<int>();
2506  b^ar<int>();
2507  au^to T = ba^z<X<int>>;
2508  ba^z<int> = 0;
2509  })cpp");
2510 
2511  TestTU TU = TestTU::withCode(T.code());
2512  auto AST = TU.build();
2513  for (const auto &P : T.points()) {
2514  auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
2515  ASSERT_TRUE(H);
2516  EXPECT_EQ(H->Documentation, "doc");
2517  }
2518 }
2519 
2520 TEST(Hover, NoCrash) {
2521  Annotations T(R"cpp(
2522  /* error-ok */
2523  template<typename T> T foo(T);
2524 
2525  // Setter variable heuristic might fail if the callexpr is broken.
2526  struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
2527 
2528  TestTU TU = TestTU::withCode(T.code());
2529  auto AST = TU.build();
2530  for (const auto &P : T.points())
2531  getHover(AST, P, format::getLLVMStyle(), nullptr);
2532 }
2533 
2534 TEST(Hover, DocsFromMostSpecial) {
2535  Annotations T(R"cpp(
2536  // doc1
2537  template <typename T> class $doc1^X {};
2538  // doc2
2539  template <> class $doc2^X<int> {};
2540  // doc3
2541  template <typename T> class $doc3^X<T*> {};
2542  void foo() {
2543  X$doc1^<char>();
2544  X$doc2^<int>();
2545  X$doc3^<int*>();
2546  })cpp");
2547 
2548  TestTU TU = TestTU::withCode(T.code());
2549  auto AST = TU.build();
2550  for (auto Comment : {"doc1", "doc2", "doc3"}) {
2551  for (const auto &P : T.points(Comment)) {
2552  auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
2553  ASSERT_TRUE(H);
2554  EXPECT_EQ(H->Documentation, Comment);
2555  }
2556  }
2557 }
2558 
2559 TEST(Hover, Present) {
2560  struct {
2561  const std::function<void(HoverInfo &)> Builder;
2562  llvm::StringRef ExpectedRender;
2563  } Cases[] = {
2564  {
2565  [](HoverInfo &HI) {
2566  HI.Kind = index::SymbolKind::Unknown;
2567  HI.Name = "X";
2568  },
2569  R"(X)",
2570  },
2571  {
2572  [](HoverInfo &HI) {
2573  HI.Kind = index::SymbolKind::NamespaceAlias;
2574  HI.Name = "foo";
2575  },
2576  R"(namespace-alias foo)",
2577  },
2578  {
2579  [](HoverInfo &HI) {
2580  HI.Kind = index::SymbolKind::Class;
2581  HI.Size = 10;
2582  HI.TemplateParameters = {
2583  {std::string("typename"), std::string("T"), llvm::None},
2584  {std::string("typename"), std::string("C"),
2585  std::string("bool")},
2586  };
2587  HI.Documentation = "documentation";
2588  HI.Definition =
2589  "template <typename T, typename C = bool> class Foo {}";
2590  HI.Name = "foo";
2591  HI.NamespaceScope.emplace();
2592  },
2593  R"(class foo
2594 
2595 Size: 10 bytes
2596 documentation
2597 
2598 template <typename T, typename C = bool> class Foo {})",
2599  },
2600  {
2601  [](HoverInfo &HI) {
2602  HI.Kind = index::SymbolKind::Function;
2603  HI.Name = "foo";
2604  HI.Type = "type";
2605  HI.ReturnType = "ret_type";
2606  HI.Parameters.emplace();
2607  HoverInfo::Param P;
2608  HI.Parameters->push_back(P);
2609  P.Type = "type";
2610  HI.Parameters->push_back(P);
2611  P.Name = "foo";
2612  HI.Parameters->push_back(P);
2613  P.Default = "default";
2614  HI.Parameters->push_back(P);
2615  HI.NamespaceScope = "ns::";
2616  HI.Definition = "ret_type foo(params) {}";
2617  },
2618  "function foo\n"
2619  "\n"
2620  "→ ret_type\n"
2621  "Parameters:\n"
2622  "- \n"
2623  "- type\n"
2624  "- type foo\n"
2625  "- type foo = default\n"
2626  "\n"
2627  "// In namespace ns\n"
2628  "ret_type foo(params) {}",
2629  },
2630  {
2631  [](HoverInfo &HI) {
2632  HI.Kind = index::SymbolKind::Field;
2633  HI.LocalScope = "test::Bar::";
2634  HI.Value = "value";
2635  HI.Name = "foo";
2636  HI.Type = "type";
2637  HI.Definition = "def";
2638  HI.Size = 4;
2639  HI.Offset = 12;
2640  HI.Padding = 4;
2641  },
2642  R"(field foo
2643 
2644 Type: type
2645 Value = value
2646 Offset: 12 bytes
2647 Size: 4 bytes (+4 padding)
2648 
2649 // In test::Bar
2650 def)",
2651  },
2652  {
2653  [](HoverInfo &HI) {
2654  HI.Kind = index::SymbolKind::Field;
2655  HI.AccessSpecifier = "public";
2656  HI.Name = "foo";
2657  HI.LocalScope = "test::Bar::";
2658  HI.Definition = "def";
2659  },
2660  R"(field foo
2661 
2662 // In test::Bar
2663 public: def)",
2664  },
2665  {
2666  [](HoverInfo &HI) {
2667  HI.Definition = "int method()";
2668  HI.AccessSpecifier = "protected";
2669  HI.Kind = index::SymbolKind::InstanceMethod;
2670  HI.NamespaceScope = "";
2671  HI.LocalScope = "cls<int>::";
2672  HI.Name = "method";
2673  HI.Parameters.emplace();
2674  HI.ReturnType = "int";
2675  HI.Type = "int ()";
2676  },
2677  R"(instance-method method
2678 
2679 → int
2680 
2681 // In cls<int>
2682 protected: int method())",
2683  },
2684  {
2685  [](HoverInfo &HI) {
2686  HI.Kind = index::SymbolKind::Union;
2687  HI.AccessSpecifier = "private";
2688  HI.Name = "foo";
2689  HI.NamespaceScope = "ns1::";
2690  HI.Definition = "union foo {}";
2691  },
2692  R"(union foo
2693 
2694 // In namespace ns1
2695 private: union foo {})",
2696  },
2697  {
2698  [](HoverInfo &HI) {
2699  HI.Kind = index::SymbolKind::Variable;
2700  HI.Name = "foo";
2701  HI.Definition = "int foo = 3";
2702  HI.LocalScope = "test::Bar::";
2703  HI.Value = "3";
2704  HI.Type = "int";
2705  HI.CalleeArgInfo.emplace();
2706  HI.CalleeArgInfo->Name = "arg_a";
2707  HI.CalleeArgInfo->Type = "int";
2708  HI.CalleeArgInfo->Default = "7";
2709  HI.CallPassType.emplace();
2710  HI.CallPassType->PassBy = PassMode::Value;
2711  HI.CallPassType->Converted = false;
2712  },
2713  R"(variable foo
2714 
2715 Type: int
2716 Value = 3
2717 Passed as arg_a
2718 
2719 // In test::Bar
2720 int foo = 3)",
2721  },
2722  {
2723  [](HoverInfo &HI) {
2724  HI.Kind = index::SymbolKind::Variable;
2725  HI.Name = "foo";
2726  HI.Definition = "int foo = 3";
2727  HI.LocalScope = "test::Bar::";
2728  HI.Value = "3";
2729  HI.Type = "int";
2730  HI.CalleeArgInfo.emplace();
2731  HI.CalleeArgInfo->Name = "arg_a";
2732  HI.CalleeArgInfo->Type = "int";
2733  HI.CalleeArgInfo->Default = "7";
2734  HI.CallPassType.emplace();
2735  HI.CallPassType->PassBy = PassMode::Ref;
2736  HI.CallPassType->Converted = false;
2737  },
2738  R"(variable foo
2739 
2740 Type: int
2741 Value = 3
2742 Passed by reference as arg_a
2743 
2744 // In test::Bar
2745 int foo = 3)",
2746  },
2747  {
2748  [](HoverInfo &HI) {
2749  HI.Kind = index::SymbolKind::Variable;
2750  HI.Name = "foo";
2751  HI.Definition = "int foo = 3";
2752  HI.LocalScope = "test::Bar::";
2753  HI.Value = "3";
2754  HI.Type = "int";
2755  HI.CalleeArgInfo.emplace();
2756  HI.CalleeArgInfo->Name = "arg_a";
2757  HI.CalleeArgInfo->Type = "int";
2758  HI.CalleeArgInfo->Default = "7";
2759  HI.CallPassType.emplace();
2760  HI.CallPassType->PassBy = PassMode::Value;
2761  HI.CallPassType->Converted = true;
2762  },
2763  R"(variable foo
2764 
2765 Type: int
2766 Value = 3
2767 Passed as arg_a (converted to int)
2768 
2769 // In test::Bar
2770 int foo = 3)",
2771  },
2772  {
2773  [](HoverInfo &HI) {
2774  HI.Kind = index::SymbolKind::Variable;
2775  HI.Name = "foo";
2776  HI.Definition = "int foo = 3";
2777  HI.LocalScope = "test::Bar::";
2778  HI.Value = "3";
2779  HI.Type = "int";
2780  HI.CalleeArgInfo.emplace();
2781  HI.CalleeArgInfo->Name = "arg_a";
2782  HI.CalleeArgInfo->Type = "int";
2783  HI.CalleeArgInfo->Default = "7";
2784  HI.CallPassType.emplace();
2785  HI.CallPassType->PassBy = PassMode::ConstRef;
2786  HI.CallPassType->Converted = true;
2787  },
2788  R"(variable foo
2789 
2790 Type: int
2791 Value = 3
2792 Passed by const reference as arg_a (converted to int)
2793 
2794 // In test::Bar
2795 int foo = 3)",
2796  },
2797  {
2798  [](HoverInfo &HI) {
2799  HI.Name = "stdio.h";
2800  HI.Definition = "/usr/include/stdio.h";
2801  },
2802  R"(stdio.h
2803 
2804 /usr/include/stdio.h)",
2805  }};
2806 
2807  for (const auto &C : Cases) {
2808  HoverInfo HI;
2809  C.Builder(HI);
2810  EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
2811  }
2812 }
2813 
2814 TEST(Hover, ParseDocumentation) {
2815  struct Case {
2816  llvm::StringRef Documentation;
2817  llvm::StringRef ExpectedRenderMarkdown;
2818  llvm::StringRef ExpectedRenderPlainText;
2819  } Cases[] = {{
2820  " \n foo\nbar",
2821  "foo bar",
2822  "foo bar",
2823  },
2824  {
2825  "foo\nbar \n ",
2826  "foo bar",
2827  "foo bar",
2828  },
2829  {
2830  "foo \nbar",
2831  "foo bar",
2832  "foo bar",
2833  },
2834  {
2835  "foo \nbar",
2836  "foo bar",
2837  "foo bar",
2838  },
2839  {
2840  "foo\n\n\nbar",
2841  "foo \nbar",
2842  "foo\nbar",
2843  },
2844  {
2845  "foo\n\n\n\tbar",
2846  "foo \nbar",
2847  "foo\nbar",
2848  },
2849  {
2850  "foo\n\n\n bar",
2851  "foo \nbar",
2852  "foo\nbar",
2853  },
2854  {
2855  "foo.\nbar",
2856  "foo. \nbar",
2857  "foo.\nbar",
2858  },
2859  {
2860  "foo. \nbar",
2861  "foo. \nbar",
2862  "foo.\nbar",
2863  },
2864  {
2865  "foo\n*bar",
2866  "foo \n\\*bar",
2867  "foo\n*bar",
2868  },
2869  {
2870  "foo\nbar",
2871  "foo bar",
2872  "foo bar",
2873  },
2874  {
2875  "Tests primality of `p`.",
2876  "Tests primality of `p`.",
2877  "Tests primality of `p`.",
2878  },
2879  {
2880  "'`' should not occur in `Code`",
2881  "'\\`' should not occur in `Code`",
2882  "'`' should not occur in `Code`",
2883  },
2884  {
2885  "`not\nparsed`",
2886  "\\`not parsed\\`",
2887  "`not parsed`",
2888  }};
2889 
2890  for (const auto &C : Cases) {
2891  markup::Document Output;
2892  parseDocumentation(C.Documentation, Output);
2893 
2894  EXPECT_EQ(Output.asMarkdown(), C.ExpectedRenderMarkdown);
2895  EXPECT_EQ(Output.asPlainText(), C.ExpectedRenderPlainText);
2896  }
2897 }
2898 
2899 // This is a separate test as headings don't create any differences in plaintext
2900 // mode.
2901 TEST(Hover, PresentHeadings) {
2902  HoverInfo HI;
2903  HI.Kind = index::SymbolKind::Variable;
2904  HI.Name = "foo";
2905 
2906  EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo`");
2907 }
2908 
2909 // This is a separate test as rulers behave differently in markdown vs
2910 // plaintext.
2911 TEST(Hover, PresentRulers) {
2912  HoverInfo HI;
2913  HI.Kind = index::SymbolKind::Variable;
2914  HI.Name = "foo";
2915  HI.Value = "val";
2916  HI.Definition = "def";
2917 
2918  llvm::StringRef ExpectedMarkdown = //
2919  "### variable `foo` \n"
2920  "\n"
2921  "---\n"
2922  "Value = `val` \n"
2923  "\n"
2924  "---\n"
2925  "```cpp\n"
2926  "def\n"
2927  "```";
2928  EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown);
2929 
2930  llvm::StringRef ExpectedPlaintext = R"pt(variable foo
2931 
2932 Value = val
2933 
2934 def)pt";
2935  EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);
2936 }
2937 } // namespace
2938 } // namespace clangd
2939 } // namespace clang
clang::clangd::findDecl
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:215
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:751
Expected
std::vector< const char * > Expected
Definition: PrintASTTests.cpp:27
TestTU.h
clang::clangd::getHover
llvm::Optional< HoverInfo > getHover(ParsedAST &AST, Position Pos, format::FormatStyle Style, const SymbolIndex *Index)
Get the hover information when hovering at Pos.
Definition: Hover.cpp:913
clang::clangd::func
Symbol func(llvm::StringRef Name)
Definition: TestIndex.cpp:60
clang::clangd::ParsedAST::build
static llvm::Optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
Definition: ParsedAST.cpp:248
Hover.h
Code
std::string Code
Definition: FindTargetTests.cpp:67
MemIndex.h
clang::clangd::Unknown
@ Unknown
Definition: FuzzyMatch.h:56
Builder
CodeCompletionBuilder Builder
Definition: CodeCompletionStringsTests.cpp:36
clang::clangd::MemIndex::build
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
Definition: MemIndex.cpp:19
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:37
Annotations.h
Output
std::string Output
Definition: TraceTests.cpp:162
clang::clangd::getSymbolID
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Definition: AST.cpp:337
Index
const SymbolIndex * Index
Definition: Dexp.cpp:99
TestIndex.h
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::HoverInfo::PassType::PassMode
PassMode
Definition: Hover.h:87
clang::clangd::parseDocumentation
void parseDocumentation(llvm::StringRef Input, markup::Document &Output)
Definition: Hover.cpp:1179
clang::clangd::SymbolSlab::Builder::insert
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
Definition: Symbol.cpp:50
Value
static constexpr bool Value
Definition: SuspiciousCallArgumentCheck.cpp:72
AST.h