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