1 //===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ASTSignals.h"
10 #include "Annotations.h"
11 #include "ClangdServer.h"
12 #include "CodeComplete.h"
19 #include "SourceCode.h"
22 #include "TestIndex.h"
24 #include "index/Index.h"
25 #include "index/MemIndex.h"
26 #include "index/SymbolOrigin.h"
27 #include "support/Threading.h"
28 #include "clang/Sema/CodeCompleteConsumer.h"
29 #include "clang/Tooling/CompilationDatabase.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/Support/Error.h"
32 #include "llvm/Support/Path.h"
33 #include "llvm/Testing/Annotations/Annotations.h"
34 #include "llvm/Testing/Support/Error.h"
35 #include "llvm/Testing/Support/SupportHelpers.h"
36 #include "gmock/gmock.h"
37 #include "gtest/gtest.h"
38 #include <condition_variable>
48 using ::testing::AllOf
;
49 using ::testing::Contains
;
50 using ::testing::ElementsAre
;
51 using ::testing::Field
;
52 using ::testing::HasSubstr
;
53 using ::testing::IsEmpty
;
55 using ::testing::UnorderedElementsAre
;
56 using ContextKind
= CodeCompletionContext::Kind
;
58 // GMock helpers for matching completion items.
59 MATCHER_P(named
, Name
, "") { return arg
.Name
== Name
; }
60 MATCHER_P(mainFileRefs
, Refs
, "") { return arg
.MainFileRefs
== Refs
; }
61 MATCHER_P(scopeRefs
, Refs
, "") { return arg
.ScopeRefsInFile
== Refs
; }
62 MATCHER_P(nameStartsWith
, Prefix
, "") {
63 return llvm::StringRef(arg
.Name
).starts_with(Prefix
);
65 MATCHER_P(filterText
, F
, "") { return arg
.FilterText
== F
; }
66 MATCHER_P(scope
, S
, "") { return arg
.Scope
== S
; }
67 MATCHER_P(qualifier
, Q
, "") { return arg
.RequiredQualifier
== Q
; }
68 MATCHER_P(labeled
, Label
, "") {
69 return arg
.RequiredQualifier
+ arg
.Name
+ arg
.Signature
== Label
;
71 MATCHER_P(sigHelpLabeled
, Label
, "") { return arg
.label
== Label
; }
72 MATCHER_P(kind
, K
, "") { return arg
.Kind
== K
; }
73 MATCHER_P(doc
, D
, "") {
74 return arg
.Documentation
&& arg
.Documentation
->asPlainText() == D
;
76 MATCHER_P(returnType
, D
, "") { return arg
.ReturnType
== D
; }
77 MATCHER_P(hasInclude
, IncludeHeader
, "") {
78 return !arg
.Includes
.empty() && arg
.Includes
[0].Header
== IncludeHeader
;
80 MATCHER_P(insertInclude
, IncludeHeader
, "") {
81 return !arg
.Includes
.empty() && arg
.Includes
[0].Header
== IncludeHeader
&&
82 bool(arg
.Includes
[0].Insertion
);
84 MATCHER_P(insertIncludeText
, InsertedText
, "") {
85 return !arg
.Includes
.empty() && arg
.Includes
[0].Insertion
&&
86 arg
.Includes
[0].Insertion
->newText
== InsertedText
;
88 MATCHER(insertInclude
, "") {
89 return !arg
.Includes
.empty() && bool(arg
.Includes
[0].Insertion
);
91 MATCHER_P(snippetSuffix
, Text
, "") { return arg
.SnippetSuffix
== Text
; }
92 MATCHER_P(origin
, OriginSet
, "") { return arg
.Origin
== OriginSet
; }
93 MATCHER_P(signature
, S
, "") { return arg
.Signature
== S
; }
94 MATCHER_P(replacesRange
, Range
, "") {
95 return arg
.CompletionTokenRange
== Range
;
98 // Shorthand for Contains(named(Name)).
99 Matcher
<const std::vector
<CodeCompletion
> &> has(std::string Name
) {
100 return Contains(named(std::move(Name
)));
102 Matcher
<const std::vector
<CodeCompletion
> &> has(std::string Name
,
103 CompletionItemKind K
) {
104 return Contains(AllOf(named(std::move(Name
)), kind(K
)));
106 MATCHER(isDocumented
, "") { return arg
.Documentation
.has_value(); }
107 MATCHER(deprecated
, "") { return arg
.Deprecated
; }
109 std::unique_ptr
<SymbolIndex
> memIndex(std::vector
<Symbol
> Symbols
) {
110 SymbolSlab::Builder Slab
;
111 for (const auto &Sym
: Symbols
)
113 return MemIndex::build(std::move(Slab
).build(), RefSlab(), RelationSlab());
116 // Runs code completion.
117 // If IndexSymbols is non-empty, an index will be built and passed to opts.
118 CodeCompleteResult
completions(const TestTU
&TU
, Position Point
,
119 std::vector
<Symbol
> IndexSymbols
= {},
120 clangd::CodeCompleteOptions Opts
= {}) {
121 std::unique_ptr
<SymbolIndex
> OverrideIndex
;
122 if (!IndexSymbols
.empty()) {
123 assert(!Opts
.Index
&& "both Index and IndexSymbols given!");
124 OverrideIndex
= memIndex(std::move(IndexSymbols
));
125 Opts
.Index
= OverrideIndex
.get();
129 auto Inputs
= TU
.inputs(FS
);
130 IgnoreDiagnostics Diags
;
131 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
133 ADD_FAILURE() << "Couldn't build CompilerInvocation";
136 auto Preamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
137 /*InMemory=*/true, /*Callback=*/nullptr);
138 return codeComplete(testPath(TU
.Filename
), Point
, Preamble
.get(), Inputs
,
142 // Runs code completion.
143 CodeCompleteResult
completions(llvm::StringRef Text
,
144 std::vector
<Symbol
> IndexSymbols
= {},
145 clangd::CodeCompleteOptions Opts
= {},
146 PathRef FilePath
= "foo.cpp") {
147 Annotations
Test(Text
);
148 auto TU
= TestTU::withCode(Test
.code());
149 // To make sure our tests for completiopns inside templates work on Windows.
150 TU
.Filename
= FilePath
.str();
151 return completions(TU
, Test
.point(), std::move(IndexSymbols
),
155 // Runs code completion without the clang parser.
156 CodeCompleteResult
completionsNoCompile(llvm::StringRef Text
,
157 std::vector
<Symbol
> IndexSymbols
= {},
158 clangd::CodeCompleteOptions Opts
= {},
159 PathRef FilePath
= "foo.cpp") {
160 std::unique_ptr
<SymbolIndex
> OverrideIndex
;
161 if (!IndexSymbols
.empty()) {
162 assert(!Opts
.Index
&& "both Index and IndexSymbols given!");
163 OverrideIndex
= memIndex(std::move(IndexSymbols
));
164 Opts
.Index
= OverrideIndex
.get();
168 Annotations
Test(Text
);
169 ParseInputs ParseInput
{tooling::CompileCommand(), &FS
, Test
.code().str()};
170 return codeComplete(FilePath
, Test
.point(), /*Preamble=*/nullptr, ParseInput
,
174 Symbol
withReferences(int N
, Symbol S
) {
179 #if CLANGD_DECISION_FOREST
180 TEST(DecisionForestRankingModel
, NameMatchSanityTest
) {
181 clangd::CodeCompleteOptions Opts
;
182 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
183 auto Results
= completions(
185 struct MemberAccess {
187 int AlphaBetaGamma();
189 int func() { MemberAccess().ABG^ }
191 /*IndexSymbols=*/{}, Opts
);
192 EXPECT_THAT(Results
.Completions
,
193 ElementsAre(named("ABG"), named("AlphaBetaGamma")));
196 TEST(DecisionForestRankingModel
, ReferencesAffectRanking
) {
197 clangd::CodeCompleteOptions Opts
;
198 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
199 constexpr int NumReferences
= 100000;
201 completions("int main() { clang^ }",
202 {ns("clangA"), withReferences(NumReferences
, func("clangD"))},
205 ElementsAre(named("clangD"), named("clangA")));
207 completions("int main() { clang^ }",
208 {withReferences(NumReferences
, ns("clangA")), func("clangD")},
211 ElementsAre(named("clangA"), named("clangD")));
213 #endif // CLANGD_DECISION_FOREST
215 TEST(DecisionForestRankingModel
, DecisionForestScorerCallbackTest
) {
216 clangd::CodeCompleteOptions Opts
;
217 constexpr float MagicNumber
= 1234.5678f
;
218 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
219 Opts
.DecisionForestScorer
= [&](const SymbolQualitySignals
&,
220 const SymbolRelevanceSignals
&, float Base
) {
221 DecisionForestScores Scores
;
222 Scores
.Total
= MagicNumber
;
223 Scores
.ExcludingName
= MagicNumber
;
226 llvm::StringRef Code
= "int func() { int xyz; xy^ }";
227 auto Results
= completions(Code
,
228 /*IndexSymbols=*/{}, Opts
);
229 ASSERT_EQ(Results
.Completions
.size(), 1u);
230 EXPECT_EQ(Results
.Completions
[0].Score
.Total
, MagicNumber
);
231 EXPECT_EQ(Results
.Completions
[0].Score
.ExcludingName
, MagicNumber
);
233 // Do not use DecisionForestScorer for heuristics model.
234 Opts
.RankingModel
= CodeCompleteOptions::Heuristics
;
235 Results
= completions(Code
,
236 /*IndexSymbols=*/{}, Opts
);
237 ASSERT_EQ(Results
.Completions
.size(), 1u);
238 EXPECT_NE(Results
.Completions
[0].Score
.Total
, MagicNumber
);
239 EXPECT_NE(Results
.Completions
[0].Score
.ExcludingName
, MagicNumber
);
242 TEST(CompletionTest
, Limit
) {
243 clangd::CodeCompleteOptions Opts
;
245 auto Results
= completions(R
"cpp(
246 struct ClassWithMembers {
252 int main() { ClassWithMembers().^ }
254 /*IndexSymbols=*/{}, Opts
);
256 EXPECT_TRUE(Results
.HasMore
);
257 EXPECT_THAT(Results
.Completions
, ElementsAre(named("AAA"), named("BBB")));
260 TEST(CompletionTest
, Filter
) {
261 std::string Body
= R
"cpp(
271 // Only items matching the fuzzy query are returned.
272 EXPECT_THAT(completions(Body
+ "int main() { S().Foba^ }").Completions
,
273 AllOf(has("FooBar"), has("FooBaz"), Not(has("Qux"))));
275 // Macros require prefix match, either from index or AST.
276 Symbol Sym
= var("MotorCarIndex");
277 Sym
.SymInfo
.Kind
= index::SymbolKind::Macro
;
279 completions(Body
+ "int main() { C^ }", {Sym
}).Completions
,
280 AllOf(has("Car"), Not(has("MotorCar")), Not(has("MotorCarIndex"))));
281 EXPECT_THAT(completions(Body
+ "int main() { M^ }", {Sym
}).Completions
,
282 AllOf(has("MotorCar"), has("MotorCarIndex")));
285 void testAfterDotCompletion(clangd::CodeCompleteOptions Opts
) {
286 auto Results
= completions(
292 // Make sure this is not in preamble.
295 struct GlobalClass {};
297 struct ClassWithMembers {
307 struct LocalClass {};
309 /// doc for local_var.
315 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts
);
317 EXPECT_TRUE(Results
.RanParser
);
318 // Class members. The only items that must be present in after-dot
320 EXPECT_THAT(Results
.Completions
,
321 AllOf(has("method"), has("field"), Not(has("ClassWithMembers")),
322 Not(has("operator=")), Not(has("~ClassWithMembers"))));
323 EXPECT_IFF(Opts
.IncludeIneligibleResults
, Results
.Completions
,
324 has("private_field"));
328 Not(AnyOf(has("global_var"), has("index_var"), has("global_func"),
329 has("global_func()"), has("index_func"), has("GlobalClass"),
330 has("IndexClass"), has("MACRO"), has("LocalClass"))));
331 // There should be no code patterns (aka snippets) in after-dot
332 // completion. At least there aren't any we're aware of.
333 EXPECT_THAT(Results
.Completions
,
334 Not(Contains(kind(CompletionItemKind::Snippet
))));
335 // Check documentation.
336 EXPECT_THAT(Results
.Completions
, Contains(isDocumented()));
339 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts
) {
340 auto Results
= completions(
345 // Make sure this is not in preamble.
348 struct GlobalClass {};
350 struct ClassWithMembers {
356 struct LocalClass {};
358 /// doc for local_var.
364 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts
);
366 EXPECT_TRUE(Results
.RanParser
);
367 // Class members. Should never be present in global completions.
368 EXPECT_THAT(Results
.Completions
,
369 Not(AnyOf(has("method"), has("method()"), has("field"))));
371 EXPECT_THAT(Results
.Completions
,
372 AllOf(has("global_var"), has("index_var"), has("global_func"),
373 has("index_func" /* our fake symbol doesn't include () */),
374 has("GlobalClass"), has("IndexClass")));
376 EXPECT_THAT(Results
.Completions
, has("MACRO"));
377 // Local items. Must be present always.
378 EXPECT_THAT(Results
.Completions
,
379 AllOf(has("local_var"), has("LocalClass"),
380 Contains(kind(CompletionItemKind::Snippet
))));
381 // Check documentation.
382 EXPECT_THAT(Results
.Completions
, Contains(isDocumented()));
385 TEST(CompletionTest
, CompletionOptions
) {
386 auto Test
= [&](const clangd::CodeCompleteOptions
&Opts
) {
387 testAfterDotCompletion(Opts
);
388 testGlobalScopeCompletion(Opts
);
390 // We used to test every combination of options, but that got too slow (2^N).
392 &clangd::CodeCompleteOptions::IncludeIneligibleResults
,
394 // Test default options.
396 // Test with one flag flipped.
397 for (auto &F
: Flags
) {
398 clangd::CodeCompleteOptions O
;
404 TEST(CompletionTest
, Accessible
) {
405 auto Internal
= completions(R
"cpp(
408 protected: void prot();
409 private: void priv();
411 void Foo::pub() { this->^ }
413 EXPECT_THAT(Internal
.Completions
,
414 AllOf(has("priv"), has("prot"), has("pub")));
416 auto External
= completions(R
"cpp(
419 protected: void prot();
420 private: void priv();
427 EXPECT_THAT(External
.Completions
,
428 AllOf(has("pub"), Not(has("prot")), Not(has("priv"))));
430 auto Results
= completions(R
"cpp(
433 protected: void prot();
434 private: void priv();
436 struct Bar : public Foo {
437 private: using Foo::pub;
444 EXPECT_THAT(Results
.Completions
,
445 AllOf(Not(has("priv")), Not(has("prot")), Not(has("pub"))));
448 TEST(CompletionTest
, Qualifiers
) {
449 auto Results
= completions(R
"cpp(
451 public: int foo() const;
454 class Bar : public Foo {
457 void test() { Bar().^ }
459 EXPECT_THAT(Results
.Completions
,
460 Contains(AllOf(qualifier(""), named("bar"))));
461 // Hidden members are not shown.
462 EXPECT_THAT(Results
.Completions
,
463 Not(Contains(AllOf(qualifier("Foo::"), named("foo")))));
464 // Private members are not shown.
465 EXPECT_THAT(Results
.Completions
,
466 Not(Contains(AllOf(qualifier(""), named("foo")))));
469 // https://github.com/clangd/clangd/issues/1451
470 TEST(CompletionTest
, QualificationWithInlineNamespace
) {
471 auto Results
= completions(R
"cpp(
472 namespace a { inline namespace b {} }
473 using namespace a::b;
477 EXPECT_THAT(Results
.Completions
,
478 UnorderedElementsAre(AllOf(qualifier("a::"), named("Foo"))));
481 TEST(CompletionTest
, InjectedTypename
) {
482 // These are suppressed when accessed as a member...
483 EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions
,
485 EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions
,
487 // ...but accessible in other, more useful cases.
488 EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions
,
491 completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions
,
495 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
498 // This case is marginal (`using X::X` is useful), we allow it for now.
499 EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions
,
503 TEST(CompletionTest
, SkipInjectedWhenUnqualified
) {
504 EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions
,
505 ElementsAre(named("X"), named("~X")));
508 TEST(CompletionTest
, Snippets
) {
509 clangd::CodeCompleteOptions Opts
;
510 auto Results
= completions(
514 int f(int i, const float f) const;
521 /*IndexSymbols=*/{}, Opts
);
524 HasSubsequence(named("a"),
525 snippetSuffix("(${1:int i}, ${2:const float f})")));
528 TEST(CompletionTest
, HeuristicsForMemberFunctionCompletion
) {
529 clangd::CodeCompleteOptions Opts
;
530 Opts
.EnableSnippets
= true;
532 Annotations
Code(R
"cpp(
534 static int staticMethod(int);
535 int method(int) const;
536 template <typename T, typename U, typename V = int>
538 template <typename T, int U>
539 static T staticGeneric();
547 struct Derived : Foo {
560 ; // Prevent parsing as 'f.f'
566 d.Derived::$canBeCall^
574 ; // Prevent parsing as 'f.f'
580 d.Derived::$canBeCall^
583 auto TU
= TestTU::withCode(Code
.code());
585 for (const auto &P
: Code
.points("canNotBeCall")) {
586 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
587 EXPECT_THAT(Results
.Completions
,
588 Contains(AllOf(named("method"), signature("(int) const"),
589 snippetSuffix(""))));
590 // We don't have any arguments to deduce against if this isn't a call.
591 // Thus, we should emit these deducible template arguments explicitly.
594 Contains(AllOf(named("generic"),
595 signature("<typename T, typename U>(U, V)"),
596 snippetSuffix("<${1:typename T}, ${2:typename U}>"))));
599 for (const auto &P
: Code
.points("canBeCall")) {
600 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
601 EXPECT_THAT(Results
.Completions
,
602 Contains(AllOf(named("method"), signature("(int) const"),
603 snippetSuffix("(${1:int})"))));
606 Contains(AllOf(named("generic"), signature("<typename T>(U, V)"),
607 snippetSuffix("<${1:typename T}>(${2:U}, ${3:V})"))));
610 // static method will always keep the snippet
611 for (const auto &P
: Code
.points()) {
612 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
613 EXPECT_THAT(Results
.Completions
,
614 Contains(AllOf(named("staticMethod"), signature("(int)"),
615 snippetSuffix("(${1:int})"))));
616 EXPECT_THAT(Results
.Completions
,
618 named("staticGeneric"), signature("<typename T, int U>()"),
619 snippetSuffix("<${1:typename T}, ${2:int U}>()"))));
623 TEST(CompletionTest
, NoSnippetsInUsings
) {
624 clangd::CodeCompleteOptions Opts
;
625 Opts
.EnableSnippets
= true;
626 auto Results
= completions(
629 int func(int a, int b);
634 /*IndexSymbols=*/{}, Opts
);
635 EXPECT_THAT(Results
.Completions
,
636 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
637 snippetSuffix(""))));
639 // Check index completions too.
640 auto Func
= func("ns::func");
641 Func
.CompletionSnippetSuffix
= "(${1:int a}, ${2: int b})";
642 Func
.Signature
= "(int a, int b)";
643 Func
.ReturnType
= "void";
645 Results
= completions(R
"cpp(
649 /*IndexSymbols=*/{Func
}, Opts
);
650 EXPECT_THAT(Results
.Completions
,
651 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
652 snippetSuffix(""))));
654 // Check all-scopes completions too.
655 Opts
.AllScopes
= true;
656 Results
= completions(R
"cpp(
659 /*IndexSymbols=*/{Func
}, Opts
);
660 EXPECT_THAT(Results
.Completions
,
661 Contains(AllOf(named("func"), labeled("ns::func(int a, int b)"),
662 snippetSuffix(""))));
665 TEST(CompletionTest
, Kinds
) {
666 auto Results
= completions(
671 // make sure MACRO is not included in preamble.
675 {func("indexFunction"), var("indexVariable"), cls("indexClass"),
676 macro("indexObjMacro"), macro("indexFuncMacro", "(x, y)")});
677 EXPECT_THAT(Results
.Completions
,
678 AllOf(has("function", CompletionItemKind::Function
),
679 has("variable", CompletionItemKind::Variable
),
680 has("int", CompletionItemKind::Keyword
),
681 has("Struct", CompletionItemKind::Struct
),
682 has("MACRO", CompletionItemKind::Constant
),
683 has("indexFunction", CompletionItemKind::Function
),
684 has("indexVariable", CompletionItemKind::Variable
),
685 has("indexClass", CompletionItemKind::Class
),
686 has("indexObjMacro", CompletionItemKind::Constant
),
687 has("indexFuncMacro", CompletionItemKind::Function
)));
689 Results
= completions("nam^");
690 EXPECT_THAT(Results
.Completions
,
691 has("namespace", CompletionItemKind::Snippet
));
693 // Members of anonymous unions are of kind 'field'.
694 Results
= completions(
705 UnorderedElementsAre(AllOf(named("a"), kind(CompletionItemKind::Field
))));
707 // Completion kinds for templates should not be unknown.
708 Results
= completions(
710 template <class T> struct complete_class {};
711 template <class T> void complete_function();
712 template <class T> using complete_type_alias = int;
713 template <class T> int complete_variable = 10;
716 template <class T> static int complete_static_member = 10;
718 static auto x = complete_^
723 UnorderedElementsAre(
724 AllOf(named("complete_class"), kind(CompletionItemKind::Class
)),
725 AllOf(named("complete_function"), kind(CompletionItemKind::Function
)),
726 AllOf(named("complete_type_alias"),
727 kind(CompletionItemKind::Interface
)),
728 AllOf(named("complete_variable"), kind(CompletionItemKind::Variable
)),
729 AllOf(named("complete_static_member"),
730 kind(CompletionItemKind::Property
))));
732 Results
= completions(
741 Contains(AllOf(named("Red"), kind(CompletionItemKind::EnumMember
))));
744 TEST(CompletionTest
, NoDuplicates
) {
745 auto Results
= completions(
756 // Make sure there are no duplicate entries of 'Adapter'.
757 EXPECT_THAT(Results
.Completions
, ElementsAre(named("Adapter")));
760 TEST(CompletionTest
, ScopedNoIndex
) {
761 auto Results
= completions(
763 namespace fake { int BigBang, Babble, Box; };
764 int main() { fake::ba^ }
766 // Babble is a better match than BigBang. Box doesn't match at all.
767 EXPECT_THAT(Results.Completions,
768 ElementsAre(named("Babble
"), named("BigBang
")));
771 TEST(CompletionTest, Scoped) {
772 auto Results = completions(
774 namespace fake
{ int Babble
, Box
; };
775 int main() { fake::ba
^ }
777 {var("fake::BigBang")});
778 EXPECT_THAT(Results
.Completions
,
779 ElementsAre(named("Babble"), named("BigBang")));
782 TEST(CompletionTest
, ScopedWithFilter
) {
783 auto Results
= completions(
787 {cls("ns::XYZ"), func("ns::foo")});
788 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(named("XYZ")));
791 TEST(CompletionTest
, ReferencesAffectRanking
) {
792 EXPECT_THAT(completions("int main() { abs^ }", {func("absA"), func("absB")})
794 HasSubsequence(named("absA"), named("absB")));
795 EXPECT_THAT(completions("int main() { abs^ }",
796 {func("absA"), withReferences(1000, func("absB"))})
798 HasSubsequence(named("absB"), named("absA")));
801 TEST(CompletionTest
, ContextWords
) {
802 auto Results
= completions(R
"cpp(
803 enum class Color { RED, YELLOW, BLUE };
805 // (blank lines so the definition above isn't "context
")
807 // "It was a yellow car
," he said. "Big yellow car
, new."
808 auto Finish = Color::^
810 // Yellow would normally sort last (alphabetic).
811 // But the recent mention should bump it up.
812 ASSERT_THAT(Results
.Completions
,
813 HasSubsequence(named("YELLOW"), named("BLUE")));
816 TEST(CompletionTest
, GlobalQualified
) {
817 auto Results
= completions(
822 EXPECT_THAT(Results
.Completions
,
823 AllOf(has("XYZ", CompletionItemKind::Class
),
824 has("f", CompletionItemKind::Function
)));
827 TEST(CompletionTest
, FullyQualified
) {
828 auto Results
= completions(
830 namespace ns { void bar(); }
834 EXPECT_THAT(Results
.Completions
,
835 AllOf(has("XYZ", CompletionItemKind::Class
),
836 has("bar", CompletionItemKind::Function
)));
839 TEST(CompletionTest
, SemaIndexMerge
) {
840 auto Results
= completions(
842 namespace ns { int local; void both(); }
845 {func("ns::both"), cls("ns::Index")});
846 // We get results from both index and sema, with no duplicates.
847 EXPECT_THAT(Results
.Completions
,
848 UnorderedElementsAre(
849 AllOf(named("local"), origin(SymbolOrigin::AST
)),
850 AllOf(named("Index"), origin(SymbolOrigin::Static
)),
852 origin(SymbolOrigin::AST
| SymbolOrigin::Static
))));
855 TEST(CompletionTest
, SemaIndexMergeWithLimit
) {
856 clangd::CodeCompleteOptions Opts
;
858 auto Results
= completions(
860 namespace ns { int local; void both(); }
863 {func("ns::both"), cls("ns::Index")}, Opts
);
864 EXPECT_EQ(Results
.Completions
.size(), Opts
.Limit
);
865 EXPECT_TRUE(Results
.HasMore
);
868 TEST(CompletionTest
, IncludeInsertionPreprocessorIntegrationTests
) {
870 TU
.ExtraArgs
.push_back("-I" + testPath("sub"));
871 TU
.AdditionalFiles
["sub/bar.h"] = "";
872 auto BarURI
= URI::create(testPath("sub/bar.h")).toString();
874 Symbol Sym
= cls("ns::X");
875 Sym
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
876 Sym
.IncludeHeaders
.emplace_back(BarURI
, 1, Symbol::Include
);
877 // Shorten include path based on search directory and insert.
878 Annotations
Test("int main() { ns::^ }");
879 TU
.Code
= Test
.code().str();
880 auto Results
= completions(TU
, Test
.point(), {Sym
});
881 EXPECT_THAT(Results
.Completions
,
882 ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
883 // Can be disabled via option.
884 CodeCompleteOptions NoInsertion
;
885 NoInsertion
.InsertIncludes
= CodeCompleteOptions::NeverInsert
;
886 Results
= completions(TU
, Test
.point(), {Sym
}, NoInsertion
);
887 EXPECT_THAT(Results
.Completions
,
888 ElementsAre(AllOf(named("X"), Not(insertInclude()))));
889 // Duplicate based on inclusions in preamble.
890 Test
= Annotations(R
"cpp(
891 #include "sub
/bar
.h
" // not shortest, so should only match resolved.
894 TU
.Code
= Test
.code().str();
895 Results
= completions(TU
, Test
.point(), {Sym
});
896 EXPECT_THAT(Results
.Completions
, ElementsAre(AllOf(named("X"), labeled("X"),
897 Not(insertInclude()))));
900 TEST(CompletionTest
, NoIncludeInsertionWhenDeclFoundInFile
) {
901 Symbol SymX
= cls("ns::X");
902 Symbol SymY
= cls("ns::Y");
903 std::string BarHeader
= testPath("bar.h");
904 auto BarURI
= URI::create(BarHeader
).toString();
905 SymX
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
906 SymY
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
907 SymX
.IncludeHeaders
.emplace_back("<bar>", 1, Symbol::Include
);
908 SymY
.IncludeHeaders
.emplace_back("<bar>", 1, Symbol::Include
);
909 // Shorten include path based on search directory and insert.
910 auto Results
= completions(R
"cpp(
918 EXPECT_THAT(Results
.Completions
,
919 ElementsAre(AllOf(named("X"), Not(insertInclude())),
920 AllOf(named("Y"), Not(insertInclude()))));
923 TEST(CompletionTest
, IndexSuppressesPreambleCompletions
) {
924 Annotations
Test(R
"cpp(
926 namespace ns { int local; }
928 void f2() { ns::preamble().$2^; }
930 auto TU
= TestTU::withCode(Test
.code());
931 TU
.AdditionalFiles
["bar.h"] =
932 R
"cpp(namespace ns { struct preamble { int member; }; })cpp";
934 clangd::CodeCompleteOptions Opts
= {};
935 auto I
= memIndex({var("ns::index")});
936 Opts
.Index
= I
.get();
937 auto WithIndex
= completions(TU
, Test
.point(), {}, Opts
);
938 EXPECT_THAT(WithIndex
.Completions
,
939 UnorderedElementsAre(named("local"), named("index")));
940 auto ClassFromPreamble
= completions(TU
, Test
.point("2"), {}, Opts
);
941 EXPECT_THAT(ClassFromPreamble
.Completions
, Contains(named("member")));
943 Opts
.Index
= nullptr;
944 auto WithoutIndex
= completions(TU
, Test
.point(), {}, Opts
);
945 EXPECT_THAT(WithoutIndex
.Completions
,
946 UnorderedElementsAre(named("local"), named("preamble")));
949 // This verifies that we get normal preprocessor completions in the preamble.
950 // This is a regression test for an old bug: if we override the preamble and
951 // try to complete inside it, clang kicks our completion point just outside the
952 // preamble, resulting in always getting top-level completions.
953 TEST(CompletionTest
, CompletionInPreamble
) {
954 auto Results
= completions(R
"cpp(
962 EXPECT_THAT(Results
, ElementsAre(named("ifndef")));
965 TEST(CompletionTest
, CompletionRecoveryASTType
) {
966 auto Results
= completions(R
"cpp(
967 struct S { int member; };
970 // No overload matches, but we have recovery-expr with the correct type.
974 EXPECT_THAT(Results
, ElementsAre(named("member")));
977 TEST(CompletionTest
, DynamicIndexIncludeInsertion
) {
979 MockCompilationDatabase CDB
;
980 ClangdServer::Options Opts
= ClangdServer::optsForTest();
981 Opts
.BuildDynamicSymbolIndex
= true;
982 ClangdServer
Server(CDB
, FS
, Opts
);
984 FS
.Files
[testPath("foo_header.h")] = R
"cpp(
991 const std::string
FileContent(R
"cpp(
992 #include "foo_header
.h
"
997 Server
.addDocument(testPath("foo_impl.cpp"), FileContent
);
998 // Wait for the dynamic index being built.
999 ASSERT_TRUE(Server
.blockUntilIdleForTest());
1001 auto File
= testPath("foo.cpp");
1002 Annotations
Test("Foo^ foo;");
1003 runAddDocument(Server
, File
, Test
.code());
1004 auto CompletionList
=
1005 llvm::cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1007 EXPECT_THAT(CompletionList
.Completions
,
1008 ElementsAre(AllOf(named("Foo"), hasInclude("\"foo_header.h\""),
1012 TEST(CompletionTest
, DynamicIndexMultiFile
) {
1014 MockCompilationDatabase CDB
;
1015 auto Opts
= ClangdServer::optsForTest();
1016 Opts
.BuildDynamicSymbolIndex
= true;
1017 ClangdServer
Server(CDB
, FS
, Opts
);
1019 FS
.Files
[testPath("foo.h")] = R
"cpp(
1020 namespace ns { class XYZ {}; void foo(int x) {} }
1022 runAddDocument(Server
, testPath("foo.cpp"), R
"cpp(
1026 auto File
= testPath("bar.cpp");
1027 Annotations
Test(R
"cpp(
1035 runAddDocument(Server
, File
, Test
.code());
1037 auto Results
= cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1038 // "XYZ" and "foo" are not included in the file being completed but are still
1039 // visible through the index.
1040 EXPECT_THAT(Results
.Completions
, has("XYZ", CompletionItemKind::Class
));
1041 EXPECT_THAT(Results
.Completions
, has("foo", CompletionItemKind::Function
));
1042 EXPECT_THAT(Results
.Completions
, has("XXX", CompletionItemKind::Class
));
1043 EXPECT_THAT(Results
.Completions
,
1044 Contains((named("fooooo"), kind(CompletionItemKind::Function
),
1045 doc("Doooc"), returnType("void"))));
1048 TEST(CompletionTest
, Documentation
) {
1049 auto Results
= completions(
1051 // Non-doxygen comment.
1052 __attribute__((annotate("custom_annotation
"))) int foo();
1053 /// Doxygen comment.
1063 EXPECT_THAT(Results
.Completions
,
1066 doc("Annotation: custom_annotation\nNon-doxygen comment."))));
1068 Results
.Completions
,
1069 Contains(AllOf(named("bar"), doc("Doxygen comment.\n\\param int a"))));
1070 EXPECT_THAT(Results
.Completions
,
1071 Contains(AllOf(named("baz"), doc("Multi-line block comment"))));
1074 TEST(CompletionTest
, CommentsFromSystemHeaders
) {
1076 MockCompilationDatabase CDB
;
1078 auto Opts
= ClangdServer::optsForTest();
1079 Opts
.BuildDynamicSymbolIndex
= true;
1081 ClangdServer
Server(CDB
, FS
, Opts
);
1083 FS
.Files
[testPath("foo.h")] = R
"cpp(
1084 #pragma GCC system_header
1086 // This comment should be retained!
1090 auto File
= testPath("foo.cpp");
1091 Annotations
Test(R
"cpp(
1095 runAddDocument(Server
, File
, Test
.code());
1096 auto CompletionList
=
1097 llvm::cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1100 CompletionList
.Completions
,
1101 Contains(AllOf(named("foo"), doc("This comment should be retained!"))));
1104 TEST(CompletionTest
, GlobalCompletionFiltering
) {
1106 Symbol Class
= cls("XYZ");
1107 Class
.Flags
= static_cast<Symbol::SymbolFlag
>(
1108 Class
.Flags
& ~(Symbol::IndexedForCodeCompletion
));
1109 Symbol Func
= func("XYZ::foooo");
1110 Func
.Flags
= static_cast<Symbol::SymbolFlag
>(
1111 Func
.Flags
& ~(Symbol::IndexedForCodeCompletion
));
1113 auto Results
= completions(R
"(// void f() {
1117 EXPECT_THAT(Results
.Completions
, IsEmpty());
1120 TEST(CodeCompleteTest
, DisableTypoCorrection
) {
1121 auto Results
= completions(R
"cpp(
1122 namespace clang { int v; }
1123 void f() { clangd::^
1125 EXPECT_TRUE(Results
.Completions
.empty());
1128 TEST(CodeCompleteTest
, NoColonColonAtTheEnd
) {
1129 auto Results
= completions(R
"cpp(
1136 EXPECT_THAT(Results
.Completions
, Contains(labeled("clang")));
1137 EXPECT_THAT(Results
.Completions
, Not(Contains(labeled("clang::"))));
1140 TEST(CompletionTests
, EmptySnippetDoesNotCrash
) {
1141 // See https://github.com/clangd/clangd/issues/1216
1142 auto Results
= completions(R
"cpp(
1144 auto w = [&](auto &&f) { return f(f); };
1145 auto f = w([&](auto &&f) {
1146 return [&](auto &&n) {
1150 return n * ^(f)(n - 1);
1157 TEST(CompletionTest
, Issue1427Crash
) {
1158 // Need to provide main file signals to ensure that the branch in
1159 // SymbolRelevanceSignals::computeASTSignals() that tries to
1160 // compute a symbol ID is taken.
1161 ASTSignals MainFileSignals
;
1162 CodeCompleteOptions Opts
;
1163 Opts
.MainFileSignals
= &MainFileSignals
;
1172 TEST(CompletionTest
, BacktrackCrashes
) {
1173 // Sema calls code completion callbacks twice in these cases.
1174 auto Results
= completions(R
"cpp(
1176 struct FooBarBaz {};
1182 EXPECT_THAT(Results
.Completions
, ElementsAre(labeled("FooBarBaz")));
1184 // Check we don't crash in that case too.
1186 struct FooBarBaz {};
1188 if (FooBarBaz * x^) {}
1193 TEST(CompletionTest
, CompleteInMacroWithStringification
) {
1194 auto Results
= completions(R
"cpp(
1195 void f(const char *, int x);
1196 #define F(x) f(#x, x)
1203 int f(int input_num) {
1208 EXPECT_THAT(Results
.Completions
,
1209 UnorderedElementsAre(named("X"), named("Y")));
1212 TEST(CompletionTest
, CompleteInMacroAndNamespaceWithStringification
) {
1213 auto Results
= completions(R
"cpp(
1214 void f(const char *, int x);
1215 #define F(x) f(#x, x)
1220 int f(int input_num) {
1226 EXPECT_THAT(Results
.Completions
, Contains(named("X")));
1229 TEST(CompletionTest
, IgnoreCompleteInExcludedPPBranchWithRecoveryContext
) {
1230 auto Results
= completions(R
"cpp(
1231 int bar(int param_in_bar) {
1234 int foo(int param_in_foo) {
1236 // In recovery mode, "param_in_foo
" will also be suggested among many other
1237 // unrelated symbols; however, this is really a special case where this works.
1238 // If the #if block is outside of the function, "param_in_foo
" is still
1239 // suggested, but "bar
" and "foo
" are missing. So the recovery mode doesn't
1240 // really provide useful results in excluded branches.
1246 EXPECT_TRUE(Results
.Completions
.empty());
1249 TEST(CompletionTest
, DefaultArgs
) {
1250 clangd::CodeCompleteOptions Opts
;
1251 std::string Context
= R
"cpp(
1253 int Y(int A, int B = 0);
1254 int Z(int A, int B = 0, int C = 0, int D = 0);
1256 EXPECT_THAT(completions(Context
+ "int y = X^", {}, Opts
).Completions
,
1257 UnorderedElementsAre(labeled("X(int A = 0)")));
1258 EXPECT_THAT(completions(Context
+ "int y = Y^", {}, Opts
).Completions
,
1259 UnorderedElementsAre(AllOf(labeled("Y(int A, int B = 0)"),
1260 snippetSuffix("(${1:int A})"))));
1261 EXPECT_THAT(completions(Context
+ "int y = Z^", {}, Opts
).Completions
,
1262 UnorderedElementsAre(
1263 AllOf(labeled("Z(int A, int B = 0, int C = 0, int D = 0)"),
1264 snippetSuffix("(${1:int A})"))));
1267 TEST(CompletionTest
, NoCrashWithTemplateParamsAndPreferredTypes
) {
1268 auto Completions
= completions(R
"cpp(
1269 template <template <class> class TT> int foo() {
1274 EXPECT_THAT(Completions
, Contains(named("TT")));
1277 TEST(CompletionTest
, NestedTemplateHeuristics
) {
1278 auto Completions
= completions(R
"cpp(
1279 struct Plain { int xxx; };
1280 template <typename T> class Templ { Plain ppp; };
1281 template <typename T> void foo(Templ<T> &t) {
1282 // Formally ppp has DependentTy, because Templ may be specialized.
1283 // However we sholud be able to see into it using the primary template.
1288 EXPECT_THAT(Completions
, Contains(named("xxx")));
1291 TEST(CompletionTest
, RecordCCResultCallback
) {
1292 std::vector
<CodeCompletion
> RecordedCompletions
;
1293 CodeCompleteOptions Opts
;
1294 Opts
.RecordCCResult
= [&RecordedCompletions
](const CodeCompletion
&CC
,
1295 const SymbolQualitySignals
&,
1296 const SymbolRelevanceSignals
&,
1298 RecordedCompletions
.push_back(CC
);
1301 completions("int xy1, xy2; int a = xy^", /*IndexSymbols=*/{}, Opts
);
1302 EXPECT_THAT(RecordedCompletions
,
1303 UnorderedElementsAre(named("xy1"), named("xy2")));
1306 TEST(CompletionTest
, ASTSignals
) {
1309 unsigned MainFileRefs
;
1310 unsigned ScopeRefsInFile
;
1312 CodeCompleteOptions Opts
;
1313 std::vector
<Completion
> RecordedCompletions
;
1314 Opts
.RecordCCResult
= [&RecordedCompletions
](const CodeCompletion
&CC
,
1315 const SymbolQualitySignals
&,
1316 const SymbolRelevanceSignals
&R
,
1318 RecordedCompletions
.push_back({CC
.Name
, R
.MainFileRefs
, R
.ScopeRefsInFile
});
1320 ASTSignals MainFileSignals
;
1321 MainFileSignals
.ReferencedSymbols
[var("xy1").ID
] = 3;
1322 MainFileSignals
.ReferencedSymbols
[var("xy2").ID
] = 1;
1323 MainFileSignals
.ReferencedSymbols
[var("xyindex").ID
] = 10;
1324 MainFileSignals
.RelatedNamespaces
["tar::"] = 5;
1325 MainFileSignals
.RelatedNamespaces
["bar::"] = 3;
1326 Opts
.MainFileSignals
= &MainFileSignals
;
1327 Opts
.AllScopes
= true;
1337 /*IndexSymbols=*/{var("xyindex"), var("tar::xytar"), var("bar::xybar")},
1339 EXPECT_THAT(RecordedCompletions
,
1340 UnorderedElementsAre(
1341 AllOf(named("xy1"), mainFileRefs(3u), scopeRefs(0u)),
1342 AllOf(named("xy2"), mainFileRefs(1u), scopeRefs(0u)),
1343 AllOf(named("xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1344 AllOf(named("xytar"), mainFileRefs(0u), scopeRefs(5u)),
1345 AllOf(/*both from sema and index*/ named("xybar"),
1346 mainFileRefs(0u), scopeRefs(3u))));
1350 signatures(llvm::StringRef Text
, Position Point
,
1351 std::vector
<Symbol
> IndexSymbols
= {},
1352 MarkupKind DocumentationFormat
= MarkupKind::PlainText
) {
1353 std::unique_ptr
<SymbolIndex
> Index
;
1354 if (!IndexSymbols
.empty())
1355 Index
= memIndex(IndexSymbols
);
1357 auto TU
= TestTU::withCode(Text
);
1359 auto Inputs
= TU
.inputs(FS
);
1360 Inputs
.Index
= Index
.get();
1361 IgnoreDiagnostics Diags
;
1362 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
1364 ADD_FAILURE() << "Couldn't build CompilerInvocation";
1367 auto Preamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
1368 /*InMemory=*/true, /*Callback=*/nullptr);
1370 ADD_FAILURE() << "Couldn't build Preamble";
1373 return signatureHelp(testPath(TU
.Filename
), Point
, *Preamble
, Inputs
,
1374 DocumentationFormat
);
1378 signatures(llvm::StringRef Text
, std::vector
<Symbol
> IndexSymbols
= {},
1379 MarkupKind DocumentationFormat
= MarkupKind::PlainText
) {
1380 Annotations
Test(Text
);
1381 return signatures(Test
.code(), Test
.point(), std::move(IndexSymbols
),
1382 DocumentationFormat
);
1385 struct ExpectedParameter
{
1387 std::pair
<unsigned, unsigned> Offsets
;
1389 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
,
1390 const ExpectedParameter
&P
) {
1391 return OS
<< P
.Text
;
1393 MATCHER_P(paramsAre
, P
, "") {
1394 if (P
.size() != arg
.parameters
.size())
1396 for (unsigned I
= 0; I
< P
.size(); ++I
) {
1397 if (P
[I
].Text
!= arg
.parameters
[I
].labelString
||
1398 P
[I
].Offsets
!= arg
.parameters
[I
].labelOffsets
)
1403 MATCHER_P(sigDoc
, doc
, "") { return arg
.documentation
.value
== doc
; }
1405 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g.
1406 /// foo([[int p1]], [[double p2]]) -> void
1407 Matcher
<SignatureInformation
> sig(llvm::StringRef AnnotatedLabel
) {
1408 llvm::Annotations
A(AnnotatedLabel
);
1409 std::string Label
= std::string(A
.code());
1410 std::vector
<ExpectedParameter
> Parameters
;
1411 for (auto Range
: A
.ranges()) {
1412 Parameters
.emplace_back();
1414 ExpectedParameter
&P
= Parameters
.back();
1415 P
.Text
= Label
.substr(Range
.Begin
, Range
.End
- Range
.Begin
);
1416 P
.Offsets
.first
= lspLength(llvm::StringRef(Label
).substr(0, Range
.Begin
));
1417 P
.Offsets
.second
= lspLength(llvm::StringRef(Label
).substr(1, Range
.End
));
1419 return AllOf(sigHelpLabeled(Label
), paramsAre(Parameters
));
1422 TEST(SignatureHelpTest
, Overloads
) {
1423 auto Results
= signatures(R
"cpp(
1424 void foo(int x, int y);
1425 void foo(int x, float y);
1426 void foo(float x, int y);
1427 void foo(float x, float y);
1428 void bar(int x, int y = 0);
1429 int main() { foo(^); }
1431 EXPECT_THAT(Results
.signatures
,
1432 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1433 sig("foo([[float x]], [[int y]]) -> void"),
1434 sig("foo([[int x]], [[float y]]) -> void"),
1435 sig("foo([[int x]], [[int y]]) -> void")));
1436 // We always prefer the first signature.
1437 EXPECT_EQ(0, Results
.activeSignature
);
1438 EXPECT_EQ(0, Results
.activeParameter
);
1441 TEST(SignatureHelpTest
, FunctionPointers
) {
1442 llvm::StringLiteral Tests
[] = {
1443 // Variable of function pointer type
1445 void (*foo)(int x, int y);
1446 int main() { foo(^); }
1448 // Wrapped in an AttributedType
1450 void (__stdcall *foo)(int x, int y);
1451 int main() { foo(^); }
1453 // Another syntax for an AttributedType
1455 void (__attribute__(stdcall) *foo)(int x, int y);
1456 int main() { foo(^); },
1458 // Wrapped in a typedef
1460 typedef void (*fn)(int x, int y);
1462 int main() { foo(^); }
1464 // Wrapped in both a typedef and an AttributedTyped
1466 typedef void (__stdcall *fn)(int x, int y);
1468 int main() { foo(^); }
1470 // Field of function pointer type
1473 void (*foo)(int x, int y);
1476 int main() { s.foo(^); }
1478 // Field of function pointer typedef type
1480 typedef void (*fn)(int x, int y);
1485 int main() { s.foo(^); }
1487 for (auto Test
: Tests
)
1488 EXPECT_THAT(signatures(Test
).signatures
,
1489 UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1492 TEST(SignatureHelpTest
, Constructors
) {
1493 std::string Top
= R
"cpp(
1496 S(const S &) = delete;
1500 auto CheckParenInit
= [&](std::string Init
) {
1501 EXPECT_THAT(signatures(Top
+ Init
).signatures
,
1502 UnorderedElementsAre(sig("S([[int]])")))
1505 CheckParenInit("S s(^);");
1506 CheckParenInit("auto s = S(^);");
1507 CheckParenInit("auto s = new S(^);");
1509 auto CheckBracedInit
= [&](std::string Init
) {
1510 EXPECT_THAT(signatures(Top
+ Init
).signatures
,
1511 UnorderedElementsAre(sig("S{[[int]]}")))
1514 CheckBracedInit("S s{^};");
1515 CheckBracedInit("S s = {^};");
1516 CheckBracedInit("auto s = S{^};");
1517 // FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression.
1518 // CheckBracedInit("auto s = new S{^};");
1519 CheckBracedInit("int x(S); int i = x({^});");
1522 TEST(SignatureHelpTest
, Aggregates
) {
1523 std::string Top
= R
"cpp(
1528 auto AggregateSig
= sig("S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1529 EXPECT_THAT(signatures(Top
+ "S s{^}").signatures
,
1530 UnorderedElementsAre(AggregateSig
, sig("S{}"),
1531 sig("S{[[const S &]]}"),
1532 sig("S{[[S &&]]}")));
1533 EXPECT_THAT(signatures(Top
+ "S s{1,^}").signatures
,
1534 ElementsAre(AggregateSig
));
1535 EXPECT_EQ(signatures(Top
+ "S s{1,^}").activeParameter
, 1);
1536 EXPECT_THAT(signatures(Top
+ "S s{.c=3,^}").signatures
,
1537 ElementsAre(AggregateSig
));
1538 EXPECT_EQ(signatures(Top
+ "S s{.c=3,^}").activeParameter
, 3);
1541 TEST(SignatureHelpTest
, OverloadInitListRegression
) {
1542 auto Results
= signatures(R
"cpp(
1551 EXPECT_THAT(Results
.signatures
, UnorderedElementsAre(sig("f() -> void")));
1554 TEST(SignatureHelpTest
, DefaultArgs
) {
1555 auto Results
= signatures(R
"cpp(
1556 void bar(int x, int y = 0);
1557 void bar(float x = 0, int y = 42);
1560 EXPECT_THAT(Results
.signatures
,
1561 UnorderedElementsAre(
1562 sig("bar([[int x]], [[int y = 0]]) -> void"),
1563 sig("bar([[float x = 0]], [[int y = 42]]) -> void")));
1564 EXPECT_EQ(0, Results
.activeSignature
);
1565 EXPECT_EQ(0, Results
.activeParameter
);
1568 TEST(SignatureHelpTest
, ActiveArg
) {
1569 auto Results
= signatures(R
"cpp(
1570 int baz(int a, int b, int c);
1571 int main() { baz(baz(1,2,3), ^); }
1573 EXPECT_THAT(Results
.signatures
,
1574 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1575 EXPECT_EQ(0, Results
.activeSignature
);
1576 EXPECT_EQ(1, Results
.activeParameter
);
1579 TEST(SignatureHelpTest
, OpeningParen
) {
1580 llvm::StringLiteral Tests
[] = {
1581 // Recursive function call.
1583 int foo(int a, int b, int c);
1585 foo(foo $p^( foo(10, 10, 10), ^ )));
1587 // Functional type cast.
1590 Foo(int a, int b, int c);
1598 Foo(int a, int b, int c);
1601 new Foo $p^( 10, ^ );
1605 int foo(int a, int b, int c);
1609 // Macro expansions.
1614 int foo(int a, int b, int c);
1617 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1618 // the recovery expression.
1619 ID(foo $p^( 10, ^ ))
1623 int foo(int a, int b);
1624 template <typename T> void bar(T t) {
1627 // Dependent args on templated func.
1629 template <typename T>
1631 template <typename T> void bar(T t) {
1634 // Dependent args on member.
1636 struct Foo { int foo(int, int); };
1637 template <typename T> void bar(T t) {
1641 // Dependent args on templated member.
1643 struct Foo { template <typename T> int foo(T, T); };
1644 template <typename T> void bar(T t) {
1650 for (auto Test
: Tests
) {
1651 Annotations
Code(Test
);
1652 EXPECT_EQ(signatures(Code
.code(), Code
.point()).argListStart
,
1654 << "Test source:" << Test
;
1658 TEST(SignatureHelpTest
, StalePreamble
) {
1661 IgnoreDiagnostics Diags
;
1663 auto Inputs
= TU
.inputs(FS
);
1664 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
1666 auto EmptyPreamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
1667 /*InMemory=*/true, /*Callback=*/nullptr);
1668 ASSERT_TRUE(EmptyPreamble
);
1670 TU
.AdditionalFiles
["a.h"] = "int foo(int x);";
1671 const Annotations
Test(R
"cpp(
1673 void bar() { foo(^2); })cpp");
1674 TU
.Code
= Test
.code().str();
1676 signatureHelp(testPath(TU
.Filename
), Test
.point(), *EmptyPreamble
,
1677 TU
.inputs(FS
), MarkupKind::PlainText
);
1678 EXPECT_THAT(Results
.signatures
, ElementsAre(sig("foo([[int x]]) -> int")));
1679 EXPECT_EQ(0, Results
.activeSignature
);
1680 EXPECT_EQ(0, Results
.activeParameter
);
1683 class IndexRequestCollector
: public SymbolIndex
{
1685 IndexRequestCollector(std::vector
<Symbol
> Syms
= {}) : Symbols(Syms
) {}
1688 fuzzyFind(const FuzzyFindRequest
&Req
,
1689 llvm::function_ref
<void(const Symbol
&)> Callback
) const override
{
1690 std::unique_lock
<std::mutex
> Lock(Mut
);
1691 Requests
.push_back(Req
);
1692 ReceivedRequestCV
.notify_one();
1693 for (const auto &Sym
: Symbols
)
1698 void lookup(const LookupRequest
&,
1699 llvm::function_ref
<void(const Symbol
&)>) const override
{}
1701 bool refs(const RefsRequest
&,
1702 llvm::function_ref
<void(const Ref
&)>) const override
{
1706 void relations(const RelationsRequest
&,
1707 llvm::function_ref
<void(const SymbolID
&, const Symbol
&)>)
1710 llvm::unique_function
<IndexContents(llvm::StringRef
) const>
1711 indexedFiles() const override
{
1712 return [](llvm::StringRef
) { return IndexContents::None
; };
1715 // This is incorrect, but IndexRequestCollector is not an actual index and it
1716 // isn't used in production code.
1717 size_t estimateMemoryUsage() const override
{ return 0; }
1719 const std::vector
<FuzzyFindRequest
> consumeRequests(size_t Num
) const {
1720 std::unique_lock
<std::mutex
> Lock(Mut
);
1721 EXPECT_TRUE(wait(Lock
, ReceivedRequestCV
, timeoutSeconds(30),
1722 [this, Num
] { return Requests
.size() == Num
; }));
1723 auto Reqs
= std::move(Requests
);
1729 std::vector
<Symbol
> Symbols
;
1730 // We need a mutex to handle async fuzzy find requests.
1731 mutable std::condition_variable ReceivedRequestCV
;
1732 mutable std::mutex Mut
;
1733 mutable std::vector
<FuzzyFindRequest
> Requests
;
1736 // Clients have to consume exactly Num requests.
1737 std::vector
<FuzzyFindRequest
> captureIndexRequests(llvm::StringRef Code
,
1739 clangd::CodeCompleteOptions Opts
;
1740 IndexRequestCollector Requests
;
1741 Opts
.Index
= &Requests
;
1742 completions(Code
, {}, Opts
);
1743 const auto Reqs
= Requests
.consumeRequests(Num
);
1744 EXPECT_EQ(Reqs
.size(), Num
);
1748 TEST(CompletionTest
, UnqualifiedIdQuery
) {
1749 auto Requests
= captureIndexRequests(R
"cpp(
1751 using namespace std;
1759 EXPECT_THAT(Requests
,
1760 ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1761 UnorderedElementsAre("", "ns::", "std::"))));
1764 TEST(CompletionTest
, EnclosingScopeComesFirst
) {
1765 auto Requests
= captureIndexRequests(R
"cpp(
1767 using namespace std;
1779 EXPECT_THAT(Requests
,
1781 &FuzzyFindRequest::Scopes
,
1782 UnorderedElementsAre("", "std::", "nx::ns::", "nx::"))));
1783 EXPECT_EQ(Requests
[0].Scopes
[0], "nx::ns::");
1786 TEST(CompletionTest
, ResolvedQualifiedIdQuery
) {
1787 auto Requests
= captureIndexRequests(R
"cpp(
1789 namespace ns2 {} // ignore
1790 namespace ns3 { namespace nns3 {} }
1792 using namespace ns1;
1793 using namespace ns3::nns3;
1802 EXPECT_THAT(Requests
,
1804 &FuzzyFindRequest::Scopes
,
1805 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::"))));
1808 TEST(CompletionTest
, UnresolvedQualifierIdQuery
) {
1809 auto Requests
= captureIndexRequests(R
"cpp(
1819 EXPECT_THAT(Requests
,
1821 &FuzzyFindRequest::Scopes
,
1822 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
1825 TEST(CompletionTest
, UnresolvedNestedQualifierIdQuery
) {
1826 auto Requests
= captureIndexRequests(R
"cpp(
1836 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1837 UnorderedElementsAre("a::bar::"))));
1840 TEST(CompletionTest
, EmptyQualifiedQuery
) {
1841 auto Requests
= captureIndexRequests(R
"cpp(
1849 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1850 UnorderedElementsAre("", "ns::"))));
1853 TEST(CompletionTest
, GlobalQualifiedQuery
) {
1854 auto Requests
= captureIndexRequests(R
"cpp(
1862 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1863 UnorderedElementsAre(""))));
1866 TEST(CompletionTest
, NoDuplicatedQueryScopes
) {
1867 auto Requests
= captureIndexRequests(R
"cpp(
1878 EXPECT_THAT(Requests
,
1879 ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1880 UnorderedElementsAre("na::", "na::nb::", ""))));
1883 TEST(CompletionTest
, NoIndexCompletionsInsideClasses
) {
1884 auto Completions
= completions(
1887 int SomeNameOfField;
1888 typedef int SomeNameOfTypedefField;
1892 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
1894 EXPECT_THAT(Completions
.Completions
,
1895 AllOf(Contains(labeled("SomeNameOfField")),
1896 Contains(labeled("SomeNameOfTypedefField")),
1897 Not(Contains(labeled("SomeNameInTheIndex")))));
1900 TEST(CompletionTest
, NoIndexCompletionsInsideDependentCode
) {
1902 auto Completions
= completions(
1909 {func("::SomeNameInTheIndex")});
1911 EXPECT_THAT(Completions
.Completions
,
1912 Not(Contains(labeled("SomeNameInTheIndex"))));
1916 auto Completions
= completions(
1920 T::template Y<int>::^
1923 {func("::SomeNameInTheIndex")});
1925 EXPECT_THAT(Completions
.Completions
,
1926 Not(Contains(labeled("SomeNameInTheIndex"))));
1930 auto Completions
= completions(
1937 {func("::SomeNameInTheIndex")});
1939 EXPECT_THAT(Completions
.Completions
,
1940 Not(Contains(labeled("SomeNameInTheIndex"))));
1944 TEST(CompletionTest
, OverloadBundling
) {
1945 clangd::CodeCompleteOptions Opts
;
1946 Opts
.BundleOverloads
= true;
1948 std::string Context
= R
"cpp(
1950 // Overload with int
1951 int a(int) __attribute__((deprecated("", "")));
1952 // Overload with bool
1963 // Member completions are bundled.
1964 EXPECT_THAT(completions(Context
+ "int y = X().^", {}, Opts
).Completions
,
1965 UnorderedElementsAre(labeled("a(…)"), labeled("b(float)")));
1967 // Constructor completions are bundled.
1968 EXPECT_THAT(completions(Context
+ "X z = X^", {}, Opts
).Completions
,
1969 UnorderedElementsAre(labeled("X"), labeled("X(…)")));
1971 // Non-member completions are bundled, including index+sema.
1972 Symbol NoArgsGFunc
= func("GFuncC");
1974 completions(Context
+ "int y = GFunc^", {NoArgsGFunc
}, Opts
).Completions
,
1975 UnorderedElementsAre(labeled("GFuncC(…)"), labeled("GFuncD(int)")));
1977 // Differences in header-to-insert suppress bundling.
1978 std::string DeclFile
= URI::create(testPath("foo")).toString();
1979 NoArgsGFunc
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
1980 NoArgsGFunc
.IncludeHeaders
.emplace_back("<foo>", 1, Symbol::Include
);
1982 completions(Context
+ "int y = GFunc^", {NoArgsGFunc
}, Opts
).Completions
,
1983 UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")),
1984 labeled("GFuncC(int)"), labeled("GFuncD(int)")));
1986 // Examine a bundled completion in detail.
1988 completions(Context
+ "int y = X().a^", {}, Opts
).Completions
.front();
1989 EXPECT_EQ(A
.Name
, "a");
1990 EXPECT_EQ(A
.Signature
, "(…)");
1991 EXPECT_EQ(A
.BundleSize
, 2u);
1992 EXPECT_EQ(A
.Kind
, CompletionItemKind::Method
);
1993 EXPECT_EQ(A
.ReturnType
, "int"); // All overloads return int.
1994 // For now we just return one of the doc strings arbitrarily.
1995 ASSERT_TRUE(A
.Documentation
);
1996 ASSERT_FALSE(A
.Deprecated
); // Not all overloads deprecated.
1998 A
.Documentation
->asPlainText(),
1999 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool")));
2000 EXPECT_EQ(A
.SnippetSuffix
, "($0)");
2003 TEST(CompletionTest
, OverloadBundlingSameFileDifferentURI
) {
2004 clangd::CodeCompleteOptions Opts
;
2005 Opts
.BundleOverloads
= true;
2007 Symbol SymX
= sym("ns::X", index::SymbolKind::Function
, "@F@\\0#");
2008 Symbol SymY
= sym("ns::X", index::SymbolKind::Function
, "@F@\\0#I#");
2009 std::string BarHeader
= testPath("bar.h");
2010 auto BarURI
= URI::create(BarHeader
).toString();
2011 SymX
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
2012 SymY
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
2013 // The include header is different, but really it's the same file.
2014 SymX
.IncludeHeaders
.emplace_back("\"bar.h\"", 1, Symbol::Include
);
2015 SymY
.IncludeHeaders
.emplace_back(BarURI
.c_str(), 1, Symbol::Include
);
2017 auto Results
= completions("void f() { ::ns::^ }", {SymX
, SymY
}, Opts
);
2018 // Expect both results are bundled, despite the different-but-same
2020 ASSERT_EQ(1u, Results
.Completions
.size());
2021 const auto &R
= Results
.Completions
.front();
2022 EXPECT_EQ("X", R
.Name
);
2023 EXPECT_EQ(2u, R
.BundleSize
);
2026 TEST(CompletionTest
, DocumentationFromChangedFileCrash
) {
2028 auto FooH
= testPath("foo.h");
2029 auto FooCpp
= testPath("foo.cpp");
2030 FS
.Files
[FooH
] = R
"cpp(
2031 // this is my documentation comment.
2034 FS
.Files
[FooCpp
] = "";
2036 MockCompilationDatabase CDB
;
2037 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2039 Annotations
Source(R
"cpp(
2042 // This makes sure we have func from header in the AST.
2046 Server
.addDocument(FooCpp
, Source
.code(), "null", WantDiagnostics::Yes
);
2047 // We need to wait for preamble to build.
2048 ASSERT_TRUE(Server
.blockUntilIdleForTest());
2050 // Change the header file. Completion will reuse the old preamble!
2051 FS
.Files
[FooH
] = R
"cpp(
2055 clangd::CodeCompleteOptions Opts
;
2056 CodeCompleteResult Completions
=
2057 cantFail(runCodeComplete(Server
, FooCpp
, Source
.point(), Opts
));
2058 // We shouldn't crash. Unfortunately, current workaround is to not produce
2059 // comments for symbols from headers.
2060 EXPECT_THAT(Completions
.Completions
,
2061 Contains(AllOf(Not(isDocumented()), named("func"))));
2064 TEST(CompletionTest
, NonDocComments
) {
2065 const char *Text
= R
"cpp(
2066 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
2067 namespace comments_ns {
2070 // ------------------
2073 // A comment and a decl are separated by newlines.
2074 // Therefore, the comment shouldn't show up as doc comment.
2078 // this comment should be in the results.
2085 int comments_quux();
2089 // This comment should not be there.
2092 int Struct<T>::comments_qux() {
2095 // This comment **should** be in results.
2097 int Struct<T>::comments_quux() {
2102 // We should not get any of those comments in completion.
2104 completions(Text
).Completions
,
2105 UnorderedElementsAre(AllOf(Not(isDocumented()), named("comments_foo")),
2106 AllOf(isDocumented(), named("comments_baz")),
2107 AllOf(isDocumented(), named("comments_quux")),
2108 AllOf(Not(isDocumented()), named("comments_ns")),
2109 // FIXME(ibiryukov): the following items should have
2110 // empty documentation, since they are separated from
2111 // a comment with an empty line. Unfortunately, I
2112 // couldn't make Sema tests pass if we ignore those.
2113 AllOf(isDocumented(), named("comments_bar")),
2114 AllOf(isDocumented(), named("comments_qux"))));
2117 TEST(CompletionTest
, CompleteOnInvalidLine
) {
2118 auto FooCpp
= testPath("foo.cpp");
2120 MockCompilationDatabase CDB
;
2122 FS
.Files
[FooCpp
] = "// empty file";
2124 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2125 // Run completion outside the file range.
2129 EXPECT_THAT_EXPECTED(
2130 runCodeComplete(Server
, FooCpp
, Pos
, clangd::CodeCompleteOptions()),
2134 TEST(CompletionTest
, QualifiedNames
) {
2135 auto Results
= completions(
2137 namespace ns { int local; void both(); }
2138 void f() { ::ns::^ }
2140 {func("ns::both"), cls("ns::Index")});
2141 // We get results from both index and sema, with no duplicates.
2143 Results
.Completions
,
2144 UnorderedElementsAre(scope("ns::"), scope("ns::"), scope("ns::")));
2147 TEST(CompletionTest
, Render
) {
2151 C
.Signature
= "(bool) const";
2152 C
.SnippetSuffix
= "(${0:bool})";
2153 C
.ReturnType
= "int";
2154 C
.RequiredQualifier
= "Foo::";
2155 C
.Scope
= "ns::Foo::";
2156 C
.Documentation
.emplace();
2157 C
.Documentation
->addParagraph().appendText("This is ").appendCode("x()");
2158 C
.Includes
.emplace_back();
2159 auto &Include
= C
.Includes
.back();
2160 Include
.Header
= "\"foo.h\"";
2161 C
.Kind
= CompletionItemKind::Method
;
2162 C
.Score
.Total
= 1.0;
2163 C
.Score
.ExcludingName
= .5;
2164 C
.Origin
= SymbolOrigin::AST
| SymbolOrigin::Static
;
2166 CodeCompleteOptions Opts
;
2167 Opts
.IncludeIndicator
.Insert
= "^";
2168 Opts
.IncludeIndicator
.NoInsert
= "";
2169 Opts
.EnableSnippets
= false;
2171 auto R
= C
.render(Opts
);
2172 EXPECT_EQ(R
.label
, "Foo::x");
2173 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2174 EXPECT_EQ(R
.insertText
, "Foo::x");
2175 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::PlainText
);
2176 EXPECT_EQ(R
.filterText
, "x");
2177 EXPECT_EQ(R
.detail
, "int");
2178 EXPECT_EQ(R
.documentation
->value
, "From \"foo.h\"\nThis is x()");
2179 EXPECT_THAT(R
.additionalTextEdits
, IsEmpty());
2180 EXPECT_EQ(R
.sortText
, sortText(1.0, "x"));
2181 EXPECT_FALSE(R
.deprecated
);
2182 EXPECT_EQ(R
.score
, .5f
);
2184 C
.FilterText
= "xtra";
2186 EXPECT_EQ(R
.filterText
, "xtra");
2187 EXPECT_EQ(R
.sortText
, sortText(1.0, "xtra"));
2189 Opts
.EnableSnippets
= true;
2191 EXPECT_EQ(R
.insertText
, "Foo::x(${0:bool})");
2192 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::Snippet
);
2194 C
.SnippetSuffix
= "";
2196 EXPECT_EQ(R
.insertText
, "Foo::x");
2197 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::PlainText
);
2199 Include
.Insertion
.emplace();
2201 EXPECT_EQ(R
.label
, "^Foo::x");
2202 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2203 EXPECT_THAT(R
.additionalTextEdits
, Not(IsEmpty()));
2205 Opts
.ShowOrigins
= true;
2207 EXPECT_EQ(R
.label
, "^[AS]Foo::x");
2208 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2212 EXPECT_EQ(R
.detail
, "[2 overloads]");
2213 EXPECT_EQ(R
.documentation
->value
, "From \"foo.h\"\nThis is x()");
2215 C
.Deprecated
= true;
2217 EXPECT_TRUE(R
.deprecated
);
2219 Opts
.DocumentationFormat
= MarkupKind::Markdown
;
2221 EXPECT_EQ(R
.documentation
->value
, "From `\"foo.h\"` \nThis is `x()`");
2224 TEST(CompletionTest
, IgnoreRecoveryResults
) {
2225 auto Results
= completions(
2227 namespace ns { int NotRecovered() { return 0; } }
2229 // Sema enters recovery mode first and then normal mode.
2230 if (auto x = ns::NotRecover^)
2233 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(named("NotRecovered")));
2236 TEST(CompletionTest
, ScopeOfClassFieldInConstructorInitializer
) {
2237 auto Results
= completions(
2240 class X { public: X(); int x_; };
2244 EXPECT_THAT(Results
.Completions
,
2245 UnorderedElementsAre(AllOf(scope("ns::X::"), named("x_"))));
2248 // Like other class members, constructor init lists have to parse what's below,
2249 // after the completion point.
2250 // But recovering from an incomplete constructor init list is particularly
2251 // tricky because the bulk of the list is not surrounded by brackets.
2252 TEST(CompletionTest
, ConstructorInitListIncomplete
) {
2253 auto Results
= completions(
2262 EXPECT_THAT(Results
.Completions
, ElementsAre(named("xyz_")));
2264 Results
= completions(
2275 EXPECT_THAT(Results
.Completions
, ElementsAre(named("foo")));
2278 TEST(CompletionTest
, CodeCompletionContext
) {
2279 auto Results
= completions(
2282 class X { public: X(); int x_; };
2290 EXPECT_THAT(Results
.Context
, CodeCompletionContext::CCC_DotMemberAccess
);
2293 TEST(CompletionTest
, FixItForArrowToDot
) {
2295 MockCompilationDatabase CDB
;
2297 CodeCompleteOptions Opts
;
2298 Opts
.IncludeFixIts
= true;
2305 class ClassWithPtr {
2307 void MemberFunction();
2308 Auxilary* operator->() const;
2316 auto Results
= completions(Code
, {}, Opts
);
2317 EXPECT_EQ(Results
.Completions
.size(), 3u);
2319 TextEdit ReplacementEdit
;
2320 ReplacementEdit
.range
= Annotations(Code
).range();
2321 ReplacementEdit
.newText
= ".";
2322 for (const auto &C
: Results
.Completions
) {
2323 EXPECT_TRUE(C
.FixIts
.size() == 1u || C
.Name
== "AuxFunction");
2324 if (!C
.FixIts
.empty()) {
2325 EXPECT_THAT(C
.FixIts
, ElementsAre(ReplacementEdit
));
2330 TEST(CompletionTest
, FixItForDotToArrow
) {
2331 CodeCompleteOptions Opts
;
2332 Opts
.IncludeFixIts
= true;
2339 class ClassWithPtr {
2341 void MemberFunction();
2342 Auxilary* operator->() const;
2350 auto Results
= completions(Code
, {}, Opts
);
2351 EXPECT_EQ(Results
.Completions
.size(), 3u);
2353 TextEdit ReplacementEdit
;
2354 ReplacementEdit
.range
= Annotations(Code
).range();
2355 ReplacementEdit
.newText
= "->";
2356 for (const auto &C
: Results
.Completions
) {
2357 EXPECT_TRUE(C
.FixIts
.empty() || C
.Name
== "AuxFunction");
2358 if (!C
.FixIts
.empty()) {
2359 EXPECT_THAT(C
.FixIts
, ElementsAre(ReplacementEdit
));
2364 TEST(CompletionTest
, RenderWithFixItMerged
) {
2366 FixIt
.range
.end
.character
= 5;
2367 FixIt
.newText
= "->";
2371 C
.RequiredQualifier
= "Foo::";
2373 C
.CompletionTokenRange
.start
.character
= 5;
2375 CodeCompleteOptions Opts
;
2376 Opts
.IncludeFixIts
= true;
2378 auto R
= C
.render(Opts
);
2379 EXPECT_TRUE(R
.textEdit
);
2380 EXPECT_EQ(R
.textEdit
->newText
, "->Foo::x");
2381 EXPECT_TRUE(R
.additionalTextEdits
.empty());
2384 TEST(CompletionTest
, RenderWithFixItNonMerged
) {
2386 FixIt
.range
.end
.character
= 4;
2387 FixIt
.newText
= "->";
2391 C
.RequiredQualifier
= "Foo::";
2393 C
.CompletionTokenRange
.start
.character
= 5;
2395 CodeCompleteOptions Opts
;
2396 Opts
.IncludeFixIts
= true;
2398 auto R
= C
.render(Opts
);
2399 EXPECT_TRUE(R
.textEdit
);
2400 EXPECT_EQ(R
.textEdit
->newText
, "Foo::x");
2401 EXPECT_THAT(R
.additionalTextEdits
, UnorderedElementsAre(FixIt
));
2404 TEST(CompletionTest
, CompletionTokenRange
) {
2406 MockCompilationDatabase CDB
;
2408 TU
.AdditionalFiles
["foo/abc/foo.h"] = "";
2410 constexpr const char *TestCodes
[] = {
2432 #include "foo
/[[a
^/]]foo
.h
"
2435 #include "foo
/abc
/[[fo
^o
.h
"]]
2438 for (const auto &Text
: TestCodes
) {
2439 Annotations
TestCode(Text
);
2440 TU
.Code
= TestCode
.code().str();
2441 auto Results
= completions(TU
, TestCode
.point());
2442 if (Results
.Completions
.size() != 1) {
2443 ADD_FAILURE() << "Results.Completions.size() != 1" << Text
;
2446 EXPECT_THAT(Results
.Completions
.front().CompletionTokenRange
,
2451 TEST(SignatureHelpTest
, OverloadsOrdering
) {
2452 const auto Results
= signatures(R
"cpp(
2454 void foo(int x, float y);
2455 void foo(float x, int y);
2456 void foo(float x, float y);
2457 void foo(int x, int y = 0);
2458 int main() { foo(^); }
2460 EXPECT_THAT(Results
.signatures
,
2461 ElementsAre(sig("foo([[int x]]) -> void"),
2462 sig("foo([[int x]], [[int y = 0]]) -> void"),
2463 sig("foo([[float x]], [[int y]]) -> void"),
2464 sig("foo([[int x]], [[float y]]) -> void"),
2465 sig("foo([[float x]], [[float y]]) -> void")));
2466 // We always prefer the first signature.
2467 EXPECT_EQ(0, Results
.activeSignature
);
2468 EXPECT_EQ(0, Results
.activeParameter
);
2471 TEST(SignatureHelpTest
, InstantiatedSignatures
) {
2472 StringRef Sig0
= R
"cpp(
2481 EXPECT_THAT(signatures(Sig0
).signatures
,
2482 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2484 StringRef Sig1
= R
"cpp(
2492 EXPECT_THAT(signatures(Sig1
).signatures
,
2493 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2495 StringRef Sig2
= R
"cpp(
2496 template <class ...T>
2504 EXPECT_THAT(signatures(Sig2
).signatures
,
2505 ElementsAre(sig("foo([[T...]]) -> void")));
2507 // It is debatable whether we should substitute the outer template parameter
2508 // ('T') in that case. Currently we don't substitute it in signature help, but
2509 // do substitute in code complete.
2510 // FIXME: make code complete and signature help consistent, figure out which
2512 StringRef Sig3
= R
"cpp(
2520 X<int>().foo<double>(^)
2524 EXPECT_THAT(signatures(Sig3
).signatures
,
2525 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2528 TEST(SignatureHelpTest
, IndexDocumentation
) {
2529 Symbol Foo0
= sym("foo", index::SymbolKind::Function
, "@F@\\0#");
2530 Foo0
.Documentation
= "doc from the index";
2531 Symbol Foo1
= sym("foo", index::SymbolKind::Function
, "@F@\\0#I#");
2532 Foo1
.Documentation
= "doc from the index";
2533 Symbol Foo2
= sym("foo", index::SymbolKind::Function
, "@F@\\0#I#I#");
2535 StringRef Sig0
= R
"cpp(
2545 signatures(Sig0
, {Foo0
}).signatures
,
2546 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2547 AllOf(sig("foo([[double]]) -> int"), sigDoc(""))));
2549 StringRef Sig1
= R
"cpp(
2551 // Overriden doc from sema
2562 signatures(Sig1
, {Foo0
, Foo1
, Foo2
}).signatures
,
2564 AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2565 AllOf(sig("foo([[int]]) -> int"), sigDoc("Overriden doc from sema")),
2566 AllOf(sig("foo([[int]], [[int]]) -> int"), sigDoc("doc from sema"))));
2569 TEST(SignatureHelpTest
, DynamicIndexDocumentation
) {
2571 MockCompilationDatabase CDB
;
2572 ClangdServer::Options Opts
= ClangdServer::optsForTest();
2573 Opts
.BuildDynamicSymbolIndex
= true;
2574 ClangdServer
Server(CDB
, FS
, Opts
);
2576 FS
.Files
[testPath("foo.h")] = R
"cpp(
2582 Annotations
FileContent(R
"cpp(
2589 auto File
= testPath("test.cpp");
2590 Server
.addDocument(File
, FileContent
.code());
2591 // Wait for the dynamic index being built.
2592 ASSERT_TRUE(Server
.blockUntilIdleForTest());
2593 EXPECT_THAT(llvm::cantFail(runSignatureHelp(Server
, File
, FileContent
.point(),
2594 MarkupKind::PlainText
))
2596 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
2599 TEST(CompletionTest
, ArgumentListsPolicy
) {
2600 CodeCompleteOptions Opts
;
2601 Opts
.EnableSnippets
= true;
2602 Opts
.ArgumentLists
= Config::ArgumentListsPolicy::Delimiters
;
2605 auto Results
= completions(
2608 void xfoo(int x, int y);
2609 void f() { xfo^ })cpp",
2612 Results
.Completions
,
2613 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("()")),
2614 AllOf(named("xfoo"), snippetSuffix("($0)"))));
2617 auto Results
= completions(
2620 void f() { xba^ })cpp",
2622 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(AllOf(
2623 named("xbar"), snippetSuffix("()"))));
2626 Opts
.BundleOverloads
= true;
2627 auto Results
= completions(
2630 void xfoo(int x, int y);
2631 void f() { xfo^ })cpp",
2634 Results
.Completions
,
2635 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("($0)"))));
2638 auto Results
= completions(
2640 template <class T, class U>
2641 void xfoo(int a, U b);
2642 void f() { xfo^ })cpp",
2645 Results
.Completions
,
2646 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("<$1>($0)"))));
2649 auto Results
= completions(
2654 using foo_alias = T**;
2657 void f() { foo_^ })cpp",
2660 Results
.Completions
,
2661 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
2662 AllOf(named("foo_alias"), snippetSuffix("<$0>")),
2663 AllOf(named("foo_var"), snippetSuffix("<$0>"))));
2666 auto Results
= completions(
2668 #define FOO(x, y) x##f
2671 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(AllOf(
2672 named("FOO"), snippetSuffix("($0)"))));
2675 Opts
.ArgumentLists
= Config::ArgumentListsPolicy::None
;
2676 auto Results
= completions(
2678 void xfoo(int x, int y);
2679 void f() { xfo^ })cpp",
2681 EXPECT_THAT(Results
.Completions
,
2682 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(""))));
2685 Opts
.ArgumentLists
= Config::ArgumentListsPolicy::OpenDelimiter
;
2686 auto Results
= completions(
2688 void xfoo(int x, int y);
2689 void f() { xfo^ })cpp",
2691 EXPECT_THAT(Results
.Completions
,
2692 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("("))));
2696 TEST(CompletionTest
, SuggestOverrides
) {
2697 constexpr const char *const Text(R
"cpp(
2700 virtual void vfunc(bool param);
2701 virtual void vfunc(bool param, int p);
2702 void func(bool param);
2704 class B : public A {
2705 virtual void ttt(bool param) const;
2706 void vfunc(bool param, int p) override;
2708 class C : public B {
2710 void vfunc(bool param) override;
2714 const auto Results
= completions(Text
);
2716 Results
.Completions
,
2717 AllOf(Contains(AllOf(labeled("void vfunc(bool param, int p) override"),
2718 nameStartsWith("vfunc"))),
2719 Contains(AllOf(labeled("void ttt(bool param) const override"),
2720 nameStartsWith("ttt"))),
2721 Not(Contains(labeled("void vfunc(bool param) override")))));
2724 TEST(CompletionTest
, OverridesNonIdentName
) {
2725 // Check the completions call does not crash.
2728 virtual ~Base() = 0;
2729 virtual operator int() = 0;
2730 virtual Base& operator+(Base&) = 0;
2733 struct Derived : Base {
2739 TEST(CompletionTest
, NoCrashOnMissingNewLineAtEOF
) {
2740 auto FooCpp
= testPath("foo.cpp");
2742 MockCompilationDatabase CDB
;
2744 Annotations
F("#pragma ^ // no new line");
2745 FS
.Files
[FooCpp
] = F
.code().str();
2746 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2747 runAddDocument(Server
, FooCpp
, F
.code());
2748 // Run completion outside the file range.
2749 EXPECT_THAT(cantFail(runCodeComplete(Server
, FooCpp
, F
.point(),
2750 clangd::CodeCompleteOptions()))
2753 EXPECT_THAT(cantFail(runSignatureHelp(Server
, FooCpp
, F
.point(),
2754 MarkupKind::PlainText
))
2759 TEST(GuessCompletionPrefix
, Filters
) {
2760 for (llvm::StringRef Case
: {
2761 "[[scope::]][[ident]]^",
2770 "some text [[scope::more::]][[identif]]^ier",
2771 "some text [[scope::]][[mor]]^e::identifier",
2772 "weird case foo::[[::bar::]][[baz]]^",
2775 Annotations
F(Case
);
2776 auto Offset
= cantFail(positionToOffset(F
.code(), F
.point()));
2777 auto ToStringRef
= [&](Range R
) {
2778 return F
.code().slice(cantFail(positionToOffset(F
.code(), R
.start
)),
2779 cantFail(positionToOffset(F
.code(), R
.end
)));
2781 auto WantQualifier
= ToStringRef(F
.ranges()[0]),
2782 WantName
= ToStringRef(F
.ranges()[1]);
2784 auto Prefix
= guessCompletionPrefix(F
.code(), Offset
);
2785 // Even when components are empty, check their offsets are correct.
2786 EXPECT_EQ(WantQualifier
, Prefix
.Qualifier
) << Case
;
2787 EXPECT_EQ(WantQualifier
.begin(), Prefix
.Qualifier
.begin()) << Case
;
2788 EXPECT_EQ(WantName
, Prefix
.Name
) << Case
;
2789 EXPECT_EQ(WantName
.begin(), Prefix
.Name
.begin()) << Case
;
2793 TEST(CompletionTest
, EnableSpeculativeIndexRequest
) {
2795 MockCompilationDatabase CDB
;
2796 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2798 auto File
= testPath("foo.cpp");
2799 Annotations
Test(R
"cpp(
2800 namespace ns1 { int abc; }
2801 namespace ns2 { int abc; }
2802 void f() { ns1::ab$1^; ns1::ab$2^; }
2803 void f2() { ns2::ab$3^; }
2805 runAddDocument(Server
, File
, Test
.code());
2806 clangd::CodeCompleteOptions Opts
= {};
2808 IndexRequestCollector Requests
;
2809 Opts
.Index
= &Requests
;
2811 auto CompleteAtPoint
= [&](StringRef P
) {
2812 auto CCR
= cantFail(runCodeComplete(Server
, File
, Test
.point(P
), Opts
));
2813 EXPECT_TRUE(CCR
.HasMore
);
2816 CompleteAtPoint("1");
2817 auto Reqs1
= Requests
.consumeRequests(1);
2818 ASSERT_EQ(Reqs1
.size(), 1u);
2819 EXPECT_THAT(Reqs1
[0].Scopes
, UnorderedElementsAre("ns1::"));
2821 CompleteAtPoint("2");
2822 auto Reqs2
= Requests
.consumeRequests(1);
2823 // Speculation succeeded. Used speculative index result.
2824 ASSERT_EQ(Reqs2
.size(), 1u);
2825 EXPECT_EQ(Reqs2
[0], Reqs1
[0]);
2827 CompleteAtPoint("3");
2828 // Speculation failed. Sent speculative index request and the new index
2829 // request after sema.
2830 auto Reqs3
= Requests
.consumeRequests(2);
2831 ASSERT_EQ(Reqs3
.size(), 2u);
2834 TEST(CompletionTest
, InsertTheMostPopularHeader
) {
2835 std::string DeclFile
= URI::create(testPath("foo")).toString();
2836 Symbol Sym
= func("Func");
2837 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2838 Sym
.IncludeHeaders
.emplace_back("\"foo.h\"", 2, Symbol::Include
);
2839 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000, Symbol::Include
);
2841 auto Results
= completions("Fun^", {Sym
}).Completions
;
2842 assert(!Results
.empty());
2843 EXPECT_THAT(Results
[0], AllOf(named("Func"), insertInclude("\"bar.h\"")));
2844 EXPECT_EQ(Results
[0].Includes
.size(), 2u);
2847 TEST(CompletionTest
, InsertIncludeOrImport
) {
2848 std::string DeclFile
= URI::create(testPath("foo")).toString();
2849 Symbol Sym
= func("Func");
2850 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2851 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000,
2852 Symbol::Include
| Symbol::Import
);
2853 CodeCompleteOptions Opts
;
2854 // Should only take effect in import contexts.
2855 Opts
.ImportInsertions
= true;
2856 auto Results
= completions("Fun^", {Sym
}, Opts
).Completions
;
2857 assert(!Results
.empty());
2858 EXPECT_THAT(Results
[0],
2859 AllOf(named("Func"), insertIncludeText("#include \"bar.h\"\n")));
2862 Signals
.InsertionDirective
= Symbol::IncludeDirective::Import
;
2863 Opts
.MainFileSignals
= &Signals
;
2864 Results
= completions("Fun^", {Sym
}, Opts
, "Foo.m").Completions
;
2865 assert(!Results
.empty());
2866 EXPECT_THAT(Results
[0],
2867 AllOf(named("Func"), insertIncludeText("#import \"bar.h\"\n")));
2869 Sym
.IncludeHeaders
[0].SupportedDirectives
= Symbol::Import
;
2870 Results
= completions("Fun^", {Sym
}).Completions
;
2871 assert(!Results
.empty());
2872 EXPECT_THAT(Results
[0], AllOf(named("Func"), Not(insertInclude())));
2875 TEST(CompletionTest
, NoInsertIncludeIfOnePresent
) {
2876 Annotations
Test(R
"cpp(
2880 auto TU
= TestTU::withCode(Test
.code());
2881 TU
.AdditionalFiles
["foo.h"] = "";
2883 std::string DeclFile
= URI::create(testPath("foo")).toString();
2884 Symbol Sym
= func("Func");
2885 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2886 Sym
.IncludeHeaders
.emplace_back("\"foo.h\"", 2, Symbol::Include
);
2887 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000, Symbol::Include
);
2889 EXPECT_THAT(completions(TU
, Test
.point(), {Sym
}).Completions
,
2890 UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""),
2891 Not(insertInclude()))));
2894 TEST(CompletionTest
, MergeMacrosFromIndexAndSema
) {
2896 Sym
.Name
= "Clangd_Macro_Test";
2897 Sym
.ID
= SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test");
2898 Sym
.SymInfo
.Kind
= index::SymbolKind::Macro
;
2899 Sym
.Flags
|= Symbol::IndexedForCodeCompletion
;
2900 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym
})
2902 UnorderedElementsAre(named("Clangd_Macro_Test")));
2905 TEST(CompletionTest
, MacroFromPreamble
) {
2906 Annotations
Test(R
"cpp(#define CLANGD_PREAMBLE_MAIN x
2909 #define CLANGD_MAIN x
2910 void f() { CLANGD_^ }
2912 auto TU
= TestTU::withCode(Test
.code());
2913 TU
.HeaderCode
= "#define CLANGD_PREAMBLE_HEADER x";
2914 auto Results
= completions(TU
, Test
.point(), {func("CLANGD_INDEX")});
2915 // We should get results from the main file, including the preamble section.
2916 // However no results from included files (the index should cover them).
2917 EXPECT_THAT(Results
.Completions
,
2918 UnorderedElementsAre(named("CLANGD_PREAMBLE_MAIN"),
2919 named("CLANGD_MAIN"),
2920 named("CLANGD_INDEX")));
2923 TEST(CompletionTest
, DeprecatedResults
) {
2924 std::string Body
= R
"cpp(
2926 void TestClangc() __attribute__((deprecated("", "")));
2930 completions(Body
+ "int main() { TestClang^ }").Completions
,
2931 UnorderedElementsAre(AllOf(named("TestClangd"), Not(deprecated())),
2932 AllOf(named("TestClangc"), deprecated())));
2935 TEST(SignatureHelpTest
, PartialSpec
) {
2936 const auto Results
= signatures(R
"cpp(
2937 template <typename T> struct Foo {};
2938 template <typename T> struct Foo<T*> { Foo(T); };
2939 Foo<int*> F(^);)cpp");
2940 EXPECT_THAT(Results
.signatures
, Contains(sig("Foo([[T]])")));
2941 EXPECT_EQ(0, Results
.activeParameter
);
2944 TEST(SignatureHelpTest
, InsideArgument
) {
2946 const auto Results
= signatures(R
"cpp(
2948 void foo(int x, int y);
2949 int main() { foo(1+^); }
2951 EXPECT_THAT(Results
.signatures
,
2952 ElementsAre(sig("foo([[int x]]) -> void"),
2953 sig("foo([[int x]], [[int y]]) -> void")));
2954 EXPECT_EQ(0, Results
.activeParameter
);
2957 const auto Results
= signatures(R
"cpp(
2959 void foo(int x, int y);
2960 int main() { foo(1^); }
2962 EXPECT_THAT(Results
.signatures
,
2963 ElementsAre(sig("foo([[int x]]) -> void"),
2964 sig("foo([[int x]], [[int y]]) -> void")));
2965 EXPECT_EQ(0, Results
.activeParameter
);
2968 const auto Results
= signatures(R
"cpp(
2970 void foo(int x, int y);
2971 int main() { foo(1^0); }
2973 EXPECT_THAT(Results
.signatures
,
2974 ElementsAre(sig("foo([[int x]]) -> void"),
2975 sig("foo([[int x]], [[int y]]) -> void")));
2976 EXPECT_EQ(0, Results
.activeParameter
);
2979 const auto Results
= signatures(R
"cpp(
2981 void foo(int x, int y);
2982 int bar(int x, int y);
2983 int main() { bar(foo(2, 3^)); }
2985 EXPECT_THAT(Results
.signatures
,
2986 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
2987 EXPECT_EQ(1, Results
.activeParameter
);
2991 TEST(SignatureHelpTest
, ConstructorInitializeFields
) {
2993 const auto Results
= signatures(R
"cpp(
2994 struct A { A(int); };
3000 EXPECT_THAT(Results
.signatures
,
3001 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
3002 sig("A([[const A &]])")));
3005 const auto Results
= signatures(R
"cpp(
3006 struct A { A(int); };
3012 // FIXME: currently the parser skips over the decl of a_elem as part of the
3013 // (broken) init list, so we don't get signatures for the first member.
3014 EXPECT_THAT(Results
.signatures
, IsEmpty());
3017 const auto Results
= signatures(R
"cpp(
3018 struct A { A(int); };
3025 EXPECT_THAT(Results
.signatures
,
3026 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
3027 sig("A([[const A &]])")));
3030 const auto Results
= signatures(R
"cpp(
3039 B() : c_elem(A(1^)) {}
3043 EXPECT_THAT(Results
.signatures
,
3044 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
3045 sig("A([[const A &]])")));
3049 TEST(SignatureHelpTest
, Variadic
) {
3050 const std::string Header
= R
"cpp(
3051 void fun(int x, ...) {}
3053 const std::string ExpectedSig
= "fun([[int x]], [[...]]) -> void";
3056 const auto Result
= signatures(Header
+ "fun(^);}");
3057 EXPECT_EQ(0, Result
.activeParameter
);
3058 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3061 const auto Result
= signatures(Header
+ "fun(1, ^);}");
3062 EXPECT_EQ(1, Result
.activeParameter
);
3063 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3066 const auto Result
= signatures(Header
+ "fun(1, 2, ^);}");
3067 EXPECT_EQ(1, Result
.activeParameter
);
3068 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3072 TEST(SignatureHelpTest
, VariadicTemplate
) {
3073 const std::string Header
= R
"cpp(
3074 template<typename T, typename ...Args>
3075 void fun(T t, Args ...args) {}
3077 const std::string ExpectedSig
= "fun([[T t]], [[Args args...]]) -> void";
3080 const auto Result
= signatures(Header
+ "fun(^);}");
3081 EXPECT_EQ(0, Result
.activeParameter
);
3082 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3085 const auto Result
= signatures(Header
+ "fun(1, ^);}");
3086 EXPECT_EQ(1, Result
.activeParameter
);
3087 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3090 const auto Result
= signatures(Header
+ "fun(1, 2, ^);}");
3091 EXPECT_EQ(1, Result
.activeParameter
);
3092 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3096 TEST(SignatureHelpTest
, VariadicMethod
) {
3097 const std::string Header
= R
"cpp(
3099 template<typename T, typename ...Args>
3100 void fun(T t, Args ...args) {}
3102 void test() {C c; )cpp";
3103 const std::string ExpectedSig
= "fun([[T t]], [[Args args...]]) -> void";
3106 const auto Result
= signatures(Header
+ "c.fun(^);}");
3107 EXPECT_EQ(0, Result
.activeParameter
);
3108 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3111 const auto Result
= signatures(Header
+ "c.fun(1, ^);}");
3112 EXPECT_EQ(1, Result
.activeParameter
);
3113 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3116 const auto Result
= signatures(Header
+ "c.fun(1, 2, ^);}");
3117 EXPECT_EQ(1, Result
.activeParameter
);
3118 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3122 TEST(SignatureHelpTest
, VariadicType
) {
3123 const std::string Header
= R
"cpp(
3124 void fun(int x, ...) {}
3125 auto get_fun() { return fun; }
3128 const std::string ExpectedSig
= "([[int]], [[...]]) -> void";
3131 const auto Result
= signatures(Header
+ "get_fun()(^);}");
3132 EXPECT_EQ(0, Result
.activeParameter
);
3133 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3136 const auto Result
= signatures(Header
+ "get_fun()(1, ^);}");
3137 EXPECT_EQ(1, Result
.activeParameter
);
3138 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3141 const auto Result
= signatures(Header
+ "get_fun()(1, 2, ^);}");
3142 EXPECT_EQ(1, Result
.activeParameter
);
3143 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3147 TEST(CompletionTest
, IncludedCompletionKinds
) {
3148 Annotations
Test(R
"cpp(#include "^)cpp
");
3149 auto TU = TestTU::withCode(Test.code());
3150 TU.AdditionalFiles["sub
/bar
.h
"] = "";
3151 TU.ExtraArgs.push_back("-I
" + testPath("sub
"));
3153 auto Results = completions(TU, Test.point());
3154 EXPECT_THAT(Results.Completions,
3155 AllOf(has("sub
/", CompletionItemKind::Folder),
3156 has("bar
.h
\"", CompletionItemKind::File)));
3159 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3166 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3167 clangd::CodeCompleteOptions Opts = {};
3168 Opts.AllScopes = true;
3170 auto Results = completions(
3172 void f() { na::Clangd
^ }
3174 {cls("na::ClangdA
"), cls("nx::ClangdX
"), cls("Clangd3
")}, Opts);
3175 EXPECT_THAT(Results.Completions,
3176 UnorderedElementsAre(
3177 AllOf(qualifier(""), scope("na::"), named("ClangdA
"))));
3180 TEST(CompletionTest, AllScopesCompletion) {
3181 clangd::CodeCompleteOptions Opts = {};
3182 Opts.AllScopes = true;
3184 auto Results = completions(
3187 void f() { Clangd
^ }
3190 {cls("nx::Clangd1
"), cls("ny::Clangd2
"), cls("Clangd3
"),
3191 cls("na::nb::Clangd4
"), enmConstant("na::C::Clangd5
")},
3194 Results.Completions,
3195 UnorderedElementsAre(AllOf(qualifier("nx::"), named("Clangd1
"),
3196 kind(CompletionItemKind::Class)),
3197 AllOf(qualifier("ny::"), named("Clangd2
"),
3198 kind(CompletionItemKind::Class)),
3199 AllOf(qualifier(""), scope(""), named("Clangd3
"),
3200 kind(CompletionItemKind::Class)),
3201 AllOf(qualifier("nb::"), named("Clangd4
"),
3202 kind(CompletionItemKind::Class)),
3203 AllOf(qualifier("C::"), named("Clangd5
"),
3204 kind(CompletionItemKind::EnumMember))));
3207 TEST(CompletionTest, NoQualifierIfShadowed) {
3208 clangd::CodeCompleteOptions Opts = {};
3209 Opts.AllScopes = true;
3211 auto Results = completions(R"cpp(
3212 namespace nx
{ class Clangd1
{}; }
3214 void f() { Clangd
^ }
3216 {cls("nx::Clangd1
"), cls("nx::Clangd2
")}, Opts);
3217 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and
3218 // needs no qualifier.
3219 EXPECT_THAT(Results.Completions,
3220 UnorderedElementsAre(AllOf(qualifier(""), named("Clangd1
")),
3221 AllOf(qualifier("nx::"), named("Clangd2
"))));
3224 TEST(CompletionTest, NoCompletionsForNewNames) {
3225 clangd::CodeCompleteOptions Opts;
3226 Opts.AllScopes = true;
3227 auto Results = completions(R"cpp(
3230 {cls("naber
"), cls("nx::naber
")}, Opts);
3231 EXPECT_THAT(Results.Completions, UnorderedElementsAre());
3234 TEST(CompletionTest, Lambda) {
3235 clangd::CodeCompleteOptions Opts = {};
3237 auto Results = completions(R"cpp(
3239 auto Lambda
= [](int a
, const double &b
) {return 1.f
;};
3245 ASSERT_EQ(Results.Completions.size(), 1u);
3246 const auto &A = Results.Completions.front();
3247 EXPECT_EQ(A.Name, "Lambda
");
3248 EXPECT_EQ(A.Signature, "(int a
, const double &b
) const");
3249 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3250 EXPECT_EQ(A.ReturnType, "float");
3251 EXPECT_EQ(A.SnippetSuffix, "($
{1:int a
}, $
{2:const double &b
})");
3254 TEST(CompletionTest, StructuredBinding) {
3255 clangd::CodeCompleteOptions Opts = {};
3257 auto Results = completions(R"cpp(
3259 using Float
= float;
3264 const auto &[xxx
, yyy
] = S
{};
3270 ASSERT_EQ(Results.Completions.size(), 1u);
3271 const auto &A = Results.Completions.front();
3272 EXPECT_EQ(A.Name, "yyy
");
3273 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3274 EXPECT_EQ(A.ReturnType, "const Float
");
3277 TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3278 auto Results = completions(R"objc(
3280 @
property(nonatomic
, setter
=setXToIgnoreComplete
:) int value
;
3282 Foo
*foo
= [Foo
new]; int y
= [foo v
^]
3284 /*IndexSymbols=*/{},
3285 /*Opts=*/{}, "Foo
.m
");
3287 auto C = Results.Completions;
3288 EXPECT_THAT(C, ElementsAre(named("value
")));
3289 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3290 EXPECT_THAT(C, ElementsAre(returnType("int")));
3291 EXPECT_THAT(C, ElementsAre(signature("")));
3292 EXPECT_THAT(C, ElementsAre(snippetSuffix("")));
3295 TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3296 auto Results = completions(R"objc(
3298 - (int)valueForCharacter
:(char)c
;
3300 Foo
*foo
= [Foo
new]; int y
= [foo v
^]
3302 /*IndexSymbols=*/{},
3303 /*Opts=*/{}, "Foo
.m
");
3305 auto C = Results.Completions;
3306 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3307 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3308 EXPECT_THAT(C, ElementsAre(returnType("int")));
3309 EXPECT_THAT(C, ElementsAre(signature("(char)")));
3310 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(char)}")));
3313 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3314 auto Results = completions(R"objc(
3316 + (id
)fooWithValue
:(int)value fooey
:(unsigned int)fooey
;
3320 /*IndexSymbols=*/{},
3321 /*Opts=*/{}, "Foo
.m
");
3323 auto C = Results.Completions;
3324 EXPECT_THAT(C, ElementsAre(named("fooWithValue
:")));
3325 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3326 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3327 EXPECT_THAT(C, ElementsAre(signature("(int) fooey
:(unsigned int)")));
3329 C, ElementsAre(snippetSuffix("$
{1:(int)} fooey
:$
{2:(unsigned int)}")));
3332 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3333 auto Results = completions(R"objc(
3335 + (id
)fooWithValue
:(int)value fooey
:(unsigned int)fooey
;
3337 id val
= [Foo fooWithValue
:10 f
^]
3339 /*IndexSymbols=*/{},
3340 /*Opts=*/{}, "Foo
.m
");
3342 auto C = Results.Completions;
3343 EXPECT_THAT(C, ElementsAre(named("fooey
:")));
3344 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3345 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3346 EXPECT_THAT(C, ElementsAre(signature("(unsigned int)")));
3347 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(unsigned int)}")));
3350 TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3351 auto Results = completions(R"objc(
3353 + (id
)player
:(id
)player willRun
:(id
)run
;
3357 /*IndexSymbols=*/{},
3358 /*Opts=*/{}, "Foo
.m
");
3360 auto C = Results.Completions;
3361 EXPECT_THAT(C, ElementsAre(named("player
:")));
3362 EXPECT_THAT(C, ElementsAre(filterText("player
:willRun
:")));
3363 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3364 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3365 EXPECT_THAT(C, ElementsAre(signature("(id
) willRun
:(id
)")));
3366 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(id
)} willRun
:$
{2:(id
)}")));
3369 TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3370 auto Results = completions(R"objc(
3378 /*IndexSymbols=*/{},
3379 /*Opts=*/{}, "Foo
.m
");
3381 auto C = Results.Completions;
3382 EXPECT_THAT(C, ElementsAre(named("foo
")));
3383 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3384 EXPECT_THAT(C, ElementsAre(qualifier("- (void)")));
3387 TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3388 auto Results = completions(R"objc(
3390 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3396 /*IndexSymbols=*/{},
3397 /*Opts=*/{}, "Foo
.m
");
3399 auto C = Results.Completions;
3400 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3401 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3402 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3403 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument
:(id
)object
")));
3406 TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3407 auto Results = completions(R"objc(
3409 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3415 /*IndexSymbols=*/{},
3416 /*Opts=*/{}, "Foo
.m
");
3418 auto C = Results.Completions;
3419 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3420 EXPECT_THAT(C, ElementsAre(filterText("valueForCharacter
:secondArgument
:")));
3421 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3422 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3423 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument
:(id
)object
")));
3426 TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3427 auto Results = completions(R"objc(
3429 - (int)valueForCharacter
:(char)c
;
3435 /*IndexSymbols=*/{},
3436 /*Opts=*/{}, "Foo
.m
");
3438 auto C = Results.Completions;
3439 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3440 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3441 EXPECT_THAT(C, ElementsAre(signature("(char)c
")));
3444 TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3445 auto Results = completions(R"objc(
3447 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3450 - (int)valueForCharacter
:(char)c second
^
3453 /*IndexSymbols=*/{},
3454 /*Opts=*/{}, "Foo
.m
");
3456 auto C = Results.Completions;
3457 EXPECT_THAT(C, ElementsAre(named("secondArgument
:")));
3458 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3459 EXPECT_THAT(C, ElementsAre(signature("(id
)object
")));
3462 TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3463 Symbol FoodClass = objcClass("FoodClass
");
3464 Symbol SymFood = objcProtocol("Food
");
3465 Symbol SymFooey = objcProtocol("Fooey
");
3466 auto Results = completions("id
<Foo
^>", {SymFood, FoodClass, SymFooey},
3467 /*Opts=*/{}, "Foo
.m
");
3469 // Should only give protocols for ObjC protocol completions.
3470 EXPECT_THAT(Results.Completions,
3471 UnorderedElementsAre(
3472 AllOf(named("Food
"), kind(CompletionItemKind::Interface)),
3473 AllOf(named("Fooey
"), kind(CompletionItemKind::Interface))));
3475 Results = completions("Fo
^", {SymFood, FoodClass, SymFooey},
3476 /*Opts=*/{}, "Foo
.m
");
3477 // Shouldn't give protocols for non protocol completions.
3479 Results.Completions,
3480 ElementsAre(AllOf(named("FoodClass
"), kind(CompletionItemKind::Class))));
3483 TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3485 MockCompilationDatabase CDB;
3486 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
3488 auto File = testPath("Foo
.m
");
3489 Annotations Test(R"cpp(
3495 runAddDocument(Server, File, Test.code());
3496 clangd::CodeCompleteOptions Opts = {};
3498 Symbol FoodClass = objcClass("FoodClass
");
3499 IndexRequestCollector Requests({FoodClass});
3500 Opts.Index = &Requests;
3502 auto CompleteAtPoint = [&](StringRef P) {
3503 return cantFail(runCodeComplete(Server, File, Test.point(P), Opts))
3507 auto C = CompleteAtPoint("1");
3508 auto Reqs1 = Requests.consumeRequests(1);
3509 ASSERT_EQ(Reqs1.size(), 1u);
3510 EXPECT_THAT(C, ElementsAre(AllOf(named("Food
"),
3511 kind(CompletionItemKind::Interface))));
3513 C = CompleteAtPoint("2");
3514 auto Reqs2 = Requests.consumeRequests(1);
3515 // Speculation succeeded. Used speculative index result, but filtering now to
3516 // now include FoodClass.
3517 ASSERT_EQ(Reqs2.size(), 1u);
3518 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3519 EXPECT_THAT(C, ElementsAre(AllOf(named("FoodClass
"),
3520 kind(CompletionItemKind::Class))));
3523 TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3524 Symbol FoodCategory = objcCategory("FoodClass
", "Extension
");
3525 auto Results = completions(R"objc(
3532 /*Opts=*/{}, "Foo
.m
");
3533 EXPECT_THAT(Results.Completions, IsEmpty());
3536 TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3537 Symbol FoodClass = objcClass("FoodClass
");
3538 FoodClass.IncludeHeaders.emplace_back("\"Foo
.h
\"", 2, Symbol::Import);
3539 Symbol SymFood = objcProtocol("Food
");
3540 auto Results = completions("@
class Foo
^", {SymFood, FoodClass},
3541 /*Opts=*/{}, "Foo
.m
");
3543 // Should only give class names without any include insertion.
3544 EXPECT_THAT(Results.Completions,
3545 UnorderedElementsAre(AllOf(named("FoodClass
"),
3546 kind(CompletionItemKind::Class),
3547 Not(insertInclude()))));
3550 TEST(CompletionTest, CursorInSnippets) {
3551 clangd::CodeCompleteOptions Options;
3552 Options.EnableSnippets = true;
3553 auto Results = completions(
3555 void while_foo(int a
, int b
);
3559 /*IndexSymbols=*/{}, Options);
3561 // Last placeholder in code patterns should be $0 to put the cursor there.
3562 EXPECT_THAT(Results.Completions,
3563 Contains(AllOf(named("while"),
3564 snippetSuffix(" ($
{1:condition
}) {\n$
0\n}"))));
3565 // However, snippets for functions must *not* end with $0.
3566 EXPECT_THAT(Results.Completions,
3567 Contains(AllOf(named("while_foo
"),
3568 snippetSuffix("($
{1:int a
}, $
{2:int b
})"))));
3570 Results = completions(R"cpp(
3572 Base(int a
, int b
) {}
3575 struct Derived
: Base
{
3579 /*IndexSymbols=*/{}, Options);
3580 // Constructors from base classes are a kind of pattern that shouldn't end
3582 EXPECT_THAT(Results.Completions,
3583 Contains(AllOf(named("Base
"),
3584 snippetSuffix("($
{1:int a
}, $
{2:int b
})"))));
3587 TEST(CompletionTest, WorksWithNullType) {
3588 auto R = completions(R"cpp(
3590 for (auto [loopVar
] : y
) { // y has to be unresolved.
3595 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar
")));
3598 TEST(CompletionTest, UsingDecl) {
3599 const char *Header(R"cpp(
3604 const char *Source(R"cpp(
3608 auto Index = TestTU::withHeaderCode(Header).index();
3609 clangd::CodeCompleteOptions Opts;
3610 Opts.Index = Index.get();
3611 Opts.AllScopes = true;
3612 auto R = completions(Source, {}, Opts);
3613 EXPECT_THAT(R.Completions,
3614 ElementsAre(AllOf(scope("std::"), named("foo
"),
3615 kind(CompletionItemKind::Reference))));
3618 TEST(CompletionTest, Enums) {
3619 const char *Header(R"cpp(
3621 enum Unscoped
{ Clangd1
};
3623 enum Unscoped
{ Clangd2
};
3625 enum class Scoped
{ Clangd3
};
3627 const char *Source(R"cpp(
3631 auto Index = TestTU::withHeaderCode(Header).index();
3632 clangd::CodeCompleteOptions Opts;
3633 Opts.Index = Index.get();
3634 Opts.AllScopes = true;
3635 auto R = completions(Source, {}, Opts);
3636 EXPECT_THAT(R.Completions, UnorderedElementsAre(
3637 AllOf(scope("ns::"), named("Clangd1
"),
3638 kind(CompletionItemKind::EnumMember)),
3639 AllOf(scope("ns::C::"), named("Clangd2
"),
3640 kind(CompletionItemKind::EnumMember)),
3641 AllOf(scope("ns::Scoped::"), named("Clangd3
"),
3642 kind(CompletionItemKind::EnumMember))));
3645 TEST(CompletionTest, ScopeIsUnresolved) {
3646 clangd::CodeCompleteOptions Opts = {};
3647 Opts.AllScopes = true;
3649 auto Results = completions(R"cpp(
3654 {cls("a::b::XYZ
")}, Opts);
3655 EXPECT_THAT(Results.Completions,
3656 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ
"))));
3659 TEST(CompletionTest, NestedScopeIsUnresolved) {
3660 clangd::CodeCompleteOptions Opts = {};
3661 Opts.AllScopes = true;
3663 auto Results = completions(R"cpp(
3666 void f() { b::c::X
^ }
3669 {cls("a::b::c::XYZ
")}, Opts);
3670 EXPECT_THAT(Results.Completions,
3671 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ
"))));
3674 // Clang parser gets confused here and doesn't report the ns:: prefix.
3675 // Naive behavior is to insert it again. We examine the source and recover.
3676 TEST(CompletionTest, NamespaceDoubleInsertion) {
3677 clangd::CodeCompleteOptions Opts = {};
3679 auto Results = completions(R"cpp(
3686 {cls("foo::ns::ABCDE
")}, Opts);
3687 EXPECT_THAT(Results.Completions,
3688 UnorderedElementsAre(AllOf(qualifier(""), named("ABCDE
"))));
3691 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
3692 // Despite the fact that base method matches the ref-qualifier better,
3693 // completion results should only include the derived method.
3694 auto Completions = completions(R"cpp(
3697 double size() const;
3699 struct deque
: deque_base
{
3706 EXPECT_THAT(Completions,
3707 ElementsAre(AllOf(returnType("int"), named("size
"))));
3710 TEST(CompletionTest, NoCrashWithIncompleteLambda) {
3711 auto Completions = completions("auto&& x
= []{^").Completions;
3712 // The completion of x itself can cause a problem: in the code completion
3713 // callback, its type is not known, which affects the linkage calculation.
3714 // A bad linkage value gets cached, and subsequently updated.
3715 EXPECT_THAT(Completions, Contains(named("x
")));
3717 auto Signatures = signatures("auto x() { x(^").signatures;
3718 EXPECT_THAT(Signatures, Contains(sig("x() -> auto")));
3721 TEST(CompletionTest, DelayedTemplateParsing) {
3722 Annotations Test(R"cpp(
3724 template <typename T
> int foo() { return xx
^; }
3726 auto TU = TestTU::withCode(Test.code());
3727 // Even though delayed-template-parsing is on, we will disable it to provide
3728 // completion in templates.
3729 TU.ExtraArgs.push_back("-fdelayed
-template-parsing
");
3731 EXPECT_THAT(completions(TU, Test.point()).Completions,
3732 Contains(named("xxx
")));
3735 TEST(CompletionTest, CompletionRange) {
3736 const char *WithRange = "auto x
= [[abc
]]^";
3737 auto Completions = completions(WithRange);
3738 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3739 Completions = completionsNoCompile(WithRange);
3740 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3742 const char *EmptyRange = "auto x
= [[]]^";
3743 Completions = completions(EmptyRange);
3744 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3745 Completions = completionsNoCompile(EmptyRange);
3746 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3748 // Sema doesn't trigger at all here, while the no-sema completion runs
3749 // heuristics as normal and reports a range. It'd be nice to be consistent.
3750 const char *NoCompletion = "/* foo [[]]^ */";
3751 Completions = completions(NoCompletion);
3752 EXPECT_EQ(Completions.CompletionRange, std::nullopt);
3753 Completions = completionsNoCompile(NoCompletion);
3754 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
3757 TEST(NoCompileCompletionTest, Basic) {
3758 auto Results = completionsNoCompile(R"cpp(
3765 EXPECT_FALSE(Results.RanParser);
3766 EXPECT_THAT(Results.Completions,
3767 UnorderedElementsAre(named("void"), named("func
"), named("int"),
3768 named("xyz
"), named("abc
")));
3771 TEST(NoCompileCompletionTest, WithFilter) {
3772 auto Results = completionsNoCompile(R"cpp(
3781 EXPECT_THAT(Results.Completions,
3782 UnorderedElementsAre(named("sym1
"), named("sym2
")));
3785 TEST(NoCompileCompletionTest, WithIndex) {
3786 std::vector<Symbol> Syms = {func("xxx
"), func("a::xxx
"), func("ns::b::xxx
"),
3787 func("c::xxx
"), func("ns::d::xxx
")};
3788 auto Results = completionsNoCompile(
3790 // Current-scopes, unqualified completion.
3800 EXPECT_THAT(Results.Completions,
3801 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3802 AllOf(qualifier(""), scope("a::")),
3803 AllOf(qualifier(""), scope("ns::b::"))));
3804 CodeCompleteOptions Opts;
3805 Opts.AllScopes = true;
3806 Results = completionsNoCompile(
3808 // All-scopes unqualified completion.
3818 EXPECT_THAT(Results.Completions,
3819 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3820 AllOf(qualifier(""), scope("a::")),
3821 AllOf(qualifier(""), scope("ns::b::")),
3822 AllOf(qualifier("c::"), scope("c::")),
3823 AllOf(qualifier("d::"), scope("ns::d::"))));
3824 Results = completionsNoCompile(
3826 // Qualified completion.
3836 EXPECT_THAT(Results.Completions,
3837 ElementsAre(AllOf(qualifier(""), scope("ns::b::"))));
3838 Results = completionsNoCompile(
3840 // Absolutely qualified completion.
3850 EXPECT_THAT(Results.Completions,
3851 ElementsAre(AllOf(qualifier(""), scope("a::"))));
3854 TEST(AllowImplicitCompletion, All) {
3855 const char *Yes[] = {
3859 " # include <^foo.h>",
3860 "#import <foo/^bar.h>",
3861 "#include_next \"^",
3863 const char *No[] = {
3867 "#include <foo.h> //^",
3868 "#include \"foo.h\"^",
3872 for (const char *Test
: Yes
) {
3873 llvm::Annotations
A(Test
);
3874 EXPECT_TRUE(allowImplicitCompletion(A
.code(), A
.point())) << Test
;
3876 for (const char *Test
: No
) {
3877 llvm::Annotations
A(Test
);
3878 EXPECT_FALSE(allowImplicitCompletion(A
.code(), A
.point())) << Test
;
3882 TEST(CompletionTest
, FunctionArgsExist
) {
3883 clangd::CodeCompleteOptions Opts
;
3884 Opts
.EnableSnippets
= true;
3885 std::string Context
= R
"cpp(
3892 template <typename T>
3894 Container(int Size) {}
3897 EXPECT_THAT(completions(Context
+ "int y = fo^", {}, Opts
).Completions
,
3898 UnorderedElementsAre(
3899 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3901 completions(Context
+ "int y = fo^(42)", {}, Opts
).Completions
,
3902 UnorderedElementsAre(AllOf(labeled("foo(int A)"), snippetSuffix(""))));
3903 // FIXME(kirillbobyrev): No snippet should be produced here.
3904 EXPECT_THAT(completions(Context
+ "int y = fo^o(42)", {}, Opts
).Completions
,
3905 UnorderedElementsAre(
3906 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3908 completions(Context
+ "int y = ba^", {}, Opts
).Completions
,
3909 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("()"))));
3910 EXPECT_THAT(completions(Context
+ "int y = ba^()", {}, Opts
).Completions
,
3911 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix(""))));
3913 completions(Context
+ "Object o = Obj^", {}, Opts
).Completions
,
3914 Contains(AllOf(labeled("Object(int B)"), snippetSuffix("(${1:int B})"),
3915 kind(CompletionItemKind::Constructor
))));
3916 EXPECT_THAT(completions(Context
+ "Object o = Obj^()", {}, Opts
).Completions
,
3917 Contains(AllOf(labeled("Object(int B)"), snippetSuffix(""),
3918 kind(CompletionItemKind::Constructor
))));
3920 completions(Context
+ "Container c = Cont^", {}, Opts
).Completions
,
3921 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3922 snippetSuffix("<${1:typename T}>(${2:int Size})"),
3923 kind(CompletionItemKind::Constructor
))));
3925 completions(Context
+ "Container c = Cont^()", {}, Opts
).Completions
,
3926 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3927 snippetSuffix("<${1:typename T}>"),
3928 kind(CompletionItemKind::Constructor
))));
3930 completions(Context
+ "Container c = Cont^<int>()", {}, Opts
).Completions
,
3931 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3933 kind(CompletionItemKind::Constructor
))));
3934 EXPECT_THAT(completions(Context
+ "MAC^(2)", {}, Opts
).Completions
,
3935 Contains(AllOf(labeled("MACRO(x)"), snippetSuffix(""),
3936 kind(CompletionItemKind::Function
))));
3939 TEST(CompletionTest
, FunctionArgsExist_Issue1785
) {
3940 // This is a scenario where the implementation of our check for
3941 // "is there a function argument list right after the cursor"
3942 // gave a bogus result.
3943 clangd::CodeCompleteOptions Opts
;
3944 Opts
.EnableSnippets
= true;
3945 // The whitespace in this testcase is important!
3946 std::string Code
= R
"cpp(
3958 completions(Code
, {}, Opts
).Completions
,
3959 Contains(AllOf(labeled("waldo(int)"), snippetSuffix("(${1:int})"))));
3962 TEST(CompletionTest
, NoCrashDueToMacroOrdering
) {
3963 EXPECT_THAT(completions(R
"cpp(
3965 #define ECHO2(X) ECHO(X)
3966 int finish_preamble = EC^HO(2);)cpp")
3968 UnorderedElementsAre(labeled("ECHO(X)"), labeled("ECHO2(X)")));
3971 TEST(CompletionTest
, ObjCCategoryDecls
) {
3973 TU
.ExtraArgs
.push_back("-xobjective-c");
3974 TU
.HeaderCode
= R
"objc(
3978 @interface Foo (FooExt1)
3981 @interface Foo (FooExt2)
3987 @interface Bar (BarExt)
3991 Annotations
Test(R
"objc(
3992 @implementation Foo (^)
3995 TU
.Code
= Test
.code().str();
3996 auto Results
= completions(TU
, Test
.point());
3997 EXPECT_THAT(Results
.Completions
,
3998 UnorderedElementsAre(labeled("FooExt1"), labeled("FooExt2")));
4001 Annotations
Test(R
"objc(
4005 TU
.Code
= Test
.code().str();
4006 auto Results
= completions(TU
, Test
.point());
4007 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(labeled("BarExt")));
4011 TEST(CompletionTest
, PreambleCodeComplete
) {
4012 llvm::StringLiteral Baseline
= "\n#define MACRO 12\nint num = MACRO;";
4013 llvm::StringLiteral ModifiedCC
=
4014 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
4016 Annotations
Test(ModifiedCC
);
4017 auto BaselineTU
= TestTU::withCode(Baseline
);
4018 auto ModifiedTU
= TestTU::withCode(Test
.code());
4021 auto Inputs
= ModifiedTU
.inputs(FS
);
4022 auto Result
= codeComplete(testPath(ModifiedTU
.Filename
), Test
.point(),
4023 BaselineTU
.preamble().get(), Inputs
, {});
4024 EXPECT_THAT(Result
.Completions
, Not(testing::IsEmpty()));
4027 TEST(CompletionTest
, CommentParamName
) {
4028 const std::string Code
= R
"cpp(
4029 void fun(int foo, int bar);
4030 void overloaded(int param_int);
4031 void overloaded(int param_int, int param_other);
4032 void overloaded(char param_char);
4036 EXPECT_THAT(completions(Code
+ "fun(/*^").Completions
,
4037 UnorderedElementsAre(labeled("foo=*/")));
4038 EXPECT_THAT(completions(Code
+ "fun(1, /*^").Completions
,
4039 UnorderedElementsAre(labeled("bar=*/")));
4040 EXPECT_THAT(completions(Code
+ "/*^").Completions
, IsEmpty());
4041 // Test de-duplication.
4043 completions(Code
+ "overloaded(/*^").Completions
,
4044 UnorderedElementsAre(labeled("param_int=*/"), labeled("param_char=*/")));
4045 // Comment already has some text in it.
4046 EXPECT_THAT(completions(Code
+ "fun(/* ^").Completions
,
4047 UnorderedElementsAre(labeled("foo=*/")));
4048 EXPECT_THAT(completions(Code
+ "fun(/* f^").Completions
,
4049 UnorderedElementsAre(labeled("foo=*/")));
4050 EXPECT_THAT(completions(Code
+ "fun(/* x^").Completions
, IsEmpty());
4051 EXPECT_THAT(completions(Code
+ "fun(/* f ^").Completions
, IsEmpty());
4055 std::string
CompletionRangeTest(Code
+ "fun(/*[[^]]");
4056 auto Results
= completions(CompletionRangeTest
);
4057 EXPECT_THAT(Results
.CompletionRange
,
4058 llvm::ValueIs(Annotations(CompletionRangeTest
).range()));
4060 Results
.Completions
,
4062 AllOf(replacesRange(Annotations(CompletionRangeTest
).range()),
4063 origin(SymbolOrigin::AST
), kind(CompletionItemKind::Text
))));
4066 std::string
CompletionRangeTest(Code
+ "fun(/*[[fo^]]");
4067 auto Results
= completions(CompletionRangeTest
);
4068 EXPECT_THAT(Results
.CompletionRange
,
4069 llvm::ValueIs(Annotations(CompletionRangeTest
).range()));
4071 Results
.Completions
,
4073 AllOf(replacesRange(Annotations(CompletionRangeTest
).range()),
4074 origin(SymbolOrigin::AST
), kind(CompletionItemKind::Text
))));
4078 TEST(CompletionTest
, Concepts
) {
4079 Annotations
Code(R
"cpp(
4081 concept A = sizeof(T) <= 8;
4083 template<$tparam^A U>
4086 template<typename T>
4087 int bar(T t) requires $expr^A<int>;
4090 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
4092 $toplevel^A auto i = 19;
4094 template<$toplevel^A auto i> void constrainedNTTP();
4096 // FIXME: The first parameter should be dropped in this case.
4097 void abbreviated($expr^A auto x) {}
4100 TU
.Code
= Code
.code().str();
4101 TU
.ExtraArgs
= {"-std=c++20"};
4103 auto Sym
= conceptSym("same_as");
4104 Sym
.Signature
= "<typename Tp, typename Up>";
4105 Sym
.CompletionSnippetSuffix
= "<${1:typename Tp}, ${2:typename Up}>";
4106 std::vector
<Symbol
> Syms
= {Sym
};
4107 for (auto P
: Code
.points("tparam")) {
4109 completions(TU
, P
, Syms
).Completions
,
4110 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4111 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4112 snippetSuffix("<${2:typename Up}>"))),
4113 Contains(named("class")), Contains(named("typename"))))
4114 << "Completing template parameter at position " << P
;
4117 for (auto P
: Code
.points("toplevel")) {
4119 completions(TU
, P
, Syms
).Completions
,
4120 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4121 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4122 snippetSuffix("<${2:typename Up}>")))))
4123 << "Completing 'requires' expression at position " << P
;
4126 for (auto P
: Code
.points("expr")) {
4128 completions(TU
, P
, Syms
).Completions
,
4129 AllOf(Contains(AllOf(named("A"), signature("<class T>"),
4130 snippetSuffix("<${1:class T}>"))),
4132 named("same_as"), signature("<typename Tp, typename Up>"),
4133 snippetSuffix("<${1:typename Tp}, ${2:typename Up}>")))))
4134 << "Completing 'requires' expression at position " << P
;
4138 TEST(SignatureHelp
, DocFormat
) {
4139 Annotations
Code(R
"cpp(
4140 // Comment `with` markup.
4142 void bar() { foo(^); }
4144 for (auto DocumentationFormat
:
4145 {MarkupKind::PlainText
, MarkupKind::Markdown
}) {
4146 auto Sigs
= signatures(Code
.code(), Code
.point(), /*IndexSymbols=*/{},
4147 DocumentationFormat
);
4148 ASSERT_EQ(Sigs
.signatures
.size(), 1U);
4149 EXPECT_EQ(Sigs
.signatures
[0].documentation
.kind
, DocumentationFormat
);
4153 TEST(SignatureHelp
, TemplateArguments
) {
4154 std::string Top
= R
"cpp(
4155 template <typename T, int> bool foo(char);
4156 template <int I, int> bool foo(float);
4159 auto First
= signatures(Top
+ "bool x = foo<^");
4162 UnorderedElementsAre(sig("foo<[[typename T]], [[int]]>() -> bool"),
4163 sig("foo<[[int I]], [[int]]>() -> bool")));
4164 EXPECT_EQ(First
.activeParameter
, 0);
4166 auto Second
= signatures(Top
+ "bool x = foo<1, ^");
4167 EXPECT_THAT(Second
.signatures
,
4168 ElementsAre(sig("foo<[[int I]], [[int]]>() -> bool")));
4169 EXPECT_EQ(Second
.activeParameter
, 1);
4172 TEST(CompletionTest
, DoNotCrash
) {
4173 llvm::StringLiteral Cases
[] = {
4175 template <typename = int> struct Foo {};
4176 auto a = [x(3)](Foo<^>){};
4179 for (auto Case
: Cases
) {
4181 auto Completions
= completions(Case
);
4184 TEST(CompletionTest
, PreambleFromDifferentTarget
) {
4185 constexpr std::string_view PreambleTarget
= "x86_64";
4186 constexpr std::string_view Contents
=
4187 "int foo(int); int num; int num2 = foo(n^";
4189 Annotations
Test(Contents
);
4190 auto TU
= TestTU::withCode(Test
.code());
4191 TU
.ExtraArgs
.emplace_back("-target");
4192 TU
.ExtraArgs
.emplace_back(PreambleTarget
);
4193 auto Preamble
= TU
.preamble();
4194 ASSERT_TRUE(Preamble
);
4195 // Switch target to wasm.
4196 TU
.ExtraArgs
.pop_back();
4197 TU
.ExtraArgs
.emplace_back("wasm32");
4200 auto Inputs
= TU
.inputs(FS
);
4201 auto Result
= codeComplete(testPath(TU
.Filename
), Test
.point(),
4202 Preamble
.get(), Inputs
, {});
4204 signatureHelp(testPath(TU
.Filename
), Test
.point(), *Preamble
, Inputs
, {});
4206 // Make sure we don't crash.
4207 EXPECT_THAT(Result
.Completions
, Not(testing::IsEmpty()));
4208 EXPECT_THAT(Signatures
.signatures
, Not(testing::IsEmpty()));
4211 } // namespace clangd
4212 } // namespace clang