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