clang-tools  9.0.0
CodeCompleteTests.cpp
Go to the documentation of this file.
1 //===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===//
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 "Annotations.h"
10 #include "ClangdServer.h"
11 #include "CodeComplete.h"
12 #include "Compiler.h"
13 #include "Matchers.h"
14 #include "Protocol.h"
15 #include "Quality.h"
16 #include "SourceCode.h"
17 #include "SyncAPI.h"
18 #include "TestFS.h"
19 #include "TestIndex.h"
20 #include "TestTU.h"
21 #include "index/Index.h"
22 #include "index/MemIndex.h"
23 #include "clang/Sema/CodeCompleteConsumer.h"
24 #include "clang/Tooling/CompilationDatabase.h"
25 #include "llvm/Support/Error.h"
26 #include "llvm/Support/Path.h"
27 #include "llvm/Testing/Support/Error.h"
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 
31 namespace clang {
32 namespace clangd {
33 
34 namespace {
35 using ::llvm::Failed;
36 using ::testing::AllOf;
37 using ::testing::Contains;
38 using ::testing::ElementsAre;
39 using ::testing::Field;
40 using ::testing::HasSubstr;
41 using ::testing::IsEmpty;
42 using ::testing::Not;
43 using ::testing::UnorderedElementsAre;
44 
45 class IgnoreDiagnostics : public DiagnosticsConsumer {
47  std::vector<Diag> Diagnostics) override {}
48 };
49 
50 // GMock helpers for matching completion items.
51 MATCHER_P(Named, Name, "") { return arg.Name == Name; }
52 MATCHER_P(NameStartsWith, Prefix, "") {
53  return llvm::StringRef(arg.Name).startswith(Prefix);
54 }
55 MATCHER_P(Scope, S, "") { return arg.Scope == S; }
56 MATCHER_P(Qualifier, Q, "") { return arg.RequiredQualifier == Q; }
57 MATCHER_P(Labeled, Label, "") {
58  return arg.RequiredQualifier + arg.Name + arg.Signature == Label;
59 }
60 MATCHER_P(SigHelpLabeled, Label, "") { return arg.label == Label; }
61 MATCHER_P(Kind, K, "") { return arg.Kind == K; }
62 MATCHER_P(Doc, D, "") { return arg.Documentation == D; }
63 MATCHER_P(ReturnType, D, "") { return arg.ReturnType == D; }
64 MATCHER_P(HasInclude, IncludeHeader, "") {
65  return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader;
66 }
67 MATCHER_P(InsertInclude, IncludeHeader, "") {
68  return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader &&
69  bool(arg.Includes[0].Insertion);
70 }
71 MATCHER(InsertInclude, "") {
72  return !arg.Includes.empty() && bool(arg.Includes[0].Insertion);
73 }
74 MATCHER_P(SnippetSuffix, Text, "") { return arg.SnippetSuffix == Text; }
75 MATCHER_P(Origin, OriginSet, "") { return arg.Origin == OriginSet; }
76 MATCHER_P(Signature, S, "") { return arg.Signature == S; }
77 
78 // Shorthand for Contains(Named(Name)).
79 Matcher<const std::vector<CodeCompletion> &> Has(std::string Name) {
80  return Contains(Named(std::move(Name)));
81 }
82 Matcher<const std::vector<CodeCompletion> &> Has(std::string Name,
84  return Contains(AllOf(Named(std::move(Name)), Kind(K)));
85 }
86 MATCHER(IsDocumented, "") { return !arg.Documentation.empty(); }
87 MATCHER(Deprecated, "") { return arg.Deprecated; }
88 
89 std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) {
91  for (const auto &Sym : Symbols)
92  Slab.insert(Sym);
93  return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
94 }
95 
96 CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode,
97  Position point,
98  std::vector<Symbol> IndexSymbols = {},
99  clangd::CodeCompleteOptions Opts = {}) {
100  std::unique_ptr<SymbolIndex> OverrideIndex;
101  if (!IndexSymbols.empty()) {
102  assert(!Opts.Index && "both Index and IndexSymbols given!");
103  OverrideIndex = memIndex(std::move(IndexSymbols));
104  Opts.Index = OverrideIndex.get();
105  }
106 
107  auto File = testPath("foo.cpp");
108  runAddDocument(Server, File, TestCode);
109  auto CompletionList =
110  llvm::cantFail(runCodeComplete(Server, File, point, Opts));
111  return CompletionList;
112 }
113 
114 CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef Text,
115  std::vector<Symbol> IndexSymbols = {},
116  clangd::CodeCompleteOptions Opts = {},
117  PathRef FilePath = "foo.cpp") {
118  std::unique_ptr<SymbolIndex> OverrideIndex;
119  if (!IndexSymbols.empty()) {
120  assert(!Opts.Index && "both Index and IndexSymbols given!");
121  OverrideIndex = memIndex(std::move(IndexSymbols));
122  Opts.Index = OverrideIndex.get();
123  }
124 
125  auto File = testPath(FilePath);
126  Annotations Test(Text);
127  runAddDocument(Server, File, Test.code());
128  auto CompletionList =
129  llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts));
130  return CompletionList;
131 }
132 
133 // Builds a server and runs code completion.
134 // If IndexSymbols is non-empty, an index will be built and passed to opts.
135 CodeCompleteResult completions(llvm::StringRef Text,
136  std::vector<Symbol> IndexSymbols = {},
137  clangd::CodeCompleteOptions Opts = {},
138  PathRef FilePath = "foo.cpp") {
139  MockFSProvider FS;
140  MockCompilationDatabase CDB;
141  IgnoreDiagnostics DiagConsumer;
142  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
143  return completions(Server, Text, std::move(IndexSymbols), std::move(Opts),
144  FilePath);
145 }
146 
147 // Builds a server and runs code completion.
148 // If IndexSymbols is non-empty, an index will be built and passed to opts.
149 CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
150  std::vector<Symbol> IndexSymbols = {},
151  clangd::CodeCompleteOptions Opts = {},
152  PathRef FilePath = "foo.cpp") {
153  std::unique_ptr<SymbolIndex> OverrideIndex;
154  if (!IndexSymbols.empty()) {
155  assert(!Opts.Index && "both Index and IndexSymbols given!");
156  OverrideIndex = memIndex(std::move(IndexSymbols));
157  Opts.Index = OverrideIndex.get();
158  }
159 
160  MockFSProvider FS;
161  Annotations Test(Text);
162  return codeComplete(FilePath, tooling::CompileCommand(), /*Preamble=*/nullptr,
163  Test.code(), Test.point(), FS.getFileSystem(), Opts);
164 }
165 
166 Symbol withReferences(int N, Symbol S) {
167  S.References = N;
168  return S;
169 }
170 
171 TEST(CompletionTest, Limit) {
172  clangd::CodeCompleteOptions Opts;
173  Opts.Limit = 2;
174  auto Results = completions(R"cpp(
175 struct ClassWithMembers {
176  int AAA();
177  int BBB();
178  int CCC();
179 };
180 
181 int main() { ClassWithMembers().^ }
182  )cpp",
183  /*IndexSymbols=*/{}, Opts);
184 
185  EXPECT_TRUE(Results.HasMore);
186  EXPECT_THAT(Results.Completions, ElementsAre(Named("AAA"), Named("BBB")));
187 }
188 
189 TEST(CompletionTest, Filter) {
190  std::string Body = R"cpp(
191  #define MotorCar
192  int Car;
193  struct S {
194  int FooBar;
195  int FooBaz;
196  int Qux;
197  };
198  )cpp";
199 
200  // Only items matching the fuzzy query are returned.
201  EXPECT_THAT(completions(Body + "int main() { S().Foba^ }").Completions,
202  AllOf(Has("FooBar"), Has("FooBaz"), Not(Has("Qux"))));
203 
204  // Macros require prefix match.
205  EXPECT_THAT(completions(Body + "int main() { C^ }").Completions,
206  AllOf(Has("Car"), Not(Has("MotorCar"))));
207 }
208 
209 void TestAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
210  auto Results = completions(
211  R"cpp(
212  int global_var;
213 
214  int global_func();
215 
216  // Make sure this is not in preamble.
217  #define MACRO X
218 
219  struct GlobalClass {};
220 
221  struct ClassWithMembers {
222  /// Doc for method.
223  int method();
224 
225  int field;
226  private:
227  int private_field;
228  };
229 
230  int test() {
231  struct LocalClass {};
232 
233  /// Doc for local_var.
234  int local_var;
235 
236  ClassWithMembers().^
237  }
238  )cpp",
239  {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
240 
241  EXPECT_TRUE(Results.RanParser);
242  // Class members. The only items that must be present in after-dot
243  // completion.
244  EXPECT_THAT(Results.Completions,
245  AllOf(Has("method"), Has("field"), Not(Has("ClassWithMembers")),
246  Not(Has("operator=")), Not(Has("~ClassWithMembers"))));
247  EXPECT_IFF(Opts.IncludeIneligibleResults, Results.Completions,
248  Has("private_field"));
249  // Global items.
250  EXPECT_THAT(
251  Results.Completions,
252  Not(AnyOf(Has("global_var"), Has("index_var"), Has("global_func"),
253  Has("global_func()"), Has("index_func"), Has("GlobalClass"),
254  Has("IndexClass"), Has("MACRO"), Has("LocalClass"))));
255  // There should be no code patterns (aka snippets) in after-dot
256  // completion. At least there aren't any we're aware of.
257  EXPECT_THAT(Results.Completions,
258  Not(Contains(Kind(CompletionItemKind::Snippet))));
259  // Check documentation.
260  EXPECT_IFF(Opts.IncludeComments, Results.Completions,
261  Contains(IsDocumented()));
262 }
263 
264 void TestGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
265  auto Results = completions(
266  R"cpp(
267  int global_var;
268  int global_func();
269 
270  // Make sure this is not in preamble.
271  #define MACRO X
272 
273  struct GlobalClass {};
274 
275  struct ClassWithMembers {
276  /// Doc for method.
277  int method();
278  };
279 
280  int test() {
281  struct LocalClass {};
282 
283  /// Doc for local_var.
284  int local_var;
285 
286  ^
287  }
288  )cpp",
289  {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
290 
291  EXPECT_TRUE(Results.RanParser);
292  // Class members. Should never be present in global completions.
293  EXPECT_THAT(Results.Completions,
294  Not(AnyOf(Has("method"), Has("method()"), Has("field"))));
295  // Global items.
296  EXPECT_THAT(Results.Completions,
297  AllOf(Has("global_var"), Has("index_var"), Has("global_func"),
298  Has("index_func" /* our fake symbol doesn't include () */),
299  Has("GlobalClass"), Has("IndexClass")));
300  // A macro.
301  EXPECT_IFF(Opts.IncludeMacros, Results.Completions, Has("MACRO"));
302  // Local items. Must be present always.
303  EXPECT_THAT(Results.Completions,
304  AllOf(Has("local_var"), Has("LocalClass"),
305  Contains(Kind(CompletionItemKind::Snippet))));
306  // Check documentation.
307  EXPECT_IFF(Opts.IncludeComments, Results.Completions,
308  Contains(IsDocumented()));
309 }
310 
311 TEST(CompletionTest, CompletionOptions) {
312  auto Test = [&](const clangd::CodeCompleteOptions &Opts) {
313  TestAfterDotCompletion(Opts);
314  TestGlobalScopeCompletion(Opts);
315  };
316  // We used to test every combination of options, but that got too slow (2^N).
317  auto Flags = {
322  };
323  // Test default options.
324  Test({});
325  // Test with one flag flipped.
326  for (auto &F : Flags) {
327  clangd::CodeCompleteOptions O;
328  O.*F ^= true;
329  Test(O);
330  }
331 }
332 
333 TEST(CompletionTest, Accessible) {
334  auto Internal = completions(R"cpp(
335  class Foo {
336  public: void pub();
337  protected: void prot();
338  private: void priv();
339  };
340  void Foo::pub() { this->^ }
341  )cpp");
342  EXPECT_THAT(Internal.Completions,
343  AllOf(Has("priv"), Has("prot"), Has("pub")));
344 
345  auto External = completions(R"cpp(
346  class Foo {
347  public: void pub();
348  protected: void prot();
349  private: void priv();
350  };
351  void test() {
352  Foo F;
353  F.^
354  }
355  )cpp");
356  EXPECT_THAT(External.Completions,
357  AllOf(Has("pub"), Not(Has("prot")), Not(Has("priv"))));
358 }
359 
360 TEST(CompletionTest, Qualifiers) {
361  auto Results = completions(R"cpp(
362  class Foo {
363  public: int foo() const;
364  int bar() const;
365  };
366  class Bar : public Foo {
367  int foo() const;
368  };
369  void test() { Bar().^ }
370  )cpp");
371  EXPECT_THAT(Results.Completions,
372  Contains(AllOf(Qualifier(""), Named("bar"))));
373  // Hidden members are not shown.
374  EXPECT_THAT(Results.Completions,
375  Not(Contains(AllOf(Qualifier("Foo::"), Named("foo")))));
376  // Private members are not shown.
377  EXPECT_THAT(Results.Completions,
378  Not(Contains(AllOf(Qualifier(""), Named("foo")))));
379 }
380 
381 TEST(CompletionTest, InjectedTypename) {
382  // These are suppressed when accessed as a member...
383  EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions,
384  Not(Has("X")));
385  EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions,
386  Not(Has("X")));
387  // ...but accessible in other, more useful cases.
388  EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions,
389  Has("X"));
390  EXPECT_THAT(
391  completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions,
392  Has("Y"));
393  EXPECT_THAT(
394  completions(
395  "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
396  .Completions,
397  Has("Y"));
398  // This case is marginal (`using X::X` is useful), we allow it for now.
399  EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions,
400  Has("X"));
401 }
402 
403 TEST(CompletionTest, SkipInjectedWhenUnqualified) {
404  EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions,
405  ElementsAre(Named("X"), Named("~X")));
406 }
407 
408 TEST(CompletionTest, Snippets) {
409  clangd::CodeCompleteOptions Opts;
410  auto Results = completions(
411  R"cpp(
412  struct fake {
413  int a;
414  int f(int i, const float f) const;
415  };
416  int main() {
417  fake f;
418  f.^
419  }
420  )cpp",
421  /*IndexSymbols=*/{}, Opts);
422  EXPECT_THAT(
423  Results.Completions,
424  HasSubsequence(Named("a"),
425  SnippetSuffix("(${1:int i}, ${2:const float f})")));
426 }
427 
428 TEST(CompletionTest, Kinds) {
429  auto Results = completions(
430  R"cpp(
431  int variable;
432  struct Struct {};
433  int function();
434  // make sure MACRO is not included in preamble.
435  #define MACRO 10
436  int X = ^
437  )cpp",
438  {func("indexFunction"), var("indexVariable"), cls("indexClass")});
439  EXPECT_THAT(Results.Completions,
440  AllOf(Has("function", CompletionItemKind::Function),
441  Has("variable", CompletionItemKind::Variable),
442  Has("int", CompletionItemKind::Keyword),
443  Has("Struct", CompletionItemKind::Class),
444  Has("MACRO", CompletionItemKind::Text),
445  Has("indexFunction", CompletionItemKind::Function),
446  Has("indexVariable", CompletionItemKind::Variable),
447  Has("indexClass", CompletionItemKind::Class)));
448 
449  Results = completions("nam^");
450  EXPECT_THAT(Results.Completions,
451  Has("namespace", CompletionItemKind::Snippet));
452 
453  // Members of anonymous unions are of kind 'field'.
454  Results = completions(
455  R"cpp(
456  struct X{
457  union {
458  void *a;
459  };
460  };
461  auto u = X().^
462  )cpp");
463  EXPECT_THAT(
464  Results.Completions,
465  UnorderedElementsAre(AllOf(Named("a"), Kind(CompletionItemKind::Field))));
466 
467  // Completion kinds for templates should not be unknown.
468  Results = completions(
469  R"cpp(
470  template <class T> struct complete_class {};
471  template <class T> void complete_function();
472  template <class T> using complete_type_alias = int;
473  template <class T> int complete_variable = 10;
474 
475  struct X {
476  template <class T> static int complete_static_member = 10;
477 
478  static auto x = complete_^
479  }
480  )cpp");
481  EXPECT_THAT(
482  Results.Completions,
483  UnorderedElementsAre(
484  AllOf(Named("complete_class"), Kind(CompletionItemKind::Class)),
485  AllOf(Named("complete_function"), Kind(CompletionItemKind::Function)),
486  AllOf(Named("complete_type_alias"),
488  AllOf(Named("complete_variable"), Kind(CompletionItemKind::Variable)),
489  AllOf(Named("complete_static_member"),
491 }
492 
493 TEST(CompletionTest, NoDuplicates) {
494  auto Results = completions(
495  R"cpp(
496  class Adapter {
497  };
498 
499  void f() {
500  Adapter^
501  }
502  )cpp",
503  {cls("Adapter")});
504 
505  // Make sure there are no duplicate entries of 'Adapter'.
506  EXPECT_THAT(Results.Completions, ElementsAre(Named("Adapter")));
507 }
508 
509 TEST(CompletionTest, ScopedNoIndex) {
510  auto Results = completions(
511  R"cpp(
512  namespace fake { int BigBang, Babble, Box; };
513  int main() { fake::ba^ }
514  ")cpp");
515  // Babble is a better match than BigBang. Box doesn't match at all.
516  EXPECT_THAT(Results.Completions,
517  ElementsAre(Named("Babble"), Named("BigBang")));
518 }
519 
520 TEST(CompletionTest, Scoped) {
521  auto Results = completions(
522  R"cpp(
523  namespace fake { int Babble, Box; };
524  int main() { fake::ba^ }
525  ")cpp",
526  {var("fake::BigBang")});
527  EXPECT_THAT(Results.Completions,
528  ElementsAre(Named("Babble"), Named("BigBang")));
529 }
530 
531 TEST(CompletionTest, ScopedWithFilter) {
532  auto Results = completions(
533  R"cpp(
534  void f() { ns::x^ }
535  )cpp",
536  {cls("ns::XYZ"), func("ns::foo")});
537  EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("XYZ")));
538 }
539 
540 TEST(CompletionTest, ReferencesAffectRanking) {
541  auto Results = completions("int main() { abs^ }", {ns("absl"), func("absb")});
542  EXPECT_THAT(Results.Completions,
543  HasSubsequence(Named("absb"), Named("absl")));
544  Results = completions("int main() { abs^ }",
545  {withReferences(10000, ns("absl")), func("absb")});
546  EXPECT_THAT(Results.Completions,
547  HasSubsequence(Named("absl"), Named("absb")));
548 }
549 
550 TEST(CompletionTest, ContextWords) {
551  auto Results = completions(R"cpp(
552  enum class Color { RED, YELLOW, BLUE };
553 
554  // (blank lines so the definition above isn't "context")
555 
556  // "It was a yellow car," he said. "Big yellow car, new."
557  auto Finish = Color::^
558  )cpp");
559  // Yellow would normally sort last (alphabetic).
560  // But the recent mention shuold bump it up.
561  ASSERT_THAT(Results.Completions,
562  HasSubsequence(Named("YELLOW"), Named("BLUE")));
563 }
564 
565 TEST(CompletionTest, GlobalQualified) {
566  auto Results = completions(
567  R"cpp(
568  void f() { ::^ }
569  )cpp",
570  {cls("XYZ")});
571  EXPECT_THAT(Results.Completions,
572  AllOf(Has("XYZ", CompletionItemKind::Class),
573  Has("f", CompletionItemKind::Function)));
574 }
575 
576 TEST(CompletionTest, FullyQualified) {
577  auto Results = completions(
578  R"cpp(
579  namespace ns { void bar(); }
580  void f() { ::ns::^ }
581  )cpp",
582  {cls("ns::XYZ")});
583  EXPECT_THAT(Results.Completions,
584  AllOf(Has("XYZ", CompletionItemKind::Class),
585  Has("bar", CompletionItemKind::Function)));
586 }
587 
588 TEST(CompletionTest, SemaIndexMerge) {
589  auto Results = completions(
590  R"cpp(
591  namespace ns { int local; void both(); }
592  void f() { ::ns::^ }
593  )cpp",
594  {func("ns::both"), cls("ns::Index")});
595  // We get results from both index and sema, with no duplicates.
596  EXPECT_THAT(Results.Completions,
597  UnorderedElementsAre(
598  AllOf(Named("local"), Origin(SymbolOrigin::AST)),
599  AllOf(Named("Index"), Origin(SymbolOrigin::Static)),
600  AllOf(Named("both"),
602 }
603 
604 TEST(CompletionTest, SemaIndexMergeWithLimit) {
605  clangd::CodeCompleteOptions Opts;
606  Opts.Limit = 1;
607  auto Results = completions(
608  R"cpp(
609  namespace ns { int local; void both(); }
610  void f() { ::ns::^ }
611  )cpp",
612  {func("ns::both"), cls("ns::Index")}, Opts);
613  EXPECT_EQ(Results.Completions.size(), Opts.Limit);
614  EXPECT_TRUE(Results.HasMore);
615 }
616 
617 TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
618  MockFSProvider FS;
619  MockCompilationDatabase CDB;
620  std::string Subdir = testPath("sub");
621  std::string SearchDirArg = (Twine("-I") + Subdir).str();
622  CDB.ExtraClangFlags = {SearchDirArg.c_str()};
623  std::string BarHeader = testPath("sub/bar.h");
624  FS.Files[BarHeader] = "";
625 
626  IgnoreDiagnostics DiagConsumer;
627  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
628  auto BarURI = URI::create(BarHeader).toString();
629  Symbol Sym = cls("ns::X");
630  Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
631  Sym.IncludeHeaders.emplace_back(BarURI, 1);
632  // Shoten include path based on search dirctory and insert.
633  auto Results = completions(Server,
634  R"cpp(
635  int main() { ns::^ }
636  )cpp",
637  {Sym});
638  EXPECT_THAT(Results.Completions,
639  ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\""))));
640  // Can be disabled via option.
641  CodeCompleteOptions NoInsertion;
642  NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
643  Results = completions(Server,
644  R"cpp(
645  int main() { ns::^ }
646  )cpp",
647  {Sym}, NoInsertion);
648  EXPECT_THAT(Results.Completions,
649  ElementsAre(AllOf(Named("X"), Not(InsertInclude()))));
650  // Duplicate based on inclusions in preamble.
651  Results = completions(Server,
652  R"cpp(
653  #include "sub/bar.h" // not shortest, so should only match resolved.
654  int main() { ns::^ }
655  )cpp",
656  {Sym});
657  EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Labeled("X"),
658  Not(InsertInclude()))));
659 }
660 
661 TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
662  MockFSProvider FS;
663  MockCompilationDatabase CDB;
664 
665  IgnoreDiagnostics DiagConsumer;
666  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
667  Symbol SymX = cls("ns::X");
668  Symbol SymY = cls("ns::Y");
669  std::string BarHeader = testPath("bar.h");
670  auto BarURI = URI::create(BarHeader).toString();
671  SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
672  SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
673  SymX.IncludeHeaders.emplace_back("<bar>", 1);
674  SymY.IncludeHeaders.emplace_back("<bar>", 1);
675  // Shoten include path based on search dirctory and insert.
676  auto Results = completions(Server,
677  R"cpp(
678  namespace ns {
679  class X;
680  class Y {};
681  }
682  int main() { ns::^ }
683  )cpp",
684  {SymX, SymY});
685  EXPECT_THAT(Results.Completions,
686  ElementsAre(AllOf(Named("X"), Not(InsertInclude())),
687  AllOf(Named("Y"), Not(InsertInclude()))));
688 }
689 
690 TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
691  MockFSProvider FS;
692  MockCompilationDatabase CDB;
693  IgnoreDiagnostics DiagConsumer;
694  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
695 
696  FS.Files[testPath("bar.h")] =
697  R"cpp(namespace ns { struct preamble { int member; }; })cpp";
698  auto File = testPath("foo.cpp");
699  Annotations Test(R"cpp(
700  #include "bar.h"
701  namespace ns { int local; }
702  void f() { ns::^; }
703  void f2() { ns::preamble().$2^; }
704  )cpp");
705  runAddDocument(Server, File, Test.code());
706  clangd::CodeCompleteOptions Opts = {};
707 
708  auto I = memIndex({var("ns::index")});
709  Opts.Index = I.get();
710  auto WithIndex = cantFail(runCodeComplete(Server, File, Test.point(), Opts));
711  EXPECT_THAT(WithIndex.Completions,
712  UnorderedElementsAre(Named("local"), Named("index")));
713  auto ClassFromPreamble =
714  cantFail(runCodeComplete(Server, File, Test.point("2"), Opts));
715  EXPECT_THAT(ClassFromPreamble.Completions, Contains(Named("member")));
716 
717  Opts.Index = nullptr;
718  auto WithoutIndex =
719  cantFail(runCodeComplete(Server, File, Test.point(), Opts));
720  EXPECT_THAT(WithoutIndex.Completions,
721  UnorderedElementsAre(Named("local"), Named("preamble")));
722 }
723 
724 // This verifies that we get normal preprocessor completions in the preamble.
725 // This is a regression test for an old bug: if we override the preamble and
726 // try to complete inside it, clang kicks our completion point just outside the
727 // preamble, resulting in always getting top-level completions.
728 TEST(CompletionTest, CompletionInPreamble) {
729  auto Results = completions(R"cpp(
730  #ifnd^ef FOO_H_
731  #define BAR_H_
732  #include <bar.h>
733  int foo() {}
734  #endif
735  )cpp")
736  .Completions;
737  EXPECT_THAT(Results, ElementsAre(Named("ifndef")));
738 }
739 
740 TEST(CompletionTest, DynamicIndexIncludeInsertion) {
741  MockFSProvider FS;
742  MockCompilationDatabase CDB;
743  IgnoreDiagnostics DiagConsumer;
744  ClangdServer::Options Opts = ClangdServer::optsForTest();
745  Opts.BuildDynamicSymbolIndex = true;
746  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
747 
748  FS.Files[testPath("foo_header.h")] = R"cpp(
749  #pragma once
750  struct Foo {
751  // Member doc
752  int foo();
753  };
754  )cpp";
755  const std::string FileContent(R"cpp(
756  #include "foo_header.h"
757  int Foo::foo() {
758  return 42;
759  }
760  )cpp");
761  Server.addDocument(testPath("foo_impl.cpp"), FileContent);
762  // Wait for the dynamic index being built.
763  ASSERT_TRUE(Server.blockUntilIdleForTest());
764  EXPECT_THAT(completions(Server, "Foo^ foo;").Completions,
765  ElementsAre(AllOf(Named("Foo"), HasInclude("\"foo_header.h\""),
766  InsertInclude())));
767 }
768 
769 TEST(CompletionTest, DynamicIndexMultiFile) {
770  MockFSProvider FS;
771  MockCompilationDatabase CDB;
772  IgnoreDiagnostics DiagConsumer;
773  auto Opts = ClangdServer::optsForTest();
774  Opts.BuildDynamicSymbolIndex = true;
775  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
776 
777  FS.Files[testPath("foo.h")] = R"cpp(
778  namespace ns { class XYZ {}; void foo(int x) {} }
779  )cpp";
780  runAddDocument(Server, testPath("foo.cpp"), R"cpp(
781  #include "foo.h"
782  )cpp");
783 
784  auto File = testPath("bar.cpp");
785  Annotations Test(R"cpp(
786  namespace ns {
787  class XXX {};
788  /// Doooc
789  void fooooo() {}
790  }
791  void f() { ns::^ }
792  )cpp");
793  runAddDocument(Server, File, Test.code());
794 
795  auto Results = cantFail(runCodeComplete(Server, File, Test.point(), {}));
796  // "XYZ" and "foo" are not included in the file being completed but are still
797  // visible through the index.
798  EXPECT_THAT(Results.Completions, Has("XYZ", CompletionItemKind::Class));
799  EXPECT_THAT(Results.Completions, Has("foo", CompletionItemKind::Function));
800  EXPECT_THAT(Results.Completions, Has("XXX", CompletionItemKind::Class));
801  EXPECT_THAT(Results.Completions,
802  Contains((Named("fooooo"), Kind(CompletionItemKind::Function),
803  Doc("Doooc"), ReturnType("void"))));
804 }
805 
806 TEST(CompletionTest, Documentation) {
807  auto Results = completions(
808  R"cpp(
809  // Non-doxygen comment.
810  int foo();
811  /// Doxygen comment.
812  /// \param int a
813  int bar(int a);
814  /* Multi-line
815  block comment
816  */
817  int baz();
818 
819  int x = ^
820  )cpp");
821  EXPECT_THAT(Results.Completions,
822  Contains(AllOf(Named("foo"), Doc("Non-doxygen comment."))));
823  EXPECT_THAT(
824  Results.Completions,
825  Contains(AllOf(Named("bar"), Doc("Doxygen comment.\n\\param int a"))));
826  EXPECT_THAT(Results.Completions,
827  Contains(AllOf(Named("baz"), Doc("Multi-line\nblock comment"))));
828 }
829 
830 TEST(CompletionTest, GlobalCompletionFiltering) {
831 
832  Symbol Class = cls("XYZ");
833  Class.Flags = static_cast<Symbol::SymbolFlag>(
834  Class.Flags & ~(Symbol::IndexedForCodeCompletion));
835  Symbol Func = func("XYZ::foooo");
836  Func.Flags = static_cast<Symbol::SymbolFlag>(
837  Func.Flags & ~(Symbol::IndexedForCodeCompletion));
838 
839  auto Results = completions(R"(// void f() {
840  XYZ::foooo^
841  })",
842  {Class, Func});
843  EXPECT_THAT(Results.Completions, IsEmpty());
844 }
845 
846 TEST(CodeCompleteTest, DisableTypoCorrection) {
847  auto Results = completions(R"cpp(
848  namespace clang { int v; }
849  void f() { clangd::^
850  )cpp");
851  EXPECT_TRUE(Results.Completions.empty());
852 }
853 
854 TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
855  auto Results = completions(R"cpp(
856  namespace clang { }
857  void f() {
858  clan^
859  }
860  )cpp");
861 
862  EXPECT_THAT(Results.Completions, Contains(Labeled("clang")));
863  EXPECT_THAT(Results.Completions, Not(Contains(Labeled("clang::"))));
864 }
865 
866 TEST(CompletionTest, BacktrackCrashes) {
867  // Sema calls code completion callbacks twice in these cases.
868  auto Results = completions(R"cpp(
869  namespace ns {
870  struct FooBarBaz {};
871  } // namespace ns
872 
873  int foo(ns::FooBar^
874  )cpp");
875 
876  EXPECT_THAT(Results.Completions, ElementsAre(Labeled("FooBarBaz")));
877 
878  // Check we don't crash in that case too.
879  completions(R"cpp(
880  struct FooBarBaz {};
881  void test() {
882  if (FooBarBaz * x^) {}
883  }
884 )cpp");
885 }
886 
887 TEST(CompletionTest, CompleteInMacroWithStringification) {
888  auto Results = completions(R"cpp(
889 void f(const char *, int x);
890 #define F(x) f(#x, x)
891 
892 namespace ns {
893 int X;
894 int Y;
895 } // namespace ns
896 
897 int f(int input_num) {
898  F(ns::^)
899 }
900 )cpp");
901 
902  EXPECT_THAT(Results.Completions,
903  UnorderedElementsAre(Named("X"), Named("Y")));
904 }
905 
906 TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
907  auto Results = completions(R"cpp(
908 void f(const char *, int x);
909 #define F(x) f(#x, x)
910 
911 namespace ns {
912 int X;
913 
914 int f(int input_num) {
915  F(^)
916 }
917 } // namespace ns
918 )cpp");
919 
920  EXPECT_THAT(Results.Completions, Contains(Named("X")));
921 }
922 
923 TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
924  auto Results = completions(R"cpp(
925  int bar(int param_in_bar) {
926  }
927 
928  int foo(int param_in_foo) {
929 #if 0
930  // In recorvery mode, "param_in_foo" will also be suggested among many other
931  // unrelated symbols; however, this is really a special case where this works.
932  // If the #if block is outside of the function, "param_in_foo" is still
933  // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
934  // really provide useful results in excluded branches.
935  par^
936 #endif
937  }
938 )cpp");
939 
940  EXPECT_TRUE(Results.Completions.empty());
941 }
942 SignatureHelp signatures(llvm::StringRef Text, Position Point,
943  std::vector<Symbol> IndexSymbols = {}) {
944  std::unique_ptr<SymbolIndex> Index;
945  if (!IndexSymbols.empty())
946  Index = memIndex(IndexSymbols);
947 
948  MockFSProvider FS;
949  MockCompilationDatabase CDB;
950  IgnoreDiagnostics DiagConsumer;
951  ClangdServer::Options Opts = ClangdServer::optsForTest();
952  Opts.StaticIndex = Index.get();
953 
954  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
955  auto File = testPath("foo.cpp");
956  runAddDocument(Server, File, Text);
957  return llvm::cantFail(runSignatureHelp(Server, File, Point));
958 }
959 
960 SignatureHelp signatures(llvm::StringRef Text,
961  std::vector<Symbol> IndexSymbols = {}) {
962  Annotations Test(Text);
963  return signatures(Test.code(), Test.point(), std::move(IndexSymbols));
964 }
965 
966 struct ExpectedParameter {
967  std::string Text;
968  std::pair<unsigned, unsigned> Offsets;
969 };
970 MATCHER_P(ParamsAre, P, "") {
971  if (P.size() != arg.parameters.size())
972  return false;
973  for (unsigned I = 0; I < P.size(); ++I) {
974  if (P[I].Text != arg.parameters[I].labelString ||
975  P[I].Offsets != arg.parameters[I].labelOffsets)
976  return false;
977  }
978  return true;
979 }
980 MATCHER_P(SigDoc, Doc, "") { return arg.documentation == Doc; }
981 
982 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g.
983 /// foo([[int p1]], [[double p2]]) -> void
984 Matcher<SignatureInformation> Sig(llvm::StringRef AnnotatedLabel) {
985  llvm::Annotations A(AnnotatedLabel);
986  std::string Label = A.code();
987  std::vector<ExpectedParameter> Parameters;
988  for (auto Range : A.ranges()) {
989  Parameters.emplace_back();
990 
991  ExpectedParameter &P = Parameters.back();
992  P.Text = Label.substr(Range.Begin, Range.End - Range.Begin);
993  P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin));
994  P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End));
995  }
996  return AllOf(SigHelpLabeled(Label), ParamsAre(Parameters));
997 }
998 
999 TEST(SignatureHelpTest, Overloads) {
1000  auto Results = signatures(R"cpp(
1001  void foo(int x, int y);
1002  void foo(int x, float y);
1003  void foo(float x, int y);
1004  void foo(float x, float y);
1005  void bar(int x, int y = 0);
1006  int main() { foo(^); }
1007  )cpp");
1008  EXPECT_THAT(Results.signatures,
1009  UnorderedElementsAre(Sig("foo([[float x]], [[float y]]) -> void"),
1010  Sig("foo([[float x]], [[int y]]) -> void"),
1011  Sig("foo([[int x]], [[float y]]) -> void"),
1012  Sig("foo([[int x]], [[int y]]) -> void")));
1013  // We always prefer the first signature.
1014  EXPECT_EQ(0, Results.activeSignature);
1015  EXPECT_EQ(0, Results.activeParameter);
1016 }
1017 
1018 TEST(SignatureHelpTest, DefaultArgs) {
1019  auto Results = signatures(R"cpp(
1020  void bar(int x, int y = 0);
1021  void bar(float x = 0, int y = 42);
1022  int main() { bar(^
1023  )cpp");
1024  EXPECT_THAT(Results.signatures,
1025  UnorderedElementsAre(
1026  Sig("bar([[int x]], [[int y = 0]]) -> void"),
1027  Sig("bar([[float x = 0]], [[int y = 42]]) -> void")));
1028  EXPECT_EQ(0, Results.activeSignature);
1029  EXPECT_EQ(0, Results.activeParameter);
1030 }
1031 
1032 TEST(SignatureHelpTest, ActiveArg) {
1033  auto Results = signatures(R"cpp(
1034  int baz(int a, int b, int c);
1035  int main() { baz(baz(1,2,3), ^); }
1036  )cpp");
1037  EXPECT_THAT(Results.signatures,
1038  ElementsAre(Sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1039  EXPECT_EQ(0, Results.activeSignature);
1040  EXPECT_EQ(1, Results.activeParameter);
1041 }
1042 
1043 TEST(SignatureHelpTest, OpeningParen) {
1044  llvm::StringLiteral Tests[] = {// Recursive function call.
1045  R"cpp(
1046  int foo(int a, int b, int c);
1047  int main() {
1048  foo(foo $p^( foo(10, 10, 10), ^ )));
1049  })cpp",
1050  // Functional type cast.
1051  R"cpp(
1052  struct Foo {
1053  Foo(int a, int b, int c);
1054  };
1055  int main() {
1056  Foo $p^( 10, ^ );
1057  })cpp",
1058  // New expression.
1059  R"cpp(
1060  struct Foo {
1061  Foo(int a, int b, int c);
1062  };
1063  int main() {
1064  new Foo $p^( 10, ^ );
1065  })cpp",
1066  // Macro expansion.
1067  R"cpp(
1068  int foo(int a, int b, int c);
1069  #define FOO foo(
1070 
1071  int main() {
1072  // Macro expansions.
1073  $p^FOO 10, ^ );
1074  })cpp",
1075  // Macro arguments.
1076  R"cpp(
1077  int foo(int a, int b, int c);
1078  int main() {
1079  #define ID(X) X
1080  ID(foo $p^( foo(10), ^ ))
1081  })cpp"};
1082 
1083  for (auto Test : Tests) {
1084  Annotations Code(Test);
1085  EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
1086  Code.point("p"))
1087  << "Test source:" << Test;
1088  }
1089 }
1090 
1091 class IndexRequestCollector : public SymbolIndex {
1092 public:
1093  bool
1094  fuzzyFind(const FuzzyFindRequest &Req,
1095  llvm::function_ref<void(const Symbol &)> Callback) const override {
1096  std::lock_guard<std::mutex> Lock(Mut);
1097  Requests.push_back(Req);
1098  return true;
1099  }
1100 
1101  void lookup(const LookupRequest &,
1102  llvm::function_ref<void(const Symbol &)>) const override {}
1103 
1104  void refs(const RefsRequest &,
1105  llvm::function_ref<void(const Ref &)>) const override {}
1106 
1107  void relations(const RelationsRequest &,
1108  llvm::function_ref<void(const SymbolID &, const Symbol &)>)
1109  const override {}
1110 
1111  // This is incorrect, but IndexRequestCollector is not an actual index and it
1112  // isn't used in production code.
1113  size_t estimateMemoryUsage() const override { return 0; }
1114 
1115  const std::vector<FuzzyFindRequest> consumeRequests() const {
1116  std::lock_guard<std::mutex> Lock(Mut);
1117  auto Reqs = std::move(Requests);
1118  Requests = {};
1119  return Reqs;
1120  }
1121 
1122 private:
1123  // We need a mutex to handle async fuzzy find requests.
1124  mutable std::mutex Mut;
1125  mutable std::vector<FuzzyFindRequest> Requests;
1126 };
1127 
1128 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code) {
1129  clangd::CodeCompleteOptions Opts;
1130  IndexRequestCollector Requests;
1131  Opts.Index = &Requests;
1132  completions(Code, {}, Opts);
1133  return Requests.consumeRequests();
1134 }
1135 
1136 TEST(CompletionTest, UnqualifiedIdQuery) {
1137  auto Requests = captureIndexRequests(R"cpp(
1138  namespace std {}
1139  using namespace std;
1140  namespace ns {
1141  void f() {
1142  vec^
1143  }
1144  }
1145  )cpp");
1146 
1147  EXPECT_THAT(Requests,
1148  ElementsAre(Field(&FuzzyFindRequest::Scopes,
1149  UnorderedElementsAre("", "ns::", "std::"))));
1150 }
1151 
1152 TEST(CompletionTest, EnclosingScopeComesFirst) {
1153  auto Requests = captureIndexRequests(R"cpp(
1154  namespace std {}
1155  using namespace std;
1156  namespace nx {
1157  namespace ns {
1158  namespace {
1159  void f() {
1160  vec^
1161  }
1162  }
1163  }
1164  }
1165  )cpp");
1166 
1167  EXPECT_THAT(Requests,
1168  ElementsAre(Field(
1170  UnorderedElementsAre("", "std::", "nx::ns::", "nx::"))));
1171  EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::");
1172 }
1173 
1174 TEST(CompletionTest, ResolvedQualifiedIdQuery) {
1175  auto Requests = captureIndexRequests(R"cpp(
1176  namespace ns1 {}
1177  namespace ns2 {} // ignore
1178  namespace ns3 { namespace nns3 {} }
1179  namespace foo {
1180  using namespace ns1;
1181  using namespace ns3::nns3;
1182  }
1183  namespace ns {
1184  void f() {
1185  foo::^
1186  }
1187  }
1188  )cpp");
1189 
1190  EXPECT_THAT(Requests,
1191  ElementsAre(Field(
1193  UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::"))));
1194 }
1195 
1196 TEST(CompletionTest, UnresolvedQualifierIdQuery) {
1197  auto Requests = captureIndexRequests(R"cpp(
1198  namespace a {}
1199  using namespace a;
1200  namespace ns {
1201  void f() {
1202  bar::^
1203  }
1204  } // namespace ns
1205  )cpp");
1206 
1207  EXPECT_THAT(Requests,
1208  ElementsAre(Field(
1210  UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
1211 }
1212 
1213 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
1214  auto Requests = captureIndexRequests(R"cpp(
1215  namespace a {}
1216  using namespace a;
1217  namespace ns {
1218  void f() {
1219  ::a::bar::^
1220  }
1221  } // namespace ns
1222  )cpp");
1223 
1224  EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1225  UnorderedElementsAre("a::bar::"))));
1226 }
1227 
1228 TEST(CompletionTest, EmptyQualifiedQuery) {
1229  auto Requests = captureIndexRequests(R"cpp(
1230  namespace ns {
1231  void f() {
1232  ^
1233  }
1234  } // namespace ns
1235  )cpp");
1236 
1237  EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1238  UnorderedElementsAre("", "ns::"))));
1239 }
1240 
1241 TEST(CompletionTest, GlobalQualifiedQuery) {
1242  auto Requests = captureIndexRequests(R"cpp(
1243  namespace ns {
1244  void f() {
1245  ::^
1246  }
1247  } // namespace ns
1248  )cpp");
1249 
1250  EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1251  UnorderedElementsAre(""))));
1252 }
1253 
1254 TEST(CompletionTest, NoDuplicatedQueryScopes) {
1255  auto Requests = captureIndexRequests(R"cpp(
1256  namespace {}
1257 
1258  namespace na {
1259  namespace {}
1260  namespace nb {
1261  ^
1262  } // namespace nb
1263  } // namespace na
1264  )cpp");
1265 
1266  EXPECT_THAT(Requests,
1267  ElementsAre(Field(&FuzzyFindRequest::Scopes,
1268  UnorderedElementsAre("na::", "na::nb::", ""))));
1269 }
1270 
1271 TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
1272  auto Completions = completions(
1273  R"cpp(
1274  struct Foo {
1275  int SomeNameOfField;
1276  typedef int SomeNameOfTypedefField;
1277  };
1278 
1279  Foo::^)cpp",
1280  {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
1281 
1282  EXPECT_THAT(Completions.Completions,
1283  AllOf(Contains(Labeled("SomeNameOfField")),
1284  Contains(Labeled("SomeNameOfTypedefField")),
1285  Not(Contains(Labeled("SomeNameInTheIndex")))));
1286 }
1287 
1288 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
1289  {
1290  auto Completions = completions(
1291  R"cpp(
1292  template <class T>
1293  void foo() {
1294  T::^
1295  }
1296  )cpp",
1297  {func("::SomeNameInTheIndex")});
1298 
1299  EXPECT_THAT(Completions.Completions,
1300  Not(Contains(Labeled("SomeNameInTheIndex"))));
1301  }
1302 
1303  {
1304  auto Completions = completions(
1305  R"cpp(
1306  template <class T>
1307  void foo() {
1308  T::template Y<int>::^
1309  }
1310  )cpp",
1311  {func("::SomeNameInTheIndex")});
1312 
1313  EXPECT_THAT(Completions.Completions,
1314  Not(Contains(Labeled("SomeNameInTheIndex"))));
1315  }
1316 
1317  {
1318  auto Completions = completions(
1319  R"cpp(
1320  template <class T>
1321  void foo() {
1322  T::foo::^
1323  }
1324  )cpp",
1325  {func("::SomeNameInTheIndex")});
1326 
1327  EXPECT_THAT(Completions.Completions,
1328  Not(Contains(Labeled("SomeNameInTheIndex"))));
1329  }
1330 }
1331 
1332 TEST(CompletionTest, OverloadBundling) {
1333  clangd::CodeCompleteOptions Opts;
1334  Opts.BundleOverloads = true;
1335 
1336  std::string Context = R"cpp(
1337  struct X {
1338  // Overload with int
1339  int a(int);
1340  // Overload with bool
1341  int a(bool);
1342  int b(float);
1343  };
1344  int GFuncC(int);
1345  int GFuncD(int);
1346  )cpp";
1347 
1348  // Member completions are bundled.
1349  EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions,
1350  UnorderedElementsAre(Labeled("a(…)"), Labeled("b(float)")));
1351 
1352  // Non-member completions are bundled, including index+sema.
1353  Symbol NoArgsGFunc = func("GFuncC");
1354  EXPECT_THAT(
1355  completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1356  UnorderedElementsAre(Labeled("GFuncC(…)"), Labeled("GFuncD(int)")));
1357 
1358  // Differences in header-to-insert suppress bundling.
1359  std::string DeclFile = URI::create(testPath("foo")).toString();
1360  NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
1361  NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1);
1362  EXPECT_THAT(
1363  completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1364  UnorderedElementsAre(AllOf(Named("GFuncC"), InsertInclude("<foo>")),
1365  Labeled("GFuncC(int)"), Labeled("GFuncD(int)")));
1366 
1367  // Examine a bundled completion in detail.
1368  auto A =
1369  completions(Context + "int y = X().a^", {}, Opts).Completions.front();
1370  EXPECT_EQ(A.Name, "a");
1371  EXPECT_EQ(A.Signature, "(…)");
1372  EXPECT_EQ(A.BundleSize, 2u);
1373  EXPECT_EQ(A.Kind, CompletionItemKind::Method);
1374  EXPECT_EQ(A.ReturnType, "int"); // All overloads return int.
1375  // For now we just return one of the doc strings arbitrarily.
1376  EXPECT_THAT(A.Documentation, AnyOf(HasSubstr("Overload with int"),
1377  HasSubstr("Overload with bool")));
1378  EXPECT_EQ(A.SnippetSuffix, "($0)");
1379 }
1380 
1381 TEST(CompletionTest, DocumentationFromChangedFileCrash) {
1382  MockFSProvider FS;
1383  auto FooH = testPath("foo.h");
1384  auto FooCpp = testPath("foo.cpp");
1385  FS.Files[FooH] = R"cpp(
1386  // this is my documentation comment.
1387  int func();
1388  )cpp";
1389  FS.Files[FooCpp] = "";
1390 
1391  MockCompilationDatabase CDB;
1392  IgnoreDiagnostics DiagConsumer;
1393  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1394 
1395  Annotations Source(R"cpp(
1396  #include "foo.h"
1397  int func() {
1398  // This makes sure we have func from header in the AST.
1399  }
1400  int a = fun^
1401  )cpp");
1402  Server.addDocument(FooCpp, Source.code(), WantDiagnostics::Yes);
1403  // We need to wait for preamble to build.
1404  ASSERT_TRUE(Server.blockUntilIdleForTest());
1405 
1406  // Change the header file. Completion will reuse the old preamble!
1407  FS.Files[FooH] = R"cpp(
1408  int func();
1409  )cpp";
1410 
1411  clangd::CodeCompleteOptions Opts;
1412  Opts.IncludeComments = true;
1413  CodeCompleteResult Completions =
1414  cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts));
1415  // We shouldn't crash. Unfortunately, current workaround is to not produce
1416  // comments for symbols from headers.
1417  EXPECT_THAT(Completions.Completions,
1418  Contains(AllOf(Not(IsDocumented()), Named("func"))));
1419 }
1420 
1421 TEST(CompletionTest, NonDocComments) {
1422  MockFSProvider FS;
1423  auto FooCpp = testPath("foo.cpp");
1424  FS.Files[FooCpp] = "";
1425 
1426  MockCompilationDatabase CDB;
1427  IgnoreDiagnostics DiagConsumer;
1428  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1429 
1430  Annotations Source(R"cpp(
1431  // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
1432  namespace comments_ns {
1433  }
1434 
1435  // ------------------
1436  int comments_foo();
1437 
1438  // A comment and a decl are separated by newlines.
1439  // Therefore, the comment shouldn't show up as doc comment.
1440 
1441  int comments_bar();
1442 
1443  // this comment should be in the results.
1444  int comments_baz();
1445 
1446 
1447  template <class T>
1448  struct Struct {
1449  int comments_qux();
1450  int comments_quux();
1451  };
1452 
1453 
1454  // This comment should not be there.
1455 
1456  template <class T>
1457  int Struct<T>::comments_qux() {
1458  }
1459 
1460  // This comment **should** be in results.
1461  template <class T>
1462  int Struct<T>::comments_quux() {
1463  int a = comments^;
1464  }
1465  )cpp");
1466  // FIXME: Auto-completion in a template requires disabling delayed template
1467  // parsing.
1468  CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing");
1469  runAddDocument(Server, FooCpp, Source.code(), WantDiagnostics::Yes);
1470  CodeCompleteResult Completions = cantFail(runCodeComplete(
1471  Server, FooCpp, Source.point(), clangd::CodeCompleteOptions()));
1472 
1473  // We should not get any of those comments in completion.
1474  EXPECT_THAT(
1475  Completions.Completions,
1476  UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")),
1477  AllOf(IsDocumented(), Named("comments_baz")),
1478  AllOf(IsDocumented(), Named("comments_quux")),
1479  AllOf(Not(IsDocumented()), Named("comments_ns")),
1480  // FIXME(ibiryukov): the following items should have
1481  // empty documentation, since they are separated from
1482  // a comment with an empty line. Unfortunately, I
1483  // couldn't make Sema tests pass if we ignore those.
1484  AllOf(IsDocumented(), Named("comments_bar")),
1485  AllOf(IsDocumented(), Named("comments_qux"))));
1486 }
1487 
1488 TEST(CompletionTest, CompleteOnInvalidLine) {
1489  auto FooCpp = testPath("foo.cpp");
1490 
1491  MockCompilationDatabase CDB;
1492  IgnoreDiagnostics DiagConsumer;
1493  MockFSProvider FS;
1494  FS.Files[FooCpp] = "// empty file";
1495 
1496  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1497  // Run completion outside the file range.
1498  Position Pos;
1499  Pos.line = 100;
1500  Pos.character = 0;
1501  EXPECT_THAT_EXPECTED(
1502  runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()),
1503  Failed());
1504 }
1505 
1506 TEST(CompletionTest, QualifiedNames) {
1507  auto Results = completions(
1508  R"cpp(
1509  namespace ns { int local; void both(); }
1510  void f() { ::ns::^ }
1511  )cpp",
1512  {func("ns::both"), cls("ns::Index")});
1513  // We get results from both index and sema, with no duplicates.
1514  EXPECT_THAT(
1515  Results.Completions,
1516  UnorderedElementsAre(Scope("ns::"), Scope("ns::"), Scope("ns::")));
1517 }
1518 
1519 TEST(CompletionTest, Render) {
1520  CodeCompletion C;
1521  C.Name = "x";
1522  C.Signature = "(bool) const";
1523  C.SnippetSuffix = "(${0:bool})";
1524  C.ReturnType = "int";
1525  C.RequiredQualifier = "Foo::";
1526  C.Scope = "ns::Foo::";
1527  C.Documentation = "This is x().";
1528  C.Includes.emplace_back();
1529  auto &Include = C.Includes.back();
1530  Include.Header = "\"foo.h\"";
1531  C.Kind = CompletionItemKind::Method;
1532  C.Score.Total = 1.0;
1534 
1535  CodeCompleteOptions Opts;
1536  Opts.IncludeIndicator.Insert = "^";
1537  Opts.IncludeIndicator.NoInsert = "";
1538  Opts.EnableSnippets = false;
1539 
1540  auto R = C.render(Opts);
1541  EXPECT_EQ(R.label, "Foo::x(bool) const");
1542  EXPECT_EQ(R.insertText, "Foo::x");
1543  EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText);
1544  EXPECT_EQ(R.filterText, "x");
1545  EXPECT_EQ(R.detail, "int\n\"foo.h\"");
1546  EXPECT_EQ(R.documentation, "This is x().");
1547  EXPECT_THAT(R.additionalTextEdits, IsEmpty());
1548  EXPECT_EQ(R.sortText, sortText(1.0, "x"));
1549  EXPECT_FALSE(R.deprecated);
1550 
1551  Opts.EnableSnippets = true;
1552  R = C.render(Opts);
1553  EXPECT_EQ(R.insertText, "Foo::x(${0:bool})");
1554  EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
1555 
1556  Include.Insertion.emplace();
1557  R = C.render(Opts);
1558  EXPECT_EQ(R.label, "^Foo::x(bool) const");
1559  EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
1560 
1561  Opts.ShowOrigins = true;
1562  R = C.render(Opts);
1563  EXPECT_EQ(R.label, "^[AS]Foo::x(bool) const");
1564 
1565  C.BundleSize = 2;
1566  R = C.render(Opts);
1567  EXPECT_EQ(R.detail, "[2 overloads]\n\"foo.h\"");
1568 
1569  C.Deprecated = true;
1570  R = C.render(Opts);
1571  EXPECT_TRUE(R.deprecated);
1572 }
1573 
1574 TEST(CompletionTest, IgnoreRecoveryResults) {
1575  auto Results = completions(
1576  R"cpp(
1577  namespace ns { int NotRecovered() { return 0; } }
1578  void f() {
1579  // Sema enters recovery mode first and then normal mode.
1580  if (auto x = ns::NotRecover^)
1581  }
1582  )cpp");
1583  EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("NotRecovered")));
1584 }
1585 
1586 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
1587  auto Results = completions(
1588  R"cpp(
1589  namespace ns {
1590  class X { public: X(); int x_; };
1591  X::X() : x_^(0) {}
1592  }
1593  )cpp");
1594  EXPECT_THAT(Results.Completions,
1595  UnorderedElementsAre(AllOf(Scope("ns::X::"), Named("x_"))));
1596 }
1597 
1598 TEST(CompletionTest, CodeCompletionContext) {
1599  auto Results = completions(
1600  R"cpp(
1601  namespace ns {
1602  class X { public: X(); int x_; };
1603  void f() {
1604  X x;
1605  x.^;
1606  }
1607  }
1608  )cpp");
1609 
1610  EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
1611 }
1612 
1613 TEST(CompletionTest, FixItForArrowToDot) {
1614  MockFSProvider FS;
1615  MockCompilationDatabase CDB;
1616  IgnoreDiagnostics DiagConsumer;
1617  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1618 
1619  CodeCompleteOptions Opts;
1620  Opts.IncludeFixIts = true;
1621  Annotations TestCode(
1622  R"cpp(
1623  class Auxilary {
1624  public:
1625  void AuxFunction();
1626  };
1627  class ClassWithPtr {
1628  public:
1629  void MemberFunction();
1630  Auxilary* operator->() const;
1631  Auxilary* Aux;
1632  };
1633  void f() {
1634  ClassWithPtr x;
1635  x[[->]]^;
1636  }
1637  )cpp");
1638  auto Results =
1639  completions(Server, TestCode.code(), TestCode.point(), {}, Opts);
1640  EXPECT_EQ(Results.Completions.size(), 3u);
1641 
1642  TextEdit ReplacementEdit;
1643  ReplacementEdit.range = TestCode.range();
1644  ReplacementEdit.newText = ".";
1645  for (const auto &C : Results.Completions) {
1646  EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction");
1647  if (!C.FixIts.empty()) {
1648  EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
1649  }
1650  }
1651 }
1652 
1653 TEST(CompletionTest, FixItForDotToArrow) {
1654  MockFSProvider FS;
1655  MockCompilationDatabase CDB;
1656  IgnoreDiagnostics DiagConsumer;
1657  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1658 
1659  CodeCompleteOptions Opts;
1660  Opts.IncludeFixIts = true;
1661  Annotations TestCode(
1662  R"cpp(
1663  class Auxilary {
1664  public:
1665  void AuxFunction();
1666  };
1667  class ClassWithPtr {
1668  public:
1669  void MemberFunction();
1670  Auxilary* operator->() const;
1671  Auxilary* Aux;
1672  };
1673  void f() {
1674  ClassWithPtr x;
1675  x[[.]]^;
1676  }
1677  )cpp");
1678  auto Results =
1679  completions(Server, TestCode.code(), TestCode.point(), {}, Opts);
1680  EXPECT_EQ(Results.Completions.size(), 3u);
1681 
1682  TextEdit ReplacementEdit;
1683  ReplacementEdit.range = TestCode.range();
1684  ReplacementEdit.newText = "->";
1685  for (const auto &C : Results.Completions) {
1686  EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction");
1687  if (!C.FixIts.empty()) {
1688  EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
1689  }
1690  }
1691 }
1692 
1693 TEST(CompletionTest, RenderWithFixItMerged) {
1694  TextEdit FixIt;
1695  FixIt.range.end.character = 5;
1696  FixIt.newText = "->";
1697 
1698  CodeCompletion C;
1699  C.Name = "x";
1700  C.RequiredQualifier = "Foo::";
1701  C.FixIts = {FixIt};
1702  C.CompletionTokenRange.start.character = 5;
1703 
1704  CodeCompleteOptions Opts;
1705  Opts.IncludeFixIts = true;
1706 
1707  auto R = C.render(Opts);
1708  EXPECT_TRUE(R.textEdit);
1709  EXPECT_EQ(R.textEdit->newText, "->Foo::x");
1710  EXPECT_TRUE(R.additionalTextEdits.empty());
1711 }
1712 
1713 TEST(CompletionTest, RenderWithFixItNonMerged) {
1714  TextEdit FixIt;
1715  FixIt.range.end.character = 4;
1716  FixIt.newText = "->";
1717 
1718  CodeCompletion C;
1719  C.Name = "x";
1720  C.RequiredQualifier = "Foo::";
1721  C.FixIts = {FixIt};
1722  C.CompletionTokenRange.start.character = 5;
1723 
1724  CodeCompleteOptions Opts;
1725  Opts.IncludeFixIts = true;
1726 
1727  auto R = C.render(Opts);
1728  EXPECT_TRUE(R.textEdit);
1729  EXPECT_EQ(R.textEdit->newText, "Foo::x");
1730  EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt));
1731 }
1732 
1733 TEST(CompletionTest, CompletionTokenRange) {
1734  MockFSProvider FS;
1735  MockCompilationDatabase CDB;
1736  IgnoreDiagnostics DiagConsumer;
1737  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1738 
1739  constexpr const char *TestCodes[] = {
1740  R"cpp(
1741  class Auxilary {
1742  public:
1743  void AuxFunction();
1744  };
1745  void f() {
1746  Auxilary x;
1747  x.[[Aux]]^;
1748  }
1749  )cpp",
1750  R"cpp(
1751  class Auxilary {
1752  public:
1753  void AuxFunction();
1754  };
1755  void f() {
1756  Auxilary x;
1757  x.[[]]^;
1758  }
1759  )cpp"};
1760  for (const auto &Text : TestCodes) {
1761  Annotations TestCode(Text);
1762  auto Results = completions(Server, TestCode.code(), TestCode.point());
1763 
1764  EXPECT_EQ(Results.Completions.size(), 1u);
1765  EXPECT_THAT(Results.Completions.front().CompletionTokenRange,
1766  TestCode.range());
1767  }
1768 }
1769 
1770 TEST(SignatureHelpTest, OverloadsOrdering) {
1771  const auto Results = signatures(R"cpp(
1772  void foo(int x);
1773  void foo(int x, float y);
1774  void foo(float x, int y);
1775  void foo(float x, float y);
1776  void foo(int x, int y = 0);
1777  int main() { foo(^); }
1778  )cpp");
1779  EXPECT_THAT(Results.signatures,
1780  ElementsAre(Sig("foo([[int x]]) -> void"),
1781  Sig("foo([[int x]], [[int y = 0]]) -> void"),
1782  Sig("foo([[float x]], [[int y]]) -> void"),
1783  Sig("foo([[int x]], [[float y]]) -> void"),
1784  Sig("foo([[float x]], [[float y]]) -> void")));
1785  // We always prefer the first signature.
1786  EXPECT_EQ(0, Results.activeSignature);
1787  EXPECT_EQ(0, Results.activeParameter);
1788 }
1789 
1790 TEST(SignatureHelpTest, InstantiatedSignatures) {
1791  StringRef Sig0 = R"cpp(
1792  template <class T>
1793  void foo(T, T, T);
1794 
1795  int main() {
1796  foo<int>(^);
1797  }
1798  )cpp";
1799 
1800  EXPECT_THAT(signatures(Sig0).signatures,
1801  ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void")));
1802 
1803  StringRef Sig1 = R"cpp(
1804  template <class T>
1805  void foo(T, T, T);
1806 
1807  int main() {
1808  foo(10, ^);
1809  })cpp";
1810 
1811  EXPECT_THAT(signatures(Sig1).signatures,
1812  ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void")));
1813 
1814  StringRef Sig2 = R"cpp(
1815  template <class ...T>
1816  void foo(T...);
1817 
1818  int main() {
1819  foo<int>(^);
1820  }
1821  )cpp";
1822 
1823  EXPECT_THAT(signatures(Sig2).signatures,
1824  ElementsAre(Sig("foo([[T...]]) -> void")));
1825 
1826  // It is debatable whether we should substitute the outer template parameter
1827  // ('T') in that case. Currently we don't substitute it in signature help, but
1828  // do substitute in code complete.
1829  // FIXME: make code complete and signature help consistent, figure out which
1830  // way is better.
1831  StringRef Sig3 = R"cpp(
1832  template <class T>
1833  struct X {
1834  template <class U>
1835  void foo(T, U);
1836  };
1837 
1838  int main() {
1839  X<int>().foo<double>(^)
1840  }
1841  )cpp";
1842 
1843  EXPECT_THAT(signatures(Sig3).signatures,
1844  ElementsAre(Sig("foo([[T]], [[U]]) -> void")));
1845 }
1846 
1847 TEST(SignatureHelpTest, IndexDocumentation) {
1848  Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#");
1849  Foo0.Documentation = "Doc from the index";
1850  Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#");
1851  Foo1.Documentation = "Doc from the index";
1852  Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#");
1853 
1854  StringRef Sig0 = R"cpp(
1855  int foo();
1856  int foo(double);
1857 
1858  void test() {
1859  foo(^);
1860  }
1861  )cpp";
1862 
1863  EXPECT_THAT(
1864  signatures(Sig0, {Foo0}).signatures,
1865  ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")),
1866  AllOf(Sig("foo([[double]]) -> int"), SigDoc(""))));
1867 
1868  StringRef Sig1 = R"cpp(
1869  int foo();
1870  // Overriden doc from sema
1871  int foo(int);
1872  // Doc from sema
1873  int foo(int, int);
1874 
1875  void test() {
1876  foo(^);
1877  }
1878  )cpp";
1879 
1880  EXPECT_THAT(
1881  signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
1882  ElementsAre(
1883  AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")),
1884  AllOf(Sig("foo([[int]]) -> int"), SigDoc("Overriden doc from sema")),
1885  AllOf(Sig("foo([[int]], [[int]]) -> int"), SigDoc("Doc from sema"))));
1886 }
1887 
1888 TEST(SignatureHelpTest, DynamicIndexDocumentation) {
1889  MockFSProvider FS;
1890  MockCompilationDatabase CDB;
1891  IgnoreDiagnostics DiagConsumer;
1892  ClangdServer::Options Opts = ClangdServer::optsForTest();
1893  Opts.BuildDynamicSymbolIndex = true;
1894  ClangdServer Server(CDB, FS, DiagConsumer, Opts);
1895 
1896  FS.Files[testPath("foo.h")] = R"cpp(
1897  struct Foo {
1898  // Member doc
1899  int foo();
1900  };
1901  )cpp";
1902  Annotations FileContent(R"cpp(
1903  #include "foo.h"
1904  void test() {
1905  Foo f;
1906  f.foo(^);
1907  }
1908  )cpp");
1909  auto File = testPath("test.cpp");
1910  Server.addDocument(File, FileContent.code());
1911  // Wait for the dynamic index being built.
1912  ASSERT_TRUE(Server.blockUntilIdleForTest());
1913  EXPECT_THAT(
1914  llvm::cantFail(runSignatureHelp(Server, File, FileContent.point()))
1915  .signatures,
1916  ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Member doc"))));
1917 }
1918 
1919 TEST(CompletionTest, CompletionFunctionArgsDisabled) {
1920  CodeCompleteOptions Opts;
1921  Opts.EnableSnippets = true;
1922  Opts.EnableFunctionArgSnippets = false;
1923 
1924  {
1925  auto Results = completions(
1926  R"cpp(
1927  void xfoo();
1928  void xfoo(int x, int y);
1929  void f() { xfo^ })cpp",
1930  {}, Opts);
1931  EXPECT_THAT(
1932  Results.Completions,
1933  UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("()")),
1934  AllOf(Named("xfoo"), SnippetSuffix("($0)"))));
1935  }
1936  {
1937  auto Results = completions(
1938  R"cpp(
1939  void xbar();
1940  void f() { xba^ })cpp",
1941  {}, Opts);
1942  EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
1943  Named("xbar"), SnippetSuffix("()"))));
1944  }
1945  {
1946  Opts.BundleOverloads = true;
1947  auto Results = completions(
1948  R"cpp(
1949  void xfoo();
1950  void xfoo(int x, int y);
1951  void f() { xfo^ })cpp",
1952  {}, Opts);
1953  EXPECT_THAT(
1954  Results.Completions,
1955  UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("($0)"))));
1956  }
1957  {
1958  auto Results = completions(
1959  R"cpp(
1960  template <class T, class U>
1961  void xfoo(int a, U b);
1962  void f() { xfo^ })cpp",
1963  {}, Opts);
1964  EXPECT_THAT(
1965  Results.Completions,
1966  UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("<$1>($0)"))));
1967  }
1968  {
1969  auto Results = completions(
1970  R"cpp(
1971  template <class T>
1972  class foo_class{};
1973  template <class T>
1974  using foo_alias = T**;
1975  void f() { foo_^ })cpp",
1976  {}, Opts);
1977  EXPECT_THAT(
1978  Results.Completions,
1979  UnorderedElementsAre(AllOf(Named("foo_class"), SnippetSuffix("<$0>")),
1980  AllOf(Named("foo_alias"), SnippetSuffix("<$0>"))));
1981  }
1982 }
1983 
1984 TEST(CompletionTest, SuggestOverrides) {
1985  constexpr const char *const Text(R"cpp(
1986  class A {
1987  public:
1988  virtual void vfunc(bool param);
1989  virtual void vfunc(bool param, int p);
1990  void func(bool param);
1991  };
1992  class B : public A {
1993  virtual void ttt(bool param) const;
1994  void vfunc(bool param, int p) override;
1995  };
1996  class C : public B {
1997  public:
1998  void vfunc(bool param) override;
1999  ^
2000  };
2001  )cpp");
2002  const auto Results = completions(Text);
2003  EXPECT_THAT(
2004  Results.Completions,
2005  AllOf(Contains(AllOf(Labeled("void vfunc(bool param, int p) override"),
2006  NameStartsWith("vfunc"))),
2007  Contains(AllOf(Labeled("void ttt(bool param) const override"),
2008  NameStartsWith("ttt"))),
2009  Not(Contains(Labeled("void vfunc(bool param) override")))));
2010 }
2011 
2012 TEST(CompletionTest, OverridesNonIdentName) {
2013  // Check the completions call does not crash.
2014  completions(R"cpp(
2015  struct Base {
2016  virtual ~Base() = 0;
2017  virtual operator int() = 0;
2018  virtual Base& operator+(Base&) = 0;
2019  };
2020 
2021  struct Derived : Base {
2022  ^
2023  };
2024  )cpp");
2025 }
2026 
2027 TEST(GuessCompletionPrefix, Filters) {
2028  for (llvm::StringRef Case : {
2029  "[[scope::]][[ident]]^",
2030  "[[]][[]]^",
2031  "\n[[]][[]]^",
2032  "[[]][[ab]]^",
2033  "x.[[]][[ab]]^",
2034  "x.[[]][[]]^",
2035  "[[x::]][[ab]]^",
2036  "[[x::]][[]]^",
2037  "[[::x::]][[ab]]^",
2038  "some text [[scope::more::]][[identif]]^ier",
2039  "some text [[scope::]][[mor]]^e::identifier",
2040  "weird case foo::[[::bar::]][[baz]]^",
2041  }) {
2042  Annotations F(Case);
2043  auto Offset = cantFail(positionToOffset(F.code(), F.point()));
2044  auto ToStringRef = [&](Range R) {
2045  return F.code().slice(cantFail(positionToOffset(F.code(), R.start)),
2046  cantFail(positionToOffset(F.code(), R.end)));
2047  };
2048  auto WantQualifier = ToStringRef(F.ranges()[0]),
2049  WantName = ToStringRef(F.ranges()[1]);
2050 
2051  auto Prefix = guessCompletionPrefix(F.code(), Offset);
2052  // Even when components are empty, check their offsets are correct.
2053  EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
2054  EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
2055  EXPECT_EQ(WantName, Prefix.Name) << Case;
2056  EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
2057  }
2058 }
2059 
2060 TEST(CompletionTest, EnableSpeculativeIndexRequest) {
2061  MockFSProvider FS;
2062  MockCompilationDatabase CDB;
2063  IgnoreDiagnostics DiagConsumer;
2064  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
2065 
2066  auto File = testPath("foo.cpp");
2067  Annotations Test(R"cpp(
2068  namespace ns1 { int abc; }
2069  namespace ns2 { int abc; }
2070  void f() { ns1::ab$1^; ns1::ab$2^; }
2071  void f2() { ns2::ab$3^; }
2072  )cpp");
2073  runAddDocument(Server, File, Test.code());
2074  clangd::CodeCompleteOptions Opts = {};
2075 
2076  IndexRequestCollector Requests;
2077  Opts.Index = &Requests;
2078  Opts.SpeculativeIndexRequest = true;
2079 
2080  auto CompleteAtPoint = [&](StringRef P) {
2081  cantFail(runCodeComplete(Server, File, Test.point(P), Opts));
2082  // Sleep for a while to make sure asynchronous call (if applicable) is also
2083  // triggered before callback is invoked.
2084  std::this_thread::sleep_for(std::chrono::milliseconds(100));
2085  };
2086 
2087  CompleteAtPoint("1");
2088  auto Reqs1 = Requests.consumeRequests();
2089  ASSERT_EQ(Reqs1.size(), 1u);
2090  EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::"));
2091 
2092  CompleteAtPoint("2");
2093  auto Reqs2 = Requests.consumeRequests();
2094  // Speculation succeeded. Used speculative index result.
2095  ASSERT_EQ(Reqs2.size(), 1u);
2096  EXPECT_EQ(Reqs2[0], Reqs1[0]);
2097 
2098  CompleteAtPoint("3");
2099  // Speculation failed. Sent speculative index request and the new index
2100  // request after sema.
2101  auto Reqs3 = Requests.consumeRequests();
2102  ASSERT_EQ(Reqs3.size(), 2u);
2103 }
2104 
2105 TEST(CompletionTest, InsertTheMostPopularHeader) {
2106  std::string DeclFile = URI::create(testPath("foo")).toString();
2107  Symbol sym = func("Func");
2108  sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2109  sym.IncludeHeaders.emplace_back("\"foo.h\"", 2);
2110  sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000);
2111 
2112  auto Results = completions("Fun^", {sym}).Completions;
2113  assert(!Results.empty());
2114  EXPECT_THAT(Results[0], AllOf(Named("Func"), InsertInclude("\"bar.h\"")));
2115  EXPECT_EQ(Results[0].Includes.size(), 2u);
2116 }
2117 
2118 TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
2119  MockFSProvider FS;
2120  MockCompilationDatabase CDB;
2121 
2122  std::string FooHeader = testPath("foo.h");
2123  FS.Files[FooHeader] = "";
2124 
2125  IgnoreDiagnostics DiagConsumer;
2126  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
2127 
2128  std::string DeclFile = URI::create(testPath("foo")).toString();
2129  Symbol sym = func("Func");
2130  sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2131  sym.IncludeHeaders.emplace_back("\"foo.h\"", 2);
2132  sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000);
2133 
2134  EXPECT_THAT(
2135  completions(Server, "#include \"foo.h\"\nFun^", {sym}).Completions,
2136  UnorderedElementsAre(
2137  AllOf(Named("Func"), HasInclude("\"foo.h\""), Not(InsertInclude()))));
2138 }
2139 
2140 TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
2141  Symbol Sym;
2142  Sym.Name = "Clangd_Macro_Test";
2143  Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test");
2144  Sym.SymInfo.Kind = index::SymbolKind::Macro;
2145  Sym.Flags |= Symbol::IndexedForCodeCompletion;
2146  EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
2147  .Completions,
2148  UnorderedElementsAre(Named("Clangd_Macro_Test")));
2149 }
2150 
2151 TEST(CompletionTest, MacroFromPreamble) {
2152  MockFSProvider FS;
2153  MockCompilationDatabase CDB;
2154  std::string FooHeader = testPath("foo.h");
2155  FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n";
2156  IgnoreDiagnostics DiagConsumer;
2157  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
2158  auto Results = completions(
2159  R"cpp(#include "foo.h"
2160  #define CLANGD_PREAMBLE_MAIN x
2161 
2162  int x = 0;
2163  #define CLANGD_MAIN x
2164  void f() { CLANGD_^ }
2165  )cpp",
2166  {func("CLANGD_INDEX")});
2167  // We should get results from the main file, including the preamble section.
2168  // However no results from included files (the index should cover them).
2169  EXPECT_THAT(Results.Completions,
2170  UnorderedElementsAre(Named("CLANGD_PREAMBLE_MAIN"),
2171  Named("CLANGD_MAIN"),
2172  Named("CLANGD_INDEX")));
2173 }
2174 
2175 TEST(CompletionTest, DeprecatedResults) {
2176  std::string Body = R"cpp(
2177  void TestClangd();
2178  void TestClangc() __attribute__((deprecated("", "")));
2179  )cpp";
2180 
2181  EXPECT_THAT(
2182  completions(Body + "int main() { TestClang^ }").Completions,
2183  UnorderedElementsAre(AllOf(Named("TestClangd"), Not(Deprecated())),
2184  AllOf(Named("TestClangc"), Deprecated())));
2185 }
2186 
2187 TEST(SignatureHelpTest, InsideArgument) {
2188  {
2189  const auto Results = signatures(R"cpp(
2190  void foo(int x);
2191  void foo(int x, int y);
2192  int main() { foo(1+^); }
2193  )cpp");
2194  EXPECT_THAT(Results.signatures,
2195  ElementsAre(Sig("foo([[int x]]) -> void"),
2196  Sig("foo([[int x]], [[int y]]) -> void")));
2197  EXPECT_EQ(0, Results.activeParameter);
2198  }
2199  {
2200  const auto Results = signatures(R"cpp(
2201  void foo(int x);
2202  void foo(int x, int y);
2203  int main() { foo(1^); }
2204  )cpp");
2205  EXPECT_THAT(Results.signatures,
2206  ElementsAre(Sig("foo([[int x]]) -> void"),
2207  Sig("foo([[int x]], [[int y]]) -> void")));
2208  EXPECT_EQ(0, Results.activeParameter);
2209  }
2210  {
2211  const auto Results = signatures(R"cpp(
2212  void foo(int x);
2213  void foo(int x, int y);
2214  int main() { foo(1^0); }
2215  )cpp");
2216  EXPECT_THAT(Results.signatures,
2217  ElementsAre(Sig("foo([[int x]]) -> void"),
2218  Sig("foo([[int x]], [[int y]]) -> void")));
2219  EXPECT_EQ(0, Results.activeParameter);
2220  }
2221  {
2222  const auto Results = signatures(R"cpp(
2223  void foo(int x);
2224  void foo(int x, int y);
2225  int bar(int x, int y);
2226  int main() { bar(foo(2, 3^)); }
2227  )cpp");
2228  EXPECT_THAT(Results.signatures,
2229  ElementsAre(Sig("foo([[int x]], [[int y]]) -> void")));
2230  EXPECT_EQ(1, Results.activeParameter);
2231  }
2232 }
2233 
2234 TEST(SignatureHelpTest, ConstructorInitializeFields) {
2235  {
2236  const auto Results = signatures(R"cpp(
2237  struct A {
2238  A(int);
2239  };
2240  struct B {
2241  B() : a_elem(^) {}
2242  A a_elem;
2243  };
2244  )cpp");
2245  EXPECT_THAT(Results.signatures,
2246  UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"),
2247  Sig("A([[const A &]])")));
2248  }
2249  {
2250  const auto Results = signatures(R"cpp(
2251  struct A {
2252  A(int);
2253  };
2254  struct C {
2255  C(int);
2256  C(A);
2257  };
2258  struct B {
2259  B() : c_elem(A(1^)) {}
2260  C c_elem;
2261  };
2262  )cpp");
2263  EXPECT_THAT(Results.signatures,
2264  UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"),
2265  Sig("A([[const A &]])")));
2266  }
2267 }
2268 
2269 TEST(CompletionTest, IncludedCompletionKinds) {
2270  MockFSProvider FS;
2271  MockCompilationDatabase CDB;
2272  std::string Subdir = testPath("sub");
2273  std::string SearchDirArg = (Twine("-I") + Subdir).str();
2274  CDB.ExtraClangFlags = {SearchDirArg.c_str()};
2275  std::string BarHeader = testPath("sub/bar.h");
2276  FS.Files[BarHeader] = "";
2277  IgnoreDiagnostics DiagConsumer;
2278  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
2279  auto Results = completions(Server,
2280  R"cpp(
2281  #include "^"
2282  )cpp");
2283  EXPECT_THAT(Results.Completions,
2284  AllOf(Has("sub/", CompletionItemKind::Folder),
2285  Has("bar.h\"", CompletionItemKind::File)));
2286 }
2287 
2288 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
2289  auto Results = completions(
2290  R"cpp(
2291  #include "./^"
2292  )cpp");
2293  EXPECT_TRUE(Results.Completions.empty());
2294 }
2295 
2296 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
2297  clangd::CodeCompleteOptions Opts = {};
2298  Opts.AllScopes = true;
2299 
2300  auto Results = completions(
2301  R"cpp(
2302  void f() { na::Clangd^ }
2303  )cpp",
2304  {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts);
2305  EXPECT_THAT(Results.Completions,
2306  UnorderedElementsAre(
2307  AllOf(Qualifier(""), Scope("na::"), Named("ClangdA"))));
2308 }
2309 
2310 TEST(CompletionTest, AllScopesCompletion) {
2311  clangd::CodeCompleteOptions Opts = {};
2312  Opts.AllScopes = true;
2313 
2314  auto Results = completions(
2315  R"cpp(
2316  namespace na {
2317  void f() { Clangd^ }
2318  }
2319  )cpp",
2320  {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"),
2321  cls("na::nb::Clangd4")},
2322  Opts);
2323  EXPECT_THAT(
2324  Results.Completions,
2325  UnorderedElementsAre(AllOf(Qualifier("nx::"), Named("Clangd1")),
2326  AllOf(Qualifier("ny::"), Named("Clangd2")),
2327  AllOf(Qualifier(""), Scope(""), Named("Clangd3")),
2328  AllOf(Qualifier("nb::"), Named("Clangd4"))));
2329 }
2330 
2331 TEST(CompletionTest, NoQualifierIfShadowed) {
2332  clangd::CodeCompleteOptions Opts = {};
2333  Opts.AllScopes = true;
2334 
2335  auto Results = completions(R"cpp(
2336  namespace nx { class Clangd1 {}; }
2337  using nx::Clangd1;
2338  void f() { Clangd^ }
2339  )cpp",
2340  {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts);
2341  // Although Clangd1 is from another namespace, Sema tells us it's in-scope and
2342  // needs no qualifier.
2343  EXPECT_THAT(Results.Completions,
2344  UnorderedElementsAre(AllOf(Qualifier(""), Named("Clangd1")),
2345  AllOf(Qualifier("nx::"), Named("Clangd2"))));
2346 }
2347 
2348 TEST(CompletionTest, NoCompletionsForNewNames) {
2349  clangd::CodeCompleteOptions Opts;
2350  Opts.AllScopes = true;
2351  auto Results = completions(R"cpp(
2352  void f() { int n^ }
2353  )cpp",
2354  {cls("naber"), cls("nx::naber")}, Opts);
2355  EXPECT_THAT(Results.Completions, UnorderedElementsAre());
2356 }
2357 
2358 TEST(CompletionTest, ObjectiveCMethodNoArguments) {
2359  auto Results = completions(R"objc(
2360  @interface Foo
2361  @property(nonatomic, setter=setXToIgnoreComplete:) int value;
2362  @end
2363  Foo *foo = [Foo new]; int y = [foo v^]
2364  )objc",
2365  /*IndexSymbols=*/{},
2366  /*Opts=*/{}, "Foo.m");
2367 
2368  auto C = Results.Completions;
2369  EXPECT_THAT(C, ElementsAre(Named("value")));
2370  EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method)));
2371  EXPECT_THAT(C, ElementsAre(ReturnType("int")));
2372  EXPECT_THAT(C, ElementsAre(Signature("")));
2373  EXPECT_THAT(C, ElementsAre(SnippetSuffix("")));
2374 }
2375 
2376 TEST(CompletionTest, ObjectiveCMethodOneArgument) {
2377  auto Results = completions(R"objc(
2378  @interface Foo
2379  - (int)valueForCharacter:(char)c;
2380  @end
2381  Foo *foo = [Foo new]; int y = [foo v^]
2382  )objc",
2383  /*IndexSymbols=*/{},
2384  /*Opts=*/{}, "Foo.m");
2385 
2386  auto C = Results.Completions;
2387  EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:")));
2388  EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method)));
2389  EXPECT_THAT(C, ElementsAre(ReturnType("int")));
2390  EXPECT_THAT(C, ElementsAre(Signature("(char)")));
2391  EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(char)}")));
2392 }
2393 
2394 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
2395  auto Results = completions(R"objc(
2396  @interface Foo
2397  + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
2398  @end
2399  id val = [Foo foo^]
2400  )objc",
2401  /*IndexSymbols=*/{},
2402  /*Opts=*/{}, "Foo.m");
2403 
2404  auto C = Results.Completions;
2405  EXPECT_THAT(C, ElementsAre(Named("fooWithValue:")));
2406  EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method)));
2407  EXPECT_THAT(C, ElementsAre(ReturnType("id")));
2408  EXPECT_THAT(C, ElementsAre(Signature("(int) fooey:(unsigned int)")));
2409  EXPECT_THAT(
2410  C, ElementsAre(SnippetSuffix("${1:(int)} fooey:${2:(unsigned int)}")));
2411 }
2412 
2413 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
2414  auto Results = completions(R"objc(
2415  @interface Foo
2416  + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
2417  @end
2418  id val = [Foo fooWithValue:10 f^]
2419  )objc",
2420  /*IndexSymbols=*/{},
2421  /*Opts=*/{}, "Foo.m");
2422 
2423  auto C = Results.Completions;
2424  EXPECT_THAT(C, ElementsAre(Named("fooey:")));
2425  EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method)));
2426  EXPECT_THAT(C, ElementsAre(ReturnType("id")));
2427  EXPECT_THAT(C, ElementsAre(Signature("(unsigned int)")));
2428  EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}")));
2429 }
2430 
2431 TEST(CompletionTest, CursorInSnippets) {
2432  clangd::CodeCompleteOptions Options;
2433  Options.EnableSnippets = true;
2434  auto Results = completions(
2435  R"cpp(
2436  void while_foo(int a, int b);
2437  void test() {
2438  whil^
2439  })cpp",
2440  /*IndexSymbols=*/{}, Options);
2441 
2442  // Last placeholder in code patterns should be $0 to put the cursor there.
2443  EXPECT_THAT(Results.Completions,
2444  Contains(AllOf(
2445  Named("while"),
2446  SnippetSuffix(" (${1:condition}) {\n${0:statements}\n}"))));
2447  // However, snippets for functions must *not* end with $0.
2448  EXPECT_THAT(Results.Completions,
2449  Contains(AllOf(Named("while_foo"),
2450  SnippetSuffix("(${1:int a}, ${2:int b})"))));
2451 }
2452 
2453 TEST(CompletionTest, WorksWithNullType) {
2454  auto R = completions(R"cpp(
2455  int main() {
2456  for (auto [loopVar] : y ) { // y has to be unresolved.
2457  int z = loopV^;
2458  }
2459  }
2460  )cpp");
2461  EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar")));
2462 }
2463 
2464 TEST(CompletionTest, UsingDecl) {
2465  const char *Header(R"cpp(
2466  void foo(int);
2467  namespace std {
2468  using ::foo;
2469  })cpp");
2470  const char *Source(R"cpp(
2471  void bar() {
2472  std::^;
2473  })cpp");
2474  auto Index = TestTU::withHeaderCode(Header).index();
2475  clangd::CodeCompleteOptions Opts;
2476  Opts.Index = Index.get();
2477  Opts.AllScopes = true;
2478  auto R = completions(Source, {}, Opts);
2479  EXPECT_THAT(R.Completions,
2480  ElementsAre(AllOf(Scope("std::"), Named("foo"),
2482 }
2483 
2484 TEST(CompletionTest, ScopeIsUnresolved) {
2485  clangd::CodeCompleteOptions Opts = {};
2486  Opts.AllScopes = true;
2487 
2488  auto Results = completions(R"cpp(
2489  namespace a {
2490  void f() { b::X^ }
2491  }
2492  )cpp",
2493  {cls("a::b::XYZ")}, Opts);
2494  EXPECT_THAT(Results.Completions,
2495  UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ"))));
2496 }
2497 
2498 TEST(CompletionTest, NestedScopeIsUnresolved) {
2499  clangd::CodeCompleteOptions Opts = {};
2500  Opts.AllScopes = true;
2501 
2502  auto Results = completions(R"cpp(
2503  namespace a {
2504  namespace b {}
2505  void f() { b::c::X^ }
2506  }
2507  )cpp",
2508  {cls("a::b::c::XYZ")}, Opts);
2509  EXPECT_THAT(Results.Completions,
2510  UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ"))));
2511 }
2512 
2513 // Clang parser gets confused here and doesn't report the ns:: prefix.
2514 // Naive behavior is to insert it again. We examine the source and recover.
2515 TEST(CompletionTest, NamespaceDoubleInsertion) {
2516  clangd::CodeCompleteOptions Opts = {};
2517 
2518  auto Results = completions(R"cpp(
2519  namespace foo {
2520  namespace ns {}
2521  #define M(X) < X
2522  M(ns::ABC^
2523  }
2524  )cpp",
2525  {cls("foo::ns::ABCDE")}, Opts);
2526  EXPECT_THAT(Results.Completions,
2527  UnorderedElementsAre(AllOf(Qualifier(""), Named("ABCDE"))));
2528 }
2529 
2530 TEST(NoCompileCompletionTest, Basic) {
2531  auto Results = completionsNoCompile(R"cpp(
2532  void func() {
2533  int xyz;
2534  int abc;
2535  ^
2536  }
2537  )cpp");
2538  EXPECT_FALSE(Results.RanParser);
2539  EXPECT_THAT(Results.Completions,
2540  UnorderedElementsAre(Named("void"), Named("func"), Named("int"),
2541  Named("xyz"), Named("abc")));
2542 }
2543 
2544 TEST(NoCompileCompletionTest, WithFilter) {
2545  auto Results = completionsNoCompile(R"cpp(
2546  void func() {
2547  int sym1;
2548  int sym2;
2549  int xyz1;
2550  int xyz2;
2551  sy^
2552  }
2553  )cpp");
2554  EXPECT_THAT(Results.Completions,
2555  UnorderedElementsAre(Named("sym1"), Named("sym2")));
2556 }
2557 
2558 TEST(NoCompileCompletionTest, WithIndex) {
2559  std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"),
2560  func("c::xxx"), func("ns::d::xxx")};
2561  auto Results = completionsNoCompile(
2562  R"cpp(
2563  // Current-scopes, unqualified completion.
2564  using namespace a;
2565  namespace ns {
2566  using namespace b;
2567  void foo() {
2568  xx^
2569  }
2570  )cpp",
2571  Syms);
2572  EXPECT_THAT(Results.Completions,
2573  UnorderedElementsAre(AllOf(Qualifier(""), Scope("")),
2574  AllOf(Qualifier(""), Scope("a::")),
2575  AllOf(Qualifier(""), Scope("ns::b::"))));
2576  CodeCompleteOptions Opts;
2577  Opts.AllScopes = true;
2578  Results = completionsNoCompile(
2579  R"cpp(
2580  // All-scopes unqualified completion.
2581  using namespace a;
2582  namespace ns {
2583  using namespace b;
2584  void foo() {
2585  xx^
2586  }
2587  )cpp",
2588  Syms, Opts);
2589  EXPECT_THAT(Results.Completions,
2590  UnorderedElementsAre(AllOf(Qualifier(""), Scope("")),
2591  AllOf(Qualifier(""), Scope("a::")),
2592  AllOf(Qualifier(""), Scope("ns::b::")),
2593  AllOf(Qualifier("c::"), Scope("c::")),
2594  AllOf(Qualifier("d::"), Scope("ns::d::"))));
2595  Results = completionsNoCompile(
2596  R"cpp(
2597  // Qualified completion.
2598  using namespace a;
2599  namespace ns {
2600  using namespace b;
2601  void foo() {
2602  b::xx^
2603  }
2604  )cpp",
2605  Syms, Opts);
2606  EXPECT_THAT(Results.Completions,
2607  ElementsAre(AllOf(Qualifier(""), Scope("ns::b::"))));
2608  Results = completionsNoCompile(
2609  R"cpp(
2610  // Absolutely qualified completion.
2611  using namespace a;
2612  namespace ns {
2613  using namespace b;
2614  void foo() {
2615  ::a::xx^
2616  }
2617  )cpp",
2618  Syms, Opts);
2619  EXPECT_THAT(Results.Completions,
2620  ElementsAre(AllOf(Qualifier(""), Scope("a::"))));
2621 }
2622 
2623 } // namespace
2624 } // namespace clangd
2625 } // namespace clang
int Limit
MATCHER_P(Named, N, "")
llvm::Expected< CodeCompleteResult > runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, clangd::CodeCompleteOptions Opts)
Definition: SyncAPI.cpp:73
Symbol cls(llvm::StringRef Name)
Definition: TestIndex.cpp:64
The primary text to be inserted is treated as a snippet.
llvm::Expected< SignatureHelp > runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:80
size_t lspLength(llvm::StringRef Code)
Definition: SourceCode.cpp:117
The primary text to be inserted is treated as a plain string.
std::string Subdir
PolySubsequenceMatcher< Args... > HasSubsequence(Args &&... M)
std::string sortText(float Score, llvm::StringRef Name)
Returns a string that sorts in the same order as (-Score, Tiebreak), for LSP.
Definition: Quality.cpp:482
Symbol ns(llvm::StringRef Name)
Definition: TestIndex.cpp:72
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
std::vector< CodeCompletionResult > Results
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
MockFSProvider FS
static Options optsForTest()
Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, llvm::StringRef USRFormat)
Definition: TestIndex.cpp:39
Symbol var(llvm::StringRef Name)
Definition: TestIndex.cpp:68
std::vector< std::string > Scopes
If this is non-empty, symbols must be in at least one of the scopes (e.g.
Definition: Index.h:36
CompletionItemKind
The kind of a completion entry.
Definition: Protocol.h:259
BindArgumentKind Kind
bool IncludeComments
Add comments to code completion results, if available.
Definition: CodeComplete.h:58
bool IncludeCodePatterns
Add code patterns to completion results.
Definition: CodeComplete.h:52
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
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
Definition: TestTU.h:39
Whether or not this symbol is meant to be used for the code completion.
Definition: Symbol.h:119
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Definition: TestIndex.cpp:106
TEST(BackgroundQueueTest, Priority)
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:141
std::string testPath(PathRef File)
Definition: TestFS.cpp:82
std::string SearchDirArg
std::string Signature
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
MATCHER(Declared, "")
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
Definition: CodeComplete.h:62
static constexpr llvm::StringLiteral Name
const Decl * D
Definition: XRefs.cpp:868
SymbolSlab Symbols
std::string ReturnType
std::string SnippetSuffix
CodeCompleteResult codeComplete(PathRef FileName, const tooling::CompileCommand &Command, const PreambleData *Preamble, llvm::StringRef Contents, Position Pos, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
CodeCompletionBuilder Builder
size_t Offset
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
Definition: URI.cpp:186
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
ClangdServer Server
CharSourceRange Range
SourceRange for the file name.
std::string IncludeHeader
std::unique_ptr< SymbolIndex > index() const
Definition: TestTU.cpp:84
bool IncludeMacros
Add macros to code completion results.
Definition: CodeComplete.h:55
IgnoreDiagnostics DiagConsumer
llvm::Optional< FixItHint > FixIt
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, unsigned Offset)
std::pair< unsigned, unsigned > Offsets
std::array< uint8_t, 20 > SymbolID
#define EXPECT_IFF(condition, value, matcher)
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags)
Definition: SyncAPI.cpp:15
const SymbolIndex * Index
Definition: Dexp.cpp:84
Symbol func(llvm::StringRef Name)
Definition: TestIndex.cpp:60