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