clang-tools 19.0.0git
CodeCompleteTests.cpp
Go to the documentation of this file.
1//===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ASTSignals.h"
10#include "Annotations.h"
11#include "ClangdServer.h"
12#include "CodeComplete.h"
13#include "Compiler.h"
14#include "Feature.h"
15#include "Matchers.h"
16#include "Protocol.h"
17#include "Quality.h"
18#include "SourceCode.h"
19#include "SyncAPI.h"
20#include "TestFS.h"
21#include "TestIndex.h"
22#include "TestTU.h"
23#include "index/Index.h"
24#include "index/MemIndex.h"
25#include "index/SymbolOrigin.h"
26#include "support/Threading.h"
27#include "clang/Sema/CodeCompleteConsumer.h"
28#include "clang/Tooling/CompilationDatabase.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/Support/Error.h"
31#include "llvm/Support/Path.h"
32#include "llvm/Testing/Annotations/Annotations.h"
33#include "llvm/Testing/Support/Error.h"
34#include "llvm/Testing/Support/SupportHelpers.h"
35#include "gmock/gmock.h"
36#include "gtest/gtest.h"
37#include <condition_variable>
38#include <functional>
39#include <mutex>
40#include <vector>
41
42namespace clang {
43namespace clangd {
44
45namespace {
46using ::llvm::Failed;
47using ::testing::AllOf;
48using ::testing::Contains;
49using ::testing::ElementsAre;
50using ::testing::Field;
51using ::testing::HasSubstr;
52using ::testing::IsEmpty;
53using ::testing::Not;
54using ::testing::UnorderedElementsAre;
55using ContextKind = CodeCompletionContext::Kind;
56
57// GMock helpers for matching completion items.
58MATCHER_P(named, Name, "") { return arg.Name == Name; }
59MATCHER_P(mainFileRefs, Refs, "") { return arg.MainFileRefs == Refs; }
60MATCHER_P(scopeRefs, Refs, "") { return arg.ScopeRefsInFile == Refs; }
61MATCHER_P(nameStartsWith, Prefix, "") {
62 return llvm::StringRef(arg.Name).starts_with(Prefix);
63}
64MATCHER_P(filterText, F, "") { return arg.FilterText == F; }
65MATCHER_P(scope, S, "") { return arg.Scope == S; }
66MATCHER_P(qualifier, Q, "") { return arg.RequiredQualifier == Q; }
67MATCHER_P(labeled, Label, "") {
68 return arg.RequiredQualifier + arg.Name + arg.Signature == Label;
69}
70MATCHER_P(sigHelpLabeled, Label, "") { return arg.label == Label; }
71MATCHER_P(kind, K, "") { return arg.Kind == K; }
72MATCHER_P(doc, D, "") {
73 return arg.Documentation && arg.Documentation->asPlainText() == D;
74}
75MATCHER_P(returnType, D, "") { return arg.ReturnType == D; }
76MATCHER_P(hasInclude, IncludeHeader, "") {
77 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader;
78}
79MATCHER_P(insertInclude, IncludeHeader, "") {
80 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader &&
81 bool(arg.Includes[0].Insertion);
82}
83MATCHER_P(insertIncludeText, InsertedText, "") {
84 return !arg.Includes.empty() && arg.Includes[0].Insertion &&
85 arg.Includes[0].Insertion->newText == InsertedText;
86}
87MATCHER(insertInclude, "") {
88 return !arg.Includes.empty() && bool(arg.Includes[0].Insertion);
89}
90MATCHER_P(snippetSuffix, Text, "") { return arg.SnippetSuffix == Text; }
91MATCHER_P(origin, OriginSet, "") { return arg.Origin == OriginSet; }
92MATCHER_P(signature, S, "") { return arg.Signature == S; }
93MATCHER_P(replacesRange, Range, "") {
94 return arg.CompletionTokenRange == Range;
95}
96
97// Shorthand for Contains(named(Name)).
98Matcher<const std::vector<CodeCompletion> &> has(std::string Name) {
99 return Contains(named(std::move(Name)));
100}
101Matcher<const std::vector<CodeCompletion> &> has(std::string Name,
103 return Contains(AllOf(named(std::move(Name)), kind(K)));
104}
105MATCHER(isDocumented, "") { return arg.Documentation.has_value(); }
106MATCHER(deprecated, "") { return arg.Deprecated; }
107
108std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) {
109 SymbolSlab::Builder Slab;
110 for (const auto &Sym : Symbols)
111 Slab.insert(Sym);
112 return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
113}
114
115// Runs code completion.
116// If IndexSymbols is non-empty, an index will be built and passed to opts.
117CodeCompleteResult completions(const TestTU &TU, Position Point,
118 std::vector<Symbol> IndexSymbols = {},
119 clangd::CodeCompleteOptions Opts = {}) {
120 std::unique_ptr<SymbolIndex> OverrideIndex;
121 if (!IndexSymbols.empty()) {
122 assert(!Opts.Index && "both Index and IndexSymbols given!");
123 OverrideIndex = memIndex(std::move(IndexSymbols));
124 Opts.Index = OverrideIndex.get();
125 }
126
127 MockFS FS;
128 auto Inputs = TU.inputs(FS);
129 IgnoreDiagnostics Diags;
130 auto CI = buildCompilerInvocation(Inputs, Diags);
131 if (!CI) {
132 ADD_FAILURE() << "Couldn't build CompilerInvocation";
133 return {};
134 }
135 auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
136 /*InMemory=*/true, /*Callback=*/nullptr);
137 return codeComplete(testPath(TU.Filename), Point, Preamble.get(), Inputs,
138 Opts);
139}
140
141// Runs code completion.
142CodeCompleteResult completions(llvm::StringRef Text,
143 std::vector<Symbol> IndexSymbols = {},
144 clangd::CodeCompleteOptions Opts = {},
145 PathRef FilePath = "foo.cpp") {
146 Annotations Test(Text);
147 auto TU = TestTU::withCode(Test.code());
148 // To make sure our tests for completiopns inside templates work on Windows.
149 TU.Filename = FilePath.str();
150 return completions(TU, Test.point(), std::move(IndexSymbols),
151 std::move(Opts));
152}
153
154// Runs code completion without the clang parser.
155CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
156 std::vector<Symbol> IndexSymbols = {},
157 clangd::CodeCompleteOptions Opts = {},
158 PathRef FilePath = "foo.cpp") {
159 std::unique_ptr<SymbolIndex> OverrideIndex;
160 if (!IndexSymbols.empty()) {
161 assert(!Opts.Index && "both Index and IndexSymbols given!");
162 OverrideIndex = memIndex(std::move(IndexSymbols));
163 Opts.Index = OverrideIndex.get();
164 }
165
166 MockFS FS;
167 Annotations Test(Text);
168 ParseInputs ParseInput{tooling::CompileCommand(), &FS, Test.code().str()};
169 return codeComplete(FilePath, Test.point(), /*Preamble=*/nullptr, ParseInput,
170 Opts);
171}
172
173Symbol withReferences(int N, Symbol S) {
174 S.References = N;
175 return S;
176}
177
178#if CLANGD_DECISION_FOREST
179TEST(DecisionForestRankingModel, NameMatchSanityTest) {
180 clangd::CodeCompleteOptions Opts;
182 auto Results = completions(
183 R"cpp(
184struct MemberAccess {
185 int ABG();
186 int AlphaBetaGamma();
187};
188int func() { MemberAccess().ABG^ }
189)cpp",
190 /*IndexSymbols=*/{}, Opts);
191 EXPECT_THAT(Results.Completions,
192 ElementsAre(named("ABG"), named("AlphaBetaGamma")));
193}
194
195TEST(DecisionForestRankingModel, ReferencesAffectRanking) {
196 clangd::CodeCompleteOptions Opts;
198 constexpr int NumReferences = 100000;
199 EXPECT_THAT(
200 completions("int main() { clang^ }",
201 {ns("clangA"), withReferences(NumReferences, func("clangD"))},
202 Opts)
203 .Completions,
204 ElementsAre(named("clangD"), named("clangA")));
205 EXPECT_THAT(
206 completions("int main() { clang^ }",
207 {withReferences(NumReferences, ns("clangA")), func("clangD")},
208 Opts)
209 .Completions,
210 ElementsAre(named("clangA"), named("clangD")));
211}
212#endif // CLANGD_DECISION_FOREST
213
214TEST(DecisionForestRankingModel, DecisionForestScorerCallbackTest) {
215 clangd::CodeCompleteOptions Opts;
216 constexpr float MagicNumber = 1234.5678f;
218 Opts.DecisionForestScorer = [&](const SymbolQualitySignals &,
219 const SymbolRelevanceSignals &, float Base) {
220 DecisionForestScores Scores;
221 Scores.Total = MagicNumber;
222 Scores.ExcludingName = MagicNumber;
223 return Scores;
224 };
225 llvm::StringRef Code = "int func() { int xyz; xy^ }";
226 auto Results = completions(Code,
227 /*IndexSymbols=*/{}, Opts);
228 ASSERT_EQ(Results.Completions.size(), 1u);
229 EXPECT_EQ(Results.Completions[0].Score.Total, MagicNumber);
230 EXPECT_EQ(Results.Completions[0].Score.ExcludingName, MagicNumber);
231
232 // Do not use DecisionForestScorer for heuristics model.
234 Results = completions(Code,
235 /*IndexSymbols=*/{}, Opts);
236 ASSERT_EQ(Results.Completions.size(), 1u);
237 EXPECT_NE(Results.Completions[0].Score.Total, MagicNumber);
238 EXPECT_NE(Results.Completions[0].Score.ExcludingName, MagicNumber);
239}
240
241TEST(CompletionTest, Limit) {
242 clangd::CodeCompleteOptions Opts;
243 Opts.Limit = 2;
244 auto Results = completions(R"cpp(
245struct ClassWithMembers {
246 int AAA();
247 int BBB();
248 int CCC();
249};
250
251int main() { ClassWithMembers().^ }
252 )cpp",
253 /*IndexSymbols=*/{}, Opts);
254
255 EXPECT_TRUE(Results.HasMore);
256 EXPECT_THAT(Results.Completions, ElementsAre(named("AAA"), named("BBB")));
257}
258
259TEST(CompletionTest, Filter) {
260 std::string Body = R"cpp(
261 #define MotorCar
262 int Car;
263 struct S {
264 int FooBar;
265 int FooBaz;
266 int Qux;
267 };
268 )cpp";
269
270 // Only items matching the fuzzy query are returned.
271 EXPECT_THAT(completions(Body + "int main() { S().Foba^ }").Completions,
272 AllOf(has("FooBar"), has("FooBaz"), Not(has("Qux"))));
273
274 // Macros require prefix match, either from index or AST.
275 Symbol Sym = var("MotorCarIndex");
276 Sym.SymInfo.Kind = index::SymbolKind::Macro;
277 EXPECT_THAT(
278 completions(Body + "int main() { C^ }", {Sym}).Completions,
279 AllOf(has("Car"), Not(has("MotorCar")), Not(has("MotorCarIndex"))));
280 EXPECT_THAT(completions(Body + "int main() { M^ }", {Sym}).Completions,
281 AllOf(has("MotorCar"), has("MotorCarIndex")));
282}
283
284void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
285 auto Results = completions(
286 R"cpp(
287 int global_var;
288
289 int global_func();
290
291 // Make sure this is not in preamble.
292 #define MACRO X
293
294 struct GlobalClass {};
295
296 struct ClassWithMembers {
297 /// doc for method.
298 int method();
299
300 int field;
301 private:
302 int private_field;
303 };
304
305 int test() {
306 struct LocalClass {};
307
308 /// doc for local_var.
309 int local_var;
310
311 ClassWithMembers().^
312 }
313 )cpp",
314 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
315
316 EXPECT_TRUE(Results.RanParser);
317 // Class members. The only items that must be present in after-dot
318 // completion.
319 EXPECT_THAT(Results.Completions,
320 AllOf(has("method"), has("field"), Not(has("ClassWithMembers")),
321 Not(has("operator=")), Not(has("~ClassWithMembers"))));
323 has("private_field"));
324 // Global items.
325 EXPECT_THAT(
326 Results.Completions,
327 Not(AnyOf(has("global_var"), has("index_var"), has("global_func"),
328 has("global_func()"), has("index_func"), has("GlobalClass"),
329 has("IndexClass"), has("MACRO"), has("LocalClass"))));
330 // There should be no code patterns (aka snippets) in after-dot
331 // completion. At least there aren't any we're aware of.
332 EXPECT_THAT(Results.Completions,
333 Not(Contains(kind(CompletionItemKind::Snippet))));
334 // Check documentation.
335 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
336}
337
338void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
339 auto Results = completions(
340 R"cpp(
341 int global_var;
342 int global_func();
343
344 // Make sure this is not in preamble.
345 #define MACRO X
346
347 struct GlobalClass {};
348
349 struct ClassWithMembers {
350 /// doc for method.
351 int method();
352 };
353
354 int test() {
355 struct LocalClass {};
356
357 /// doc for local_var.
358 int local_var;
359
360 ^
361 }
362 )cpp",
363 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
364
365 EXPECT_TRUE(Results.RanParser);
366 // Class members. Should never be present in global completions.
367 EXPECT_THAT(Results.Completions,
368 Not(AnyOf(has("method"), has("method()"), has("field"))));
369 // Global items.
370 EXPECT_THAT(Results.Completions,
371 AllOf(has("global_var"), has("index_var"), has("global_func"),
372 has("index_func" /* our fake symbol doesn't include () */),
373 has("GlobalClass"), has("IndexClass")));
374 // A macro.
375 EXPECT_THAT(Results.Completions, has("MACRO"));
376 // Local items. Must be present always.
377 EXPECT_THAT(Results.Completions,
378 AllOf(has("local_var"), has("LocalClass"),
379 Contains(kind(CompletionItemKind::Snippet))));
380 // Check documentation.
381 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
382}
383
384TEST(CompletionTest, CompletionOptions) {
385 auto Test = [&](const clangd::CodeCompleteOptions &Opts) {
386 testAfterDotCompletion(Opts);
387 testGlobalScopeCompletion(Opts);
388 };
389 // We used to test every combination of options, but that got too slow (2^N).
390 auto Flags = {
392 };
393 // Test default options.
394 Test({});
395 // Test with one flag flipped.
396 for (auto &F : Flags) {
397 clangd::CodeCompleteOptions O;
398 O.*F ^= true;
399 Test(O);
400 }
401}
402
403TEST(CompletionTest, Accessible) {
404 auto Internal = completions(R"cpp(
405 class Foo {
406 public: void pub();
407 protected: void prot();
408 private: void priv();
409 };
410 void Foo::pub() { this->^ }
411 )cpp");
412 EXPECT_THAT(Internal.Completions,
413 AllOf(has("priv"), has("prot"), has("pub")));
414
415 auto External = completions(R"cpp(
416 class Foo {
417 public: void pub();
418 protected: void prot();
419 private: void priv();
420 };
421 void test() {
422 Foo F;
423 F.^
424 }
425 )cpp");
426 EXPECT_THAT(External.Completions,
427 AllOf(has("pub"), Not(has("prot")), Not(has("priv"))));
428
429 auto Results = completions(R"cpp(
430 struct Foo {
431 public: void pub();
432 protected: void prot();
433 private: void priv();
434 };
435 struct Bar : public Foo {
436 private: using Foo::pub;
437 };
438 void test() {
439 Bar B;
440 B.^
441 }
442 )cpp");
443 EXPECT_THAT(Results.Completions,
444 AllOf(Not(has("priv")), Not(has("prot")), Not(has("pub"))));
445}
446
447TEST(CompletionTest, Qualifiers) {
448 auto Results = completions(R"cpp(
449 class Foo {
450 public: int foo() const;
451 int bar() const;
452 };
453 class Bar : public Foo {
454 int foo() const;
455 };
456 void test() { Bar().^ }
457 )cpp");
458 EXPECT_THAT(Results.Completions,
459 Contains(AllOf(qualifier(""), named("bar"))));
460 // Hidden members are not shown.
461 EXPECT_THAT(Results.Completions,
462 Not(Contains(AllOf(qualifier("Foo::"), named("foo")))));
463 // Private members are not shown.
464 EXPECT_THAT(Results.Completions,
465 Not(Contains(AllOf(qualifier(""), named("foo")))));
466}
467
468// https://github.com/clangd/clangd/issues/1451
469TEST(CompletionTest, QualificationWithInlineNamespace) {
470 auto Results = completions(R"cpp(
471 namespace a { inline namespace b {} }
472 using namespace a::b;
473 void f() { Foo^ }
474 )cpp",
475 {cls("a::Foo")});
476 EXPECT_THAT(Results.Completions,
477 UnorderedElementsAre(AllOf(qualifier("a::"), named("Foo"))));
478}
479
480TEST(CompletionTest, InjectedTypename) {
481 // These are suppressed when accessed as a member...
482 EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions,
483 Not(has("X")));
484 EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions,
485 Not(has("X")));
486 // ...but accessible in other, more useful cases.
487 EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions,
488 has("X"));
489 EXPECT_THAT(
490 completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions,
491 has("Y"));
492 EXPECT_THAT(
493 completions(
494 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
495 .Completions,
496 has("Y"));
497 // This case is marginal (`using X::X` is useful), we allow it for now.
498 EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions,
499 has("X"));
500}
501
502TEST(CompletionTest, SkipInjectedWhenUnqualified) {
503 EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions,
504 ElementsAre(named("X"), named("~X")));
505}
506
507TEST(CompletionTest, Snippets) {
508 clangd::CodeCompleteOptions Opts;
509 auto Results = completions(
510 R"cpp(
511 struct fake {
512 int a;
513 int f(int i, const float f) const;
514 };
515 int main() {
516 fake f;
517 f.^
518 }
519 )cpp",
520 /*IndexSymbols=*/{}, Opts);
521 EXPECT_THAT(
522 Results.Completions,
523 HasSubsequence(named("a"),
524 snippetSuffix("(${1:int i}, ${2:const float f})")));
525}
526
527TEST(CompletionTest, HeuristicsForMemberFunctionCompletion) {
528 clangd::CodeCompleteOptions Opts;
529 Opts.EnableSnippets = true;
530
531 Annotations Code(R"cpp(
532 struct Foo {
533 static int staticMethod(int);
534 int method(int) const;
535 template <typename T, typename U, typename V = int>
536 T generic(U, V);
537 template <typename T, int U>
538 static T staticGeneric();
539 Foo() {
540 this->$canBeCall^
541 $canBeCall^
542 Foo::$canBeCall^
543 }
544 };
545
546 struct Derived : Foo {
547 using Foo::method;
548 using Foo::generic;
549 Derived() {
550 Foo::$canBeCall^
551 }
552 };
553
554 struct OtherClass {
555 OtherClass() {
556 Foo f;
557 Derived d;
558 f.$canBeCall^
559 ; // Prevent parsing as 'f.f'
560 f.Foo::$canBeCall^
561 &Foo::$canNotBeCall^
562 ;
563 d.Foo::$canBeCall^
564 ;
565 d.Derived::$canBeCall^
566 }
567 };
568
569 int main() {
570 Foo f;
571 Derived d;
572 f.$canBeCall^
573 ; // Prevent parsing as 'f.f'
574 f.Foo::$canBeCall^
575 &Foo::$canNotBeCall^
576 ;
577 d.Foo::$canBeCall^
578 ;
579 d.Derived::$canBeCall^
580 }
581 )cpp");
582 auto TU = TestTU::withCode(Code.code());
583
584 for (const auto &P : Code.points("canNotBeCall")) {
585 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
586 EXPECT_THAT(Results.Completions,
587 Contains(AllOf(named("method"), signature("(int) const"),
588 snippetSuffix(""))));
589 // We don't have any arguments to deduce against if this isn't a call.
590 // Thus, we should emit these deducible template arguments explicitly.
591 EXPECT_THAT(
592 Results.Completions,
593 Contains(AllOf(named("generic"),
594 signature("<typename T, typename U>(U, V)"),
595 snippetSuffix("<${1:typename T}, ${2:typename U}>"))));
596 }
597
598 for (const auto &P : Code.points("canBeCall")) {
599 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
600 EXPECT_THAT(Results.Completions,
601 Contains(AllOf(named("method"), signature("(int) const"),
602 snippetSuffix("(${1:int})"))));
603 EXPECT_THAT(
604 Results.Completions,
605 Contains(AllOf(named("generic"), signature("<typename T>(U, V)"),
606 snippetSuffix("<${1:typename T}>(${2:U}, ${3:V})"))));
607 }
608
609 // static method will always keep the snippet
610 for (const auto &P : Code.points()) {
611 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
612 EXPECT_THAT(Results.Completions,
613 Contains(AllOf(named("staticMethod"), signature("(int)"),
614 snippetSuffix("(${1:int})"))));
615 EXPECT_THAT(Results.Completions,
616 Contains(AllOf(
617 named("staticGeneric"), signature("<typename T, int U>()"),
618 snippetSuffix("<${1:typename T}, ${2:int U}>()"))));
619 }
620}
621
622TEST(CompletionTest, NoSnippetsInUsings) {
623 clangd::CodeCompleteOptions Opts;
624 Opts.EnableSnippets = true;
625 auto Results = completions(
626 R"cpp(
627 namespace ns {
628 int func(int a, int b);
629 }
630
631 using ns::^;
632 )cpp",
633 /*IndexSymbols=*/{}, Opts);
634 EXPECT_THAT(Results.Completions,
635 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
636 snippetSuffix(""))));
637
638 // Check index completions too.
639 auto Func = func("ns::func");
640 Func.CompletionSnippetSuffix = "(${1:int a}, ${2: int b})";
641 Func.Signature = "(int a, int b)";
642 Func.ReturnType = "void";
643
644 Results = completions(R"cpp(
645 namespace ns {}
646 using ns::^;
647 )cpp",
648 /*IndexSymbols=*/{Func}, Opts);
649 EXPECT_THAT(Results.Completions,
650 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
651 snippetSuffix(""))));
652
653 // Check all-scopes completions too.
654 Opts.AllScopes = true;
655 Results = completions(R"cpp(
656 using ^;
657 )cpp",
658 /*IndexSymbols=*/{Func}, Opts);
659 EXPECT_THAT(Results.Completions,
660 Contains(AllOf(named("func"), labeled("ns::func(int a, int b)"),
661 snippetSuffix(""))));
662}
663
664TEST(CompletionTest, Kinds) {
665 auto Results = completions(
666 R"cpp(
667 int variable;
668 struct Struct {};
669 int function();
670 // make sure MACRO is not included in preamble.
671 #define MACRO 10
672 int X = ^
673 )cpp",
674 {func("indexFunction"), var("indexVariable"), cls("indexClass")});
675 EXPECT_THAT(Results.Completions,
676 AllOf(has("function", CompletionItemKind::Function),
677 has("variable", CompletionItemKind::Variable),
678 has("int", CompletionItemKind::Keyword),
679 has("Struct", CompletionItemKind::Struct),
680 has("MACRO", CompletionItemKind::Constant),
681 has("indexFunction", CompletionItemKind::Function),
682 has("indexVariable", CompletionItemKind::Variable),
683 has("indexClass", CompletionItemKind::Class)));
684
685 Results = completions("nam^");
686 EXPECT_THAT(Results.Completions,
687 has("namespace", CompletionItemKind::Snippet));
688
689 // Members of anonymous unions are of kind 'field'.
690 Results = completions(
691 R"cpp(
692 struct X{
693 union {
694 void *a;
695 };
696 };
697 auto u = X().^
698 )cpp");
699 EXPECT_THAT(
700 Results.Completions,
701 UnorderedElementsAre(AllOf(named("a"), kind(CompletionItemKind::Field))));
702
703 // Completion kinds for templates should not be unknown.
704 Results = completions(
705 R"cpp(
706 template <class T> struct complete_class {};
707 template <class T> void complete_function();
708 template <class T> using complete_type_alias = int;
709 template <class T> int complete_variable = 10;
710
711 struct X {
712 template <class T> static int complete_static_member = 10;
713
714 static auto x = complete_^
715 }
716 )cpp");
717 EXPECT_THAT(
718 Results.Completions,
719 UnorderedElementsAre(
720 AllOf(named("complete_class"), kind(CompletionItemKind::Class)),
721 AllOf(named("complete_function"), kind(CompletionItemKind::Function)),
722 AllOf(named("complete_type_alias"),
724 AllOf(named("complete_variable"), kind(CompletionItemKind::Variable)),
725 AllOf(named("complete_static_member"),
727
728 Results = completions(
729 R"cpp(
730 enum Color {
731 Red
732 };
733 Color u = ^
734 )cpp");
735 EXPECT_THAT(
736 Results.Completions,
737 Contains(AllOf(named("Red"), kind(CompletionItemKind::EnumMember))));
738}
739
740TEST(CompletionTest, NoDuplicates) {
741 auto Results = completions(
742 R"cpp(
743 class Adapter {
744 };
745
746 void f() {
747 Adapter^
748 }
749 )cpp",
750 {cls("Adapter")});
751
752 // Make sure there are no duplicate entries of 'Adapter'.
753 EXPECT_THAT(Results.Completions, ElementsAre(named("Adapter")));
754}
755
756TEST(CompletionTest, ScopedNoIndex) {
757 auto Results = completions(
758 R"cpp(
759 namespace fake { int BigBang, Babble, Box; };
760 int main() { fake::ba^ }
761 ")cpp");
762 // Babble is a better match than BigBang. Box doesn't match at all.
763 EXPECT_THAT(Results.Completions,
764 ElementsAre(named("Babble"), named("BigBang")));
765}
766
767TEST(CompletionTest, Scoped) {
768 auto Results = completions(
769 R"cpp(
770 namespace fake { int Babble, Box; };
771 int main() { fake::ba^ }
772 ")cpp",
773 {var("fake::BigBang")});
774 EXPECT_THAT(Results.Completions,
775 ElementsAre(named("Babble"), named("BigBang")));
776}
777
778TEST(CompletionTest, ScopedWithFilter) {
779 auto Results = completions(
780 R"cpp(
781 void f() { ns::x^ }
782 )cpp",
783 {cls("ns::XYZ"), func("ns::foo")});
784 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("XYZ")));
785}
786
787TEST(CompletionTest, ReferencesAffectRanking) {
788 EXPECT_THAT(completions("int main() { abs^ }", {func("absA"), func("absB")})
789 .Completions,
790 HasSubsequence(named("absA"), named("absB")));
791 EXPECT_THAT(completions("int main() { abs^ }",
792 {func("absA"), withReferences(1000, func("absB"))})
793 .Completions,
794 HasSubsequence(named("absB"), named("absA")));
795}
796
797TEST(CompletionTest, ContextWords) {
798 auto Results = completions(R"cpp(
799 enum class Color { RED, YELLOW, BLUE };
800
801 // (blank lines so the definition above isn't "context")
802
803 // "It was a yellow car," he said. "Big yellow car, new."
804 auto Finish = Color::^
805 )cpp");
806 // Yellow would normally sort last (alphabetic).
807 // But the recent mention should bump it up.
808 ASSERT_THAT(Results.Completions,
809 HasSubsequence(named("YELLOW"), named("BLUE")));
810}
811
812TEST(CompletionTest, GlobalQualified) {
813 auto Results = completions(
814 R"cpp(
815 void f() { ::^ }
816 )cpp",
817 {cls("XYZ")});
818 EXPECT_THAT(Results.Completions,
819 AllOf(has("XYZ", CompletionItemKind::Class),
821}
822
823TEST(CompletionTest, FullyQualified) {
824 auto Results = completions(
825 R"cpp(
826 namespace ns { void bar(); }
827 void f() { ::ns::^ }
828 )cpp",
829 {cls("ns::XYZ")});
830 EXPECT_THAT(Results.Completions,
831 AllOf(has("XYZ", CompletionItemKind::Class),
832 has("bar", CompletionItemKind::Function)));
833}
834
835TEST(CompletionTest, SemaIndexMerge) {
836 auto Results = completions(
837 R"cpp(
838 namespace ns { int local; void both(); }
839 void f() { ::ns::^ }
840 )cpp",
841 {func("ns::both"), cls("ns::Index")});
842 // We get results from both index and sema, with no duplicates.
843 EXPECT_THAT(Results.Completions,
844 UnorderedElementsAre(
845 AllOf(named("local"), origin(SymbolOrigin::AST)),
846 AllOf(named("Index"), origin(SymbolOrigin::Static)),
847 AllOf(named("both"),
849}
850
851TEST(CompletionTest, SemaIndexMergeWithLimit) {
852 clangd::CodeCompleteOptions Opts;
853 Opts.Limit = 1;
854 auto Results = completions(
855 R"cpp(
856 namespace ns { int local; void both(); }
857 void f() { ::ns::^ }
858 )cpp",
859 {func("ns::both"), cls("ns::Index")}, Opts);
860 EXPECT_EQ(Results.Completions.size(), Opts.Limit);
861 EXPECT_TRUE(Results.HasMore);
862}
863
864TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
865 TestTU TU;
866 TU.ExtraArgs.push_back("-I" + testPath("sub"));
867 TU.AdditionalFiles["sub/bar.h"] = "";
868 auto BarURI = URI::create(testPath("sub/bar.h")).toString();
869
870 Symbol Sym = cls("ns::X");
871 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
872 Sym.IncludeHeaders.emplace_back(BarURI, 1, Symbol::Include);
873 // Shorten include path based on search directory and insert.
874 Annotations Test("int main() { ns::^ }");
875 TU.Code = Test.code().str();
876 auto Results = completions(TU, Test.point(), {Sym});
877 EXPECT_THAT(Results.Completions,
878 ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
879 // Can be disabled via option.
880 CodeCompleteOptions NoInsertion;
881 NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
882 Results = completions(TU, Test.point(), {Sym}, NoInsertion);
883 EXPECT_THAT(Results.Completions,
884 ElementsAre(AllOf(named("X"), Not(insertInclude()))));
885 // Duplicate based on inclusions in preamble.
886 Test = Annotations(R"cpp(
887 #include "sub/bar.h" // not shortest, so should only match resolved.
888 int main() { ns::^ }
889 )cpp");
890 TU.Code = Test.code().str();
891 Results = completions(TU, Test.point(), {Sym});
892 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(named("X"), labeled("X"),
893 Not(insertInclude()))));
894}
895
896TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
897 Symbol SymX = cls("ns::X");
898 Symbol SymY = cls("ns::Y");
899 std::string BarHeader = testPath("bar.h");
900 auto BarURI = URI::create(BarHeader).toString();
901 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
902 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
903 SymX.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
904 SymY.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
905 // Shorten include path based on search directory and insert.
906 auto Results = completions(R"cpp(
907 namespace ns {
908 class X;
909 class Y {};
910 }
911 int main() { ns::^ }
912 )cpp",
913 {SymX, SymY});
914 EXPECT_THAT(Results.Completions,
915 ElementsAre(AllOf(named("X"), Not(insertInclude())),
916 AllOf(named("Y"), Not(insertInclude()))));
917}
918
919TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
920 Annotations Test(R"cpp(
921 #include "bar.h"
922 namespace ns { int local; }
923 void f() { ns::^; }
924 void f2() { ns::preamble().$2^; }
925 )cpp");
926 auto TU = TestTU::withCode(Test.code());
927 TU.AdditionalFiles["bar.h"] =
928 R"cpp(namespace ns { struct preamble { int member; }; })cpp";
929
930 clangd::CodeCompleteOptions Opts = {};
931 auto I = memIndex({var("ns::index")});
932 Opts.Index = I.get();
933 auto WithIndex = completions(TU, Test.point(), {}, Opts);
934 EXPECT_THAT(WithIndex.Completions,
935 UnorderedElementsAre(named("local"), named("index")));
936 auto ClassFromPreamble = completions(TU, Test.point("2"), {}, Opts);
937 EXPECT_THAT(ClassFromPreamble.Completions, Contains(named("member")));
938
939 Opts.Index = nullptr;
940 auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
941 EXPECT_THAT(WithoutIndex.Completions,
942 UnorderedElementsAre(named("local"), named("preamble")));
943}
944
945// This verifies that we get normal preprocessor completions in the preamble.
946// This is a regression test for an old bug: if we override the preamble and
947// try to complete inside it, clang kicks our completion point just outside the
948// preamble, resulting in always getting top-level completions.
949TEST(CompletionTest, CompletionInPreamble) {
950 auto Results = completions(R"cpp(
951 #ifnd^ef FOO_H_
952 #define BAR_H_
953 #include <bar.h>
954 int foo() {}
955 #endif
956 )cpp")
957 .Completions;
958 EXPECT_THAT(Results, ElementsAre(named("ifndef")));
959}
960
961TEST(CompletionTest, CompletionRecoveryASTType) {
962 auto Results = completions(R"cpp(
963 struct S { int member; };
964 S overloaded(int);
965 void foo() {
966 // No overload matches, but we have recovery-expr with the correct type.
967 overloaded().^
968 })cpp")
969 .Completions;
970 EXPECT_THAT(Results, ElementsAre(named("member")));
971}
972
973TEST(CompletionTest, DynamicIndexIncludeInsertion) {
974 MockFS FS;
975 MockCompilationDatabase CDB;
976 ClangdServer::Options Opts = ClangdServer::optsForTest();
977 Opts.BuildDynamicSymbolIndex = true;
978 ClangdServer Server(CDB, FS, Opts);
979
980 FS.Files[testPath("foo_header.h")] = R"cpp(
981 #pragma once
982 struct Foo {
983 // Member doc
984 int foo();
985 };
986 )cpp";
987 const std::string FileContent(R"cpp(
988 #include "foo_header.h"
989 int Foo::foo() {
990 return 42;
991 }
992 )cpp");
993 Server.addDocument(testPath("foo_impl.cpp"), FileContent);
994 // Wait for the dynamic index being built.
995 ASSERT_TRUE(Server.blockUntilIdleForTest());
996
997 auto File = testPath("foo.cpp");
998 Annotations Test("Foo^ foo;");
999 runAddDocument(Server, File, Test.code());
1000 auto CompletionList =
1001 llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
1002
1003 EXPECT_THAT(CompletionList.Completions,
1004 ElementsAre(AllOf(named("Foo"), hasInclude("\"foo_header.h\""),
1005 insertInclude())));
1006}
1007
1008TEST(CompletionTest, DynamicIndexMultiFile) {
1009 MockFS FS;
1010 MockCompilationDatabase CDB;
1011 auto Opts = ClangdServer::optsForTest();
1012 Opts.BuildDynamicSymbolIndex = true;
1013 ClangdServer Server(CDB, FS, Opts);
1014
1015 FS.Files[testPath("foo.h")] = R"cpp(
1016 namespace ns { class XYZ {}; void foo(int x) {} }
1017 )cpp";
1018 runAddDocument(Server, testPath("foo.cpp"), R"cpp(
1019 #include "foo.h"
1020 )cpp");
1021
1022 auto File = testPath("bar.cpp");
1023 Annotations Test(R"cpp(
1024 namespace ns {
1025 class XXX {};
1026 /// Doooc
1027 void fooooo() {}
1028 }
1029 void f() { ns::^ }
1030 )cpp");
1031 runAddDocument(Server, File, Test.code());
1032
1033 auto Results = cantFail(runCodeComplete(Server, File, Test.point(), {}));
1034 // "XYZ" and "foo" are not included in the file being completed but are still
1035 // visible through the index.
1036 EXPECT_THAT(Results.Completions, has("XYZ", CompletionItemKind::Class));
1037 EXPECT_THAT(Results.Completions, has("foo", CompletionItemKind::Function));
1038 EXPECT_THAT(Results.Completions, has("XXX", CompletionItemKind::Class));
1039 EXPECT_THAT(Results.Completions,
1040 Contains((named("fooooo"), kind(CompletionItemKind::Function),
1041 doc("Doooc"), returnType("void"))));
1042}
1043
1044TEST(CompletionTest, Documentation) {
1045 auto Results = completions(
1046 R"cpp(
1047 // Non-doxygen comment.
1048 __attribute__((annotate("custom_annotation"))) int foo();
1049 /// Doxygen comment.
1050 /// \param int a
1051 int bar(int a);
1052 /* Multi-line
1053 block comment
1054 */
1055 int baz();
1056
1057 int x = ^
1058 )cpp");
1059 EXPECT_THAT(Results.Completions,
1060 Contains(AllOf(
1061 named("foo"),
1062 doc("Annotation: custom_annotation\nNon-doxygen comment."))));
1063 EXPECT_THAT(
1064 Results.Completions,
1065 Contains(AllOf(named("bar"), doc("Doxygen comment.\n\\param int a"))));
1066 EXPECT_THAT(Results.Completions,
1067 Contains(AllOf(named("baz"), doc("Multi-line block comment"))));
1068}
1069
1070TEST(CompletionTest, CommentsFromSystemHeaders) {
1071 MockFS FS;
1072 MockCompilationDatabase CDB;
1073
1074 auto Opts = ClangdServer::optsForTest();
1075 Opts.BuildDynamicSymbolIndex = true;
1076
1077 ClangdServer Server(CDB, FS, Opts);
1078
1079 FS.Files[testPath("foo.h")] = R"cpp(
1080 #pragma GCC system_header
1081
1082 // This comment should be retained!
1083 int foo();
1084 )cpp";
1085
1086 auto File = testPath("foo.cpp");
1087 Annotations Test(R"cpp(
1088#include "foo.h"
1089int x = foo^
1090 )cpp");
1091 runAddDocument(Server, File, Test.code());
1092 auto CompletionList =
1093 llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
1094
1095 EXPECT_THAT(
1096 CompletionList.Completions,
1097 Contains(AllOf(named("foo"), doc("This comment should be retained!"))));
1098}
1099
1100TEST(CompletionTest, GlobalCompletionFiltering) {
1101
1102 Symbol Class = cls("XYZ");
1103 Class.Flags = static_cast<Symbol::SymbolFlag>(
1105 Symbol Func = func("XYZ::foooo");
1106 Func.Flags = static_cast<Symbol::SymbolFlag>(
1107 Func.Flags & ~(Symbol::IndexedForCodeCompletion));
1108
1109 auto Results = completions(R"(// void f() {
1110 XYZ::foooo^
1111 })",
1112 {Class, Func});
1113 EXPECT_THAT(Results.Completions, IsEmpty());
1114}
1115
1116TEST(CodeCompleteTest, DisableTypoCorrection) {
1117 auto Results = completions(R"cpp(
1118 namespace clang { int v; }
1119 void f() { clangd::^
1120 )cpp");
1121 EXPECT_TRUE(Results.Completions.empty());
1122}
1123
1124TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
1125 auto Results = completions(R"cpp(
1126 namespace clang { }
1127 void f() {
1128 clan^
1129 }
1130 )cpp");
1131
1132 EXPECT_THAT(Results.Completions, Contains(labeled("clang")));
1133 EXPECT_THAT(Results.Completions, Not(Contains(labeled("clang::"))));
1134}
1135
1136TEST(CompletionTests, EmptySnippetDoesNotCrash) {
1137 // See https://github.com/clangd/clangd/issues/1216
1138 auto Results = completions(R"cpp(
1139 int main() {
1140 auto w = [&](auto &&f) { return f(f); };
1141 auto f = w([&](auto &&f) {
1142 return [&](auto &&n) {
1143 if (n == 0) {
1144 return 1;
1145 }
1146 return n * ^(f)(n - 1);
1147 };
1148 })(10);
1149 }
1150 )cpp");
1151}
1152
1153TEST(CompletionTest, Issue1427Crash) {
1154 // Need to provide main file signals to ensure that the branch in
1155 // SymbolRelevanceSignals::computeASTSignals() that tries to
1156 // compute a symbol ID is taken.
1157 ASTSignals MainFileSignals;
1158 CodeCompleteOptions Opts;
1159 Opts.MainFileSignals = &MainFileSignals;
1160 completions(R"cpp(
1161 auto f = []() {
1162 1.0_^
1163 };
1164 )cpp",
1165 {}, Opts);
1166}
1167
1168TEST(CompletionTest, BacktrackCrashes) {
1169 // Sema calls code completion callbacks twice in these cases.
1170 auto Results = completions(R"cpp(
1171 namespace ns {
1172 struct FooBarBaz {};
1173 } // namespace ns
1174
1175 int foo(ns::FooBar^
1176 )cpp");
1177
1178 EXPECT_THAT(Results.Completions, ElementsAre(labeled("FooBarBaz")));
1179
1180 // Check we don't crash in that case too.
1181 completions(R"cpp(
1182 struct FooBarBaz {};
1183 void test() {
1184 if (FooBarBaz * x^) {}
1185 }
1186)cpp");
1187}
1188
1189TEST(CompletionTest, CompleteInMacroWithStringification) {
1190 auto Results = completions(R"cpp(
1191void f(const char *, int x);
1192#define F(x) f(#x, x)
1193
1194namespace ns {
1195int X;
1196int Y;
1197} // namespace ns
1198
1199int f(int input_num) {
1200 F(ns::^)
1201}
1202)cpp");
1203
1204 EXPECT_THAT(Results.Completions,
1205 UnorderedElementsAre(named("X"), named("Y")));
1206}
1207
1208TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
1209 auto Results = completions(R"cpp(
1210void f(const char *, int x);
1211#define F(x) f(#x, x)
1212
1213namespace ns {
1214int X;
1215
1216int f(int input_num) {
1217 F(^)
1218}
1219} // namespace ns
1220)cpp");
1221
1222 EXPECT_THAT(Results.Completions, Contains(named("X")));
1223}
1224
1225TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
1226 auto Results = completions(R"cpp(
1227 int bar(int param_in_bar) {
1228 }
1229
1230 int foo(int param_in_foo) {
1231#if 0
1232 // In recovery mode, "param_in_foo" will also be suggested among many other
1233 // unrelated symbols; however, this is really a special case where this works.
1234 // If the #if block is outside of the function, "param_in_foo" is still
1235 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
1236 // really provide useful results in excluded branches.
1237 par^
1238#endif
1239 }
1240)cpp");
1241
1242 EXPECT_TRUE(Results.Completions.empty());
1243}
1244
1245TEST(CompletionTest, DefaultArgs) {
1246 clangd::CodeCompleteOptions Opts;
1247 std::string Context = R"cpp(
1248 int X(int A = 0);
1249 int Y(int A, int B = 0);
1250 int Z(int A, int B = 0, int C = 0, int D = 0);
1251 )cpp";
1252 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions,
1253 UnorderedElementsAre(labeled("X(int A = 0)")));
1254 EXPECT_THAT(completions(Context + "int y = Y^", {}, Opts).Completions,
1255 UnorderedElementsAre(AllOf(labeled("Y(int A, int B = 0)"),
1256 snippetSuffix("(${1:int A})"))));
1257 EXPECT_THAT(completions(Context + "int y = Z^", {}, Opts).Completions,
1258 UnorderedElementsAre(
1259 AllOf(labeled("Z(int A, int B = 0, int C = 0, int D = 0)"),
1260 snippetSuffix("(${1:int A})"))));
1261}
1262
1263TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) {
1264 auto Completions = completions(R"cpp(
1265template <template <class> class TT> int foo() {
1266 int a = ^
1267}
1268)cpp")
1269 .Completions;
1270 EXPECT_THAT(Completions, Contains(named("TT")));
1271}
1272
1273TEST(CompletionTest, NestedTemplateHeuristics) {
1274 auto Completions = completions(R"cpp(
1275struct Plain { int xxx; };
1276template <typename T> class Templ { Plain ppp; };
1277template <typename T> void foo(Templ<T> &t) {
1278 // Formally ppp has DependentTy, because Templ may be specialized.
1279 // However we sholud be able to see into it using the primary template.
1280 t.ppp.^
1281}
1282)cpp")
1283 .Completions;
1284 EXPECT_THAT(Completions, Contains(named("xxx")));
1285}
1286
1287TEST(CompletionTest, RecordCCResultCallback) {
1288 std::vector<CodeCompletion> RecordedCompletions;
1289 CodeCompleteOptions Opts;
1290 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC,
1291 const SymbolQualitySignals &,
1292 const SymbolRelevanceSignals &,
1293 float Score) {
1294 RecordedCompletions.push_back(CC);
1295 };
1296
1297 completions("int xy1, xy2; int a = xy^", /*IndexSymbols=*/{}, Opts);
1298 EXPECT_THAT(RecordedCompletions,
1299 UnorderedElementsAre(named("xy1"), named("xy2")));
1300}
1301
1302TEST(CompletionTest, ASTSignals) {
1303 struct Completion {
1304 std::string Name;
1305 unsigned MainFileRefs;
1306 unsigned ScopeRefsInFile;
1307 };
1308 CodeCompleteOptions Opts;
1309 std::vector<Completion> RecordedCompletions;
1310 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC,
1311 const SymbolQualitySignals &,
1312 const SymbolRelevanceSignals &R,
1313 float Score) {
1314 RecordedCompletions.push_back({CC.Name, R.MainFileRefs, R.ScopeRefsInFile});
1315 };
1316 ASTSignals MainFileSignals;
1317 MainFileSignals.ReferencedSymbols[var("xy1").ID] = 3;
1318 MainFileSignals.ReferencedSymbols[var("xy2").ID] = 1;
1319 MainFileSignals.ReferencedSymbols[var("xyindex").ID] = 10;
1320 MainFileSignals.RelatedNamespaces["tar::"] = 5;
1321 MainFileSignals.RelatedNamespaces["bar::"] = 3;
1322 Opts.MainFileSignals = &MainFileSignals;
1323 Opts.AllScopes = true;
1324 completions(
1325 R"cpp(
1326 int xy1;
1327 int xy2;
1328 namespace bar {
1329 int xybar = 1;
1330 int a = xy^
1331 }
1332 )cpp",
1333 /*IndexSymbols=*/{var("xyindex"), var("tar::xytar"), var("bar::xybar")},
1334 Opts);
1335 EXPECT_THAT(RecordedCompletions,
1336 UnorderedElementsAre(
1337 AllOf(named("xy1"), mainFileRefs(3u), scopeRefs(0u)),
1338 AllOf(named("xy2"), mainFileRefs(1u), scopeRefs(0u)),
1339 AllOf(named("xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1340 AllOf(named("xytar"), mainFileRefs(0u), scopeRefs(5u)),
1341 AllOf(/*both from sema and index*/ named("xybar"),
1342 mainFileRefs(0u), scopeRefs(3u))));
1343}
1344
1345SignatureHelp
1346signatures(llvm::StringRef Text, Position Point,
1347 std::vector<Symbol> IndexSymbols = {},
1348 MarkupKind DocumentationFormat = MarkupKind::PlainText) {
1349 std::unique_ptr<SymbolIndex> Index;
1350 if (!IndexSymbols.empty())
1351 Index = memIndex(IndexSymbols);
1352
1353 auto TU = TestTU::withCode(Text);
1354 MockFS FS;
1355 auto Inputs = TU.inputs(FS);
1356 Inputs.Index = Index.get();
1357 IgnoreDiagnostics Diags;
1358 auto CI = buildCompilerInvocation(Inputs, Diags);
1359 if (!CI) {
1360 ADD_FAILURE() << "Couldn't build CompilerInvocation";
1361 return {};
1362 }
1363 auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
1364 /*InMemory=*/true, /*Callback=*/nullptr);
1365 if (!Preamble) {
1366 ADD_FAILURE() << "Couldn't build Preamble";
1367 return {};
1368 }
1369 return signatureHelp(testPath(TU.Filename), Point, *Preamble, Inputs,
1370 DocumentationFormat);
1371}
1372
1373SignatureHelp
1374signatures(llvm::StringRef Text, std::vector<Symbol> IndexSymbols = {},
1375 MarkupKind DocumentationFormat = MarkupKind::PlainText) {
1376 Annotations Test(Text);
1377 return signatures(Test.code(), Test.point(), std::move(IndexSymbols),
1378 DocumentationFormat);
1379}
1380
1381struct ExpectedParameter {
1382 std::string Text;
1383 std::pair<unsigned, unsigned> Offsets;
1384};
1385llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1386 const ExpectedParameter &P) {
1387 return OS << P.Text;
1388}
1389MATCHER_P(paramsAre, P, "") {
1390 if (P.size() != arg.parameters.size())
1391 return false;
1392 for (unsigned I = 0; I < P.size(); ++I) {
1393 if (P[I].Text != arg.parameters[I].labelString ||
1394 P[I].Offsets != arg.parameters[I].labelOffsets)
1395 return false;
1396 }
1397 return true;
1398}
1399MATCHER_P(sigDoc, doc, "") { return arg.documentation.value == doc; }
1400
1401/// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g.
1402/// foo([[int p1]], [[double p2]]) -> void
1403Matcher<SignatureInformation> sig(llvm::StringRef AnnotatedLabel) {
1404 llvm::Annotations A(AnnotatedLabel);
1405 std::string Label = std::string(A.code());
1406 std::vector<ExpectedParameter> Parameters;
1407 for (auto Range : A.ranges()) {
1408 Parameters.emplace_back();
1409
1410 ExpectedParameter &P = Parameters.back();
1411 P.Text = Label.substr(Range.Begin, Range.End - Range.Begin);
1412 P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin));
1413 P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End));
1414 }
1415 return AllOf(sigHelpLabeled(Label), paramsAre(Parameters));
1416}
1417
1418TEST(SignatureHelpTest, Overloads) {
1419 auto Results = signatures(R"cpp(
1420 void foo(int x, int y);
1421 void foo(int x, float y);
1422 void foo(float x, int y);
1423 void foo(float x, float y);
1424 void bar(int x, int y = 0);
1425 int main() { foo(^); }
1426 )cpp");
1427 EXPECT_THAT(Results.signatures,
1428 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1429 sig("foo([[float x]], [[int y]]) -> void"),
1430 sig("foo([[int x]], [[float y]]) -> void"),
1431 sig("foo([[int x]], [[int y]]) -> void")));
1432 // We always prefer the first signature.
1433 EXPECT_EQ(0, Results.activeSignature);
1434 EXPECT_EQ(0, Results.activeParameter);
1435}
1436
1437TEST(SignatureHelpTest, FunctionPointers) {
1438 llvm::StringLiteral Tests[] = {
1439 // Variable of function pointer type
1440 R"cpp(
1441 void (*foo)(int x, int y);
1442 int main() { foo(^); }
1443 )cpp",
1444 // Wrapped in an AttributedType
1445 R"cpp(
1446 void (__stdcall *foo)(int x, int y);
1447 int main() { foo(^); }
1448 )cpp",
1449 // Another syntax for an AttributedType
1450 R"cpp(
1451 void (__attribute__(stdcall) *foo)(int x, int y);
1452 int main() { foo(^); },
1453 )cpp",
1454 // Wrapped in a typedef
1455 R"cpp(
1456 typedef void (*fn)(int x, int y);
1457 fn foo;
1458 int main() { foo(^); }
1459 )cpp",
1460 // Wrapped in both a typedef and an AttributedTyped
1461 R"cpp(
1462 typedef void (__stdcall *fn)(int x, int y);
1463 fn foo;
1464 int main() { foo(^); }
1465 )cpp"};
1466 for (auto Test : Tests)
1467 EXPECT_THAT(signatures(Test).signatures,
1468 UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1469}
1470
1471TEST(SignatureHelpTest, Constructors) {
1472 std::string Top = R"cpp(
1473 struct S {
1474 S(int);
1475 S(const S &) = delete;
1476 };
1477 )cpp";
1478
1479 auto CheckParenInit = [&](std::string Init) {
1480 EXPECT_THAT(signatures(Top + Init).signatures,
1481 UnorderedElementsAre(sig("S([[int]])")))
1482 << Init;
1483 };
1484 CheckParenInit("S s(^);");
1485 CheckParenInit("auto s = S(^);");
1486 CheckParenInit("auto s = new S(^);");
1487
1488 auto CheckBracedInit = [&](std::string Init) {
1489 EXPECT_THAT(signatures(Top + Init).signatures,
1490 UnorderedElementsAre(sig("S{[[int]]}")))
1491 << Init;
1492 };
1493 CheckBracedInit("S s{^};");
1494 CheckBracedInit("S s = {^};");
1495 CheckBracedInit("auto s = S{^};");
1496 // FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression.
1497 // CheckBracedInit("auto s = new S{^};");
1498 CheckBracedInit("int x(S); int i = x({^});");
1499}
1500
1501TEST(SignatureHelpTest, Aggregates) {
1502 std::string Top = R"cpp(
1503 struct S {
1504 int a, b, c, d;
1505 };
1506 )cpp";
1507 auto AggregateSig = sig("S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1508 EXPECT_THAT(signatures(Top + "S s{^}").signatures,
1509 UnorderedElementsAre(AggregateSig, sig("S{}"),
1510 sig("S{[[const S &]]}"),
1511 sig("S{[[S &&]]}")));
1512 EXPECT_THAT(signatures(Top + "S s{1,^}").signatures,
1513 ElementsAre(AggregateSig));
1514 EXPECT_EQ(signatures(Top + "S s{1,^}").activeParameter, 1);
1515 EXPECT_THAT(signatures(Top + "S s{.c=3,^}").signatures,
1516 ElementsAre(AggregateSig));
1517 EXPECT_EQ(signatures(Top + "S s{.c=3,^}").activeParameter, 3);
1518}
1519
1520TEST(SignatureHelpTest, OverloadInitListRegression) {
1521 auto Results = signatures(R"cpp(
1522 struct A {int x;};
1523 struct B {B(A);};
1524 void f();
1525 int main() {
1526 B b({1});
1527 f(^);
1528 }
1529 )cpp");
1530 EXPECT_THAT(Results.signatures, UnorderedElementsAre(sig("f() -> void")));
1531}
1532
1533TEST(SignatureHelpTest, DefaultArgs) {
1534 auto Results = signatures(R"cpp(
1535 void bar(int x, int y = 0);
1536 void bar(float x = 0, int y = 42);
1537 int main() { bar(^
1538 )cpp");
1539 EXPECT_THAT(Results.signatures,
1540 UnorderedElementsAre(
1541 sig("bar([[int x]], [[int y = 0]]) -> void"),
1542 sig("bar([[float x = 0]], [[int y = 42]]) -> void")));
1543 EXPECT_EQ(0, Results.activeSignature);
1544 EXPECT_EQ(0, Results.activeParameter);
1545}
1546
1547TEST(SignatureHelpTest, ActiveArg) {
1548 auto Results = signatures(R"cpp(
1549 int baz(int a, int b, int c);
1550 int main() { baz(baz(1,2,3), ^); }
1551 )cpp");
1552 EXPECT_THAT(Results.signatures,
1553 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1554 EXPECT_EQ(0, Results.activeSignature);
1555 EXPECT_EQ(1, Results.activeParameter);
1556}
1557
1558TEST(SignatureHelpTest, OpeningParen) {
1559 llvm::StringLiteral Tests[] = {
1560 // Recursive function call.
1561 R"cpp(
1562 int foo(int a, int b, int c);
1563 int main() {
1564 foo(foo $p^( foo(10, 10, 10), ^ )));
1565 })cpp",
1566 // Functional type cast.
1567 R"cpp(
1568 struct Foo {
1569 Foo(int a, int b, int c);
1570 };
1571 int main() {
1572 Foo $p^( 10, ^ );
1573 })cpp",
1574 // New expression.
1575 R"cpp(
1576 struct Foo {
1577 Foo(int a, int b, int c);
1578 };
1579 int main() {
1580 new Foo $p^( 10, ^ );
1581 })cpp",
1582 // Macro expansion.
1583 R"cpp(
1584 int foo(int a, int b, int c);
1585 #define FOO foo(
1586
1587 int main() {
1588 // Macro expansions.
1589 $p^FOO 10, ^ );
1590 })cpp",
1591 // Macro arguments.
1592 R"cpp(
1593 int foo(int a, int b, int c);
1594 int main() {
1595 #define ID(X) X
1596 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1597 // the recovery expression.
1598 ID(foo $p^( 10, ^ ))
1599 })cpp",
1600 // Dependent args.
1601 R"cpp(
1602 int foo(int a, int b);
1603 template <typename T> void bar(T t) {
1604 foo$p^(t, ^t);
1605 })cpp",
1606 // Dependent args on templated func.
1607 R"cpp(
1608 template <typename T>
1609 int foo(T, T);
1610 template <typename T> void bar(T t) {
1611 foo$p^(t, ^t);
1612 })cpp",
1613 // Dependent args on member.
1614 R"cpp(
1615 struct Foo { int foo(int, int); };
1616 template <typename T> void bar(T t) {
1617 Foo f;
1618 f.foo$p^(t, ^t);
1619 })cpp",
1620 // Dependent args on templated member.
1621 R"cpp(
1622 struct Foo { template <typename T> int foo(T, T); };
1623 template <typename T> void bar(T t) {
1624 Foo f;
1625 f.foo$p^(t, ^t);
1626 })cpp",
1627 };
1628
1629 for (auto Test : Tests) {
1630 Annotations Code(Test);
1631 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
1632 Code.point("p"))
1633 << "Test source:" << Test;
1634 }
1635}
1636
1637TEST(SignatureHelpTest, StalePreamble) {
1638 TestTU TU;
1639 TU.Code = "";
1640 IgnoreDiagnostics Diags;
1641 MockFS FS;
1642 auto Inputs = TU.inputs(FS);
1643 auto CI = buildCompilerInvocation(Inputs, Diags);
1644 ASSERT_TRUE(CI);
1645 auto EmptyPreamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
1646 /*InMemory=*/true, /*Callback=*/nullptr);
1647 ASSERT_TRUE(EmptyPreamble);
1648
1649 TU.AdditionalFiles["a.h"] = "int foo(int x);";
1650 const Annotations Test(R"cpp(
1651 #include "a.h"
1652 void bar() { foo(^2); })cpp");
1653 TU.Code = Test.code().str();
1654 auto Results =
1655 signatureHelp(testPath(TU.Filename), Test.point(), *EmptyPreamble,
1656 TU.inputs(FS), MarkupKind::PlainText);
1657 EXPECT_THAT(Results.signatures, ElementsAre(sig("foo([[int x]]) -> int")));
1658 EXPECT_EQ(0, Results.activeSignature);
1659 EXPECT_EQ(0, Results.activeParameter);
1660}
1661
1662class IndexRequestCollector : public SymbolIndex {
1663public:
1664 IndexRequestCollector(std::vector<Symbol> Syms = {}) : Symbols(Syms) {}
1665
1666 bool
1667 fuzzyFind(const FuzzyFindRequest &Req,
1668 llvm::function_ref<void(const Symbol &)> Callback) const override {
1669 std::unique_lock<std::mutex> Lock(Mut);
1670 Requests.push_back(Req);
1671 ReceivedRequestCV.notify_one();
1672 for (const auto &Sym : Symbols)
1673 Callback(Sym);
1674 return true;
1675 }
1676
1677 void lookup(const LookupRequest &,
1678 llvm::function_ref<void(const Symbol &)>) const override {}
1679
1680 bool refs(const RefsRequest &,
1681 llvm::function_ref<void(const Ref &)>) const override {
1682 return false;
1683 }
1684
1685 void relations(const RelationsRequest &,
1686 llvm::function_ref<void(const SymbolID &, const Symbol &)>)
1687 const override {}
1688
1689 llvm::unique_function<IndexContents(llvm::StringRef) const>
1690 indexedFiles() const override {
1691 return [](llvm::StringRef) { return IndexContents::None; };
1692 }
1693
1694 // This is incorrect, but IndexRequestCollector is not an actual index and it
1695 // isn't used in production code.
1696 size_t estimateMemoryUsage() const override { return 0; }
1697
1698 const std::vector<FuzzyFindRequest> consumeRequests(size_t Num) const {
1699 std::unique_lock<std::mutex> Lock(Mut);
1700 EXPECT_TRUE(wait(Lock, ReceivedRequestCV, timeoutSeconds(30),
1701 [this, Num] { return Requests.size() == Num; }));
1702 auto Reqs = std::move(Requests);
1703 Requests = {};
1704 return Reqs;
1705 }
1706
1707private:
1708 std::vector<Symbol> Symbols;
1709 // We need a mutex to handle async fuzzy find requests.
1710 mutable std::condition_variable ReceivedRequestCV;
1711 mutable std::mutex Mut;
1712 mutable std::vector<FuzzyFindRequest> Requests;
1713};
1714
1715// Clients have to consume exactly Num requests.
1716std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code,
1717 size_t Num = 1) {
1718 clangd::CodeCompleteOptions Opts;
1719 IndexRequestCollector Requests;
1720 Opts.Index = &Requests;
1721 completions(Code, {}, Opts);
1722 const auto Reqs = Requests.consumeRequests(Num);
1723 EXPECT_EQ(Reqs.size(), Num);
1724 return Reqs;
1725}
1726
1727TEST(CompletionTest, UnqualifiedIdQuery) {
1728 auto Requests = captureIndexRequests(R"cpp(
1729 namespace std {}
1730 using namespace std;
1731 namespace ns {
1732 void f() {
1733 vec^
1734 }
1735 }
1736 )cpp");
1737
1738 EXPECT_THAT(Requests,
1739 ElementsAre(Field(&FuzzyFindRequest::Scopes,
1740 UnorderedElementsAre("", "ns::", "std::"))));
1741}
1742
1743TEST(CompletionTest, EnclosingScopeComesFirst) {
1744 auto Requests = captureIndexRequests(R"cpp(
1745 namespace std {}
1746 using namespace std;
1747 namespace nx {
1748 namespace ns {
1749 namespace {
1750 void f() {
1751 vec^
1752 }
1753 }
1754 }
1755 }
1756 )cpp");
1757
1758 EXPECT_THAT(Requests,
1759 ElementsAre(Field(
1761 UnorderedElementsAre("", "std::", "nx::ns::", "nx::"))));
1762 EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::");
1763}
1764
1765TEST(CompletionTest, ResolvedQualifiedIdQuery) {
1766 auto Requests = captureIndexRequests(R"cpp(
1767 namespace ns1 {}
1768 namespace ns2 {} // ignore
1769 namespace ns3 { namespace nns3 {} }
1770 namespace foo {
1771 using namespace ns1;
1772 using namespace ns3::nns3;
1773 }
1774 namespace ns {
1775 void f() {
1776 foo::^
1777 }
1778 }
1779 )cpp");
1780
1781 EXPECT_THAT(Requests,
1782 ElementsAre(Field(
1784 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::"))));
1785}
1786
1787TEST(CompletionTest, UnresolvedQualifierIdQuery) {
1788 auto Requests = captureIndexRequests(R"cpp(
1789 namespace a {}
1790 using namespace a;
1791 namespace ns {
1792 void f() {
1793 bar::^
1794 }
1795 } // namespace ns
1796 )cpp");
1797
1798 EXPECT_THAT(Requests,
1799 ElementsAre(Field(
1801 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
1802}
1803
1804TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
1805 auto Requests = captureIndexRequests(R"cpp(
1806 namespace a {}
1807 using namespace a;
1808 namespace ns {
1809 void f() {
1810 ::a::bar::^
1811 }
1812 } // namespace ns
1813 )cpp");
1814
1815 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1816 UnorderedElementsAre("a::bar::"))));
1817}
1818
1819TEST(CompletionTest, EmptyQualifiedQuery) {
1820 auto Requests = captureIndexRequests(R"cpp(
1821 namespace ns {
1822 void f() {
1823 ^
1824 }
1825 } // namespace ns
1826 )cpp");
1827
1828 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1829 UnorderedElementsAre("", "ns::"))));
1830}
1831
1832TEST(CompletionTest, GlobalQualifiedQuery) {
1833 auto Requests = captureIndexRequests(R"cpp(
1834 namespace ns {
1835 void f() {
1836 ::^
1837 }
1838 } // namespace ns
1839 )cpp");
1840
1841 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1842 UnorderedElementsAre(""))));
1843}
1844
1845TEST(CompletionTest, NoDuplicatedQueryScopes) {
1846 auto Requests = captureIndexRequests(R"cpp(
1847 namespace {}
1848
1849 namespace na {
1850 namespace {}
1851 namespace nb {
1852 ^
1853 } // namespace nb
1854 } // namespace na
1855 )cpp");
1856
1857 EXPECT_THAT(Requests,
1858 ElementsAre(Field(&FuzzyFindRequest::Scopes,
1859 UnorderedElementsAre("na::", "na::nb::", ""))));
1860}
1861
1862TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
1863 auto Completions = completions(
1864 R"cpp(
1865 struct Foo {
1866 int SomeNameOfField;
1867 typedef int SomeNameOfTypedefField;
1868 };
1869
1870 Foo::^)cpp",
1871 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
1872
1873 EXPECT_THAT(Completions.Completions,
1874 AllOf(Contains(labeled("SomeNameOfField")),
1875 Contains(labeled("SomeNameOfTypedefField")),
1876 Not(Contains(labeled("SomeNameInTheIndex")))));
1877}
1878
1879TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
1880 {
1881 auto Completions = completions(
1882 R"cpp(
1883 template <class T>
1884 void foo() {
1885 T::^
1886 }
1887 )cpp",
1888 {func("::SomeNameInTheIndex")});
1889
1890 EXPECT_THAT(Completions.Completions,
1891 Not(Contains(labeled("SomeNameInTheIndex"))));
1892 }
1893
1894 {
1895 auto Completions = completions(
1896 R"cpp(
1897 template <class T>
1898 void foo() {
1899 T::template Y<int>::^
1900 }
1901 )cpp",
1902 {func("::SomeNameInTheIndex")});
1903
1904 EXPECT_THAT(Completions.Completions,
1905 Not(Contains(labeled("SomeNameInTheIndex"))));
1906 }
1907
1908 {
1909 auto Completions = completions(
1910 R"cpp(
1911 template <class T>
1912 void foo() {
1913 T::foo::^
1914 }
1915 )cpp",
1916 {func("::SomeNameInTheIndex")});
1917
1918 EXPECT_THAT(Completions.Completions,
1919 Not(Contains(labeled("SomeNameInTheIndex"))));
1920 }
1921}
1922
1923TEST(CompletionTest, OverloadBundling) {
1924 clangd::CodeCompleteOptions Opts;
1925 Opts.BundleOverloads = true;
1926
1927 std::string Context = R"cpp(
1928 struct X {
1929 // Overload with int
1930 int a(int) __attribute__((deprecated("", "")));
1931 // Overload with bool
1932 int a(bool);
1933 int b(float);
1934
1935 X(int);
1936 X(float);
1937 };
1938 int GFuncC(int);
1939 int GFuncD(int);
1940 )cpp";
1941
1942 // Member completions are bundled.
1943 EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions,
1944 UnorderedElementsAre(labeled("a(…)"), labeled("b(float)")));
1945
1946 // Constructor completions are bundled.
1947 EXPECT_THAT(completions(Context + "X z = X^", {}, Opts).Completions,
1948 UnorderedElementsAre(labeled("X"), labeled("X(…)")));
1949
1950 // Non-member completions are bundled, including index+sema.
1951 Symbol NoArgsGFunc = func("GFuncC");
1952 EXPECT_THAT(
1953 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1954 UnorderedElementsAre(labeled("GFuncC(…)"), labeled("GFuncD(int)")));
1955
1956 // Differences in header-to-insert suppress bundling.
1957 std::string DeclFile = URI::create(testPath("foo")).toString();
1958 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
1959 NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1, Symbol::Include);
1960 EXPECT_THAT(
1961 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1962 UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")),
1963 labeled("GFuncC(int)"), labeled("GFuncD(int)")));
1964
1965 // Examine a bundled completion in detail.
1966 auto A =
1967 completions(Context + "int y = X().a^", {}, Opts).Completions.front();
1968 EXPECT_EQ(A.Name, "a");
1969 EXPECT_EQ(A.Signature, "(…)");
1970 EXPECT_EQ(A.BundleSize, 2u);
1971 EXPECT_EQ(A.Kind, CompletionItemKind::Method);
1972 EXPECT_EQ(A.ReturnType, "int"); // All overloads return int.
1973 // For now we just return one of the doc strings arbitrarily.
1974 ASSERT_TRUE(A.Documentation);
1975 ASSERT_FALSE(A.Deprecated); // Not all overloads deprecated.
1976 EXPECT_THAT(
1977 A.Documentation->asPlainText(),
1978 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool")));
1979 EXPECT_EQ(A.SnippetSuffix, "($0)");
1980}
1981
1982TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
1983 clangd::CodeCompleteOptions Opts;
1984 Opts.BundleOverloads = true;
1985
1986 Symbol SymX = sym("ns::X", index::SymbolKind::Function, "@F@\\0#");
1987 Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#");
1988 std::string BarHeader = testPath("bar.h");
1989 auto BarURI = URI::create(BarHeader).toString();
1990 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
1991 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
1992 // The include header is different, but really it's the same file.
1993 SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1, Symbol::Include);
1994 SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1, Symbol::Include);
1995
1996 auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts);
1997 // Expect both results are bundled, despite the different-but-same
1998 // IncludeHeader.
1999 ASSERT_EQ(1u, Results.Completions.size());
2000 const auto &R = Results.Completions.front();
2001 EXPECT_EQ("X", R.Name);
2002 EXPECT_EQ(2u, R.BundleSize);
2003}
2004
2005TEST(CompletionTest, DocumentationFromChangedFileCrash) {
2006 MockFS FS;
2007 auto FooH = testPath("foo.h");
2008 auto FooCpp = testPath("foo.cpp");
2009 FS.Files[FooH] = R"cpp(
2010 // this is my documentation comment.
2011 int func();
2012 )cpp";
2013 FS.Files[FooCpp] = "";
2014
2015 MockCompilationDatabase CDB;
2016 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2017
2018 Annotations Source(R"cpp(
2019 #include "foo.h"
2020 int func() {
2021 // This makes sure we have func from header in the AST.
2022 }
2023 int a = fun^
2024 )cpp");
2025 Server.addDocument(FooCpp, Source.code(), "null", WantDiagnostics::Yes);
2026 // We need to wait for preamble to build.
2027 ASSERT_TRUE(Server.blockUntilIdleForTest());
2028
2029 // Change the header file. Completion will reuse the old preamble!
2030 FS.Files[FooH] = R"cpp(
2031 int func();
2032 )cpp";
2033
2034 clangd::CodeCompleteOptions Opts;
2035 CodeCompleteResult Completions =
2036 cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts));
2037 // We shouldn't crash. Unfortunately, current workaround is to not produce
2038 // comments for symbols from headers.
2039 EXPECT_THAT(Completions.Completions,
2040 Contains(AllOf(Not(isDocumented()), named("func"))));
2041}
2042
2043TEST(CompletionTest, NonDocComments) {
2044 const char *Text = R"cpp(
2045 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
2046 namespace comments_ns {
2047 }
2048
2049 // ------------------
2050 int comments_foo();
2051
2052 // A comment and a decl are separated by newlines.
2053 // Therefore, the comment shouldn't show up as doc comment.
2054
2055 int comments_bar();
2056
2057 // this comment should be in the results.
2058 int comments_baz();
2059
2060
2061 template <class T>
2062 struct Struct {
2063 int comments_qux();
2064 int comments_quux();
2065 };
2066
2067
2068 // This comment should not be there.
2069
2070 template <class T>
2071 int Struct<T>::comments_qux() {
2072 }
2073
2074 // This comment **should** be in results.
2075 template <class T>
2076 int Struct<T>::comments_quux() {
2077 int a = comments^;
2078 }
2079 )cpp";
2080
2081 // We should not get any of those comments in completion.
2082 EXPECT_THAT(
2083 completions(Text).Completions,
2084 UnorderedElementsAre(AllOf(Not(isDocumented()), named("comments_foo")),
2085 AllOf(isDocumented(), named("comments_baz")),
2086 AllOf(isDocumented(), named("comments_quux")),
2087 AllOf(Not(isDocumented()), named("comments_ns")),
2088 // FIXME(ibiryukov): the following items should have
2089 // empty documentation, since they are separated from
2090 // a comment with an empty line. Unfortunately, I
2091 // couldn't make Sema tests pass if we ignore those.
2092 AllOf(isDocumented(), named("comments_bar")),
2093 AllOf(isDocumented(), named("comments_qux"))));
2094}
2095
2096TEST(CompletionTest, CompleteOnInvalidLine) {
2097 auto FooCpp = testPath("foo.cpp");
2098
2099 MockCompilationDatabase CDB;
2100 MockFS FS;
2101 FS.Files[FooCpp] = "// empty file";
2102
2103 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2104 // Run completion outside the file range.
2105 Position Pos;
2106 Pos.line = 100;
2107 Pos.character = 0;
2108 EXPECT_THAT_EXPECTED(
2109 runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()),
2110 Failed());
2111}
2112
2113TEST(CompletionTest, QualifiedNames) {
2114 auto Results = completions(
2115 R"cpp(
2116 namespace ns { int local; void both(); }
2117 void f() { ::ns::^ }
2118 )cpp",
2119 {func("ns::both"), cls("ns::Index")});
2120 // We get results from both index and sema, with no duplicates.
2121 EXPECT_THAT(
2122 Results.Completions,
2123 UnorderedElementsAre(scope("ns::"), scope("ns::"), scope("ns::")));
2124}
2125
2126TEST(CompletionTest, Render) {
2127 CodeCompletion C;
2128 C.Name = "x";
2129 C.FilterText = "x";
2130 C.Signature = "(bool) const";
2131 C.SnippetSuffix = "(${0:bool})";
2132 C.ReturnType = "int";
2133 C.RequiredQualifier = "Foo::";
2134 C.Scope = "ns::Foo::";
2135 C.Documentation.emplace();
2136 C.Documentation->addParagraph().appendText("This is ").appendCode("x()");
2137 C.Includes.emplace_back();
2138 auto &Include = C.Includes.back();
2139 Include.Header = "\"foo.h\"";
2141 C.Score.Total = 1.0;
2142 C.Score.ExcludingName = .5;
2144
2145 CodeCompleteOptions Opts;
2146 Opts.IncludeIndicator.Insert = "^";
2147 Opts.IncludeIndicator.NoInsert = "";
2148 Opts.EnableSnippets = false;
2149
2150 auto R = C.render(Opts);
2151 EXPECT_EQ(R.label, "Foo::x");
2152 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2153 EXPECT_EQ(R.insertText, "Foo::x");
2154 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText);
2155 EXPECT_EQ(R.filterText, "x");
2156 EXPECT_EQ(R.detail, "int");
2157 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()");
2158 EXPECT_THAT(R.additionalTextEdits, IsEmpty());
2159 EXPECT_EQ(R.sortText, sortText(1.0, "x"));
2160 EXPECT_FALSE(R.deprecated);
2161 EXPECT_EQ(R.score, .5f);
2162
2163 C.FilterText = "xtra";
2164 R = C.render(Opts);
2165 EXPECT_EQ(R.filterText, "xtra");
2166 EXPECT_EQ(R.sortText, sortText(1.0, "xtra"));
2167
2168 Opts.EnableSnippets = true;
2169 R = C.render(Opts);
2170 EXPECT_EQ(R.insertText, "Foo::x(${0:bool})");
2171 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
2172
2173 C.SnippetSuffix = "";
2174 R = C.render(Opts);
2175 EXPECT_EQ(R.insertText, "Foo::x");
2176 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText);
2177
2178 Include.Insertion.emplace();
2179 R = C.render(Opts);
2180 EXPECT_EQ(R.label, "^Foo::x");
2181 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2182 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
2183
2184 Opts.ShowOrigins = true;
2185 R = C.render(Opts);
2186 EXPECT_EQ(R.label, "^[AS]Foo::x");
2187 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2188
2189 C.BundleSize = 2;
2190 R = C.render(Opts);
2191 EXPECT_EQ(R.detail, "[2 overloads]");
2192 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()");
2193
2194 C.Deprecated = true;
2195 R = C.render(Opts);
2196 EXPECT_TRUE(R.deprecated);
2197
2199 R = C.render(Opts);
2200 EXPECT_EQ(R.documentation->value, "From `\"foo.h\"` \nThis is `x()`");
2201}
2202
2203TEST(CompletionTest, IgnoreRecoveryResults) {
2204 auto Results = completions(
2205 R"cpp(
2206 namespace ns { int NotRecovered() { return 0; } }
2207 void f() {
2208 // Sema enters recovery mode first and then normal mode.
2209 if (auto x = ns::NotRecover^)
2210 }
2211 )cpp");
2212 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("NotRecovered")));
2213}
2214
2215TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
2216 auto Results = completions(
2217 R"cpp(
2218 namespace ns {
2219 class X { public: X(); int x_; };
2220 X::X() : x_^(0) {}
2221 }
2222 )cpp");
2223 EXPECT_THAT(Results.Completions,
2224 UnorderedElementsAre(AllOf(scope("ns::X::"), named("x_"))));
2225}
2226
2227// Like other class members, constructor init lists have to parse what's below,
2228// after the completion point.
2229// But recovering from an incomplete constructor init list is particularly
2230// tricky because the bulk of the list is not surrounded by brackets.
2231TEST(CompletionTest, ConstructorInitListIncomplete) {
2232 auto Results = completions(
2233 R"cpp(
2234 namespace ns {
2235 struct X {
2236 X() : x^
2237 int xyz_;
2238 };
2239 }
2240 )cpp");
2241 EXPECT_THAT(Results.Completions, ElementsAre(named("xyz_")));
2242
2243 Results = completions(
2244 R"cpp(
2245 int foo();
2246
2247 namespace ns {
2248 struct X {
2249 X() : xyz_(fo^
2250 int xyz_;
2251 };
2252 }
2253 )cpp");
2254 EXPECT_THAT(Results.Completions, ElementsAre(named("foo")));
2255}
2256
2257TEST(CompletionTest, CodeCompletionContext) {
2258 auto Results = completions(
2259 R"cpp(
2260 namespace ns {
2261 class X { public: X(); int x_; };
2262 void f() {
2263 X x;
2264 x.^;
2265 }
2266 }
2267 )cpp");
2268
2269 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
2270}
2271
2272TEST(CompletionTest, FixItForArrowToDot) {
2273 MockFS FS;
2274 MockCompilationDatabase CDB;
2275
2276 CodeCompleteOptions Opts;
2277 Opts.IncludeFixIts = true;
2278 const char *Code =
2279 R"cpp(
2280 class Auxilary {
2281 public:
2282 void AuxFunction();
2283 };
2284 class ClassWithPtr {
2285 public:
2286 void MemberFunction();
2287 Auxilary* operator->() const;
2288 Auxilary* Aux;
2289 };
2290 void f() {
2291 ClassWithPtr x;
2292 x[[->]]^;
2293 }
2294 )cpp";
2295 auto Results = completions(Code, {}, Opts);
2296 EXPECT_EQ(Results.Completions.size(), 3u);
2297
2298 TextEdit ReplacementEdit;
2299 ReplacementEdit.range = Annotations(Code).range();
2300 ReplacementEdit.newText = ".";
2301 for (const auto &C : Results.Completions) {
2302 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction");
2303 if (!C.FixIts.empty()) {
2304 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
2305 }
2306 }
2307}
2308
2309TEST(CompletionTest, FixItForDotToArrow) {
2310 CodeCompleteOptions Opts;
2311 Opts.IncludeFixIts = true;
2312 const char *Code =
2313 R"cpp(
2314 class Auxilary {
2315 public:
2316 void AuxFunction();
2317 };
2318 class ClassWithPtr {
2319 public:
2320 void MemberFunction();
2321 Auxilary* operator->() const;
2322 Auxilary* Aux;
2323 };
2324 void f() {
2325 ClassWithPtr x;
2326 x[[.]]^;
2327 }
2328 )cpp";
2329 auto Results = completions(Code, {}, Opts);
2330 EXPECT_EQ(Results.Completions.size(), 3u);
2331
2332 TextEdit ReplacementEdit;
2333 ReplacementEdit.range = Annotations(Code).range();
2334 ReplacementEdit.newText = "->";
2335 for (const auto &C : Results.Completions) {
2336 EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction");
2337 if (!C.FixIts.empty()) {
2338 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
2339 }
2340 }
2341}
2342
2343TEST(CompletionTest, RenderWithFixItMerged) {
2344 TextEdit FixIt;
2345 FixIt.range.end.character = 5;
2346 FixIt.newText = "->";
2347
2348 CodeCompletion C;
2349 C.Name = "x";
2350 C.RequiredQualifier = "Foo::";
2351 C.FixIts = {FixIt};
2352 C.CompletionTokenRange.start.character = 5;
2353
2354 CodeCompleteOptions Opts;
2355 Opts.IncludeFixIts = true;
2356
2357 auto R = C.render(Opts);
2358 EXPECT_TRUE(R.textEdit);
2359 EXPECT_EQ(R.textEdit->newText, "->Foo::x");
2360 EXPECT_TRUE(R.additionalTextEdits.empty());
2361}
2362
2363TEST(CompletionTest, RenderWithFixItNonMerged) {
2364 TextEdit FixIt;
2365 FixIt.range.end.character = 4;
2366 FixIt.newText = "->";
2367
2368 CodeCompletion C;
2369 C.Name = "x";
2370 C.RequiredQualifier = "Foo::";
2371 C.FixIts = {FixIt};
2372 C.CompletionTokenRange.start.character = 5;
2373
2374 CodeCompleteOptions Opts;
2375 Opts.IncludeFixIts = true;
2376
2377 auto R = C.render(Opts);
2378 EXPECT_TRUE(R.textEdit);
2379 EXPECT_EQ(R.textEdit->newText, "Foo::x");
2380 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt));
2381}
2382
2383TEST(CompletionTest, CompletionTokenRange) {
2384 MockFS FS;
2385 MockCompilationDatabase CDB;
2386 TestTU TU;
2387 TU.AdditionalFiles["foo/abc/foo.h"] = "";
2388
2389 constexpr const char *TestCodes[] = {
2390 R"cpp(
2391 class Auxilary {
2392 public:
2393 void AuxFunction();
2394 };
2395 void f() {
2396 Auxilary x;
2397 x.[[Aux]]^;
2398 }
2399 )cpp",
2400 R"cpp(
2401 class Auxilary {
2402 public:
2403 void AuxFunction();
2404 };
2405 void f() {
2406 Auxilary x;
2407 x.[[]]^;
2408 }
2409 )cpp",
2410 R"cpp(
2411 #include "foo/[[a^/]]foo.h"
2412 )cpp",
2413 R"cpp(
2414 #include "foo/abc/[[fo^o.h"]]
2415 )cpp",
2416 };
2417 for (const auto &Text : TestCodes) {
2418 Annotations TestCode(Text);
2419 TU.Code = TestCode.code().str();
2420 auto Results = completions(TU, TestCode.point());
2421 if (Results.Completions.size() != 1) {
2422 ADD_FAILURE() << "Results.Completions.size() != 1" << Text;
2423 continue;
2424 }
2425 EXPECT_THAT(Results.Completions.front().CompletionTokenRange,
2426 TestCode.range());
2427 }
2428}
2429
2430TEST(SignatureHelpTest, OverloadsOrdering) {
2431 const auto Results = signatures(R"cpp(
2432 void foo(int x);
2433 void foo(int x, float y);
2434 void foo(float x, int y);
2435 void foo(float x, float y);
2436 void foo(int x, int y = 0);
2437 int main() { foo(^); }
2438 )cpp");
2439 EXPECT_THAT(Results.signatures,
2440 ElementsAre(sig("foo([[int x]]) -> void"),
2441 sig("foo([[int x]], [[int y = 0]]) -> void"),
2442 sig("foo([[float x]], [[int y]]) -> void"),
2443 sig("foo([[int x]], [[float y]]) -> void"),
2444 sig("foo([[float x]], [[float y]]) -> void")));
2445 // We always prefer the first signature.
2446 EXPECT_EQ(0, Results.activeSignature);
2447 EXPECT_EQ(0, Results.activeParameter);
2448}
2449
2450TEST(SignatureHelpTest, InstantiatedSignatures) {
2451 StringRef Sig0 = R"cpp(
2452 template <class T>
2453 void foo(T, T, T);
2454
2455 int main() {
2456 foo<int>(^);
2457 }
2458 )cpp";
2459
2460 EXPECT_THAT(signatures(Sig0).signatures,
2461 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2462
2463 StringRef Sig1 = R"cpp(
2464 template <class T>
2465 void foo(T, T, T);
2466
2467 int main() {
2468 foo(10, ^);
2469 })cpp";
2470
2471 EXPECT_THAT(signatures(Sig1).signatures,
2472 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2473
2474 StringRef Sig2 = R"cpp(
2475 template <class ...T>
2476 void foo(T...);
2477
2478 int main() {
2479 foo<int>(^);
2480 }
2481 )cpp";
2482
2483 EXPECT_THAT(signatures(Sig2).signatures,
2484 ElementsAre(sig("foo([[T...]]) -> void")));
2485
2486 // It is debatable whether we should substitute the outer template parameter
2487 // ('T') in that case. Currently we don't substitute it in signature help, but
2488 // do substitute in code complete.
2489 // FIXME: make code complete and signature help consistent, figure out which
2490 // way is better.
2491 StringRef Sig3 = R"cpp(
2492 template <class T>
2493 struct X {
2494 template <class U>
2495 void foo(T, U);
2496 };
2497
2498 int main() {
2499 X<int>().foo<double>(^)
2500 }
2501 )cpp";
2502
2503 EXPECT_THAT(signatures(Sig3).signatures,
2504 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2505}
2506
2507TEST(SignatureHelpTest, IndexDocumentation) {
2508 Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#");
2509 Foo0.Documentation = "doc from the index";
2510 Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#");
2511 Foo1.Documentation = "doc from the index";
2512 Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#");
2513
2514 StringRef Sig0 = R"cpp(
2515 int foo();
2516 int foo(double);
2517
2518 void test() {
2519 foo(^);
2520 }
2521 )cpp";
2522
2523 EXPECT_THAT(
2524 signatures(Sig0, {Foo0}).signatures,
2525 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2526 AllOf(sig("foo([[double]]) -> int"), sigDoc(""))));
2527
2528 StringRef Sig1 = R"cpp(
2529 int foo();
2530 // Overriden doc from sema
2531 int foo(int);
2532 // doc from sema
2533 int foo(int, int);
2534
2535 void test() {
2536 foo(^);
2537 }
2538 )cpp";
2539
2540 EXPECT_THAT(
2541 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
2542 ElementsAre(
2543 AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2544 AllOf(sig("foo([[int]]) -> int"), sigDoc("Overriden doc from sema")),
2545 AllOf(sig("foo([[int]], [[int]]) -> int"), sigDoc("doc from sema"))));
2546}
2547
2548TEST(SignatureHelpTest, DynamicIndexDocumentation) {
2549 MockFS FS;
2550 MockCompilationDatabase CDB;
2551 ClangdServer::Options Opts = ClangdServer::optsForTest();
2552 Opts.BuildDynamicSymbolIndex = true;
2553 ClangdServer Server(CDB, FS, Opts);
2554
2555 FS.Files[testPath("foo.h")] = R"cpp(
2556 struct Foo {
2557 // Member doc
2558 int foo();
2559 };
2560 )cpp";
2561 Annotations FileContent(R"cpp(
2562 #include "foo.h"
2563 void test() {
2564 Foo f;
2565 f.foo(^);
2566 }
2567 )cpp");
2568 auto File = testPath("test.cpp");
2569 Server.addDocument(File, FileContent.code());
2570 // Wait for the dynamic index being built.
2571 ASSERT_TRUE(Server.blockUntilIdleForTest());
2572 EXPECT_THAT(llvm::cantFail(runSignatureHelp(Server, File, FileContent.point(),
2574 .signatures,
2575 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
2576}
2577
2578TEST(CompletionTest, CompletionFunctionArgsDisabled) {
2579 CodeCompleteOptions Opts;
2580 Opts.EnableSnippets = true;
2581 Opts.EnableFunctionArgSnippets = false;
2582
2583 {
2584 auto Results = completions(
2585 R"cpp(
2586 void xfoo();
2587 void xfoo(int x, int y);
2588 void f() { xfo^ })cpp",
2589 {}, Opts);
2590 EXPECT_THAT(
2591 Results.Completions,
2592 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("()")),
2593 AllOf(named("xfoo"), snippetSuffix("($0)"))));
2594 }
2595 {
2596 auto Results = completions(
2597 R"cpp(
2598 void xbar();
2599 void f() { xba^ })cpp",
2600 {}, Opts);
2601 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2602 named("xbar"), snippetSuffix("()"))));
2603 }
2604 {
2605 Opts.BundleOverloads = true;
2606 auto Results = completions(
2607 R"cpp(
2608 void xfoo();
2609 void xfoo(int x, int y);
2610 void f() { xfo^ })cpp",
2611 {}, Opts);
2612 EXPECT_THAT(
2613 Results.Completions,
2614 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("($0)"))));
2615 }
2616 {
2617 auto Results = completions(
2618 R"cpp(
2619 template <class T, class U>
2620 void xfoo(int a, U b);
2621 void f() { xfo^ })cpp",
2622 {}, Opts);
2623 EXPECT_THAT(
2624 Results.Completions,
2625 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("<$1>($0)"))));
2626 }
2627 {
2628 auto Results = completions(
2629 R"cpp(
2630 template <class T>
2631 class foo_class{};
2632 template <class T>
2633 using foo_alias = T**;
2634 void f() { foo_^ })cpp",
2635 {}, Opts);
2636 EXPECT_THAT(
2637 Results.Completions,
2638 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
2639 AllOf(named("foo_alias"), snippetSuffix("<$0>"))));
2640 }
2641 {
2642 auto Results = completions(
2643 R"cpp(
2644 #define FOO(x, y) x##f
2645 FO^ )cpp",
2646 {}, Opts);
2647 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2648 named("FOO"), snippetSuffix("($0)"))));
2649 }
2650}
2651
2652TEST(CompletionTest, SuggestOverrides) {
2653 constexpr const char *const Text(R"cpp(
2654 class A {
2655 public:
2656 virtual void vfunc(bool param);
2657 virtual void vfunc(bool param, int p);
2658 void func(bool param);
2659 };
2660 class B : public A {
2661 virtual void ttt(bool param) const;
2662 void vfunc(bool param, int p) override;
2663 };
2664 class C : public B {
2665 public:
2666 void vfunc(bool param) override;
2667 ^
2668 };
2669 )cpp");
2670 const auto Results = completions(Text);
2671 EXPECT_THAT(
2672 Results.Completions,
2673 AllOf(Contains(AllOf(labeled("void vfunc(bool param, int p) override"),
2674 nameStartsWith("vfunc"))),
2675 Contains(AllOf(labeled("void ttt(bool param) const override"),
2676 nameStartsWith("ttt"))),
2677 Not(Contains(labeled("void vfunc(bool param) override")))));
2678}
2679
2680TEST(CompletionTest, OverridesNonIdentName) {
2681 // Check the completions call does not crash.
2682 completions(R"cpp(
2683 struct Base {
2684 virtual ~Base() = 0;
2685 virtual operator int() = 0;
2686 virtual Base& operator+(Base&) = 0;
2687 };
2688
2689 struct Derived : Base {
2690 ^
2691 };
2692 )cpp");
2693}
2694
2695TEST(CompletionTest, NoCrashOnMissingNewLineAtEOF) {
2696 auto FooCpp = testPath("foo.cpp");
2697
2698 MockCompilationDatabase CDB;
2699 MockFS FS;
2700 Annotations F("#pragma ^ // no new line");
2701 FS.Files[FooCpp] = F.code().str();
2702 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2703 runAddDocument(Server, FooCpp, F.code());
2704 // Run completion outside the file range.
2705 EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, F.point(),
2706 clangd::CodeCompleteOptions()))
2707 .Completions,
2708 IsEmpty());
2709 EXPECT_THAT(cantFail(runSignatureHelp(Server, FooCpp, F.point(),
2711 .signatures,
2712 IsEmpty());
2713}
2714
2715TEST(GuessCompletionPrefix, Filters) {
2716 for (llvm::StringRef Case : {
2717 "[[scope::]][[ident]]^",
2718 "[[]][[]]^",
2719 "\n[[]][[]]^",
2720 "[[]][[ab]]^",
2721 "x.[[]][[ab]]^",
2722 "x.[[]][[]]^",
2723 "[[x::]][[ab]]^",
2724 "[[x::]][[]]^",
2725 "[[::x::]][[ab]]^",
2726 "some text [[scope::more::]][[identif]]^ier",
2727 "some text [[scope::]][[mor]]^e::identifier",
2728 "weird case foo::[[::bar::]][[baz]]^",
2729 "/* [[]][[]]^ */",
2730 }) {
2731 Annotations F(Case);
2732 auto Offset = cantFail(positionToOffset(F.code(), F.point()));
2733 auto ToStringRef = [&](Range R) {
2734 return F.code().slice(cantFail(positionToOffset(F.code(), R.start)),
2735 cantFail(positionToOffset(F.code(), R.end)));
2736 };
2737 auto WantQualifier = ToStringRef(F.ranges()[0]),
2738 WantName = ToStringRef(F.ranges()[1]);
2739
2740 auto Prefix = guessCompletionPrefix(F.code(), Offset);
2741 // Even when components are empty, check their offsets are correct.
2742 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
2743 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
2744 EXPECT_EQ(WantName, Prefix.Name) << Case;
2745 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
2746 }
2747}
2748
2749TEST(CompletionTest, EnableSpeculativeIndexRequest) {
2750 MockFS FS;
2751 MockCompilationDatabase CDB;
2752 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2753
2754 auto File = testPath("foo.cpp");
2755 Annotations Test(R"cpp(
2756 namespace ns1 { int abc; }
2757 namespace ns2 { int abc; }
2758 void f() { ns1::ab$1^; ns1::ab$2^; }
2759 void f2() { ns2::ab$3^; }
2760 )cpp");
2761 runAddDocument(Server, File, Test.code());
2762 clangd::CodeCompleteOptions Opts = {};
2763
2764 IndexRequestCollector Requests;
2765 Opts.Index = &Requests;
2766
2767 auto CompleteAtPoint = [&](StringRef P) {
2768 auto CCR = cantFail(runCodeComplete(Server, File, Test.point(P), Opts));
2769 EXPECT_TRUE(CCR.HasMore);
2770 };
2771
2772 CompleteAtPoint("1");
2773 auto Reqs1 = Requests.consumeRequests(1);
2774 ASSERT_EQ(Reqs1.size(), 1u);
2775 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::"));
2776
2777 CompleteAtPoint("2");
2778 auto Reqs2 = Requests.consumeRequests(1);
2779 // Speculation succeeded. Used speculative index result.
2780 ASSERT_EQ(Reqs2.size(), 1u);
2781 EXPECT_EQ(Reqs2[0], Reqs1[0]);
2782
2783 CompleteAtPoint("3");
2784 // Speculation failed. Sent speculative index request and the new index
2785 // request after sema.
2786 auto Reqs3 = Requests.consumeRequests(2);
2787 ASSERT_EQ(Reqs3.size(), 2u);
2788}
2789
2790TEST(CompletionTest, InsertTheMostPopularHeader) {
2791 std::string DeclFile = URI::create(testPath("foo")).toString();
2792 Symbol Sym = func("Func");
2793 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2794 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
2795 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
2796
2797 auto Results = completions("Fun^", {Sym}).Completions;
2798 assert(!Results.empty());
2799 EXPECT_THAT(Results[0], AllOf(named("Func"), insertInclude("\"bar.h\"")));
2800 EXPECT_EQ(Results[0].Includes.size(), 2u);
2801}
2802
2803TEST(CompletionTest, InsertIncludeOrImport) {
2804 std::string DeclFile = URI::create(testPath("foo")).toString();
2805 Symbol Sym = func("Func");
2806 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2807 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000,
2809 CodeCompleteOptions Opts;
2810 // Should only take effect in import contexts.
2811 Opts.ImportInsertions = true;
2812 auto Results = completions("Fun^", {Sym}, Opts).Completions;
2813 assert(!Results.empty());
2814 EXPECT_THAT(Results[0],
2815 AllOf(named("Func"), insertIncludeText("#include \"bar.h\"\n")));
2816
2817 ASTSignals Signals;
2818 Signals.InsertionDirective = Symbol::IncludeDirective::Import;
2819 Opts.MainFileSignals = &Signals;
2820 Results = completions("Fun^", {Sym}, Opts, "Foo.m").Completions;
2821 assert(!Results.empty());
2822 EXPECT_THAT(Results[0],
2823 AllOf(named("Func"), insertIncludeText("#import \"bar.h\"\n")));
2824
2825 Sym.IncludeHeaders[0].SupportedDirectives = Symbol::Import;
2826 Results = completions("Fun^", {Sym}).Completions;
2827 assert(!Results.empty());
2828 EXPECT_THAT(Results[0], AllOf(named("Func"), Not(insertInclude())));
2829}
2830
2831TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
2832 Annotations Test(R"cpp(
2833 #include "foo.h"
2834 Fun^
2835 )cpp");
2836 auto TU = TestTU::withCode(Test.code());
2837 TU.AdditionalFiles["foo.h"] = "";
2838
2839 std::string DeclFile = URI::create(testPath("foo")).toString();
2840 Symbol Sym = func("Func");
2841 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2842 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
2843 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
2844
2845 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions,
2846 UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""),
2847 Not(insertInclude()))));
2848}
2849
2850TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
2851 Symbol Sym;
2852 Sym.Name = "Clangd_Macro_Test";
2853 Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test");
2854 Sym.SymInfo.Kind = index::SymbolKind::Macro;
2856 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
2857 .Completions,
2858 UnorderedElementsAre(named("Clangd_Macro_Test")));
2859}
2860
2861TEST(CompletionTest, MacroFromPreamble) {
2862 Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x
2863
2864 int x = 0;
2865 #define CLANGD_MAIN x
2866 void f() { CLANGD_^ }
2867 )cpp");
2868 auto TU = TestTU::withCode(Test.code());
2869 TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x";
2870 auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")});
2871 // We should get results from the main file, including the preamble section.
2872 // However no results from included files (the index should cover them).
2873 EXPECT_THAT(Results.Completions,
2874 UnorderedElementsAre(named("CLANGD_PREAMBLE_MAIN"),
2875 named("CLANGD_MAIN"),
2876 named("CLANGD_INDEX")));
2877}
2878
2879TEST(CompletionTest, DeprecatedResults) {
2880 std::string Body = R"cpp(
2881 void TestClangd();
2882 void TestClangc() __attribute__((deprecated("", "")));
2883 )cpp";
2884
2885 EXPECT_THAT(
2886 completions(Body + "int main() { TestClang^ }").Completions,
2887 UnorderedElementsAre(AllOf(named("TestClangd"), Not(deprecated())),
2888 AllOf(named("TestClangc"), deprecated())));
2889}
2890
2891TEST(SignatureHelpTest, PartialSpec) {
2892 const auto Results = signatures(R"cpp(
2893 template <typename T> struct Foo {};
2894 template <typename T> struct Foo<T*> { Foo(T); };
2895 Foo<int*> F(^);)cpp");
2896 EXPECT_THAT(Results.signatures, Contains(sig("Foo([[T]])")));
2897 EXPECT_EQ(0, Results.activeParameter);
2898}
2899
2900TEST(SignatureHelpTest, InsideArgument) {
2901 {
2902 const auto Results = signatures(R"cpp(
2903 void foo(int x);
2904 void foo(int x, int y);
2905 int main() { foo(1+^); }
2906 )cpp");
2907 EXPECT_THAT(Results.signatures,
2908 ElementsAre(sig("foo([[int x]]) -> void"),
2909 sig("foo([[int x]], [[int y]]) -> void")));
2910 EXPECT_EQ(0, Results.activeParameter);
2911 }
2912 {
2913 const auto Results = signatures(R"cpp(
2914 void foo(int x);
2915 void foo(int x, int y);
2916 int main() { foo(1^); }
2917 )cpp");
2918 EXPECT_THAT(Results.signatures,
2919 ElementsAre(sig("foo([[int x]]) -> void"),
2920 sig("foo([[int x]], [[int y]]) -> void")));
2921 EXPECT_EQ(0, Results.activeParameter);
2922 }
2923 {
2924 const auto Results = signatures(R"cpp(
2925 void foo(int x);
2926 void foo(int x, int y);
2927 int main() { foo(1^0); }
2928 )cpp");
2929 EXPECT_THAT(Results.signatures,
2930 ElementsAre(sig("foo([[int x]]) -> void"),
2931 sig("foo([[int x]], [[int y]]) -> void")));
2932 EXPECT_EQ(0, Results.activeParameter);
2933 }
2934 {
2935 const auto Results = signatures(R"cpp(
2936 void foo(int x);
2937 void foo(int x, int y);
2938 int bar(int x, int y);
2939 int main() { bar(foo(2, 3^)); }
2940 )cpp");
2941 EXPECT_THAT(Results.signatures,
2942 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
2943 EXPECT_EQ(1, Results.activeParameter);
2944 }
2945}
2946
2947TEST(SignatureHelpTest, ConstructorInitializeFields) {
2948 {
2949 const auto Results = signatures(R"cpp(
2950 struct A { A(int); };
2951 struct B {
2952 B() : a_elem(^) {}
2953 A a_elem;
2954 };
2955 )cpp");
2956 EXPECT_THAT(Results.signatures,
2957 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2958 sig("A([[const A &]])")));
2959 }
2960 {
2961 const auto Results = signatures(R"cpp(
2962 struct A { A(int); };
2963 struct B {
2964 B() : a_elem(^
2965 A a_elem;
2966 };
2967 )cpp");
2968 // FIXME: currently the parser skips over the decl of a_elem as part of the
2969 // (broken) init list, so we don't get signatures for the first member.
2970 EXPECT_THAT(Results.signatures, IsEmpty());
2971 }
2972 {
2973 const auto Results = signatures(R"cpp(
2974 struct A { A(int); };
2975 struct B {
2976 B() : a_elem(^
2977 int dummy_elem;
2978 A a_elem;
2979 };
2980 )cpp");
2981 EXPECT_THAT(Results.signatures,
2982 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2983 sig("A([[const A &]])")));
2984 }
2985 {
2986 const auto Results = signatures(R"cpp(
2987 struct A {
2988 A(int);
2989 };
2990 struct C {
2991 C(int);
2992 C(A);
2993 };
2994 struct B {
2995 B() : c_elem(A(1^)) {}
2996 C c_elem;
2997 };
2998 )cpp");
2999 EXPECT_THAT(Results.signatures,
3000 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
3001 sig("A([[const A &]])")));
3002 }
3003}
3004
3005TEST(SignatureHelpTest, Variadic) {
3006 const std::string Header = R"cpp(
3007 void fun(int x, ...) {}
3008 void test() {)cpp";
3009 const std::string ExpectedSig = "fun([[int x]], [[...]]) -> void";
3010
3011 {
3012 const auto Result = signatures(Header + "fun(^);}");
3013 EXPECT_EQ(0, Result.activeParameter);
3014 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3015 }
3016 {
3017 const auto Result = signatures(Header + "fun(1, ^);}");
3018 EXPECT_EQ(1, Result.activeParameter);
3019 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3020 }
3021 {
3022 const auto Result = signatures(Header + "fun(1, 2, ^);}");
3023 EXPECT_EQ(1, Result.activeParameter);
3024 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3025 }
3026}
3027
3028TEST(SignatureHelpTest, VariadicTemplate) {
3029 const std::string Header = R"cpp(
3030 template<typename T, typename ...Args>
3031 void fun(T t, Args ...args) {}
3032 void test() {)cpp";
3033 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void";
3034
3035 {
3036 const auto Result = signatures(Header + "fun(^);}");
3037 EXPECT_EQ(0, Result.activeParameter);
3038 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3039 }
3040 {
3041 const auto Result = signatures(Header + "fun(1, ^);}");
3042 EXPECT_EQ(1, Result.activeParameter);
3043 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3044 }
3045 {
3046 const auto Result = signatures(Header + "fun(1, 2, ^);}");
3047 EXPECT_EQ(1, Result.activeParameter);
3048 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3049 }
3050}
3051
3052TEST(SignatureHelpTest, VariadicMethod) {
3053 const std::string Header = R"cpp(
3054 class C {
3055 template<typename T, typename ...Args>
3056 void fun(T t, Args ...args) {}
3057 };
3058 void test() {C c; )cpp";
3059 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void";
3060
3061 {
3062 const auto Result = signatures(Header + "c.fun(^);}");
3063 EXPECT_EQ(0, Result.activeParameter);
3064 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3065 }
3066 {
3067 const auto Result = signatures(Header + "c.fun(1, ^);}");
3068 EXPECT_EQ(1, Result.activeParameter);
3069 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3070 }
3071 {
3072 const auto Result = signatures(Header + "c.fun(1, 2, ^);}");
3073 EXPECT_EQ(1, Result.activeParameter);
3074 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3075 }
3076}
3077
3078TEST(SignatureHelpTest, VariadicType) {
3079 const std::string Header = R"cpp(
3080 void fun(int x, ...) {}
3081 auto get_fun() { return fun; }
3082 void test() {
3083 )cpp";
3084 const std::string ExpectedSig = "([[int]], [[...]]) -> void";
3085
3086 {
3087 const auto Result = signatures(Header + "get_fun()(^);}");
3088 EXPECT_EQ(0, Result.activeParameter);
3089 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3090 }
3091 {
3092 const auto Result = signatures(Header + "get_fun()(1, ^);}");
3093 EXPECT_EQ(1, Result.activeParameter);
3094 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3095 }
3096 {
3097 const auto Result = signatures(Header + "get_fun()(1, 2, ^);}");
3098 EXPECT_EQ(1, Result.activeParameter);
3099 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3100 }
3101}
3102
3103TEST(CompletionTest, IncludedCompletionKinds) {
3104 Annotations Test(R"cpp(#include "^)cpp");
3105 auto TU = TestTU::withCode(Test.code());
3106 TU.AdditionalFiles["sub/bar.h"] = "";
3107 TU.ExtraArgs.push_back("-I" + testPath("sub"));
3108
3109 auto Results = completions(TU, Test.point());
3110 EXPECT_THAT(Results.Completions,
3111 AllOf(has("sub/", CompletionItemKind::Folder),
3112 has("bar.h\"", CompletionItemKind::File)));
3113}
3114
3115TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3116 completions(
3117 R"cpp(
3118 #include "./^"
3119 )cpp");
3120}
3121
3122TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3123 clangd::CodeCompleteOptions Opts = {};
3124 Opts.AllScopes = true;
3125
3126 auto Results = completions(
3127 R"cpp(
3128 void f() { na::Clangd^ }
3129 )cpp",
3130 {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts);
3131 EXPECT_THAT(Results.Completions,
3132 UnorderedElementsAre(
3133 AllOf(qualifier(""), scope("na::"), named("ClangdA"))));
3134}
3135
3136TEST(CompletionTest, AllScopesCompletion) {
3137 clangd::CodeCompleteOptions Opts = {};
3138 Opts.AllScopes = true;
3139
3140 auto Results = completions(
3141 R"cpp(
3142 namespace na {
3143 void f() { Clangd^ }
3144 }
3145 )cpp",
3146 {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"),
3147 cls("na::nb::Clangd4"), enmConstant("na::C::Clangd5")},
3148 Opts);
3149 EXPECT_THAT(
3150 Results.Completions,
3151 UnorderedElementsAre(AllOf(qualifier("nx::"), named("Clangd1"),
3153 AllOf(qualifier("ny::"), named("Clangd2"),
3155 AllOf(qualifier(""), scope(""), named("Clangd3"),
3157 AllOf(qualifier("nb::"), named("Clangd4"),
3159 AllOf(qualifier("C::"), named("Clangd5"),
3161}
3162
3163TEST(CompletionTest, NoQualifierIfShadowed) {
3164 clangd::CodeCompleteOptions Opts = {};
3165 Opts.AllScopes = true;
3166
3167 auto Results = completions(R"cpp(
3168 namespace nx { class Clangd1 {}; }
3169 using nx::Clangd1;
3170 void f() { Clangd^ }
3171 )cpp",
3172 {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts);
3173 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and
3174 // needs no qualifier.
3175 EXPECT_THAT(Results.Completions,
3176 UnorderedElementsAre(AllOf(qualifier(""), named("Clangd1")),
3177 AllOf(qualifier("nx::"), named("Clangd2"))));
3178}
3179
3180TEST(CompletionTest, NoCompletionsForNewNames) {
3181 clangd::CodeCompleteOptions Opts;
3182 Opts.AllScopes = true;
3183 auto Results = completions(R"cpp(
3184 void f() { int n^ }
3185 )cpp",
3186 {cls("naber"), cls("nx::naber")}, Opts);
3187 EXPECT_THAT(Results.Completions, UnorderedElementsAre());
3188}
3189
3190TEST(CompletionTest, Lambda) {
3191 clangd::CodeCompleteOptions Opts = {};
3192
3193 auto Results = completions(R"cpp(
3194 void function() {
3195 auto Lambda = [](int a, const double &b) {return 1.f;};
3196 Lam^
3197 }
3198 )cpp",
3199 {}, Opts);
3200
3201 ASSERT_EQ(Results.Completions.size(), 1u);
3202 const auto &A = Results.Completions.front();
3203 EXPECT_EQ(A.Name, "Lambda");
3204 EXPECT_EQ(A.Signature, "(int a, const double &b) const");
3205 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3206 EXPECT_EQ(A.ReturnType, "float");
3207 EXPECT_EQ(A.SnippetSuffix, "(${1:int a}, ${2:const double &b})");
3208}
3209
3210TEST(CompletionTest, StructuredBinding) {
3211 clangd::CodeCompleteOptions Opts = {};
3212
3213 auto Results = completions(R"cpp(
3214 struct S {
3215 using Float = float;
3216 int x;
3217 Float y;
3218 };
3219 void function() {
3220 const auto &[xxx, yyy] = S{};
3221 yyy^
3222 }
3223 )cpp",
3224 {}, Opts);
3225
3226 ASSERT_EQ(Results.Completions.size(), 1u);
3227 const auto &A = Results.Completions.front();
3228 EXPECT_EQ(A.Name, "yyy");
3229 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3230 EXPECT_EQ(A.ReturnType, "const Float");
3231}
3232
3233TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3234 auto Results = completions(R"objc(
3235 @interface Foo
3236 @property(nonatomic, setter=setXToIgnoreComplete:) int value;
3237 @end
3238 Foo *foo = [Foo new]; int y = [foo v^]
3239 )objc",
3240 /*IndexSymbols=*/{},
3241 /*Opts=*/{}, "Foo.m");
3242
3243 auto C = Results.Completions;
3244 EXPECT_THAT(C, ElementsAre(named("value")));
3245 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3246 EXPECT_THAT(C, ElementsAre(returnType("int")));
3247 EXPECT_THAT(C, ElementsAre(signature("")));
3248 EXPECT_THAT(C, ElementsAre(snippetSuffix("")));
3249}
3250
3251TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3252 auto Results = completions(R"objc(
3253 @interface Foo
3254 - (int)valueForCharacter:(char)c;
3255 @end
3256 Foo *foo = [Foo new]; int y = [foo v^]
3257 )objc",
3258 /*IndexSymbols=*/{},
3259 /*Opts=*/{}, "Foo.m");
3260
3261 auto C = Results.Completions;
3262 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3263 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3264 EXPECT_THAT(C, ElementsAre(returnType("int")));
3265 EXPECT_THAT(C, ElementsAre(signature("(char)")));
3266 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(char)}")));
3267}
3268
3269TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3270 auto Results = completions(R"objc(
3271 @interface Foo
3272 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3273 @end
3274 id val = [Foo foo^]
3275 )objc",
3276 /*IndexSymbols=*/{},
3277 /*Opts=*/{}, "Foo.m");
3278
3279 auto C = Results.Completions;
3280 EXPECT_THAT(C, ElementsAre(named("fooWithValue:")));
3281 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3282 EXPECT_THAT(C, ElementsAre(returnType("id")));
3283 EXPECT_THAT(C, ElementsAre(signature("(int) fooey:(unsigned int)")));
3284 EXPECT_THAT(
3285 C, ElementsAre(snippetSuffix("${1:(int)} fooey:${2:(unsigned int)}")));
3286}
3287
3288TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3289 auto Results = completions(R"objc(
3290 @interface Foo
3291 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3292 @end
3293 id val = [Foo fooWithValue:10 f^]
3294 )objc",
3295 /*IndexSymbols=*/{},
3296 /*Opts=*/{}, "Foo.m");
3297
3298 auto C = Results.Completions;
3299 EXPECT_THAT(C, ElementsAre(named("fooey:")));
3300 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3301 EXPECT_THAT(C, ElementsAre(returnType("id")));
3302 EXPECT_THAT(C, ElementsAre(signature("(unsigned int)")));
3303 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(unsigned int)}")));
3304}
3305
3306TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3307 auto Results = completions(R"objc(
3308 @interface Foo
3309 + (id)player:(id)player willRun:(id)run;
3310 @end
3311 id val = [Foo wi^]
3312 )objc",
3313 /*IndexSymbols=*/{},
3314 /*Opts=*/{}, "Foo.m");
3315
3316 auto C = Results.Completions;
3317 EXPECT_THAT(C, ElementsAre(named("player:")));
3318 EXPECT_THAT(C, ElementsAre(filterText("player:willRun:")));
3319 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3320 EXPECT_THAT(C, ElementsAre(returnType("id")));
3321 EXPECT_THAT(C, ElementsAre(signature("(id) willRun:(id)")));
3322 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(id)} willRun:${2:(id)}")));
3323}
3324
3325TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3326 auto Results = completions(R"objc(
3327 @interface Foo
3328 - (void)foo;
3329 @end
3330 @implementation Foo
3331 fo^
3332 @end
3333 )objc",
3334 /*IndexSymbols=*/{},
3335 /*Opts=*/{}, "Foo.m");
3336
3337 auto C = Results.Completions;
3338 EXPECT_THAT(C, ElementsAre(named("foo")));
3339 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3340 EXPECT_THAT(C, ElementsAre(qualifier("- (void)")));
3341}
3342
3343TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3344 auto Results = completions(R"objc(
3345 @interface Foo
3346 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3347 @end
3348 @implementation Foo
3349 valueFor^
3350 @end
3351 )objc",
3352 /*IndexSymbols=*/{},
3353 /*Opts=*/{}, "Foo.m");
3354
3355 auto C = Results.Completions;
3356 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3357 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3358 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3359 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object")));
3360}
3361
3362TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3363 auto Results = completions(R"objc(
3364 @interface Foo
3365 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3366 @end
3367 @implementation Foo
3368 secondArg^
3369 @end
3370 )objc",
3371 /*IndexSymbols=*/{},
3372 /*Opts=*/{}, "Foo.m");
3373
3374 auto C = Results.Completions;
3375 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3376 EXPECT_THAT(C, ElementsAre(filterText("valueForCharacter:secondArgument:")));
3377 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3378 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3379 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object")));
3380}
3381
3382TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3383 auto Results = completions(R"objc(
3384 @interface Foo
3385 - (int)valueForCharacter:(char)c;
3386 @end
3387 @implementation Foo
3388 - (int)valueFor^
3389 @end
3390 )objc",
3391 /*IndexSymbols=*/{},
3392 /*Opts=*/{}, "Foo.m");
3393
3394 auto C = Results.Completions;
3395 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3396 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3397 EXPECT_THAT(C, ElementsAre(signature("(char)c")));
3398}
3399
3400TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3401 auto Results = completions(R"objc(
3402 @interface Foo
3403 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3404 @end
3405 @implementation Foo
3406 - (int)valueForCharacter:(char)c second^
3407 @end
3408 )objc",
3409 /*IndexSymbols=*/{},
3410 /*Opts=*/{}, "Foo.m");
3411
3412 auto C = Results.Completions;
3413 EXPECT_THAT(C, ElementsAre(named("secondArgument:")));
3414 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3415 EXPECT_THAT(C, ElementsAre(signature("(id)object")));
3416}
3417
3418TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3419 Symbol FoodClass = objcClass("FoodClass");
3420 Symbol SymFood = objcProtocol("Food");
3421 Symbol SymFooey = objcProtocol("Fooey");
3422 auto Results = completions("id<Foo^>", {SymFood, FoodClass, SymFooey},
3423 /*Opts=*/{}, "Foo.m");
3424
3425 // Should only give protocols for ObjC protocol completions.
3426 EXPECT_THAT(Results.Completions,
3427 UnorderedElementsAre(
3428 AllOf(named("Food"), kind(CompletionItemKind::Interface)),
3429 AllOf(named("Fooey"), kind(CompletionItemKind::Interface))));
3430
3431 Results = completions("Fo^", {SymFood, FoodClass, SymFooey},
3432 /*Opts=*/{}, "Foo.m");
3433 // Shouldn't give protocols for non protocol completions.
3434 EXPECT_THAT(
3435 Results.Completions,
3436 ElementsAre(AllOf(named("FoodClass"), kind(CompletionItemKind::Class))));
3437}
3438
3439TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3440 MockFS FS;
3441 MockCompilationDatabase CDB;
3442 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
3443
3444 auto File = testPath("Foo.m");
3445 Annotations Test(R"cpp(
3446 @protocol Food
3447 @end
3448 id<Foo$1^> foo;
3449 Foo$2^ bar;
3450 )cpp");
3451 runAddDocument(Server, File, Test.code());
3452 clangd::CodeCompleteOptions Opts = {};
3453
3454 Symbol FoodClass = objcClass("FoodClass");
3455 IndexRequestCollector Requests({FoodClass});
3456 Opts.Index = &Requests;
3457
3458 auto CompleteAtPoint = [&](StringRef P) {
3459 return cantFail(runCodeComplete(Server, File, Test.point(P), Opts))
3460 .Completions;
3461 };
3462
3463 auto C = CompleteAtPoint("1");
3464 auto Reqs1 = Requests.consumeRequests(1);
3465 ASSERT_EQ(Reqs1.size(), 1u);
3466 EXPECT_THAT(C, ElementsAre(AllOf(named("Food"),
3468
3469 C = CompleteAtPoint("2");
3470 auto Reqs2 = Requests.consumeRequests(1);
3471 // Speculation succeeded. Used speculative index result, but filtering now to
3472 // now include FoodClass.
3473 ASSERT_EQ(Reqs2.size(), 1u);
3474 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3475 EXPECT_THAT(C, ElementsAre(AllOf(named("FoodClass"),
3477}
3478
3479TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3480 Symbol FoodCategory = objcCategory("FoodClass", "Extension");
3481 auto Results = completions(R"objc(
3482 @interface Foo
3483 @end
3484 @interface Foo (^)
3485 @end
3486 )objc",
3487 {FoodCategory},
3488 /*Opts=*/{}, "Foo.m");
3489 EXPECT_THAT(Results.Completions, IsEmpty());
3490}
3491
3492TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3493 Symbol FoodClass = objcClass("FoodClass");
3494 FoodClass.IncludeHeaders.emplace_back("\"Foo.h\"", 2, Symbol::Import);
3495 Symbol SymFood = objcProtocol("Food");
3496 auto Results = completions("@class Foo^", {SymFood, FoodClass},
3497 /*Opts=*/{}, "Foo.m");
3498
3499 // Should only give class names without any include insertion.
3500 EXPECT_THAT(Results.Completions,
3501 UnorderedElementsAre(AllOf(named("FoodClass"),
3503 Not(insertInclude()))));
3504}
3505
3506TEST(CompletionTest, CursorInSnippets) {
3507 clangd::CodeCompleteOptions Options;
3508 Options.EnableSnippets = true;
3509 auto Results = completions(
3510 R"cpp(
3511 void while_foo(int a, int b);
3512 void test() {
3513 whil^
3514 })cpp",
3515 /*IndexSymbols=*/{}, Options);
3516
3517 // Last placeholder in code patterns should be $0 to put the cursor there.
3518 EXPECT_THAT(Results.Completions,
3519 Contains(AllOf(named("while"),
3520 snippetSuffix(" (${1:condition}) {\n$0\n}"))));
3521 // However, snippets for functions must *not* end with $0.
3522 EXPECT_THAT(Results.Completions,
3523 Contains(AllOf(named("while_foo"),
3524 snippetSuffix("(${1:int a}, ${2:int b})"))));
3525
3526 Results = completions(R"cpp(
3527 struct Base {
3528 Base(int a, int b) {}
3529 };
3530
3531 struct Derived : Base {
3532 Derived() : Base^
3533 };
3534 )cpp",
3535 /*IndexSymbols=*/{}, Options);
3536 // Constructors from base classes are a kind of pattern that shouldn't end
3537 // with $0.
3538 EXPECT_THAT(Results.Completions,
3539 Contains(AllOf(named("Base"),
3540 snippetSuffix("(${1:int a}, ${2:int b})"))));
3541}
3542
3543TEST(CompletionTest, WorksWithNullType) {
3544 auto R = completions(R"cpp(
3545 int main() {
3546 for (auto [loopVar] : y ) { // y has to be unresolved.
3547 int z = loopV^;
3548 }
3549 }
3550 )cpp");
3551 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar")));
3552}
3553
3554TEST(CompletionTest, UsingDecl) {
3555 const char *Header(R"cpp(
3556 void foo(int);
3557 namespace std {
3558 using ::foo;
3559 })cpp");
3560 const char *Source(R"cpp(
3561 void bar() {
3562 std::^;
3563 })cpp");
3564 auto Index = TestTU::withHeaderCode(Header).index();
3565 clangd::CodeCompleteOptions Opts;
3566 Opts.Index = Index.get();
3567 Opts.AllScopes = true;
3568 auto R = completions(Source, {}, Opts);
3569 EXPECT_THAT(R.Completions,
3570 ElementsAre(AllOf(scope("std::"), named("foo"),
3572}
3573
3574TEST(CompletionTest, Enums) {
3575 const char *Header(R"cpp(
3576 namespace ns {
3577 enum Unscoped { Clangd1 };
3578 class C {
3579 enum Unscoped { Clangd2 };
3580 };
3581 enum class Scoped { Clangd3 };
3582 })cpp");
3583 const char *Source(R"cpp(
3584 void bar() {
3585 Clangd^
3586 })cpp");
3587 auto Index = TestTU::withHeaderCode(Header).index();
3588 clangd::CodeCompleteOptions Opts;
3589 Opts.Index = Index.get();
3590 Opts.AllScopes = true;
3591 auto R = completions(Source, {}, Opts);
3592 EXPECT_THAT(R.Completions, UnorderedElementsAre(
3593 AllOf(scope("ns::"), named("Clangd1"),
3595 AllOf(scope("ns::C::"), named("Clangd2"),
3597 AllOf(scope("ns::Scoped::"), named("Clangd3"),
3599}
3600
3601TEST(CompletionTest, ScopeIsUnresolved) {
3602 clangd::CodeCompleteOptions Opts = {};
3603 Opts.AllScopes = true;
3604
3605 auto Results = completions(R"cpp(
3606 namespace a {
3607 void f() { b::X^ }
3608 }
3609 )cpp",
3610 {cls("a::b::XYZ")}, Opts);
3611 EXPECT_THAT(Results.Completions,
3612 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ"))));
3613}
3614
3615TEST(CompletionTest, NestedScopeIsUnresolved) {
3616 clangd::CodeCompleteOptions Opts = {};
3617 Opts.AllScopes = true;
3618
3619 auto Results = completions(R"cpp(
3620 namespace a {
3621 namespace b {}
3622 void f() { b::c::X^ }
3623 }
3624 )cpp",
3625 {cls("a::b::c::XYZ")}, Opts);
3626 EXPECT_THAT(Results.Completions,
3627 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ"))));
3628}
3629
3630// Clang parser gets confused here and doesn't report the ns:: prefix.
3631// Naive behavior is to insert it again. We examine the source and recover.
3632TEST(CompletionTest, NamespaceDoubleInsertion) {
3633 clangd::CodeCompleteOptions Opts = {};
3634
3635 auto Results = completions(R"cpp(
3636 namespace foo {
3637 namespace ns {}
3638 #define M(X) < X
3639 M(ns::ABC^
3640 }
3641 )cpp",
3642 {cls("foo::ns::ABCDE")}, Opts);
3643 EXPECT_THAT(Results.Completions,
3644 UnorderedElementsAre(AllOf(qualifier(""), named("ABCDE"))));
3645}
3646
3647TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
3648 // Despite the fact that base method matches the ref-qualifier better,
3649 // completion results should only include the derived method.
3650 auto Completions = completions(R"cpp(
3651 struct deque_base {
3652 float size();
3653 double size() const;
3654 };
3655 struct deque : deque_base {
3656 int size() const;
3657 };
3658
3659 auto x = deque().^
3660 )cpp")
3661 .Completions;
3662 EXPECT_THAT(Completions,
3663 ElementsAre(AllOf(returnType("int"), named("size"))));
3664}
3665
3666TEST(CompletionTest, NoCrashWithIncompleteLambda) {
3667 auto Completions = completions("auto&& x = []{^").Completions;
3668 // The completion of x itself can cause a problem: in the code completion
3669 // callback, its type is not known, which affects the linkage calculation.
3670 // A bad linkage value gets cached, and subsequently updated.
3671 EXPECT_THAT(Completions, Contains(named("x")));
3672
3673 auto Signatures = signatures("auto x() { x(^").signatures;
3674 EXPECT_THAT(Signatures, Contains(sig("x() -> auto")));
3675}
3676
3677TEST(CompletionTest, DelayedTemplateParsing) {
3678 Annotations Test(R"cpp(
3679 int xxx;
3680 template <typename T> int foo() { return xx^; }
3681 )cpp");
3682 auto TU = TestTU::withCode(Test.code());
3683 // Even though delayed-template-parsing is on, we will disable it to provide
3684 // completion in templates.
3685 TU.ExtraArgs.push_back("-fdelayed-template-parsing");
3686
3687 EXPECT_THAT(completions(TU, Test.point()).Completions,
3688 Contains(named("xxx")));
3689}
3690
3691TEST(CompletionTest, CompletionRange) {
3692 const char *WithRange = "auto x = [[abc]]^";
3693 auto Completions = completions(WithRange);
3694 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3695 Completions = completionsNoCompile(WithRange);
3696 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3697
3698 const char *EmptyRange = "auto x = [[]]^";
3699 Completions = completions(EmptyRange);
3700 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3701 Completions = completionsNoCompile(EmptyRange);
3702 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3703
3704 // Sema doesn't trigger at all here, while the no-sema completion runs
3705 // heuristics as normal and reports a range. It'd be nice to be consistent.
3706 const char *NoCompletion = "/* foo [[]]^ */";
3707 Completions = completions(NoCompletion);
3708 EXPECT_EQ(Completions.CompletionRange, std::nullopt);
3709 Completions = completionsNoCompile(NoCompletion);
3710 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
3711}
3712
3713TEST(NoCompileCompletionTest, Basic) {
3714 auto Results = completionsNoCompile(R"cpp(
3715 void func() {
3716 int xyz;
3717 int abc;
3718 ^
3719 }
3720 )cpp");
3721 EXPECT_FALSE(Results.RanParser);
3722 EXPECT_THAT(Results.Completions,
3723 UnorderedElementsAre(named("void"), named("func"), named("int"),
3724 named("xyz"), named("abc")));
3725}
3726
3727TEST(NoCompileCompletionTest, WithFilter) {
3728 auto Results = completionsNoCompile(R"cpp(
3729 void func() {
3730 int sym1;
3731 int sym2;
3732 int xyz1;
3733 int xyz2;
3734 sy^
3735 }
3736 )cpp");
3737 EXPECT_THAT(Results.Completions,
3738 UnorderedElementsAre(named("sym1"), named("sym2")));
3739}
3740
3741TEST(NoCompileCompletionTest, WithIndex) {
3742 std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"),
3743 func("c::xxx"), func("ns::d::xxx")};
3744 auto Results = completionsNoCompile(
3745 R"cpp(
3746 // Current-scopes, unqualified completion.
3747 using namespace a;
3748 namespace ns {
3749 using namespace b;
3750 void foo() {
3751 xx^
3752 }
3753 }
3754 )cpp",
3755 Syms);
3756 EXPECT_THAT(Results.Completions,
3757 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3758 AllOf(qualifier(""), scope("a::")),
3759 AllOf(qualifier(""), scope("ns::b::"))));
3760 CodeCompleteOptions Opts;
3761 Opts.AllScopes = true;
3762 Results = completionsNoCompile(
3763 R"cpp(
3764 // All-scopes unqualified completion.
3765 using namespace a;
3766 namespace ns {
3767 using namespace b;
3768 void foo() {
3769 xx^
3770 }
3771 }
3772 )cpp",
3773 Syms, Opts);
3774 EXPECT_THAT(Results.Completions,
3775 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3776 AllOf(qualifier(""), scope("a::")),
3777 AllOf(qualifier(""), scope("ns::b::")),
3778 AllOf(qualifier("c::"), scope("c::")),
3779 AllOf(qualifier("d::"), scope("ns::d::"))));
3780 Results = completionsNoCompile(
3781 R"cpp(
3782 // Qualified completion.
3783 using namespace a;
3784 namespace ns {
3785 using namespace b;
3786 void foo() {
3787 b::xx^
3788 }
3789 }
3790 )cpp",
3791 Syms, Opts);
3792 EXPECT_THAT(Results.Completions,
3793 ElementsAre(AllOf(qualifier(""), scope("ns::b::"))));
3794 Results = completionsNoCompile(
3795 R"cpp(
3796 // Absolutely qualified completion.
3797 using namespace a;
3798 namespace ns {
3799 using namespace b;
3800 void foo() {
3801 ::a::xx^
3802 }
3803 }
3804 )cpp",
3805 Syms, Opts);
3806 EXPECT_THAT(Results.Completions,
3807 ElementsAre(AllOf(qualifier(""), scope("a::"))));
3808}
3809
3810TEST(AllowImplicitCompletion, All) {
3811 const char *Yes[] = {
3812 "foo.^bar",
3813 "foo->^bar",
3814 "foo::^bar",
3815 " # include <^foo.h>",
3816 "#import <foo/^bar.h>",
3817 "#include_next \"^",
3818 };
3819 const char *No[] = {
3820 "foo>^bar",
3821 "foo:^bar",
3822 "foo\n^bar",
3823 "#include <foo.h> //^",
3824 "#include \"foo.h\"^",
3825 "#error <^",
3826 "#<^",
3827 };
3828 for (const char *Test : Yes) {
3829 llvm::Annotations A(Test);
3830 EXPECT_TRUE(allowImplicitCompletion(A.code(), A.point())) << Test;
3831 }
3832 for (const char *Test : No) {
3833 llvm::Annotations A(Test);
3834 EXPECT_FALSE(allowImplicitCompletion(A.code(), A.point())) << Test;
3835 }
3836}
3837
3838TEST(CompletionTest, FunctionArgsExist) {
3839 clangd::CodeCompleteOptions Opts;
3840 Opts.EnableSnippets = true;
3841 std::string Context = R"cpp(
3842 #define MACRO(x)
3843 int foo(int A);
3844 int bar();
3845 struct Object {
3846 Object(int B) {}
3847 };
3848 template <typename T>
3849 struct Container {
3850 Container(int Size) {}
3851 };
3852 )cpp";
3853 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions,
3854 UnorderedElementsAre(
3855 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3856 EXPECT_THAT(
3857 completions(Context + "int y = fo^(42)", {}, Opts).Completions,
3858 UnorderedElementsAre(AllOf(labeled("foo(int A)"), snippetSuffix(""))));
3859 // FIXME(kirillbobyrev): No snippet should be produced here.
3860 EXPECT_THAT(completions(Context + "int y = fo^o(42)", {}, Opts).Completions,
3861 UnorderedElementsAre(
3862 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3863 EXPECT_THAT(
3864 completions(Context + "int y = ba^", {}, Opts).Completions,
3865 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("()"))));
3866 EXPECT_THAT(completions(Context + "int y = ba^()", {}, Opts).Completions,
3867 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix(""))));
3868 EXPECT_THAT(
3869 completions(Context + "Object o = Obj^", {}, Opts).Completions,
3870 Contains(AllOf(labeled("Object(int B)"), snippetSuffix("(${1:int B})"),
3872 EXPECT_THAT(completions(Context + "Object o = Obj^()", {}, Opts).Completions,
3873 Contains(AllOf(labeled("Object(int B)"), snippetSuffix(""),
3875 EXPECT_THAT(
3876 completions(Context + "Container c = Cont^", {}, Opts).Completions,
3877 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3878 snippetSuffix("<${1:typename T}>(${2:int Size})"),
3880 EXPECT_THAT(
3881 completions(Context + "Container c = Cont^()", {}, Opts).Completions,
3882 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3883 snippetSuffix("<${1:typename T}>"),
3885 EXPECT_THAT(
3886 completions(Context + "Container c = Cont^<int>()", {}, Opts).Completions,
3887 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3888 snippetSuffix(""),
3890 EXPECT_THAT(completions(Context + "MAC^(2)", {}, Opts).Completions,
3891 Contains(AllOf(labeled("MACRO(x)"), snippetSuffix(""),
3893}
3894
3895TEST(CompletionTest, FunctionArgsExist_Issue1785) {
3896 // This is a scenario where the implementation of our check for
3897 // "is there a function argument list right after the cursor"
3898 // gave a bogus result.
3899 clangd::CodeCompleteOptions Opts;
3900 Opts.EnableSnippets = true;
3901 // The whitespace in this testcase is important!
3902 std::string Code = R"cpp(
3903void waldo(int);
3904
3905int main()
3906{
3907 wal^
3908
3909
3910 // ( )
3911}
3912 )cpp";
3913 EXPECT_THAT(
3914 completions(Code, {}, Opts).Completions,
3915 Contains(AllOf(labeled("waldo(int)"), snippetSuffix("(${1:int})"))));
3916}
3917
3918TEST(CompletionTest, NoCrashDueToMacroOrdering) {
3919 EXPECT_THAT(completions(R"cpp(
3920 #define ECHO(X) X
3921 #define ECHO2(X) ECHO(X)
3922 int finish_preamble = EC^HO(2);)cpp")
3923 .Completions,
3924 UnorderedElementsAre(labeled("ECHO(X)"), labeled("ECHO2(X)")));
3925}
3926
3927TEST(CompletionTest, ObjCCategoryDecls) {
3928 TestTU TU;
3929 TU.ExtraArgs.push_back("-xobjective-c");
3930 TU.HeaderCode = R"objc(
3931 @interface Foo
3932 @end
3933
3934 @interface Foo (FooExt1)
3935 @end
3936
3937 @interface Foo (FooExt2)
3938 @end
3939
3940 @interface Bar
3941 @end
3942
3943 @interface Bar (BarExt)
3944 @end)objc";
3945
3946 {
3947 Annotations Test(R"objc(
3948 @implementation Foo (^)
3949 @end
3950 )objc");
3951 TU.Code = Test.code().str();
3952 auto Results = completions(TU, Test.point());
3953 EXPECT_THAT(Results.Completions,
3954 UnorderedElementsAre(labeled("FooExt1"), labeled("FooExt2")));
3955 }
3956 {
3957 Annotations Test(R"objc(
3958 @interface Foo (^)
3959 @end
3960 )objc");
3961 TU.Code = Test.code().str();
3962 auto Results = completions(TU, Test.point());
3963 EXPECT_THAT(Results.Completions, UnorderedElementsAre(labeled("BarExt")));
3964 }
3965}
3966
3967TEST(CompletionTest, PreambleCodeComplete) {
3968 llvm::StringLiteral Baseline = "\n#define MACRO 12\nint num = MACRO;";
3969 llvm::StringLiteral ModifiedCC =
3970 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
3971
3972 Annotations Test(ModifiedCC);
3973 auto BaselineTU = TestTU::withCode(Baseline);
3974 auto ModifiedTU = TestTU::withCode(Test.code());
3975
3976 MockFS FS;
3977 auto Inputs = ModifiedTU.inputs(FS);
3978 auto Result = codeComplete(testPath(ModifiedTU.Filename), Test.point(),
3979 BaselineTU.preamble().get(), Inputs, {});
3980 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
3981}
3982
3983TEST(CompletionTest, CommentParamName) {
3984 const std::string Code = R"cpp(
3985 void fun(int foo, int bar);
3986 void overloaded(int param_int);
3987 void overloaded(int param_int, int param_other);
3988 void overloaded(char param_char);
3989 int main() {
3990 )cpp";
3991
3992 EXPECT_THAT(completions(Code + "fun(/*^").Completions,
3993 UnorderedElementsAre(labeled("foo=*/")));
3994 EXPECT_THAT(completions(Code + "fun(1, /*^").Completions,
3995 UnorderedElementsAre(labeled("bar=*/")));
3996 EXPECT_THAT(completions(Code + "/*^").Completions, IsEmpty());
3997 // Test de-duplication.
3998 EXPECT_THAT(
3999 completions(Code + "overloaded(/*^").Completions,
4000 UnorderedElementsAre(labeled("param_int=*/"), labeled("param_char=*/")));
4001 // Comment already has some text in it.
4002 EXPECT_THAT(completions(Code + "fun(/* ^").Completions,
4003 UnorderedElementsAre(labeled("foo=*/")));
4004 EXPECT_THAT(completions(Code + "fun(/* f^").Completions,
4005 UnorderedElementsAre(labeled("foo=*/")));
4006 EXPECT_THAT(completions(Code + "fun(/* x^").Completions, IsEmpty());
4007 EXPECT_THAT(completions(Code + "fun(/* f ^").Completions, IsEmpty());
4008
4009 // Test ranges
4010 {
4011 std::string CompletionRangeTest(Code + "fun(/*[[^]]");
4012 auto Results = completions(CompletionRangeTest);
4013 EXPECT_THAT(Results.CompletionRange,
4014 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
4015 EXPECT_THAT(
4016 Results.Completions,
4017 testing::Each(
4018 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
4020 }
4021 {
4022 std::string CompletionRangeTest(Code + "fun(/*[[fo^]]");
4023 auto Results = completions(CompletionRangeTest);
4024 EXPECT_THAT(Results.CompletionRange,
4025 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
4026 EXPECT_THAT(
4027 Results.Completions,
4028 testing::Each(
4029 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
4031 }
4032}
4033
4034TEST(CompletionTest, Concepts) {
4035 Annotations Code(R"cpp(
4036 template<class T>
4037 concept A = sizeof(T) <= 8;
4038
4039 template<$tparam^A U>
4040 int foo();
4041
4042 template<typename T>
4043 int bar(T t) requires $expr^A<int>;
4044
4045 template<class T>
4046 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
4047
4048 $toplevel^A auto i = 19;
4049
4050 template<$toplevel^A auto i> void constrainedNTTP();
4051
4052 // FIXME: The first parameter should be dropped in this case.
4053 void abbreviated($expr^A auto x) {}
4054 )cpp");
4055 TestTU TU;
4056 TU.Code = Code.code().str();
4057 TU.ExtraArgs = {"-std=c++20"};
4058
4059 auto Sym = conceptSym("same_as");
4060 Sym.Signature = "<typename Tp, typename Up>";
4061 Sym.CompletionSnippetSuffix = "<${1:typename Tp}, ${2:typename Up}>";
4062 std::vector<Symbol> Syms = {Sym};
4063 for (auto P : Code.points("tparam")) {
4064 ASSERT_THAT(
4065 completions(TU, P, Syms).Completions,
4066 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4067 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4068 snippetSuffix("<${2:typename Up}>"))),
4069 Contains(named("class")), Contains(named("typename"))))
4070 << "Completing template parameter at position " << P;
4071 }
4072
4073 for (auto P : Code.points("toplevel")) {
4074 EXPECT_THAT(
4075 completions(TU, P, Syms).Completions,
4076 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4077 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4078 snippetSuffix("<${2:typename Up}>")))))
4079 << "Completing 'requires' expression at position " << P;
4080 }
4081
4082 for (auto P : Code.points("expr")) {
4083 EXPECT_THAT(
4084 completions(TU, P, Syms).Completions,
4085 AllOf(Contains(AllOf(named("A"), signature("<class T>"),
4086 snippetSuffix("<${1:class T}>"))),
4087 Contains(AllOf(
4088 named("same_as"), signature("<typename Tp, typename Up>"),
4089 snippetSuffix("<${1:typename Tp}, ${2:typename Up}>")))))
4090 << "Completing 'requires' expression at position " << P;
4091 }
4092}
4093
4094TEST(SignatureHelp, DocFormat) {
4095 Annotations Code(R"cpp(
4096 // Comment `with` markup.
4097 void foo(int);
4098 void bar() { foo(^); }
4099 )cpp");
4100 for (auto DocumentationFormat :
4102 auto Sigs = signatures(Code.code(), Code.point(), /*IndexSymbols=*/{},
4103 DocumentationFormat);
4104 ASSERT_EQ(Sigs.signatures.size(), 1U);
4105 EXPECT_EQ(Sigs.signatures[0].documentation.kind, DocumentationFormat);
4106 }
4107}
4108
4109TEST(SignatureHelp, TemplateArguments) {
4110 std::string Top = R"cpp(
4111 template <typename T, int> bool foo(char);
4112 template <int I, int> bool foo(float);
4113 )cpp";
4114
4115 auto First = signatures(Top + "bool x = foo<^");
4116 EXPECT_THAT(
4117 First.signatures,
4118 UnorderedElementsAre(sig("foo<[[typename T]], [[int]]>() -> bool"),
4119 sig("foo<[[int I]], [[int]]>() -> bool")));
4120 EXPECT_EQ(First.activeParameter, 0);
4121
4122 auto Second = signatures(Top + "bool x = foo<1, ^");
4123 EXPECT_THAT(Second.signatures,
4124 ElementsAre(sig("foo<[[int I]], [[int]]>() -> bool")));
4125 EXPECT_EQ(Second.activeParameter, 1);
4126}
4127
4128TEST(CompletionTest, DoNotCrash) {
4129 llvm::StringLiteral Cases[] = {
4130 R"cpp(
4131 template <typename = int> struct Foo {};
4132 auto a = [x(3)](Foo<^>){};
4133 )cpp",
4134 };
4135 for (auto Case : Cases) {
4136 SCOPED_TRACE(Case);
4137 auto Completions = completions(Case);
4138 }
4139}
4140
4141} // namespace
4142} // namespace clangd
4143} // namespace clang
ArrayRef< const ParmVarDecl * > Parameters
Definition: AST.cpp:816
llvm::SmallString< 256U > Name
const ParseInputs & ParseInput
size_t Offset
std::vector< CodeCompletionResult > Results
std::string Code
const Criteria C
CognitiveComplexity CC
std::optional< float > Score
std::string Text
CharSourceRange Range
SourceRange for the file name.
size_t Pos
Kind K
Definition: Rename.cpp:474
std::unique_ptr< CompilerInvocation > CI
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
std::optional< FixItHint > FixIt
#define EXPECT_IFF(condition, value, matcher)
static Options optsForTest()
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
Definition: MemIndex.cpp:17
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
Definition: URI.cpp:208
Symbol objcProtocol(llvm::StringRef Name)
Definition: TestIndex.cpp:112
Symbol objcClass(llvm::StringRef Name)
Definition: TestIndex.cpp:103
Symbol func(llvm::StringRef Name)
Definition: TestIndex.cpp:61
Symbol cls(llvm::StringRef Name)
Definition: TestIndex.cpp:65
Symbol objcCategory(llvm::StringRef Name, llvm::StringRef CategoryName)
Definition: TestIndex.cpp:107
std::string sortText(float Score, llvm::StringRef Name)
Returns a string that sorts in the same order as (-Score, Tiebreak), for LSP.
Definition: Quality.cpp:549
Symbol conceptSym(llvm::StringRef Name)
Definition: TestIndex.cpp:85
IndexContents
Describes what data is covered by an index.
Definition: Index.h:93
size_t lspLength(llvm::StringRef Code)
Definition: SourceCode.cpp:149
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, unsigned Offset)
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Definition: Compiler.cpp:95
CompletionItemKind
The kind of a completion entry.
Definition: Protocol.h:338
Symbol ns(llvm::StringRef Name)
Definition: TestIndex.cpp:81
bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset)
Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, llvm::StringRef USRFormat)
Definition: TestIndex.cpp:40
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
llvm::Expected< CodeCompleteResult > runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, clangd::CodeCompleteOptions Opts)
Definition: SyncAPI.cpp:72
MATCHER_P(named, N, "")
llvm::Expected< SignatureHelp > runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos, MarkupKind DocumentationFormat)
Definition: SyncAPI.cpp:79
std::string testPath(PathRef File, llvm::sys::path::Style Style)
Definition: TestFS.cpp:93
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback, PreambleBuildStats *Stats)
Build a preamble for the new inputs unless an old one can be reused.
Definition: Preamble.cpp:591
TEST(BackgroundQueueTest, Priority)
void wait(std::unique_lock< std::mutex > &Lock, std::condition_variable &CV, Deadline D)
Wait once on CV for the specified duration.
Definition: Threading.cpp:121
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:173
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, llvm::StringRef Version, WantDiagnostics WantDiags, bool ForceRebuild)
Definition: SyncAPI.cpp:17
@ No
Diagnostics must be generated for this snapshot.
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Definition: TestIndex.cpp:146
Symbol enmConstant(llvm::StringRef Name)
Definition: TestIndex.cpp:73
Deadline timeoutSeconds(std::optional< double > Seconds)
Makes a deadline from a timeout in seconds. std::nullopt means wait forever.
Definition: Threading.cpp:113
MATCHER(declared, "")
CodeCompleteResult codeComplete(PathRef FileName, Position Pos, const PreambleData *Preamble, const ParseInputs &ParseInput, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Gets code completions at a specified Pos in FileName.
@ PlainText
The primary text to be inserted is treated as a plain string.
@ Snippet
The primary text to be inserted is treated as a snippet.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
SignatureHelp signatureHelp(PathRef FileName, Position Pos, const PreambleData &Preamble, const ParseInputs &ParseInput, MarkupKind DocumentationFormat)
Get signature help at a specified Pos in FileName.
PolySubsequenceMatcher< Args... > HasSubsequence(Args &&... M)
Symbol var(llvm::StringRef Name)
Definition: TestIndex.cpp:77
std::array< uint8_t, 20 > SymbolID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::function< void(const CodeCompletion &, const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Score)> RecordCCResult
Callback invoked on all CompletionCandidate after they are scored and before they are ranked (by -Sco...
Definition: CodeComplete.h:131
MarkupKind DocumentationFormat
Whether to present doc comments as plain-text or markdown.
Definition: CodeComplete.h:66
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
Definition: CodeComplete.h:53
const SymbolIndex * Index
If Index is set, it is used to augment the code completion results.
Definition: CodeComplete.h:92
const ASTSignals * MainFileSignals
Definition: CodeComplete.h:94
std::function< DecisionForestScores(const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Base)> DecisionForestScorer
Callback used to score a CompletionCandidate if DecisionForest ranking model is enabled.
Definition: CodeComplete.h:147
CodeCompletionRankingModel RankingModel
Definition: CodeComplete.h:139
bool ImportInsertions
Whether include insertions for Objective-C code should use #import instead of #include.
Definition: CodeComplete.h:75
bool AllScopes
Whether to include index symbols that are not defined in the scopes visible from the code completion ...
Definition: CodeComplete.h:108
bool EnableFunctionArgSnippets
Whether to generate snippets for function arguments on code-completion.
Definition: CodeComplete.h:101
size_t Limit
Limit the number of results returned (0 means no limit).
Definition: CodeComplete.h:63
std::optional< bool > BundleOverloads
Combine overloads into a single completion item where possible.
Definition: CodeComplete.h:59
bool IncludeFixIts
Include completions that require small corrections, e.g.
Definition: CodeComplete.h:97
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
bool EnableSnippets
When true, completion items will contain expandable code snippets in completion (e....
Definition: CodeComplete.h:49
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
Definition: CodeComplete.h:85
std::vector< std::string > Scopes
If this is non-empty, symbols must be in at least one of the scopes (e.g.
Definition: Index.h:36
const SymbolIndex * Index
Definition: Compiler.h:58
@ IndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.
Definition: Symbol.h:141
@ Include
#include "header.h"
Definition: Symbol.h:93
@ Import
#import "header.h"
Definition: Symbol.h:95
SymbolID ID
The ID of the symbol.
Definition: Symbol.h:41
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
Definition: TestTU.h:42
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:36
std::unique_ptr< SymbolIndex > index() const
Definition: TestTU.cpp:175