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