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"
18 #include "SourceCode.h"
21 #include "TestIndex.h"
23 #include "index/Index.h"
24 #include "index/MemIndex.h"
25 #include "index/SymbolOrigin.h"
26 #include "support/Threading.h"
27 #include "clang/Sema/CodeCompleteConsumer.h"
28 #include "clang/Tooling/CompilationDatabase.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/Path.h"
32 #include "llvm/Testing/Annotations/Annotations.h"
33 #include "llvm/Testing/Support/Error.h"
34 #include "llvm/Testing/Support/SupportHelpers.h"
35 #include "gmock/gmock.h"
36 #include "gtest/gtest.h"
37 #include <condition_variable>
47 using ::testing::AllOf
;
48 using ::testing::Contains
;
49 using ::testing::ElementsAre
;
50 using ::testing::Field
;
51 using ::testing::HasSubstr
;
52 using ::testing::IsEmpty
;
54 using ::testing::UnorderedElementsAre
;
55 using ContextKind
= CodeCompletionContext::Kind
;
57 // GMock helpers for matching completion items.
58 MATCHER_P(named
, Name
, "") { return arg
.Name
== Name
; }
59 MATCHER_P(mainFileRefs
, Refs
, "") { return arg
.MainFileRefs
== Refs
; }
60 MATCHER_P(scopeRefs
, Refs
, "") { return arg
.ScopeRefsInFile
== Refs
; }
61 MATCHER_P(nameStartsWith
, Prefix
, "") {
62 return llvm::StringRef(arg
.Name
).startswith(Prefix
);
64 MATCHER_P(filterText
, F
, "") { return arg
.FilterText
== F
; }
65 MATCHER_P(scope
, S
, "") { return arg
.Scope
== S
; }
66 MATCHER_P(qualifier
, Q
, "") { return arg
.RequiredQualifier
== Q
; }
67 MATCHER_P(labeled
, Label
, "") {
68 return arg
.RequiredQualifier
+ arg
.Name
+ arg
.Signature
== Label
;
70 MATCHER_P(sigHelpLabeled
, Label
, "") { return arg
.label
== Label
; }
71 MATCHER_P(kind
, K
, "") { return arg
.Kind
== K
; }
72 MATCHER_P(doc
, D
, "") {
73 return arg
.Documentation
&& arg
.Documentation
->asPlainText() == D
;
75 MATCHER_P(returnType
, D
, "") { return arg
.ReturnType
== D
; }
76 MATCHER_P(hasInclude
, IncludeHeader
, "") {
77 return !arg
.Includes
.empty() && arg
.Includes
[0].Header
== IncludeHeader
;
79 MATCHER_P(insertInclude
, IncludeHeader
, "") {
80 return !arg
.Includes
.empty() && arg
.Includes
[0].Header
== IncludeHeader
&&
81 bool(arg
.Includes
[0].Insertion
);
83 MATCHER_P(insertIncludeText
, InsertedText
, "") {
84 return !arg
.Includes
.empty() && arg
.Includes
[0].Insertion
&&
85 arg
.Includes
[0].Insertion
->newText
== InsertedText
;
87 MATCHER(insertInclude
, "") {
88 return !arg
.Includes
.empty() && bool(arg
.Includes
[0].Insertion
);
90 MATCHER_P(snippetSuffix
, Text
, "") { return arg
.SnippetSuffix
== Text
; }
91 MATCHER_P(origin
, OriginSet
, "") { return arg
.Origin
== OriginSet
; }
92 MATCHER_P(signature
, S
, "") { return arg
.Signature
== S
; }
93 MATCHER_P(replacesRange
, Range
, "") {
94 return arg
.CompletionTokenRange
== Range
;
97 // Shorthand for Contains(named(Name)).
98 Matcher
<const std::vector
<CodeCompletion
> &> has(std::string Name
) {
99 return Contains(named(std::move(Name
)));
101 Matcher
<const std::vector
<CodeCompletion
> &> has(std::string Name
,
102 CompletionItemKind K
) {
103 return Contains(AllOf(named(std::move(Name
)), kind(K
)));
105 MATCHER(isDocumented
, "") { return arg
.Documentation
.has_value(); }
106 MATCHER(deprecated
, "") { return arg
.Deprecated
; }
108 std::unique_ptr
<SymbolIndex
> memIndex(std::vector
<Symbol
> Symbols
) {
109 SymbolSlab::Builder Slab
;
110 for (const auto &Sym
: Symbols
)
112 return MemIndex::build(std::move(Slab
).build(), RefSlab(), RelationSlab());
115 // Runs code completion.
116 // If IndexSymbols is non-empty, an index will be built and passed to opts.
117 CodeCompleteResult
completions(const TestTU
&TU
, Position Point
,
118 std::vector
<Symbol
> IndexSymbols
= {},
119 clangd::CodeCompleteOptions Opts
= {}) {
120 std::unique_ptr
<SymbolIndex
> OverrideIndex
;
121 if (!IndexSymbols
.empty()) {
122 assert(!Opts
.Index
&& "both Index and IndexSymbols given!");
123 OverrideIndex
= memIndex(std::move(IndexSymbols
));
124 Opts
.Index
= OverrideIndex
.get();
128 auto Inputs
= TU
.inputs(FS
);
129 IgnoreDiagnostics Diags
;
130 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
132 ADD_FAILURE() << "Couldn't build CompilerInvocation";
135 auto Preamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
136 /*InMemory=*/true, /*Callback=*/nullptr);
137 return codeComplete(testPath(TU
.Filename
), Point
, Preamble
.get(), Inputs
,
141 // Runs code completion.
142 CodeCompleteResult
completions(llvm::StringRef Text
,
143 std::vector
<Symbol
> IndexSymbols
= {},
144 clangd::CodeCompleteOptions Opts
= {},
145 PathRef FilePath
= "foo.cpp") {
146 Annotations
Test(Text
);
147 auto TU
= TestTU::withCode(Test
.code());
148 // To make sure our tests for completiopns inside templates work on Windows.
149 TU
.Filename
= FilePath
.str();
150 return completions(TU
, Test
.point(), std::move(IndexSymbols
),
154 // Runs code completion without the clang parser.
155 CodeCompleteResult
completionsNoCompile(llvm::StringRef Text
,
156 std::vector
<Symbol
> IndexSymbols
= {},
157 clangd::CodeCompleteOptions Opts
= {},
158 PathRef FilePath
= "foo.cpp") {
159 std::unique_ptr
<SymbolIndex
> OverrideIndex
;
160 if (!IndexSymbols
.empty()) {
161 assert(!Opts
.Index
&& "both Index and IndexSymbols given!");
162 OverrideIndex
= memIndex(std::move(IndexSymbols
));
163 Opts
.Index
= OverrideIndex
.get();
167 Annotations
Test(Text
);
168 ParseInputs ParseInput
{tooling::CompileCommand(), &FS
, Test
.code().str()};
169 return codeComplete(FilePath
, Test
.point(), /*Preamble=*/nullptr, ParseInput
,
173 Symbol
withReferences(int N
, Symbol S
) {
178 #if CLANGD_DECISION_FOREST
179 TEST(DecisionForestRankingModel
, NameMatchSanityTest
) {
180 clangd::CodeCompleteOptions Opts
;
181 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
182 auto Results
= completions(
184 struct MemberAccess {
186 int AlphaBetaGamma();
188 int func() { MemberAccess().ABG^ }
190 /*IndexSymbols=*/{}, Opts
);
191 EXPECT_THAT(Results
.Completions
,
192 ElementsAre(named("ABG"), named("AlphaBetaGamma")));
195 TEST(DecisionForestRankingModel
, ReferencesAffectRanking
) {
196 clangd::CodeCompleteOptions Opts
;
197 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
198 constexpr int NumReferences
= 100000;
200 completions("int main() { clang^ }",
201 {ns("clangA"), withReferences(NumReferences
, func("clangD"))},
204 ElementsAre(named("clangD"), named("clangA")));
206 completions("int main() { clang^ }",
207 {withReferences(NumReferences
, ns("clangA")), func("clangD")},
210 ElementsAre(named("clangA"), named("clangD")));
212 #endif // CLANGD_DECISION_FOREST
214 TEST(DecisionForestRankingModel
, DecisionForestScorerCallbackTest
) {
215 clangd::CodeCompleteOptions Opts
;
216 constexpr float MagicNumber
= 1234.5678f
;
217 Opts
.RankingModel
= CodeCompleteOptions::DecisionForest
;
218 Opts
.DecisionForestScorer
= [&](const SymbolQualitySignals
&,
219 const SymbolRelevanceSignals
&, float Base
) {
220 DecisionForestScores Scores
;
221 Scores
.Total
= MagicNumber
;
222 Scores
.ExcludingName
= MagicNumber
;
225 llvm::StringRef Code
= "int func() { int xyz; xy^ }";
226 auto Results
= completions(Code
,
227 /*IndexSymbols=*/{}, Opts
);
228 ASSERT_EQ(Results
.Completions
.size(), 1u);
229 EXPECT_EQ(Results
.Completions
[0].Score
.Total
, MagicNumber
);
230 EXPECT_EQ(Results
.Completions
[0].Score
.ExcludingName
, MagicNumber
);
232 // Do not use DecisionForestScorer for heuristics model.
233 Opts
.RankingModel
= CodeCompleteOptions::Heuristics
;
234 Results
= completions(Code
,
235 /*IndexSymbols=*/{}, Opts
);
236 ASSERT_EQ(Results
.Completions
.size(), 1u);
237 EXPECT_NE(Results
.Completions
[0].Score
.Total
, MagicNumber
);
238 EXPECT_NE(Results
.Completions
[0].Score
.ExcludingName
, MagicNumber
);
241 TEST(CompletionTest
, Limit
) {
242 clangd::CodeCompleteOptions Opts
;
244 auto Results
= completions(R
"cpp(
245 struct ClassWithMembers {
251 int main() { ClassWithMembers().^ }
253 /*IndexSymbols=*/{}, Opts
);
255 EXPECT_TRUE(Results
.HasMore
);
256 EXPECT_THAT(Results
.Completions
, ElementsAre(named("AAA"), named("BBB")));
259 TEST(CompletionTest
, Filter
) {
260 std::string Body
= R
"cpp(
270 // Only items matching the fuzzy query are returned.
271 EXPECT_THAT(completions(Body
+ "int main() { S().Foba^ }").Completions
,
272 AllOf(has("FooBar"), has("FooBaz"), Not(has("Qux"))));
274 // Macros require prefix match, either from index or AST.
275 Symbol Sym
= var("MotorCarIndex");
276 Sym
.SymInfo
.Kind
= index::SymbolKind::Macro
;
278 completions(Body
+ "int main() { C^ }", {Sym
}).Completions
,
279 AllOf(has("Car"), Not(has("MotorCar")), Not(has("MotorCarIndex"))));
280 EXPECT_THAT(completions(Body
+ "int main() { M^ }", {Sym
}).Completions
,
281 AllOf(has("MotorCar"), has("MotorCarIndex")));
284 void testAfterDotCompletion(clangd::CodeCompleteOptions Opts
) {
285 auto Results
= completions(
291 // Make sure this is not in preamble.
294 struct GlobalClass {};
296 struct ClassWithMembers {
306 struct LocalClass {};
308 /// doc for local_var.
314 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts
);
316 EXPECT_TRUE(Results
.RanParser
);
317 // Class members. The only items that must be present in after-dot
319 EXPECT_THAT(Results
.Completions
,
320 AllOf(has("method"), has("field"), Not(has("ClassWithMembers")),
321 Not(has("operator=")), Not(has("~ClassWithMembers"))));
322 EXPECT_IFF(Opts
.IncludeIneligibleResults
, Results
.Completions
,
323 has("private_field"));
327 Not(AnyOf(has("global_var"), has("index_var"), has("global_func"),
328 has("global_func()"), has("index_func"), has("GlobalClass"),
329 has("IndexClass"), has("MACRO"), has("LocalClass"))));
330 // There should be no code patterns (aka snippets) in after-dot
331 // completion. At least there aren't any we're aware of.
332 EXPECT_THAT(Results
.Completions
,
333 Not(Contains(kind(CompletionItemKind::Snippet
))));
334 // Check documentation.
335 EXPECT_THAT(Results
.Completions
, Contains(isDocumented()));
338 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts
) {
339 auto Results
= completions(
344 // Make sure this is not in preamble.
347 struct GlobalClass {};
349 struct ClassWithMembers {
355 struct LocalClass {};
357 /// doc for local_var.
363 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts
);
365 EXPECT_TRUE(Results
.RanParser
);
366 // Class members. Should never be present in global completions.
367 EXPECT_THAT(Results
.Completions
,
368 Not(AnyOf(has("method"), has("method()"), has("field"))));
370 EXPECT_THAT(Results
.Completions
,
371 AllOf(has("global_var"), has("index_var"), has("global_func"),
372 has("index_func" /* our fake symbol doesn't include () */),
373 has("GlobalClass"), has("IndexClass")));
375 EXPECT_THAT(Results
.Completions
, has("MACRO"));
376 // Local items. Must be present always.
377 EXPECT_THAT(Results
.Completions
,
378 AllOf(has("local_var"), has("LocalClass"),
379 Contains(kind(CompletionItemKind::Snippet
))));
380 // Check documentation.
381 EXPECT_THAT(Results
.Completions
, Contains(isDocumented()));
384 TEST(CompletionTest
, CompletionOptions
) {
385 auto Test
= [&](const clangd::CodeCompleteOptions
&Opts
) {
386 testAfterDotCompletion(Opts
);
387 testGlobalScopeCompletion(Opts
);
389 // We used to test every combination of options, but that got too slow (2^N).
391 &clangd::CodeCompleteOptions::IncludeIneligibleResults
,
393 // Test default options.
395 // Test with one flag flipped.
396 for (auto &F
: Flags
) {
397 clangd::CodeCompleteOptions O
;
403 TEST(CompletionTest
, Accessible
) {
404 auto Internal
= completions(R
"cpp(
407 protected: void prot();
408 private: void priv();
410 void Foo::pub() { this->^ }
412 EXPECT_THAT(Internal
.Completions
,
413 AllOf(has("priv"), has("prot"), has("pub")));
415 auto External
= completions(R
"cpp(
418 protected: void prot();
419 private: void priv();
426 EXPECT_THAT(External
.Completions
,
427 AllOf(has("pub"), Not(has("prot")), Not(has("priv"))));
429 auto Results
= completions(R
"cpp(
432 protected: void prot();
433 private: void priv();
435 struct Bar : public Foo {
436 private: using Foo::pub;
443 EXPECT_THAT(Results
.Completions
,
444 AllOf(Not(has("priv")), Not(has("prot")), Not(has("pub"))));
447 TEST(CompletionTest
, Qualifiers
) {
448 auto Results
= completions(R
"cpp(
450 public: int foo() const;
453 class Bar : public Foo {
456 void test() { Bar().^ }
458 EXPECT_THAT(Results
.Completions
,
459 Contains(AllOf(qualifier(""), named("bar"))));
460 // Hidden members are not shown.
461 EXPECT_THAT(Results
.Completions
,
462 Not(Contains(AllOf(qualifier("Foo::"), named("foo")))));
463 // Private members are not shown.
464 EXPECT_THAT(Results
.Completions
,
465 Not(Contains(AllOf(qualifier(""), named("foo")))));
468 // https://github.com/clangd/clangd/issues/1451
469 TEST(CompletionTest
, QualificationWithInlineNamespace
) {
470 auto Results
= completions(R
"cpp(
471 namespace a { inline namespace b {} }
472 using namespace a::b;
476 EXPECT_THAT(Results
.Completions
,
477 UnorderedElementsAre(AllOf(qualifier("a::"), named("Foo"))));
480 TEST(CompletionTest
, InjectedTypename
) {
481 // These are suppressed when accessed as a member...
482 EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions
,
484 EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions
,
486 // ...but accessible in other, more useful cases.
487 EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions
,
490 completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions
,
494 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
497 // This case is marginal (`using X::X` is useful), we allow it for now.
498 EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions
,
502 TEST(CompletionTest
, SkipInjectedWhenUnqualified
) {
503 EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions
,
504 ElementsAre(named("X"), named("~X")));
507 TEST(CompletionTest
, Snippets
) {
508 clangd::CodeCompleteOptions Opts
;
509 auto Results
= completions(
513 int f(int i, const float f) const;
520 /*IndexSymbols=*/{}, Opts
);
523 HasSubsequence(named("a"),
524 snippetSuffix("(${1:int i}, ${2:const float f})")));
527 TEST(CompletionTest
, HeuristicsForMemberFunctionCompletion
) {
528 clangd::CodeCompleteOptions Opts
;
529 Opts
.EnableSnippets
= true;
531 Annotations
Code(R
"cpp(
533 static int staticMethod(int);
534 int method(int) const;
535 template <typename T, typename U, typename V = int>
537 template <typename T, int U>
538 static T staticGeneric();
546 struct Derived : Foo {
559 ; // Prevent parsing as 'f.f'
565 d.Derived::$canBeCall^
573 ; // Prevent parsing as 'f.f'
579 d.Derived::$canBeCall^
582 auto TU
= TestTU::withCode(Code
.code());
584 for (const auto &P
: Code
.points("canNotBeCall")) {
585 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
586 EXPECT_THAT(Results
.Completions
,
587 Contains(AllOf(named("method"), signature("(int) const"),
588 snippetSuffix(""))));
589 // We don't have any arguments to deduce against if this isn't a call.
590 // Thus, we should emit these deducible template arguments explicitly.
593 Contains(AllOf(named("generic"),
594 signature("<typename T, typename U>(U, V)"),
595 snippetSuffix("<${1:typename T}, ${2:typename U}>"))));
598 for (const auto &P
: Code
.points("canBeCall")) {
599 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
600 EXPECT_THAT(Results
.Completions
,
601 Contains(AllOf(named("method"), signature("(int) const"),
602 snippetSuffix("(${1:int})"))));
605 Contains(AllOf(named("generic"), signature("<typename T>(U, V)"),
606 snippetSuffix("<${1:typename T}>(${2:U}, ${3:V})"))));
609 // static method will always keep the snippet
610 for (const auto &P
: Code
.points()) {
611 auto Results
= completions(TU
, P
, /*IndexSymbols*/ {}, Opts
);
612 EXPECT_THAT(Results
.Completions
,
613 Contains(AllOf(named("staticMethod"), signature("(int)"),
614 snippetSuffix("(${1:int})"))));
615 EXPECT_THAT(Results
.Completions
,
617 named("staticGeneric"), signature("<typename T, int U>()"),
618 snippetSuffix("<${1:typename T}, ${2:int U}>()"))));
622 TEST(CompletionTest
, NoSnippetsInUsings
) {
623 clangd::CodeCompleteOptions Opts
;
624 Opts
.EnableSnippets
= true;
625 auto Results
= completions(
628 int func(int a, int b);
633 /*IndexSymbols=*/{}, Opts
);
634 EXPECT_THAT(Results
.Completions
,
635 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
636 snippetSuffix(""))));
638 // Check index completions too.
639 auto Func
= func("ns::func");
640 Func
.CompletionSnippetSuffix
= "(${1:int a}, ${2: int b})";
641 Func
.Signature
= "(int a, int b)";
642 Func
.ReturnType
= "void";
644 Results
= completions(R
"cpp(
648 /*IndexSymbols=*/{Func
}, Opts
);
649 EXPECT_THAT(Results
.Completions
,
650 ElementsAre(AllOf(named("func"), labeled("func(int a, int b)"),
651 snippetSuffix(""))));
653 // Check all-scopes completions too.
654 Opts
.AllScopes
= true;
655 Results
= completions(R
"cpp(
658 /*IndexSymbols=*/{Func
}, Opts
);
659 EXPECT_THAT(Results
.Completions
,
660 Contains(AllOf(named("func"), labeled("ns::func(int a, int b)"),
661 snippetSuffix(""))));
664 TEST(CompletionTest
, Kinds
) {
665 auto Results
= completions(
670 // make sure MACRO is not included in preamble.
674 {func("indexFunction"), var("indexVariable"), cls("indexClass")});
675 EXPECT_THAT(Results
.Completions
,
676 AllOf(has("function", CompletionItemKind::Function
),
677 has("variable", CompletionItemKind::Variable
),
678 has("int", CompletionItemKind::Keyword
),
679 has("Struct", CompletionItemKind::Struct
),
680 has("MACRO", CompletionItemKind::Constant
),
681 has("indexFunction", CompletionItemKind::Function
),
682 has("indexVariable", CompletionItemKind::Variable
),
683 has("indexClass", CompletionItemKind::Class
)));
685 Results
= completions("nam^");
686 EXPECT_THAT(Results
.Completions
,
687 has("namespace", CompletionItemKind::Snippet
));
689 // Members of anonymous unions are of kind 'field'.
690 Results
= completions(
701 UnorderedElementsAre(AllOf(named("a"), kind(CompletionItemKind::Field
))));
703 // Completion kinds for templates should not be unknown.
704 Results
= completions(
706 template <class T> struct complete_class {};
707 template <class T> void complete_function();
708 template <class T> using complete_type_alias = int;
709 template <class T> int complete_variable = 10;
712 template <class T> static int complete_static_member = 10;
714 static auto x = complete_^
719 UnorderedElementsAre(
720 AllOf(named("complete_class"), kind(CompletionItemKind::Class
)),
721 AllOf(named("complete_function"), kind(CompletionItemKind::Function
)),
722 AllOf(named("complete_type_alias"),
723 kind(CompletionItemKind::Interface
)),
724 AllOf(named("complete_variable"), kind(CompletionItemKind::Variable
)),
725 AllOf(named("complete_static_member"),
726 kind(CompletionItemKind::Property
))));
728 Results
= completions(
737 Contains(AllOf(named("Red"), kind(CompletionItemKind::EnumMember
))));
740 TEST(CompletionTest
, NoDuplicates
) {
741 auto Results
= completions(
752 // Make sure there are no duplicate entries of 'Adapter'.
753 EXPECT_THAT(Results
.Completions
, ElementsAre(named("Adapter")));
756 TEST(CompletionTest
, ScopedNoIndex
) {
757 auto Results
= completions(
759 namespace fake { int BigBang, Babble, Box; };
760 int main() { fake::ba^ }
762 // Babble is a better match than BigBang. Box doesn't match at all.
763 EXPECT_THAT(Results.Completions,
764 ElementsAre(named("Babble
"), named("BigBang
")));
767 TEST(CompletionTest, Scoped) {
768 auto Results = completions(
770 namespace fake
{ int Babble
, Box
; };
771 int main() { fake::ba
^ }
773 {var("fake::BigBang")});
774 EXPECT_THAT(Results
.Completions
,
775 ElementsAre(named("Babble"), named("BigBang")));
778 TEST(CompletionTest
, ScopedWithFilter
) {
779 auto Results
= completions(
783 {cls("ns::XYZ"), func("ns::foo")});
784 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(named("XYZ")));
787 TEST(CompletionTest
, ReferencesAffectRanking
) {
788 EXPECT_THAT(completions("int main() { abs^ }", {func("absA"), func("absB")})
790 HasSubsequence(named("absA"), named("absB")));
791 EXPECT_THAT(completions("int main() { abs^ }",
792 {func("absA"), withReferences(1000, func("absB"))})
794 HasSubsequence(named("absB"), named("absA")));
797 TEST(CompletionTest
, ContextWords
) {
798 auto Results
= completions(R
"cpp(
799 enum class Color { RED, YELLOW, BLUE };
801 // (blank lines so the definition above isn't "context
")
803 // "It was a yellow car
," he said. "Big yellow car
, new."
804 auto Finish = Color::^
806 // Yellow would normally sort last (alphabetic).
807 // But the recent mention should bump it up.
808 ASSERT_THAT(Results
.Completions
,
809 HasSubsequence(named("YELLOW"), named("BLUE")));
812 TEST(CompletionTest
, GlobalQualified
) {
813 auto Results
= completions(
818 EXPECT_THAT(Results
.Completions
,
819 AllOf(has("XYZ", CompletionItemKind::Class
),
820 has("f", CompletionItemKind::Function
)));
823 TEST(CompletionTest
, FullyQualified
) {
824 auto Results
= completions(
826 namespace ns { void bar(); }
830 EXPECT_THAT(Results
.Completions
,
831 AllOf(has("XYZ", CompletionItemKind::Class
),
832 has("bar", CompletionItemKind::Function
)));
835 TEST(CompletionTest
, SemaIndexMerge
) {
836 auto Results
= completions(
838 namespace ns { int local; void both(); }
841 {func("ns::both"), cls("ns::Index")});
842 // We get results from both index and sema, with no duplicates.
843 EXPECT_THAT(Results
.Completions
,
844 UnorderedElementsAre(
845 AllOf(named("local"), origin(SymbolOrigin::AST
)),
846 AllOf(named("Index"), origin(SymbolOrigin::Static
)),
848 origin(SymbolOrigin::AST
| SymbolOrigin::Static
))));
851 TEST(CompletionTest
, SemaIndexMergeWithLimit
) {
852 clangd::CodeCompleteOptions Opts
;
854 auto Results
= completions(
856 namespace ns { int local; void both(); }
859 {func("ns::both"), cls("ns::Index")}, Opts
);
860 EXPECT_EQ(Results
.Completions
.size(), Opts
.Limit
);
861 EXPECT_TRUE(Results
.HasMore
);
864 TEST(CompletionTest
, IncludeInsertionPreprocessorIntegrationTests
) {
866 TU
.ExtraArgs
.push_back("-I" + testPath("sub"));
867 TU
.AdditionalFiles
["sub/bar.h"] = "";
868 auto BarURI
= URI::create(testPath("sub/bar.h")).toString();
870 Symbol Sym
= cls("ns::X");
871 Sym
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
872 Sym
.IncludeHeaders
.emplace_back(BarURI
, 1, Symbol::Include
);
873 // Shorten include path based on search directory and insert.
874 Annotations
Test("int main() { ns::^ }");
875 TU
.Code
= Test
.code().str();
876 auto Results
= completions(TU
, Test
.point(), {Sym
});
877 EXPECT_THAT(Results
.Completions
,
878 ElementsAre(AllOf(named("X"), insertInclude("\"bar.h\""))));
879 // Can be disabled via option.
880 CodeCompleteOptions NoInsertion
;
881 NoInsertion
.InsertIncludes
= CodeCompleteOptions::NeverInsert
;
882 Results
= completions(TU
, Test
.point(), {Sym
}, NoInsertion
);
883 EXPECT_THAT(Results
.Completions
,
884 ElementsAre(AllOf(named("X"), Not(insertInclude()))));
885 // Duplicate based on inclusions in preamble.
886 Test
= Annotations(R
"cpp(
887 #include "sub
/bar
.h
" // not shortest, so should only match resolved.
890 TU
.Code
= Test
.code().str();
891 Results
= completions(TU
, Test
.point(), {Sym
});
892 EXPECT_THAT(Results
.Completions
, ElementsAre(AllOf(named("X"), labeled("X"),
893 Not(insertInclude()))));
896 TEST(CompletionTest
, NoIncludeInsertionWhenDeclFoundInFile
) {
897 Symbol SymX
= cls("ns::X");
898 Symbol SymY
= cls("ns::Y");
899 std::string BarHeader
= testPath("bar.h");
900 auto BarURI
= URI::create(BarHeader
).toString();
901 SymX
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
902 SymY
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
903 SymX
.IncludeHeaders
.emplace_back("<bar>", 1, Symbol::Include
);
904 SymY
.IncludeHeaders
.emplace_back("<bar>", 1, Symbol::Include
);
905 // Shorten include path based on search directory and insert.
906 auto Results
= completions(R
"cpp(
914 EXPECT_THAT(Results
.Completions
,
915 ElementsAre(AllOf(named("X"), Not(insertInclude())),
916 AllOf(named("Y"), Not(insertInclude()))));
919 TEST(CompletionTest
, IndexSuppressesPreambleCompletions
) {
920 Annotations
Test(R
"cpp(
922 namespace ns { int local; }
924 void f2() { ns::preamble().$2^; }
926 auto TU
= TestTU::withCode(Test
.code());
927 TU
.AdditionalFiles
["bar.h"] =
928 R
"cpp(namespace ns { struct preamble { int member; }; })cpp";
930 clangd::CodeCompleteOptions Opts
= {};
931 auto I
= memIndex({var("ns::index")});
932 Opts
.Index
= I
.get();
933 auto WithIndex
= completions(TU
, Test
.point(), {}, Opts
);
934 EXPECT_THAT(WithIndex
.Completions
,
935 UnorderedElementsAre(named("local"), named("index")));
936 auto ClassFromPreamble
= completions(TU
, Test
.point("2"), {}, Opts
);
937 EXPECT_THAT(ClassFromPreamble
.Completions
, Contains(named("member")));
939 Opts
.Index
= nullptr;
940 auto WithoutIndex
= completions(TU
, Test
.point(), {}, Opts
);
941 EXPECT_THAT(WithoutIndex
.Completions
,
942 UnorderedElementsAre(named("local"), named("preamble")));
945 // This verifies that we get normal preprocessor completions in the preamble.
946 // This is a regression test for an old bug: if we override the preamble and
947 // try to complete inside it, clang kicks our completion point just outside the
948 // preamble, resulting in always getting top-level completions.
949 TEST(CompletionTest
, CompletionInPreamble
) {
950 auto Results
= completions(R
"cpp(
958 EXPECT_THAT(Results
, ElementsAre(named("ifndef")));
961 TEST(CompletionTest
, CompletionRecoveryASTType
) {
962 auto Results
= completions(R
"cpp(
963 struct S { int member; };
966 // No overload matches, but we have recovery-expr with the correct type.
970 EXPECT_THAT(Results
, ElementsAre(named("member")));
973 TEST(CompletionTest
, DynamicIndexIncludeInsertion
) {
975 MockCompilationDatabase CDB
;
976 ClangdServer::Options Opts
= ClangdServer::optsForTest();
977 Opts
.BuildDynamicSymbolIndex
= true;
978 ClangdServer
Server(CDB
, FS
, Opts
);
980 FS
.Files
[testPath("foo_header.h")] = R
"cpp(
987 const std::string
FileContent(R
"cpp(
988 #include "foo_header
.h
"
993 Server
.addDocument(testPath("foo_impl.cpp"), FileContent
);
994 // Wait for the dynamic index being built.
995 ASSERT_TRUE(Server
.blockUntilIdleForTest());
997 auto File
= testPath("foo.cpp");
998 Annotations
Test("Foo^ foo;");
999 runAddDocument(Server
, File
, Test
.code());
1000 auto CompletionList
=
1001 llvm::cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1003 EXPECT_THAT(CompletionList
.Completions
,
1004 ElementsAre(AllOf(named("Foo"), hasInclude("\"foo_header.h\""),
1008 TEST(CompletionTest
, DynamicIndexMultiFile
) {
1010 MockCompilationDatabase CDB
;
1011 auto Opts
= ClangdServer::optsForTest();
1012 Opts
.BuildDynamicSymbolIndex
= true;
1013 ClangdServer
Server(CDB
, FS
, Opts
);
1015 FS
.Files
[testPath("foo.h")] = R
"cpp(
1016 namespace ns { class XYZ {}; void foo(int x) {} }
1018 runAddDocument(Server
, testPath("foo.cpp"), R
"cpp(
1022 auto File
= testPath("bar.cpp");
1023 Annotations
Test(R
"cpp(
1031 runAddDocument(Server
, File
, Test
.code());
1033 auto Results
= cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1034 // "XYZ" and "foo" are not included in the file being completed but are still
1035 // visible through the index.
1036 EXPECT_THAT(Results
.Completions
, has("XYZ", CompletionItemKind::Class
));
1037 EXPECT_THAT(Results
.Completions
, has("foo", CompletionItemKind::Function
));
1038 EXPECT_THAT(Results
.Completions
, has("XXX", CompletionItemKind::Class
));
1039 EXPECT_THAT(Results
.Completions
,
1040 Contains((named("fooooo"), kind(CompletionItemKind::Function
),
1041 doc("Doooc"), returnType("void"))));
1044 TEST(CompletionTest
, Documentation
) {
1045 auto Results
= completions(
1047 // Non-doxygen comment.
1048 __attribute__((annotate("custom_annotation
"))) int foo();
1049 /// Doxygen comment.
1059 EXPECT_THAT(Results
.Completions
,
1062 doc("Annotation: custom_annotation\nNon-doxygen comment."))));
1064 Results
.Completions
,
1065 Contains(AllOf(named("bar"), doc("Doxygen comment.\n\\param int a"))));
1066 EXPECT_THAT(Results
.Completions
,
1067 Contains(AllOf(named("baz"), doc("Multi-line block comment"))));
1070 TEST(CompletionTest
, CommentsFromSystemHeaders
) {
1072 MockCompilationDatabase CDB
;
1074 auto Opts
= ClangdServer::optsForTest();
1075 Opts
.BuildDynamicSymbolIndex
= true;
1077 ClangdServer
Server(CDB
, FS
, Opts
);
1079 FS
.Files
[testPath("foo.h")] = R
"cpp(
1080 #pragma GCC system_header
1082 // This comment should be retained!
1086 auto File
= testPath("foo.cpp");
1087 Annotations
Test(R
"cpp(
1091 runAddDocument(Server
, File
, Test
.code());
1092 auto CompletionList
=
1093 llvm::cantFail(runCodeComplete(Server
, File
, Test
.point(), {}));
1096 CompletionList
.Completions
,
1097 Contains(AllOf(named("foo"), doc("This comment should be retained!"))));
1100 TEST(CompletionTest
, GlobalCompletionFiltering
) {
1102 Symbol Class
= cls("XYZ");
1103 Class
.Flags
= static_cast<Symbol::SymbolFlag
>(
1104 Class
.Flags
& ~(Symbol::IndexedForCodeCompletion
));
1105 Symbol Func
= func("XYZ::foooo");
1106 Func
.Flags
= static_cast<Symbol::SymbolFlag
>(
1107 Func
.Flags
& ~(Symbol::IndexedForCodeCompletion
));
1109 auto Results
= completions(R
"(// void f() {
1113 EXPECT_THAT(Results
.Completions
, IsEmpty());
1116 TEST(CodeCompleteTest
, DisableTypoCorrection
) {
1117 auto Results
= completions(R
"cpp(
1118 namespace clang { int v; }
1119 void f() { clangd::^
1121 EXPECT_TRUE(Results
.Completions
.empty());
1124 TEST(CodeCompleteTest
, NoColonColonAtTheEnd
) {
1125 auto Results
= completions(R
"cpp(
1132 EXPECT_THAT(Results
.Completions
, Contains(labeled("clang")));
1133 EXPECT_THAT(Results
.Completions
, Not(Contains(labeled("clang::"))));
1136 TEST(CompletionTests
, EmptySnippetDoesNotCrash
) {
1137 // See https://github.com/clangd/clangd/issues/1216
1138 auto Results
= completions(R
"cpp(
1140 auto w = [&](auto &&f) { return f(f); };
1141 auto f = w([&](auto &&f) {
1142 return [&](auto &&n) {
1146 return n * ^(f)(n - 1);
1153 TEST(CompletionTest
, Issue1427Crash
) {
1154 // Need to provide main file signals to ensure that the branch in
1155 // SymbolRelevanceSignals::computeASTSignals() that tries to
1156 // compute a symbol ID is taken.
1157 ASTSignals MainFileSignals
;
1158 CodeCompleteOptions Opts
;
1159 Opts
.MainFileSignals
= &MainFileSignals
;
1168 TEST(CompletionTest
, BacktrackCrashes
) {
1169 // Sema calls code completion callbacks twice in these cases.
1170 auto Results
= completions(R
"cpp(
1172 struct FooBarBaz {};
1178 EXPECT_THAT(Results
.Completions
, ElementsAre(labeled("FooBarBaz")));
1180 // Check we don't crash in that case too.
1182 struct FooBarBaz {};
1184 if (FooBarBaz * x^) {}
1189 TEST(CompletionTest
, CompleteInMacroWithStringification
) {
1190 auto Results
= completions(R
"cpp(
1191 void f(const char *, int x);
1192 #define F(x) f(#x, x)
1199 int f(int input_num) {
1204 EXPECT_THAT(Results
.Completions
,
1205 UnorderedElementsAre(named("X"), named("Y")));
1208 TEST(CompletionTest
, CompleteInMacroAndNamespaceWithStringification
) {
1209 auto Results
= completions(R
"cpp(
1210 void f(const char *, int x);
1211 #define F(x) f(#x, x)
1216 int f(int input_num) {
1222 EXPECT_THAT(Results
.Completions
, Contains(named("X")));
1225 TEST(CompletionTest
, IgnoreCompleteInExcludedPPBranchWithRecoveryContext
) {
1226 auto Results
= completions(R
"cpp(
1227 int bar(int param_in_bar) {
1230 int foo(int param_in_foo) {
1232 // In recovery mode, "param_in_foo
" will also be suggested among many other
1233 // unrelated symbols; however, this is really a special case where this works.
1234 // If the #if block is outside of the function, "param_in_foo
" is still
1235 // suggested, but "bar
" and "foo
" are missing. So the recovery mode doesn't
1236 // really provide useful results in excluded branches.
1242 EXPECT_TRUE(Results
.Completions
.empty());
1245 TEST(CompletionTest
, DefaultArgs
) {
1246 clangd::CodeCompleteOptions Opts
;
1247 std::string Context
= R
"cpp(
1249 int Y(int A, int B = 0);
1250 int Z(int A, int B = 0, int C = 0, int D = 0);
1252 EXPECT_THAT(completions(Context
+ "int y = X^", {}, Opts
).Completions
,
1253 UnorderedElementsAre(labeled("X(int A = 0)")));
1254 EXPECT_THAT(completions(Context
+ "int y = Y^", {}, Opts
).Completions
,
1255 UnorderedElementsAre(AllOf(labeled("Y(int A, int B = 0)"),
1256 snippetSuffix("(${1:int A})"))));
1257 EXPECT_THAT(completions(Context
+ "int y = Z^", {}, Opts
).Completions
,
1258 UnorderedElementsAre(
1259 AllOf(labeled("Z(int A, int B = 0, int C = 0, int D = 0)"),
1260 snippetSuffix("(${1:int A})"))));
1263 TEST(CompletionTest
, NoCrashWithTemplateParamsAndPreferredTypes
) {
1264 auto Completions
= completions(R
"cpp(
1265 template <template <class> class TT> int foo() {
1270 EXPECT_THAT(Completions
, Contains(named("TT")));
1273 TEST(CompletionTest
, NestedTemplateHeuristics
) {
1274 auto Completions
= completions(R
"cpp(
1275 struct Plain { int xxx; };
1276 template <typename T> class Templ { Plain ppp; };
1277 template <typename T> void foo(Templ<T> &t) {
1278 // Formally ppp has DependentTy, because Templ may be specialized.
1279 // However we sholud be able to see into it using the primary template.
1284 EXPECT_THAT(Completions
, Contains(named("xxx")));
1287 TEST(CompletionTest
, RecordCCResultCallback
) {
1288 std::vector
<CodeCompletion
> RecordedCompletions
;
1289 CodeCompleteOptions Opts
;
1290 Opts
.RecordCCResult
= [&RecordedCompletions
](const CodeCompletion
&CC
,
1291 const SymbolQualitySignals
&,
1292 const SymbolRelevanceSignals
&,
1294 RecordedCompletions
.push_back(CC
);
1297 completions("int xy1, xy2; int a = xy^", /*IndexSymbols=*/{}, Opts
);
1298 EXPECT_THAT(RecordedCompletions
,
1299 UnorderedElementsAre(named("xy1"), named("xy2")));
1302 TEST(CompletionTest
, ASTSignals
) {
1305 unsigned MainFileRefs
;
1306 unsigned ScopeRefsInFile
;
1308 CodeCompleteOptions Opts
;
1309 std::vector
<Completion
> RecordedCompletions
;
1310 Opts
.RecordCCResult
= [&RecordedCompletions
](const CodeCompletion
&CC
,
1311 const SymbolQualitySignals
&,
1312 const SymbolRelevanceSignals
&R
,
1314 RecordedCompletions
.push_back({CC
.Name
, R
.MainFileRefs
, R
.ScopeRefsInFile
});
1316 ASTSignals MainFileSignals
;
1317 MainFileSignals
.ReferencedSymbols
[var("xy1").ID
] = 3;
1318 MainFileSignals
.ReferencedSymbols
[var("xy2").ID
] = 1;
1319 MainFileSignals
.ReferencedSymbols
[var("xyindex").ID
] = 10;
1320 MainFileSignals
.RelatedNamespaces
["tar::"] = 5;
1321 MainFileSignals
.RelatedNamespaces
["bar::"] = 3;
1322 Opts
.MainFileSignals
= &MainFileSignals
;
1323 Opts
.AllScopes
= true;
1333 /*IndexSymbols=*/{var("xyindex"), var("tar::xytar"), var("bar::xybar")},
1335 EXPECT_THAT(RecordedCompletions
,
1336 UnorderedElementsAre(
1337 AllOf(named("xy1"), mainFileRefs(3u), scopeRefs(0u)),
1338 AllOf(named("xy2"), mainFileRefs(1u), scopeRefs(0u)),
1339 AllOf(named("xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1340 AllOf(named("xytar"), mainFileRefs(0u), scopeRefs(5u)),
1341 AllOf(/*both from sema and index*/ named("xybar"),
1342 mainFileRefs(0u), scopeRefs(3u))));
1346 signatures(llvm::StringRef Text
, Position Point
,
1347 std::vector
<Symbol
> IndexSymbols
= {},
1348 MarkupKind DocumentationFormat
= MarkupKind::PlainText
) {
1349 std::unique_ptr
<SymbolIndex
> Index
;
1350 if (!IndexSymbols
.empty())
1351 Index
= memIndex(IndexSymbols
);
1353 auto TU
= TestTU::withCode(Text
);
1355 auto Inputs
= TU
.inputs(FS
);
1356 Inputs
.Index
= Index
.get();
1357 IgnoreDiagnostics Diags
;
1358 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
1360 ADD_FAILURE() << "Couldn't build CompilerInvocation";
1363 auto Preamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
1364 /*InMemory=*/true, /*Callback=*/nullptr);
1366 ADD_FAILURE() << "Couldn't build Preamble";
1369 return signatureHelp(testPath(TU
.Filename
), Point
, *Preamble
, Inputs
,
1370 DocumentationFormat
);
1374 signatures(llvm::StringRef Text
, std::vector
<Symbol
> IndexSymbols
= {},
1375 MarkupKind DocumentationFormat
= MarkupKind::PlainText
) {
1376 Annotations
Test(Text
);
1377 return signatures(Test
.code(), Test
.point(), std::move(IndexSymbols
),
1378 DocumentationFormat
);
1381 struct ExpectedParameter
{
1383 std::pair
<unsigned, unsigned> Offsets
;
1385 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
,
1386 const ExpectedParameter
&P
) {
1387 return OS
<< P
.Text
;
1389 MATCHER_P(paramsAre
, P
, "") {
1390 if (P
.size() != arg
.parameters
.size())
1392 for (unsigned I
= 0; I
< P
.size(); ++I
) {
1393 if (P
[I
].Text
!= arg
.parameters
[I
].labelString
||
1394 P
[I
].Offsets
!= arg
.parameters
[I
].labelOffsets
)
1399 MATCHER_P(sigDoc
, doc
, "") { return arg
.documentation
.value
== doc
; }
1401 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g.
1402 /// foo([[int p1]], [[double p2]]) -> void
1403 Matcher
<SignatureInformation
> sig(llvm::StringRef AnnotatedLabel
) {
1404 llvm::Annotations
A(AnnotatedLabel
);
1405 std::string Label
= std::string(A
.code());
1406 std::vector
<ExpectedParameter
> Parameters
;
1407 for (auto Range
: A
.ranges()) {
1408 Parameters
.emplace_back();
1410 ExpectedParameter
&P
= Parameters
.back();
1411 P
.Text
= Label
.substr(Range
.Begin
, Range
.End
- Range
.Begin
);
1412 P
.Offsets
.first
= lspLength(llvm::StringRef(Label
).substr(0, Range
.Begin
));
1413 P
.Offsets
.second
= lspLength(llvm::StringRef(Label
).substr(1, Range
.End
));
1415 return AllOf(sigHelpLabeled(Label
), paramsAre(Parameters
));
1418 TEST(SignatureHelpTest
, Overloads
) {
1419 auto Results
= signatures(R
"cpp(
1420 void foo(int x, int y);
1421 void foo(int x, float y);
1422 void foo(float x, int y);
1423 void foo(float x, float y);
1424 void bar(int x, int y = 0);
1425 int main() { foo(^); }
1427 EXPECT_THAT(Results
.signatures
,
1428 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1429 sig("foo([[float x]], [[int y]]) -> void"),
1430 sig("foo([[int x]], [[float y]]) -> void"),
1431 sig("foo([[int x]], [[int y]]) -> void")));
1432 // We always prefer the first signature.
1433 EXPECT_EQ(0, Results
.activeSignature
);
1434 EXPECT_EQ(0, Results
.activeParameter
);
1437 TEST(SignatureHelpTest
, FunctionPointers
) {
1438 llvm::StringLiteral Tests
[] = {
1439 // Variable of function pointer type
1441 void (*foo)(int x, int y);
1442 int main() { foo(^); }
1444 // Wrapped in an AttributedType
1446 void (__stdcall *foo)(int x, int y);
1447 int main() { foo(^); }
1449 // Another syntax for an AttributedType
1451 void (__attribute__(stdcall) *foo)(int x, int y);
1452 int main() { foo(^); },
1454 // Wrapped in a typedef
1456 typedef void (*fn)(int x, int y);
1458 int main() { foo(^); }
1460 // Wrapped in both a typedef and an AttributedTyped
1462 typedef void (__stdcall *fn)(int x, int y);
1464 int main() { foo(^); }
1466 for (auto Test
: Tests
)
1467 EXPECT_THAT(signatures(Test
).signatures
,
1468 UnorderedElementsAre(sig("([[int x]], [[int y]]) -> void")));
1471 TEST(SignatureHelpTest
, Constructors
) {
1472 std::string Top
= R
"cpp(
1475 S(const S &) = delete;
1479 auto CheckParenInit
= [&](std::string Init
) {
1480 EXPECT_THAT(signatures(Top
+ Init
).signatures
,
1481 UnorderedElementsAre(sig("S([[int]])")))
1484 CheckParenInit("S s(^);");
1485 CheckParenInit("auto s = S(^);");
1486 CheckParenInit("auto s = new S(^);");
1488 auto CheckBracedInit
= [&](std::string Init
) {
1489 EXPECT_THAT(signatures(Top
+ Init
).signatures
,
1490 UnorderedElementsAre(sig("S{[[int]]}")))
1493 CheckBracedInit("S s{^};");
1494 CheckBracedInit("S s = {^};");
1495 CheckBracedInit("auto s = S{^};");
1496 // FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression.
1497 // CheckBracedInit("auto s = new S{^};");
1498 CheckBracedInit("int x(S); int i = x({^});");
1501 TEST(SignatureHelpTest
, Aggregates
) {
1502 std::string Top
= R
"cpp(
1507 auto AggregateSig
= sig("S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1508 EXPECT_THAT(signatures(Top
+ "S s{^}").signatures
,
1509 UnorderedElementsAre(AggregateSig
, sig("S{}"),
1510 sig("S{[[const S &]]}"),
1511 sig("S{[[S &&]]}")));
1512 EXPECT_THAT(signatures(Top
+ "S s{1,^}").signatures
,
1513 ElementsAre(AggregateSig
));
1514 EXPECT_EQ(signatures(Top
+ "S s{1,^}").activeParameter
, 1);
1515 EXPECT_THAT(signatures(Top
+ "S s{.c=3,^}").signatures
,
1516 ElementsAre(AggregateSig
));
1517 EXPECT_EQ(signatures(Top
+ "S s{.c=3,^}").activeParameter
, 3);
1520 TEST(SignatureHelpTest
, OverloadInitListRegression
) {
1521 auto Results
= signatures(R
"cpp(
1530 EXPECT_THAT(Results
.signatures
, UnorderedElementsAre(sig("f() -> void")));
1533 TEST(SignatureHelpTest
, DefaultArgs
) {
1534 auto Results
= signatures(R
"cpp(
1535 void bar(int x, int y = 0);
1536 void bar(float x = 0, int y = 42);
1539 EXPECT_THAT(Results
.signatures
,
1540 UnorderedElementsAre(
1541 sig("bar([[int x]], [[int y = 0]]) -> void"),
1542 sig("bar([[float x = 0]], [[int y = 42]]) -> void")));
1543 EXPECT_EQ(0, Results
.activeSignature
);
1544 EXPECT_EQ(0, Results
.activeParameter
);
1547 TEST(SignatureHelpTest
, ActiveArg
) {
1548 auto Results
= signatures(R
"cpp(
1549 int baz(int a, int b, int c);
1550 int main() { baz(baz(1,2,3), ^); }
1552 EXPECT_THAT(Results
.signatures
,
1553 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1554 EXPECT_EQ(0, Results
.activeSignature
);
1555 EXPECT_EQ(1, Results
.activeParameter
);
1558 TEST(SignatureHelpTest
, OpeningParen
) {
1559 llvm::StringLiteral Tests
[] = {
1560 // Recursive function call.
1562 int foo(int a, int b, int c);
1564 foo(foo $p^( foo(10, 10, 10), ^ )));
1566 // Functional type cast.
1569 Foo(int a, int b, int c);
1577 Foo(int a, int b, int c);
1580 new Foo $p^( 10, ^ );
1584 int foo(int a, int b, int c);
1588 // Macro expansions.
1593 int foo(int a, int b, int c);
1596 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1597 // the recovery expression.
1598 ID(foo $p^( 10, ^ ))
1602 int foo(int a, int b);
1603 template <typename T> void bar(T t) {
1606 // Dependent args on templated func.
1608 template <typename T>
1610 template <typename T> void bar(T t) {
1613 // Dependent args on member.
1615 struct Foo { int foo(int, int); };
1616 template <typename T> void bar(T t) {
1620 // Dependent args on templated member.
1622 struct Foo { template <typename T> int foo(T, T); };
1623 template <typename T> void bar(T t) {
1629 for (auto Test
: Tests
) {
1630 Annotations
Code(Test
);
1631 EXPECT_EQ(signatures(Code
.code(), Code
.point()).argListStart
,
1633 << "Test source:" << Test
;
1637 TEST(SignatureHelpTest
, StalePreamble
) {
1640 IgnoreDiagnostics Diags
;
1642 auto Inputs
= TU
.inputs(FS
);
1643 auto CI
= buildCompilerInvocation(Inputs
, Diags
);
1645 auto EmptyPreamble
= buildPreamble(testPath(TU
.Filename
), *CI
, Inputs
,
1646 /*InMemory=*/true, /*Callback=*/nullptr);
1647 ASSERT_TRUE(EmptyPreamble
);
1649 TU
.AdditionalFiles
["a.h"] = "int foo(int x);";
1650 const Annotations
Test(R
"cpp(
1652 void bar() { foo(^2); })cpp");
1653 TU
.Code
= Test
.code().str();
1655 signatureHelp(testPath(TU
.Filename
), Test
.point(), *EmptyPreamble
,
1656 TU
.inputs(FS
), MarkupKind::PlainText
);
1657 EXPECT_THAT(Results
.signatures
, ElementsAre(sig("foo([[int x]]) -> int")));
1658 EXPECT_EQ(0, Results
.activeSignature
);
1659 EXPECT_EQ(0, Results
.activeParameter
);
1662 class IndexRequestCollector
: public SymbolIndex
{
1664 IndexRequestCollector(std::vector
<Symbol
> Syms
= {}) : Symbols(Syms
) {}
1667 fuzzyFind(const FuzzyFindRequest
&Req
,
1668 llvm::function_ref
<void(const Symbol
&)> Callback
) const override
{
1669 std::unique_lock
<std::mutex
> Lock(Mut
);
1670 Requests
.push_back(Req
);
1671 ReceivedRequestCV
.notify_one();
1672 for (const auto &Sym
: Symbols
)
1677 void lookup(const LookupRequest
&,
1678 llvm::function_ref
<void(const Symbol
&)>) const override
{}
1680 bool refs(const RefsRequest
&,
1681 llvm::function_ref
<void(const Ref
&)>) const override
{
1685 void relations(const RelationsRequest
&,
1686 llvm::function_ref
<void(const SymbolID
&, const Symbol
&)>)
1689 llvm::unique_function
<IndexContents(llvm::StringRef
) const>
1690 indexedFiles() const override
{
1691 return [](llvm::StringRef
) { return IndexContents::None
; };
1694 // This is incorrect, but IndexRequestCollector is not an actual index and it
1695 // isn't used in production code.
1696 size_t estimateMemoryUsage() const override
{ return 0; }
1698 const std::vector
<FuzzyFindRequest
> consumeRequests(size_t Num
) const {
1699 std::unique_lock
<std::mutex
> Lock(Mut
);
1700 EXPECT_TRUE(wait(Lock
, ReceivedRequestCV
, timeoutSeconds(30),
1701 [this, Num
] { return Requests
.size() == Num
; }));
1702 auto Reqs
= std::move(Requests
);
1708 std::vector
<Symbol
> Symbols
;
1709 // We need a mutex to handle async fuzzy find requests.
1710 mutable std::condition_variable ReceivedRequestCV
;
1711 mutable std::mutex Mut
;
1712 mutable std::vector
<FuzzyFindRequest
> Requests
;
1715 // Clients have to consume exactly Num requests.
1716 std::vector
<FuzzyFindRequest
> captureIndexRequests(llvm::StringRef Code
,
1718 clangd::CodeCompleteOptions Opts
;
1719 IndexRequestCollector Requests
;
1720 Opts
.Index
= &Requests
;
1721 completions(Code
, {}, Opts
);
1722 const auto Reqs
= Requests
.consumeRequests(Num
);
1723 EXPECT_EQ(Reqs
.size(), Num
);
1727 TEST(CompletionTest
, UnqualifiedIdQuery
) {
1728 auto Requests
= captureIndexRequests(R
"cpp(
1730 using namespace std;
1738 EXPECT_THAT(Requests
,
1739 ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1740 UnorderedElementsAre("", "ns::", "std::"))));
1743 TEST(CompletionTest
, EnclosingScopeComesFirst
) {
1744 auto Requests
= captureIndexRequests(R
"cpp(
1746 using namespace std;
1758 EXPECT_THAT(Requests
,
1760 &FuzzyFindRequest::Scopes
,
1761 UnorderedElementsAre("", "std::", "nx::ns::", "nx::"))));
1762 EXPECT_EQ(Requests
[0].Scopes
[0], "nx::ns::");
1765 TEST(CompletionTest
, ResolvedQualifiedIdQuery
) {
1766 auto Requests
= captureIndexRequests(R
"cpp(
1768 namespace ns2 {} // ignore
1769 namespace ns3 { namespace nns3 {} }
1771 using namespace ns1;
1772 using namespace ns3::nns3;
1781 EXPECT_THAT(Requests
,
1783 &FuzzyFindRequest::Scopes
,
1784 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::"))));
1787 TEST(CompletionTest
, UnresolvedQualifierIdQuery
) {
1788 auto Requests
= captureIndexRequests(R
"cpp(
1798 EXPECT_THAT(Requests
,
1800 &FuzzyFindRequest::Scopes
,
1801 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::"))));
1804 TEST(CompletionTest
, UnresolvedNestedQualifierIdQuery
) {
1805 auto Requests
= captureIndexRequests(R
"cpp(
1815 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1816 UnorderedElementsAre("a::bar::"))));
1819 TEST(CompletionTest
, EmptyQualifiedQuery
) {
1820 auto Requests
= captureIndexRequests(R
"cpp(
1828 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1829 UnorderedElementsAre("", "ns::"))));
1832 TEST(CompletionTest
, GlobalQualifiedQuery
) {
1833 auto Requests
= captureIndexRequests(R
"cpp(
1841 EXPECT_THAT(Requests
, ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1842 UnorderedElementsAre(""))));
1845 TEST(CompletionTest
, NoDuplicatedQueryScopes
) {
1846 auto Requests
= captureIndexRequests(R
"cpp(
1857 EXPECT_THAT(Requests
,
1858 ElementsAre(Field(&FuzzyFindRequest::Scopes
,
1859 UnorderedElementsAre("na::", "na::nb::", ""))));
1862 TEST(CompletionTest
, NoIndexCompletionsInsideClasses
) {
1863 auto Completions
= completions(
1866 int SomeNameOfField;
1867 typedef int SomeNameOfTypedefField;
1871 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")});
1873 EXPECT_THAT(Completions
.Completions
,
1874 AllOf(Contains(labeled("SomeNameOfField")),
1875 Contains(labeled("SomeNameOfTypedefField")),
1876 Not(Contains(labeled("SomeNameInTheIndex")))));
1879 TEST(CompletionTest
, NoIndexCompletionsInsideDependentCode
) {
1881 auto Completions
= completions(
1888 {func("::SomeNameInTheIndex")});
1890 EXPECT_THAT(Completions
.Completions
,
1891 Not(Contains(labeled("SomeNameInTheIndex"))));
1895 auto Completions
= completions(
1899 T::template Y<int>::^
1902 {func("::SomeNameInTheIndex")});
1904 EXPECT_THAT(Completions
.Completions
,
1905 Not(Contains(labeled("SomeNameInTheIndex"))));
1909 auto Completions
= completions(
1916 {func("::SomeNameInTheIndex")});
1918 EXPECT_THAT(Completions
.Completions
,
1919 Not(Contains(labeled("SomeNameInTheIndex"))));
1923 TEST(CompletionTest
, OverloadBundling
) {
1924 clangd::CodeCompleteOptions Opts
;
1925 Opts
.BundleOverloads
= true;
1927 std::string Context
= R
"cpp(
1929 // Overload with int
1930 int a(int) __attribute__((deprecated("", "")));
1931 // Overload with bool
1942 // Member completions are bundled.
1943 EXPECT_THAT(completions(Context
+ "int y = X().^", {}, Opts
).Completions
,
1944 UnorderedElementsAre(labeled("a(…)"), labeled("b(float)")));
1946 // Constructor completions are bundled.
1947 EXPECT_THAT(completions(Context
+ "X z = X^", {}, Opts
).Completions
,
1948 UnorderedElementsAre(labeled("X"), labeled("X(…)")));
1950 // Non-member completions are bundled, including index+sema.
1951 Symbol NoArgsGFunc
= func("GFuncC");
1953 completions(Context
+ "int y = GFunc^", {NoArgsGFunc
}, Opts
).Completions
,
1954 UnorderedElementsAre(labeled("GFuncC(…)"), labeled("GFuncD(int)")));
1956 // Differences in header-to-insert suppress bundling.
1957 std::string DeclFile
= URI::create(testPath("foo")).toString();
1958 NoArgsGFunc
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
1959 NoArgsGFunc
.IncludeHeaders
.emplace_back("<foo>", 1, Symbol::Include
);
1961 completions(Context
+ "int y = GFunc^", {NoArgsGFunc
}, Opts
).Completions
,
1962 UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")),
1963 labeled("GFuncC(int)"), labeled("GFuncD(int)")));
1965 // Examine a bundled completion in detail.
1967 completions(Context
+ "int y = X().a^", {}, Opts
).Completions
.front();
1968 EXPECT_EQ(A
.Name
, "a");
1969 EXPECT_EQ(A
.Signature
, "(…)");
1970 EXPECT_EQ(A
.BundleSize
, 2u);
1971 EXPECT_EQ(A
.Kind
, CompletionItemKind::Method
);
1972 EXPECT_EQ(A
.ReturnType
, "int"); // All overloads return int.
1973 // For now we just return one of the doc strings arbitrarily.
1974 ASSERT_TRUE(A
.Documentation
);
1975 ASSERT_FALSE(A
.Deprecated
); // Not all overloads deprecated.
1977 A
.Documentation
->asPlainText(),
1978 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool")));
1979 EXPECT_EQ(A
.SnippetSuffix
, "($0)");
1982 TEST(CompletionTest
, OverloadBundlingSameFileDifferentURI
) {
1983 clangd::CodeCompleteOptions Opts
;
1984 Opts
.BundleOverloads
= true;
1986 Symbol SymX
= sym("ns::X", index::SymbolKind::Function
, "@F@\\0#");
1987 Symbol SymY
= sym("ns::X", index::SymbolKind::Function
, "@F@\\0#I#");
1988 std::string BarHeader
= testPath("bar.h");
1989 auto BarURI
= URI::create(BarHeader
).toString();
1990 SymX
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
1991 SymY
.CanonicalDeclaration
.FileURI
= BarURI
.c_str();
1992 // The include header is different, but really it's the same file.
1993 SymX
.IncludeHeaders
.emplace_back("\"bar.h\"", 1, Symbol::Include
);
1994 SymY
.IncludeHeaders
.emplace_back(BarURI
.c_str(), 1, Symbol::Include
);
1996 auto Results
= completions("void f() { ::ns::^ }", {SymX
, SymY
}, Opts
);
1997 // Expect both results are bundled, despite the different-but-same
1999 ASSERT_EQ(1u, Results
.Completions
.size());
2000 const auto &R
= Results
.Completions
.front();
2001 EXPECT_EQ("X", R
.Name
);
2002 EXPECT_EQ(2u, R
.BundleSize
);
2005 TEST(CompletionTest
, DocumentationFromChangedFileCrash
) {
2007 auto FooH
= testPath("foo.h");
2008 auto FooCpp
= testPath("foo.cpp");
2009 FS
.Files
[FooH
] = R
"cpp(
2010 // this is my documentation comment.
2013 FS
.Files
[FooCpp
] = "";
2015 MockCompilationDatabase CDB
;
2016 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2018 Annotations
Source(R
"cpp(
2021 // This makes sure we have func from header in the AST.
2025 Server
.addDocument(FooCpp
, Source
.code(), "null", WantDiagnostics::Yes
);
2026 // We need to wait for preamble to build.
2027 ASSERT_TRUE(Server
.blockUntilIdleForTest());
2029 // Change the header file. Completion will reuse the old preamble!
2030 FS
.Files
[FooH
] = R
"cpp(
2034 clangd::CodeCompleteOptions Opts
;
2035 CodeCompleteResult Completions
=
2036 cantFail(runCodeComplete(Server
, FooCpp
, Source
.point(), Opts
));
2037 // We shouldn't crash. Unfortunately, current workaround is to not produce
2038 // comments for symbols from headers.
2039 EXPECT_THAT(Completions
.Completions
,
2040 Contains(AllOf(Not(isDocumented()), named("func"))));
2043 TEST(CompletionTest
, NonDocComments
) {
2044 const char *Text
= R
"cpp(
2045 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
2046 namespace comments_ns {
2049 // ------------------
2052 // A comment and a decl are separated by newlines.
2053 // Therefore, the comment shouldn't show up as doc comment.
2057 // this comment should be in the results.
2064 int comments_quux();
2068 // This comment should not be there.
2071 int Struct<T>::comments_qux() {
2074 // This comment **should** be in results.
2076 int Struct<T>::comments_quux() {
2081 // We should not get any of those comments in completion.
2083 completions(Text
).Completions
,
2084 UnorderedElementsAre(AllOf(Not(isDocumented()), named("comments_foo")),
2085 AllOf(isDocumented(), named("comments_baz")),
2086 AllOf(isDocumented(), named("comments_quux")),
2087 AllOf(Not(isDocumented()), named("comments_ns")),
2088 // FIXME(ibiryukov): the following items should have
2089 // empty documentation, since they are separated from
2090 // a comment with an empty line. Unfortunately, I
2091 // couldn't make Sema tests pass if we ignore those.
2092 AllOf(isDocumented(), named("comments_bar")),
2093 AllOf(isDocumented(), named("comments_qux"))));
2096 TEST(CompletionTest
, CompleteOnInvalidLine
) {
2097 auto FooCpp
= testPath("foo.cpp");
2099 MockCompilationDatabase CDB
;
2101 FS
.Files
[FooCpp
] = "// empty file";
2103 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2104 // Run completion outside the file range.
2108 EXPECT_THAT_EXPECTED(
2109 runCodeComplete(Server
, FooCpp
, Pos
, clangd::CodeCompleteOptions()),
2113 TEST(CompletionTest
, QualifiedNames
) {
2114 auto Results
= completions(
2116 namespace ns { int local; void both(); }
2117 void f() { ::ns::^ }
2119 {func("ns::both"), cls("ns::Index")});
2120 // We get results from both index and sema, with no duplicates.
2122 Results
.Completions
,
2123 UnorderedElementsAre(scope("ns::"), scope("ns::"), scope("ns::")));
2126 TEST(CompletionTest
, Render
) {
2130 C
.Signature
= "(bool) const";
2131 C
.SnippetSuffix
= "(${0:bool})";
2132 C
.ReturnType
= "int";
2133 C
.RequiredQualifier
= "Foo::";
2134 C
.Scope
= "ns::Foo::";
2135 C
.Documentation
.emplace();
2136 C
.Documentation
->addParagraph().appendText("This is ").appendCode("x()");
2137 C
.Includes
.emplace_back();
2138 auto &Include
= C
.Includes
.back();
2139 Include
.Header
= "\"foo.h\"";
2140 C
.Kind
= CompletionItemKind::Method
;
2141 C
.Score
.Total
= 1.0;
2142 C
.Score
.ExcludingName
= .5;
2143 C
.Origin
= SymbolOrigin::AST
| SymbolOrigin::Static
;
2145 CodeCompleteOptions Opts
;
2146 Opts
.IncludeIndicator
.Insert
= "^";
2147 Opts
.IncludeIndicator
.NoInsert
= "";
2148 Opts
.EnableSnippets
= false;
2150 auto R
= C
.render(Opts
);
2151 EXPECT_EQ(R
.label
, "Foo::x");
2152 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2153 EXPECT_EQ(R
.insertText
, "Foo::x");
2154 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::PlainText
);
2155 EXPECT_EQ(R
.filterText
, "x");
2156 EXPECT_EQ(R
.detail
, "int");
2157 EXPECT_EQ(R
.documentation
->value
, "From \"foo.h\"\nThis is x()");
2158 EXPECT_THAT(R
.additionalTextEdits
, IsEmpty());
2159 EXPECT_EQ(R
.sortText
, sortText(1.0, "x"));
2160 EXPECT_FALSE(R
.deprecated
);
2161 EXPECT_EQ(R
.score
, .5f
);
2163 C
.FilterText
= "xtra";
2165 EXPECT_EQ(R
.filterText
, "xtra");
2166 EXPECT_EQ(R
.sortText
, sortText(1.0, "xtra"));
2168 Opts
.EnableSnippets
= true;
2170 EXPECT_EQ(R
.insertText
, "Foo::x(${0:bool})");
2171 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::Snippet
);
2173 C
.SnippetSuffix
= "";
2175 EXPECT_EQ(R
.insertText
, "Foo::x");
2176 EXPECT_EQ(R
.insertTextFormat
, InsertTextFormat::PlainText
);
2178 Include
.Insertion
.emplace();
2180 EXPECT_EQ(R
.label
, "^Foo::x");
2181 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2182 EXPECT_THAT(R
.additionalTextEdits
, Not(IsEmpty()));
2184 Opts
.ShowOrigins
= true;
2186 EXPECT_EQ(R
.label
, "^[AS]Foo::x");
2187 EXPECT_EQ(R
.labelDetails
->detail
, "(bool) const");
2191 EXPECT_EQ(R
.detail
, "[2 overloads]");
2192 EXPECT_EQ(R
.documentation
->value
, "From \"foo.h\"\nThis is x()");
2194 C
.Deprecated
= true;
2196 EXPECT_TRUE(R
.deprecated
);
2198 Opts
.DocumentationFormat
= MarkupKind::Markdown
;
2200 EXPECT_EQ(R
.documentation
->value
, "From `\"foo.h\"` \nThis is `x()`");
2203 TEST(CompletionTest
, IgnoreRecoveryResults
) {
2204 auto Results
= completions(
2206 namespace ns { int NotRecovered() { return 0; } }
2208 // Sema enters recovery mode first and then normal mode.
2209 if (auto x = ns::NotRecover^)
2212 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(named("NotRecovered")));
2215 TEST(CompletionTest
, ScopeOfClassFieldInConstructorInitializer
) {
2216 auto Results
= completions(
2219 class X { public: X(); int x_; };
2223 EXPECT_THAT(Results
.Completions
,
2224 UnorderedElementsAre(AllOf(scope("ns::X::"), named("x_"))));
2227 // Like other class members, constructor init lists have to parse what's below,
2228 // after the completion point.
2229 // But recovering from an incomplete constructor init list is particularly
2230 // tricky because the bulk of the list is not surrounded by brackets.
2231 TEST(CompletionTest
, ConstructorInitListIncomplete
) {
2232 auto Results
= completions(
2241 EXPECT_THAT(Results
.Completions
, ElementsAre(named("xyz_")));
2243 Results
= completions(
2254 EXPECT_THAT(Results
.Completions
, ElementsAre(named("foo")));
2257 TEST(CompletionTest
, CodeCompletionContext
) {
2258 auto Results
= completions(
2261 class X { public: X(); int x_; };
2269 EXPECT_THAT(Results
.Context
, CodeCompletionContext::CCC_DotMemberAccess
);
2272 TEST(CompletionTest
, FixItForArrowToDot
) {
2274 MockCompilationDatabase CDB
;
2276 CodeCompleteOptions Opts
;
2277 Opts
.IncludeFixIts
= true;
2284 class ClassWithPtr {
2286 void MemberFunction();
2287 Auxilary* operator->() const;
2295 auto Results
= completions(Code
, {}, Opts
);
2296 EXPECT_EQ(Results
.Completions
.size(), 3u);
2298 TextEdit ReplacementEdit
;
2299 ReplacementEdit
.range
= Annotations(Code
).range();
2300 ReplacementEdit
.newText
= ".";
2301 for (const auto &C
: Results
.Completions
) {
2302 EXPECT_TRUE(C
.FixIts
.size() == 1u || C
.Name
== "AuxFunction");
2303 if (!C
.FixIts
.empty()) {
2304 EXPECT_THAT(C
.FixIts
, ElementsAre(ReplacementEdit
));
2309 TEST(CompletionTest
, FixItForDotToArrow
) {
2310 CodeCompleteOptions Opts
;
2311 Opts
.IncludeFixIts
= true;
2318 class ClassWithPtr {
2320 void MemberFunction();
2321 Auxilary* operator->() const;
2329 auto Results
= completions(Code
, {}, Opts
);
2330 EXPECT_EQ(Results
.Completions
.size(), 3u);
2332 TextEdit ReplacementEdit
;
2333 ReplacementEdit
.range
= Annotations(Code
).range();
2334 ReplacementEdit
.newText
= "->";
2335 for (const auto &C
: Results
.Completions
) {
2336 EXPECT_TRUE(C
.FixIts
.empty() || C
.Name
== "AuxFunction");
2337 if (!C
.FixIts
.empty()) {
2338 EXPECT_THAT(C
.FixIts
, ElementsAre(ReplacementEdit
));
2343 TEST(CompletionTest
, RenderWithFixItMerged
) {
2345 FixIt
.range
.end
.character
= 5;
2346 FixIt
.newText
= "->";
2350 C
.RequiredQualifier
= "Foo::";
2352 C
.CompletionTokenRange
.start
.character
= 5;
2354 CodeCompleteOptions Opts
;
2355 Opts
.IncludeFixIts
= true;
2357 auto R
= C
.render(Opts
);
2358 EXPECT_TRUE(R
.textEdit
);
2359 EXPECT_EQ(R
.textEdit
->newText
, "->Foo::x");
2360 EXPECT_TRUE(R
.additionalTextEdits
.empty());
2363 TEST(CompletionTest
, RenderWithFixItNonMerged
) {
2365 FixIt
.range
.end
.character
= 4;
2366 FixIt
.newText
= "->";
2370 C
.RequiredQualifier
= "Foo::";
2372 C
.CompletionTokenRange
.start
.character
= 5;
2374 CodeCompleteOptions Opts
;
2375 Opts
.IncludeFixIts
= true;
2377 auto R
= C
.render(Opts
);
2378 EXPECT_TRUE(R
.textEdit
);
2379 EXPECT_EQ(R
.textEdit
->newText
, "Foo::x");
2380 EXPECT_THAT(R
.additionalTextEdits
, UnorderedElementsAre(FixIt
));
2383 TEST(CompletionTest
, CompletionTokenRange
) {
2385 MockCompilationDatabase CDB
;
2387 TU
.AdditionalFiles
["foo/abc/foo.h"] = "";
2389 constexpr const char *TestCodes
[] = {
2411 #include "foo
/[[a
^/]]foo
.h
"
2414 #include "foo
/abc
/[[fo
^o
.h
"]]
2417 for (const auto &Text
: TestCodes
) {
2418 Annotations
TestCode(Text
);
2419 TU
.Code
= TestCode
.code().str();
2420 auto Results
= completions(TU
, TestCode
.point());
2421 if (Results
.Completions
.size() != 1) {
2422 ADD_FAILURE() << "Results.Completions.size() != 1" << Text
;
2425 EXPECT_THAT(Results
.Completions
.front().CompletionTokenRange
,
2430 TEST(SignatureHelpTest
, OverloadsOrdering
) {
2431 const auto Results
= signatures(R
"cpp(
2433 void foo(int x, float y);
2434 void foo(float x, int y);
2435 void foo(float x, float y);
2436 void foo(int x, int y = 0);
2437 int main() { foo(^); }
2439 EXPECT_THAT(Results
.signatures
,
2440 ElementsAre(sig("foo([[int x]]) -> void"),
2441 sig("foo([[int x]], [[int y = 0]]) -> void"),
2442 sig("foo([[float x]], [[int y]]) -> void"),
2443 sig("foo([[int x]], [[float y]]) -> void"),
2444 sig("foo([[float x]], [[float y]]) -> void")));
2445 // We always prefer the first signature.
2446 EXPECT_EQ(0, Results
.activeSignature
);
2447 EXPECT_EQ(0, Results
.activeParameter
);
2450 TEST(SignatureHelpTest
, InstantiatedSignatures
) {
2451 StringRef Sig0
= R
"cpp(
2460 EXPECT_THAT(signatures(Sig0
).signatures
,
2461 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2463 StringRef Sig1
= R
"cpp(
2471 EXPECT_THAT(signatures(Sig1
).signatures
,
2472 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2474 StringRef Sig2
= R
"cpp(
2475 template <class ...T>
2483 EXPECT_THAT(signatures(Sig2
).signatures
,
2484 ElementsAre(sig("foo([[T...]]) -> void")));
2486 // It is debatable whether we should substitute the outer template parameter
2487 // ('T') in that case. Currently we don't substitute it in signature help, but
2488 // do substitute in code complete.
2489 // FIXME: make code complete and signature help consistent, figure out which
2491 StringRef Sig3
= R
"cpp(
2499 X<int>().foo<double>(^)
2503 EXPECT_THAT(signatures(Sig3
).signatures
,
2504 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2507 TEST(SignatureHelpTest
, IndexDocumentation
) {
2508 Symbol Foo0
= sym("foo", index::SymbolKind::Function
, "@F@\\0#");
2509 Foo0
.Documentation
= "doc from the index";
2510 Symbol Foo1
= sym("foo", index::SymbolKind::Function
, "@F@\\0#I#");
2511 Foo1
.Documentation
= "doc from the index";
2512 Symbol Foo2
= sym("foo", index::SymbolKind::Function
, "@F@\\0#I#I#");
2514 StringRef Sig0
= R
"cpp(
2524 signatures(Sig0
, {Foo0
}).signatures
,
2525 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2526 AllOf(sig("foo([[double]]) -> int"), sigDoc(""))));
2528 StringRef Sig1
= R
"cpp(
2530 // Overriden doc from sema
2541 signatures(Sig1
, {Foo0
, Foo1
, Foo2
}).signatures
,
2543 AllOf(sig("foo() -> int"), sigDoc("doc from the index")),
2544 AllOf(sig("foo([[int]]) -> int"), sigDoc("Overriden doc from sema")),
2545 AllOf(sig("foo([[int]], [[int]]) -> int"), sigDoc("doc from sema"))));
2548 TEST(SignatureHelpTest
, DynamicIndexDocumentation
) {
2550 MockCompilationDatabase CDB
;
2551 ClangdServer::Options Opts
= ClangdServer::optsForTest();
2552 Opts
.BuildDynamicSymbolIndex
= true;
2553 ClangdServer
Server(CDB
, FS
, Opts
);
2555 FS
.Files
[testPath("foo.h")] = R
"cpp(
2561 Annotations
FileContent(R
"cpp(
2568 auto File
= testPath("test.cpp");
2569 Server
.addDocument(File
, FileContent
.code());
2570 // Wait for the dynamic index being built.
2571 ASSERT_TRUE(Server
.blockUntilIdleForTest());
2572 EXPECT_THAT(llvm::cantFail(runSignatureHelp(Server
, File
, FileContent
.point(),
2573 MarkupKind::PlainText
))
2575 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
2578 TEST(CompletionTest
, CompletionFunctionArgsDisabled
) {
2579 CodeCompleteOptions Opts
;
2580 Opts
.EnableSnippets
= true;
2581 Opts
.EnableFunctionArgSnippets
= false;
2584 auto Results
= completions(
2587 void xfoo(int x, int y);
2588 void f() { xfo^ })cpp",
2591 Results
.Completions
,
2592 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("()")),
2593 AllOf(named("xfoo"), snippetSuffix("($0)"))));
2596 auto Results
= completions(
2599 void f() { xba^ })cpp",
2601 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(AllOf(
2602 named("xbar"), snippetSuffix("()"))));
2605 Opts
.BundleOverloads
= true;
2606 auto Results
= completions(
2609 void xfoo(int x, int y);
2610 void f() { xfo^ })cpp",
2613 Results
.Completions
,
2614 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("($0)"))));
2617 auto Results
= completions(
2619 template <class T, class U>
2620 void xfoo(int a, U b);
2621 void f() { xfo^ })cpp",
2624 Results
.Completions
,
2625 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("<$1>($0)"))));
2628 auto Results
= completions(
2633 using foo_alias = T**;
2634 void f() { foo_^ })cpp",
2637 Results
.Completions
,
2638 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")),
2639 AllOf(named("foo_alias"), snippetSuffix("<$0>"))));
2642 auto Results
= completions(
2644 #define FOO(x, y) x##f
2647 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(AllOf(
2648 named("FOO"), snippetSuffix("($0)"))));
2652 TEST(CompletionTest
, SuggestOverrides
) {
2653 constexpr const char *const Text(R
"cpp(
2656 virtual void vfunc(bool param);
2657 virtual void vfunc(bool param, int p);
2658 void func(bool param);
2660 class B : public A {
2661 virtual void ttt(bool param) const;
2662 void vfunc(bool param, int p) override;
2664 class C : public B {
2666 void vfunc(bool param) override;
2670 const auto Results
= completions(Text
);
2672 Results
.Completions
,
2673 AllOf(Contains(AllOf(labeled("void vfunc(bool param, int p) override"),
2674 nameStartsWith("vfunc"))),
2675 Contains(AllOf(labeled("void ttt(bool param) const override"),
2676 nameStartsWith("ttt"))),
2677 Not(Contains(labeled("void vfunc(bool param) override")))));
2680 TEST(CompletionTest
, OverridesNonIdentName
) {
2681 // Check the completions call does not crash.
2684 virtual ~Base() = 0;
2685 virtual operator int() = 0;
2686 virtual Base& operator+(Base&) = 0;
2689 struct Derived : Base {
2695 TEST(CompletionTest
, NoCrashOnMissingNewLineAtEOF
) {
2696 auto FooCpp
= testPath("foo.cpp");
2698 MockCompilationDatabase CDB
;
2700 Annotations
F("#pragma ^ // no new line");
2701 FS
.Files
[FooCpp
] = F
.code().str();
2702 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2703 runAddDocument(Server
, FooCpp
, F
.code());
2704 // Run completion outside the file range.
2705 EXPECT_THAT(cantFail(runCodeComplete(Server
, FooCpp
, F
.point(),
2706 clangd::CodeCompleteOptions()))
2709 EXPECT_THAT(cantFail(runSignatureHelp(Server
, FooCpp
, F
.point(),
2710 MarkupKind::PlainText
))
2715 TEST(GuessCompletionPrefix
, Filters
) {
2716 for (llvm::StringRef Case
: {
2717 "[[scope::]][[ident]]^",
2726 "some text [[scope::more::]][[identif]]^ier",
2727 "some text [[scope::]][[mor]]^e::identifier",
2728 "weird case foo::[[::bar::]][[baz]]^",
2731 Annotations
F(Case
);
2732 auto Offset
= cantFail(positionToOffset(F
.code(), F
.point()));
2733 auto ToStringRef
= [&](Range R
) {
2734 return F
.code().slice(cantFail(positionToOffset(F
.code(), R
.start
)),
2735 cantFail(positionToOffset(F
.code(), R
.end
)));
2737 auto WantQualifier
= ToStringRef(F
.ranges()[0]),
2738 WantName
= ToStringRef(F
.ranges()[1]);
2740 auto Prefix
= guessCompletionPrefix(F
.code(), Offset
);
2741 // Even when components are empty, check their offsets are correct.
2742 EXPECT_EQ(WantQualifier
, Prefix
.Qualifier
) << Case
;
2743 EXPECT_EQ(WantQualifier
.begin(), Prefix
.Qualifier
.begin()) << Case
;
2744 EXPECT_EQ(WantName
, Prefix
.Name
) << Case
;
2745 EXPECT_EQ(WantName
.begin(), Prefix
.Name
.begin()) << Case
;
2749 TEST(CompletionTest
, EnableSpeculativeIndexRequest
) {
2751 MockCompilationDatabase CDB
;
2752 ClangdServer
Server(CDB
, FS
, ClangdServer::optsForTest());
2754 auto File
= testPath("foo.cpp");
2755 Annotations
Test(R
"cpp(
2756 namespace ns1 { int abc; }
2757 namespace ns2 { int abc; }
2758 void f() { ns1::ab$1^; ns1::ab$2^; }
2759 void f2() { ns2::ab$3^; }
2761 runAddDocument(Server
, File
, Test
.code());
2762 clangd::CodeCompleteOptions Opts
= {};
2764 IndexRequestCollector Requests
;
2765 Opts
.Index
= &Requests
;
2767 auto CompleteAtPoint
= [&](StringRef P
) {
2768 auto CCR
= cantFail(runCodeComplete(Server
, File
, Test
.point(P
), Opts
));
2769 EXPECT_TRUE(CCR
.HasMore
);
2772 CompleteAtPoint("1");
2773 auto Reqs1
= Requests
.consumeRequests(1);
2774 ASSERT_EQ(Reqs1
.size(), 1u);
2775 EXPECT_THAT(Reqs1
[0].Scopes
, UnorderedElementsAre("ns1::"));
2777 CompleteAtPoint("2");
2778 auto Reqs2
= Requests
.consumeRequests(1);
2779 // Speculation succeeded. Used speculative index result.
2780 ASSERT_EQ(Reqs2
.size(), 1u);
2781 EXPECT_EQ(Reqs2
[0], Reqs1
[0]);
2783 CompleteAtPoint("3");
2784 // Speculation failed. Sent speculative index request and the new index
2785 // request after sema.
2786 auto Reqs3
= Requests
.consumeRequests(2);
2787 ASSERT_EQ(Reqs3
.size(), 2u);
2790 TEST(CompletionTest
, InsertTheMostPopularHeader
) {
2791 std::string DeclFile
= URI::create(testPath("foo")).toString();
2792 Symbol Sym
= func("Func");
2793 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2794 Sym
.IncludeHeaders
.emplace_back("\"foo.h\"", 2, Symbol::Include
);
2795 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000, Symbol::Include
);
2797 auto Results
= completions("Fun^", {Sym
}).Completions
;
2798 assert(!Results
.empty());
2799 EXPECT_THAT(Results
[0], AllOf(named("Func"), insertInclude("\"bar.h\"")));
2800 EXPECT_EQ(Results
[0].Includes
.size(), 2u);
2803 TEST(CompletionTest
, InsertIncludeOrImport
) {
2804 std::string DeclFile
= URI::create(testPath("foo")).toString();
2805 Symbol Sym
= func("Func");
2806 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2807 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000,
2808 Symbol::Include
| Symbol::Import
);
2809 CodeCompleteOptions Opts
;
2810 // Should only take effect in import contexts.
2811 Opts
.ImportInsertions
= true;
2812 auto Results
= completions("Fun^", {Sym
}, Opts
).Completions
;
2813 assert(!Results
.empty());
2814 EXPECT_THAT(Results
[0],
2815 AllOf(named("Func"), insertIncludeText("#include \"bar.h\"\n")));
2818 Signals
.InsertionDirective
= Symbol::IncludeDirective::Import
;
2819 Opts
.MainFileSignals
= &Signals
;
2820 Results
= completions("Fun^", {Sym
}, Opts
, "Foo.m").Completions
;
2821 assert(!Results
.empty());
2822 EXPECT_THAT(Results
[0],
2823 AllOf(named("Func"), insertIncludeText("#import \"bar.h\"\n")));
2825 Sym
.IncludeHeaders
[0].SupportedDirectives
= Symbol::Import
;
2826 Results
= completions("Fun^", {Sym
}).Completions
;
2827 assert(!Results
.empty());
2828 EXPECT_THAT(Results
[0], AllOf(named("Func"), Not(insertInclude())));
2831 TEST(CompletionTest
, NoInsertIncludeIfOnePresent
) {
2832 Annotations
Test(R
"cpp(
2836 auto TU
= TestTU::withCode(Test
.code());
2837 TU
.AdditionalFiles
["foo.h"] = "";
2839 std::string DeclFile
= URI::create(testPath("foo")).toString();
2840 Symbol Sym
= func("Func");
2841 Sym
.CanonicalDeclaration
.FileURI
= DeclFile
.c_str();
2842 Sym
.IncludeHeaders
.emplace_back("\"foo.h\"", 2, Symbol::Include
);
2843 Sym
.IncludeHeaders
.emplace_back("\"bar.h\"", 1000, Symbol::Include
);
2845 EXPECT_THAT(completions(TU
, Test
.point(), {Sym
}).Completions
,
2846 UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""),
2847 Not(insertInclude()))));
2850 TEST(CompletionTest
, MergeMacrosFromIndexAndSema
) {
2852 Sym
.Name
= "Clangd_Macro_Test";
2853 Sym
.ID
= SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test");
2854 Sym
.SymInfo
.Kind
= index::SymbolKind::Macro
;
2855 Sym
.Flags
|= Symbol::IndexedForCodeCompletion
;
2856 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym
})
2858 UnorderedElementsAre(named("Clangd_Macro_Test")));
2861 TEST(CompletionTest
, MacroFromPreamble
) {
2862 Annotations
Test(R
"cpp(#define CLANGD_PREAMBLE_MAIN x
2865 #define CLANGD_MAIN x
2866 void f() { CLANGD_^ }
2868 auto TU
= TestTU::withCode(Test
.code());
2869 TU
.HeaderCode
= "#define CLANGD_PREAMBLE_HEADER x";
2870 auto Results
= completions(TU
, Test
.point(), {func("CLANGD_INDEX")});
2871 // We should get results from the main file, including the preamble section.
2872 // However no results from included files (the index should cover them).
2873 EXPECT_THAT(Results
.Completions
,
2874 UnorderedElementsAre(named("CLANGD_PREAMBLE_MAIN"),
2875 named("CLANGD_MAIN"),
2876 named("CLANGD_INDEX")));
2879 TEST(CompletionTest
, DeprecatedResults
) {
2880 std::string Body
= R
"cpp(
2882 void TestClangc() __attribute__((deprecated("", "")));
2886 completions(Body
+ "int main() { TestClang^ }").Completions
,
2887 UnorderedElementsAre(AllOf(named("TestClangd"), Not(deprecated())),
2888 AllOf(named("TestClangc"), deprecated())));
2891 TEST(SignatureHelpTest
, PartialSpec
) {
2892 const auto Results
= signatures(R
"cpp(
2893 template <typename T> struct Foo {};
2894 template <typename T> struct Foo<T*> { Foo(T); };
2895 Foo<int*> F(^);)cpp");
2896 EXPECT_THAT(Results
.signatures
, Contains(sig("Foo([[T]])")));
2897 EXPECT_EQ(0, Results
.activeParameter
);
2900 TEST(SignatureHelpTest
, InsideArgument
) {
2902 const auto Results
= signatures(R
"cpp(
2904 void foo(int x, int y);
2905 int main() { foo(1+^); }
2907 EXPECT_THAT(Results
.signatures
,
2908 ElementsAre(sig("foo([[int x]]) -> void"),
2909 sig("foo([[int x]], [[int y]]) -> void")));
2910 EXPECT_EQ(0, Results
.activeParameter
);
2913 const auto Results
= signatures(R
"cpp(
2915 void foo(int x, int y);
2916 int main() { foo(1^); }
2918 EXPECT_THAT(Results
.signatures
,
2919 ElementsAre(sig("foo([[int x]]) -> void"),
2920 sig("foo([[int x]], [[int y]]) -> void")));
2921 EXPECT_EQ(0, Results
.activeParameter
);
2924 const auto Results
= signatures(R
"cpp(
2926 void foo(int x, int y);
2927 int main() { foo(1^0); }
2929 EXPECT_THAT(Results
.signatures
,
2930 ElementsAre(sig("foo([[int x]]) -> void"),
2931 sig("foo([[int x]], [[int y]]) -> void")));
2932 EXPECT_EQ(0, Results
.activeParameter
);
2935 const auto Results
= signatures(R
"cpp(
2937 void foo(int x, int y);
2938 int bar(int x, int y);
2939 int main() { bar(foo(2, 3^)); }
2941 EXPECT_THAT(Results
.signatures
,
2942 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
2943 EXPECT_EQ(1, Results
.activeParameter
);
2947 TEST(SignatureHelpTest
, ConstructorInitializeFields
) {
2949 const auto Results
= signatures(R
"cpp(
2950 struct A { A(int); };
2956 EXPECT_THAT(Results
.signatures
,
2957 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2958 sig("A([[const A &]])")));
2961 const auto Results
= signatures(R
"cpp(
2962 struct A { A(int); };
2968 // FIXME: currently the parser skips over the decl of a_elem as part of the
2969 // (broken) init list, so we don't get signatures for the first member.
2970 EXPECT_THAT(Results
.signatures
, IsEmpty());
2973 const auto Results
= signatures(R
"cpp(
2974 struct A { A(int); };
2981 EXPECT_THAT(Results
.signatures
,
2982 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
2983 sig("A([[const A &]])")));
2986 const auto Results
= signatures(R
"cpp(
2995 B() : c_elem(A(1^)) {}
2999 EXPECT_THAT(Results
.signatures
,
3000 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"),
3001 sig("A([[const A &]])")));
3005 TEST(SignatureHelpTest
, Variadic
) {
3006 const std::string Header
= R
"cpp(
3007 void fun(int x, ...) {}
3009 const std::string ExpectedSig
= "fun([[int x]], [[...]]) -> void";
3012 const auto Result
= signatures(Header
+ "fun(^);}");
3013 EXPECT_EQ(0, Result
.activeParameter
);
3014 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3017 const auto Result
= signatures(Header
+ "fun(1, ^);}");
3018 EXPECT_EQ(1, Result
.activeParameter
);
3019 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3022 const auto Result
= signatures(Header
+ "fun(1, 2, ^);}");
3023 EXPECT_EQ(1, Result
.activeParameter
);
3024 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3028 TEST(SignatureHelpTest
, VariadicTemplate
) {
3029 const std::string Header
= R
"cpp(
3030 template<typename T, typename ...Args>
3031 void fun(T t, Args ...args) {}
3033 const std::string ExpectedSig
= "fun([[T t]], [[Args args...]]) -> void";
3036 const auto Result
= signatures(Header
+ "fun(^);}");
3037 EXPECT_EQ(0, Result
.activeParameter
);
3038 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3041 const auto Result
= signatures(Header
+ "fun(1, ^);}");
3042 EXPECT_EQ(1, Result
.activeParameter
);
3043 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3046 const auto Result
= signatures(Header
+ "fun(1, 2, ^);}");
3047 EXPECT_EQ(1, Result
.activeParameter
);
3048 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3052 TEST(SignatureHelpTest
, VariadicMethod
) {
3053 const std::string Header
= R
"cpp(
3055 template<typename T, typename ...Args>
3056 void fun(T t, Args ...args) {}
3058 void test() {C c; )cpp";
3059 const std::string ExpectedSig
= "fun([[T t]], [[Args args...]]) -> void";
3062 const auto Result
= signatures(Header
+ "c.fun(^);}");
3063 EXPECT_EQ(0, Result
.activeParameter
);
3064 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3067 const auto Result
= signatures(Header
+ "c.fun(1, ^);}");
3068 EXPECT_EQ(1, Result
.activeParameter
);
3069 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3072 const auto Result
= signatures(Header
+ "c.fun(1, 2, ^);}");
3073 EXPECT_EQ(1, Result
.activeParameter
);
3074 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3078 TEST(SignatureHelpTest
, VariadicType
) {
3079 const std::string Header
= R
"cpp(
3080 void fun(int x, ...) {}
3081 auto get_fun() { return fun; }
3084 const std::string ExpectedSig
= "([[int]], [[...]]) -> void";
3087 const auto Result
= signatures(Header
+ "get_fun()(^);}");
3088 EXPECT_EQ(0, Result
.activeParameter
);
3089 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3092 const auto Result
= signatures(Header
+ "get_fun()(1, ^);}");
3093 EXPECT_EQ(1, Result
.activeParameter
);
3094 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3097 const auto Result
= signatures(Header
+ "get_fun()(1, 2, ^);}");
3098 EXPECT_EQ(1, Result
.activeParameter
);
3099 EXPECT_THAT(Result
.signatures
, UnorderedElementsAre(sig(ExpectedSig
)));
3103 TEST(CompletionTest
, IncludedCompletionKinds
) {
3104 Annotations
Test(R
"cpp(#include "^)cpp
");
3105 auto TU = TestTU::withCode(Test.code());
3106 TU.AdditionalFiles["sub
/bar
.h
"] = "";
3107 TU.ExtraArgs.push_back("-I
" + testPath("sub
"));
3109 auto Results = completions(TU, Test.point());
3110 EXPECT_THAT(Results.Completions,
3111 AllOf(has("sub
/", CompletionItemKind::Folder),
3112 has("bar
.h
\"", CompletionItemKind::File)));
3115 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3122 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3123 clangd::CodeCompleteOptions Opts = {};
3124 Opts.AllScopes = true;
3126 auto Results = completions(
3128 void f() { na::Clangd
^ }
3130 {cls("na::ClangdA
"), cls("nx::ClangdX
"), cls("Clangd3
")}, Opts);
3131 EXPECT_THAT(Results.Completions,
3132 UnorderedElementsAre(
3133 AllOf(qualifier(""), scope("na::"), named("ClangdA
"))));
3136 TEST(CompletionTest, AllScopesCompletion) {
3137 clangd::CodeCompleteOptions Opts = {};
3138 Opts.AllScopes = true;
3140 auto Results = completions(
3143 void f() { Clangd
^ }
3146 {cls("nx::Clangd1
"), cls("ny::Clangd2
"), cls("Clangd3
"),
3147 cls("na::nb::Clangd4
"), enmConstant("na::C::Clangd5
")},
3150 Results.Completions,
3151 UnorderedElementsAre(AllOf(qualifier("nx::"), named("Clangd1
"),
3152 kind(CompletionItemKind::Class)),
3153 AllOf(qualifier("ny::"), named("Clangd2
"),
3154 kind(CompletionItemKind::Class)),
3155 AllOf(qualifier(""), scope(""), named("Clangd3
"),
3156 kind(CompletionItemKind::Class)),
3157 AllOf(qualifier("nb::"), named("Clangd4
"),
3158 kind(CompletionItemKind::Class)),
3159 AllOf(qualifier("C::"), named("Clangd5
"),
3160 kind(CompletionItemKind::EnumMember))));
3163 TEST(CompletionTest, NoQualifierIfShadowed) {
3164 clangd::CodeCompleteOptions Opts = {};
3165 Opts.AllScopes = true;
3167 auto Results = completions(R"cpp(
3168 namespace nx
{ class Clangd1
{}; }
3170 void f() { Clangd
^ }
3172 {cls("nx::Clangd1
"), cls("nx::Clangd2
")}, Opts);
3173 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and
3174 // needs no qualifier.
3175 EXPECT_THAT(Results.Completions,
3176 UnorderedElementsAre(AllOf(qualifier(""), named("Clangd1
")),
3177 AllOf(qualifier("nx::"), named("Clangd2
"))));
3180 TEST(CompletionTest, NoCompletionsForNewNames) {
3181 clangd::CodeCompleteOptions Opts;
3182 Opts.AllScopes = true;
3183 auto Results = completions(R"cpp(
3186 {cls("naber
"), cls("nx::naber
")}, Opts);
3187 EXPECT_THAT(Results.Completions, UnorderedElementsAre());
3190 TEST(CompletionTest, Lambda) {
3191 clangd::CodeCompleteOptions Opts = {};
3193 auto Results = completions(R"cpp(
3195 auto Lambda
= [](int a
, const double &b
) {return 1.f
;};
3201 ASSERT_EQ(Results.Completions.size(), 1u);
3202 const auto &A = Results.Completions.front();
3203 EXPECT_EQ(A.Name, "Lambda
");
3204 EXPECT_EQ(A.Signature, "(int a
, const double &b
) const");
3205 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3206 EXPECT_EQ(A.ReturnType, "float");
3207 EXPECT_EQ(A.SnippetSuffix, "($
{1:int a
}, $
{2:const double &b
})");
3210 TEST(CompletionTest, StructuredBinding) {
3211 clangd::CodeCompleteOptions Opts = {};
3213 auto Results = completions(R"cpp(
3215 using Float
= float;
3220 const auto &[xxx
, yyy
] = S
{};
3226 ASSERT_EQ(Results.Completions.size(), 1u);
3227 const auto &A = Results.Completions.front();
3228 EXPECT_EQ(A.Name, "yyy
");
3229 EXPECT_EQ(A.Kind, CompletionItemKind::Variable);
3230 EXPECT_EQ(A.ReturnType, "const Float
");
3233 TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3234 auto Results = completions(R"objc(
3236 @
property(nonatomic
, setter
=setXToIgnoreComplete
:) int value
;
3238 Foo
*foo
= [Foo
new]; int y
= [foo v
^]
3240 /*IndexSymbols=*/{},
3241 /*Opts=*/{}, "Foo
.m
");
3243 auto C = Results.Completions;
3244 EXPECT_THAT(C, ElementsAre(named("value
")));
3245 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3246 EXPECT_THAT(C, ElementsAre(returnType("int")));
3247 EXPECT_THAT(C, ElementsAre(signature("")));
3248 EXPECT_THAT(C, ElementsAre(snippetSuffix("")));
3251 TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3252 auto Results = completions(R"objc(
3254 - (int)valueForCharacter
:(char)c
;
3256 Foo
*foo
= [Foo
new]; int y
= [foo v
^]
3258 /*IndexSymbols=*/{},
3259 /*Opts=*/{}, "Foo
.m
");
3261 auto C = Results.Completions;
3262 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3263 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3264 EXPECT_THAT(C, ElementsAre(returnType("int")));
3265 EXPECT_THAT(C, ElementsAre(signature("(char)")));
3266 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(char)}")));
3269 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3270 auto Results = completions(R"objc(
3272 + (id
)fooWithValue
:(int)value fooey
:(unsigned int)fooey
;
3276 /*IndexSymbols=*/{},
3277 /*Opts=*/{}, "Foo
.m
");
3279 auto C = Results.Completions;
3280 EXPECT_THAT(C, ElementsAre(named("fooWithValue
:")));
3281 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3282 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3283 EXPECT_THAT(C, ElementsAre(signature("(int) fooey
:(unsigned int)")));
3285 C, ElementsAre(snippetSuffix("$
{1:(int)} fooey
:$
{2:(unsigned int)}")));
3288 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3289 auto Results = completions(R"objc(
3291 + (id
)fooWithValue
:(int)value fooey
:(unsigned int)fooey
;
3293 id val
= [Foo fooWithValue
:10 f
^]
3295 /*IndexSymbols=*/{},
3296 /*Opts=*/{}, "Foo
.m
");
3298 auto C = Results.Completions;
3299 EXPECT_THAT(C, ElementsAre(named("fooey
:")));
3300 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3301 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3302 EXPECT_THAT(C, ElementsAre(signature("(unsigned int)")));
3303 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(unsigned int)}")));
3306 TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3307 auto Results = completions(R"objc(
3309 + (id
)player
:(id
)player willRun
:(id
)run
;
3313 /*IndexSymbols=*/{},
3314 /*Opts=*/{}, "Foo
.m
");
3316 auto C = Results.Completions;
3317 EXPECT_THAT(C, ElementsAre(named("player
:")));
3318 EXPECT_THAT(C, ElementsAre(filterText("player
:willRun
:")));
3319 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3320 EXPECT_THAT(C, ElementsAre(returnType("id
")));
3321 EXPECT_THAT(C, ElementsAre(signature("(id
) willRun
:(id
)")));
3322 EXPECT_THAT(C, ElementsAre(snippetSuffix("$
{1:(id
)} willRun
:$
{2:(id
)}")));
3325 TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3326 auto Results = completions(R"objc(
3334 /*IndexSymbols=*/{},
3335 /*Opts=*/{}, "Foo
.m
");
3337 auto C = Results.Completions;
3338 EXPECT_THAT(C, ElementsAre(named("foo
")));
3339 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3340 EXPECT_THAT(C, ElementsAre(qualifier("- (void)")));
3343 TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3344 auto Results = completions(R"objc(
3346 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3352 /*IndexSymbols=*/{},
3353 /*Opts=*/{}, "Foo
.m
");
3355 auto C = Results.Completions;
3356 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3357 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3358 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3359 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument
:(id
)object
")));
3362 TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3363 auto Results = completions(R"objc(
3365 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3371 /*IndexSymbols=*/{},
3372 /*Opts=*/{}, "Foo
.m
");
3374 auto C = Results.Completions;
3375 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3376 EXPECT_THAT(C, ElementsAre(filterText("valueForCharacter
:secondArgument
:")));
3377 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3378 EXPECT_THAT(C, ElementsAre(qualifier("- (int)")));
3379 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument
:(id
)object
")));
3382 TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3383 auto Results = completions(R"objc(
3385 - (int)valueForCharacter
:(char)c
;
3391 /*IndexSymbols=*/{},
3392 /*Opts=*/{}, "Foo
.m
");
3394 auto C = Results.Completions;
3395 EXPECT_THAT(C, ElementsAre(named("valueForCharacter
:")));
3396 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3397 EXPECT_THAT(C, ElementsAre(signature("(char)c
")));
3400 TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3401 auto Results = completions(R"objc(
3403 - (int)valueForCharacter
:(char)c secondArgument
:(id
)object
;
3406 - (int)valueForCharacter
:(char)c second
^
3409 /*IndexSymbols=*/{},
3410 /*Opts=*/{}, "Foo
.m
");
3412 auto C = Results.Completions;
3413 EXPECT_THAT(C, ElementsAre(named("secondArgument
:")));
3414 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method)));
3415 EXPECT_THAT(C, ElementsAre(signature("(id
)object
")));
3418 TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3419 Symbol FoodClass = objcClass("FoodClass
");
3420 Symbol SymFood = objcProtocol("Food
");
3421 Symbol SymFooey = objcProtocol("Fooey
");
3422 auto Results = completions("id
<Foo
^>", {SymFood, FoodClass, SymFooey},
3423 /*Opts=*/{}, "Foo
.m
");
3425 // Should only give protocols for ObjC protocol completions.
3426 EXPECT_THAT(Results.Completions,
3427 UnorderedElementsAre(
3428 AllOf(named("Food
"), kind(CompletionItemKind::Interface)),
3429 AllOf(named("Fooey
"), kind(CompletionItemKind::Interface))));
3431 Results = completions("Fo
^", {SymFood, FoodClass, SymFooey},
3432 /*Opts=*/{}, "Foo
.m
");
3433 // Shouldn't give protocols for non protocol completions.
3435 Results.Completions,
3436 ElementsAre(AllOf(named("FoodClass
"), kind(CompletionItemKind::Class))));
3439 TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3441 MockCompilationDatabase CDB;
3442 ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
3444 auto File = testPath("Foo
.m
");
3445 Annotations Test(R"cpp(
3451 runAddDocument(Server, File, Test.code());
3452 clangd::CodeCompleteOptions Opts = {};
3454 Symbol FoodClass = objcClass("FoodClass
");
3455 IndexRequestCollector Requests({FoodClass});
3456 Opts.Index = &Requests;
3458 auto CompleteAtPoint = [&](StringRef P) {
3459 return cantFail(runCodeComplete(Server, File, Test.point(P), Opts))
3463 auto C = CompleteAtPoint("1");
3464 auto Reqs1 = Requests.consumeRequests(1);
3465 ASSERT_EQ(Reqs1.size(), 1u);
3466 EXPECT_THAT(C, ElementsAre(AllOf(named("Food
"),
3467 kind(CompletionItemKind::Interface))));
3469 C = CompleteAtPoint("2");
3470 auto Reqs2 = Requests.consumeRequests(1);
3471 // Speculation succeeded. Used speculative index result, but filtering now to
3472 // now include FoodClass.
3473 ASSERT_EQ(Reqs2.size(), 1u);
3474 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3475 EXPECT_THAT(C, ElementsAre(AllOf(named("FoodClass
"),
3476 kind(CompletionItemKind::Class))));
3479 TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3480 Symbol FoodCategory = objcCategory("FoodClass
", "Extension
");
3481 auto Results = completions(R"objc(
3488 /*Opts=*/{}, "Foo
.m
");
3489 EXPECT_THAT(Results.Completions, IsEmpty());
3492 TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3493 Symbol FoodClass = objcClass("FoodClass
");
3494 FoodClass.IncludeHeaders.emplace_back("\"Foo
.h
\"", 2, Symbol::Import);
3495 Symbol SymFood = objcProtocol("Food
");
3496 auto Results = completions("@
class Foo
^", {SymFood, FoodClass},
3497 /*Opts=*/{}, "Foo
.m
");
3499 // Should only give class names without any include insertion.
3500 EXPECT_THAT(Results.Completions,
3501 UnorderedElementsAre(AllOf(named("FoodClass
"),
3502 kind(CompletionItemKind::Class),
3503 Not(insertInclude()))));
3506 TEST(CompletionTest, CursorInSnippets) {
3507 clangd::CodeCompleteOptions Options;
3508 Options.EnableSnippets = true;
3509 auto Results = completions(
3511 void while_foo(int a
, int b
);
3515 /*IndexSymbols=*/{}, Options);
3517 // Last placeholder in code patterns should be $0 to put the cursor there.
3518 EXPECT_THAT(Results.Completions,
3519 Contains(AllOf(named("while"),
3520 snippetSuffix(" ($
{1:condition
}) {\n$
0\n}"))));
3521 // However, snippets for functions must *not* end with $0.
3522 EXPECT_THAT(Results.Completions,
3523 Contains(AllOf(named("while_foo
"),
3524 snippetSuffix("($
{1:int a
}, $
{2:int b
})"))));
3526 Results = completions(R"cpp(
3528 Base(int a
, int b
) {}
3531 struct Derived
: Base
{
3535 /*IndexSymbols=*/{}, Options);
3536 // Constructors from base classes are a kind of pattern that shouldn't end
3538 EXPECT_THAT(Results.Completions,
3539 Contains(AllOf(named("Base
"),
3540 snippetSuffix("($
{1:int a
}, $
{2:int b
})"))));
3543 TEST(CompletionTest, WorksWithNullType) {
3544 auto R = completions(R"cpp(
3546 for (auto [loopVar
] : y
) { // y has to be unresolved.
3551 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar
")));
3554 TEST(CompletionTest, UsingDecl) {
3555 const char *Header(R"cpp(
3560 const char *Source(R"cpp(
3564 auto Index = TestTU::withHeaderCode(Header).index();
3565 clangd::CodeCompleteOptions Opts;
3566 Opts.Index = Index.get();
3567 Opts.AllScopes = true;
3568 auto R = completions(Source, {}, Opts);
3569 EXPECT_THAT(R.Completions,
3570 ElementsAre(AllOf(scope("std::"), named("foo
"),
3571 kind(CompletionItemKind::Reference))));
3574 TEST(CompletionTest, Enums) {
3575 const char *Header(R"cpp(
3577 enum Unscoped
{ Clangd1
};
3579 enum Unscoped
{ Clangd2
};
3581 enum class Scoped
{ Clangd3
};
3583 const char *Source(R"cpp(
3587 auto Index = TestTU::withHeaderCode(Header).index();
3588 clangd::CodeCompleteOptions Opts;
3589 Opts.Index = Index.get();
3590 Opts.AllScopes = true;
3591 auto R = completions(Source, {}, Opts);
3592 EXPECT_THAT(R.Completions, UnorderedElementsAre(
3593 AllOf(scope("ns::"), named("Clangd1
"),
3594 kind(CompletionItemKind::EnumMember)),
3595 AllOf(scope("ns::C::"), named("Clangd2
"),
3596 kind(CompletionItemKind::EnumMember)),
3597 AllOf(scope("ns::Scoped::"), named("Clangd3
"),
3598 kind(CompletionItemKind::EnumMember))));
3601 TEST(CompletionTest, ScopeIsUnresolved) {
3602 clangd::CodeCompleteOptions Opts = {};
3603 Opts.AllScopes = true;
3605 auto Results = completions(R"cpp(
3610 {cls("a::b::XYZ
")}, Opts);
3611 EXPECT_THAT(Results.Completions,
3612 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ
"))));
3615 TEST(CompletionTest, NestedScopeIsUnresolved) {
3616 clangd::CodeCompleteOptions Opts = {};
3617 Opts.AllScopes = true;
3619 auto Results = completions(R"cpp(
3622 void f() { b::c::X
^ }
3625 {cls("a::b::c::XYZ
")}, Opts);
3626 EXPECT_THAT(Results.Completions,
3627 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ
"))));
3630 // Clang parser gets confused here and doesn't report the ns:: prefix.
3631 // Naive behavior is to insert it again. We examine the source and recover.
3632 TEST(CompletionTest, NamespaceDoubleInsertion) {
3633 clangd::CodeCompleteOptions Opts = {};
3635 auto Results = completions(R"cpp(
3642 {cls("foo::ns::ABCDE
")}, Opts);
3643 EXPECT_THAT(Results.Completions,
3644 UnorderedElementsAre(AllOf(qualifier(""), named("ABCDE
"))));
3647 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
3648 // Despite the fact that base method matches the ref-qualifier better,
3649 // completion results should only include the derived method.
3650 auto Completions = completions(R"cpp(
3653 double size() const;
3655 struct deque
: deque_base
{
3662 EXPECT_THAT(Completions,
3663 ElementsAre(AllOf(returnType("int"), named("size
"))));
3666 TEST(CompletionTest, NoCrashWithIncompleteLambda) {
3667 auto Completions = completions("auto&& x
= []{^").Completions;
3668 // The completion of x itself can cause a problem: in the code completion
3669 // callback, its type is not known, which affects the linkage calculation.
3670 // A bad linkage value gets cached, and subsequently updated.
3671 EXPECT_THAT(Completions, Contains(named("x
")));
3673 auto Signatures = signatures("auto x() { x(^").signatures;
3674 EXPECT_THAT(Signatures, Contains(sig("x() -> auto")));
3677 TEST(CompletionTest, DelayedTemplateParsing) {
3678 Annotations Test(R"cpp(
3680 template <typename T
> int foo() { return xx
^; }
3682 auto TU = TestTU::withCode(Test.code());
3683 // Even though delayed-template-parsing is on, we will disable it to provide
3684 // completion in templates.
3685 TU.ExtraArgs.push_back("-fdelayed
-template-parsing
");
3687 EXPECT_THAT(completions(TU, Test.point()).Completions,
3688 Contains(named("xxx
")));
3691 TEST(CompletionTest, CompletionRange) {
3692 const char *WithRange = "auto x
= [[abc
]]^";
3693 auto Completions = completions(WithRange);
3694 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3695 Completions = completionsNoCompile(WithRange);
3696 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3698 const char *EmptyRange = "auto x
= [[]]^";
3699 Completions = completions(EmptyRange);
3700 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3701 Completions = completionsNoCompile(EmptyRange);
3702 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3704 // Sema doesn't trigger at all here, while the no-sema completion runs
3705 // heuristics as normal and reports a range. It'd be nice to be consistent.
3706 const char *NoCompletion = "/* foo [[]]^ */";
3707 Completions = completions(NoCompletion);
3708 EXPECT_EQ(Completions.CompletionRange, std::nullopt);
3709 Completions = completionsNoCompile(NoCompletion);
3710 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
3713 TEST(NoCompileCompletionTest, Basic) {
3714 auto Results = completionsNoCompile(R"cpp(
3721 EXPECT_FALSE(Results.RanParser);
3722 EXPECT_THAT(Results.Completions,
3723 UnorderedElementsAre(named("void"), named("func
"), named("int"),
3724 named("xyz
"), named("abc
")));
3727 TEST(NoCompileCompletionTest, WithFilter) {
3728 auto Results = completionsNoCompile(R"cpp(
3737 EXPECT_THAT(Results.Completions,
3738 UnorderedElementsAre(named("sym1
"), named("sym2
")));
3741 TEST(NoCompileCompletionTest, WithIndex) {
3742 std::vector<Symbol> Syms = {func("xxx
"), func("a::xxx
"), func("ns::b::xxx
"),
3743 func("c::xxx
"), func("ns::d::xxx
")};
3744 auto Results = completionsNoCompile(
3746 // Current-scopes, unqualified completion.
3756 EXPECT_THAT(Results.Completions,
3757 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3758 AllOf(qualifier(""), scope("a::")),
3759 AllOf(qualifier(""), scope("ns::b::"))));
3760 CodeCompleteOptions Opts;
3761 Opts.AllScopes = true;
3762 Results = completionsNoCompile(
3764 // All-scopes unqualified completion.
3774 EXPECT_THAT(Results.Completions,
3775 UnorderedElementsAre(AllOf(qualifier(""), scope("")),
3776 AllOf(qualifier(""), scope("a::")),
3777 AllOf(qualifier(""), scope("ns::b::")),
3778 AllOf(qualifier("c::"), scope("c::")),
3779 AllOf(qualifier("d::"), scope("ns::d::"))));
3780 Results = completionsNoCompile(
3782 // Qualified completion.
3792 EXPECT_THAT(Results.Completions,
3793 ElementsAre(AllOf(qualifier(""), scope("ns::b::"))));
3794 Results = completionsNoCompile(
3796 // Absolutely qualified completion.
3806 EXPECT_THAT(Results.Completions,
3807 ElementsAre(AllOf(qualifier(""), scope("a::"))));
3810 TEST(AllowImplicitCompletion, All) {
3811 const char *Yes[] = {
3815 " # include <^foo.h>",
3816 "#import <foo/^bar.h>",
3817 "#include_next \"^",
3819 const char *No[] = {
3823 "#include <foo.h> //^",
3824 "#include \"foo.h\"^",
3828 for (const char *Test
: Yes
) {
3829 llvm::Annotations
A(Test
);
3830 EXPECT_TRUE(allowImplicitCompletion(A
.code(), A
.point())) << Test
;
3832 for (const char *Test
: No
) {
3833 llvm::Annotations
A(Test
);
3834 EXPECT_FALSE(allowImplicitCompletion(A
.code(), A
.point())) << Test
;
3838 TEST(CompletionTest
, FunctionArgsExist
) {
3839 clangd::CodeCompleteOptions Opts
;
3840 Opts
.EnableSnippets
= true;
3841 std::string Context
= R
"cpp(
3848 template <typename T>
3850 Container(int Size) {}
3853 EXPECT_THAT(completions(Context
+ "int y = fo^", {}, Opts
).Completions
,
3854 UnorderedElementsAre(
3855 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3857 completions(Context
+ "int y = fo^(42)", {}, Opts
).Completions
,
3858 UnorderedElementsAre(AllOf(labeled("foo(int A)"), snippetSuffix(""))));
3859 // FIXME(kirillbobyrev): No snippet should be produced here.
3860 EXPECT_THAT(completions(Context
+ "int y = fo^o(42)", {}, Opts
).Completions
,
3861 UnorderedElementsAre(
3862 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})"))));
3864 completions(Context
+ "int y = ba^", {}, Opts
).Completions
,
3865 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("()"))));
3866 EXPECT_THAT(completions(Context
+ "int y = ba^()", {}, Opts
).Completions
,
3867 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix(""))));
3869 completions(Context
+ "Object o = Obj^", {}, Opts
).Completions
,
3870 Contains(AllOf(labeled("Object(int B)"), snippetSuffix("(${1:int B})"),
3871 kind(CompletionItemKind::Constructor
))));
3872 EXPECT_THAT(completions(Context
+ "Object o = Obj^()", {}, Opts
).Completions
,
3873 Contains(AllOf(labeled("Object(int B)"), snippetSuffix(""),
3874 kind(CompletionItemKind::Constructor
))));
3876 completions(Context
+ "Container c = Cont^", {}, Opts
).Completions
,
3877 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3878 snippetSuffix("<${1:typename T}>(${2:int Size})"),
3879 kind(CompletionItemKind::Constructor
))));
3881 completions(Context
+ "Container c = Cont^()", {}, Opts
).Completions
,
3882 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3883 snippetSuffix("<${1:typename T}>"),
3884 kind(CompletionItemKind::Constructor
))));
3886 completions(Context
+ "Container c = Cont^<int>()", {}, Opts
).Completions
,
3887 Contains(AllOf(labeled("Container<typename T>(int Size)"),
3889 kind(CompletionItemKind::Constructor
))));
3890 EXPECT_THAT(completions(Context
+ "MAC^(2)", {}, Opts
).Completions
,
3891 Contains(AllOf(labeled("MACRO(x)"), snippetSuffix(""),
3892 kind(CompletionItemKind::Function
))));
3895 TEST(CompletionTest
, NoCrashDueToMacroOrdering
) {
3896 EXPECT_THAT(completions(R
"cpp(
3898 #define ECHO2(X) ECHO(X)
3899 int finish_preamble = EC^HO(2);)cpp")
3901 UnorderedElementsAre(labeled("ECHO(X)"), labeled("ECHO2(X)")));
3904 TEST(CompletionTest
, ObjCCategoryDecls
) {
3906 TU
.ExtraArgs
.push_back("-xobjective-c");
3907 TU
.HeaderCode
= R
"objc(
3911 @interface Foo (FooExt1)
3914 @interface Foo (FooExt2)
3920 @interface Bar (BarExt)
3924 Annotations
Test(R
"objc(
3925 @implementation Foo (^)
3928 TU
.Code
= Test
.code().str();
3929 auto Results
= completions(TU
, Test
.point());
3930 EXPECT_THAT(Results
.Completions
,
3931 UnorderedElementsAre(labeled("FooExt1"), labeled("FooExt2")));
3934 Annotations
Test(R
"objc(
3938 TU
.Code
= Test
.code().str();
3939 auto Results
= completions(TU
, Test
.point());
3940 EXPECT_THAT(Results
.Completions
, UnorderedElementsAre(labeled("BarExt")));
3944 TEST(CompletionTest
, PreambleCodeComplete
) {
3945 llvm::StringLiteral Baseline
= "\n#define MACRO 12\nint num = MACRO;";
3946 llvm::StringLiteral ModifiedCC
=
3947 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
3949 Annotations
Test(ModifiedCC
);
3950 auto BaselineTU
= TestTU::withCode(Baseline
);
3951 auto ModifiedTU
= TestTU::withCode(Test
.code());
3954 auto Inputs
= ModifiedTU
.inputs(FS
);
3955 auto Result
= codeComplete(testPath(ModifiedTU
.Filename
), Test
.point(),
3956 BaselineTU
.preamble().get(), Inputs
, {});
3957 EXPECT_THAT(Result
.Completions
, Not(testing::IsEmpty()));
3960 TEST(CompletionTest
, CommentParamName
) {
3961 const std::string Code
= R
"cpp(
3962 void fun(int foo, int bar);
3963 void overloaded(int param_int);
3964 void overloaded(int param_int, int param_other);
3965 void overloaded(char param_char);
3969 EXPECT_THAT(completions(Code
+ "fun(/*^").Completions
,
3970 UnorderedElementsAre(labeled("foo=*/")));
3971 EXPECT_THAT(completions(Code
+ "fun(1, /*^").Completions
,
3972 UnorderedElementsAre(labeled("bar=*/")));
3973 EXPECT_THAT(completions(Code
+ "/*^").Completions
, IsEmpty());
3974 // Test de-duplication.
3976 completions(Code
+ "overloaded(/*^").Completions
,
3977 UnorderedElementsAre(labeled("param_int=*/"), labeled("param_char=*/")));
3978 // Comment already has some text in it.
3979 EXPECT_THAT(completions(Code
+ "fun(/* ^").Completions
,
3980 UnorderedElementsAre(labeled("foo=*/")));
3981 EXPECT_THAT(completions(Code
+ "fun(/* f^").Completions
,
3982 UnorderedElementsAre(labeled("foo=*/")));
3983 EXPECT_THAT(completions(Code
+ "fun(/* x^").Completions
, IsEmpty());
3984 EXPECT_THAT(completions(Code
+ "fun(/* f ^").Completions
, IsEmpty());
3988 std::string
CompletionRangeTest(Code
+ "fun(/*[[^]]");
3989 auto Results
= completions(CompletionRangeTest
);
3990 EXPECT_THAT(Results
.CompletionRange
,
3991 llvm::ValueIs(Annotations(CompletionRangeTest
).range()));
3993 Results
.Completions
,
3995 AllOf(replacesRange(Annotations(CompletionRangeTest
).range()),
3996 origin(SymbolOrigin::AST
), kind(CompletionItemKind::Text
))));
3999 std::string
CompletionRangeTest(Code
+ "fun(/*[[fo^]]");
4000 auto Results
= completions(CompletionRangeTest
);
4001 EXPECT_THAT(Results
.CompletionRange
,
4002 llvm::ValueIs(Annotations(CompletionRangeTest
).range()));
4004 Results
.Completions
,
4006 AllOf(replacesRange(Annotations(CompletionRangeTest
).range()),
4007 origin(SymbolOrigin::AST
), kind(CompletionItemKind::Text
))));
4011 TEST(CompletionTest
, Concepts
) {
4012 Annotations
Code(R
"cpp(
4014 concept A = sizeof(T) <= 8;
4016 template<$tparam^A U>
4019 template<typename T>
4020 int bar(T t) requires $expr^A<int>;
4023 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
4025 $toplevel^A auto i = 19;
4027 template<$toplevel^A auto i> void constrainedNTTP();
4029 // FIXME: The first parameter should be dropped in this case.
4030 void abbreviated($expr^A auto x) {}
4033 TU
.Code
= Code
.code().str();
4034 TU
.ExtraArgs
= {"-std=c++20"};
4036 auto Sym
= conceptSym("same_as");
4037 Sym
.Signature
= "<typename Tp, typename Up>";
4038 Sym
.CompletionSnippetSuffix
= "<${1:typename Tp}, ${2:typename Up}>";
4039 std::vector
<Symbol
> Syms
= {Sym
};
4040 for (auto P
: Code
.points("tparam")) {
4042 completions(TU
, P
, Syms
).Completions
,
4043 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4044 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4045 snippetSuffix("<${2:typename Up}>"))),
4046 Contains(named("class")), Contains(named("typename"))))
4047 << "Completing template parameter at position " << P
;
4050 for (auto P
: Code
.points("toplevel")) {
4052 completions(TU
, P
, Syms
).Completions
,
4053 AllOf(Contains(AllOf(named("A"), signature(""), snippetSuffix(""))),
4054 Contains(AllOf(named("same_as"), signature("<typename Up>"),
4055 snippetSuffix("<${2:typename Up}>")))))
4056 << "Completing 'requires' expression at position " << P
;
4059 for (auto P
: Code
.points("expr")) {
4061 completions(TU
, P
, Syms
).Completions
,
4062 AllOf(Contains(AllOf(named("A"), signature("<class T>"),
4063 snippetSuffix("<${1:class T}>"))),
4065 named("same_as"), signature("<typename Tp, typename Up>"),
4066 snippetSuffix("<${1:typename Tp}, ${2:typename Up}>")))))
4067 << "Completing 'requires' expression at position " << P
;
4071 TEST(SignatureHelp
, DocFormat
) {
4072 Annotations
Code(R
"cpp(
4073 // Comment `with` markup.
4075 void bar() { foo(^); }
4077 for (auto DocumentationFormat
:
4078 {MarkupKind::PlainText
, MarkupKind::Markdown
}) {
4079 auto Sigs
= signatures(Code
.code(), Code
.point(), /*IndexSymbols=*/{},
4080 DocumentationFormat
);
4081 ASSERT_EQ(Sigs
.signatures
.size(), 1U);
4082 EXPECT_EQ(Sigs
.signatures
[0].documentation
.kind
, DocumentationFormat
);
4086 TEST(SignatureHelp
, TemplateArguments
) {
4087 std::string Top
= R
"cpp(
4088 template <typename T, int> bool foo(char);
4089 template <int I, int> bool foo(float);
4092 auto First
= signatures(Top
+ "bool x = foo<^");
4095 UnorderedElementsAre(sig("foo<[[typename T]], [[int]]>() -> bool"),
4096 sig("foo<[[int I]], [[int]]>() -> bool")));
4097 EXPECT_EQ(First
.activeParameter
, 0);
4099 auto Second
= signatures(Top
+ "bool x = foo<1, ^");
4100 EXPECT_THAT(Second
.signatures
,
4101 ElementsAre(sig("foo<[[int I]], [[int]]>() -> bool")));
4102 EXPECT_EQ(Second
.activeParameter
, 1);
4105 TEST(CompletionTest
, DoNotCrash
) {
4106 llvm::StringLiteral Cases
[] = {
4108 template <typename = int> struct Foo {};
4109 auto a = [x(3)](Foo<^>){};
4112 for (auto Case
: Cases
) {
4114 auto Completions
= completions(Case
);
4119 } // namespace clangd
4120 } // namespace clang