[AMDGPU][AsmParser][NFC] Translate parsed MIMG instructions to MCInsts automatically.
[llvm-project.git] / clang-tools-extra / clangd / unittests / CodeCompleteTests.cpp
blobdd6ee4422447162cf8c33ef103fa69019e41f118
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 "Feature.h"
15 #include "Matchers.h"
16 #include "Protocol.h"
17 #include "Quality.h"
18 #include "SourceCode.h"
19 #include "SyncAPI.h"
20 #include "TestFS.h"
21 #include "TestIndex.h"
22 #include "TestTU.h"
23 #include "index/Index.h"
24 #include "index/MemIndex.h"
25 #include "index/SymbolOrigin.h"
26 #include "support/Threading.h"
27 #include "clang/Sema/CodeCompleteConsumer.h"
28 #include "clang/Tooling/CompilationDatabase.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Testing/Annotations/Annotations.h"
33 #include "llvm/Testing/Support/Error.h"
34 #include "llvm/Testing/Support/SupportHelpers.h"
35 #include "gmock/gmock.h"
36 #include "gtest/gtest.h"
37 #include <condition_variable>
38 #include <functional>
39 #include <mutex>
40 #include <vector>
42 namespace clang {
43 namespace clangd {
45 namespace {
46 using ::llvm::Failed;
47 using ::testing::AllOf;
48 using ::testing::Contains;
49 using ::testing::ElementsAre;
50 using ::testing::Field;
51 using ::testing::HasSubstr;
52 using ::testing::IsEmpty;
53 using ::testing::Not;
54 using ::testing::UnorderedElementsAre;
55 using ContextKind = CodeCompletionContext::Kind;
57 // GMock helpers for matching completion items.
58 MATCHER_P(named, Name, "") { return arg.Name == Name; }
59 MATCHER_P(mainFileRefs, Refs, "") { return arg.MainFileRefs == Refs; }
60 MATCHER_P(scopeRefs, Refs, "") { return arg.ScopeRefsInFile == Refs; }
61 MATCHER_P(nameStartsWith, Prefix, "") {
62 return llvm::StringRef(arg.Name).startswith(Prefix);
64 MATCHER_P(filterText, F, "") { return arg.FilterText == F; }
65 MATCHER_P(scope, S, "") { return arg.Scope == S; }
66 MATCHER_P(qualifier, Q, "") { return arg.RequiredQualifier == Q; }
67 MATCHER_P(labeled, Label, "") {
68 return arg.RequiredQualifier + arg.Name + arg.Signature == Label;
70 MATCHER_P(sigHelpLabeled, Label, "") { return arg.label == Label; }
71 MATCHER_P(kind, K, "") { return arg.Kind == K; }
72 MATCHER_P(doc, D, "") {
73 return arg.Documentation && arg.Documentation->asPlainText() == D;
75 MATCHER_P(returnType, D, "") { return arg.ReturnType == D; }
76 MATCHER_P(hasInclude, IncludeHeader, "") {
77 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader;
79 MATCHER_P(insertInclude, IncludeHeader, "") {
80 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader &&
81 bool(arg.Includes[0].Insertion);
83 MATCHER_P(insertIncludeText, InsertedText, "") {
84 return !arg.Includes.empty() && arg.Includes[0].Insertion &&
85 arg.Includes[0].Insertion->newText == InsertedText;
87 MATCHER(insertInclude, "") {
88 return !arg.Includes.empty() && bool(arg.Includes[0].Insertion);
90 MATCHER_P(snippetSuffix, Text, "") { return arg.SnippetSuffix == Text; }
91 MATCHER_P(origin, OriginSet, "") { return arg.Origin == OriginSet; }
92 MATCHER_P(signature, S, "") { return arg.Signature == S; }
93 MATCHER_P(replacesRange, Range, "") {
94 return arg.CompletionTokenRange == Range;
97 // Shorthand for Contains(named(Name)).
98 Matcher<const std::vector<CodeCompletion> &> has(std::string Name) {
99 return Contains(named(std::move(Name)));
101 Matcher<const std::vector<CodeCompletion> &> has(std::string Name,
102 CompletionItemKind K) {
103 return Contains(AllOf(named(std::move(Name)), kind(K)));
105 MATCHER(isDocumented, "") { return arg.Documentation.has_value(); }
106 MATCHER(deprecated, "") { return arg.Deprecated; }
108 std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) {
109 SymbolSlab::Builder Slab;
110 for (const auto &Sym : Symbols)
111 Slab.insert(Sym);
112 return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
115 // Runs code completion.
116 // If IndexSymbols is non-empty, an index will be built and passed to opts.
117 CodeCompleteResult completions(const TestTU &TU, Position Point,
118 std::vector<Symbol> IndexSymbols = {},
119 clangd::CodeCompleteOptions Opts = {}) {
120 std::unique_ptr<SymbolIndex> OverrideIndex;
121 if (!IndexSymbols.empty()) {
122 assert(!Opts.Index && "both Index and IndexSymbols given!");
123 OverrideIndex = memIndex(std::move(IndexSymbols));
124 Opts.Index = OverrideIndex.get();
127 MockFS FS;
128 auto Inputs = TU.inputs(FS);
129 IgnoreDiagnostics Diags;
130 auto CI = buildCompilerInvocation(Inputs, Diags);
131 if (!CI) {
132 ADD_FAILURE() << "Couldn't build CompilerInvocation";
133 return {};
135 auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
136 /*InMemory=*/true, /*Callback=*/nullptr);
137 return codeComplete(testPath(TU.Filename), Point, Preamble.get(), Inputs,
138 Opts);
141 // Runs code completion.
142 CodeCompleteResult completions(llvm::StringRef Text,
143 std::vector<Symbol> IndexSymbols = {},
144 clangd::CodeCompleteOptions Opts = {},
145 PathRef FilePath = "foo.cpp") {
146 Annotations Test(Text);
147 auto TU = TestTU::withCode(Test.code());
148 // To make sure our tests for completiopns inside templates work on Windows.
149 TU.Filename = FilePath.str();
150 return completions(TU, Test.point(), std::move(IndexSymbols),
151 std::move(Opts));
154 // Runs code completion without the clang parser.
155 CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
156 std::vector<Symbol> IndexSymbols = {},
157 clangd::CodeCompleteOptions Opts = {},
158 PathRef FilePath = "foo.cpp") {
159 std::unique_ptr<SymbolIndex> OverrideIndex;
160 if (!IndexSymbols.empty()) {
161 assert(!Opts.Index && "both Index and IndexSymbols given!");
162 OverrideIndex = memIndex(std::move(IndexSymbols));
163 Opts.Index = OverrideIndex.get();
166 MockFS FS;
167 Annotations Test(Text);
168 ParseInputs ParseInput{tooling::CompileCommand(), &FS, Test.code().str()};
169 return codeComplete(FilePath, Test.point(), /*Preamble=*/nullptr, ParseInput,
170 Opts);
173 Symbol withReferences(int N, Symbol S) {
174 S.References = N;
175 return S;
178 #if CLANGD_DECISION_FOREST
179 TEST(DecisionForestRankingModel, NameMatchSanityTest) {
180 clangd::CodeCompleteOptions Opts;
181 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
182 auto Results = completions(
183 R"cpp(
184 struct MemberAccess {
185 int ABG();
186 int AlphaBetaGamma();
188 int func() { MemberAccess().ABG^ }
189 )cpp",
190 /*IndexSymbols=*/{}, Opts);
191 EXPECT_THAT(Results.Completions,
192 ElementsAre(named("ABG"), named("AlphaBetaGamma")));
195 TEST(DecisionForestRankingModel, ReferencesAffectRanking) {
196 clangd::CodeCompleteOptions Opts;
197 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
198 constexpr int NumReferences = 100000;
199 EXPECT_THAT(
200 completions("int main() { clang^ }",
201 {ns("clangA"), withReferences(NumReferences, func("clangD"))},
202 Opts)
203 .Completions,
204 ElementsAre(named("clangD"), named("clangA")));
205 EXPECT_THAT(
206 completions("int main() { clang^ }",
207 {withReferences(NumReferences, ns("clangA")), func("clangD")},
208 Opts)
209 .Completions,
210 ElementsAre(named("clangA"), named("clangD")));
212 #endif // CLANGD_DECISION_FOREST
214 TEST(DecisionForestRankingModel, DecisionForestScorerCallbackTest) {
215 clangd::CodeCompleteOptions Opts;
216 constexpr float MagicNumber = 1234.5678f;
217 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
218 Opts.DecisionForestScorer = [&](const SymbolQualitySignals &,
219 const SymbolRelevanceSignals &, float Base) {
220 DecisionForestScores Scores;
221 Scores.Total = MagicNumber;
222 Scores.ExcludingName = MagicNumber;
223 return Scores;
225 llvm::StringRef Code = "int func() { int xyz; xy^ }";
226 auto Results = completions(Code,
227 /*IndexSymbols=*/{}, Opts);
228 ASSERT_EQ(Results.Completions.size(), 1u);
229 EXPECT_EQ(Results.Completions[0].Score.Total, MagicNumber);
230 EXPECT_EQ(Results.Completions[0].Score.ExcludingName, MagicNumber);
232 // Do not use DecisionForestScorer for heuristics model.
233 Opts.RankingModel = CodeCompleteOptions::Heuristics;
234 Results = completions(Code,
235 /*IndexSymbols=*/{}, Opts);
236 ASSERT_EQ(Results.Completions.size(), 1u);
237 EXPECT_NE(Results.Completions[0].Score.Total, MagicNumber);
238 EXPECT_NE(Results.Completions[0].Score.ExcludingName, MagicNumber);
241 TEST(CompletionTest, Limit) {
242 clangd::CodeCompleteOptions Opts;
243 Opts.Limit = 2;
244 auto Results = completions(R"cpp(
245 struct ClassWithMembers {
246 int AAA();
247 int BBB();
248 int CCC();
251 int main() { ClassWithMembers().^ }
252 )cpp",
253 /*IndexSymbols=*/{}, Opts);
255 EXPECT_TRUE(Results.HasMore);
256 EXPECT_THAT(Results.Completions, ElementsAre(named("AAA"), named("BBB")));
259 TEST(CompletionTest, Filter) {
260 std::string Body = R"cpp(
261 #define MotorCar
262 int Car;
263 struct S {
264 int FooBar;
265 int FooBaz;
266 int Qux;
268 )cpp";
270 // Only items matching the fuzzy query are returned.
271 EXPECT_THAT(completions(Body + "int main() { S().Foba^ }").Completions,
272 AllOf(has("FooBar"), has("FooBaz"), Not(has("Qux"))));
274 // Macros require prefix match, either from index or AST.
275 Symbol Sym = var("MotorCarIndex");
276 Sym.SymInfo.Kind = index::SymbolKind::Macro;
277 EXPECT_THAT(
278 completions(Body + "int main() { C^ }", {Sym}).Completions,
279 AllOf(has("Car"), Not(has("MotorCar")), Not(has("MotorCarIndex"))));
280 EXPECT_THAT(completions(Body + "int main() { M^ }", {Sym}).Completions,
281 AllOf(has("MotorCar"), has("MotorCarIndex")));
284 void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
285 auto Results = completions(
286 R"cpp(
287 int global_var;
289 int global_func();
291 // Make sure this is not in preamble.
292 #define MACRO X
294 struct GlobalClass {};
296 struct ClassWithMembers {
297 /// doc for method.
298 int method();
300 int field;
301 private:
302 int private_field;
305 int test() {
306 struct LocalClass {};
308 /// doc for local_var.
309 int local_var;
311 ClassWithMembers().^
313 )cpp",
314 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
316 EXPECT_TRUE(Results.RanParser);
317 // Class members. The only items that must be present in after-dot
318 // completion.
319 EXPECT_THAT(Results.Completions,
320 AllOf(has("method"), has("field"), Not(has("ClassWithMembers")),
321 Not(has("operator=")), Not(has("~ClassWithMembers"))));
322 EXPECT_IFF(Opts.IncludeIneligibleResults, Results.Completions,
323 has("private_field"));
324 // Global items.
325 EXPECT_THAT(
326 Results.Completions,
327 Not(AnyOf(has("global_var"), has("index_var"), has("global_func"),
328 has("global_func()"), has("index_func"), has("GlobalClass"),
329 has("IndexClass"), has("MACRO"), has("LocalClass"))));
330 // There should be no code patterns (aka snippets) in after-dot
331 // completion. At least there aren't any we're aware of.
332 EXPECT_THAT(Results.Completions,
333 Not(Contains(kind(CompletionItemKind::Snippet))));
334 // Check documentation.
335 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
338 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
339 auto Results = completions(
340 R"cpp(
341 int global_var;
342 int global_func();
344 // Make sure this is not in preamble.
345 #define MACRO X
347 struct GlobalClass {};
349 struct ClassWithMembers {
350 /// doc for method.
351 int method();
354 int test() {
355 struct LocalClass {};
357 /// doc for local_var.
358 int local_var;
362 )cpp",
363 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts);
365 EXPECT_TRUE(Results.RanParser);
366 // Class members. Should never be present in global completions.
367 EXPECT_THAT(Results.Completions,
368 Not(AnyOf(has("method"), has("method()"), has("field"))));
369 // Global items.
370 EXPECT_THAT(Results.Completions,
371 AllOf(has("global_var"), has("index_var"), has("global_func"),
372 has("index_func" /* our fake symbol doesn't include () */),
373 has("GlobalClass"), has("IndexClass")));
374 // A macro.
375 EXPECT_THAT(Results.Completions, has("MACRO"));
376 // Local items. Must be present always.
377 EXPECT_THAT(Results.Completions,
378 AllOf(has("local_var"), has("LocalClass"),
379 Contains(kind(CompletionItemKind::Snippet))));
380 // Check documentation.
381 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
384 TEST(CompletionTest, CompletionOptions) {
385 auto Test = [&](const clangd::CodeCompleteOptions &Opts) {
386 testAfterDotCompletion(Opts);
387 testGlobalScopeCompletion(Opts);
389 // We used to test every combination of options, but that got too slow (2^N).
390 auto Flags = {
391 &clangd::CodeCompleteOptions::IncludeIneligibleResults,
393 // Test default options.
394 Test({});
395 // Test with one flag flipped.
396 for (auto &F : Flags) {
397 clangd::CodeCompleteOptions O;
398 O.*F ^= true;
399 Test(O);
403 TEST(CompletionTest, Accessible) {
404 auto Internal = completions(R"cpp(
405 class Foo {
406 public: void pub();
407 protected: void prot();
408 private: void priv();
410 void Foo::pub() { this->^ }
411 )cpp");
412 EXPECT_THAT(Internal.Completions,
413 AllOf(has("priv"), has("prot"), has("pub")));
415 auto External = completions(R"cpp(
416 class Foo {
417 public: void pub();
418 protected: void prot();
419 private: void priv();
421 void test() {
422 Foo F;
425 )cpp");
426 EXPECT_THAT(External.Completions,
427 AllOf(has("pub"), Not(has("prot")), Not(has("priv"))));
429 auto Results = completions(R"cpp(
430 struct Foo {
431 public: void pub();
432 protected: void prot();
433 private: void priv();
435 struct Bar : public Foo {
436 private: using Foo::pub;
438 void test() {
439 Bar B;
442 )cpp");
443 EXPECT_THAT(Results.Completions,
444 AllOf(Not(has("priv")), Not(has("prot")), Not(has("pub"))));
447 TEST(CompletionTest, Qualifiers) {
448 auto Results = completions(R"cpp(
449 class Foo {
450 public: int foo() const;
451 int bar() const;
453 class Bar : public Foo {
454 int foo() const;
456 void test() { Bar().^ }
457 )cpp");
458 EXPECT_THAT(Results.Completions,
459 Contains(AllOf(qualifier(""), named("bar"))));
460 // Hidden members are not shown.
461 EXPECT_THAT(Results.Completions,
462 Not(Contains(AllOf(qualifier("Foo::"), named("foo")))));
463 // Private members are not shown.
464 EXPECT_THAT(Results.Completions,
465 Not(Contains(AllOf(qualifier(""), named("foo")))));
468 // https://github.com/clangd/clangd/issues/1451
469 TEST(CompletionTest, QualificationWithInlineNamespace) {
470 auto Results = completions(R"cpp(
471 namespace a { inline namespace b {} }
472 using namespace a::b;
473 void f() { Foo^ }
474 )cpp",
475 {cls("a::Foo")});
476 EXPECT_THAT(Results.Completions,
477 UnorderedElementsAre(AllOf(qualifier("a::"), named("Foo"))));
480 TEST(CompletionTest, InjectedTypename) {
481 // These are suppressed when accessed as a member...
482 EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions,
483 Not(has("X")));
484 EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions,
485 Not(has("X")));
486 // ...but accessible in other, more useful cases.
487 EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions,
488 has("X"));
489 EXPECT_THAT(
490 completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions,
491 has("Y"));
492 EXPECT_THAT(
493 completions(
494 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
495 .Completions,
496 has("Y"));
497 // This case is marginal (`using X::X` is useful), we allow it for now.
498 EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions,
499 has("X"));
502 TEST(CompletionTest, SkipInjectedWhenUnqualified) {
503 EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions,
504 ElementsAre(named("X"), named("~X")));
507 TEST(CompletionTest, Snippets) {
508 clangd::CodeCompleteOptions Opts;
509 auto Results = completions(
510 R"cpp(
511 struct fake {
512 int a;
513 int f(int i, const float f) const;
515 int main() {
516 fake f;
519 )cpp",
520 /*IndexSymbols=*/{}, Opts);
521 EXPECT_THAT(
522 Results.Completions,
523 HasSubsequence(named("a"),
524 snippetSuffix("(${1:int i}, ${2:const float f})")));
527 TEST(CompletionTest, HeuristicsForMemberFunctionCompletion) {
528 clangd::CodeCompleteOptions Opts;
529 Opts.EnableSnippets = true;
531 Annotations Code(R"cpp(
532 struct Foo {
533 static int staticMethod();
534 int method() const;
535 Foo() {
536 this->$keepSnippet^
537 $keepSnippet^
538 Foo::$keepSnippet^
542 struct Derived : Foo {
543 Derived() {
544 Foo::$keepSnippet^
548 struct OtherClass {
549 OtherClass() {
550 Foo f;
551 f.$keepSnippet^
552 &Foo::$noSnippet^
556 int main() {
557 Foo f;
558 f.$keepSnippet^
559 &Foo::$noSnippet^
561 )cpp");
562 auto TU = TestTU::withCode(Code.code());
564 for (const auto &P : Code.points("noSnippet")) {
565 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
566 EXPECT_THAT(Results.Completions,
567 Contains(AllOf(named("method"), snippetSuffix(""))));
570 for (const auto &P : Code.points("keepSnippet")) {
571 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
572 EXPECT_THAT(Results.Completions,
573 Contains(AllOf(named("method"), snippetSuffix("()"))));
576 // static method will always keep the snippet
577 for (const auto &P : Code.points()) {
578 auto Results = completions(TU, P, /*IndexSymbols*/ {}, Opts);
579 EXPECT_THAT(Results.Completions,
580 Contains(AllOf(named("staticMethod"), snippetSuffix("()"))));
584 TEST(CompletionTest, NoSnippetsInUsings) {
585 clangd::CodeCompleteOptions Opts;
586 Opts.EnableSnippets = true;
587 auto Results = completions(
588 R"cpp(
589 namespace ns {
590 int func(int a, int b);
593 using ns::^;
594 )cpp",
595 /*IndexSymbols=*/{}, Opts);
596 EXPECT_THAT(Results.Completions,
597 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
598 snippetSuffix(""))));
600 // Check index completions too.
601 auto Func = func("ns::func");
602 Func.CompletionSnippetSuffix = "(${1:int a}, ${2: int b})";
603 Func.Signature = "(int a, int b)";
604 Func.ReturnType = "void";
606 Results = completions(R"cpp(
607 namespace ns {}
608 using ns::^;
609 )cpp",
610 /*IndexSymbols=*/{Func}, Opts);
611 EXPECT_THAT(Results.Completions,
612 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
613 snippetSuffix(""))));
615 // Check all-scopes completions too.
616 Opts.AllScopes = true;
617 Results = completions(R"cpp(
618 using ^;
619 )cpp",
620 /*IndexSymbols=*/{Func}, Opts);
621 EXPECT_THAT(Results.Completions,
622 Contains(AllOf(named("func"), labeled("ns::func(int a, int b)"),
623 snippetSuffix(""))));
626 TEST(CompletionTest, Kinds) {
627 auto Results = completions(
628 R"cpp(
629 int variable;
630 struct Struct {};
631 int function();
632 // make sure MACRO is not included in preamble.
633 #define MACRO 10
634 int X = ^
635 )cpp",
636 {func("indexFunction"), var("indexVariable"), cls("indexClass")});
637 EXPECT_THAT(Results.Completions,
638 AllOf(has("function", CompletionItemKind::Function),
639 has("variable", CompletionItemKind::Variable),
640 has("int", CompletionItemKind::Keyword),
641 has("Struct", CompletionItemKind::Struct),
642 has("MACRO", CompletionItemKind::Constant),
643 has("indexFunction", CompletionItemKind::Function),
644 has("indexVariable", CompletionItemKind::Variable),
645 has("indexClass", CompletionItemKind::Class)));
647 Results = completions("nam^");
648 EXPECT_THAT(Results.Completions,
649 has("namespace", CompletionItemKind::Snippet));
651 // Members of anonymous unions are of kind 'field'.
652 Results = completions(
653 R"cpp(
654 struct X{
655 union {
656 void *a;
659 auto u = X().^
660 )cpp");
661 EXPECT_THAT(
662 Results.Completions,
663 UnorderedElementsAre(AllOf(named("a"), kind(CompletionItemKind::Field))));
665 // Completion kinds for templates should not be unknown.
666 Results = completions(
667 R"cpp(
668 template <class T> struct complete_class {};
669 template <class T> void complete_function();
670 template <class T> using complete_type_alias = int;
671 template <class T> int complete_variable = 10;
673 struct X {
674 template <class T> static int complete_static_member = 10;
676 static auto x = complete_^
678 )cpp");
679 EXPECT_THAT(
680 Results.Completions,
681 UnorderedElementsAre(
682 AllOf(named("complete_class"), kind(CompletionItemKind::Class)),
683 AllOf(named("complete_function"), kind(CompletionItemKind::Function)),
684 AllOf(named("complete_type_alias"),
685 kind(CompletionItemKind::Interface)),
686 AllOf(named("complete_variable"), kind(CompletionItemKind::Variable)),
687 AllOf(named("complete_static_member"),
688 kind(CompletionItemKind::Property))));
690 Results = completions(
691 R"cpp(
692 enum Color {
695 Color u = ^
696 )cpp");
697 EXPECT_THAT(
698 Results.Completions,
699 Contains(AllOf(named("Red"), kind(CompletionItemKind::EnumMember))));
702 TEST(CompletionTest, NoDuplicates) {
703 auto Results = completions(
704 R"cpp(
705 class Adapter {
708 void f() {
709 Adapter^
711 )cpp",
712 {cls("Adapter")});
714 // Make sure there are no duplicate entries of 'Adapter'.
715 EXPECT_THAT(Results.Completions, ElementsAre(named("Adapter")));
718 TEST(CompletionTest, ScopedNoIndex) {
719 auto Results = completions(
720 R"cpp(
721 namespace fake { int BigBang, Babble, Box; };
722 int main() { fake::ba^ }
723 ")cpp");
724 // Babble is a better match than BigBang. Box doesn't match at all.
725 EXPECT_THAT(Results.Completions,
726 ElementsAre(named("Babble"), named("BigBang")));
729 TEST(CompletionTest, Scoped) {
730 auto Results = completions(
731 R"cpp(
732 namespace fake { int Babble, Box; };
733 int main() { fake::ba^ }
734 ")cpp",
735 {var("fake::BigBang")});
736 EXPECT_THAT(Results.Completions,
737 ElementsAre(named("Babble"), named("BigBang")));
740 TEST(CompletionTest, ScopedWithFilter) {
741 auto Results = completions(
742 R"cpp(
743 void f() { ns::x^ }
744 )cpp",
745 {cls("ns::XYZ"), func("ns::foo")});
746 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("XYZ")));
749 TEST(CompletionTest, ReferencesAffectRanking) {
750 EXPECT_THAT(completions("int main() { abs^ }", {func("absA"), func("absB")})
751 .Completions,
752 HasSubsequence(named("absA"), named("absB")));
753 EXPECT_THAT(completions("int main() { abs^ }",
754 {func("absA"), withReferences(1000, func("absB"))})
755 .Completions,
756 HasSubsequence(named("absB"), named("absA")));
759 TEST(CompletionTest, ContextWords) {
760 auto Results = completions(R"cpp(
761 enum class Color { RED, YELLOW, BLUE };
763 // (blank lines so the definition above isn't "context")
765 // "It was a yellow car," he said. "Big yellow car, new."
766 auto Finish = Color::^
767 )cpp");
768 // Yellow would normally sort last (alphabetic).
769 // But the recent mention should bump it up.
770 ASSERT_THAT(Results.Completions,
771 HasSubsequence(named("YELLOW"), named("BLUE")));
774 TEST(CompletionTest, GlobalQualified) {
775 auto Results = completions(
776 R"cpp(
777 void f() { ::^ }
778 )cpp",
779 {cls("XYZ")});
780 EXPECT_THAT(Results.Completions,
781 AllOf(has("XYZ", CompletionItemKind::Class),
782 has("f", CompletionItemKind::Function)));
785 TEST(CompletionTest, FullyQualified) {
786 auto Results = completions(
787 R"cpp(
788 namespace ns { void bar(); }
789 void f() { ::ns::^ }
790 )cpp",
791 {cls("ns::XYZ")});
792 EXPECT_THAT(Results.Completions,
793 AllOf(has("XYZ", CompletionItemKind::Class),
794 has("bar", CompletionItemKind::Function)));
797 TEST(CompletionTest, SemaIndexMerge) {
798 auto Results = completions(
799 R"cpp(
800 namespace ns { int local; void both(); }
801 void f() { ::ns::^ }
802 )cpp",
803 {func("ns::both"), cls("ns::Index")});
804 // We get results from both index and sema, with no duplicates.
805 EXPECT_THAT(Results.Completions,
806 UnorderedElementsAre(
807 AllOf(named("local"), origin(SymbolOrigin::AST)),
808 AllOf(named("Index"), origin(SymbolOrigin::Static)),
809 AllOf(named("both"),
810 origin(SymbolOrigin::AST | SymbolOrigin::Static))));
813 TEST(CompletionTest, SemaIndexMergeWithLimit) {
814 clangd::CodeCompleteOptions Opts;
815 Opts.Limit = 1;
816 auto Results = completions(
817 R"cpp(
818 namespace ns { int local; void both(); }
819 void f() { ::ns::^ }
820 )cpp",
821 {func("ns::both"), cls("ns::Index")}, Opts);
822 EXPECT_EQ(Results.Completions.size(), Opts.Limit);
823 EXPECT_TRUE(Results.HasMore);
826 TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
827 TestTU TU;
828 TU.ExtraArgs.push_back("-I" + testPath("sub"));
829 TU.AdditionalFiles["sub/bar.h"] = "";
830 auto BarURI = URI::create(testPath("sub/bar.h")).toString();
832 Symbol Sym = cls("ns::X");
833 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
834 Sym.IncludeHeaders.emplace_back(BarURI, 1, Symbol::Include);
835 // Shorten include path based on search directory and insert.
836 Annotations Test("int main() { ns::^ }");
837 TU.Code = Test.code().str();
838 auto Results = completions(TU, Test.point(), {Sym});
839 EXPECT_THAT(Results.Completions,
840 ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
841 // Can be disabled via option.
842 CodeCompleteOptions NoInsertion;
843 NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert;
844 Results = completions(TU, Test.point(), {Sym}, NoInsertion);
845 EXPECT_THAT(Results.Completions,
846 ElementsAre(AllOf(named("X"), Not(insertInclude()))));
847 // Duplicate based on inclusions in preamble.
848 Test = Annotations(R"cpp(
849 #include "sub/bar.h" // not shortest, so should only match resolved.
850 int main() { ns::^ }
851 )cpp");
852 TU.Code = Test.code().str();
853 Results = completions(TU, Test.point(), {Sym});
854 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(named("X"), labeled("X"),
855 Not(insertInclude()))));
858 TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
859 Symbol SymX = cls("ns::X");
860 Symbol SymY = cls("ns::Y");
861 std::string BarHeader = testPath("bar.h");
862 auto BarURI = URI::create(BarHeader).toString();
863 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
864 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
865 SymX.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
866 SymY.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
867 // Shorten include path based on search directory and insert.
868 auto Results = completions(R"cpp(
869 namespace ns {
870 class X;
871 class Y {};
873 int main() { ns::^ }
874 )cpp",
875 {SymX, SymY});
876 EXPECT_THAT(Results.Completions,
877 ElementsAre(AllOf(named("X"), Not(insertInclude())),
878 AllOf(named("Y"), Not(insertInclude()))));
881 TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
882 Annotations Test(R"cpp(
883 #include "bar.h"
884 namespace ns { int local; }
885 void f() { ns::^; }
886 void f2() { ns::preamble().$2^; }
887 )cpp");
888 auto TU = TestTU::withCode(Test.code());
889 TU.AdditionalFiles["bar.h"] =
890 R"cpp(namespace ns { struct preamble { int member; }; })cpp";
892 clangd::CodeCompleteOptions Opts = {};
893 auto I = memIndex({var("ns::index")});
894 Opts.Index = I.get();
895 auto WithIndex = completions(TU, Test.point(), {}, Opts);
896 EXPECT_THAT(WithIndex.Completions,
897 UnorderedElementsAre(named("local"), named("index")));
898 auto ClassFromPreamble = completions(TU, Test.point("2"), {}, Opts);
899 EXPECT_THAT(ClassFromPreamble.Completions, Contains(named("member")));
901 Opts.Index = nullptr;
902 auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
903 EXPECT_THAT(WithoutIndex.Completions,
904 UnorderedElementsAre(named("local"), named("preamble")));
907 // This verifies that we get normal preprocessor completions in the preamble.
908 // This is a regression test for an old bug: if we override the preamble and
909 // try to complete inside it, clang kicks our completion point just outside the
910 // preamble, resulting in always getting top-level completions.
911 TEST(CompletionTest, CompletionInPreamble) {
912 auto Results = completions(R"cpp(
913 #ifnd^ef FOO_H_
914 #define BAR_H_
915 #include <bar.h>
916 int foo() {}
917 #endif
918 )cpp")
919 .Completions;
920 EXPECT_THAT(Results, ElementsAre(named("ifndef")));
923 TEST(CompletionTest, CompletionRecoveryASTType) {
924 auto Results = completions(R"cpp(
925 struct S { int member; };
926 S overloaded(int);
927 void foo() {
928 // No overload matches, but we have recovery-expr with the correct type.
929 overloaded().^
930 })cpp")
931 .Completions;
932 EXPECT_THAT(Results, ElementsAre(named("member")));
935 TEST(CompletionTest, DynamicIndexIncludeInsertion) {
936 MockFS FS;
937 MockCompilationDatabase CDB;
938 ClangdServer::Options Opts = ClangdServer::optsForTest();
939 Opts.BuildDynamicSymbolIndex = true;
940 ClangdServer Server(CDB, FS, Opts);
942 FS.Files[testPath("foo_header.h")] = R"cpp(
943 #pragma once
944 struct Foo {
945 // Member doc
946 int foo();
948 )cpp";
949 const std::string FileContent(R"cpp(
950 #include "foo_header.h"
951 int Foo::foo() {
952 return 42;
954 )cpp");
955 Server.addDocument(testPath("foo_impl.cpp"), FileContent);
956 // Wait for the dynamic index being built.
957 ASSERT_TRUE(Server.blockUntilIdleForTest());
959 auto File = testPath("foo.cpp");
960 Annotations Test("Foo^ foo;");
961 runAddDocument(Server, File, Test.code());
962 auto CompletionList =
963 llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
965 EXPECT_THAT(CompletionList.Completions,
966 ElementsAre(AllOf(named("Foo"), hasInclude("\"foo_header.h\""),
967 insertInclude())));
970 TEST(CompletionTest, DynamicIndexMultiFile) {
971 MockFS FS;
972 MockCompilationDatabase CDB;
973 auto Opts = ClangdServer::optsForTest();
974 Opts.BuildDynamicSymbolIndex = true;
975 ClangdServer Server(CDB, FS, Opts);
977 FS.Files[testPath("foo.h")] = R"cpp(
978 namespace ns { class XYZ {}; void foo(int x) {} }
979 )cpp";
980 runAddDocument(Server, testPath("foo.cpp"), R"cpp(
981 #include "foo.h"
982 )cpp");
984 auto File = testPath("bar.cpp");
985 Annotations Test(R"cpp(
986 namespace ns {
987 class XXX {};
988 /// Doooc
989 void fooooo() {}
991 void f() { ns::^ }
992 )cpp");
993 runAddDocument(Server, File, Test.code());
995 auto Results = cantFail(runCodeComplete(Server, File, Test.point(), {}));
996 // "XYZ" and "foo" are not included in the file being completed but are still
997 // visible through the index.
998 EXPECT_THAT(Results.Completions, has("XYZ", CompletionItemKind::Class));
999 EXPECT_THAT(Results.Completions, has("foo", CompletionItemKind::Function));
1000 EXPECT_THAT(Results.Completions, has("XXX", CompletionItemKind::Class));
1001 EXPECT_THAT(Results.Completions,
1002 Contains((named("fooooo"), kind(CompletionItemKind::Function),
1003 doc("Doooc"), returnType("void"))));
1006 TEST(CompletionTest, Documentation) {
1007 auto Results = completions(
1008 R"cpp(
1009 // Non-doxygen comment.
1010 __attribute__((annotate("custom_annotation"))) int foo();
1011 /// Doxygen comment.
1012 /// \param int a
1013 int bar(int a);
1014 /* Multi-line
1015 block comment
1017 int baz();
1019 int x = ^
1020 )cpp");
1021 EXPECT_THAT(Results.Completions,
1022 Contains(AllOf(
1023 named("foo"),
1024 doc("Annotation: custom_annotation\nNon-doxygen comment."))));
1025 EXPECT_THAT(
1026 Results.Completions,
1027 Contains(AllOf(named("bar"), doc("Doxygen comment.\n\\param int a"))));
1028 EXPECT_THAT(Results.Completions,
1029 Contains(AllOf(named("baz"), doc("Multi-line block comment"))));
1032 TEST(CompletionTest, CommentsFromSystemHeaders) {
1033 MockFS FS;
1034 MockCompilationDatabase CDB;
1036 auto Opts = ClangdServer::optsForTest();
1037 Opts.BuildDynamicSymbolIndex = true;
1039 ClangdServer Server(CDB, FS, Opts);
1041 FS.Files[testPath("foo.h")] = R"cpp(
1042 #pragma GCC system_header
1044 // This comment should be retained!
1045 int foo();
1046 )cpp";
1048 auto File = testPath("foo.cpp");
1049 Annotations Test(R"cpp(
1050 #include "foo.h"
1051 int x = foo^
1052 )cpp");
1053 runAddDocument(Server, File, Test.code());
1054 auto CompletionList =
1055 llvm::cantFail(runCodeComplete(Server, File, Test.point(), {}));
1057 EXPECT_THAT(
1058 CompletionList.Completions,
1059 Contains(AllOf(named("foo"), doc("This comment should be retained!"))));
1062 TEST(CompletionTest, GlobalCompletionFiltering) {
1064 Symbol Class = cls("XYZ");
1065 Class.Flags = static_cast<Symbol::SymbolFlag>(
1066 Class.Flags & ~(Symbol::IndexedForCodeCompletion));
1067 Symbol Func = func("XYZ::foooo");
1068 Func.Flags = static_cast<Symbol::SymbolFlag>(
1069 Func.Flags & ~(Symbol::IndexedForCodeCompletion));
1071 auto Results = completions(R"(// void f() {
1072 XYZ::foooo^
1073 })",
1074 {Class, Func});
1075 EXPECT_THAT(Results.Completions, IsEmpty());
1078 TEST(CodeCompleteTest, DisableTypoCorrection) {
1079 auto Results = completions(R"cpp(
1080 namespace clang { int v; }
1081 void f() { clangd::^
1082 )cpp");
1083 EXPECT_TRUE(Results.Completions.empty());
1086 TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
1087 auto Results = completions(R"cpp(
1088 namespace clang { }
1089 void f() {
1090 clan^
1092 )cpp");
1094 EXPECT_THAT(Results.Completions, Contains(labeled("clang")));
1095 EXPECT_THAT(Results.Completions, Not(Contains(labeled("clang::"))));
1098 TEST(CompletionTests, EmptySnippetDoesNotCrash) {
1099 // See https://github.com/clangd/clangd/issues/1216
1100 auto Results = completions(R"cpp(
1101 int main() {
1102 auto w = [&](auto &&f) { return f(f); };
1103 auto f = w([&](auto &&f) {
1104 return [&](auto &&n) {
1105 if (n == 0) {
1106 return 1;
1108 return n * ^(f)(n - 1);
1110 })(10);
1112 )cpp");
1115 TEST(CompletionTest, Issue1427Crash) {
1116 // Need to provide main file signals to ensure that the branch in
1117 // SymbolRelevanceSignals::computeASTSignals() that tries to
1118 // compute a symbol ID is taken.
1119 ASTSignals MainFileSignals;
1120 CodeCompleteOptions Opts;
1121 Opts.MainFileSignals = &MainFileSignals;
1122 completions(R"cpp(
1123 auto f = []() {
1124 1.0_^
1126 )cpp",
1127 {}, Opts);
1130 TEST(CompletionTest, BacktrackCrashes) {
1131 // Sema calls code completion callbacks twice in these cases.
1132 auto Results = completions(R"cpp(
1133 namespace ns {
1134 struct FooBarBaz {};
1135 } // namespace ns
1137 int foo(ns::FooBar^
1138 )cpp");
1140 EXPECT_THAT(Results.Completions, ElementsAre(labeled("FooBarBaz")));
1142 // Check we don't crash in that case too.
1143 completions(R"cpp(
1144 struct FooBarBaz {};
1145 void test() {
1146 if (FooBarBaz * x^) {}
1148 )cpp");
1151 TEST(CompletionTest, CompleteInMacroWithStringification) {
1152 auto Results = completions(R"cpp(
1153 void f(const char *, int x);
1154 #define F(x) f(#x, x)
1156 namespace ns {
1157 int X;
1158 int Y;
1159 } // namespace ns
1161 int f(int input_num) {
1162 F(ns::^)
1164 )cpp");
1166 EXPECT_THAT(Results.Completions,
1167 UnorderedElementsAre(named("X"), named("Y")));
1170 TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
1171 auto Results = completions(R"cpp(
1172 void f(const char *, int x);
1173 #define F(x) f(#x, x)
1175 namespace ns {
1176 int X;
1178 int f(int input_num) {
1179 F(^)
1181 } // namespace ns
1182 )cpp");
1184 EXPECT_THAT(Results.Completions, Contains(named("X")));
1187 TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
1188 auto Results = completions(R"cpp(
1189 int bar(int param_in_bar) {
1192 int foo(int param_in_foo) {
1193 #if 0
1194 // In recovery mode, "param_in_foo" will also be suggested among many other
1195 // unrelated symbols; however, this is really a special case where this works.
1196 // If the #if block is outside of the function, "param_in_foo" is still
1197 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
1198 // really provide useful results in excluded branches.
1199 par^
1200 #endif
1202 )cpp");
1204 EXPECT_TRUE(Results.Completions.empty());
1207 TEST(CompletionTest, DefaultArgs) {
1208 clangd::CodeCompleteOptions Opts;
1209 std::string Context = R"cpp(
1210 int X(int A = 0);
1211 int Y(int A, int B = 0);
1212 int Z(int A, int B = 0, int C = 0, int D = 0);
1213 )cpp";
1214 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions,
1215 UnorderedElementsAre(labeled("X(int A = 0)")));
1216 EXPECT_THAT(completions(Context + "int y = Y^", {}, Opts).Completions,
1217 UnorderedElementsAre(AllOf(labeled("Y(int A, int B = 0)"),
1218 snippetSuffix("(${1:int A})"))));
1219 EXPECT_THAT(completions(Context + "int y = Z^", {}, Opts).Completions,
1220 UnorderedElementsAre(
1221 AllOf(labeled("Z(int A, int B = 0, int C = 0, int D = 0)"),
1222 snippetSuffix("(${1:int A})"))));
1225 TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) {
1226 auto Completions = completions(R"cpp(
1227 template <template <class> class TT> int foo() {
1228 int a = ^
1230 )cpp")
1231 .Completions;
1232 EXPECT_THAT(Completions, Contains(named("TT")));
1235 TEST(CompletionTest, NestedTemplateHeuristics) {
1236 auto Completions = completions(R"cpp(
1237 struct Plain { int xxx; };
1238 template <typename T> class Templ { Plain ppp; };
1239 template <typename T> void foo(Templ<T> &t) {
1240 // Formally ppp has DependentTy, because Templ may be specialized.
1241 // However we sholud be able to see into it using the primary template.
1242 t.ppp.^
1244 )cpp")
1245 .Completions;
1246 EXPECT_THAT(Completions, Contains(named("xxx")));
1249 TEST(CompletionTest, RecordCCResultCallback) {
1250 std::vector<CodeCompletion> RecordedCompletions;
1251 CodeCompleteOptions Opts;
1252 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC,
1253 const SymbolQualitySignals &,
1254 const SymbolRelevanceSignals &,
1255 float Score) {
1256 RecordedCompletions.push_back(CC);
1259 completions("int xy1, xy2; int a = xy^", /*IndexSymbols=*/{}, Opts);
1260 EXPECT_THAT(RecordedCompletions,
1261 UnorderedElementsAre(named("xy1"), named("xy2")));
1264 TEST(CompletionTest, ASTSignals) {
1265 struct Completion {
1266 std::string Name;
1267 unsigned MainFileRefs;
1268 unsigned ScopeRefsInFile;
1270 CodeCompleteOptions Opts;
1271 std::vector<Completion> RecordedCompletions;
1272 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC,
1273 const SymbolQualitySignals &,
1274 const SymbolRelevanceSignals &R,
1275 float Score) {
1276 RecordedCompletions.push_back({CC.Name, R.MainFileRefs, R.ScopeRefsInFile});
1278 ASTSignals MainFileSignals;
1279 MainFileSignals.ReferencedSymbols[var("xy1").ID] = 3;
1280 MainFileSignals.ReferencedSymbols[var("xy2").ID] = 1;
1281 MainFileSignals.ReferencedSymbols[var("xyindex").ID] = 10;
1282 MainFileSignals.RelatedNamespaces["tar::"] = 5;
1283 MainFileSignals.RelatedNamespaces["bar::"] = 3;
1284 Opts.MainFileSignals = &MainFileSignals;
1285 Opts.AllScopes = true;
1286 completions(
1287 R"cpp(
1288 int xy1;
1289 int xy2;
1290 namespace bar {
1291 int xybar = 1;
1292 int a = xy^
1294 )cpp",
1295 /*IndexSymbols=*/{var("xyindex"), var("tar::xytar"), var("bar::xybar")},
1296 Opts);
1297 EXPECT_THAT(RecordedCompletions,
1298 UnorderedElementsAre(
1299 AllOf(named("xy1"), mainFileRefs(3u), scopeRefs(0u)),
1300 AllOf(named("xy2"), mainFileRefs(1u), scopeRefs(0u)),
1301 AllOf(named("xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1302 AllOf(named("xytar"), mainFileRefs(0u), scopeRefs(5u)),
1303 AllOf(/*both from sema and index*/ named("xybar"),
1304 mainFileRefs(0u), scopeRefs(3u))));
1307 SignatureHelp
1308 signatures(llvm::StringRef Text, Position Point,
1309 std::vector<Symbol> IndexSymbols = {},
1310 MarkupKind DocumentationFormat = MarkupKind::PlainText) {
1311 std::unique_ptr<SymbolIndex> Index;
1312 if (!IndexSymbols.empty())
1313 Index = memIndex(IndexSymbols);
1315 auto TU = TestTU::withCode(Text);
1316 MockFS FS;
1317 auto Inputs = TU.inputs(FS);
1318 Inputs.Index = Index.get();
1319 IgnoreDiagnostics Diags;
1320 auto CI = buildCompilerInvocation(Inputs, Diags);
1321 if (!CI) {
1322 ADD_FAILURE() << "Couldn't build CompilerInvocation";
1323 return {};
1325 auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
1326 /*InMemory=*/true, /*Callback=*/nullptr);
1327 if (!Preamble) {
1328 ADD_FAILURE() << "Couldn't build Preamble";
1329 return {};
1331 return signatureHelp(testPath(TU.Filename), Point, *Preamble, Inputs,
1332 DocumentationFormat);
1335 SignatureHelp
1336 signatures(llvm::StringRef Text, std::vector<Symbol> IndexSymbols = {},
1337 MarkupKind DocumentationFormat = MarkupKind::PlainText) {
1338 Annotations Test(Text);
1339 return signatures(Test.code(), Test.point(), std::move(IndexSymbols),
1340 DocumentationFormat);
1343 struct ExpectedParameter {
1344 std::string Text;
1345 std::pair<unsigned, unsigned> Offsets;
1347 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1348 const ExpectedParameter &P) {
1349 return OS << P.Text;
1351 MATCHER_P(paramsAre, P, "") {
1352 if (P.size() != arg.parameters.size())
1353 return false;
1354 for (unsigned I = 0; I < P.size(); ++I) {
1355 if (P[I].Text != arg.parameters[I].labelString ||
1356 P[I].Offsets != arg.parameters[I].labelOffsets)
1357 return false;
1359 return true;
1361 MATCHER_P(sigDoc, doc, "") { return arg.documentation.value == doc; }
1363 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g.
1364 /// foo([[int p1]], [[double p2]]) -> void
1365 Matcher<SignatureInformation> sig(llvm::StringRef AnnotatedLabel) {
1366 llvm::Annotations A(AnnotatedLabel);
1367 std::string Label = std::string(A.code());
1368 std::vector<ExpectedParameter> Parameters;
1369 for (auto Range : A.ranges()) {
1370 Parameters.emplace_back();
1372 ExpectedParameter &P = Parameters.back();
1373 P.Text = Label.substr(Range.Begin, Range.End - Range.Begin);
1374 P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin));
1375 P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End));
1377 return AllOf(sigHelpLabeled(Label), paramsAre(Parameters));
1380 TEST(SignatureHelpTest, Overloads) {
1381 auto Results = signatures(R"cpp(
1382 void foo(int x, int y);
1383 void foo(int x, float y);
1384 void foo(float x, int y);
1385 void foo(float x, float y);
1386 void bar(int x, int y = 0);
1387 int main() { foo(^); }
1388 )cpp");
1389 EXPECT_THAT(Results.signatures,
1390 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1391 sig("foo([[float x]], [[int y]]) -> void"),
1392 sig("foo([[int x]], [[float y]]) -> void"),
1393 sig("foo([[int x]], [[int y]]) -> void")));
1394 // We always prefer the first signature.
1395 EXPECT_EQ(0, Results.activeSignature);
1396 EXPECT_EQ(0, Results.activeParameter);
1399 TEST(SignatureHelpTest, FunctionPointers) {
1400 auto FunctionPointerResults = signatures(R"cpp(
1401 void (*foo)(int x, int y);
1402 int main() { foo(^); }
1403 )cpp");
1404 EXPECT_THAT(FunctionPointerResults.signatures,
1405 UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1407 auto FunctionPointerTypedefResults = signatures(R"cpp(
1408 typedef void (*fn)(int x, int y);
1409 fn foo;
1410 int main() { foo(^); }
1411 )cpp");
1412 EXPECT_THAT(FunctionPointerTypedefResults.signatures,
1413 UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1416 TEST(SignatureHelpTest, Constructors) {
1417 std::string Top = R"cpp(
1418 struct S {
1419 S(int);
1420 S(const S &) = delete;
1422 )cpp";
1424 auto CheckParenInit = [&](std::string Init) {
1425 EXPECT_THAT(signatures(Top + Init).signatures,
1426 UnorderedElementsAre(sig("S([[int]])")))
1427 << Init;
1429 CheckParenInit("S s(^);");
1430 CheckParenInit("auto s = S(^);");
1431 CheckParenInit("auto s = new S(^);");
1433 auto CheckBracedInit = [&](std::string Init) {
1434 EXPECT_THAT(signatures(Top + Init).signatures,
1435 UnorderedElementsAre(sig("S{[[int]]}")))
1436 << Init;
1438 CheckBracedInit("S s{^};");
1439 CheckBracedInit("S s = {^};");
1440 CheckBracedInit("auto s = S{^};");
1441 // FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression.
1442 // CheckBracedInit("auto s = new S{^};");
1443 CheckBracedInit("int x(S); int i = x({^});");
1446 TEST(SignatureHelpTest, Aggregates) {
1447 std::string Top = R"cpp(
1448 struct S {
1449 int a, b, c, d;
1451 )cpp";
1452 auto AggregateSig = sig("S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1453 EXPECT_THAT(signatures(Top + "S s{^}").signatures,
1454 UnorderedElementsAre(AggregateSig, sig("S{}"),
1455 sig("S{[[const S &]]}"),
1456 sig("S{[[S &&]]}")));
1457 EXPECT_THAT(signatures(Top + "S s{1,^}").signatures,
1458 ElementsAre(AggregateSig));
1459 EXPECT_EQ(signatures(Top + "S s{1,^}").activeParameter, 1);
1460 EXPECT_THAT(signatures(Top + "S s{.c=3,^}").signatures,
1461 ElementsAre(AggregateSig));
1462 EXPECT_EQ(signatures(Top + "S s{.c=3,^}").activeParameter, 3);
1465 TEST(SignatureHelpTest, OverloadInitListRegression) {
1466 auto Results = signatures(R"cpp(
1467 struct A {int x;};
1468 struct B {B(A);};
1469 void f();
1470 int main() {
1471 B b({1});
1472 f(^);
1474 )cpp");
1475 EXPECT_THAT(Results.signatures, UnorderedElementsAre(sig("f() -> void")));
1478 TEST(SignatureHelpTest, DefaultArgs) {
1479 auto Results = signatures(R"cpp(
1480 void bar(int x, int y = 0);
1481 void bar(float x = 0, int y = 42);
1482 int main() { bar(^
1483 )cpp");
1484 EXPECT_THAT(Results.signatures,
1485 UnorderedElementsAre(
1486 sig("bar([[int x]], [[int y = 0]]) -> void"),
1487 sig("bar([[float x = 0]], [[int y = 42]]) -> void")));
1488 EXPECT_EQ(0, Results.activeSignature);
1489 EXPECT_EQ(0, Results.activeParameter);
1492 TEST(SignatureHelpTest, ActiveArg) {
1493 auto Results = signatures(R"cpp(
1494 int baz(int a, int b, int c);
1495 int main() { baz(baz(1,2,3), ^); }
1496 )cpp");
1497 EXPECT_THAT(Results.signatures,
1498 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1499 EXPECT_EQ(0, Results.activeSignature);
1500 EXPECT_EQ(1, Results.activeParameter);
1503 TEST(SignatureHelpTest, OpeningParen) {
1504 llvm::StringLiteral Tests[] = {
1505 // Recursive function call.
1506 R"cpp(
1507 int foo(int a, int b, int c);
1508 int main() {
1509 foo(foo $p^( foo(10, 10, 10), ^ )));
1510 })cpp",
1511 // Functional type cast.
1512 R"cpp(
1513 struct Foo {
1514 Foo(int a, int b, int c);
1516 int main() {
1517 Foo $p^( 10, ^ );
1518 })cpp",
1519 // New expression.
1520 R"cpp(
1521 struct Foo {
1522 Foo(int a, int b, int c);
1524 int main() {
1525 new Foo $p^( 10, ^ );
1526 })cpp",
1527 // Macro expansion.
1528 R"cpp(
1529 int foo(int a, int b, int c);
1530 #define FOO foo(
1532 int main() {
1533 // Macro expansions.
1534 $p^FOO 10, ^ );
1535 })cpp",
1536 // Macro arguments.
1537 R"cpp(
1538 int foo(int a, int b, int c);
1539 int main() {
1540 #define ID(X) X
1541 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1542 // the recovery expression.
1543 ID(foo $p^( 10, ^ ))
1544 })cpp",
1545 // Dependent args.
1546 R"cpp(
1547 int foo(int a, int b);
1548 template <typename T> void bar(T t) {
1549 foo$p^(t, ^t);
1550 })cpp",
1551 // Dependent args on templated func.
1552 R"cpp(
1553 template <typename T>
1554 int foo(T, T);
1555 template <typename T> void bar(T t) {
1556 foo$p^(t, ^t);
1557 })cpp",
1558 // Dependent args on member.
1559 R"cpp(
1560 struct Foo { int foo(int, int); };
1561 template <typename T> void bar(T t) {
1562 Foo f;
1563 f.foo$p^(t, ^t);
1564 })cpp",
1565 // Dependent args on templated member.
1566 R"cpp(
1567 struct Foo { template <typename T> int foo(T, T); };
1568 template <typename T> void bar(T t) {
1569 Foo f;
1570 f.foo$p^(t, ^t);
1571 })cpp",
1574 for (auto Test : Tests) {
1575 Annotations Code(Test);
1576 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
1577 Code.point("p"))
1578 << "Test source:" << Test;
1582 TEST(SignatureHelpTest, StalePreamble) {
1583 TestTU TU;
1584 TU.Code = "";
1585 IgnoreDiagnostics Diags;
1586 MockFS FS;
1587 auto Inputs = TU.inputs(FS);
1588 auto CI = buildCompilerInvocation(Inputs, Diags);
1589 ASSERT_TRUE(CI);
1590 auto EmptyPreamble = buildPreamble(testPath(TU.Filename), *CI, Inputs,
1591 /*InMemory=*/true, /*Callback=*/nullptr);
1592 ASSERT_TRUE(EmptyPreamble);
1594 TU.AdditionalFiles["a.h"] = "int foo(int x);";
1595 const Annotations Test(R"cpp(
1596 #include "a.h"
1597 void bar() { foo(^2); })cpp");
1598 TU.Code = Test.code().str();
1599 auto Results =
1600 signatureHelp(testPath(TU.Filename), Test.point(), *EmptyPreamble,
1601 TU.inputs(FS), MarkupKind::PlainText);
1602 EXPECT_THAT(Results.signatures, ElementsAre(sig("foo([[int x]]) -> int")));
1603 EXPECT_EQ(0, Results.activeSignature);
1604 EXPECT_EQ(0, Results.activeParameter);
1607 class IndexRequestCollector : public SymbolIndex {
1608 public:
1609 IndexRequestCollector(std::vector<Symbol> Syms = {}) : Symbols(Syms) {}
1611 bool
1612 fuzzyFind(const FuzzyFindRequest &Req,
1613 llvm::function_ref<void(const Symbol &)> Callback) const override {
1614 std::unique_lock<std::mutex> Lock(Mut);
1615 Requests.push_back(Req);
1616 ReceivedRequestCV.notify_one();
1617 for (const auto &Sym : Symbols)
1618 Callback(Sym);
1619 return true;
1622 void lookup(const LookupRequest &,
1623 llvm::function_ref<void(const Symbol &)>) const override {}
1625 bool refs(const RefsRequest &,
1626 llvm::function_ref<void(const Ref &)>) const override {
1627 return false;
1630 void relations(const RelationsRequest &,
1631 llvm::function_ref<void(const SymbolID &, const Symbol &)>)
1632 const override {}
1634 llvm::unique_function<IndexContents(llvm::StringRef) const>
1635 indexedFiles() const override {
1636 return [](llvm::StringRef) { return IndexContents::None; };
1639 // This is incorrect, but IndexRequestCollector is not an actual index and it
1640 // isn't used in production code.
1641 size_t estimateMemoryUsage() const override { return 0; }
1643 const std::vector<FuzzyFindRequest> consumeRequests(size_t Num) const {
1644 std::unique_lock<std::mutex> Lock(Mut);
1645 EXPECT_TRUE(wait(Lock, ReceivedRequestCV, timeoutSeconds(30),
1646 [this, Num] { return Requests.size() == Num; }));
1647 auto Reqs = std::move(Requests);
1648 Requests = {};
1649 return Reqs;
1652 private:
1653 std::vector<Symbol> Symbols;
1654 // We need a mutex to handle async fuzzy find requests.
1655 mutable std::condition_variable ReceivedRequestCV;
1656 mutable std::mutex Mut;
1657 mutable std::vector<FuzzyFindRequest> Requests;
1660 // Clients have to consume exactly Num requests.
1661 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code,
1662 size_t Num = 1) {
1663 clangd::CodeCompleteOptions Opts;
1664 IndexRequestCollector Requests;
1665 Opts.Index = &Requests;
1666 completions(Code, {}, Opts);
1667 const auto Reqs = Requests.consumeRequests(Num);
1668 EXPECT_EQ(Reqs.size(), Num);
1669 return Reqs;
1672 TEST(CompletionTest, UnqualifiedIdQuery) {
1673 auto Requests = captureIndexRequests(R"cpp(
1674 namespace std {}
1675 using namespace std;
1676 namespace ns {
1677 void f() {
1678 vec^
1681 )cpp");
1683 EXPECT_THAT(Requests,
1684 ElementsAre(Field(&FuzzyFindRequest::Scopes,
1685 UnorderedElementsAre("", "ns::", "std::"))));
1688 TEST(CompletionTest, EnclosingScopeComesFirst) {
1689 auto Requests = captureIndexRequests(R"cpp(
1690 namespace std {}
1691 using namespace std;
1692 namespace nx {
1693 namespace ns {
1694 namespace {
1695 void f() {
1696 vec^
1701 )cpp");
1703 EXPECT_THAT(Requests,
1704 ElementsAre(Field(
1705 &FuzzyFindRequest::Scopes,
1706 UnorderedElementsAre("", "std::", "nx::ns::", "nx::"))));
1707 EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::");
1710 TEST(CompletionTest, ResolvedQualifiedIdQuery) {
1711 auto Requests = captureIndexRequests(R"cpp(
1712 namespace ns1 {}
1713 namespace ns2 {} // ignore
1714 namespace ns3 { namespace nns3 {} }
1715 namespace foo {
1716 using namespace ns1;
1717 using namespace ns3::nns3;
1719 namespace ns {
1720 void f() {
1721 foo::^
1724 )cpp");
1726 EXPECT_THAT(Requests,
1727 ElementsAre(Field(
1728 &FuzzyFindRequest::Scopes,
1729 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::"))));
1732 TEST(CompletionTest, UnresolvedQualifierIdQuery) {
1733 auto Requests = captureIndexRequests(R"cpp(
1734 namespace a {}
1735 using namespace a;
1736 namespace ns {
1737 void f() {
1738 bar::^
1740 } // namespace ns
1741 )cpp");
1743 EXPECT_THAT(Requests,
1744 ElementsAre(Field(
1745 &FuzzyFindRequest::Scopes,
1746 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
1749 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
1750 auto Requests = captureIndexRequests(R"cpp(
1751 namespace a {}
1752 using namespace a;
1753 namespace ns {
1754 void f() {
1755 ::a::bar::^
1757 } // namespace ns
1758 )cpp");
1760 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1761 UnorderedElementsAre("a::bar::"))));
1764 TEST(CompletionTest, EmptyQualifiedQuery) {
1765 auto Requests = captureIndexRequests(R"cpp(
1766 namespace ns {
1767 void f() {
1770 } // namespace ns
1771 )cpp");
1773 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1774 UnorderedElementsAre("", "ns::"))));
1777 TEST(CompletionTest, GlobalQualifiedQuery) {
1778 auto Requests = captureIndexRequests(R"cpp(
1779 namespace ns {
1780 void f() {
1783 } // namespace ns
1784 )cpp");
1786 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes,
1787 UnorderedElementsAre(""))));
1790 TEST(CompletionTest, NoDuplicatedQueryScopes) {
1791 auto Requests = captureIndexRequests(R"cpp(
1792 namespace {}
1794 namespace na {
1795 namespace {}
1796 namespace nb {
1798 } // namespace nb
1799 } // namespace na
1800 )cpp");
1802 EXPECT_THAT(Requests,
1803 ElementsAre(Field(&FuzzyFindRequest::Scopes,
1804 UnorderedElementsAre("na::", "na::nb::", ""))));
1807 TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
1808 auto Completions = completions(
1809 R"cpp(
1810 struct Foo {
1811 int SomeNameOfField;
1812 typedef int SomeNameOfTypedefField;
1815 Foo::^)cpp",
1816 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
1818 EXPECT_THAT(Completions.Completions,
1819 AllOf(Contains(labeled("SomeNameOfField")),
1820 Contains(labeled("SomeNameOfTypedefField")),
1821 Not(Contains(labeled("SomeNameInTheIndex")))));
1824 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
1826 auto Completions = completions(
1827 R"cpp(
1828 template <class T>
1829 void foo() {
1830 T::^
1832 )cpp",
1833 {func("::SomeNameInTheIndex")});
1835 EXPECT_THAT(Completions.Completions,
1836 Not(Contains(labeled("SomeNameInTheIndex"))));
1840 auto Completions = completions(
1841 R"cpp(
1842 template <class T>
1843 void foo() {
1844 T::template Y<int>::^
1846 )cpp",
1847 {func("::SomeNameInTheIndex")});
1849 EXPECT_THAT(Completions.Completions,
1850 Not(Contains(labeled("SomeNameInTheIndex"))));
1854 auto Completions = completions(
1855 R"cpp(
1856 template <class T>
1857 void foo() {
1858 T::foo::^
1860 )cpp",
1861 {func("::SomeNameInTheIndex")});
1863 EXPECT_THAT(Completions.Completions,
1864 Not(Contains(labeled("SomeNameInTheIndex"))));
1868 TEST(CompletionTest, OverloadBundling) {
1869 clangd::CodeCompleteOptions Opts;
1870 Opts.BundleOverloads = true;
1872 std::string Context = R"cpp(
1873 struct X {
1874 // Overload with int
1875 int a(int) __attribute__((deprecated("", "")));
1876 // Overload with bool
1877 int a(bool);
1878 int b(float);
1880 X(int);
1881 X(float);
1883 int GFuncC(int);
1884 int GFuncD(int);
1885 )cpp";
1887 // Member completions are bundled.
1888 EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions,
1889 UnorderedElementsAre(labeled("a(…)"), labeled("b(float)")));
1891 // Constructor completions are bundled.
1892 EXPECT_THAT(completions(Context + "X z = X^", {}, Opts).Completions,
1893 UnorderedElementsAre(labeled("X"), labeled("X(…)")));
1895 // Non-member completions are bundled, including index+sema.
1896 Symbol NoArgsGFunc = func("GFuncC");
1897 EXPECT_THAT(
1898 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1899 UnorderedElementsAre(labeled("GFuncC(…)"), labeled("GFuncD(int)")));
1901 // Differences in header-to-insert suppress bundling.
1902 std::string DeclFile = URI::create(testPath("foo")).toString();
1903 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
1904 NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1, Symbol::Include);
1905 EXPECT_THAT(
1906 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1907 UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")),
1908 labeled("GFuncC(int)"), labeled("GFuncD(int)")));
1910 // Examine a bundled completion in detail.
1911 auto A =
1912 completions(Context + "int y = X().a^", {}, Opts).Completions.front();
1913 EXPECT_EQ(A.Name, "a");
1914 EXPECT_EQ(A.Signature, "(…)");
1915 EXPECT_EQ(A.BundleSize, 2u);
1916 EXPECT_EQ(A.Kind, CompletionItemKind::Method);
1917 EXPECT_EQ(A.ReturnType, "int"); // All overloads return int.
1918 // For now we just return one of the doc strings arbitrarily.
1919 ASSERT_TRUE(A.Documentation);
1920 ASSERT_FALSE(A.Deprecated); // Not all overloads deprecated.
1921 EXPECT_THAT(
1922 A.Documentation->asPlainText(),
1923 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool")));
1924 EXPECT_EQ(A.SnippetSuffix, "($0)");
1927 TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
1928 clangd::CodeCompleteOptions Opts;
1929 Opts.BundleOverloads = true;
1931 Symbol SymX = sym("ns::X", index::SymbolKind::Function, "@F@\\0#");
1932 Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#");
1933 std::string BarHeader = testPath("bar.h");
1934 auto BarURI = URI::create(BarHeader).toString();
1935 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
1936 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
1937 // The include header is different, but really it's the same file.
1938 SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1, Symbol::Include);
1939 SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1, Symbol::Include);
1941 auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts);
1942 // Expect both results are bundled, despite the different-but-same
1943 // IncludeHeader.
1944 ASSERT_EQ(1u, Results.Completions.size());
1945 const auto &R = Results.Completions.front();
1946 EXPECT_EQ("X", R.Name);
1947 EXPECT_EQ(2u, R.BundleSize);
1950 TEST(CompletionTest, DocumentationFromChangedFileCrash) {
1951 MockFS FS;
1952 auto FooH = testPath("foo.h");
1953 auto FooCpp = testPath("foo.cpp");
1954 FS.Files[FooH] = R"cpp(
1955 // this is my documentation comment.
1956 int func();
1957 )cpp";
1958 FS.Files[FooCpp] = "";
1960 MockCompilationDatabase CDB;
1961 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
1963 Annotations Source(R"cpp(
1964 #include "foo.h"
1965 int func() {
1966 // This makes sure we have func from header in the AST.
1968 int a = fun^
1969 )cpp");
1970 Server.addDocument(FooCpp, Source.code(), "null", WantDiagnostics::Yes);
1971 // We need to wait for preamble to build.
1972 ASSERT_TRUE(Server.blockUntilIdleForTest());
1974 // Change the header file. Completion will reuse the old preamble!
1975 FS.Files[FooH] = R"cpp(
1976 int func();
1977 )cpp";
1979 clangd::CodeCompleteOptions Opts;
1980 CodeCompleteResult Completions =
1981 cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts));
1982 // We shouldn't crash. Unfortunately, current workaround is to not produce
1983 // comments for symbols from headers.
1984 EXPECT_THAT(Completions.Completions,
1985 Contains(AllOf(Not(isDocumented()), named("func"))));
1988 TEST(CompletionTest, NonDocComments) {
1989 const char *Text = R"cpp(
1990 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
1991 namespace comments_ns {
1994 // ------------------
1995 int comments_foo();
1997 // A comment and a decl are separated by newlines.
1998 // Therefore, the comment shouldn't show up as doc comment.
2000 int comments_bar();
2002 // this comment should be in the results.
2003 int comments_baz();
2006 template <class T>
2007 struct Struct {
2008 int comments_qux();
2009 int comments_quux();
2013 // This comment should not be there.
2015 template <class T>
2016 int Struct<T>::comments_qux() {
2019 // This comment **should** be in results.
2020 template <class T>
2021 int Struct<T>::comments_quux() {
2022 int a = comments^;
2024 )cpp";
2026 // We should not get any of those comments in completion.
2027 EXPECT_THAT(
2028 completions(Text).Completions,
2029 UnorderedElementsAre(AllOf(Not(isDocumented()), named("comments_foo")),
2030 AllOf(isDocumented(), named("comments_baz")),
2031 AllOf(isDocumented(), named("comments_quux")),
2032 AllOf(Not(isDocumented()), named("comments_ns")),
2033 // FIXME(ibiryukov): the following items should have
2034 // empty documentation, since they are separated from
2035 // a comment with an empty line. Unfortunately, I
2036 // couldn't make Sema tests pass if we ignore those.
2037 AllOf(isDocumented(), named("comments_bar")),
2038 AllOf(isDocumented(), named("comments_qux"))));
2041 TEST(CompletionTest, CompleteOnInvalidLine) {
2042 auto FooCpp = testPath("foo.cpp");
2044 MockCompilationDatabase CDB;
2045 MockFS FS;
2046 FS.Files[FooCpp] = "// empty file";
2048 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2049 // Run completion outside the file range.
2050 Position Pos;
2051 Pos.line = 100;
2052 Pos.character = 0;
2053 EXPECT_THAT_EXPECTED(
2054 runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()),
2055 Failed());
2058 TEST(CompletionTest, QualifiedNames) {
2059 auto Results = completions(
2060 R"cpp(
2061 namespace ns { int local; void both(); }
2062 void f() { ::ns::^ }
2063 )cpp",
2064 {func("ns::both"), cls("ns::Index")});
2065 // We get results from both index and sema, with no duplicates.
2066 EXPECT_THAT(
2067 Results.Completions,
2068 UnorderedElementsAre(scope("ns::"), scope("ns::"), scope("ns::")));
2071 TEST(CompletionTest, Render) {
2072 CodeCompletion C;
2073 C.Name = "x";
2074 C.FilterText = "x";
2075 C.Signature = "(bool) const";
2076 C.SnippetSuffix = "(${0:bool})";
2077 C.ReturnType = "int";
2078 C.RequiredQualifier = "Foo::";
2079 C.Scope = "ns::Foo::";
2080 C.Documentation.emplace();
2081 C.Documentation->addParagraph().appendText("This is ").appendCode("x()");
2082 C.Includes.emplace_back();
2083 auto &Include = C.Includes.back();
2084 Include.Header = "\"foo.h\"";
2085 C.Kind = CompletionItemKind::Method;
2086 C.Score.Total = 1.0;
2087 C.Score.ExcludingName = .5;
2088 C.Origin = SymbolOrigin::AST | SymbolOrigin::Static;
2090 CodeCompleteOptions Opts;
2091 Opts.IncludeIndicator.Insert = "^";
2092 Opts.IncludeIndicator.NoInsert = "";
2093 Opts.EnableSnippets = false;
2095 auto R = C.render(Opts);
2096 EXPECT_EQ(R.label, "Foo::x");
2097 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2098 EXPECT_EQ(R.insertText, "Foo::x");
2099 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText);
2100 EXPECT_EQ(R.filterText, "x");
2101 EXPECT_EQ(R.detail, "int");
2102 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()");
2103 EXPECT_THAT(R.additionalTextEdits, IsEmpty());
2104 EXPECT_EQ(R.sortText, sortText(1.0, "x"));
2105 EXPECT_FALSE(R.deprecated);
2106 EXPECT_EQ(R.score, .5f);
2108 C.FilterText = "xtra";
2109 R = C.render(Opts);
2110 EXPECT_EQ(R.filterText, "xtra");
2111 EXPECT_EQ(R.sortText, sortText(1.0, "xtra"));
2113 Opts.EnableSnippets = true;
2114 R = C.render(Opts);
2115 EXPECT_EQ(R.insertText, "Foo::x(${0:bool})");
2116 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet);
2118 C.SnippetSuffix = "";
2119 R = C.render(Opts);
2120 EXPECT_EQ(R.insertText, "Foo::x");
2121 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText);
2123 Include.Insertion.emplace();
2124 R = C.render(Opts);
2125 EXPECT_EQ(R.label, "^Foo::x");
2126 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2127 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
2129 Opts.ShowOrigins = true;
2130 R = C.render(Opts);
2131 EXPECT_EQ(R.label, "^[AS]Foo::x");
2132 EXPECT_EQ(R.labelDetails->detail, "(bool) const");
2134 C.BundleSize = 2;
2135 R = C.render(Opts);
2136 EXPECT_EQ(R.detail, "[2 overloads]");
2137 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()");
2139 C.Deprecated = true;
2140 R = C.render(Opts);
2141 EXPECT_TRUE(R.deprecated);
2143 Opts.DocumentationFormat = MarkupKind::Markdown;
2144 R = C.render(Opts);
2145 EXPECT_EQ(R.documentation->value, "From `\"foo.h\"` \nThis is `x()`");
2148 TEST(CompletionTest, IgnoreRecoveryResults) {
2149 auto Results = completions(
2150 R"cpp(
2151 namespace ns { int NotRecovered() { return 0; } }
2152 void f() {
2153 // Sema enters recovery mode first and then normal mode.
2154 if (auto x = ns::NotRecover^)
2156 )cpp");
2157 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("NotRecovered")));
2160 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
2161 auto Results = completions(
2162 R"cpp(
2163 namespace ns {
2164 class X { public: X(); int x_; };
2165 X::X() : x_^(0) {}
2167 )cpp");
2168 EXPECT_THAT(Results.Completions,
2169 UnorderedElementsAre(AllOf(scope("ns::X::"), named("x_"))));
2172 // Like other class members, constructor init lists have to parse what's below,
2173 // after the completion point.
2174 // But recovering from an incomplete constructor init list is particularly
2175 // tricky because the bulk of the list is not surrounded by brackets.
2176 TEST(CompletionTest, ConstructorInitListIncomplete) {
2177 auto Results = completions(
2178 R"cpp(
2179 namespace ns {
2180 struct X {
2181 X() : x^
2182 int xyz_;
2185 )cpp");
2186 EXPECT_THAT(Results.Completions, ElementsAre(named("xyz_")));
2188 Results = completions(
2189 R"cpp(
2190 int foo();
2192 namespace ns {
2193 struct X {
2194 X() : xyz_(fo^
2195 int xyz_;
2198 )cpp");
2199 EXPECT_THAT(Results.Completions, ElementsAre(named("foo")));
2202 TEST(CompletionTest, CodeCompletionContext) {
2203 auto Results = completions(
2204 R"cpp(
2205 namespace ns {
2206 class X { public: X(); int x_; };
2207 void f() {
2208 X x;
2209 x.^;
2212 )cpp");
2214 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
2217 TEST(CompletionTest, FixItForArrowToDot) {
2218 MockFS FS;
2219 MockCompilationDatabase CDB;
2221 CodeCompleteOptions Opts;
2222 Opts.IncludeFixIts = true;
2223 const char *Code =
2224 R"cpp(
2225 class Auxilary {
2226 public:
2227 void AuxFunction();
2229 class ClassWithPtr {
2230 public:
2231 void MemberFunction();
2232 Auxilary* operator->() const;
2233 Auxilary* Aux;
2235 void f() {
2236 ClassWithPtr x;
2237 x[[->]]^;
2239 )cpp";
2240 auto Results = completions(Code, {}, Opts);
2241 EXPECT_EQ(Results.Completions.size(), 3u);
2243 TextEdit ReplacementEdit;
2244 ReplacementEdit.range = Annotations(Code).range();
2245 ReplacementEdit.newText = ".";
2246 for (const auto &C : Results.Completions) {
2247 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction");
2248 if (!C.FixIts.empty()) {
2249 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
2254 TEST(CompletionTest, FixItForDotToArrow) {
2255 CodeCompleteOptions Opts;
2256 Opts.IncludeFixIts = true;
2257 const char *Code =
2258 R"cpp(
2259 class Auxilary {
2260 public:
2261 void AuxFunction();
2263 class ClassWithPtr {
2264 public:
2265 void MemberFunction();
2266 Auxilary* operator->() const;
2267 Auxilary* Aux;
2269 void f() {
2270 ClassWithPtr x;
2271 x[[.]]^;
2273 )cpp";
2274 auto Results = completions(Code, {}, Opts);
2275 EXPECT_EQ(Results.Completions.size(), 3u);
2277 TextEdit ReplacementEdit;
2278 ReplacementEdit.range = Annotations(Code).range();
2279 ReplacementEdit.newText = "->";
2280 for (const auto &C : Results.Completions) {
2281 EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction");
2282 if (!C.FixIts.empty()) {
2283 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
2288 TEST(CompletionTest, RenderWithFixItMerged) {
2289 TextEdit FixIt;
2290 FixIt.range.end.character = 5;
2291 FixIt.newText = "->";
2293 CodeCompletion C;
2294 C.Name = "x";
2295 C.RequiredQualifier = "Foo::";
2296 C.FixIts = {FixIt};
2297 C.CompletionTokenRange.start.character = 5;
2299 CodeCompleteOptions Opts;
2300 Opts.IncludeFixIts = true;
2302 auto R = C.render(Opts);
2303 EXPECT_TRUE(R.textEdit);
2304 EXPECT_EQ(R.textEdit->newText, "->Foo::x");
2305 EXPECT_TRUE(R.additionalTextEdits.empty());
2308 TEST(CompletionTest, RenderWithFixItNonMerged) {
2309 TextEdit FixIt;
2310 FixIt.range.end.character = 4;
2311 FixIt.newText = "->";
2313 CodeCompletion C;
2314 C.Name = "x";
2315 C.RequiredQualifier = "Foo::";
2316 C.FixIts = {FixIt};
2317 C.CompletionTokenRange.start.character = 5;
2319 CodeCompleteOptions Opts;
2320 Opts.IncludeFixIts = true;
2322 auto R = C.render(Opts);
2323 EXPECT_TRUE(R.textEdit);
2324 EXPECT_EQ(R.textEdit->newText, "Foo::x");
2325 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt));
2328 TEST(CompletionTest, CompletionTokenRange) {
2329 MockFS FS;
2330 MockCompilationDatabase CDB;
2331 TestTU TU;
2332 TU.AdditionalFiles["foo/abc/foo.h"] = "";
2334 constexpr const char *TestCodes[] = {
2335 R"cpp(
2336 class Auxilary {
2337 public:
2338 void AuxFunction();
2340 void f() {
2341 Auxilary x;
2342 x.[[Aux]]^;
2344 )cpp",
2345 R"cpp(
2346 class Auxilary {
2347 public:
2348 void AuxFunction();
2350 void f() {
2351 Auxilary x;
2352 x.[[]]^;
2354 )cpp",
2355 R"cpp(
2356 #include "foo/[[a^/]]foo.h"
2357 )cpp",
2358 R"cpp(
2359 #include "foo/abc/[[fo^o.h"]]
2360 )cpp",
2362 for (const auto &Text : TestCodes) {
2363 Annotations TestCode(Text);
2364 TU.Code = TestCode.code().str();
2365 auto Results = completions(TU, TestCode.point());
2366 if (Results.Completions.size() != 1) {
2367 ADD_FAILURE() << "Results.Completions.size() != 1" << Text;
2368 continue;
2370 EXPECT_THAT(Results.Completions.front().CompletionTokenRange,
2371 TestCode.range());
2375 TEST(SignatureHelpTest, OverloadsOrdering) {
2376 const auto Results = signatures(R"cpp(
2377 void foo(int x);
2378 void foo(int x, float y);
2379 void foo(float x, int y);
2380 void foo(float x, float y);
2381 void foo(int x, int y = 0);
2382 int main() { foo(^); }
2383 )cpp");
2384 EXPECT_THAT(Results.signatures,
2385 ElementsAre(sig("foo([[int x]]) -> void"),
2386 sig("foo([[int x]], [[int y = 0]]) -> void"),
2387 sig("foo([[float x]], [[int y]]) -> void"),
2388 sig("foo([[int x]], [[float y]]) -> void"),
2389 sig("foo([[float x]], [[float y]]) -> void")));
2390 // We always prefer the first signature.
2391 EXPECT_EQ(0, Results.activeSignature);
2392 EXPECT_EQ(0, Results.activeParameter);
2395 TEST(SignatureHelpTest, InstantiatedSignatures) {
2396 StringRef Sig0 = R"cpp(
2397 template <class T>
2398 void foo(T, T, T);
2400 int main() {
2401 foo<int>(^);
2403 )cpp";
2405 EXPECT_THAT(signatures(Sig0).signatures,
2406 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2408 StringRef Sig1 = R"cpp(
2409 template <class T>
2410 void foo(T, T, T);
2412 int main() {
2413 foo(10, ^);
2414 })cpp";
2416 EXPECT_THAT(signatures(Sig1).signatures,
2417 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2419 StringRef Sig2 = R"cpp(
2420 template <class ...T>
2421 void foo(T...);
2423 int main() {
2424 foo<int>(^);
2426 )cpp";
2428 EXPECT_THAT(signatures(Sig2).signatures,
2429 ElementsAre(sig("foo([[T...]]) -> void")));
2431 // It is debatable whether we should substitute the outer template parameter
2432 // ('T') in that case. Currently we don't substitute it in signature help, but
2433 // do substitute in code complete.
2434 // FIXME: make code complete and signature help consistent, figure out which
2435 // way is better.
2436 StringRef Sig3 = R"cpp(
2437 template <class T>
2438 struct X {
2439 template <class U>
2440 void foo(T, U);
2443 int main() {
2444 X<int>().foo<double>(^)
2446 )cpp";
2448 EXPECT_THAT(signatures(Sig3).signatures,
2449 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2452 TEST(SignatureHelpTest, IndexDocumentation) {
2453 Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#");
2454 Foo0.Documentation = "doc from the index";
2455 Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#");
2456 Foo1.Documentation = "doc from the index";
2457 Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#");
2459 StringRef Sig0 = R"cpp(
2460 int foo();
2461 int foo(double);
2463 void test() {
2464 foo(^);
2466 )cpp";
2468 EXPECT_THAT(
2469 signatures(Sig0, {Foo0}).signatures,
2470 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2471 AllOf(sig("foo([[double]]) -> int"), sigDoc(""))));
2473 StringRef Sig1 = R"cpp(
2474 int foo();
2475 // Overriden doc from sema
2476 int foo(int);
2477 // doc from sema
2478 int foo(int, int);
2480 void test() {
2481 foo(^);
2483 )cpp";
2485 EXPECT_THAT(
2486 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
2487 ElementsAre(
2488 AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2489 AllOf(sig("foo([[int]]) -> int"), sigDoc("Overriden doc from sema")),
2490 AllOf(sig("foo([[int]], [[int]]) -> int"), sigDoc("doc from sema"))));
2493 TEST(SignatureHelpTest, DynamicIndexDocumentation) {
2494 MockFS FS;
2495 MockCompilationDatabase CDB;
2496 ClangdServer::Options Opts = ClangdServer::optsForTest();
2497 Opts.BuildDynamicSymbolIndex = true;
2498 ClangdServer Server(CDB, FS, Opts);
2500 FS.Files[testPath("foo.h")] = R"cpp(
2501 struct Foo {
2502 // Member doc
2503 int foo();
2505 )cpp";
2506 Annotations FileContent(R"cpp(
2507 #include "foo.h"
2508 void test() {
2509 Foo f;
2510 f.foo(^);
2512 )cpp");
2513 auto File = testPath("test.cpp");
2514 Server.addDocument(File, FileContent.code());
2515 // Wait for the dynamic index being built.
2516 ASSERT_TRUE(Server.blockUntilIdleForTest());
2517 EXPECT_THAT(llvm::cantFail(runSignatureHelp(Server, File, FileContent.point(),
2518 MarkupKind::PlainText))
2519 .signatures,
2520 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
2523 TEST(CompletionTest, CompletionFunctionArgsDisabled) {
2524 CodeCompleteOptions Opts;
2525 Opts.EnableSnippets = true;
2526 Opts.EnableFunctionArgSnippets = false;
2529 auto Results = completions(
2530 R"cpp(
2531 void xfoo();
2532 void xfoo(int x, int y);
2533 void f() { xfo^ })cpp",
2534 {}, Opts);
2535 EXPECT_THAT(
2536 Results.Completions,
2537 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("()")),
2538 AllOf(named("xfoo"), snippetSuffix("($0)"))));
2541 auto Results = completions(
2542 R"cpp(
2543 void xbar();
2544 void f() { xba^ })cpp",
2545 {}, Opts);
2546 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2547 named("xbar"), snippetSuffix("()"))));
2550 Opts.BundleOverloads = true;
2551 auto Results = completions(
2552 R"cpp(
2553 void xfoo();
2554 void xfoo(int x, int y);
2555 void f() { xfo^ })cpp",
2556 {}, Opts);
2557 EXPECT_THAT(
2558 Results.Completions,
2559 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("($0)"))));
2562 auto Results = completions(
2563 R"cpp(
2564 template <class T, class U>
2565 void xfoo(int a, U b);
2566 void f() { xfo^ })cpp",
2567 {}, Opts);
2568 EXPECT_THAT(
2569 Results.Completions,
2570 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("<$1>($0)"))));
2573 auto Results = completions(
2574 R"cpp(
2575 template <class T>
2576 class foo_class{};
2577 template <class T>
2578 using foo_alias = T**;
2579 void f() { foo_^ })cpp",
2580 {}, Opts);
2581 EXPECT_THAT(
2582 Results.Completions,
2583 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
2584 AllOf(named("foo_alias"), snippetSuffix("<$0>"))));
2587 auto Results = completions(
2588 R"cpp(
2589 #define FOO(x, y) x##f
2590 FO^ )cpp",
2591 {}, Opts);
2592 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2593 named("FOO"), snippetSuffix("($0)"))));
2597 TEST(CompletionTest, SuggestOverrides) {
2598 constexpr const char *const Text(R"cpp(
2599 class A {
2600 public:
2601 virtual void vfunc(bool param);
2602 virtual void vfunc(bool param, int p);
2603 void func(bool param);
2605 class B : public A {
2606 virtual void ttt(bool param) const;
2607 void vfunc(bool param, int p) override;
2609 class C : public B {
2610 public:
2611 void vfunc(bool param) override;
2614 )cpp");
2615 const auto Results = completions(Text);
2616 EXPECT_THAT(
2617 Results.Completions,
2618 AllOf(Contains(AllOf(labeled("void vfunc(bool param, int p) override"),
2619 nameStartsWith("vfunc"))),
2620 Contains(AllOf(labeled("void ttt(bool param) const override"),
2621 nameStartsWith("ttt"))),
2622 Not(Contains(labeled("void vfunc(bool param) override")))));
2625 TEST(CompletionTest, OverridesNonIdentName) {
2626 // Check the completions call does not crash.
2627 completions(R"cpp(
2628 struct Base {
2629 virtual ~Base() = 0;
2630 virtual operator int() = 0;
2631 virtual Base& operator+(Base&) = 0;
2634 struct Derived : Base {
2637 )cpp");
2640 TEST(CompletionTest, NoCrashOnMissingNewLineAtEOF) {
2641 auto FooCpp = testPath("foo.cpp");
2643 MockCompilationDatabase CDB;
2644 MockFS FS;
2645 Annotations F("#pragma ^ // no new line");
2646 FS.Files[FooCpp] = F.code().str();
2647 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2648 runAddDocument(Server, FooCpp, F.code());
2649 // Run completion outside the file range.
2650 EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, F.point(),
2651 clangd::CodeCompleteOptions()))
2652 .Completions,
2653 IsEmpty());
2654 EXPECT_THAT(cantFail(runSignatureHelp(Server, FooCpp, F.point(),
2655 MarkupKind::PlainText))
2656 .signatures,
2657 IsEmpty());
2660 TEST(GuessCompletionPrefix, Filters) {
2661 for (llvm::StringRef Case : {
2662 "[[scope::]][[ident]]^",
2663 "[[]][[]]^",
2664 "\n[[]][[]]^",
2665 "[[]][[ab]]^",
2666 "x.[[]][[ab]]^",
2667 "x.[[]][[]]^",
2668 "[[x::]][[ab]]^",
2669 "[[x::]][[]]^",
2670 "[[::x::]][[ab]]^",
2671 "some text [[scope::more::]][[identif]]^ier",
2672 "some text [[scope::]][[mor]]^e::identifier",
2673 "weird case foo::[[::bar::]][[baz]]^",
2674 "/* [[]][[]]^ */",
2675 }) {
2676 Annotations F(Case);
2677 auto Offset = cantFail(positionToOffset(F.code(), F.point()));
2678 auto ToStringRef = [&](Range R) {
2679 return F.code().slice(cantFail(positionToOffset(F.code(), R.start)),
2680 cantFail(positionToOffset(F.code(), R.end)));
2682 auto WantQualifier = ToStringRef(F.ranges()[0]),
2683 WantName = ToStringRef(F.ranges()[1]);
2685 auto Prefix = guessCompletionPrefix(F.code(), Offset);
2686 // Even when components are empty, check their offsets are correct.
2687 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
2688 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
2689 EXPECT_EQ(WantName, Prefix.Name) << Case;
2690 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
2694 TEST(CompletionTest, EnableSpeculativeIndexRequest) {
2695 MockFS FS;
2696 MockCompilationDatabase CDB;
2697 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
2699 auto File = testPath("foo.cpp");
2700 Annotations Test(R"cpp(
2701 namespace ns1 { int abc; }
2702 namespace ns2 { int abc; }
2703 void f() { ns1::ab$1^; ns1::ab$2^; }
2704 void f2() { ns2::ab$3^; }
2705 )cpp");
2706 runAddDocument(Server, File, Test.code());
2707 clangd::CodeCompleteOptions Opts = {};
2709 IndexRequestCollector Requests;
2710 Opts.Index = &Requests;
2712 auto CompleteAtPoint = [&](StringRef P) {
2713 auto CCR = cantFail(runCodeComplete(Server, File, Test.point(P), Opts));
2714 EXPECT_TRUE(CCR.HasMore);
2717 CompleteAtPoint("1");
2718 auto Reqs1 = Requests.consumeRequests(1);
2719 ASSERT_EQ(Reqs1.size(), 1u);
2720 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::"));
2722 CompleteAtPoint("2");
2723 auto Reqs2 = Requests.consumeRequests(1);
2724 // Speculation succeeded. Used speculative index result.
2725 ASSERT_EQ(Reqs2.size(), 1u);
2726 EXPECT_EQ(Reqs2[0], Reqs1[0]);
2728 CompleteAtPoint("3");
2729 // Speculation failed. Sent speculative index request and the new index
2730 // request after sema.
2731 auto Reqs3 = Requests.consumeRequests(2);
2732 ASSERT_EQ(Reqs3.size(), 2u);
2735 TEST(CompletionTest, InsertTheMostPopularHeader) {
2736 std::string DeclFile = URI::create(testPath("foo")).toString();
2737 Symbol Sym = func("Func");
2738 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2739 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
2740 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
2742 auto Results = completions("Fun^", {Sym}).Completions;
2743 assert(!Results.empty());
2744 EXPECT_THAT(Results[0], AllOf(named("Func"), insertInclude("\"bar.h\"")));
2745 EXPECT_EQ(Results[0].Includes.size(), 2u);
2748 TEST(CompletionTest, InsertIncludeOrImport) {
2749 std::string DeclFile = URI::create(testPath("foo")).toString();
2750 Symbol Sym = func("Func");
2751 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2752 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000,
2753 Symbol::Include | Symbol::Import);
2754 CodeCompleteOptions Opts;
2755 // Should only take effect in import contexts.
2756 Opts.ImportInsertions = true;
2757 auto Results = completions("Fun^", {Sym}, Opts).Completions;
2758 assert(!Results.empty());
2759 EXPECT_THAT(Results[0],
2760 AllOf(named("Func"), insertIncludeText("#include \"bar.h\"\n")));
2762 ASTSignals Signals;
2763 Signals.InsertionDirective = Symbol::IncludeDirective::Import;
2764 Opts.MainFileSignals = &Signals;
2765 Results = completions("Fun^", {Sym}, Opts, "Foo.m").Completions;
2766 assert(!Results.empty());
2767 EXPECT_THAT(Results[0],
2768 AllOf(named("Func"), insertIncludeText("#import \"bar.h\"\n")));
2770 Sym.IncludeHeaders[0].SupportedDirectives = Symbol::Import;
2771 Results = completions("Fun^", {Sym}).Completions;
2772 assert(!Results.empty());
2773 EXPECT_THAT(Results[0], AllOf(named("Func"), Not(insertInclude())));
2776 TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
2777 Annotations Test(R"cpp(
2778 #include "foo.h"
2779 Fun^
2780 )cpp");
2781 auto TU = TestTU::withCode(Test.code());
2782 TU.AdditionalFiles["foo.h"] = "";
2784 std::string DeclFile = URI::create(testPath("foo")).toString();
2785 Symbol Sym = func("Func");
2786 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2787 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
2788 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
2790 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions,
2791 UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""),
2792 Not(insertInclude()))));
2795 TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
2796 Symbol Sym;
2797 Sym.Name = "Clangd_Macro_Test";
2798 Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test");
2799 Sym.SymInfo.Kind = index::SymbolKind::Macro;
2800 Sym.Flags |= Symbol::IndexedForCodeCompletion;
2801 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
2802 .Completions,
2803 UnorderedElementsAre(named("Clangd_Macro_Test")));
2806 TEST(CompletionTest, MacroFromPreamble) {
2807 Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x
2809 int x = 0;
2810 #define CLANGD_MAIN x
2811 void f() { CLANGD_^ }
2812 )cpp");
2813 auto TU = TestTU::withCode(Test.code());
2814 TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x";
2815 auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")});
2816 // We should get results from the main file, including the preamble section.
2817 // However no results from included files (the index should cover them).
2818 EXPECT_THAT(Results.Completions,
2819 UnorderedElementsAre(named("CLANGD_PREAMBLE_MAIN"),
2820 named("CLANGD_MAIN"),
2821 named("CLANGD_INDEX")));
2824 TEST(CompletionTest, DeprecatedResults) {
2825 std::string Body = R"cpp(
2826 void TestClangd();
2827 void TestClangc() __attribute__((deprecated("", "")));
2828 )cpp";
2830 EXPECT_THAT(
2831 completions(Body + "int main() { TestClang^ }").Completions,
2832 UnorderedElementsAre(AllOf(named("TestClangd"), Not(deprecated())),
2833 AllOf(named("TestClangc"), deprecated())));
2836 TEST(SignatureHelpTest, PartialSpec) {
2837 const auto Results = signatures(R"cpp(
2838 template <typename T> struct Foo {};
2839 template <typename T> struct Foo<T*> { Foo(T); };
2840 Foo<int*> F(^);)cpp");
2841 EXPECT_THAT(Results.signatures, Contains(sig("Foo([[T]])")));
2842 EXPECT_EQ(0, Results.activeParameter);
2845 TEST(SignatureHelpTest, InsideArgument) {
2847 const auto Results = signatures(R"cpp(
2848 void foo(int x);
2849 void foo(int x, int y);
2850 int main() { foo(1+^); }
2851 )cpp");
2852 EXPECT_THAT(Results.signatures,
2853 ElementsAre(sig("foo([[int x]]) -> void"),
2854 sig("foo([[int x]], [[int y]]) -> void")));
2855 EXPECT_EQ(0, Results.activeParameter);
2858 const auto Results = signatures(R"cpp(
2859 void foo(int x);
2860 void foo(int x, int y);
2861 int main() { foo(1^); }
2862 )cpp");
2863 EXPECT_THAT(Results.signatures,
2864 ElementsAre(sig("foo([[int x]]) -> void"),
2865 sig("foo([[int x]], [[int y]]) -> void")));
2866 EXPECT_EQ(0, Results.activeParameter);
2869 const auto Results = signatures(R"cpp(
2870 void foo(int x);
2871 void foo(int x, int y);
2872 int main() { foo(1^0); }
2873 )cpp");
2874 EXPECT_THAT(Results.signatures,
2875 ElementsAre(sig("foo([[int x]]) -> void"),
2876 sig("foo([[int x]], [[int y]]) -> void")));
2877 EXPECT_EQ(0, Results.activeParameter);
2880 const auto Results = signatures(R"cpp(
2881 void foo(int x);
2882 void foo(int x, int y);
2883 int bar(int x, int y);
2884 int main() { bar(foo(2, 3^)); }
2885 )cpp");
2886 EXPECT_THAT(Results.signatures,
2887 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
2888 EXPECT_EQ(1, Results.activeParameter);
2892 TEST(SignatureHelpTest, ConstructorInitializeFields) {
2894 const auto Results = signatures(R"cpp(
2895 struct A { A(int); };
2896 struct B {
2897 B() : a_elem(^) {}
2898 A a_elem;
2900 )cpp");
2901 EXPECT_THAT(Results.signatures,
2902 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2903 sig("A([[const A &]])")));
2906 const auto Results = signatures(R"cpp(
2907 struct A { A(int); };
2908 struct B {
2909 B() : a_elem(^
2910 A a_elem;
2912 )cpp");
2913 // FIXME: currently the parser skips over the decl of a_elem as part of the
2914 // (broken) init list, so we don't get signatures for the first member.
2915 EXPECT_THAT(Results.signatures, IsEmpty());
2918 const auto Results = signatures(R"cpp(
2919 struct A { A(int); };
2920 struct B {
2921 B() : a_elem(^
2922 int dummy_elem;
2923 A a_elem;
2925 )cpp");
2926 EXPECT_THAT(Results.signatures,
2927 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2928 sig("A([[const A &]])")));
2931 const auto Results = signatures(R"cpp(
2932 struct A {
2933 A(int);
2935 struct C {
2936 C(int);
2937 C(A);
2939 struct B {
2940 B() : c_elem(A(1^)) {}
2941 C c_elem;
2943 )cpp");
2944 EXPECT_THAT(Results.signatures,
2945 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2946 sig("A([[const A &]])")));
2950 TEST(SignatureHelpTest, Variadic) {
2951 const std::string Header = R"cpp(
2952 void fun(int x, ...) {}
2953 void test() {)cpp";
2954 const std::string ExpectedSig = "fun([[int x]], [[...]]) -> void";
2957 const auto Result = signatures(Header + "fun(^);}");
2958 EXPECT_EQ(0, Result.activeParameter);
2959 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2962 const auto Result = signatures(Header + "fun(1, ^);}");
2963 EXPECT_EQ(1, Result.activeParameter);
2964 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2967 const auto Result = signatures(Header + "fun(1, 2, ^);}");
2968 EXPECT_EQ(1, Result.activeParameter);
2969 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2973 TEST(SignatureHelpTest, VariadicTemplate) {
2974 const std::string Header = R"cpp(
2975 template<typename T, typename ...Args>
2976 void fun(T t, Args ...args) {}
2977 void test() {)cpp";
2978 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void";
2981 const auto Result = signatures(Header + "fun(^);}");
2982 EXPECT_EQ(0, Result.activeParameter);
2983 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2986 const auto Result = signatures(Header + "fun(1, ^);}");
2987 EXPECT_EQ(1, Result.activeParameter);
2988 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2991 const auto Result = signatures(Header + "fun(1, 2, ^);}");
2992 EXPECT_EQ(1, Result.activeParameter);
2993 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
2997 TEST(SignatureHelpTest, VariadicMethod) {
2998 const std::string Header = R"cpp(
2999 class C {
3000 template<typename T, typename ...Args>
3001 void fun(T t, Args ...args) {}
3003 void test() {C c; )cpp";
3004 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void";
3007 const auto Result = signatures(Header + "c.fun(^);}");
3008 EXPECT_EQ(0, Result.activeParameter);
3009 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3012 const auto Result = signatures(Header + "c.fun(1, ^);}");
3013 EXPECT_EQ(1, Result.activeParameter);
3014 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3017 const auto Result = signatures(Header + "c.fun(1, 2, ^);}");
3018 EXPECT_EQ(1, Result.activeParameter);
3019 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3023 TEST(SignatureHelpTest, VariadicType) {
3024 const std::string Header = R"cpp(
3025 void fun(int x, ...) {}
3026 auto get_fun() { return fun; }
3027 void test() {
3028 )cpp";
3029 const std::string ExpectedSig = "([[int]], [[...]]) -> void";
3032 const auto Result = signatures(Header + "get_fun()(^);}");
3033 EXPECT_EQ(0, Result.activeParameter);
3034 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3037 const auto Result = signatures(Header + "get_fun()(1, ^);}");
3038 EXPECT_EQ(1, Result.activeParameter);
3039 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3042 const auto Result = signatures(Header + "get_fun()(1, 2, ^);}");
3043 EXPECT_EQ(1, Result.activeParameter);
3044 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3048 TEST(CompletionTest, IncludedCompletionKinds) {
3049 Annotations Test(R"cpp(#include "^)cpp");
3050 auto TU = TestTU::withCode(Test.code());
3051 TU.AdditionalFiles["sub/bar.h"] = "";
3052 TU.ExtraArgs.push_back("-I" + testPath("sub"));
3054 auto Results = completions(TU, Test.point());
3055 EXPECT_THAT(Results.Completions,
3056 AllOf(has("sub/", CompletionItemKind::Folder),
3057 has("bar.h\"", CompletionItemKind::File)));
3060 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3061 completions(
3062 R"cpp(
3063 #include "./^"
3064 )cpp");
3067 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3068 clangd::CodeCompleteOptions Opts = {};
3069 Opts.AllScopes = true;
3071 auto Results = completions(
3072 R"cpp(
3073 void f() { na::Clangd^ }
3074 )cpp",
3075 {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts);
3076 EXPECT_THAT(Results.Completions,
3077 UnorderedElementsAre(
3078 AllOf(qualifier(""), scope("na::"), named("ClangdA"))));
3081 TEST(CompletionTest, AllScopesCompletion) {
3082 clangd::CodeCompleteOptions Opts = {};
3083 Opts.AllScopes = true;
3085 auto Results = completions(
3086 R"cpp(
3087 namespace na {
3088 void f() { Clangd^ }
3090 )cpp",
3091 {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"),
3092 cls("na::nb::Clangd4"), enmConstant("na::C::Clangd5")},
3093 Opts);
3094 EXPECT_THAT(
3095 Results.Completions,
3096 UnorderedElementsAre(AllOf(qualifier("nx::"), named("Clangd1"),
3097 kind(CompletionItemKind::Class)),
3098 AllOf(qualifier("ny::"), named("Clangd2"),
3099 kind(CompletionItemKind::Class)),
3100 AllOf(qualifier(""), scope(""), named("Clangd3"),
3101 kind(CompletionItemKind::Class)),
3102 AllOf(qualifier("nb::"), named("Clangd4"),
3103 kind(CompletionItemKind::Class)),
3104 AllOf(qualifier("C::"), named("Clangd5"),
3105 kind(CompletionItemKind::EnumMember))));
3108 TEST(CompletionTest, NoQualifierIfShadowed) {
3109 clangd::CodeCompleteOptions Opts = {};
3110 Opts.AllScopes = true;
3112 auto Results = completions(R"cpp(
3113 namespace nx { class Clangd1 {}; }
3114 using nx::Clangd1;
3115 void f() { Clangd^ }
3116 )cpp",
3117 {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts);
3118 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and
3119 // needs no qualifier.
3120 EXPECT_THAT(Results.Completions,
3121 UnorderedElementsAre(AllOf(qualifier(""), named("Clangd1")),
3122 AllOf(qualifier("nx::"), named("Clangd2"))));
3125 TEST(CompletionTest, NoCompletionsForNewNames) {
3126 clangd::CodeCompleteOptions Opts;
3127 Opts.AllScopes = true;
3128 auto Results = completions(R"cpp(
3129 void f() { int n^ }
3130 )cpp",
3131 {cls("naber"), cls("nx::naber")}, Opts);
3132 EXPECT_THAT(Results.Completions, UnorderedElementsAre());
3135 TEST(CompletionTest, Lambda) {
3136 clangd::CodeCompleteOptions Opts = {};
3138 auto Results = completions(R"cpp(
3139 void function() {
3140 auto Lambda = [](int a, const double &b) {return 1.f;};
3141 Lam^
3143 )cpp",
3144 {}, Opts);
3146 ASSERT_EQ(Results.Completions.size(), 1u);
3147 const auto &A = Results.Completions.front();
3148 EXPECT_EQ(A.Name, "Lambda");
3149 EXPECT_EQ(A.Signature, "(int a, const double &b) const");
3150 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3151 EXPECT_EQ(A.ReturnType, "float");
3152 EXPECT_EQ(A.SnippetSuffix, "(${1:int a}, ${2:const double &b})");
3155 TEST(CompletionTest, StructuredBinding) {
3156 clangd::CodeCompleteOptions Opts = {};
3158 auto Results = completions(R"cpp(
3159 struct S {
3160 using Float = float;
3161 int x;
3162 Float y;
3164 void function() {
3165 const auto &[xxx, yyy] = S{};
3166 yyy^
3168 )cpp",
3169 {}, Opts);
3171 ASSERT_EQ(Results.Completions.size(), 1u);
3172 const auto &A = Results.Completions.front();
3173 EXPECT_EQ(A.Name, "yyy");
3174 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3175 EXPECT_EQ(A.ReturnType, "const Float");
3178 TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3179 auto Results = completions(R"objc(
3180 @interface Foo
3181 @property(nonatomic, setter=setXToIgnoreComplete:) int value;
3182 @end
3183 Foo *foo = [Foo new]; int y = [foo v^]
3184 )objc",
3185 /*IndexSymbols=*/{},
3186 /*Opts=*/{}, "Foo.m");
3188 auto C = Results.Completions;
3189 EXPECT_THAT(C, ElementsAre(named("value")));
3190 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3191 EXPECT_THAT(C, ElementsAre(returnType("int")));
3192 EXPECT_THAT(C, ElementsAre(signature("")));
3193 EXPECT_THAT(C, ElementsAre(snippetSuffix("")));
3196 TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3197 auto Results = completions(R"objc(
3198 @interface Foo
3199 - (int)valueForCharacter:(char)c;
3200 @end
3201 Foo *foo = [Foo new]; int y = [foo v^]
3202 )objc",
3203 /*IndexSymbols=*/{},
3204 /*Opts=*/{}, "Foo.m");
3206 auto C = Results.Completions;
3207 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3208 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3209 EXPECT_THAT(C, ElementsAre(returnType("int")));
3210 EXPECT_THAT(C, ElementsAre(signature("(char)")));
3211 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(char)}")));
3214 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3215 auto Results = completions(R"objc(
3216 @interface Foo
3217 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3218 @end
3219 id val = [Foo foo^]
3220 )objc",
3221 /*IndexSymbols=*/{},
3222 /*Opts=*/{}, "Foo.m");
3224 auto C = Results.Completions;
3225 EXPECT_THAT(C, ElementsAre(named("fooWithValue:")));
3226 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3227 EXPECT_THAT(C, ElementsAre(returnType("id")));
3228 EXPECT_THAT(C, ElementsAre(signature("(int) fooey:(unsigned int)")));
3229 EXPECT_THAT(
3230 C, ElementsAre(snippetSuffix("${1:(int)} fooey:${2:(unsigned int)}")));
3233 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3234 auto Results = completions(R"objc(
3235 @interface Foo
3236 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3237 @end
3238 id val = [Foo fooWithValue:10 f^]
3239 )objc",
3240 /*IndexSymbols=*/{},
3241 /*Opts=*/{}, "Foo.m");
3243 auto C = Results.Completions;
3244 EXPECT_THAT(C, ElementsAre(named("fooey:")));
3245 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3246 EXPECT_THAT(C, ElementsAre(returnType("id")));
3247 EXPECT_THAT(C, ElementsAre(signature("(unsigned int)")));
3248 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(unsigned int)}")));
3251 TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3252 auto Results = completions(R"objc(
3253 @interface Foo
3254 + (id)player:(id)player willRun:(id)run;
3255 @end
3256 id val = [Foo wi^]
3257 )objc",
3258 /*IndexSymbols=*/{},
3259 /*Opts=*/{}, "Foo.m");
3261 auto C = Results.Completions;
3262 EXPECT_THAT(C, ElementsAre(named("player:")));
3263 EXPECT_THAT(C, ElementsAre(filterText("player:willRun:")));
3264 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3265 EXPECT_THAT(C, ElementsAre(returnType("id")));
3266 EXPECT_THAT(C, ElementsAre(signature("(id) willRun:(id)")));
3267 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(id)} willRun:${2:(id)}")));
3270 TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3271 auto Results = completions(R"objc(
3272 @interface Foo
3273 - (void)foo;
3274 @end
3275 @implementation Foo
3277 @end
3278 )objc",
3279 /*IndexSymbols=*/{},
3280 /*Opts=*/{}, "Foo.m");
3282 auto C = Results.Completions;
3283 EXPECT_THAT(C, ElementsAre(named("foo")));
3284 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3285 EXPECT_THAT(C, ElementsAre(qualifier("- (void)")));
3288 TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3289 auto Results = completions(R"objc(
3290 @interface Foo
3291 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3292 @end
3293 @implementation Foo
3294 valueFor^
3295 @end
3296 )objc",
3297 /*IndexSymbols=*/{},
3298 /*Opts=*/{}, "Foo.m");
3300 auto C = Results.Completions;
3301 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3302 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3303 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3304 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object")));
3307 TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3308 auto Results = completions(R"objc(
3309 @interface Foo
3310 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3311 @end
3312 @implementation Foo
3313 secondArg^
3314 @end
3315 )objc",
3316 /*IndexSymbols=*/{},
3317 /*Opts=*/{}, "Foo.m");
3319 auto C = Results.Completions;
3320 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3321 EXPECT_THAT(C, ElementsAre(filterText("valueForCharacter:secondArgument:")));
3322 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3323 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3324 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object")));
3327 TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3328 auto Results = completions(R"objc(
3329 @interface Foo
3330 - (int)valueForCharacter:(char)c;
3331 @end
3332 @implementation Foo
3333 - (int)valueFor^
3334 @end
3335 )objc",
3336 /*IndexSymbols=*/{},
3337 /*Opts=*/{}, "Foo.m");
3339 auto C = Results.Completions;
3340 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:")));
3341 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3342 EXPECT_THAT(C, ElementsAre(signature("(char)c")));
3345 TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3346 auto Results = completions(R"objc(
3347 @interface Foo
3348 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3349 @end
3350 @implementation Foo
3351 - (int)valueForCharacter:(char)c second^
3352 @end
3353 )objc",
3354 /*IndexSymbols=*/{},
3355 /*Opts=*/{}, "Foo.m");
3357 auto C = Results.Completions;
3358 EXPECT_THAT(C, ElementsAre(named("secondArgument:")));
3359 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3360 EXPECT_THAT(C, ElementsAre(signature("(id)object")));
3363 TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3364 Symbol FoodClass = objcClass("FoodClass");
3365 Symbol SymFood = objcProtocol("Food");
3366 Symbol SymFooey = objcProtocol("Fooey");
3367 auto Results = completions("id<Foo^>", {SymFood, FoodClass, SymFooey},
3368 /*Opts=*/{}, "Foo.m");
3370 // Should only give protocols for ObjC protocol completions.
3371 EXPECT_THAT(Results.Completions,
3372 UnorderedElementsAre(
3373 AllOf(named("Food"), kind(CompletionItemKind::Interface)),
3374 AllOf(named("Fooey"), kind(CompletionItemKind::Interface))));
3376 Results = completions("Fo^", {SymFood, FoodClass, SymFooey},
3377 /*Opts=*/{}, "Foo.m");
3378 // Shouldn't give protocols for non protocol completions.
3379 EXPECT_THAT(
3380 Results.Completions,
3381 ElementsAre(AllOf(named("FoodClass"), kind(CompletionItemKind::Class))));
3384 TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3385 MockFS FS;
3386 MockCompilationDatabase CDB;
3387 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
3389 auto File = testPath("Foo.m");
3390 Annotations Test(R"cpp(
3391 @protocol Food
3392 @end
3393 id<Foo$1^> foo;
3394 Foo$2^ bar;
3395 )cpp");
3396 runAddDocument(Server, File, Test.code());
3397 clangd::CodeCompleteOptions Opts = {};
3399 Symbol FoodClass = objcClass("FoodClass");
3400 IndexRequestCollector Requests({FoodClass});
3401 Opts.Index = &Requests;
3403 auto CompleteAtPoint = [&](StringRef P) {
3404 return cantFail(runCodeComplete(Server, File, Test.point(P), Opts))
3405 .Completions;
3408 auto C = CompleteAtPoint("1");
3409 auto Reqs1 = Requests.consumeRequests(1);
3410 ASSERT_EQ(Reqs1.size(), 1u);
3411 EXPECT_THAT(C, ElementsAre(AllOf(named("Food"),
3412 kind(CompletionItemKind::Interface))));
3414 C = CompleteAtPoint("2");
3415 auto Reqs2 = Requests.consumeRequests(1);
3416 // Speculation succeeded. Used speculative index result, but filtering now to
3417 // now include FoodClass.
3418 ASSERT_EQ(Reqs2.size(), 1u);
3419 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3420 EXPECT_THAT(C, ElementsAre(AllOf(named("FoodClass"),
3421 kind(CompletionItemKind::Class))));
3424 TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3425 Symbol FoodCategory = objcCategory("FoodClass", "Extension");
3426 auto Results = completions(R"objc(
3427 @interface Foo
3428 @end
3429 @interface Foo (^)
3430 @end
3431 )objc",
3432 {FoodCategory},
3433 /*Opts=*/{}, "Foo.m");
3434 EXPECT_THAT(Results.Completions, IsEmpty());
3437 TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3438 Symbol FoodClass = objcClass("FoodClass");
3439 FoodClass.IncludeHeaders.emplace_back("\"Foo.h\"", 2, Symbol::Import);
3440 Symbol SymFood = objcProtocol("Food");
3441 auto Results = completions("@class Foo^", {SymFood, FoodClass},
3442 /*Opts=*/{}, "Foo.m");
3444 // Should only give class names without any include insertion.
3445 EXPECT_THAT(Results.Completions,
3446 UnorderedElementsAre(AllOf(named("FoodClass"),
3447 kind(CompletionItemKind::Class),
3448 Not(insertInclude()))));
3451 TEST(CompletionTest, CursorInSnippets) {
3452 clangd::CodeCompleteOptions Options;
3453 Options.EnableSnippets = true;
3454 auto Results = completions(
3455 R"cpp(
3456 void while_foo(int a, int b);
3457 void test() {
3458 whil^
3459 })cpp",
3460 /*IndexSymbols=*/{}, Options);
3462 // Last placeholder in code patterns should be $0 to put the cursor there.
3463 EXPECT_THAT(Results.Completions,
3464 Contains(AllOf(named("while"),
3465 snippetSuffix(" (${1:condition}) {\n$0\n}"))));
3466 // However, snippets for functions must *not* end with $0.
3467 EXPECT_THAT(Results.Completions,
3468 Contains(AllOf(named("while_foo"),
3469 snippetSuffix("(${1:int a}, ${2:int b})"))));
3471 Results = completions(R"cpp(
3472 struct Base {
3473 Base(int a, int b) {}
3476 struct Derived : Base {
3477 Derived() : Base^
3479 )cpp",
3480 /*IndexSymbols=*/{}, Options);
3481 // Constructors from base classes are a kind of pattern that shouldn't end
3482 // with $0.
3483 EXPECT_THAT(Results.Completions,
3484 Contains(AllOf(named("Base"),
3485 snippetSuffix("(${1:int a}, ${2:int b})"))));
3488 TEST(CompletionTest, WorksWithNullType) {
3489 auto R = completions(R"cpp(
3490 int main() {
3491 for (auto [loopVar] : y ) { // y has to be unresolved.
3492 int z = loopV^;
3495 )cpp");
3496 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar")));
3499 TEST(CompletionTest, UsingDecl) {
3500 const char *Header(R"cpp(
3501 void foo(int);
3502 namespace std {
3503 using ::foo;
3504 })cpp");
3505 const char *Source(R"cpp(
3506 void bar() {
3507 std::^;
3508 })cpp");
3509 auto Index = TestTU::withHeaderCode(Header).index();
3510 clangd::CodeCompleteOptions Opts;
3511 Opts.Index = Index.get();
3512 Opts.AllScopes = true;
3513 auto R = completions(Source, {}, Opts);
3514 EXPECT_THAT(R.Completions,
3515 ElementsAre(AllOf(scope("std::"), named("foo"),
3516 kind(CompletionItemKind::Reference))));
3519 TEST(CompletionTest, Enums) {
3520 const char *Header(R"cpp(
3521 namespace ns {
3522 enum Unscoped { Clangd1 };
3523 class C {
3524 enum Unscoped { Clangd2 };
3526 enum class Scoped { Clangd3 };
3527 })cpp");
3528 const char *Source(R"cpp(
3529 void bar() {
3530 Clangd^
3531 })cpp");
3532 auto Index = TestTU::withHeaderCode(Header).index();
3533 clangd::CodeCompleteOptions Opts;
3534 Opts.Index = Index.get();
3535 Opts.AllScopes = true;
3536 auto R = completions(Source, {}, Opts);
3537 EXPECT_THAT(R.Completions, UnorderedElementsAre(
3538 AllOf(scope("ns::"), named("Clangd1"),
3539 kind(CompletionItemKind::EnumMember)),
3540 AllOf(scope("ns::C::"), named("Clangd2"),
3541 kind(CompletionItemKind::EnumMember)),
3542 AllOf(scope("ns::Scoped::"), named("Clangd3"),
3543 kind(CompletionItemKind::EnumMember))));
3546 TEST(CompletionTest, ScopeIsUnresolved) {
3547 clangd::CodeCompleteOptions Opts = {};
3548 Opts.AllScopes = true;
3550 auto Results = completions(R"cpp(
3551 namespace a {
3552 void f() { b::X^ }
3554 )cpp",
3555 {cls("a::b::XYZ")}, Opts);
3556 EXPECT_THAT(Results.Completions,
3557 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ"))));
3560 TEST(CompletionTest, NestedScopeIsUnresolved) {
3561 clangd::CodeCompleteOptions Opts = {};
3562 Opts.AllScopes = true;
3564 auto Results = completions(R"cpp(
3565 namespace a {
3566 namespace b {}
3567 void f() { b::c::X^ }
3569 )cpp",
3570 {cls("a::b::c::XYZ")}, Opts);
3571 EXPECT_THAT(Results.Completions,
3572 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ"))));
3575 // Clang parser gets confused here and doesn't report the ns:: prefix.
3576 // Naive behavior is to insert it again. We examine the source and recover.
3577 TEST(CompletionTest, NamespaceDoubleInsertion) {
3578 clangd::CodeCompleteOptions Opts = {};
3580 auto Results = completions(R"cpp(
3581 namespace foo {
3582 namespace ns {}
3583 #define M(X) < X
3584 M(ns::ABC^
3586 )cpp",
3587 {cls("foo::ns::ABCDE")}, Opts);
3588 EXPECT_THAT(Results.Completions,
3589 UnorderedElementsAre(AllOf(qualifier(""), named("ABCDE"))));
3592 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
3593 // Despite the fact that base method matches the ref-qualifier better,
3594 // completion results should only include the derived method.
3595 auto Completions = completions(R"cpp(
3596 struct deque_base {
3597 float size();
3598 double size() const;
3600 struct deque : deque_base {
3601 int size() const;
3604 auto x = deque().^
3605 )cpp")
3606 .Completions;
3607 EXPECT_THAT(Completions,
3608 ElementsAre(AllOf(returnType("int"), named("size"))));
3611 TEST(CompletionTest, NoCrashWithIncompleteLambda) {
3612 auto Completions = completions("auto&& x = []{^").Completions;
3613 // The completion of x itself can cause a problem: in the code completion
3614 // callback, its type is not known, which affects the linkage calculation.
3615 // A bad linkage value gets cached, and subsequently updated.
3616 EXPECT_THAT(Completions, Contains(named("x")));
3618 auto Signatures = signatures("auto x() { x(^").signatures;
3619 EXPECT_THAT(Signatures, Contains(sig("x() -> auto")));
3622 TEST(CompletionTest, DelayedTemplateParsing) {
3623 Annotations Test(R"cpp(
3624 int xxx;
3625 template <typename T> int foo() { return xx^; }
3626 )cpp");
3627 auto TU = TestTU::withCode(Test.code());
3628 // Even though delayed-template-parsing is on, we will disable it to provide
3629 // completion in templates.
3630 TU.ExtraArgs.push_back("-fdelayed-template-parsing");
3632 EXPECT_THAT(completions(TU, Test.point()).Completions,
3633 Contains(named("xxx")));
3636 TEST(CompletionTest, CompletionRange) {
3637 const char *WithRange = "auto x = [[abc]]^";
3638 auto Completions = completions(WithRange);
3639 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3640 Completions = completionsNoCompile(WithRange);
3641 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3643 const char *EmptyRange = "auto x = [[]]^";
3644 Completions = completions(EmptyRange);
3645 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3646 Completions = completionsNoCompile(EmptyRange);
3647 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3649 // Sema doesn't trigger at all here, while the no-sema completion runs
3650 // heuristics as normal and reports a range. It'd be nice to be consistent.
3651 const char *NoCompletion = "/* foo [[]]^ */";
3652 Completions = completions(NoCompletion);
3653 EXPECT_EQ(Completions.CompletionRange, std::nullopt);
3654 Completions = completionsNoCompile(NoCompletion);
3655 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
3658 TEST(NoCompileCompletionTest, Basic) {
3659 auto Results = completionsNoCompile(R"cpp(
3660 void func() {
3661 int xyz;
3662 int abc;
3665 )cpp");
3666 EXPECT_FALSE(Results.RanParser);
3667 EXPECT_THAT(Results.Completions,
3668 UnorderedElementsAre(named("void"), named("func"), named("int"),
3669 named("xyz"), named("abc")));
3672 TEST(NoCompileCompletionTest, WithFilter) {
3673 auto Results = completionsNoCompile(R"cpp(
3674 void func() {
3675 int sym1;
3676 int sym2;
3677 int xyz1;
3678 int xyz2;
3681 )cpp");
3682 EXPECT_THAT(Results.Completions,
3683 UnorderedElementsAre(named("sym1"), named("sym2")));
3686 TEST(NoCompileCompletionTest, WithIndex) {
3687 std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"),
3688 func("c::xxx"), func("ns::d::xxx")};
3689 auto Results = completionsNoCompile(
3690 R"cpp(
3691 // Current-scopes, unqualified completion.
3692 using namespace a;
3693 namespace ns {
3694 using namespace b;
3695 void foo() {
3699 )cpp",
3700 Syms);
3701 EXPECT_THAT(Results.Completions,
3702 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3703 AllOf(qualifier(""), scope("a::")),
3704 AllOf(qualifier(""), scope("ns::b::"))));
3705 CodeCompleteOptions Opts;
3706 Opts.AllScopes = true;
3707 Results = completionsNoCompile(
3708 R"cpp(
3709 // All-scopes unqualified completion.
3710 using namespace a;
3711 namespace ns {
3712 using namespace b;
3713 void foo() {
3717 )cpp",
3718 Syms, Opts);
3719 EXPECT_THAT(Results.Completions,
3720 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3721 AllOf(qualifier(""), scope("a::")),
3722 AllOf(qualifier(""), scope("ns::b::")),
3723 AllOf(qualifier("c::"), scope("c::")),
3724 AllOf(qualifier("d::"), scope("ns::d::"))));
3725 Results = completionsNoCompile(
3726 R"cpp(
3727 // Qualified completion.
3728 using namespace a;
3729 namespace ns {
3730 using namespace b;
3731 void foo() {
3732 b::xx^
3735 )cpp",
3736 Syms, Opts);
3737 EXPECT_THAT(Results.Completions,
3738 ElementsAre(AllOf(qualifier(""), scope("ns::b::"))));
3739 Results = completionsNoCompile(
3740 R"cpp(
3741 // Absolutely qualified completion.
3742 using namespace a;
3743 namespace ns {
3744 using namespace b;
3745 void foo() {
3746 ::a::xx^
3749 )cpp",
3750 Syms, Opts);
3751 EXPECT_THAT(Results.Completions,
3752 ElementsAre(AllOf(qualifier(""), scope("a::"))));
3755 TEST(AllowImplicitCompletion, All) {
3756 const char *Yes[] = {
3757 "foo.^bar",
3758 "foo->^bar",
3759 "foo::^bar",
3760 " # include <^foo.h>",
3761 "#import <foo/^bar.h>",
3762 "#include_next \"^",
3764 const char *No[] = {
3765 "foo>^bar",
3766 "foo:^bar",
3767 "foo\n^bar",
3768 "#include <foo.h> //^",
3769 "#include \"foo.h\"^",
3770 "#error <^",
3771 "#<^",
3773 for (const char *Test : Yes) {
3774 llvm::Annotations A(Test);
3775 EXPECT_TRUE(allowImplicitCompletion(A.code(), A.point())) << Test;
3777 for (const char *Test : No) {
3778 llvm::Annotations A(Test);
3779 EXPECT_FALSE(allowImplicitCompletion(A.code(), A.point())) << Test;
3783 TEST(CompletionTest, FunctionArgsExist) {
3784 clangd::CodeCompleteOptions Opts;
3785 Opts.EnableSnippets = true;
3786 std::string Context = R"cpp(
3787 #define MACRO(x)
3788 int foo(int A);
3789 int bar();
3790 struct Object {
3791 Object(int B) {}
3793 template <typename T>
3794 struct Container {
3795 Container(int Size) {}
3797 )cpp";
3798 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions,
3799 UnorderedElementsAre(
3800 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3801 EXPECT_THAT(
3802 completions(Context + "int y = fo^(42)", {}, Opts).Completions,
3803 UnorderedElementsAre(AllOf(labeled("foo(int A)"), snippetSuffix(""))));
3804 // FIXME(kirillbobyrev): No snippet should be produced here.
3805 EXPECT_THAT(completions(Context + "int y = fo^o(42)", {}, Opts).Completions,
3806 UnorderedElementsAre(
3807 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3808 EXPECT_THAT(
3809 completions(Context + "int y = ba^", {}, Opts).Completions,
3810 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("()"))));
3811 EXPECT_THAT(completions(Context + "int y = ba^()", {}, Opts).Completions,
3812 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix(""))));
3813 EXPECT_THAT(
3814 completions(Context + "Object o = Obj^", {}, Opts).Completions,
3815 Contains(AllOf(labeled("Object(int B)"), snippetSuffix("(${1:int B})"),
3816 kind(CompletionItemKind::Constructor))));
3817 EXPECT_THAT(completions(Context + "Object o = Obj^()", {}, Opts).Completions,
3818 Contains(AllOf(labeled("Object(int B)"), snippetSuffix(""),
3819 kind(CompletionItemKind::Constructor))));
3820 EXPECT_THAT(
3821 completions(Context + "Container c = Cont^", {}, Opts).Completions,
3822 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3823 snippetSuffix("<${1:typename T}>(${2:int Size})"),
3824 kind(CompletionItemKind::Constructor))));
3825 EXPECT_THAT(
3826 completions(Context + "Container c = Cont^()", {}, Opts).Completions,
3827 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3828 snippetSuffix("<${1:typename T}>"),
3829 kind(CompletionItemKind::Constructor))));
3830 EXPECT_THAT(
3831 completions(Context + "Container c = Cont^<int>()", {}, Opts).Completions,
3832 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3833 snippetSuffix(""),
3834 kind(CompletionItemKind::Constructor))));
3835 EXPECT_THAT(completions(Context + "MAC^(2)", {}, Opts).Completions,
3836 Contains(AllOf(labeled("MACRO(x)"), snippetSuffix(""),
3837 kind(CompletionItemKind::Function))));
3840 TEST(CompletionTest, NoCrashDueToMacroOrdering) {
3841 EXPECT_THAT(completions(R"cpp(
3842 #define ECHO(X) X
3843 #define ECHO2(X) ECHO(X)
3844 int finish_preamble = EC^HO(2);)cpp")
3845 .Completions,
3846 UnorderedElementsAre(labeled("ECHO(X)"), labeled("ECHO2(X)")));
3849 TEST(CompletionTest, ObjCCategoryDecls) {
3850 TestTU TU;
3851 TU.ExtraArgs.push_back("-xobjective-c");
3852 TU.HeaderCode = R"objc(
3853 @interface Foo
3854 @end
3856 @interface Foo (FooExt1)
3857 @end
3859 @interface Foo (FooExt2)
3860 @end
3862 @interface Bar
3863 @end
3865 @interface Bar (BarExt)
3866 @end)objc";
3869 Annotations Test(R"objc(
3870 @implementation Foo (^)
3871 @end
3872 )objc");
3873 TU.Code = Test.code().str();
3874 auto Results = completions(TU, Test.point());
3875 EXPECT_THAT(Results.Completions,
3876 UnorderedElementsAre(labeled("FooExt1"), labeled("FooExt2")));
3879 Annotations Test(R"objc(
3880 @interface Foo (^)
3881 @end
3882 )objc");
3883 TU.Code = Test.code().str();
3884 auto Results = completions(TU, Test.point());
3885 EXPECT_THAT(Results.Completions, UnorderedElementsAre(labeled("BarExt")));
3889 TEST(CompletionTest, PreambleCodeComplete) {
3890 llvm::StringLiteral Baseline = "\n#define MACRO 12\nint num = MACRO;";
3891 llvm::StringLiteral ModifiedCC =
3892 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
3894 Annotations Test(ModifiedCC);
3895 auto BaselineTU = TestTU::withCode(Baseline);
3896 auto ModifiedTU = TestTU::withCode(Test.code());
3898 MockFS FS;
3899 auto Inputs = ModifiedTU.inputs(FS);
3900 auto Result = codeComplete(testPath(ModifiedTU.Filename), Test.point(),
3901 BaselineTU.preamble().get(), Inputs, {});
3902 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
3905 TEST(CompletionTest, CommentParamName) {
3906 const std::string Code = R"cpp(
3907 void fun(int foo, int bar);
3908 void overloaded(int param_int);
3909 void overloaded(int param_int, int param_other);
3910 void overloaded(char param_char);
3911 int main() {
3912 )cpp";
3914 EXPECT_THAT(completions(Code + "fun(/*^").Completions,
3915 UnorderedElementsAre(labeled("foo=*/")));
3916 EXPECT_THAT(completions(Code + "fun(1, /*^").Completions,
3917 UnorderedElementsAre(labeled("bar=*/")));
3918 EXPECT_THAT(completions(Code + "/*^").Completions, IsEmpty());
3919 // Test de-duplication.
3920 EXPECT_THAT(
3921 completions(Code + "overloaded(/*^").Completions,
3922 UnorderedElementsAre(labeled("param_int=*/"), labeled("param_char=*/")));
3923 // Comment already has some text in it.
3924 EXPECT_THAT(completions(Code + "fun(/* ^").Completions,
3925 UnorderedElementsAre(labeled("foo=*/")));
3926 EXPECT_THAT(completions(Code + "fun(/* f^").Completions,
3927 UnorderedElementsAre(labeled("foo=*/")));
3928 EXPECT_THAT(completions(Code + "fun(/* x^").Completions, IsEmpty());
3929 EXPECT_THAT(completions(Code + "fun(/* f ^").Completions, IsEmpty());
3931 // Test ranges
3933 std::string CompletionRangeTest(Code + "fun(/*[[^]]");
3934 auto Results = completions(CompletionRangeTest);
3935 EXPECT_THAT(Results.CompletionRange,
3936 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
3937 EXPECT_THAT(
3938 Results.Completions,
3939 testing::Each(
3940 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
3941 origin(SymbolOrigin::AST), kind(CompletionItemKind::Text))));
3944 std::string CompletionRangeTest(Code + "fun(/*[[fo^]]");
3945 auto Results = completions(CompletionRangeTest);
3946 EXPECT_THAT(Results.CompletionRange,
3947 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
3948 EXPECT_THAT(
3949 Results.Completions,
3950 testing::Each(
3951 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
3952 origin(SymbolOrigin::AST), kind(CompletionItemKind::Text))));
3956 TEST(CompletionTest, Concepts) {
3957 Annotations Code(R"cpp(
3958 template<class T>
3959 concept A = sizeof(T) <= 8;
3961 template<$tparam^A U>
3962 int foo();
3964 template<typename T>
3965 int bar(T t) requires $expr^A<int>;
3967 template<class T>
3968 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
3970 $toplevel^A auto i = 19;
3972 template<$toplevel^A auto i> void constrainedNTTP();
3974 // FIXME: The first parameter should be dropped in this case.
3975 void abbreviated($expr^A auto x) {}
3976 )cpp");
3977 TestTU TU;
3978 TU.Code = Code.code().str();
3979 TU.ExtraArgs = {"-std=c++20"};
3981 auto Sym = conceptSym("same_as");
3982 Sym.Signature = "<typename Tp, typename Up>";
3983 Sym.CompletionSnippetSuffix = "<${1:typename Tp}, ${2:typename Up}>";
3984 std::vector<Symbol> Syms = {Sym};
3985 for (auto P : Code.points("tparam")) {
3986 ASSERT_THAT(
3987 completions(TU, P, Syms).Completions,
3988 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
3989 Contains(AllOf(named("same_as"), signature("<typename Up>"),
3990 snippetSuffix("<${2:typename Up}>"))),
3991 Contains(named("class")), Contains(named("typename"))))
3992 << "Completing template parameter at position " << P;
3995 for (auto P : Code.points("toplevel")) {
3996 EXPECT_THAT(
3997 completions(TU, P, Syms).Completions,
3998 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
3999 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4000 snippetSuffix("<${2:typename Up}>")))))
4001 << "Completing 'requires' expression at position " << P;
4004 for (auto P : Code.points("expr")) {
4005 EXPECT_THAT(
4006 completions(TU, P, Syms).Completions,
4007 AllOf(Contains(AllOf(named("A"), signature("<class T>"),
4008 snippetSuffix("<${1:class T}>"))),
4009 Contains(AllOf(
4010 named("same_as"), signature("<typename Tp, typename Up>"),
4011 snippetSuffix("<${1:typename Tp}, ${2:typename Up}>")))))
4012 << "Completing 'requires' expression at position " << P;
4016 TEST(SignatureHelp, DocFormat) {
4017 Annotations Code(R"cpp(
4018 // Comment `with` markup.
4019 void foo(int);
4020 void bar() { foo(^); }
4021 )cpp");
4022 for (auto DocumentationFormat :
4023 {MarkupKind::PlainText, MarkupKind::Markdown}) {
4024 auto Sigs = signatures(Code.code(), Code.point(), /*IndexSymbols=*/{},
4025 DocumentationFormat);
4026 ASSERT_EQ(Sigs.signatures.size(), 1U);
4027 EXPECT_EQ(Sigs.signatures[0].documentation.kind, DocumentationFormat);
4031 TEST(SignatureHelp, TemplateArguments) {
4032 std::string Top = R"cpp(
4033 template <typename T, int> bool foo(char);
4034 template <int I, int> bool foo(float);
4035 )cpp";
4037 auto First = signatures(Top + "bool x = foo<^");
4038 EXPECT_THAT(
4039 First.signatures,
4040 UnorderedElementsAre(sig("foo<[[typename T]], [[int]]>() -> bool"),
4041 sig("foo<[[int I]], [[int]]>() -> bool")));
4042 EXPECT_EQ(First.activeParameter, 0);
4044 auto Second = signatures(Top + "bool x = foo<1, ^");
4045 EXPECT_THAT(Second.signatures,
4046 ElementsAre(sig("foo<[[int I]], [[int]]>() -> bool")));
4047 EXPECT_EQ(Second.activeParameter, 1);
4050 TEST(CompletionTest, DoNotCrash) {
4051 llvm::StringLiteral Cases[] = {
4052 R"cpp(
4053 template <typename = int> struct Foo {};
4054 auto a = [x(3)](Foo<^>){};
4055 )cpp",
4057 for (auto Case : Cases) {
4058 SCOPED_TRACE(Case);
4059 auto Completions = completions(Case);
4063 } // namespace
4064 } // namespace clangd
4065 } // namespace clang