28#include "clang/Sema/CodeCompleteConsumer.h"
29#include "clang/Tooling/CompilationDatabase.h"
30#include "llvm/ADT/StringRef.h"
31#include "llvm/Support/Error.h"
32#include "llvm/Support/Path.h"
33#include "llvm/Testing/Annotations/Annotations.h"
34#include "llvm/Testing/Support/Error.h"
35#include "llvm/Testing/Support/SupportHelpers.h"
36#include "gmock/gmock.h"
37#include "gtest/gtest.h"
38#include <condition_variable>
48using ::testing::AllOf;
49using ::testing::Contains;
50using ::testing::ElementsAre;
51using ::testing::Field;
52using ::testing::HasSubstr;
53using ::testing::IsEmpty;
55using ::testing::UnorderedElementsAre;
56using ContextKind = CodeCompletionContext::Kind;
59MATCHER_P(named, Name,
"") {
return arg.Name == Name; }
60MATCHER_P(mainFileRefs, Refs,
"") {
return arg.MainFileRefs == Refs; }
61MATCHER_P(scopeRefs, Refs,
"") {
return arg.ScopeRefsInFile == Refs; }
63 return llvm::StringRef(arg.Name).starts_with(Prefix);
65MATCHER_P(filterText, F,
"") {
return arg.FilterText == F; }
66MATCHER_P(scope, S,
"") {
return arg.Scope == S; }
67MATCHER_P(qualifier, Q,
"") {
return arg.RequiredQualifier == Q; }
69 return arg.RequiredQualifier + arg.Name + arg.Signature ==
Label;
72MATCHER_P(kind, K,
"") {
return arg.Kind == K; }
74 return arg.Documentation && arg.Documentation->asPlainText() ==
D;
76MATCHER_P(returnType, D,
"") {
return arg.ReturnType ==
D; }
78 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader;
80MATCHER_P(insertInclude, IncludeHeader,
"") {
81 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader &&
82 bool(arg.Includes[0].Insertion);
84MATCHER_P(insertIncludeText, InsertedText,
"") {
85 return !arg.Includes.empty() && arg.Includes[0].Insertion &&
86 arg.Includes[0].Insertion->newText == InsertedText;
89 return !arg.Includes.empty() && bool(arg.Includes[0].Insertion);
92MATCHER_P(origin, OriginSet,
"") {
return arg.Origin == OriginSet; }
93MATCHER_P(signature, S,
"") {
return arg.Signature == S; }
95 return arg.CompletionInsertRange ==
Range;
99Matcher<const std::vector<CodeCompletion> &> has(std::string Name) {
100 return Contains(named(std::move(Name)));
102Matcher<const std::vector<CodeCompletion> &> has(std::string Name,
104 return Contains(AllOf(named(std::move(Name)), kind(K)));
106MATCHER(isDocumented,
"") {
return arg.Documentation.has_value(); }
107MATCHER(deprecated,
"") {
return arg.Deprecated; }
109std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol>
Symbols) {
111 for (
const auto &Sym :
Symbols)
119 std::vector<Symbol> IndexSymbols = {},
120 clangd::CodeCompleteOptions Opts = {}) {
121 std::unique_ptr<SymbolIndex> OverrideIndex;
122 if (!IndexSymbols.empty()) {
123 assert(!Opts.Index &&
"both Index and IndexSymbols given!");
124 OverrideIndex = memIndex(std::move(IndexSymbols));
125 Opts.Index = OverrideIndex.get();
129 auto Inputs = TU.inputs(FS);
133 ADD_FAILURE() <<
"Couldn't build CompilerInvocation";
143CodeCompleteResult completions(llvm::StringRef
Text,
144 std::vector<Symbol> IndexSymbols = {},
145 clangd::CodeCompleteOptions Opts = {},
146 PathRef FilePath =
"foo.cpp") {
150 TU.Filename = FilePath.str();
151 return completions(TU, Test.point(), std::move(IndexSymbols),
156CodeCompleteResult completionsNoCompile(llvm::StringRef
Text,
157 std::vector<Symbol> IndexSymbols = {},
158 clangd::CodeCompleteOptions Opts = {},
159 PathRef FilePath =
"foo.cpp") {
160 std::unique_ptr<SymbolIndex> OverrideIndex;
161 if (!IndexSymbols.empty()) {
162 assert(!Opts.Index &&
"both Index and IndexSymbols given!");
163 OverrideIndex = memIndex(std::move(IndexSymbols));
164 Opts.Index = OverrideIndex.get();
169 ParseInputs ParseInput{tooling::CompileCommand(), &FS, Test.code().str()};
170 return codeComplete(FilePath, Test.point(),
nullptr, ParseInput,
179#if CLANGD_DECISION_FOREST
180TEST(DecisionForestRankingModel, NameMatchSanityTest) {
181 clangd::CodeCompleteOptions Opts;
182 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
183 auto Results = completions(
187 int AlphaBetaGamma();
189int func() { MemberAccess().ABG^ }
192 EXPECT_THAT(Results.Completions,
193 ElementsAre(named(
"ABG"), named(
"AlphaBetaGamma")));
196TEST(DecisionForestRankingModel, ReferencesAffectRanking) {
197 clangd::CodeCompleteOptions Opts;
198 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
199 constexpr int NumReferences = 100000;
201 completions(
"int main() { clang^ }",
202 {
ns(
"clangA"), withReferences(NumReferences,
func(
"clangD"))},
205 ElementsAre(named(
"clangD"), named(
"clangA")));
207 completions(
"int main() { clang^ }",
208 {withReferences(NumReferences,
ns(
"clangA")),
func(
"clangD")},
211 ElementsAre(named(
"clangA"), named(
"clangD")));
215TEST(DecisionForestRankingModel, DecisionForestScorerCallbackTest) {
216 clangd::CodeCompleteOptions Opts;
217 constexpr float MagicNumber = 1234.5678f;
218 Opts.RankingModel = CodeCompleteOptions::DecisionForest;
222 Scores.
Total = MagicNumber;
223 Scores.ExcludingName = MagicNumber;
226 llvm::StringRef Code =
"int func() { int xyz; xy^ }";
227 auto Results = completions(Code,
229 ASSERT_EQ(Results.Completions.size(), 1u);
230 EXPECT_EQ(Results.Completions[0].Score.Total, MagicNumber);
231 EXPECT_EQ(Results.Completions[0].Score.ExcludingName, MagicNumber);
234 Opts.RankingModel = CodeCompleteOptions::Heuristics;
235 Results = completions(Code,
237 ASSERT_EQ(Results.Completions.size(), 1u);
238 EXPECT_NE(Results.Completions[0].Score.Total, MagicNumber);
239 EXPECT_NE(Results.Completions[0].Score.ExcludingName, MagicNumber);
242TEST(CompletionTest, Limit) {
243 clangd::CodeCompleteOptions Opts;
245 auto Results = completions(R
"cpp(
246struct ClassWithMembers {
252int main() { ClassWithMembers().^ }
256 EXPECT_TRUE(Results.HasMore);
257 EXPECT_THAT(Results.Completions, ElementsAre(named(
"AAA"), named(
"BBB")));
260TEST(CompletionTest, Filter) {
261 std::string Body = R
"cpp(
272 EXPECT_THAT(completions(Body +
"int main() { S().Foba^ }").Completions,
273 AllOf(has(
"FooBar"), has(
"FooBaz"), Not(has(
"Qux"))));
277 Sym.SymInfo.Kind = index::SymbolKind::Macro;
279 completions(Body +
"int main() { C^ }", {Sym}).Completions,
280 AllOf(has(
"Car"), Not(has(
"MotorCar")), Not(has(
"MotorCarIndex"))));
281 EXPECT_THAT(completions(Body +
"int main() { M^ }", {Sym}).Completions,
282 AllOf(has(
"MotorCar"), has(
"MotorCarIndex")));
285void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
286 auto Results = completions(
292 // Make sure this is not in preamble.
295 struct GlobalClass {};
297 struct ClassWithMembers {
307 struct LocalClass {};
315 {
cls(
"IndexClass"),
var(
"index_var"),
func(
"index_func")}, Opts);
317 EXPECT_TRUE(Results.RanParser);
320 EXPECT_THAT(Results.Completions,
321 AllOf(has(
"method"), has(
"field"), Not(has(
"ClassWithMembers")),
322 Not(has(
"operator=")), Not(has(
"~ClassWithMembers"))));
323 EXPECT_IFF(Opts.IncludeIneligibleResults, Results.Completions,
324 has(
"private_field"));
328 Not(AnyOf(has(
"global_var"), has(
"index_var"), has(
"global_func"),
329 has(
"global_func()"), has(
"index_func"), has(
"GlobalClass"),
330 has(
"IndexClass"), has(
"MACRO"), has(
"LocalClass"))));
333 EXPECT_THAT(Results.Completions,
336 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
339void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
340 auto Results = completions(
345 // Make sure this is not in preamble.
348 struct GlobalClass {};
350 struct ClassWithMembers {
356 struct LocalClass {};
364 {
cls(
"IndexClass"),
var(
"index_var"),
func(
"index_func")}, Opts);
366 EXPECT_TRUE(Results.RanParser);
368 EXPECT_THAT(Results.Completions,
369 Not(AnyOf(has(
"method"), has(
"method()"), has(
"field"))));
371 EXPECT_THAT(Results.Completions,
372 AllOf(has(
"global_var"), has(
"index_var"), has(
"global_func"),
374 has(
"GlobalClass"), has(
"IndexClass")));
376 EXPECT_THAT(Results.Completions, has(
"MACRO"));
378 EXPECT_THAT(Results.Completions,
379 AllOf(has(
"local_var"), has(
"LocalClass"),
382 EXPECT_THAT(Results.Completions, Contains(isDocumented()));
385TEST(CompletionTest, CompletionOptions) {
386 auto Test = [&](
const clangd::CodeCompleteOptions &Opts) {
387 testAfterDotCompletion(Opts);
388 testGlobalScopeCompletion(Opts);
392 &clangd::CodeCompleteOptions::IncludeIneligibleResults,
397 for (
auto &F : Flags) {
398 clangd::CodeCompleteOptions O;
404TEST(CompletionTest, Accessible) {
408 protected: void prot();
409 private: void priv();
411 void Foo::pub() { this->^ }
414 AllOf(has("priv"), has(
"prot"), has(
"pub")));
416 auto External = completions(R
"cpp(
419 protected: void prot();
420 private: void priv();
427 EXPECT_THAT(External.Completions,
428 AllOf(has("pub"), Not(has(
"prot")), Not(has(
"priv"))));
430 auto Results = completions(R
"cpp(
433 protected: void prot();
434 private: void priv();
436 struct Bar : public Foo {
437 private: using Foo::pub;
444 EXPECT_THAT(Results.Completions,
445 AllOf(Not(has("priv")), Not(has(
"prot")), Not(has(
"pub"))));
448TEST(CompletionTest, Qualifiers) {
449 auto Results = completions(R
"cpp(
451 public: int foo() const;
454 class Bar : public Foo {
457 void test() { Bar().^ }
459 EXPECT_THAT(Results.Completions,
460 Contains(AllOf(qualifier(""), named(
"bar"))));
462 EXPECT_THAT(Results.Completions,
463 Not(Contains(AllOf(qualifier(
"Foo::"), named(
"foo")))));
465 EXPECT_THAT(Results.Completions,
466 Not(Contains(AllOf(qualifier(
""), named(
"foo")))));
470TEST(CompletionTest, QualificationWithInlineNamespace) {
471 auto Results = completions(R
"cpp(
472 namespace a { inline namespace b {} }
473 using namespace a::b;
477 EXPECT_THAT(Results.Completions,
478 UnorderedElementsAre(AllOf(qualifier(
"a::"), named(
"Foo"))));
481TEST(CompletionTest, InjectedTypename) {
483 EXPECT_THAT(completions(
"struct X{}; void foo(){ X().^ }").Completions,
485 EXPECT_THAT(completions(
"struct X{ void foo(){ this->^ } };").Completions,
488 EXPECT_THAT(completions(
"struct X{ void foo(){ ^ } };").Completions,
491 completions(
"struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions,
495 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
499 EXPECT_THAT(completions(
"struct X{}; void foo(){ X::^ }").Completions,
503TEST(CompletionTest, SkipInjectedWhenUnqualified) {
504 EXPECT_THAT(completions(
"struct X { void f() { X^ }};").Completions,
505 ElementsAre(named(
"X"), named(
"~X")));
508TEST(CompletionTest, Snippets) {
509 clangd::CodeCompleteOptions Opts;
510 auto Results = completions(
514 int f(int i, const float f) const;
525 snippetSuffix(
"(${1:int i}, ${2:const float f})")));
528TEST(CompletionTest, HeuristicsForMemberFunctionCompletion) {
529 clangd::CodeCompleteOptions Opts;
530 Opts.EnableSnippets =
true;
534 static int staticMethod(int name);
535 int method(int name) const;
536 template <typename T, typename U, typename V = int>
537 T generic(U nameU, V nameV);
538 template <typename T, int U>
539 static T staticGeneric();
541 this->$canBeCallNoStatic^
547 int Foo::$isDefinition^ {
551 int i = Foo::$canBeCallStaticOnly^
554 struct Derived : Foo {
566 f.$canBeCallNoStatic^
567 ; // Prevent parsing as 'f.f'
574 d.Derived::$canBeCall^
582 ; // Prevent parsing as 'f.f'
589 d.Derived::$canBeCall^
594 for (
const auto &P : Code.points(
"canNotBeCall")) {
595 auto Results = completions(TU, P, {}, Opts);
596 EXPECT_THAT(Results.Completions,
597 Contains(AllOf(named(
"method"), signature(
"(int name) const"),
598 snippetSuffix(
""))));
602 Contains(AllOf(named(
"generic"),
603 signature(
"<typename T, typename U>(U nameU, V nameV)"),
604 snippetSuffix(
"<${1:typename T}, ${2:typename U}>"))));
605 EXPECT_THAT(Results.Completions,
606 Contains(AllOf(named(
"staticMethod"), signature(
"(int name)"),
607 snippetSuffix(
""))));
608 EXPECT_THAT(Results.Completions,
610 named(
"staticGeneric"), signature(
"<typename T, int U>()"),
611 snippetSuffix(
"<${1:typename T}, ${2:int U}>"))));
614 for (
const auto &P : Code.points(
"canBeCall")) {
615 auto Results = completions(TU, P, {}, Opts);
616 EXPECT_THAT(Results.Completions,
617 Contains(AllOf(named(
"method"), signature(
"(int name) const"),
618 snippetSuffix(
"(${1:int name})"))));
622 named(
"generic"), signature(
"<typename T>(U nameU, V nameV)"),
623 snippetSuffix(
"<${1:typename T}>(${2:U nameU}, ${3:V nameV})"))));
624 EXPECT_THAT(Results.Completions,
625 Contains(AllOf(named(
"staticMethod"), signature(
"(int name)"),
626 snippetSuffix(
"(${1:int name})"))));
627 EXPECT_THAT(Results.Completions,
629 named(
"staticGeneric"), signature(
"<typename T, int U>()"),
630 snippetSuffix(
"<${1:typename T}, ${2:int U}>()"))));
633 for (
const auto &P : Code.points(
"canBeCallNoStatic")) {
634 auto Results = completions(TU, P, {}, Opts);
635 EXPECT_THAT(Results.Completions,
636 Contains(AllOf(named(
"method"), signature(
"(int name) const"),
637 snippetSuffix(
"(${1:int name})"))));
641 named(
"generic"), signature(
"<typename T>(U nameU, V nameV)"),
642 snippetSuffix(
"<${1:typename T}>(${2:U nameU}, ${3:V nameV})"))));
645 for (
const auto &P : Code.points(
"canBeCallStaticOnly")) {
646 auto Results = completions(TU, P, {}, Opts);
647 EXPECT_THAT(Results.Completions,
648 Contains(AllOf(named(
"method"), signature(
"(int name) const"),
649 snippetSuffix(
""))));
652 Contains(AllOf(named(
"generic"),
653 signature(
"<typename T, typename U>(U nameU, V nameV)"),
654 snippetSuffix(
"<${1:typename T}, ${2:typename U}>"))));
655 EXPECT_THAT(Results.Completions,
656 Contains(AllOf(named(
"staticMethod"), signature(
"(int name)"),
657 snippetSuffix(
"(${1:int name})"))));
658 EXPECT_THAT(Results.Completions,
660 named(
"staticGeneric"), signature(
"<typename T, int U>()"),
661 snippetSuffix(
"<${1:typename T}, ${2:int U}>()"))));
664 for (
const auto &P : Code.points(
"isDefinition")) {
665 auto Results = completions(TU, P, {}, Opts);
667 EXPECT_THAT(Results.Completions,
668 Contains(AllOf(named(
"method"), signature(
"(int name) const"),
669 snippetSuffix(
"(int name) const"))));
672 Contains(AllOf(named(
"generic"),
673 signature(
"<typename T, typename U>(U nameU, V nameV)"),
674 snippetSuffix(
"(U nameU, V nameV)"))));
675 EXPECT_THAT(Results.Completions,
676 Contains(AllOf(named(
"staticMethod"), signature(
"(int name)"),
677 snippetSuffix(
"(int name)"))));
678 EXPECT_THAT(Results.Completions,
679 Contains(AllOf(named(
"staticGeneric"),
680 signature(
"<typename T, int U>()"),
681 snippetSuffix(
"()"))));
685TEST(CompletionTest, PrivateMemberDefinition) {
686 clangd::CodeCompleteOptions Opts;
687 Opts.EnableSnippets =
true;
688 auto Results = completions(
691 int func(int a, int b);
696 EXPECT_THAT(Results.Completions,
697 Contains(AllOf(named(
"func"), signature(
"(int a, int b)"),
698 snippetSuffix(
"(int a, int b)"))));
701TEST(CompletionTest, DeclParamName) {
707 clangd::CodeCompleteOptions Opts;
708 Opts.EnableSnippets =
true;
709 auto FuncFromSource = completions(R
"cpp(
719 EXPECT_THAT(FuncFromSource.Completions, Contains(signature("(int day)")));
722TEST(CompletionTest, DefaultArgsWithValues) {
723 clangd::CodeCompleteOptions Opts;
724 Opts.EnableSnippets =
true;
725 auto Results = completions(
731 void foo(int x = 42, int y = 0, Arg arg = Arg(42, 0));
736 EXPECT_THAT(Results.Completions,
739 signature(
"(int x = 42, int y = 0, Arg arg = Arg(42, 0))"),
740 snippetSuffix(
"(int x, int y, Arg arg)"))));
743TEST(CompletionTest, NoSnippetsInUsings) {
744 clangd::CodeCompleteOptions Opts;
745 Opts.EnableSnippets =
true;
746 auto Results = completions(
749 int func(int a, int b);
755 EXPECT_THAT(Results.Completions,
756 ElementsAre(AllOf(named(
"func"), labeled(
"func(int a, int b)"),
757 snippetSuffix(
""))));
760 auto Func =
func(
"ns::func");
761 Func.CompletionSnippetSuffix =
"(${1:int a}, ${2: int b})";
762 Func.Signature =
"(int a, int b)";
763 Func.ReturnType =
"void";
765 Results = completions(R
"cpp(
770 EXPECT_THAT(Results.Completions,
771 ElementsAre(AllOf(named(
"func"), labeled(
"func(int a, int b)"),
772 snippetSuffix(
""))));
775 Opts.AllScopes =
true;
776 Results = completions(R
"cpp(
780 EXPECT_THAT(Results.Completions,
781 Contains(AllOf(named(
"func"), labeled(
"ns::func(int a, int b)"),
782 snippetSuffix(
""))));
785TEST(CompletionTest, Kinds) {
786 auto Results = completions(
791 // make sure MACRO is not included in preamble.
795 {func("indexFunction"),
var(
"indexVariable"),
cls(
"indexClass"),
796 macro(
"indexObjMacro"),
macro(
"indexFuncMacro",
"(x, y)")});
797 EXPECT_THAT(Results.Completions,
809 Results = completions(
"nam^");
810 EXPECT_THAT(Results.Completions,
814 Results = completions(
828 Results = completions(
830 template <class T> struct complete_class {};
831 template <class T> void complete_function();
832 template <class T> using complete_type_alias = int;
833 template <class T> int complete_variable = 10;
836 template <class T> static int complete_static_member = 10;
838 static auto x = complete_^
843 UnorderedElementsAre(
846 AllOf(named(
"complete_type_alias"),
849 AllOf(named(
"complete_static_member"),
852 Results = completions(
864TEST(CompletionTest, NoDuplicates) {
865 auto Results = completions(
877 EXPECT_THAT(Results.Completions, ElementsAre(named(
"Adapter")));
880TEST(CompletionTest, ScopedNoIndex) {
881 auto Results = completions(
883 namespace fake { int BigBang, Babble, Box; };
884 int main() { fake::ba^ }
887 EXPECT_THAT(Results.Completions,
888 ElementsAre(named(
"Babble"), named(
"BigBang")));
891TEST(CompletionTest, Scoped) {
892 auto Results = completions(
894 namespace fake { int Babble, Box; };
895 int main() { fake::ba^ }
897 {var("fake::BigBang")});
898 EXPECT_THAT(Results.Completions,
899 ElementsAre(named(
"Babble"), named(
"BigBang")));
902TEST(CompletionTest, ScopedWithFilter) {
903 auto Results = completions(
907 {cls("ns::XYZ"),
func(
"ns::foo")});
908 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named(
"XYZ")));
911TEST(CompletionTest, ReferencesAffectRanking) {
912 EXPECT_THAT(completions(
"int main() { abs^ }", {
func(
"absA"),
func(
"absB")})
915 EXPECT_THAT(completions(
"int main() { abs^ }",
916 {
func(
"absA"), withReferences(1000,
func(
"absB"))})
921TEST(CompletionTest, ContextWords) {
922 auto Results = completions(R
"cpp(
923 enum class Color { RED, YELLOW, BLUE };
925 // (blank lines so the definition above isn't "context")
927 // "It was a yellow car," he said. "Big yellow car, new."
928 auto Finish = Color::^
932 ASSERT_THAT(Results.Completions,
936TEST(CompletionTest, GlobalQualified) {
937 auto Results = completions(
942 EXPECT_THAT(Results.Completions,
947TEST(CompletionTest, FullyQualified) {
948 auto Results = completions(
950 namespace ns { void bar(); }
954 EXPECT_THAT(Results.Completions,
959TEST(CompletionTest, SemaIndexMerge) {
960 auto Results = completions(
962 namespace ns { int local; void both(); }
965 {func("ns::both"),
cls(
"ns::Index")});
967 EXPECT_THAT(Results.Completions,
968 UnorderedElementsAre(
975TEST(CompletionTest, SemaIndexMergeWithLimit) {
976 clangd::CodeCompleteOptions Opts;
978 auto Results = completions(
980 namespace ns { int local; void both(); }
983 {func("ns::both"),
cls(
"ns::Index")}, Opts);
984 EXPECT_EQ(Results.Completions.size(), Opts.Limit);
985 EXPECT_TRUE(Results.HasMore);
988TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
991 TU.AdditionalFiles[
"sub/bar.h"] =
"";
995 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
999 TU.Code = Test.code().str();
1000 auto Results = completions(TU, Test.point(), {Sym});
1001 EXPECT_THAT(Results.Completions,
1002 ElementsAre(AllOf(named(
"X"), insertInclude(
"\"bar.h\""))));
1006 Results = completions(TU, Test.point(), {Sym}, NoInsertion);
1007 EXPECT_THAT(Results.Completions,
1008 ElementsAre(AllOf(named(
"X"), Not(insertInclude()))));
1011 #include "sub/bar.h" // not shortest, so should only match resolved.
1012 int main() { ns::^ }
1014 TU.Code = Test.code().str();
1015 Results = completions(TU, Test.point(), {Sym});
1016 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(named("X"), labeled(
"X"),
1017 Not(insertInclude()))));
1020TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
1023 std::string BarHeader =
testPath(
"bar.h");
1025 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
1026 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
1030 auto Results = completions(R
"cpp(
1035 int main() { ns::^ }
1038 EXPECT_THAT(Results.Completions,
1039 ElementsAre(AllOf(named("X"), Not(insertInclude())),
1040 AllOf(named(
"Y"), Not(insertInclude()))));
1043TEST(CompletionTest, IncludeInsertionRespectsQuotedAngledConfig) {
1046 TU.AdditionalFiles[
"sub/bar.h"] =
"";
1050 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
1053 TU.Code = Test.code().str();
1054 auto Results = completions(TU, Test.point(), {Sym});
1056 EXPECT_THAT(Results.Completions,
1057 ElementsAre(AllOf(named(
"X"), insertInclude(
"\"bar.h\""))));
1060 C.Style.AngledHeaders.push_back(
1061 [](
auto header) {
return header.contains(
"bar.h"); });
1063 Results = completions(TU, Test.point(), {Sym});
1064 EXPECT_THAT(Results.Completions,
1065 ElementsAre(AllOf(named(
"X"), insertInclude(
"<bar.h>"))));
1069 C.Style.QuotedHeaders.push_back(
1070 [](
auto header) {
return header.contains(
"bar.h"); });
1072 Results = completions(TU, Test.point(), {Sym});
1073 EXPECT_THAT(Results.Completions,
1074 ElementsAre(AllOf(named(
"X"), insertInclude(
"\"bar.h\""))));
1078TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
1081 namespace ns { int local; }
1083 void f2() { ns::preamble().$2^; }
1086 TU.AdditionalFiles[
"bar.h"] =
1087 R
"cpp(namespace ns { struct preamble { int member; }; })cpp";
1089 clangd::CodeCompleteOptions Opts = {};
1090 auto I = memIndex({
var(
"ns::index")});
1091 Opts.Index = I.get();
1092 auto WithIndex = completions(TU, Test.point(), {}, Opts);
1093 EXPECT_THAT(WithIndex.Completions,
1094 UnorderedElementsAre(named(
"local"), named(
"index")));
1095 auto ClassFromPreamble = completions(TU, Test.point(
"2"), {}, Opts);
1096 EXPECT_THAT(ClassFromPreamble.Completions, Contains(named(
"member")));
1098 Opts.Index =
nullptr;
1099 auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
1100 EXPECT_THAT(WithoutIndex.Completions,
1101 UnorderedElementsAre(named(
"local"), named(
"preamble")));
1108TEST(CompletionTest, CompletionInPreamble) {
1109 auto Results = completions(R
"cpp(
1117 EXPECT_THAT(Results, ElementsAre(named("ifndef")));
1120TEST(CompletionTest, CompletionRecoveryASTType) {
1121 auto Results = completions(R
"cpp(
1122 struct S { int member; };
1125 // No overload matches, but we have recovery-expr with the correct type.
1129 EXPECT_THAT(Results, ElementsAre(named("member")));
1132TEST(CompletionTest, DynamicIndexIncludeInsertion) {
1136 Opts.BuildDynamicSymbolIndex =
true;
1139 FS.Files[
testPath(
"foo_header.h")] = R
"cpp(
1146 const std::string FileContent(R
"cpp(
1147 #include "foo_header.h"
1152 Server.addDocument(testPath("foo_impl.cpp"), FileContent);
1154 ASSERT_TRUE(Server.blockUntilIdleForTest());
1163 ElementsAre(AllOf(named(
"Foo"), hasInclude(
"\"foo_header.h\""),
1167TEST(CompletionTest, DynamicIndexMultiFile) {
1171 Opts.BuildDynamicSymbolIndex =
true;
1174 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1175 namespace ns { class XYZ {}; void foo(int x) {} }
1198 EXPECT_THAT(Results.Completions,
1200 doc(
"Doooc"), returnType(
"void"))));
1203TEST(CompletionTest, Documentation) {
1204 auto Results = completions(
1206 // Non-doxygen comment.
1207 __attribute__((annotate("custom_annotation"))) int foo();
1219 Results.Completions,
1222 doc(
"Annotation: custom_annotation\n\nNon-doxygen comment."))));
1224 Results.Completions,
1225 Contains(AllOf(named(
"bar"), doc(
"Doxygen comment.\n\\param int a"))));
1226 EXPECT_THAT(Results.Completions,
1227 Contains(AllOf(named(
"baz"), doc(
"Multi-line block comment"))));
1230TEST(CompletionTest, CommentsFromSystemHeaders) {
1235 Opts.BuildDynamicSymbolIndex =
true;
1239 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1240 #pragma GCC system_header
1242 // This comment should be retained!
1257 Contains(AllOf(named(
"foo"), doc(
"This comment should be retained!"))));
1260TEST(CompletionTest, CommentsOnMembersFromHeader) {
1265 Opts.BuildDynamicSymbolIndex =
true;
1269 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1278 template <typename T>
1301 Contains(AllOf(named(
"gamma"), doc(
"This is a member field."))));
1304 Contains(AllOf(named(
"delta"), doc(
"This is a member function."))));
1310 Contains(AllOf(named(
"omega")
1314 Contains(AllOf(named(
"epsilon"),
1315 doc(
"This is a member function inside a template."))));
1318TEST(CompletionTest, CommentsOnMembersFromHeaderOverloadBundling) {
1319 using testing::AnyOf;
1324 Opts.BuildDynamicSymbolIndex =
true;
1328 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1336 void epsilon(long l);
1339 void epsilon(int i);
1350 clangd::CodeCompleteOptions CCOpts;
1351 CCOpts.BundleOverloads = true;
1357 Contains(AllOf(named(
"epsilon"), doc(
"This one has a comment."))));
1359 Contains(AllOf(named(
"delta"), AnyOf(doc(
"bool overload."),
1360 doc(
"int overload.")))));
1363TEST(CompletionTest, GlobalCompletionFiltering) {
1372 auto Results = completions(R
"(// void f() {
1376 EXPECT_THAT(Results.Completions, IsEmpty());
1379TEST(CodeCompleteTest, DisableTypoCorrection) {
1380 auto Results = completions(R
"cpp(
1381 namespace clang { int v; }
1382 void f() { clangd::^
1384 EXPECT_TRUE(Results.Completions.empty());
1387TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
1388 auto Results = completions(R
"cpp(
1395 EXPECT_THAT(Results.Completions, Contains(labeled("clang")));
1396 EXPECT_THAT(Results.Completions, Not(Contains(labeled(
"clang::"))));
1399TEST(CompletionTests, EmptySnippetDoesNotCrash) {
1401 auto Results = completions(R
"cpp(
1403 auto w = [&](auto &&f) { return f(f); };
1404 auto f = w([&](auto &&f) {
1405 return [&](auto &&n) {
1409 return n * ^(f)(n - 1);
1416TEST(CompletionTest, Issue1427Crash) {
1422 Opts.MainFileSignals = &MainFileSignals;
1431TEST(CompletionTest, BacktrackCrashes) {
1433 auto Results = completions(R
"cpp(
1435 struct FooBarBaz {};
1441 EXPECT_THAT(Results.Completions, ElementsAre(labeled("FooBarBaz")));
1445 struct FooBarBaz {};
1447 if (FooBarBaz * x^) {}
1452TEST(CompletionTest, CompleteInMacroWithStringification) {
1453 auto Results = completions(R
"cpp(
1454void f(const char *, int x);
1455#define F(x) f(#x, x)
1462int f(int input_num) {
1467 EXPECT_THAT(Results.Completions,
1468 UnorderedElementsAre(named("X"), named(
"Y")));
1471TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
1472 auto Results = completions(R
"cpp(
1473void f(const char *, int x);
1474#define F(x) f(#x, x)
1479int f(int input_num) {
1485 EXPECT_THAT(Results.Completions, Contains(named("X")));
1488TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
1489 auto Results = completions(R
"cpp(
1490 int bar(int param_in_bar) {
1493 int foo(int param_in_foo) {
1495 // In recovery mode, "param_in_foo" will also be suggested among many other
1496 // unrelated symbols; however, this is really a special case where this works.
1497 // If the #if block is outside of the function, "param_in_foo" is still
1498 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
1499 // really provide useful results in excluded branches.
1505 EXPECT_TRUE(Results.Completions.empty());
1508TEST(CompletionTest, DefaultArgs) {
1509 clangd::CodeCompleteOptions Opts;
1512 int Y(int A, int B = 0);
1513 int Z(int A, int B = 0, int C = 0, int D = 0);
1515 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions,
1516 UnorderedElementsAre(labeled(
"X(int A = 0)")));
1517 EXPECT_THAT(completions(
Context +
"int y = Y^", {}, Opts).Completions,
1518 UnorderedElementsAre(AllOf(labeled(
"Y(int A, int B = 0)"),
1519 snippetSuffix(
"(${1:int A})"))));
1520 EXPECT_THAT(completions(
Context +
"int y = Z^", {}, Opts).Completions,
1521 UnorderedElementsAre(
1522 AllOf(labeled(
"Z(int A, int B = 0, int C = 0, int D = 0)"),
1523 snippetSuffix(
"(${1:int A})"))));
1526TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) {
1527 auto Completions = completions(R
"cpp(
1528template <template <class> class TT> int foo() {
1533 EXPECT_THAT(Completions, Contains(named("TT")));
1536TEST(CompletionTest, NestedTemplateHeuristics) {
1537 auto Completions = completions(R
"cpp(
1538struct Plain { int xxx; };
1539template <typename T> class Templ { Plain ppp; };
1540template <typename T> void foo(Templ<T> &t) {
1541 // Formally ppp has DependentTy, because Templ may be specialized.
1542 // However we sholud be able to see into it using the primary template.
1547 EXPECT_THAT(Completions, Contains(named("xxx")));
1550TEST(CompletionTest, RecordCCResultCallback) {
1551 std::vector<CodeCompletion> RecordedCompletions;
1553 Opts.RecordCCResult = [&RecordedCompletions](
const CodeCompletion &CC,
1557 RecordedCompletions.push_back(CC);
1560 completions(
"int xy1, xy2; int a = xy^", {}, Opts);
1561 EXPECT_THAT(RecordedCompletions,
1562 UnorderedElementsAre(named(
"xy1"), named(
"xy2")));
1568 unsigned MainFileRefs;
1569 unsigned ScopeRefsInFile;
1572 std::vector<Completion> RecordedCompletions;
1573 Opts.RecordCCResult = [&RecordedCompletions](
const CodeCompletion &CC,
1577 RecordedCompletions.push_back({CC.Name, R.MainFileRefs, R.ScopeRefsInFile});
1581 MainFileSignals.ReferencedSymbols[
var(
"xy2").
ID] = 1;
1582 MainFileSignals.ReferencedSymbols[
var(
"xyindex").
ID] = 10;
1583 MainFileSignals.RelatedNamespaces[
"tar::"] = 5;
1584 MainFileSignals.RelatedNamespaces[
"bar::"] = 3;
1585 Opts.MainFileSignals = &MainFileSignals;
1586 Opts.AllScopes =
true;
1596 {
var(
"xyindex"),
var(
"tar::xytar"),
var(
"bar::xybar")},
1598 EXPECT_THAT(RecordedCompletions,
1599 UnorderedElementsAre(
1600 AllOf(named(
"xy1"), mainFileRefs(3u), scopeRefs(0u)),
1601 AllOf(named(
"xy2"), mainFileRefs(1u), scopeRefs(0u)),
1602 AllOf(named(
"xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1603 AllOf(named(
"xytar"), mainFileRefs(0u), scopeRefs(5u)),
1604 AllOf( named(
"xybar"),
1605 mainFileRefs(0u), scopeRefs(3u))));
1610 std::vector<Symbol> IndexSymbols = {},
1612 std::unique_ptr<SymbolIndex> Index;
1613 if (!IndexSymbols.empty())
1614 Index = memIndex(IndexSymbols);
1618 auto Inputs = TU.inputs(FS);
1619 Inputs.Index = Index.get();
1623 ADD_FAILURE() <<
"Couldn't build CompilerInvocation";
1629 ADD_FAILURE() <<
"Couldn't build Preamble";
1633 DocumentationFormat);
1637signatures(llvm::StringRef
Text, std::vector<Symbol> IndexSymbols = {},
1640 return signatures(Test.code(), Test.point(), std::move(IndexSymbols),
1641 DocumentationFormat);
1644struct ExpectedParameter {
1646 std::pair<unsigned, unsigned> Offsets;
1648llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS,
1649 const ExpectedParameter &P) {
1650 return OS <<
P.Text;
1653 if (
P.size() != arg.parameters.size())
1655 for (
unsigned I = 0; I <
P.size(); ++I) {
1656 if (P[I].
Text != arg.parameters[I].labelString ||
1657 P[I].Offsets != arg.parameters[I].labelOffsets)
1662MATCHER_P(sigDoc, doc,
"") {
return arg.documentation.value == doc; }
1666Matcher<SignatureInformation> sig(llvm::StringRef AnnotatedLabel) {
1667 llvm::Annotations
A(AnnotatedLabel);
1668 std::string
Label = std::string(
A.code());
1669 std::vector<ExpectedParameter> Parameters;
1670 for (
auto Range :
A.ranges()) {
1671 Parameters.emplace_back();
1673 ExpectedParameter &
P = Parameters.back();
1678 return AllOf(sigHelpLabeled(
Label), paramsAre(Parameters));
1681TEST(SignatureHelpTest, Overloads) {
1682 auto Results = signatures(R
"cpp(
1683 void foo(int x, int y);
1684 void foo(int x, float y);
1685 void foo(float x, int y);
1686 void foo(float x, float y);
1687 void bar(int x, int y = 0);
1688 int main() { foo(^); }
1690 EXPECT_THAT(Results.signatures,
1691 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1692 sig(
"foo([[float x]], [[int y]]) -> void"),
1693 sig(
"foo([[int x]], [[float y]]) -> void"),
1694 sig(
"foo([[int x]], [[int y]]) -> void")));
1696 EXPECT_EQ(0, Results.activeSignature);
1697 EXPECT_EQ(0, Results.activeParameter);
1700TEST(SignatureHelpTest, DeclParamName) {
1706 auto FuncFromSource = signatures(R
"cpp(
1708 void sun(int night);
1715 EXPECT_THAT(FuncFromSource.signatures,
1716 UnorderedElementsAre(sig("sun([[int day]]) -> void")));
1719TEST(SignatureHelpTest, FunctionPointers) {
1720 llvm::StringLiteral Tests[] = {
1723 void (*foo)(int x, int y);
1724 int main() { foo(^); }
1728 void (__stdcall *foo)(int x, int y);
1729 int main() { foo(^); }
1733 void (__attribute__(stdcall) *foo)(int x, int y);
1734 int main() { foo(^); },
1738 typedef void (*fn)(int x, int y);
1740 int main() { foo(^); }
1744 typedef void (__stdcall *fn)(int x, int y);
1746 int main() { foo(^); }
1751 void (*foo)(int x, int y);
1754 int main() { s.foo(^); }
1758 typedef void (*fn)(int x, int y);
1763 int main() { s.foo(^); }
1765 for (
auto Test : Tests)
1766 EXPECT_THAT(signatures(Test).signatures,
1767 UnorderedElementsAre(sig(
"([[int x]], [[int y]]) -> void")));
1770TEST(SignatureHelpTest, Constructors) {
1771 std::string Top = R
"cpp(
1774 S(const S &) = delete;
1778 auto CheckParenInit = [&](std::string Init) {
1779 EXPECT_THAT(signatures(Top + Init).signatures,
1780 UnorderedElementsAre(sig(
"S([[int]])")))
1783 CheckParenInit(
"S s(^);");
1784 CheckParenInit(
"auto s = S(^);");
1785 CheckParenInit(
"auto s = new S(^);");
1787 auto CheckBracedInit = [&](std::string Init) {
1788 EXPECT_THAT(signatures(Top + Init).signatures,
1789 UnorderedElementsAre(sig(
"S{[[int]]}")))
1792 CheckBracedInit(
"S s{^};");
1793 CheckBracedInit(
"S s = {^};");
1794 CheckBracedInit(
"auto s = S{^};");
1797 CheckBracedInit(
"int x(S); int i = x({^});");
1800TEST(SignatureHelpTest, Aggregates) {
1801 std::string Top = R
"cpp(
1806 auto AggregateSig = sig(
"S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1807 EXPECT_THAT(signatures(Top +
"S s{^}").signatures,
1808 UnorderedElementsAre(AggregateSig, sig(
"S{}"),
1809 sig(
"S{[[const S &]]}"),
1810 sig(
"S{[[S &&]]}")));
1811 EXPECT_THAT(signatures(Top +
"S s{1,^}").signatures,
1812 ElementsAre(AggregateSig));
1813 EXPECT_EQ(signatures(Top +
"S s{1,^}").activeParameter, 1);
1814 EXPECT_THAT(signatures(Top +
"S s{.c=3,^}").signatures,
1815 ElementsAre(AggregateSig));
1816 EXPECT_EQ(signatures(Top +
"S s{.c=3,^}").activeParameter, 3);
1819TEST(SignatureHelpTest, OverloadInitListRegression) {
1820 auto Results = signatures(R
"cpp(
1829 EXPECT_THAT(Results.signatures, UnorderedElementsAre(sig("f() -> void")));
1832TEST(SignatureHelpTest, DefaultArgs) {
1833 auto Results = signatures(R
"cpp(
1834 void bar(int x, int y = 0);
1835 void bar(float x = 0, int y = 42);
1838 EXPECT_THAT(Results.signatures,
1839 UnorderedElementsAre(
1840 sig("bar([[int x]], [[int y = 0]]) -> void"),
1841 sig(
"bar([[float x = 0]], [[int y = 42]]) -> void")));
1842 EXPECT_EQ(0, Results.activeSignature);
1843 EXPECT_EQ(0, Results.activeParameter);
1846TEST(SignatureHelpTest, ActiveArg) {
1847 auto Results = signatures(R
"cpp(
1848 int baz(int a, int b, int c);
1849 int main() { baz(baz(1,2,3), ^); }
1851 EXPECT_THAT(Results.signatures,
1852 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1853 EXPECT_EQ(0, Results.activeSignature);
1854 EXPECT_EQ(1, Results.activeParameter);
1857TEST(SignatureHelpTest, OpeningParen) {
1858 llvm::StringLiteral Tests[] = {
1861 int foo(int a, int b, int c);
1863 foo(foo $p^( foo(10, 10, 10), ^ )));
1868 Foo(int a, int b, int c);
1876 Foo(int a, int b, int c);
1879 new Foo $p^( 10, ^ );
1883 int foo(int a, int b, int c);
1887 // Macro expansions.
1892 int foo(int a, int b, int c);
1895 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1896 // the recovery expression.
1897 ID(foo $p^( 10, ^ ))
1901 int foo(int a, int b);
1902 template <typename T> void bar(T t) {
1907 template <typename T>
1909 template <typename T> void bar(T t) {
1914 struct Foo { int foo(int, int); };
1915 template <typename T> void bar(T t) {
1921 struct Foo { template <typename T> int foo(T, T); };
1922 template <typename T> void bar(T t) {
1928 for (
auto Test : Tests) {
1930 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
1932 <<
"Test source:" << Test;
1936TEST(SignatureHelpTest, StalePreamble) {
1941 auto Inputs = TU.inputs(FS);
1946 ASSERT_TRUE(EmptyPreamble);
1948 TU.AdditionalFiles[
"a.h"] =
"int foo(int x);";
1951 void bar() { foo(^2); })cpp");
1952 TU.Code = Test.code().str();
1956 EXPECT_THAT(Results.signatures, ElementsAre(sig(
"foo([[int x]]) -> int")));
1957 EXPECT_EQ(0, Results.activeSignature);
1958 EXPECT_EQ(0, Results.activeParameter);
1961TEST(SignatureHelpTest, EOFInSkippedFunctionBody) {
1964void frameSizeBlocksWarning() {
1974 auto Results = signatures(Test.code(), Test.point());
1975 EXPECT_THAT(Results.signatures, IsEmpty());
1980 IndexRequestCollector(std::vector<Symbol> Syms = {}) : Symbols(Syms) {}
1983 fuzzyFind(
const FuzzyFindRequest &Req,
1984 llvm::function_ref<
void(
const Symbol &)>
Callback)
const override {
1985 std::unique_lock<std::mutex> Lock(Mut);
1986 Requests.push_back(Req);
1987 ReceivedRequestCV.notify_one();
1988 for (
const auto &Sym : Symbols)
1993 void lookup(
const LookupRequest &,
1994 llvm::function_ref<
void(
const Symbol &)>)
const override {}
1996 bool refs(
const RefsRequest &,
1997 llvm::function_ref<
void(
const Ref &)>)
const override {
2002 const ContainedRefsRequest &,
2003 llvm::function_ref<
void(
const ContainedRefsResult &)>)
const override {
2007 void relations(
const RelationsRequest &,
2008 llvm::function_ref<
void(
const SymbolID &,
const Symbol &)>)
2012 reverseRelations(
const RelationsRequest &,
2013 llvm::function_ref<
void(
const SymbolID &,
const Symbol &)>)
2017 indexedFiles()
const override {
2023 size_t estimateMemoryUsage()
const override {
return 0; }
2025 const std::vector<FuzzyFindRequest> consumeRequests(
size_t Num)
const {
2026 std::unique_lock<std::mutex> Lock(Mut);
2028 [
this, Num] {
return Requests.size() == Num; }));
2029 auto Reqs = std::move(Requests);
2035 std::vector<Symbol> Symbols;
2037 mutable std::condition_variable ReceivedRequestCV;
2038 mutable std::mutex Mut;
2039 mutable std::vector<FuzzyFindRequest> Requests;
2043std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code,
2045 clangd::CodeCompleteOptions Opts;
2046 IndexRequestCollector Requests;
2047 Opts.Index = &Requests;
2048 completions(Code, {}, Opts);
2049 const auto Reqs = Requests.consumeRequests(Num);
2050 EXPECT_EQ(Reqs.size(), Num);
2054TEST(CompletionTest, UnqualifiedIdQuery) {
2055 auto Requests = captureIndexRequests(R
"cpp(
2057 using namespace std;
2065 EXPECT_THAT(Requests,
2067 UnorderedElementsAre("",
"ns::",
"std::"))));
2070TEST(CompletionTest, EnclosingScopeComesFirst) {
2071 auto Requests = captureIndexRequests(R
"cpp(
2073 using namespace std;
2085 EXPECT_THAT(Requests,
2088 UnorderedElementsAre("",
"std::",
"nx::ns::",
"nx::"))));
2089 EXPECT_EQ(Requests[0].Scopes[0],
"nx::ns::");
2092TEST(CompletionTest, ResolvedQualifiedIdQuery) {
2093 auto Requests = captureIndexRequests(R
"cpp(
2095 namespace ns2 {} // ignore
2096 namespace ns3 { namespace nns3 {} }
2098 using namespace ns1;
2099 using namespace ns3::nns3;
2108 EXPECT_THAT(Requests,
2111 UnorderedElementsAre("foo::",
"ns1::",
"ns3::nns3::"))));
2114TEST(CompletionTest, UnresolvedQualifierIdQuery) {
2115 auto Requests = captureIndexRequests(R
"cpp(
2125 EXPECT_THAT(Requests,
2128 UnorderedElementsAre("a::bar::",
"ns::bar::",
"bar::"))));
2131TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
2132 auto Requests = captureIndexRequests(R
"cpp(
2143 UnorderedElementsAre("a::bar::"))));
2146TEST(CompletionTest, EmptyQualifiedQuery) {
2147 auto Requests = captureIndexRequests(R
"cpp(
2156 UnorderedElementsAre("",
"ns::"))));
2159TEST(CompletionTest, GlobalQualifiedQuery) {
2160 auto Requests = captureIndexRequests(R
"cpp(
2169 UnorderedElementsAre(""))));
2172TEST(CompletionTest, NoDuplicatedQueryScopes) {
2173 auto Requests = captureIndexRequests(R
"cpp(
2184 EXPECT_THAT(Requests,
2186 UnorderedElementsAre("na::",
"na::nb::",
""))));
2189TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
2190 auto Completions = completions(
2193 int SomeNameOfField;
2194 typedef int SomeNameOfTypedefField;
2198 {func("::SomeNameInTheIndex"),
func(
"::Foo::SomeNameInTheIndex")});
2200 EXPECT_THAT(Completions.Completions,
2201 AllOf(Contains(labeled(
"SomeNameOfField")),
2202 Contains(labeled(
"SomeNameOfTypedefField")),
2203 Not(Contains(labeled(
"SomeNameInTheIndex")))));
2206TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
2208 auto Completions = completions(
2215 {func("::SomeNameInTheIndex")});
2217 EXPECT_THAT(Completions.Completions,
2218 Not(Contains(labeled(
"SomeNameInTheIndex"))));
2222 auto Completions = completions(
2226 T::template Y<int>::^
2229 {func("::SomeNameInTheIndex")});
2231 EXPECT_THAT(Completions.Completions,
2232 Not(Contains(labeled(
"SomeNameInTheIndex"))));
2236 auto Completions = completions(
2243 {func("::SomeNameInTheIndex")});
2245 EXPECT_THAT(Completions.Completions,
2246 Not(Contains(labeled(
"SomeNameInTheIndex"))));
2250TEST(CompletionTest, OverloadBundling) {
2251 clangd::CodeCompleteOptions Opts;
2252 Opts.BundleOverloads =
true;
2256 // Overload with int
2257 int a(int) __attribute__((deprecated("", "")));
2258 // Overload with bool
2270 EXPECT_THAT(completions(
Context +
"int y = X().^", {}, Opts).Completions,
2271 UnorderedElementsAre(labeled(
"a(…)"), labeled(
"b(float)")));
2274 EXPECT_THAT(completions(
Context +
"X z = X^", {}, Opts).Completions,
2275 UnorderedElementsAre(labeled(
"X"), labeled(
"X(…)")));
2280 completions(
Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
2281 UnorderedElementsAre(labeled(
"GFuncC(…)"), labeled(
"GFuncD(int)")));
2285 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
2288 completions(
Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
2289 UnorderedElementsAre(AllOf(named(
"GFuncC"), insertInclude(
"<foo>")),
2290 labeled(
"GFuncC(int)"), labeled(
"GFuncD(int)")));
2294 completions(
Context +
"int y = X().a^", {}, Opts).Completions.front();
2295 EXPECT_EQ(
A.Name,
"a");
2296 EXPECT_EQ(
A.Signature,
"(…)");
2297 EXPECT_EQ(
A.BundleSize, 2u);
2299 EXPECT_EQ(
A.ReturnType,
"int");
2301 ASSERT_TRUE(
A.Documentation);
2302 ASSERT_FALSE(
A.Deprecated);
2304 A.Documentation->asPlainText(),
2305 AnyOf(HasSubstr(
"Overload with int"), HasSubstr(
"Overload with bool")));
2306 EXPECT_EQ(
A.SnippetSuffix,
"($0)");
2309TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
2310 clangd::CodeCompleteOptions Opts;
2311 Opts.BundleOverloads =
true;
2313 Symbol SymX =
sym(
"ns::X", index::SymbolKind::Function,
"@F@\\0#");
2314 Symbol SymY =
sym(
"ns::X", index::SymbolKind::Function,
"@F@\\0#I#");
2315 std::string BarHeader =
testPath(
"bar.h");
2317 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
2318 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
2323 auto Results = completions(
"void f() { ::ns::^ }", {SymX, SymY}, Opts);
2326 ASSERT_EQ(1u, Results.Completions.size());
2327 const auto &R = Results.Completions.front();
2328 EXPECT_EQ(
"X", R.Name);
2329 EXPECT_EQ(2u, R.BundleSize);
2332TEST(CompletionTest, DocumentationFromChangedFileCrash) {
2336 FS.Files[FooH] = R
"cpp(
2337 // this is my documentation comment.
2340 FS.Files[FooCpp] = "";
2348 // This makes sure we have func from header in the AST.
2354 ASSERT_TRUE(Server.blockUntilIdleForTest());
2357 FS.Files[FooH] = R
"cpp(
2361 clangd::CodeCompleteOptions Opts;
2362 CodeCompleteResult Completions =
2366 EXPECT_THAT(Completions.Completions,
2367 Contains(AllOf(Not(isDocumented()), named(
"func"))));
2370TEST(CompletionTest, NonDocComments) {
2371 const char *
Text = R
"cpp(
2372 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
2373 namespace comments_ns {
2376 // ------------------
2379 // A comment and a decl are separated by newlines.
2380 // Therefore, the comment shouldn't show up as doc comment.
2384 // this comment should be in the results.
2391 int comments_quux();
2395 // This comment should not be there.
2398 int Struct<T>::comments_qux() {
2401 // This comment **should** be in results.
2403 int Struct<T>::comments_quux() {
2410 completions(
Text).Completions,
2411 UnorderedElementsAre(AllOf(Not(isDocumented()), named(
"comments_foo")),
2412 AllOf(isDocumented(), named(
"comments_baz")),
2413 AllOf(isDocumented(), named(
"comments_quux")),
2414 AllOf(Not(isDocumented()), named(
"comments_ns")),
2419 AllOf(isDocumented(), named(
"comments_bar")),
2420 AllOf(isDocumented(), named(
"comments_qux"))));
2423TEST(CompletionTest, CompleteOnInvalidLine) {
2428 FS.
Files[FooCpp] =
"// empty file";
2435 EXPECT_THAT_EXPECTED(
2440TEST(CompletionTest, QualifiedNames) {
2441 auto Results = completions(
2443 namespace ns { int local; void both(); }
2444 void f() { ::ns::^ }
2446 {func("ns::both"),
cls(
"ns::Index")});
2449 Results.Completions,
2450 UnorderedElementsAre(scope(
"ns::"), scope(
"ns::"), scope(
"ns::")));
2453TEST(CompletionTest, Render) {
2457 C.Signature =
"(bool) const";
2458 C.SnippetSuffix =
"(${0:bool})";
2459 C.ReturnType =
"int";
2460 C.RequiredQualifier =
"Foo::";
2461 C.Scope =
"ns::Foo::";
2462 C.Documentation.emplace();
2463 C.Documentation->addParagraph().appendText(
"This is ").appendCode(
"x()");
2464 C.Includes.emplace_back();
2465 auto &Include =
C.Includes.back();
2466 Include.Header =
"\"foo.h\"";
2468 C.Score.Total = 1.0;
2469 C.Score.ExcludingName = .5;
2473 Opts.IncludeIndicator.Insert =
"^";
2474 Opts.IncludeIndicator.NoInsert =
"";
2475 Opts.EnableSnippets =
false;
2477 auto R =
C.render(Opts);
2478 EXPECT_EQ(R.label,
"Foo::x");
2479 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2480 EXPECT_EQ(R.insertText,
"Foo::x");
2482 EXPECT_EQ(R.filterText,
"x");
2483 EXPECT_EQ(R.detail,
"int");
2484 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\n\nThis is x()");
2485 EXPECT_THAT(R.additionalTextEdits, IsEmpty());
2486 EXPECT_EQ(R.sortText,
sortText(1.0,
"x"));
2487 EXPECT_FALSE(R.deprecated);
2488 EXPECT_EQ(R.score, .5f);
2490 C.FilterText =
"xtra";
2492 EXPECT_EQ(R.filterText,
"xtra");
2493 EXPECT_EQ(R.sortText,
sortText(1.0,
"xtra"));
2495 Opts.EnableSnippets =
true;
2497 EXPECT_EQ(R.insertText,
"Foo::x(${0:bool})");
2500 C.SnippetSuffix =
"";
2502 EXPECT_EQ(R.insertText,
"Foo::x");
2505 Include.Insertion.emplace();
2507 EXPECT_EQ(R.label,
"^Foo::x");
2508 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2509 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
2511 Opts.ShowOrigins =
true;
2513 EXPECT_EQ(R.label,
"^[AS]Foo::x");
2514 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2518 EXPECT_EQ(R.detail,
"[2 overloads]");
2519 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\n\nThis is x()");
2521 C.Deprecated =
true;
2523 EXPECT_TRUE(R.deprecated);
2527 EXPECT_EQ(R.documentation->value,
"From `\"foo.h\"`\n\nThis is `x()`");
2530TEST(CompletionTest, IgnoreRecoveryResults) {
2531 auto Results = completions(
2533 namespace ns { int NotRecovered() { return 0; } }
2535 // Sema enters recovery mode first and then normal mode.
2536 if (auto x = ns::NotRecover^)
2539 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("NotRecovered")));
2542TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
2543 auto Results = completions(
2546 class X { public: X(); int x_; };
2550 EXPECT_THAT(Results.Completions,
2551 UnorderedElementsAre(AllOf(scope("ns::X::"), named(
"x_"))));
2558TEST(CompletionTest, ConstructorInitListIncomplete) {
2559 auto Results = completions(
2568 EXPECT_THAT(Results.Completions, ElementsAre(named("xyz_")));
2570 Results = completions(
2581 EXPECT_THAT(Results.Completions, ElementsAre(named("foo")));
2584TEST(CompletionTest, CodeCompletionContext) {
2585 auto Results = completions(
2588 class X { public: X(); int x_; };
2596 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
2599TEST(CompletionTest, OffsetOfDesignator) {
2600 auto Results = completions(R
"cpp(
2601 struct S { int field; int other; void fieldFn(); };
2602 int x = __builtin_offsetof(S, fiel^d);
2605 Results.Completions,
2607 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
2609 Results = completions(R
"cpp(
2610 struct Inner { int field; void fieldFn(); };
2611 struct Outer { Inner inner; };
2612 int x = __builtin_offsetof(Outer, inner.fiel^d);
2615 Results.Completions,
2618 Results = completions(R
"cpp(
2619 struct Inner { int field; void fieldFn(); };
2620 struct Outer { Inner inner[2]; };
2622 int x = __builtin_offsetof(Outer, inner[i].fiel^d);
2625 Results.Completions,
2628 Results = completions(R
"cpp(
2629 struct Base { int field; void fieldFn(); };
2630 struct Derived : Base {};
2631 int x = __builtin_offsetof(Derived, fiel^d);
2634 Results.Completions,
2638TEST(CompletionTest, FixItForArrowToDot) {
2643 Opts.IncludeFixIts =
true;
2650 class ClassWithPtr {
2652 void MemberFunction();
2653 Auxilary* operator->() const;
2661 auto Results = completions(Code, {}, Opts);
2662 EXPECT_EQ(Results.Completions.size(), 3u);
2666 ReplacementEdit.newText =
".";
2667 for (
const auto &C : Results.Completions) {
2668 EXPECT_TRUE(
C.FixIts.size() == 1u ||
C.Name ==
"AuxFunction");
2669 if (!
C.FixIts.empty()) {
2670 EXPECT_THAT(
C.FixIts, ElementsAre(ReplacementEdit));
2675TEST(CompletionTest, FixItForDotToArrow) {
2677 Opts.IncludeFixIts =
true;
2684 class ClassWithPtr {
2686 void MemberFunction();
2687 Auxilary* operator->() const;
2695 auto Results = completions(Code, {}, Opts);
2696 EXPECT_EQ(Results.Completions.size(), 3u);
2700 ReplacementEdit.newText =
"->";
2701 for (
const auto &C : Results.Completions) {
2702 EXPECT_TRUE(
C.FixIts.empty() ||
C.Name ==
"AuxFunction");
2703 if (!
C.FixIts.empty()) {
2704 EXPECT_THAT(
C.FixIts, ElementsAre(ReplacementEdit));
2709TEST(CompletionTest, RenderWithFixItMerged) {
2712 FixIt.newText =
"->";
2716 C.RequiredQualifier =
"Foo::";
2718 C.CompletionInsertRange.start.character = 5;
2721 Opts.IncludeFixIts =
true;
2723 auto R =
C.render(Opts);
2724 EXPECT_TRUE(R.textEdit);
2725 EXPECT_EQ(std::get<TextEdit>(*R.textEdit).newText,
"->Foo::x");
2726 EXPECT_TRUE(R.additionalTextEdits.empty());
2729TEST(CompletionTest, RenderWithFixItNonMerged) {
2732 FixIt.newText =
"->";
2736 C.RequiredQualifier =
"Foo::";
2738 C.CompletionInsertRange.start.character = 5;
2741 Opts.IncludeFixIts =
true;
2743 auto R =
C.render(Opts);
2744 EXPECT_TRUE(R.textEdit);
2745 EXPECT_EQ(std::get<TextEdit>(*R.textEdit).newText,
"Foo::x");
2746 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt));
2749TEST(CompletionTest, CompletionInsertRange) {
2755 constexpr const char *TestCodes[] = {
2777 #include "foo/[[a^/]]foo.h"
2780 #include "foo/abc/[[fo^o.h"]]
2783 for (
const auto &
Text : TestCodes) {
2785 TU.Code = TestCode.code().str();
2786 auto Results = completions(TU, TestCode.point());
2787 if (Results.Completions.size() != 1) {
2788 ADD_FAILURE() <<
"Results.Completions.size() != 1" <<
Text;
2791 EXPECT_THAT(Results.Completions.front().CompletionInsertRange,
2796TEST(SignatureHelpTest, OverloadsOrdering) {
2797 const auto Results = signatures(R
"cpp(
2799 void foo(int x, float y);
2800 void foo(float x, int y);
2801 void foo(float x, float y);
2802 void foo(int x, int y = 0);
2803 int main() { foo(^); }
2805 EXPECT_THAT(Results.signatures,
2806 ElementsAre(sig("foo([[int x]]) -> void"),
2807 sig(
"foo([[int x]], [[int y = 0]]) -> void"),
2808 sig(
"foo([[float x]], [[int y]]) -> void"),
2809 sig(
"foo([[int x]], [[float y]]) -> void"),
2810 sig(
"foo([[float x]], [[float y]]) -> void")));
2812 EXPECT_EQ(0, Results.activeSignature);
2813 EXPECT_EQ(0, Results.activeParameter);
2816TEST(SignatureHelpTest, InstantiatedSignatures) {
2817 StringRef Sig0 = R
"cpp(
2826 EXPECT_THAT(signatures(Sig0).signatures,
2827 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2829 StringRef Sig1 = R
"cpp(
2837 EXPECT_THAT(signatures(Sig1).signatures,
2838 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2840 StringRef Sig2 = R
"cpp(
2841 template <class ...T>
2849 EXPECT_THAT(signatures(Sig2).signatures,
2850 ElementsAre(sig("foo([[T...]]) -> void")));
2857 StringRef Sig3 = R
"cpp(
2865 X<int>().foo<double>(^)
2869 EXPECT_THAT(signatures(Sig3).signatures,
2870 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2873TEST(SignatureHelpTest, IndexDocumentation) {
2874 Symbol Foo0 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#");
2875 Foo0.Documentation =
"doc from the index";
2876 Symbol Foo1 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#");
2877 Foo1.Documentation =
"doc from the index";
2878 Symbol Foo2 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#I#");
2880 StringRef Sig0 = R
"cpp(
2890 signatures(Sig0, {Foo0}).signatures,
2891 ElementsAre(AllOf(sig("foo() -> int"), sigDoc(
"doc from the index")),
2892 AllOf(sig(
"foo([[double]]) -> int"), sigDoc(
""))));
2894 StringRef Sig1 = R
"cpp(
2896 // Overriden doc from sema
2907 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
2909 AllOf(sig("foo() -> int"), sigDoc(
"doc from the index")),
2910 AllOf(sig(
"foo([[int]]) -> int"), sigDoc(
"Overriden doc from sema")),
2911 AllOf(sig(
"foo([[int]], [[int]]) -> int"), sigDoc(
"doc from sema"))));
2914TEST(SignatureHelpTest, DynamicIndexDocumentation) {
2918 Opts.BuildDynamicSymbolIndex =
true;
2921 FS.Files[
testPath(
"foo.h")] = R
"cpp(
2935 Server.addDocument(
File, FileContent.code());
2937 ASSERT_TRUE(Server.blockUntilIdleForTest());
2941 ElementsAre(AllOf(sig(
"foo() -> int"), sigDoc(
"Member doc"))));
2944TEST(CompletionTest, ArgumentListsPolicy) {
2946 Opts.EnableSnippets =
true;
2950 auto Results = completions(
2953 void xfoo(int x, int y);
2954 void f() { xfo^ })cpp",
2957 Results.Completions,
2958 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"()")),
2959 AllOf(named(
"xfoo"), snippetSuffix(
"($0)"))));
2962 auto Results = completions(
2965 void f() { xba^ })cpp",
2967 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2968 named("xbar"), snippetSuffix(
"()"))));
2971 Opts.BundleOverloads =
true;
2972 auto Results = completions(
2975 void xfoo(int x, int y);
2976 void f() { xfo^ })cpp",
2979 Results.Completions,
2980 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"($0)"))));
2983 auto Results = completions(
2985 template <class T, class U>
2986 void xfoo(int a, U b);
2987 void f() { xfo^ })cpp",
2990 Results.Completions,
2991 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"<$1>($0)"))));
2994 auto Results = completions(
2999 struct foo_struct{};
3001 using foo_alias = T**;
3004 void f() { foo_^ })cpp",
3007 Results.Completions,
3008 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix(
"<$0>")),
3009 AllOf(named(
"foo_struct"), snippetSuffix(
"<$0>")),
3010 AllOf(named(
"foo_alias"), snippetSuffix(
"<$0>")),
3011 AllOf(named(
"foo_var"), snippetSuffix(
"<$0>"))));
3014 const char *Header = R
"cpp(
3018 struct foo_struct{};
3020 using foo_alias = T**;
3025 Opts.Index = Index.get();
3026 auto Results = completions(
3028 void f() { foo_^ })cpp",
3031 Results.Completions,
3032 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix(
"<$0>")),
3033 AllOf(named(
"foo_struct"), snippetSuffix(
"<$0>")),
3034 AllOf(named(
"foo_alias"), snippetSuffix(
"<$0>")),
3035 AllOf(named(
"foo_var"), snippetSuffix(
"<$0>"))));
3036 Opts.Index =
nullptr;
3039 auto Results = completions(
3041 #define FOO(x, y) x##f
3044 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
3045 named("FOO"), snippetSuffix(
"($0)"))));
3048 auto Results = completions(
3051 auto Lambda = [](int a, const double &b) {return 1.f;};
3056 Results.Completions,
3057 UnorderedElementsAre(AllOf(named("Lambda"), snippetSuffix(
"($0)"))));
3061 auto Results = completions(
3063 void xfoo(int x, int y);
3064 void f() { xfo^ })cpp",
3066 EXPECT_THAT(Results.Completions,
3067 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
""))));
3071 auto Results = completions(
3073 void xfoo(int x, int y);
3074 void f() { xfo^ })cpp",
3076 EXPECT_THAT(Results.Completions,
3077 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"("))));
3081TEST(CompletionTest, SuggestOverrides) {
3082 constexpr const char *
const Text(R
"cpp(
3085 virtual void vfunc(bool param);
3086 virtual void vfunc(bool param, int p);
3087 void func(bool param);
3089 class B : public A {
3090 virtual void ttt(bool param) const;
3091 void vfunc(bool param, int p) override;
3093 class C : public B {
3095 void vfunc(bool param) override;
3099 const auto Results = completions(
Text);
3101 Results.Completions,
3102 AllOf(Contains(AllOf(labeled(
"void vfunc(bool param, int p) override"),
3103 nameStartsWith(
"vfunc"))),
3104 Contains(AllOf(labeled(
"void ttt(bool param) const override"),
3105 nameStartsWith(
"ttt"))),
3106 Not(Contains(labeled(
"void vfunc(bool param) override")))));
3109TEST(CompletionTest, OverridesNonIdentName) {
3113 virtual ~Base() = 0;
3114 virtual operator int() = 0;
3115 virtual Base& operator+(Base&) = 0;
3118 struct Derived : Base {
3124TEST(CompletionTest, NoCrashOnMissingNewLineAtEOF) {
3130 FS.Files[FooCpp] = F.code().str();
3135 clangd::CodeCompleteOptions()))
3144TEST(GuessCompletionPrefix, Filters) {
3145 for (llvm::StringRef Case : {
3146 "[[scope::]][[ident]]^",
3155 "some text [[scope::more::]][[identif]]^ier",
3156 "some text [[scope::]][[mor]]^e::identifier",
3157 "weird case foo::[[::bar::]][[baz]]^",
3162 auto ToStringRef = [&](
Range R) {
3166 auto WantQualifier = ToStringRef(F.ranges()[0]),
3167 WantName = ToStringRef(F.ranges()[1]);
3171 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
3172 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
3173 EXPECT_EQ(WantName, Prefix.Name) << Case;
3174 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
3178TEST(CompletionTest, EnableSpeculativeIndexRequest) {
3185 namespace ns1 { int abc; }
3186 namespace ns2 { int abc; }
3187 void f() { ns1::ab$1^; ns1::ab$2^; }
3188 void f2() { ns2::ab$3^; }
3191 clangd::CodeCompleteOptions Opts = {};
3193 IndexRequestCollector Requests;
3194 Opts.Index = &Requests;
3196 auto CompleteAtPoint = [&](StringRef
P) {
3198 EXPECT_TRUE(CCR.HasMore);
3201 CompleteAtPoint(
"1");
3202 auto Reqs1 = Requests.consumeRequests(1);
3203 ASSERT_EQ(Reqs1.size(), 1u);
3204 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre(
"ns1::"));
3206 CompleteAtPoint(
"2");
3207 auto Reqs2 = Requests.consumeRequests(1);
3209 ASSERT_EQ(Reqs2.size(), 1u);
3210 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3212 CompleteAtPoint(
"3");
3215 auto Reqs3 = Requests.consumeRequests(2);
3216 ASSERT_EQ(Reqs3.size(), 2u);
3219TEST(CompletionTest, InsertTheMostPopularHeader) {
3222 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
3226 auto Results = completions(
"Fun^", {Sym}).Completions;
3227 assert(!Results.empty());
3228 EXPECT_THAT(Results[0], AllOf(named(
"Func"), insertInclude(
"\"bar.h\"")));
3229 EXPECT_EQ(Results[0].Includes.size(), 2u);
3232TEST(CompletionTest, InsertIncludeOrImport) {
3235 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
3236 Sym.IncludeHeaders.emplace_back(
"\"bar.h\"", 1000,
3240 Opts.ImportInsertions =
true;
3241 auto Results = completions(
"Fun^", {Sym}, Opts).Completions;
3242 assert(!Results.empty());
3243 EXPECT_THAT(Results[0],
3244 AllOf(named(
"Func"), insertIncludeText(
"#include \"bar.h\"\n")));
3248 Opts.MainFileSignals = &Signals;
3249 Results = completions(
"Fun^", {Sym}, Opts,
"Foo.m").Completions;
3250 assert(!Results.empty());
3251 EXPECT_THAT(Results[0],
3252 AllOf(named(
"Func"), insertIncludeText(
"#import \"bar.h\"\n")));
3255 Results = completions(
"Fun^", {Sym}).Completions;
3256 assert(!Results.empty());
3257 EXPECT_THAT(Results[0], AllOf(named(
"Func"), Not(insertInclude())));
3260TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
3266 TU.AdditionalFiles[
"foo.h"] =
"";
3270 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
3274 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions,
3275 UnorderedElementsAre(AllOf(named(
"Func"), hasInclude(
"\"foo.h\""),
3276 Not(insertInclude()))));
3279TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
3281 Sym.Name =
"Clangd_Macro_Test";
3282 Sym.ID =
SymbolID(
"c:foo.cpp@8@macro@Clangd_Macro_Test");
3283 Sym.SymInfo.Kind = index::SymbolKind::Macro;
3285 EXPECT_THAT(completions(
"#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
3287 UnorderedElementsAre(named(
"Clangd_Macro_Test")));
3290TEST(CompletionTest, MacroFromPreamble) {
3291 Annotations Test(R
"cpp(#define CLANGD_PREAMBLE_MAIN x
3294 #define CLANGD_MAIN x
3295 void f() { CLANGD_^ }
3298 TU.HeaderCode =
"#define CLANGD_PREAMBLE_HEADER x";
3299 auto Results = completions(TU, Test.point(), {func(
"CLANGD_INDEX")});
3302 EXPECT_THAT(Results.Completions,
3303 UnorderedElementsAre(named(
"CLANGD_PREAMBLE_MAIN"),
3304 named(
"CLANGD_MAIN"),
3305 named(
"CLANGD_INDEX")));
3308TEST(CompletionTest, DeprecatedResults) {
3309 std::string Body = R
"cpp(
3311 void TestClangc() __attribute__((deprecated("", "")));
3315 completions(Body + "int main() { TestClang^ }").Completions,
3316 UnorderedElementsAre(AllOf(named(
"TestClangd"), Not(deprecated())),
3317 AllOf(named(
"TestClangc"), deprecated())));
3320TEST(SignatureHelpTest, PartialSpec) {
3321 const auto Results = signatures(R
"cpp(
3322 template <typename T> struct Foo {};
3323 template <typename T> struct Foo<T*> { Foo(T); };
3324 Foo<int*> F(^);)cpp");
3325 EXPECT_THAT(Results.signatures, Contains(sig("Foo([[T]])")));
3326 EXPECT_EQ(0, Results.activeParameter);
3329TEST(SignatureHelpTest, InsideArgument) {
3331 const auto Results = signatures(R
"cpp(
3333 void foo(int x, int y);
3334 int main() { foo(1+^); }
3336 EXPECT_THAT(Results.signatures,
3337 ElementsAre(sig("foo([[int x]]) -> void"),
3338 sig(
"foo([[int x]], [[int y]]) -> void")));
3339 EXPECT_EQ(0, Results.activeParameter);
3342 const auto Results = signatures(R
"cpp(
3344 void foo(int x, int y);
3345 int main() { foo(1^); }
3347 EXPECT_THAT(Results.signatures,
3348 ElementsAre(sig("foo([[int x]]) -> void"),
3349 sig(
"foo([[int x]], [[int y]]) -> void")));
3350 EXPECT_EQ(0, Results.activeParameter);
3353 const auto Results = signatures(R
"cpp(
3355 void foo(int x, int y);
3356 int main() { foo(1^0); }
3358 EXPECT_THAT(Results.signatures,
3359 ElementsAre(sig("foo([[int x]]) -> void"),
3360 sig(
"foo([[int x]], [[int y]]) -> void")));
3361 EXPECT_EQ(0, Results.activeParameter);
3364 const auto Results = signatures(R
"cpp(
3366 void foo(int x, int y);
3367 int bar(int x, int y);
3368 int main() { bar(foo(2, 3^)); }
3370 EXPECT_THAT(Results.signatures,
3371 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
3372 EXPECT_EQ(1, Results.activeParameter);
3376TEST(SignatureHelpTest, ConstructorInitializeFields) {
3378 const auto Results = signatures(R
"cpp(
3379 struct A { A(int); };
3385 EXPECT_THAT(Results.signatures,
3386 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3387 sig(
"A([[const A &]])")));
3390 const auto Results = signatures(R
"cpp(
3391 struct A { A(int); };
3399 EXPECT_THAT(Results.signatures, IsEmpty());
3402 const auto Results = signatures(R
"cpp(
3403 struct A { A(int); };
3410 EXPECT_THAT(Results.signatures,
3411 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3412 sig(
"A([[const A &]])")));
3415 const auto Results = signatures(R
"cpp(
3424 B() : c_elem(A(1^)) {}
3428 EXPECT_THAT(Results.signatures,
3429 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3430 sig(
"A([[const A &]])")));
3434TEST(SignatureHelpTest, Variadic) {
3435 const std::string Header = R
"cpp(
3436 void fun(int x, ...) {}
3438 const std::string ExpectedSig =
"fun([[int x]], [[...]]) -> void";
3441 const auto Result = signatures(Header +
"fun(^);}");
3442 EXPECT_EQ(0, Result.activeParameter);
3443 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3446 const auto Result = signatures(Header +
"fun(1, ^);}");
3447 EXPECT_EQ(1, Result.activeParameter);
3448 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3451 const auto Result = signatures(Header +
"fun(1, 2, ^);}");
3452 EXPECT_EQ(1, Result.activeParameter);
3453 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3457TEST(SignatureHelpTest, VariadicTemplate) {
3458 const std::string Header = R
"cpp(
3459 template<typename T, typename ...Args>
3460 void fun(T t, Args ...args) {}
3462 const std::string ExpectedSig =
"fun([[T t]], [[Args args...]]) -> void";
3465 const auto Result = signatures(Header +
"fun(^);}");
3466 EXPECT_EQ(0, Result.activeParameter);
3467 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3470 const auto Result = signatures(Header +
"fun(1, ^);}");
3471 EXPECT_EQ(1, Result.activeParameter);
3472 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3475 const auto Result = signatures(Header +
"fun(1, 2, ^);}");
3476 EXPECT_EQ(1, Result.activeParameter);
3477 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3481TEST(SignatureHelpTest, VariadicMethod) {
3482 const std::string Header = R
"cpp(
3484 template<typename T, typename ...Args>
3485 void fun(T t, Args ...args) {}
3487 void test() {C c; )cpp";
3488 const std::string ExpectedSig =
"fun([[T t]], [[Args args...]]) -> void";
3491 const auto Result = signatures(Header +
"c.fun(^);}");
3492 EXPECT_EQ(0, Result.activeParameter);
3493 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3496 const auto Result = signatures(Header +
"c.fun(1, ^);}");
3497 EXPECT_EQ(1, Result.activeParameter);
3498 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3501 const auto Result = signatures(Header +
"c.fun(1, 2, ^);}");
3502 EXPECT_EQ(1, Result.activeParameter);
3503 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3507TEST(SignatureHelpTest, VariadicType) {
3508 const std::string Header = R
"cpp(
3509 void fun(int x, ...) {}
3510 auto get_fun() { return fun; }
3513 const std::string ExpectedSig =
"([[int]], [[...]]) -> void";
3516 const auto Result = signatures(Header +
"get_fun()(^);}");
3517 EXPECT_EQ(0, Result.activeParameter);
3518 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3521 const auto Result = signatures(Header +
"get_fun()(1, ^);}");
3522 EXPECT_EQ(1, Result.activeParameter);
3523 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3526 const auto Result = signatures(Header +
"get_fun()(1, 2, ^);}");
3527 EXPECT_EQ(1, Result.activeParameter);
3528 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3532TEST(SignatureHelpTest, SkipExplicitObjectParameter) {
3535 void foo(this auto&& self, int arg);
3536 void bar(this A self, int arg);
3547 TU.ExtraArgs = {
"-std=c++23"};
3550 auto Inputs = TU.inputs(FS);
3559 EXPECT_EQ(1U, Result.signatures.size());
3561 EXPECT_THAT(Result.signatures[0], AllOf(sig(
"foo([[int arg]]) -> void")));
3567 EXPECT_EQ(1U, Result.signatures.size());
3569 EXPECT_THAT(Result.signatures[0], AllOf(sig(
"([[A]], [[int]]) -> void")));
3576 EXPECT_EQ(0U, Result.signatures.size());
3582TEST(CompletionTest, IncludedCompletionKinds) {
3585 TU.AdditionalFiles[
"sub/bar.h"] =
"";
3586 TU.ExtraArgs.push_back(
"-I" +
testPath(
"sub"));
3588 auto Results = completions(TU, Test.point());
3589 EXPECT_THAT(Results.Completions,
3594TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3601TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3602 clangd::CodeCompleteOptions Opts = {};
3603 Opts.AllScopes = true;
3605 auto Results = completions(
3607 void f() { na::Clangd^ }
3609 {cls("na::ClangdA"),
cls(
"nx::ClangdX"),
cls(
"Clangd3")}, Opts);
3610 EXPECT_THAT(Results.Completions,
3611 UnorderedElementsAre(
3612 AllOf(qualifier(
""), scope(
"na::"), named(
"ClangdA"))));
3615TEST(CompletionTest, AllScopesCompletion) {
3616 clangd::CodeCompleteOptions Opts = {};
3617 Opts.AllScopes =
true;
3619 auto Results = completions(
3622 void f() { Clangd^ }
3625 {cls("nx::Clangd1"),
cls(
"ny::Clangd2"),
cls(
"Clangd3"),
3629 Results.Completions,
3630 UnorderedElementsAre(AllOf(qualifier(
"nx::"), named(
"Clangd1"),
3632 AllOf(qualifier(
"ny::"), named(
"Clangd2"),
3634 AllOf(qualifier(
""), scope(
""), named(
"Clangd3"),
3636 AllOf(qualifier(
"nb::"), named(
"Clangd4"),
3638 AllOf(qualifier(
"C::"), named(
"Clangd5"),
3642TEST(CompletionTest, NoCodePatternsIfDisabled) {
3643 clangd::CodeCompleteOptions Opts = {};
3644 Opts.EnableSnippets =
true;
3647 auto Results = completions(R
"cpp(
3656 EXPECT_THAT(Results.Completions,
3660TEST(CompletionTest, CompleteIncludeIfCodePatternsNone) {
3661 clangd::CodeCompleteOptions Opts = {};
3662 Opts.EnableSnippets =
true;
3667 TU.AdditionalFiles[
"foo/bar.h"] =
"";
3668 TU.ExtraArgs.push_back(
"-I" +
testPath(
"foo"));
3670 auto Results = completions(TU, Test.point(), {}, Opts);
3671 EXPECT_THAT(Results.Completions,
3676TEST(CompletionTest, NoQualifierIfShadowed) {
3677 clangd::CodeCompleteOptions Opts = {};
3678 Opts.AllScopes =
true;
3680 auto Results = completions(R
"cpp(
3681 namespace nx { class Clangd1 {}; }
3683 void f() { Clangd^ }
3685 {cls("nx::Clangd1"),
cls(
"nx::Clangd2")}, Opts);
3688 EXPECT_THAT(Results.Completions,
3689 UnorderedElementsAre(AllOf(qualifier(
""), named(
"Clangd1")),
3690 AllOf(qualifier(
"nx::"), named(
"Clangd2"))));
3693TEST(CompletionTest, NoCompletionsForNewNames) {
3694 clangd::CodeCompleteOptions Opts;
3695 Opts.AllScopes =
true;
3696 auto Results = completions(R
"cpp(
3699 {cls("naber"),
cls(
"nx::naber")}, Opts);
3700 EXPECT_THAT(Results.Completions, UnorderedElementsAre());
3703TEST(CompletionTest, Lambda) {
3704 clangd::CodeCompleteOptions Opts = {};
3706 auto Results = completions(R
"cpp(
3708 auto Lambda = [](int a, const double &b) {return 1.f;};
3714 ASSERT_EQ(Results.Completions.size(), 1u);
3715 const auto &
A = Results.Completions.front();
3716 EXPECT_EQ(
A.Name,
"Lambda");
3717 EXPECT_EQ(
A.Signature,
"(int a, const double &b) const");
3719 EXPECT_EQ(
A.ReturnType,
"float");
3720 EXPECT_EQ(
A.SnippetSuffix,
"(${1:int a}, ${2:const double &b})");
3723TEST(CompletionTest, StructuredBinding) {
3724 clangd::CodeCompleteOptions Opts = {};
3726 auto Results = completions(R
"cpp(
3728 using Float = float;
3733 const auto &[xxx, yyy] = S{};
3739 ASSERT_EQ(Results.Completions.size(), 1u);
3740 const auto &
A = Results.Completions.front();
3741 EXPECT_EQ(
A.Name,
"yyy");
3743 EXPECT_EQ(
A.ReturnType,
"const Float");
3746TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3747 auto Results = completions(R
"objc(
3749 @property(nonatomic, setter=setXToIgnoreComplete:) int value;
3751 Foo *foo = [Foo new]; int y = [foo v^]
3756 auto C = Results.Completions;
3757 EXPECT_THAT(C, ElementsAre(named(
"value")));
3759 EXPECT_THAT(C, ElementsAre(returnType(
"int")));
3760 EXPECT_THAT(C, ElementsAre(signature(
"")));
3761 EXPECT_THAT(C, ElementsAre(snippetSuffix(
"")));
3764TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3765 auto Results = completions(R
"objc(
3767 - (int)valueForCharacter:(char)c;
3769 Foo *foo = [Foo new]; int y = [foo v^]
3774 auto C = Results.Completions;
3775 EXPECT_THAT(C, ElementsAre(named(
"valueForCharacter:")));
3777 EXPECT_THAT(C, ElementsAre(returnType(
"int")));
3778 EXPECT_THAT(C, ElementsAre(signature(
"(char)")));
3779 EXPECT_THAT(C, ElementsAre(snippetSuffix(
"${1:(char)}")));
3782TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3783 auto Results = completions(R
"objc(
3785 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3792 auto C = Results.Completions;
3793 EXPECT_THAT(C, ElementsAre(named(
"fooWithValue:")));
3795 EXPECT_THAT(C, ElementsAre(returnType(
"id")));
3796 EXPECT_THAT(C, ElementsAre(signature(
"(int) fooey:(unsigned int)")));
3798 C, ElementsAre(snippetSuffix(
"${1:(int)} fooey:${2:(unsigned int)}")));
3801TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3802 auto Results = completions(R
"objc(
3804 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3806 id val = [Foo fooWithValue:10 f^]
3811 auto C = Results.Completions;
3812 EXPECT_THAT(C, ElementsAre(named(
"fooey:")));
3814 EXPECT_THAT(C, ElementsAre(returnType(
"id")));
3815 EXPECT_THAT(C, ElementsAre(signature(
"(unsigned int)")));
3816 EXPECT_THAT(C, ElementsAre(snippetSuffix(
"${1:(unsigned int)}")));
3819TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3820 auto Results = completions(R
"objc(
3822 + (id)player:(id)player willRun:(id)run;
3829 auto C = Results.Completions;
3830 EXPECT_THAT(C, ElementsAre(named(
"player:")));
3831 EXPECT_THAT(C, ElementsAre(filterText(
"player:willRun:")));
3833 EXPECT_THAT(C, ElementsAre(returnType(
"id")));
3834 EXPECT_THAT(C, ElementsAre(signature(
"(id) willRun:(id)")));
3835 EXPECT_THAT(C, ElementsAre(snippetSuffix(
"${1:(id)} willRun:${2:(id)}")));
3838TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3839 auto Results = completions(R
"objc(
3850 auto C = Results.Completions;
3851 EXPECT_THAT(C, ElementsAre(named(
"foo")));
3853 EXPECT_THAT(C, ElementsAre(qualifier(
"- (void)")));
3856TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3857 auto Results = completions(R
"objc(
3859 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3868 auto C = Results.Completions;
3869 EXPECT_THAT(C, ElementsAre(named(
"valueForCharacter:")));
3871 EXPECT_THAT(C, ElementsAre(qualifier(
"- (int)")));
3872 EXPECT_THAT(C, ElementsAre(signature(
"(char)c secondArgument:(id)object")));
3875TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3876 auto Results = completions(R
"objc(
3878 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3887 auto C = Results.Completions;
3888 EXPECT_THAT(C, ElementsAre(named(
"valueForCharacter:")));
3889 EXPECT_THAT(C, ElementsAre(filterText(
"valueForCharacter:secondArgument:")));
3891 EXPECT_THAT(C, ElementsAre(qualifier(
"- (int)")));
3892 EXPECT_THAT(C, ElementsAre(signature(
"(char)c secondArgument:(id)object")));
3895TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3896 auto Results = completions(R
"objc(
3898 - (int)valueForCharacter:(char)c;
3907 auto C = Results.Completions;
3908 EXPECT_THAT(C, ElementsAre(named(
"valueForCharacter:")));
3910 EXPECT_THAT(C, ElementsAre(signature(
"(char)c")));
3913TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3914 auto Results = completions(R
"objc(
3916 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3919 - (int)valueForCharacter:(char)c second^
3925 auto C = Results.Completions;
3926 EXPECT_THAT(C, ElementsAre(named(
"secondArgument:")));
3928 EXPECT_THAT(C, ElementsAre(signature(
"(id)object")));
3931TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3935 auto Results = completions(
"id<Foo^>", {SymFood, FoodClass, SymFooey},
3939 EXPECT_THAT(Results.Completions,
3940 UnorderedElementsAre(
3944 Results = completions(
"Fo^", {SymFood, FoodClass, SymFooey},
3948 Results.Completions,
3952TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3965 clangd::CodeCompleteOptions Opts = {};
3968 IndexRequestCollector Requests({FoodClass});
3969 Opts.Index = &Requests;
3971 auto CompleteAtPoint = [&](StringRef
P) {
3976 auto C = CompleteAtPoint(
"1");
3977 auto Reqs1 = Requests.consumeRequests(1);
3978 ASSERT_EQ(Reqs1.size(), 1u);
3979 EXPECT_THAT(C, ElementsAre(AllOf(named(
"Food"),
3982 C = CompleteAtPoint(
"2");
3983 auto Reqs2 = Requests.consumeRequests(1);
3986 ASSERT_EQ(Reqs2.size(), 1u);
3987 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3988 EXPECT_THAT(C, ElementsAre(AllOf(named(
"FoodClass"),
3992TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3994 auto Results = completions(R
"objc(
4002 EXPECT_THAT(Results.Completions, IsEmpty());
4005TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
4007 FoodClass.IncludeHeaders.emplace_back(
"\"Foo.h\"", 2,
Symbol::Import);
4009 auto Results = completions(
"@class Foo^", {SymFood, FoodClass},
4013 EXPECT_THAT(Results.Completions,
4014 UnorderedElementsAre(AllOf(named(
"FoodClass"),
4016 Not(insertInclude()))));
4019TEST(CompletionTest, CursorInSnippets) {
4020 clangd::CodeCompleteOptions Options;
4021 Options.EnableSnippets =
true;
4022 auto Results = completions(
4024 void while_foo(int a, int b);
4031 EXPECT_THAT(Results.Completions,
4032 Contains(AllOf(named(
"while"),
4033 snippetSuffix(
" (${1:condition}) {\n$0\n}"))));
4035 EXPECT_THAT(Results.Completions,
4036 Contains(AllOf(named(
"while_foo"),
4037 snippetSuffix(
"(${1:int a}, ${2:int b})"))));
4039 Results = completions(R
"cpp(
4041 Base(int a, int b) {}
4044 struct Derived : Base {
4051 EXPECT_THAT(Results.Completions,
4052 Contains(AllOf(named(
"Base"),
4053 snippetSuffix(
"(${1:int a}, ${2:int b})"))));
4056TEST(CompletionTest, WorksWithNullType) {
4057 auto R = completions(R
"cpp(
4059 for (auto [loopVar] : y ) { // y has to be unresolved.
4064 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar")));
4067TEST(CompletionTest, UsingDecl) {
4068 const char *Header(R
"cpp(
4073 const char *Source(R
"cpp(
4078 clangd::CodeCompleteOptions Opts;
4079 Opts.Index = Index.get();
4080 Opts.AllScopes =
true;
4081 auto R = completions(Source, {}, Opts);
4082 EXPECT_THAT(R.Completions,
4083 ElementsAre(AllOf(scope(
"std::"), named(
"foo"),
4087TEST(CompletionTest, Enums) {
4088 const char *Header(R
"cpp(
4090 enum Unscoped { Clangd1 };
4092 enum Unscoped { Clangd2 };
4094 enum class Scoped { Clangd3 };
4096 const char *Source(R
"cpp(
4101 clangd::CodeCompleteOptions Opts;
4102 Opts.Index = Index.get();
4103 Opts.AllScopes =
true;
4104 auto R = completions(Source, {}, Opts);
4105 EXPECT_THAT(R.Completions, UnorderedElementsAre(
4106 AllOf(scope(
"ns::"), named(
"Clangd1"),
4108 AllOf(scope(
"ns::C::"), named(
"Clangd2"),
4110 AllOf(scope(
"ns::Scoped::"), named(
"Clangd3"),
4114TEST(CompletionTest, ScopeIsUnresolved) {
4115 clangd::CodeCompleteOptions Opts = {};
4116 Opts.AllScopes =
true;
4118 auto Results = completions(R
"cpp(
4123 {cls("a::b::XYZ")}, Opts);
4124 EXPECT_THAT(Results.Completions,
4125 UnorderedElementsAre(AllOf(qualifier(
""), named(
"XYZ"))));
4128TEST(CompletionTest, NestedScopeIsUnresolved) {
4129 clangd::CodeCompleteOptions Opts = {};
4130 Opts.AllScopes =
true;
4132 auto Results = completions(R
"cpp(
4135 void f() { b::c::X^ }
4138 {cls("a::b::c::XYZ")}, Opts);
4139 EXPECT_THAT(Results.Completions,
4140 UnorderedElementsAre(AllOf(qualifier(
""), named(
"XYZ"))));
4145TEST(CompletionTest, NamespaceDoubleInsertion) {
4146 clangd::CodeCompleteOptions Opts = {};
4148 auto Results = completions(R
"cpp(
4155 {cls("foo::ns::ABCDE")}, Opts);
4156 EXPECT_THAT(Results.Completions,
4157 UnorderedElementsAre(AllOf(qualifier(
""), named(
"ABCDE"))));
4160TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
4163 auto Completions = completions(R
"cpp(
4166 double size() const;
4168 struct deque : deque_base {
4175 EXPECT_THAT(Completions,
4176 ElementsAre(AllOf(returnType("int"), named(
"size"))));
4179TEST(CompletionTest, NoCrashWithIncompleteLambda) {
4180 auto Completions = completions(
"auto&& x = []{^").Completions;
4184 EXPECT_THAT(Completions, Contains(named(
"x")));
4186 auto Signatures = signatures(
"auto x() { x(^").signatures;
4187 EXPECT_THAT(Signatures, Contains(sig(
"x() -> auto")));
4190TEST(CompletionTest, DelayedTemplateParsing) {
4193 template <typename T> int foo() { return xx^; }
4198 TU.ExtraArgs.push_back(
"-fdelayed-template-parsing");
4200 EXPECT_THAT(completions(TU, Test.point()).Completions,
4201 Contains(named(
"xxx")));
4204TEST(CompletionTest, CompletionRange) {
4205 const char *WithRange =
"auto x = [[abc]]^";
4206 auto Completions = completions(WithRange);
4207 EXPECT_EQ(Completions.InsertRange,
Annotations(WithRange).range());
4208 Completions = completionsNoCompile(WithRange);
4209 EXPECT_EQ(Completions.InsertRange,
Annotations(WithRange).range());
4211 const char *EmptyRange =
"auto x = [[]]^";
4212 Completions = completions(EmptyRange);
4213 EXPECT_EQ(Completions.InsertRange,
Annotations(EmptyRange).range());
4214 Completions = completionsNoCompile(EmptyRange);
4215 EXPECT_EQ(Completions.InsertRange,
Annotations(EmptyRange).range());
4219 const char *NoCompletion =
"/* foo [[]]^ */";
4220 Completions = completions(NoCompletion);
4221 EXPECT_EQ(Completions.InsertRange, std::nullopt);
4222 Completions = completionsNoCompile(NoCompletion);
4223 EXPECT_EQ(Completions.InsertRange,
Annotations(NoCompletion).range());
4226TEST(CompletionTest, ReplaceRange) {
4227 clangd::CodeCompleteOptions Opts;
4228 Opts.EnableInsertReplace =
true;
4231 const char *EndOfToken =
4232 "struct S { int abc; }; void f() { S s; s.[[abc]]^; }";
4233 CodeCompleteResult Completions =
4234 completions(EndOfToken, {}, Opts);
4236 EXPECT_EQ(Completions.InsertRange,
A.range());
4237 EXPECT_EQ(Completions.ReplaceRange,
A.range());
4240 const char *MidWord =
"struct S { int abcd; }; void f() { S s; "
4241 "s.$replace[[$insert[[ab^]]cd]]; }";
4242 Completions = completions(MidWord, {}, Opts);
4244 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4245 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4248 const char *EmptyPrefix =
"struct S { int abcd; }; void f() { S s; "
4249 "s.$replace[[$insert[[^]]abcd]]; }";
4250 Completions = completions(EmptyPrefix, {}, Opts);
4252 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4253 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4256 const char *MidWordUTF8 =
"struct S { int naïve; }; void f() { S s; "
4257 "s.$replace[[$insert[[na^]]ïve]]; }";
4258 Completions = completions(MidWordUTF8, {}, Opts);
4260 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4261 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4264 const char *BeforeParen =
"struct S { int abcd(); }; void f() { S s; "
4265 "s.$replace[[$insert[[ab^]]cd]](123); }";
4266 Completions = completions(BeforeParen, {}, Opts);
4268 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4269 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4272 const char *BeforeAngle =
4273 "struct S { template <typename T> int abcd(); }; void f() { S s; "
4274 "s.$replace[[$insert[[ab^]]cd]]<int>(); }";
4275 Completions = completions(BeforeAngle, {}, Opts);
4277 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4278 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4281 const char *BeforeEquals =
4282 "void f() { int $replace[[$insert[[ab^]]cd]] = 1; }";
4283 Completions = completions(BeforeEquals, {}, Opts);
4285 EXPECT_EQ(Completions.InsertRange,
A.range(
"insert"));
4286 EXPECT_EQ(Completions.ReplaceRange,
A.range(
"replace"));
4289 Opts.EnableInsertReplace =
false;
4290 const char *NoReplace =
"auto x = [[abc]]^";
4291 Completions = completions(NoReplace, {}, Opts);
4292 EXPECT_EQ(Completions.InsertRange,
Annotations(NoReplace).range());
4293 EXPECT_EQ(Completions.ReplaceRange, std::nullopt);
4296TEST(CompletionTest, ReplaceRangeNoCompile) {
4297 clangd::CodeCompleteOptions Opts;
4298 Opts.EnableInsertReplace =
true;
4301 const char *EndOfToken =
"auto x = [[abc]]^";
4303 CodeCompleteResult Results =
4304 completionsNoCompile(EndOfToken, {}, Opts);
4305 EXPECT_EQ(Results.InsertRange,
A.range());
4306 EXPECT_EQ(Results.ReplaceRange,
A.range());
4309 const char *MidWord =
"auto x = $replace[[$insert[[ab^]]cd]]";
4310 Results = completionsNoCompile(MidWord, {}, Opts);
4312 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4313 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4316 const char *EmptyPrefix =
"auto x = $replace[[$insert[[^]]abcd]]";
4317 Results = completionsNoCompile(EmptyPrefix, {}, Opts);
4319 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4320 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4323 const char *MidWordUTF8 =
"auto x = $replace[[$insert[[na^]]]]ïve";
4324 Results = completionsNoCompile(MidWordUTF8, {}, Opts);
4326 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4327 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4330 const char *BeforeParen =
"auto x = $replace[[$insert[[ab^]]cd]](123);";
4331 Results = completionsNoCompile(BeforeParen, {}, Opts);
4333 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4334 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4337 const char *BeforeAngle =
"auto x = $replace[[$insert[[ab^]]cd]]<int>();";
4338 Results = completionsNoCompile(BeforeAngle, {}, Opts);
4340 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4341 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4344 const char *BeforeEquals =
"auto $replace[[$insert[[ab^]]cd]] = 1;";
4345 Results = completionsNoCompile(BeforeEquals, {}, Opts);
4347 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4348 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4351 Opts.EnableInsertReplace =
false;
4352 const char *NoReplace =
"auto x = [[abc]]^";
4353 Results = completionsNoCompile(NoReplace, {}, Opts);
4354 EXPECT_EQ(Results.InsertRange,
Annotations(NoReplace).range());
4355 EXPECT_EQ(Results.ReplaceRange, std::nullopt);
4358TEST(NoCompileCompletionTest, Basic) {
4359 auto Results = completionsNoCompile(R
"cpp(
4366 EXPECT_FALSE(Results.RanParser);
4367 EXPECT_THAT(Results.Completions,
4368 UnorderedElementsAre(named("void"), named(
"func"), named(
"int"),
4369 named(
"xyz"), named(
"abc")));
4372TEST(NoCompileCompletionTest, WithFilter) {
4373 auto Results = completionsNoCompile(R
"cpp(
4382 EXPECT_THAT(Results.Completions,
4383 UnorderedElementsAre(named("sym1"), named(
"sym2")));
4386TEST(NoCompileCompletionTest, WithIndex) {
4387 std::vector<Symbol> Syms = {
func(
"xxx"),
func(
"a::xxx"),
func(
"ns::b::xxx"),
4388 func(
"c::xxx"),
func(
"ns::d::xxx")};
4389 auto Results = completionsNoCompile(
4391 // Current-scopes, unqualified completion.
4401 EXPECT_THAT(Results.Completions,
4402 UnorderedElementsAre(AllOf(qualifier(""), scope(
"")),
4403 AllOf(qualifier(
""), scope(
"a::")),
4404 AllOf(qualifier(
""), scope(
"ns::b::"))));
4406 Opts.AllScopes =
true;
4407 Results = completionsNoCompile(
4409 // All-scopes unqualified completion.
4419 EXPECT_THAT(Results.Completions,
4420 UnorderedElementsAre(AllOf(qualifier(""), scope(
"")),
4421 AllOf(qualifier(
""), scope(
"a::")),
4422 AllOf(qualifier(
""), scope(
"ns::b::")),
4423 AllOf(qualifier(
"c::"), scope(
"c::")),
4424 AllOf(qualifier(
"d::"), scope(
"ns::d::"))));
4425 Results = completionsNoCompile(
4427 // Qualified completion.
4437 EXPECT_THAT(Results.Completions,
4438 ElementsAre(AllOf(qualifier(""), scope(
"ns::b::"))));
4439 Results = completionsNoCompile(
4441 // Absolutely qualified completion.
4451 EXPECT_THAT(Results.Completions,
4452 ElementsAre(AllOf(qualifier(""), scope(
"a::"))));
4455TEST(AllowImplicitCompletion,
All) {
4456 const char *
Yes[] = {
4460 " # include <^foo.h>",
4461 "#import <foo/^bar.h>",
4462 "#include_next \"^",
4464 const char *
No[] = {
4468 "#include <foo.h> //^",
4469 "#include \"foo.h\"^",
4473 for (
const char *Test :
Yes) {
4474 llvm::Annotations
A(Test);
4477 for (
const char *Test :
No) {
4478 llvm::Annotations
A(Test);
4483TEST(CompletionTest, FunctionArgsExist) {
4484 clangd::CodeCompleteOptions Opts;
4485 Opts.EnableSnippets =
true;
4493 template <typename T>
4495 Container(int Size) {}
4498 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions,
4499 UnorderedElementsAre(
4500 AllOf(labeled(
"foo(int A)"), snippetSuffix(
"(${1:int A})"))));
4502 completions(
Context +
"int y = fo^(42)", {}, Opts).Completions,
4503 UnorderedElementsAre(AllOf(labeled(
"foo(int A)"), snippetSuffix(
""))));
4505 completions(
Context +
"int y = fo^o(42)", {}, Opts).Completions,
4506 UnorderedElementsAre(AllOf(labeled(
"foo(int A)"), snippetSuffix(
""))));
4508 completions(
Context +
"int y = ba^", {}, Opts).Completions,
4509 UnorderedElementsAre(AllOf(labeled(
"bar()"), snippetSuffix(
"()"))));
4510 EXPECT_THAT(completions(
Context +
"int y = ba^()", {}, Opts).Completions,
4511 UnorderedElementsAre(AllOf(labeled(
"bar()"), snippetSuffix(
""))));
4512 EXPECT_THAT(completions(
Context +
"int y = ba^r()", {}, Opts).Completions,
4513 UnorderedElementsAre(AllOf(labeled(
"bar()"), snippetSuffix(
""))));
4515 completions(
Context +
"Object o = Obj^", {}, Opts).Completions,
4516 Contains(AllOf(labeled(
"Object(int B)"), snippetSuffix(
"(${1:int B})"),
4518 EXPECT_THAT(completions(
Context +
"Object o = Obj^()", {}, Opts).Completions,
4519 Contains(AllOf(labeled(
"Object(int B)"), snippetSuffix(
""),
4522 completions(
Context +
"Container c = Cont^", {}, Opts).Completions,
4523 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
4524 snippetSuffix(
"<${1:typename T}>(${2:int Size})"),
4527 completions(
Context +
"Container c = Cont^()", {}, Opts).Completions,
4528 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
4529 snippetSuffix(
"<${1:typename T}>"),
4532 completions(
Context +
"Container c = Cont^<int>()", {}, Opts).Completions,
4533 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
4537 completions(
Context +
"Container c = Cont^ainer()", {}, Opts).Completions,
4538 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
4539 snippetSuffix(
"<${1:typename T}>"),
4541 EXPECT_THAT(completions(
Context +
"MAC^(2)", {}, Opts).Completions,
4542 Contains(AllOf(labeled(
"MACRO(x)"), snippetSuffix(
""),
4544 EXPECT_THAT(completions(
Context +
"MAC^RO(2)", {}, Opts).Completions,
4545 Contains(AllOf(labeled(
"MACRO(x)"), snippetSuffix(
""),
4549TEST(CompletionTest, FunctionArgsExist_Issue1785) {
4553 clangd::CodeCompleteOptions Opts;
4554 Opts.EnableSnippets =
true;
4556 std::string Code = R
"cpp(
4568 completions(Code, {}, Opts).Completions,
4569 Contains(AllOf(labeled("waldo(int)"), snippetSuffix(
"(${1:int})"))));
4572TEST(CompletionTest, NoCrashDueToMacroOrdering) {
4573 EXPECT_THAT(completions(R
"cpp(
4575 #define ECHO2(X) ECHO(X)
4576 int finish_preamble = EC^HO(2);)cpp")
4578 UnorderedElementsAre(labeled("ECHO(X)"), labeled(
"ECHO2(X)")));
4581TEST(CompletionTest, ObjCCategoryDecls) {
4583 TU.
ExtraArgs.push_back(
"-xobjective-c");
4584 TU.HeaderCode = R
"objc(
4588 @interface Foo (FooExt1)
4591 @interface Foo (FooExt2)
4597 @interface Bar (BarExt)
4602 @implementation Foo (^)
4605 TU.Code = Test.code().str();
4606 auto Results = completions(TU, Test.point());
4607 EXPECT_THAT(Results.Completions,
4608 UnorderedElementsAre(labeled(
"FooExt1"), labeled(
"FooExt2")));
4615 TU.Code = Test.code().str();
4616 auto Results = completions(TU, Test.point());
4617 EXPECT_THAT(Results.Completions, UnorderedElementsAre(labeled(
"BarExt")));
4621TEST(CompletionTest, PreambleCodeComplete) {
4622 llvm::StringLiteral Baseline =
"\n#define MACRO 12\nint num = MACRO;";
4623 llvm::StringLiteral ModifiedCC =
4624 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
4631 auto Inputs = ModifiedTU.inputs(FS);
4633 BaselineTU.preamble().get(), Inputs, {});
4634 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
4637TEST(CompletionTest, CommentParamName) {
4638 const std::string Code = R
"cpp(
4639 void fun(int foo, int bar);
4640 void overloaded(int param_int);
4641 void overloaded(int param_int, int param_other);
4642 void overloaded(char param_char);
4646 EXPECT_THAT(completions(Code + "fun(/*^").Completions,
4647 UnorderedElementsAre(labeled(
"foo=*/")));
4648 EXPECT_THAT(completions(Code +
"fun(1, /*^").Completions,
4649 UnorderedElementsAre(labeled(
"bar=*/")));
4650 EXPECT_THAT(completions(Code +
"/*^").Completions, IsEmpty());
4653 completions(Code +
"overloaded(/*^").Completions,
4654 UnorderedElementsAre(labeled(
"param_int=*/"), labeled(
"param_char=*/")));
4656 EXPECT_THAT(completions(Code +
"fun(/* ^").Completions,
4657 UnorderedElementsAre(labeled(
"foo=*/")));
4658 EXPECT_THAT(completions(Code +
"fun(/* f^").Completions,
4659 UnorderedElementsAre(labeled(
"foo=*/")));
4660 EXPECT_THAT(completions(Code +
"fun(/* x^").Completions, IsEmpty());
4661 EXPECT_THAT(completions(Code +
"fun(/* f ^").Completions, IsEmpty());
4665 std::string CompletionRangeTest(Code +
"fun(/*[[^]]");
4666 auto Results = completions(CompletionRangeTest);
4667 EXPECT_THAT(Results.InsertRange,
4668 llvm::ValueIs(
Annotations(CompletionRangeTest).range()));
4670 Results.Completions,
4672 AllOf(replacesRange(
Annotations(CompletionRangeTest).range()),
4676 std::string CompletionRangeTest(Code +
"fun(/*[[fo^]]");
4677 auto Results = completions(CompletionRangeTest);
4678 EXPECT_THAT(Results.InsertRange,
4679 llvm::ValueIs(
Annotations(CompletionRangeTest).range()));
4681 Results.Completions,
4683 AllOf(replacesRange(
Annotations(CompletionRangeTest).range()),
4688 clangd::CodeCompleteOptions ReplaceOpts;
4689 ReplaceOpts.EnableInsertReplace =
true;
4692 const std::string NoEquals(Code +
"fun(/*$replace[[$insert[[fo^]]o*/]])");
4693 const CodeCompleteResult Results = completions(NoEquals, {}, ReplaceOpts);
4695 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4696 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4700 const std::string WithEquals(Code +
4701 "fun(/*$replace[[$insert[[fo^]]o=*/]])");
4702 const CodeCompleteResult Results = completions(WithEquals, {}, ReplaceOpts);
4704 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4705 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4709 const std::string NoClose(Code +
"fun(/*[[fo^]]");
4710 const CodeCompleteResult Results = completions(NoClose, {}, ReplaceOpts);
4712 EXPECT_EQ(Results.InsertRange,
A.range());
4713 EXPECT_EQ(Results.ReplaceRange,
A.range());
4717 const std::string WithUTF8(Code +
"fun(/*$replace[[$insert[[ca^]]fé=*/]])");
4718 const CodeCompleteResult Results = completions(WithUTF8, {}, ReplaceOpts);
4720 EXPECT_EQ(Results.InsertRange,
A.range(
"insert"));
4721 EXPECT_EQ(Results.ReplaceRange,
A.range(
"replace"));
4725TEST(CompletionTest, Concepts) {
4728 concept A = sizeof(T) <= 8;
4730 template<$tparam^A U>
4733 template<typename T>
4734 int bar(T t) requires $expr^A<int>;
4737 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
4739 $toplevel^A auto i = 19;
4741 template<$toplevel^A auto i> void constrainedNTTP();
4743 // FIXME: The first parameter should be dropped in this case.
4744 void abbreviated($expr^A auto x) {}
4747 TU.Code = Code.code().str();
4748 TU.ExtraArgs = {"-std=c++20"};
4751 Sym.Signature =
"<typename Tp, typename Up>";
4752 Sym.CompletionSnippetSuffix =
"<${1:typename Tp}, ${2:typename Up}>";
4753 std::vector<Symbol> Syms = {Sym};
4754 for (
auto P : Code.points(
"tparam")) {
4756 completions(TU, P, Syms).Completions,
4757 AllOf(Contains(AllOf(named(
"A"), signature(
""), snippetSuffix(
""))),
4758 Contains(AllOf(named(
"same_as"), signature(
"<typename Up>"),
4759 snippetSuffix(
"<${2:typename Up}>"))),
4760 Contains(named(
"class")), Contains(named(
"typename"))))
4761 <<
"Completing template parameter at position " <<
P;
4764 for (
auto P : Code.points(
"toplevel")) {
4766 completions(TU, P, Syms).Completions,
4767 AllOf(Contains(AllOf(named(
"A"), signature(
""), snippetSuffix(
""))),
4768 Contains(AllOf(named(
"same_as"), signature(
"<typename Up>"),
4769 snippetSuffix(
"<${2:typename Up}>")))))
4770 <<
"Completing 'requires' expression at position " <<
P;
4773 for (
auto P : Code.points(
"expr")) {
4775 completions(TU, P, Syms).Completions,
4776 AllOf(Contains(AllOf(named(
"A"), signature(
"<class T>"),
4777 snippetSuffix(
"<${1:class T}>"))),
4779 named(
"same_as"), signature(
"<typename Tp, typename Up>"),
4780 snippetSuffix(
"<${1:typename Tp}, ${2:typename Up}>")))))
4781 <<
"Completing 'requires' expression at position " <<
P;
4787 // Comment `with` markup.
4789 void bar() { foo(^); }
4791 for (
auto DocumentationFormat :
4793 auto Sigs = signatures(Code.code(), Code.point(), {},
4794 DocumentationFormat);
4795 ASSERT_EQ(Sigs.signatures.size(), 1U);
4796 EXPECT_EQ(Sigs.signatures[0].documentation.kind, DocumentationFormat);
4801 std::string Top = R
"cpp(
4802 template <typename T, int> bool foo(char);
4803 template <int I, int> bool foo(float);
4806 auto First = signatures(Top +
"bool x = foo<^");
4809 UnorderedElementsAre(sig(
"foo<[[typename T]], [[int]]>() -> bool"),
4810 sig(
"foo<[[int I]], [[int]]>() -> bool")));
4811 EXPECT_EQ(First.activeParameter, 0);
4813 auto Second = signatures(Top +
"bool x = foo<1, ^");
4814 EXPECT_THAT(Second.signatures,
4815 ElementsAre(sig(
"foo<[[int I]], [[int]]>() -> bool")));
4816 EXPECT_EQ(Second.activeParameter, 1);
4819TEST(CompletionTest, DoNotCrash) {
4820 llvm::StringLiteral Cases[] = {
4822 template <typename = int> struct Foo {};
4823 auto a = [x(3)](Foo<^>){};
4826 for (
auto Case : Cases) {
4828 auto Completions = completions(Case);
4831TEST(CompletionTest, PreambleFromDifferentTarget) {
4832 constexpr std::string_view PreambleTarget =
"x86_64";
4833 constexpr std::string_view Contents =
4834 "int foo(int); int num; int num2 = foo(n^";
4838 TU.ExtraArgs.emplace_back(
"-target");
4839 TU.ExtraArgs.emplace_back(PreambleTarget);
4843 TU.ExtraArgs.pop_back();
4844 TU.ExtraArgs.emplace_back(
"wasm32");
4847 auto Inputs = TU.inputs(FS);
4854 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
4855 EXPECT_THAT(Signatures.signatures, Not(testing::IsEmpty()));
4858TEST(CompletionTest, SkipExplicitObjectParameter) {
4861 void foo(this auto&& self, int arg);
4862 void bar(this A self, int arg);
4881 TU.ExtraArgs = {
"-std=c++23"};
4889 auto Inputs = TU.inputs(FS);
4894 EXPECT_THAT(Result.Completions,
4895 UnorderedElementsAre(AllOf(named(
"foo"), signature(
"(int arg)"),
4896 snippetSuffix(
"(${1:int arg})")),
4897 AllOf(named(
"bar"), signature(
"(int arg)"),
4898 snippetSuffix(
"(${1:int arg})"))));
4905 ElementsAre(AllOf(named(
"foo"), signature(
"<class self:auto>(int arg)"),
4906 snippetSuffix(
"<${1:class self:auto}>"))));
4911 EXPECT_THAT(Result.Completions,
4912 ElementsAre(AllOf(named(
"bar"), signature(
"(int arg)"),
4913 snippetSuffix(
""))));
4917TEST(CompletionTest, MemberAccessInExplicitObjMemfn) {
4921 int memberFnA(int a);
4922 int memberFnA(this A&, float a);
4924 void foo(this A& self) {
4925 // Should not offer any members here, since
4926 // it needs to be referenced through `self`.
4928 // should offer all results
4932 // should not offer any results
4940 TU.ExtraArgs = {
"-std=c++23"};
4948 auto Inputs = TU.inputs(FS);
4954 EXPECT_THAT(Result.Completions, ElementsAre());
4962 UnorderedElementsAre(named(
"member"),
4963 AllOf(named(
"memberFnA"), signature(
"(int a)"),
4964 snippetSuffix(
"(${1:int a})")),
4965 AllOf(named(
"memberFnA"), signature(
"(float a)"),
4966 snippetSuffix(
"(${1:float a})"))));
4972 EXPECT_THAT(Result.Completions, ElementsAre());
4976TEST(CompletionTest, ListExplicitObjectOverloads) {
4980 void foo2(int a) const;
4981 void foo2(this const S& self, float a);
4982 void foo3(this const S& self, int a);
4983 void foo4(this S& self, int a);
4986 void S::foo1(int a) {
4990 void S::foo2(int a) const {
4994 void S::foo3(this const S& self, int a) {
4998 void S::foo4(this S& self, int a) {
5006 void test2(const S s) {
5012 TU.ExtraArgs = {
"-std=c++23"};
5020 auto Inputs = TU.inputs(FS);
5027 UnorderedElementsAre(AllOf(named(
"foo1"), signature(
"(int a)"),
5028 snippetSuffix(
"(${1:int a})")),
5029 AllOf(named(
"foo2"), signature(
"(int a) const"),
5030 snippetSuffix(
"(${1:int a})")),
5031 AllOf(named(
"foo2"), signature(
"(float a) const"),
5032 snippetSuffix(
"(${1:float a})")),
5033 AllOf(named(
"foo3"), signature(
"(int a) const"),
5034 snippetSuffix(
"(${1:int a})")),
5035 AllOf(named(
"foo4"), signature(
"(int a)"),
5036 snippetSuffix(
"(${1:int a})"))));
5043 UnorderedElementsAre(AllOf(named(
"foo2"), signature(
"(int a) const"),
5044 snippetSuffix(
"(${1:int a})")),
5045 AllOf(named(
"foo2"), signature(
"(float a) const"),
5046 snippetSuffix(
"(${1:float a})")),
5047 AllOf(named(
"foo3"), signature(
"(int a) const"),
5048 snippetSuffix(
"(${1:int a})"))));
5055 UnorderedElementsAre(AllOf(named(
"foo2"), signature(
"(int a) const"),
5056 snippetSuffix(
"(${1:int a})")),
5057 AllOf(named(
"foo2"), signature(
"(float a) const"),
5058 snippetSuffix(
"(${1:float a})")),
5059 AllOf(named(
"foo3"), signature(
"(int a) const"),
5060 snippetSuffix(
"(${1:int a})"))));
5067 UnorderedElementsAre(AllOf(named(
"foo1"), signature(
"(int a)"),
5068 snippetSuffix(
"(${1:int a})")),
5069 AllOf(named(
"foo2"), signature(
"(int a) const"),
5070 snippetSuffix(
"(${1:int a})")),
5071 AllOf(named(
"foo2"), signature(
"(float a) const"),
5072 snippetSuffix(
"(${1:float a})")),
5073 AllOf(named(
"foo3"), signature(
"(int a) const"),
5074 snippetSuffix(
"(${1:int a})")),
5075 AllOf(named(
"foo4"), signature(
"(int a)"),
5076 snippetSuffix(
"(${1:int a})"))));
5083 UnorderedElementsAre(AllOf(named(
"foo1"), signature(
"(int a)"),
5084 snippetSuffix(
"(${1:int a})")),
5085 AllOf(named(
"foo2"), signature(
"(int a) const"),
5086 snippetSuffix(
"(${1:int a})")),
5087 AllOf(named(
"foo2"), signature(
"(float a) const"),
5088 snippetSuffix(
"(${1:float a})")),
5089 AllOf(named(
"foo3"), signature(
"(int a) const"),
5090 snippetSuffix(
"(${1:int a})")),
5091 AllOf(named(
"foo4"), signature(
"(int a)"),
5092 snippetSuffix(
"(${1:int a})"))));
5099 UnorderedElementsAre(AllOf(named(
"foo2"), signature(
"(int a) const"),
5100 snippetSuffix(
"(${1:int a})")),
5101 AllOf(named(
"foo2"), signature(
"(float a) const"),
5102 snippetSuffix(
"(${1:float a})")),
5103 AllOf(named(
"foo3"), signature(
"(int a) const"),
5104 snippetSuffix(
"(${1:int a})"))));
5108TEST(CompletionTest, FuzzyMatchMacro) {
5111 #define _gl_foo() 42
5131 auto Results = completions(TU, Code.point(
"c1"), {}, Opts);
5133 Results.Completions,
5134 ElementsAre(named(
"gl_frob"), named(
"_gl_frob"), named(
"glfbar")));
5138 auto Results = completions(TU, Code.point(
"c2"), {}, Opts);
5139 EXPECT_THAT(Results.Completions,
5140 ElementsAre(named(
"_gl_frob"), named(
"_gl_foo")));
5151 auto Results = completions(TU, Code.point(
"c1"), {}, Opts);
5152 EXPECT_THAT(Results.Completions,
5153 ElementsAre(named(
"gl_frob"), named(
"_gl_frob"),
5154 named(
"glfbar"), named(
"gl_foo")));
5159 auto Results = completions(TU, Code.point(
"c2"), {}, Opts);
5160 EXPECT_THAT(Results.Completions,
5161 ElementsAre(named(
"_gl_frob"), named(
"_gl_foo")));
#define EXPECT_IFF(condition, value, matcher)
Same as llvm::Annotations, but adjusts functions to LSP-specific types for positions and ranges.
clangd::Range range(llvm::StringRef Name="") const
Manages a collection of source files and derived data (ASTs, indexes), and provides language-aware fe...
static Options optsForTest()
A context is an immutable container for per-request data that must be propagated through layers that ...
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
llvm::StringMap< std::string > Files
An efficient structure of storing large set of symbol references in memory.
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
SymbolSlab::Builder is a mutable container that can 'freeze' to SymbolSlab.
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
WithContextValue extends Context::current() with a single value.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Symbol objcProtocol(llvm::StringRef Name)
Symbol objcClass(llvm::StringRef Name)
Symbol func(llvm::StringRef Name)
Symbol cls(llvm::StringRef Name)
Symbol objcCategory(llvm::StringRef Name, llvm::StringRef CategoryName)
std::string sortText(float Score, llvm::StringRef Name)
Returns a string that sorts in the same order as (-Score, Tiebreak), for LSP.
Symbol conceptSym(llvm::StringRef Name)
IndexContents
Describes what data is covered by an index.
size_t lspLength(llvm::StringRef Code)
CompletionPrefix guessCompletionPrefix(llvm::StringRef Content, unsigned Offset)
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, llvm::StringRef USRFormat, llvm::StringRef Signature)
CompletionItemKind
The kind of a completion entry.
Symbol ns(llvm::StringRef Name)
bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset)
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
llvm::Expected< CodeCompleteResult > runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, clangd::CodeCompleteOptions Opts)
llvm::Expected< SignatureHelp > runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos, MarkupKind DocumentationFormat)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback, PreambleBuildStats *Stats)
Build a preamble for the new inputs unless an old one can be reused.
TEST(BackgroundQueueTest, Priority)
void wait(std::unique_lock< std::mutex > &Lock, std::condition_variable &CV, Deadline D)
Wait once on CV for the specified duration.
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, llvm::StringRef Version, WantDiagnostics WantDiags, bool ForceRebuild)
Symbol macro(llvm::StringRef Name, llvm::StringRef ArgList)
llvm::StringRef PathRef
A typedef to represent a ref to file path.
@ No
Diagnostics must be generated for this snapshot.
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Symbol enmConstant(llvm::StringRef Name)
Deadline timeoutSeconds(std::optional< double > Seconds)
Makes a deadline from a timeout in seconds. std::nullopt means wait forever.
CodeCompleteResult codeComplete(PathRef FileName, Position Pos, const PreambleData *Preamble, const ParseInputs &ParseInput, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Gets code completions at a specified Pos in FileName.
@ PlainText
The primary text to be inserted is treated as a plain string.
@ Snippet
The primary text to be inserted is treated as a snippet.
SignatureHelp signatureHelp(PathRef FileName, Position Pos, const PreambleData &Preamble, const ParseInputs &ParseInput, MarkupKind DocumentationFormat)
Get signature help at a specified Pos in FileName.
PolySubsequenceMatcher< Args... > HasSubsequence(Args &&... M)
Symbol var(llvm::StringRef Name)
cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccessCheck P
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Signals derived from a valid AST of a file.
llvm::DenseMap< SymbolID, unsigned > ReferencedSymbols
Number of occurrences of each symbol present in the file.
Symbol::IncludeDirective InsertionDirective
Preferred preprocessor directive to use for inclusions by the file.
Represents a collection of completion items to be presented in the editor.
Settings that express user/project preferences and control clangd behavior.
static clangd::Key< Config > Key
Context key which can be used to set the current Config.
@ None
nothing, no argument list and also NO Delimiters "()" or "<>".
@ Delimiters
empty pair of delimiters "()" or "<>".
@ OpenDelimiter
open, only opening delimiter "(" or "<".
Same semantics as CodeComplete::Score.
std::vector< std::string > Scopes
If this is non-empty, symbols must be in at least one of the scopes (e.g.
int line
Line position in a document (zero-based).
int character
Character offset on a line in a document (zero-based).
Position end
The range's end position.
Represents the signature of a callable.
Attributes of a symbol that affect how much we like it.
Attributes of a symbol-query pair that affect how much we like it.
The class presents a C++ symbol, e.g.
@ IndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.
@ Include
#include "header.h"
@ Import
#import "header.h"
SymbolID ID
The ID of the symbol.
std::vector< std::string > ExtraArgs
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
static TestTU withCode(llvm::StringRef Code)
llvm::StringMap< std::string > AdditionalFiles
std::unique_ptr< SymbolIndex > index() const
Range range
The range of the text document to be manipulated.