24 #include "clang/Sema/CodeCompleteConsumer.h"
25 #include "clang/Tooling/CompilationDatabase.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/Path.h"
28 #include "llvm/Testing/Support/Annotations.h"
29 #include "llvm/Testing/Support/Error.h"
30 #include "gmock/gmock.h"
31 #include "gtest/gtest.h"
32 #include <condition_variable>
42 using ::testing::AllOf;
43 using ::testing::Contains;
44 using ::testing::ElementsAre;
45 using ::testing::Field;
46 using ::testing::HasSubstr;
47 using ::testing::IsEmpty;
49 using ::testing::UnorderedElementsAre;
54 return llvm::StringRef(arg.Name).startswith(Prefix);
56 MATCHER_P(Scope, S,
"") {
return arg.Scope == S; }
57 MATCHER_P(Qualifier, Q,
"") {
return arg.RequiredQualifier == Q; }
59 return arg.RequiredQualifier + arg.Name + arg.Signature == Label;
61 MATCHER_P(SigHelpLabeled, Label,
"") {
return arg.label == Label; }
64 return arg.Documentation && arg.Documentation->asPlainText() == D;
67 MATCHER_P(HasInclude, IncludeHeader,
"") {
68 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader;
70 MATCHER_P(InsertInclude, IncludeHeader,
"") {
71 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader &&
72 bool(arg.Includes[0].Insertion);
75 return !arg.Includes.empty() && bool(arg.Includes[0].Insertion);
78 MATCHER_P(Origin, OriginSet,
"") {
return arg.Origin == OriginSet; }
82 Matcher<const std::vector<CodeCompletion> &> Has(std::string
Name) {
83 return Contains(Named(std::move(
Name)));
85 Matcher<const std::vector<CodeCompletion> &> Has(std::string
Name,
87 return Contains(AllOf(Named(std::move(
Name)),
Kind(K)));
89 MATCHER(IsDocumented,
"") {
return arg.Documentation.hasValue(); }
90 MATCHER(Deprecated,
"") {
return arg.Deprecated; }
92 std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol>
Symbols) {
96 return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
101 CodeCompleteResult completions(
const TestTU &TU, Position Point,
102 std::vector<Symbol> IndexSymbols = {},
103 clangd::CodeCompleteOptions Opts = {}) {
104 std::unique_ptr<SymbolIndex> OverrideIndex;
105 if (!IndexSymbols.empty()) {
106 assert(!Opts.
Index &&
"both Index and IndexSymbols given!");
107 OverrideIndex = memIndex(std::move(IndexSymbols));
108 Opts.
Index = OverrideIndex.get();
115 IgnoreDiagnostics
Diags;
118 ADD_FAILURE() <<
"Couldn't build CompilerInvocation";
128 CodeCompleteResult completions(llvm::StringRef Text,
129 std::vector<Symbol> IndexSymbols = {},
130 clangd::CodeCompleteOptions Opts = {},
131 PathRef FilePath =
"foo.cpp") {
132 Annotations Test(Text);
136 return completions(TU, Test.point(), std::move(IndexSymbols),
141 CodeCompleteResult completionsNoCompile(llvm::StringRef Text,
142 std::vector<Symbol> IndexSymbols = {},
143 clangd::CodeCompleteOptions Opts = {},
144 PathRef FilePath =
"foo.cpp") {
145 std::unique_ptr<SymbolIndex> OverrideIndex;
146 if (!IndexSymbols.empty()) {
147 assert(!Opts.
Index &&
"both Index and IndexSymbols given!");
148 OverrideIndex = memIndex(std::move(IndexSymbols));
149 Opts.
Index = OverrideIndex.get();
153 Annotations Test(Text);
154 ParseInputs
ParseInput{tooling::CompileCommand(), &
FS, Test.code().str()};
159 Symbol withReferences(
int N, Symbol S) {
164 TEST(CompletionTest, Limit) {
165 clangd::CodeCompleteOptions Opts;
167 auto Results = completions(R
"cpp(
168 struct ClassWithMembers {
174 int main() { ClassWithMembers().^ }
179 EXPECT_THAT(
Results.Completions, ElementsAre(Named(
"AAA"), Named(
"BBB")));
182 TEST(CompletionTest, Filter) {
183 std::string Body = R
"cpp(
194 EXPECT_THAT(completions(Body +
"int main() { S().Foba^ }").Completions,
195 AllOf(Has(
"FooBar"), Has(
"FooBaz"), Not(Has(
"Qux"))));
198 EXPECT_THAT(completions(Body +
"int main() { C^ }").Completions,
199 AllOf(Has(
"Car"), Not(Has(
"MotorCar"))));
202 void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
209 // Make sure this is not in preamble.
212 struct GlobalClass {};
214 struct ClassWithMembers {
224 struct LocalClass {};
232 {
cls(
"IndexClass"),
var(
"index_var"),
func(
"index_func")}, Opts);
234 EXPECT_TRUE(
Results.RanParser);
237 EXPECT_THAT(
Results.Completions,
238 AllOf(Has(
"method"), Has(
"field"), Not(Has(
"ClassWithMembers")),
239 Not(Has(
"operator=")), Not(Has(
"~ClassWithMembers"))));
241 Has(
"private_field"));
245 Not(AnyOf(Has(
"global_var"), Has(
"index_var"), Has(
"global_func"),
246 Has(
"global_func()"), Has(
"index_func"), Has(
"GlobalClass"),
247 Has(
"IndexClass"), Has(
"MACRO"), Has(
"LocalClass"))));
250 EXPECT_THAT(
Results.Completions,
254 Contains(IsDocumented()));
257 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
263 // Make sure this is not in preamble.
266 struct GlobalClass {};
268 struct ClassWithMembers {
274 struct LocalClass {};
282 {
cls(
"IndexClass"),
var(
"index_var"),
func(
"index_func")}, Opts);
284 EXPECT_TRUE(
Results.RanParser);
286 EXPECT_THAT(
Results.Completions,
287 Not(AnyOf(Has(
"method"), Has(
"method()"), Has(
"field"))));
289 EXPECT_THAT(
Results.Completions,
290 AllOf(Has(
"global_var"), Has(
"index_var"), Has(
"global_func"),
292 Has(
"GlobalClass"), Has(
"IndexClass")));
296 EXPECT_THAT(
Results.Completions,
297 AllOf(Has(
"local_var"), Has(
"LocalClass"),
301 Contains(IsDocumented()));
304 TEST(CompletionTest, CompletionOptions) {
305 auto Test = [&](
const clangd::CodeCompleteOptions &Opts) {
306 testAfterDotCompletion(Opts);
307 testGlobalScopeCompletion(Opts);
319 for (
auto &F :
Flags) {
320 clangd::CodeCompleteOptions O;
326 TEST(CompletionTest, Accessible) {
327 auto Internal = completions(R
"cpp(
330 protected: void prot();
331 private: void priv();
333 void Foo::pub() { this->^ }
335 EXPECT_THAT(Internal.Completions,
336 AllOf(Has("priv"), Has(
"prot"), Has(
"pub")));
338 auto External = completions(R
"cpp(
341 protected: void prot();
342 private: void priv();
349 EXPECT_THAT(External.Completions,
350 AllOf(Has("pub"), Not(Has(
"prot")), Not(Has(
"priv"))));
353 TEST(CompletionTest, Qualifiers) {
354 auto Results = completions(R
"cpp(
356 public: int foo() const;
359 class Bar : public Foo {
362 void test() { Bar().^ }
364 EXPECT_THAT(Results.Completions,
365 Contains(AllOf(Qualifier(""), Named(
"bar"))));
367 EXPECT_THAT(
Results.Completions,
368 Not(Contains(AllOf(
Qualifier(
"Foo::"), Named(
"foo")))));
370 EXPECT_THAT(
Results.Completions,
371 Not(Contains(AllOf(
Qualifier(
""), Named(
"foo")))));
374 TEST(CompletionTest, InjectedTypename) {
376 EXPECT_THAT(completions(
"struct X{}; void foo(){ X().^ }").Completions,
378 EXPECT_THAT(completions(
"struct X{ void foo(){ this->^ } };").Completions,
381 EXPECT_THAT(completions(
"struct X{ void foo(){ ^ } };").Completions,
384 completions(
"struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions,
388 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };")
392 EXPECT_THAT(completions(
"struct X{}; void foo(){ X::^ }").Completions,
396 TEST(CompletionTest, SkipInjectedWhenUnqualified) {
397 EXPECT_THAT(completions(
"struct X { void f() { X^ }};").Completions,
398 ElementsAre(Named(
"X"), Named(
"~X")));
401 TEST(CompletionTest, Snippets) {
402 clangd::CodeCompleteOptions Opts;
407 int f(int i, const float f) const;
421 TEST(CompletionTest, NoSnippetsInUsings) {
422 clangd::CodeCompleteOptions Opts;
427 int func(int a, int b);
433 EXPECT_THAT(
Results.Completions,
434 ElementsAre(AllOf(Named(
"func"), Labeled(
"func(int a, int b)"),
438 auto Func =
func(
"ns::func");
439 Func.CompletionSnippetSuffix =
"(${1:int a}, ${2: int b})";
440 Func.Signature =
"(int a, int b)";
441 Func.ReturnType =
"void";
448 EXPECT_THAT(
Results.Completions,
449 ElementsAre(AllOf(Named(
"func"), Labeled(
"func(int a, int b)"),
458 EXPECT_THAT(
Results.Completions,
459 Contains(AllOf(Named(
"func"), Labeled(
"ns::func(int a, int b)"),
463 TEST(CompletionTest, Kinds) {
469 // make sure MACRO is not included in preamble.
473 {func("indexFunction"),
var(
"indexVariable"),
cls(
"indexClass")});
474 EXPECT_THAT(
Results.Completions,
485 EXPECT_THAT(
Results.Completions,
505 template <class T> struct complete_class {};
506 template <class T> void complete_function();
507 template <class T> using complete_type_alias = int;
508 template <class T> int complete_variable = 10;
511 template <class T> static int complete_static_member = 10;
513 static auto x = complete_^
518 UnorderedElementsAre(
521 AllOf(Named(
"complete_type_alias"),
524 AllOf(Named(
"complete_static_member"),
539 TEST(CompletionTest, NoDuplicates) {
552 EXPECT_THAT(
Results.Completions, ElementsAre(Named(
"Adapter")));
555 TEST(CompletionTest, ScopedNoIndex) {
558 namespace fake { int BigBang, Babble, Box; };
559 int main() { fake::ba^ }
562 EXPECT_THAT(
Results.Completions,
563 ElementsAre(Named(
"Babble"), Named(
"BigBang")));
566 TEST(CompletionTest, Scoped) {
569 namespace fake { int Babble, Box; };
570 int main() { fake::ba^ }
572 {var("fake::BigBang")});
573 EXPECT_THAT(
Results.Completions,
574 ElementsAre(Named(
"Babble"), Named(
"BigBang")));
577 TEST(CompletionTest, ScopedWithFilter) {
582 {cls("ns::XYZ"),
func(
"ns::foo")});
583 EXPECT_THAT(
Results.Completions, UnorderedElementsAre(Named(
"XYZ")));
586 TEST(CompletionTest, ReferencesAffectRanking) {
587 auto Results = completions(
"int main() { abs^ }", {
ns(
"absl"),
func(
"absb")});
588 EXPECT_THAT(
Results.Completions,
590 Results = completions(
"int main() { abs^ }",
591 {withReferences(10000,
ns(
"absl")),
func(
"absb")});
592 EXPECT_THAT(
Results.Completions,
596 TEST(CompletionTest, ContextWords) {
597 auto Results = completions(R
"cpp(
598 enum class Color { RED, YELLOW, BLUE };
600 // (blank lines so the definition above isn't "context")
602 // "It was a yellow car," he said. "Big yellow car, new."
603 auto Finish = Color::^
607 ASSERT_THAT(
Results.Completions,
611 TEST(CompletionTest, GlobalQualified) {
617 EXPECT_THAT(
Results.Completions,
622 TEST(CompletionTest, FullyQualified) {
625 namespace ns { void bar(); }
629 EXPECT_THAT(
Results.Completions,
634 TEST(CompletionTest, SemaIndexMerge) {
637 namespace ns { int local; void both(); }
640 {func("ns::both"),
cls(
"ns::Index")});
642 EXPECT_THAT(
Results.Completions,
643 UnorderedElementsAre(
650 TEST(CompletionTest, SemaIndexMergeWithLimit) {
651 clangd::CodeCompleteOptions Opts;
655 namespace ns { int local; void both(); }
658 {func("ns::both"),
cls(
"ns::Index")}, Opts);
663 TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
665 TU.ExtraArgs.push_back(
"-I" +
testPath(
"sub"));
666 TU.AdditionalFiles[
"sub/bar.h"] =
"";
669 Symbol Sym =
cls(
"ns::X");
670 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
671 Sym.IncludeHeaders.emplace_back(BarURI, 1);
673 Annotations Test(
"int main() { ns::^ }");
674 TU.Code = Test.code().str();
675 auto Results = completions(TU, Test.point(), {Sym});
676 EXPECT_THAT(
Results.Completions,
677 ElementsAre(AllOf(Named(
"X"), InsertInclude(
"\"bar.h\""))));
679 CodeCompleteOptions NoInsertion;
681 Results = completions(TU, Test.point(), {Sym}, NoInsertion);
682 EXPECT_THAT(
Results.Completions,
683 ElementsAre(AllOf(Named(
"X"), Not(InsertInclude()))));
685 Test = Annotations(R
"cpp(
686 #include "sub/bar.h" // not shortest, so should only match resolved.
689 TU.Code = Test.code().str();
690 Results = completions(TU, Test.point(), {Sym});
691 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Labeled(
"X"),
692 Not(InsertInclude()))));
695 TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
696 Symbol SymX =
cls(
"ns::X");
697 Symbol SymY =
cls(
"ns::Y");
698 std::string BarHeader =
testPath(
"bar.h");
700 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
701 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
702 SymX.IncludeHeaders.emplace_back(
"<bar>", 1);
703 SymY.IncludeHeaders.emplace_back(
"<bar>", 1);
705 auto Results = completions(R
"cpp(
713 EXPECT_THAT(Results.Completions,
714 ElementsAre(AllOf(Named("X"), Not(InsertInclude())),
715 AllOf(Named(
"Y"), Not(InsertInclude()))));
718 TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
719 Annotations Test(R
"cpp(
721 namespace ns { int local; }
723 void f2() { ns::preamble().$2^; }
727 R
"cpp(namespace ns { struct preamble { int member; }; })cpp";
729 clangd::CodeCompleteOptions Opts = {};
730 auto I = memIndex({
var(
"ns::index")});
731 Opts.
Index = I.get();
732 auto WithIndex = completions(TU, Test.point(), {}, Opts);
733 EXPECT_THAT(WithIndex.Completions,
734 UnorderedElementsAre(Named(
"local"), Named(
"index")));
735 auto ClassFromPreamble = completions(TU, Test.point(
"2"), {}, Opts);
736 EXPECT_THAT(ClassFromPreamble.Completions, Contains(Named(
"member")));
738 Opts.
Index =
nullptr;
739 auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
740 EXPECT_THAT(WithoutIndex.Completions,
741 UnorderedElementsAre(Named(
"local"), Named(
"preamble")));
748 TEST(CompletionTest, CompletionInPreamble) {
749 auto Results = completions(R
"cpp(
757 EXPECT_THAT(Results, ElementsAre(Named("ifndef")));
760 TEST(CompletionTest, CompletionRecoveryASTType) {
761 auto Results = completions(R
"cpp(
762 struct S { int member; };
765 // No overload matches, but we have recovery-expr with the correct type.
769 EXPECT_THAT(Results, ElementsAre(Named("member")));
772 TEST(CompletionTest, DynamicIndexIncludeInsertion) {
774 MockCompilationDatabase CDB;
776 Opts.BuildDynamicSymbolIndex =
true;
777 ClangdServer Server(CDB,
FS, Opts);
786 const std::string FileContent(R
"cpp(
787 #include "foo_header.h"
792 Server.addDocument(testPath("foo_impl.cpp"), FileContent);
794 ASSERT_TRUE(Server.blockUntilIdleForTest());
797 Annotations Test(
"Foo^ foo;");
799 auto CompletionList =
802 EXPECT_THAT(CompletionList.Completions,
803 ElementsAre(AllOf(Named(
"Foo"), HasInclude(
"\"foo_header.h\""),
807 TEST(CompletionTest, DynamicIndexMultiFile) {
809 MockCompilationDatabase CDB;
811 Opts.BuildDynamicSymbolIndex =
true;
812 ClangdServer Server(CDB,
FS, Opts);
815 namespace ns { class XYZ {}; void foo(int x) {} }
822 Annotations Test(R
"cpp(
838 EXPECT_THAT(
Results.Completions,
843 TEST(CompletionTest, Documentation) {
846 // Non-doxygen comment.
858 EXPECT_THAT(
Results.Completions,
859 Contains(AllOf(Named(
"foo"), Doc(
"Non-doxygen comment."))));
862 Contains(AllOf(Named(
"bar"), Doc(
"Doxygen comment.\n\\param int a"))));
863 EXPECT_THAT(
Results.Completions,
864 Contains(AllOf(Named(
"baz"), Doc(
"Multi-line block comment"))));
867 TEST(CompletionTest, CommentsFromSystemHeaders) {
869 MockCompilationDatabase CDB;
872 Opts.BuildDynamicSymbolIndex =
true;
874 ClangdServer Server(CDB,
FS, Opts);
877 #pragma GCC system_header
879 // This comment should be retained!
884 Annotations Test(R
"cpp(
889 auto CompletionList =
893 CompletionList.Completions,
894 Contains(AllOf(Named(
"foo"), Doc(
"This comment should be retained!"))));
897 TEST(CompletionTest, GlobalCompletionFiltering) {
900 Class.Flags = static_cast<Symbol::SymbolFlag>(
902 Symbol Func =
func(
"XYZ::foooo");
903 Func.Flags = static_cast<Symbol::SymbolFlag>(
906 auto Results = completions(R
"(// void f() {
910 EXPECT_THAT(Results.Completions, IsEmpty());
913 TEST(CodeCompleteTest, DisableTypoCorrection) {
914 auto Results = completions(R
"cpp(
915 namespace clang { int v; }
918 EXPECT_TRUE(Results.Completions.empty());
921 TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
922 auto Results = completions(R
"cpp(
929 EXPECT_THAT(Results.Completions, Contains(Labeled("clang")));
930 EXPECT_THAT(
Results.Completions, Not(Contains(Labeled(
"clang::"))));
933 TEST(CompletionTest, BacktrackCrashes) {
935 auto Results = completions(R
"cpp(
943 EXPECT_THAT(Results.Completions, ElementsAre(Labeled("FooBarBaz")));
949 if (FooBarBaz * x^) {}
954 TEST(CompletionTest, CompleteInMacroWithStringification) {
955 auto Results = completions(R
"cpp(
956 void f(const char *, int x);
957 #define F(x) f(#x, x)
964 int f(int input_num) {
969 EXPECT_THAT(Results.Completions,
970 UnorderedElementsAre(Named("X"), Named(
"Y")));
973 TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
974 auto Results = completions(R
"cpp(
975 void f(const char *, int x);
976 #define F(x) f(#x, x)
981 int f(int input_num) {
987 EXPECT_THAT(Results.Completions, Contains(Named("X")));
990 TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
991 auto Results = completions(R
"cpp(
992 int bar(int param_in_bar) {
995 int foo(int param_in_foo) {
997 // In recovery mode, "param_in_foo" will also be suggested among many other
998 // unrelated symbols; however, this is really a special case where this works.
999 // If the #if block is outside of the function, "param_in_foo" is still
1000 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
1001 // really provide useful results in excluded branches.
1007 EXPECT_TRUE(Results.Completions.empty());
1010 TEST(CompletionTest, DefaultArgs) {
1011 clangd::CodeCompleteOptions Opts;
1012 std::string Context = R"cpp(
1014 int Y(int A, int B = 0);
1015 int Z(int A, int B = 0, int C = 0, int D = 0);
1017 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions,
1018 UnorderedElementsAre(Labeled(
"X(int A = 0)")));
1019 EXPECT_THAT(completions(Context +
"int y = Y^", {}, Opts).Completions,
1020 UnorderedElementsAre(AllOf(Labeled(
"Y(int A, int B = 0)"),
1022 EXPECT_THAT(completions(Context +
"int y = Z^", {}, Opts).Completions,
1023 UnorderedElementsAre(
1024 AllOf(Labeled(
"Z(int A, int B = 0, int C = 0, int D = 0)"),
1028 TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) {
1029 auto Completions = completions(R
"cpp(
1030 template <template <class> class TT> int foo() {
1035 EXPECT_THAT(Completions, Contains(Named("TT")));
1038 TEST(CompletionTest, RecordCCResultCallback) {
1039 std::vector<CodeCompletion> RecordedCompletions;
1040 CodeCompleteOptions Opts;
1041 Opts.
RecordCCResult = [&RecordedCompletions](
const CodeCompletion &CC,
1042 const SymbolQualitySignals &,
1043 const SymbolRelevanceSignals &,
1045 RecordedCompletions.push_back(CC);
1048 completions(
"int xy1, xy2; int a = xy^", {}, Opts);
1049 EXPECT_THAT(RecordedCompletions,
1050 UnorderedElementsAre(Named(
"xy1"), Named(
"xy2")));
1053 SignatureHelp signatures(llvm::StringRef Text, Position Point,
1054 std::vector<Symbol> IndexSymbols = {}) {
1055 std::unique_ptr<SymbolIndex>
Index;
1056 if (!IndexSymbols.empty())
1057 Index = memIndex(IndexSymbols);
1065 IgnoreDiagnostics
Diags;
1068 ADD_FAILURE() <<
"Couldn't build CompilerInvocation";
1074 ADD_FAILURE() <<
"Couldn't build Preamble";
1080 SignatureHelp signatures(llvm::StringRef Text,
1081 std::vector<Symbol> IndexSymbols = {}) {
1082 Annotations Test(Text);
1083 return signatures(Test.code(), Test.point(), std::move(IndexSymbols));
1086 struct ExpectedParameter {
1091 if (P.size() != arg.parameters.size())
1093 for (
unsigned I = 0; I < P.size(); ++I) {
1094 if (P[I].
Text != arg.parameters[I].labelString ||
1095 P[I].Offsets != arg.parameters[I].labelOffsets)
1100 MATCHER_P(SigDoc, Doc,
"") {
return arg.documentation == Doc; }
1104 Matcher<SignatureInformation> Sig(llvm::StringRef AnnotatedLabel) {
1105 llvm::Annotations A(AnnotatedLabel);
1106 std::string Label = std::string(A.code());
1108 for (
auto Range : A.ranges()) {
1113 P.Offsets.first =
lspLength(llvm::StringRef(Label).substr(0,
Range.Begin));
1114 P.Offsets.second =
lspLength(llvm::StringRef(Label).substr(1,
Range.End));
1116 return AllOf(SigHelpLabeled(Label), ParamsAre(
Parameters));
1119 TEST(SignatureHelpTest, Overloads) {
1120 auto Results = signatures(R
"cpp(
1121 void foo(int x, int y);
1122 void foo(int x, float y);
1123 void foo(float x, int y);
1124 void foo(float x, float y);
1125 void bar(int x, int y = 0);
1126 int main() { foo(^); }
1128 EXPECT_THAT(Results.signatures,
1129 UnorderedElementsAre(Sig("foo([[float x]], [[float y]]) -> void"),
1130 Sig(
"foo([[float x]], [[int y]]) -> void"),
1131 Sig(
"foo([[int x]], [[float y]]) -> void"),
1132 Sig(
"foo([[int x]], [[int y]]) -> void")));
1134 EXPECT_EQ(0,
Results.activeSignature);
1135 EXPECT_EQ(0,
Results.activeParameter);
1138 TEST(SignatureHelpTest, DefaultArgs) {
1139 auto Results = signatures(R
"cpp(
1140 void bar(int x, int y = 0);
1141 void bar(float x = 0, int y = 42);
1144 EXPECT_THAT(Results.signatures,
1145 UnorderedElementsAre(
1146 Sig("bar([[int x]], [[int y = 0]]) -> void"),
1147 Sig(
"bar([[float x = 0]], [[int y = 42]]) -> void")));
1148 EXPECT_EQ(0,
Results.activeSignature);
1149 EXPECT_EQ(0,
Results.activeParameter);
1152 TEST(SignatureHelpTest, ActiveArg) {
1153 auto Results = signatures(R
"cpp(
1154 int baz(int a, int b, int c);
1155 int main() { baz(baz(1,2,3), ^); }
1157 EXPECT_THAT(Results.signatures,
1158 ElementsAre(Sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1159 EXPECT_EQ(0,
Results.activeSignature);
1160 EXPECT_EQ(1,
Results.activeParameter);
1163 TEST(SignatureHelpTest, OpeningParen) {
1164 llvm::StringLiteral Tests[] = {
1166 int foo(int a, int b, int c);
1168 foo(foo $p^( foo(10, 10, 10), ^ )));
1173 Foo(int a, int b, int c);
1181 Foo(int a, int b, int c);
1184 new Foo $p^( 10, ^ );
1188 int foo(int a, int b, int c);
1192 // Macro expansions.
1197 int foo(int a, int b, int c);
1200 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1201 // the recovery expression.
1202 ID(foo $p^( 10, ^ ))
1205 for (
auto Test : Tests) {
1206 Annotations
Code(Test);
1207 EXPECT_EQ(signatures(
Code.code(),
Code.point()).argListStart,
1209 <<
"Test source:" << Test;
1213 TEST(SignatureHelpTest, StalePreamble) {
1216 IgnoreDiagnostics
Diags;
1223 ASSERT_TRUE(EmptyPreamble);
1225 TU.AdditionalFiles[
"a.h"] =
"int foo(int x);";
1226 const Annotations Test(R
"cpp(
1228 void bar() { foo(^2); })cpp");
1229 TU.Code = Test.code().str();
1231 *EmptyPreamble, TU.inputs(
FS));
1232 EXPECT_THAT(
Results.signatures, ElementsAre(Sig(
"foo([[int x]]) -> int")));
1233 EXPECT_EQ(0,
Results.activeSignature);
1234 EXPECT_EQ(0,
Results.activeParameter);
1237 class IndexRequestCollector :
public SymbolIndex {
1240 fuzzyFind(
const FuzzyFindRequest &Req,
1241 llvm::function_ref<
void(
const Symbol &)>
Callback)
const override {
1242 std::unique_lock<std::mutex> Lock(Mut);
1243 Requests.push_back(Req);
1244 ReceivedRequestCV.notify_one();
1248 void lookup(
const LookupRequest &,
1249 llvm::function_ref<
void(
const Symbol &)>)
const override {}
1251 bool refs(
const RefsRequest &,
1252 llvm::function_ref<
void(
const Ref &)>)
const override {
1256 void relations(
const RelationsRequest &,
1257 llvm::function_ref<
void(
const SymbolID &,
const Symbol &)>)
1262 size_t estimateMemoryUsage()
const override {
return 0; }
1264 const std::vector<FuzzyFindRequest> consumeRequests(
size_t Num)
const {
1265 std::unique_lock<std::mutex> Lock(Mut);
1267 [
this, Num] {
return Requests.size() == Num; }));
1268 auto Reqs = std::move(Requests);
1275 mutable std::condition_variable ReceivedRequestCV;
1276 mutable std::mutex Mut;
1277 mutable std::vector<FuzzyFindRequest> Requests;
1281 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef
Code,
1283 clangd::CodeCompleteOptions Opts;
1284 IndexRequestCollector Requests;
1285 Opts.
Index = &Requests;
1286 completions(
Code, {}, Opts);
1287 const auto Reqs = Requests.consumeRequests(Num);
1288 EXPECT_EQ(Reqs.size(), Num);
1292 TEST(CompletionTest, UnqualifiedIdQuery) {
1293 auto Requests = captureIndexRequests(R
"cpp(
1295 using namespace std;
1303 EXPECT_THAT(Requests,
1305 UnorderedElementsAre("",
"ns::",
"std::"))));
1308 TEST(CompletionTest, EnclosingScopeComesFirst) {
1309 auto Requests = captureIndexRequests(R
"cpp(
1311 using namespace std;
1323 EXPECT_THAT(Requests,
1326 UnorderedElementsAre("",
"std::",
"nx::ns::",
"nx::"))));
1327 EXPECT_EQ(Requests[0].Scopes[0],
"nx::ns::");
1330 TEST(CompletionTest, ResolvedQualifiedIdQuery) {
1331 auto Requests = captureIndexRequests(R
"cpp(
1333 namespace ns2 {} // ignore
1334 namespace ns3 { namespace nns3 {} }
1336 using namespace ns1;
1337 using namespace ns3::nns3;
1346 EXPECT_THAT(Requests,
1349 UnorderedElementsAre("foo::",
"ns1::",
"ns3::nns3::"))));
1352 TEST(CompletionTest, UnresolvedQualifierIdQuery) {
1353 auto Requests = captureIndexRequests(R
"cpp(
1363 EXPECT_THAT(Requests,
1366 UnorderedElementsAre("a::bar::",
"ns::bar::",
"bar::"))));
1369 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
1370 auto Requests = captureIndexRequests(R
"cpp(
1381 UnorderedElementsAre("a::bar::"))));
1384 TEST(CompletionTest, EmptyQualifiedQuery) {
1385 auto Requests = captureIndexRequests(R
"cpp(
1394 UnorderedElementsAre("",
"ns::"))));
1397 TEST(CompletionTest, GlobalQualifiedQuery) {
1398 auto Requests = captureIndexRequests(R
"cpp(
1407 UnorderedElementsAre(""))));
1410 TEST(CompletionTest, NoDuplicatedQueryScopes) {
1411 auto Requests = captureIndexRequests(R
"cpp(
1422 EXPECT_THAT(Requests,
1424 UnorderedElementsAre("na::",
"na::nb::",
""))));
1427 TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
1428 auto Completions = completions(
1431 int SomeNameOfField;
1432 typedef int SomeNameOfTypedefField;
1436 {func("::SomeNameInTheIndex"),
func(
"::Foo::SomeNameInTheIndex")});
1438 EXPECT_THAT(Completions.Completions,
1439 AllOf(Contains(Labeled(
"SomeNameOfField")),
1440 Contains(Labeled(
"SomeNameOfTypedefField")),
1441 Not(Contains(Labeled(
"SomeNameInTheIndex")))));
1444 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
1446 auto Completions = completions(
1453 {func("::SomeNameInTheIndex")});
1455 EXPECT_THAT(Completions.Completions,
1456 Not(Contains(Labeled(
"SomeNameInTheIndex"))));
1460 auto Completions = completions(
1464 T::template Y<int>::^
1467 {func("::SomeNameInTheIndex")});
1469 EXPECT_THAT(Completions.Completions,
1470 Not(Contains(Labeled(
"SomeNameInTheIndex"))));
1474 auto Completions = completions(
1481 {func("::SomeNameInTheIndex")});
1483 EXPECT_THAT(Completions.Completions,
1484 Not(Contains(Labeled(
"SomeNameInTheIndex"))));
1488 TEST(CompletionTest, OverloadBundling) {
1489 clangd::CodeCompleteOptions Opts;
1492 std::string Context = R
"cpp(
1494 // Overload with int
1496 // Overload with bool
1505 EXPECT_THAT(completions(Context +
"int y = X().^", {}, Opts).Completions,
1506 UnorderedElementsAre(Labeled(
"a(…)"), Labeled(
"b(float)")));
1509 Symbol NoArgsGFunc =
func(
"GFuncC");
1511 completions(Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1512 UnorderedElementsAre(Labeled(
"GFuncC(…)"), Labeled(
"GFuncD(int)")));
1516 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
1517 NoArgsGFunc.IncludeHeaders.emplace_back(
"<foo>", 1);
1519 completions(Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1520 UnorderedElementsAre(AllOf(Named(
"GFuncC"), InsertInclude(
"<foo>")),
1521 Labeled(
"GFuncC(int)"), Labeled(
"GFuncD(int)")));
1525 completions(Context +
"int y = X().a^", {}, Opts).Completions.front();
1526 EXPECT_EQ(A.Name,
"a");
1527 EXPECT_EQ(A.Signature,
"(…)");
1528 EXPECT_EQ(A.BundleSize, 2u);
1530 EXPECT_EQ(A.ReturnType,
"int");
1532 ASSERT_TRUE(A.Documentation);
1534 A.Documentation->asPlainText(),
1535 AnyOf(HasSubstr(
"Overload with int"), HasSubstr(
"Overload with bool")));
1536 EXPECT_EQ(A.SnippetSuffix,
"($0)");
1539 TEST(CompletionTest, DocumentationFromChangedFileCrash) {
1544 // this is my documentation comment.
1549 MockCompilationDatabase CDB;
1552 Annotations Source(R
"cpp(
1555 // This makes sure we have func from header in the AST.
1561 ASSERT_TRUE(Server.blockUntilIdleForTest());
1568 clangd::CodeCompleteOptions Opts;
1570 CodeCompleteResult Completions =
1574 EXPECT_THAT(Completions.Completions,
1575 Contains(AllOf(Not(IsDocumented()), Named(
"func"))));
1578 TEST(CompletionTest, NonDocComments) {
1579 const char *
Text = R
"cpp(
1580 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
1581 namespace comments_ns {
1584 // ------------------
1587 // A comment and a decl are separated by newlines.
1588 // Therefore, the comment shouldn't show up as doc comment.
1592 // this comment should be in the results.
1599 int comments_quux();
1603 // This comment should not be there.
1606 int Struct<T>::comments_qux() {
1609 // This comment **should** be in results.
1611 int Struct<T>::comments_quux() {
1618 completions(Text).Completions,
1619 UnorderedElementsAre(AllOf(Not(IsDocumented()), Named(
"comments_foo")),
1620 AllOf(IsDocumented(), Named(
"comments_baz")),
1621 AllOf(IsDocumented(), Named(
"comments_quux")),
1622 AllOf(Not(IsDocumented()), Named(
"comments_ns")),
1627 AllOf(IsDocumented(), Named(
"comments_bar")),
1628 AllOf(IsDocumented(), Named(
"comments_qux"))));
1631 TEST(CompletionTest, CompleteOnInvalidLine) {
1634 MockCompilationDatabase CDB;
1636 FS.
Files[FooCpp] =
"// empty file";
1643 EXPECT_THAT_EXPECTED(
1648 TEST(CompletionTest, QualifiedNames) {
1651 namespace ns { int local; void both(); }
1652 void f() { ::ns::^ }
1654 {func("ns::both"),
cls(
"ns::Index")});
1658 UnorderedElementsAre(Scope(
"ns::"), Scope(
"ns::"), Scope(
"ns::")));
1661 TEST(CompletionTest, Render) {
1664 C.Signature =
"(bool) const";
1665 C.SnippetSuffix =
"(${0:bool})";
1666 C.ReturnType =
"int";
1667 C.RequiredQualifier =
"Foo::";
1668 C.Scope =
"ns::Foo::";
1669 C.Documentation.emplace();
1670 C.Documentation->addParagraph().appendText(
"This is ").appendCode(
"x()");
1671 C.Includes.emplace_back();
1672 auto &Include = C.Includes.back();
1673 Include.Header =
"\"foo.h\"";
1675 C.Score.Total = 1.0;
1676 C.Score.ExcludingName = .5;
1679 CodeCompleteOptions Opts;
1684 auto R = C.render(Opts);
1685 EXPECT_EQ(R.label,
"Foo::x(bool) const");
1686 EXPECT_EQ(R.insertText,
"Foo::x");
1688 EXPECT_EQ(R.filterText,
"x");
1689 EXPECT_EQ(R.detail,
"int");
1690 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\nThis is x()");
1691 EXPECT_THAT(R.additionalTextEdits, IsEmpty());
1692 EXPECT_EQ(R.sortText,
sortText(1.0,
"x"));
1693 EXPECT_FALSE(R.deprecated);
1694 EXPECT_EQ(R.score, .5f);
1698 EXPECT_EQ(R.insertText,
"Foo::x(${0:bool})");
1701 Include.Insertion.emplace();
1703 EXPECT_EQ(R.label,
"^Foo::x(bool) const");
1704 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
1708 EXPECT_EQ(R.label,
"^[AS]Foo::x(bool) const");
1712 EXPECT_EQ(R.detail,
"[2 overloads]");
1713 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\nThis is x()");
1715 C.Deprecated =
true;
1717 EXPECT_TRUE(R.deprecated);
1721 EXPECT_EQ(R.documentation->value,
"From `\"foo.h\"` \nThis is `x()`");
1724 TEST(CompletionTest, IgnoreRecoveryResults) {
1727 namespace ns { int NotRecovered() { return 0; } }
1729 // Sema enters recovery mode first and then normal mode.
1730 if (auto x = ns::NotRecover^)
1733 EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("NotRecovered")));
1736 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
1740 class X { public: X(); int x_; };
1744 EXPECT_THAT(Results.Completions,
1745 UnorderedElementsAre(AllOf(Scope("ns::X::"), Named(
"x_"))));
1748 TEST(CompletionTest, CodeCompletionContext) {
1752 class X { public: X(); int x_; };
1760 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
1763 TEST(CompletionTest, FixItForArrowToDot) {
1765 MockCompilationDatabase CDB;
1767 CodeCompleteOptions Opts;
1775 class ClassWithPtr {
1777 void MemberFunction();
1778 Auxilary* operator->() const;
1787 EXPECT_EQ(
Results.Completions.size(), 3u);
1789 TextEdit ReplacementEdit;
1790 ReplacementEdit.range = Annotations(
Code).range();
1791 ReplacementEdit.newText =
".";
1792 for (
const auto &C :
Results.Completions) {
1793 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name ==
"AuxFunction");
1794 if (!C.FixIts.empty()) {
1795 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
1800 TEST(CompletionTest, FixItForDotToArrow) {
1801 CodeCompleteOptions Opts;
1809 class ClassWithPtr {
1811 void MemberFunction();
1812 Auxilary* operator->() const;
1821 EXPECT_EQ(
Results.Completions.size(), 3u);
1823 TextEdit ReplacementEdit;
1824 ReplacementEdit.range = Annotations(
Code).range();
1825 ReplacementEdit.newText =
"->";
1826 for (
const auto &C :
Results.Completions) {
1827 EXPECT_TRUE(C.FixIts.empty() || C.Name ==
"AuxFunction");
1828 if (!C.FixIts.empty()) {
1829 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit));
1834 TEST(CompletionTest, RenderWithFixItMerged) {
1836 FixIt.range.end.character = 5;
1837 FixIt.newText =
"->";
1841 C.RequiredQualifier =
"Foo::";
1843 C.CompletionTokenRange.start.character = 5;
1845 CodeCompleteOptions Opts;
1848 auto R = C.render(Opts);
1849 EXPECT_TRUE(R.textEdit);
1850 EXPECT_EQ(R.textEdit->newText,
"->Foo::x");
1851 EXPECT_TRUE(R.additionalTextEdits.empty());
1854 TEST(CompletionTest, RenderWithFixItNonMerged) {
1856 FixIt.range.end.character = 4;
1857 FixIt.newText =
"->";
1861 C.RequiredQualifier =
"Foo::";
1863 C.CompletionTokenRange.start.character = 5;
1865 CodeCompleteOptions Opts;
1868 auto R = C.render(Opts);
1869 EXPECT_TRUE(R.textEdit);
1870 EXPECT_EQ(R.textEdit->newText,
"Foo::x");
1871 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(
FixIt));
1874 TEST(CompletionTest, CompletionTokenRange) {
1876 MockCompilationDatabase CDB;
1878 TU.AdditionalFiles[
"foo/abc/foo.h"] =
"";
1880 constexpr
const char *TestCodes[] = {
1902 #include "foo/[[a^/]]foo.h"
1905 #include "foo/abc/[[fo^o.h"]]
1908 for (
const auto &Text : TestCodes) {
1909 Annotations TestCode(Text);
1910 TU.Code = TestCode.code().str();
1911 auto Results = completions(TU, TestCode.point());
1912 if (
Results.Completions.size() != 1) {
1913 ADD_FAILURE() <<
"Results.Completions.size() != 1" <<
Text;
1916 EXPECT_THAT(
Results.Completions.front().CompletionTokenRange,
1921 TEST(SignatureHelpTest, OverloadsOrdering) {
1922 const auto Results = signatures(R
"cpp(
1924 void foo(int x, float y);
1925 void foo(float x, int y);
1926 void foo(float x, float y);
1927 void foo(int x, int y = 0);
1928 int main() { foo(^); }
1930 EXPECT_THAT(Results.signatures,
1931 ElementsAre(Sig("foo([[int x]]) -> void"),
1932 Sig(
"foo([[int x]], [[int y = 0]]) -> void"),
1933 Sig(
"foo([[float x]], [[int y]]) -> void"),
1934 Sig(
"foo([[int x]], [[float y]]) -> void"),
1935 Sig(
"foo([[float x]], [[float y]]) -> void")));
1937 EXPECT_EQ(0,
Results.activeSignature);
1938 EXPECT_EQ(0,
Results.activeParameter);
1941 TEST(SignatureHelpTest, InstantiatedSignatures) {
1942 StringRef Sig0 = R
"cpp(
1951 EXPECT_THAT(signatures(Sig0).signatures,
1952 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void")));
1954 StringRef Sig1 = R
"cpp(
1962 EXPECT_THAT(signatures(Sig1).signatures,
1963 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void")));
1965 StringRef Sig2 = R
"cpp(
1966 template <class ...T>
1974 EXPECT_THAT(signatures(Sig2).signatures,
1975 ElementsAre(Sig("foo([[T...]]) -> void")));
1982 StringRef Sig3 = R
"cpp(
1990 X<int>().foo<double>(^)
1994 EXPECT_THAT(signatures(Sig3).signatures,
1995 ElementsAre(Sig("foo([[T]], [[U]]) -> void")));
1998 TEST(SignatureHelpTest, IndexDocumentation) {
1999 Symbol Foo0 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#");
2000 Foo0.Documentation =
"Doc from the index";
2001 Symbol Foo1 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#");
2002 Foo1.Documentation =
"Doc from the index";
2003 Symbol Foo2 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#I#");
2005 StringRef Sig0 = R
"cpp(
2015 signatures(Sig0, {Foo0}).signatures,
2016 ElementsAre(AllOf(Sig("foo() -> int"), SigDoc(
"Doc from the index")),
2017 AllOf(Sig(
"foo([[double]]) -> int"), SigDoc(
""))));
2019 StringRef Sig1 = R
"cpp(
2021 // Overriden doc from sema
2032 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
2034 AllOf(Sig("foo() -> int"), SigDoc(
"Doc from the index")),
2035 AllOf(Sig(
"foo([[int]]) -> int"), SigDoc(
"Overriden doc from sema")),
2036 AllOf(Sig(
"foo([[int]], [[int]]) -> int"), SigDoc(
"Doc from sema"))));
2039 TEST(SignatureHelpTest, DynamicIndexDocumentation) {
2041 MockCompilationDatabase CDB;
2043 Opts.BuildDynamicSymbolIndex =
true;
2044 ClangdServer Server(CDB,
FS, Opts);
2052 Annotations FileContent(R"cpp(
2060 Server.addDocument(File, FileContent.code());
2062 ASSERT_TRUE(Server.blockUntilIdleForTest());
2066 ElementsAre(AllOf(Sig(
"foo() -> int"), SigDoc(
"Member doc"))));
2069 TEST(CompletionTest, CompletionFunctionArgsDisabled) {
2070 CodeCompleteOptions Opts;
2078 void xfoo(int x, int y);
2079 void f() { xfo^ })cpp",
2083 UnorderedElementsAre(AllOf(Named("xfoo"),
SnippetSuffix(
"()")),
2090 void f() { xba^ })cpp",
2092 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2100 void xfoo(int x, int y);
2101 void f() { xfo^ })cpp",
2105 UnorderedElementsAre(AllOf(Named("xfoo"),
SnippetSuffix(
"($0)"))));
2110 template <class T, class U>
2111 void xfoo(int a, U b);
2112 void f() { xfo^ })cpp",
2116 UnorderedElementsAre(AllOf(Named("xfoo"),
SnippetSuffix(
"<$1>($0)"))));
2124 using foo_alias = T**;
2125 void f() { foo_^ })cpp",
2129 UnorderedElementsAre(AllOf(Named("foo_class"),
SnippetSuffix(
"<$0>")),
2134 TEST(CompletionTest, SuggestOverrides) {
2135 constexpr
const char *
const Text(R
"cpp(
2138 virtual void vfunc(bool param);
2139 virtual void vfunc(bool param, int p);
2140 void func(bool param);
2142 class B : public A {
2143 virtual void ttt(bool param) const;
2144 void vfunc(bool param, int p) override;
2146 class C : public B {
2148 void vfunc(bool param) override;
2152 const auto Results = completions(Text);
2155 AllOf(Contains(AllOf(Labeled(
"void vfunc(bool param, int p) override"),
2156 NameStartsWith(
"vfunc"))),
2157 Contains(AllOf(Labeled(
"void ttt(bool param) const override"),
2158 NameStartsWith(
"ttt"))),
2159 Not(Contains(Labeled(
"void vfunc(bool param) override")))));
2162 TEST(CompletionTest, OverridesNonIdentName) {
2166 virtual ~Base() = 0;
2167 virtual operator int() = 0;
2168 virtual Base& operator+(Base&) = 0;
2171 struct Derived : Base {
2177 TEST(GuessCompletionPrefix, Filters) {
2178 for (llvm::StringRef Case : {
2179 "[[scope::]][[ident]]^",
2188 "some text [[scope::more::]][[identif]]^ier",
2189 "some text [[scope::]][[mor]]^e::identifier",
2190 "weird case foo::[[::bar::]][[baz]]^",
2193 Annotations F(Case);
2195 auto ToStringRef = [&](
Range R) {
2199 auto WantQualifier = ToStringRef(F.ranges()[0]),
2200 WantName = ToStringRef(F.ranges()[1]);
2204 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
2205 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
2206 EXPECT_EQ(WantName, Prefix.Name) << Case;
2207 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
2211 TEST(CompletionTest, EnableSpeculativeIndexRequest) {
2213 MockCompilationDatabase CDB;
2217 Annotations Test(R
"cpp(
2218 namespace ns1 { int abc; }
2219 namespace ns2 { int abc; }
2220 void f() { ns1::ab$1^; ns1::ab$2^; }
2221 void f2() { ns2::ab$3^; }
2224 clangd::CodeCompleteOptions Opts = {};
2226 IndexRequestCollector Requests;
2227 Opts.Index = &Requests;
2230 auto CompleteAtPoint = [&](StringRef P) {
2234 CompleteAtPoint(
"1");
2235 auto Reqs1 = Requests.consumeRequests(1);
2236 ASSERT_EQ(Reqs1.size(), 1u);
2237 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre(
"ns1::"));
2239 CompleteAtPoint(
"2");
2240 auto Reqs2 = Requests.consumeRequests(1);
2242 ASSERT_EQ(Reqs2.size(), 1u);
2243 EXPECT_EQ(Reqs2[0], Reqs1[0]);
2245 CompleteAtPoint(
"3");
2248 auto Reqs3 = Requests.consumeRequests(2);
2249 ASSERT_EQ(Reqs3.size(), 2u);
2252 TEST(CompletionTest, InsertTheMostPopularHeader) {
2254 Symbol Sym =
func(
"Func");
2255 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2256 Sym.IncludeHeaders.emplace_back(
"\"foo.h\"", 2);
2257 Sym.IncludeHeaders.emplace_back(
"\"bar.h\"", 1000);
2259 auto Results = completions(
"Fun^", {Sym}).Completions;
2261 EXPECT_THAT(
Results[0], AllOf(Named(
"Func"), InsertInclude(
"\"bar.h\"")));
2262 EXPECT_EQ(
Results[0].Includes.size(), 2u);
2265 TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
2266 Annotations Test(R
"cpp(
2274 Symbol Sym =
func(
"Func");
2275 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2276 Sym.IncludeHeaders.emplace_back(
"\"foo.h\"", 2);
2277 Sym.IncludeHeaders.emplace_back(
"\"bar.h\"", 1000);
2279 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions,
2280 UnorderedElementsAre(AllOf(Named(
"Func"), HasInclude(
"\"foo.h\""),
2281 Not(InsertInclude()))));
2284 TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
2286 Sym.Name =
"Clangd_Macro_Test";
2287 Sym.ID =
SymbolID(
"c:foo.cpp@8@macro@Clangd_Macro_Test");
2288 Sym.SymInfo.Kind = index::SymbolKind::Macro;
2290 EXPECT_THAT(completions(
"#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
2292 UnorderedElementsAre(Named(
"Clangd_Macro_Test")));
2295 TEST(CompletionTest, MacroFromPreamble) {
2296 Annotations Test(R
"cpp(#define CLANGD_PREAMBLE_MAIN x
2299 #define CLANGD_MAIN x
2300 void f() { CLANGD_^ }
2303 TU.
HeaderCode =
"#define CLANGD_PREAMBLE_HEADER x";
2304 auto Results = completions(TU, Test.point(), {
func(
"CLANGD_INDEX")});
2307 EXPECT_THAT(
Results.Completions,
2308 UnorderedElementsAre(Named(
"CLANGD_PREAMBLE_MAIN"),
2309 Named(
"CLANGD_MAIN"),
2310 Named(
"CLANGD_INDEX")));
2313 TEST(CompletionTest, DeprecatedResults) {
2314 std::string Body = R
"cpp(
2316 void TestClangc() __attribute__((deprecated("", "")));
2320 completions(Body + "int main() { TestClang^ }").Completions,
2321 UnorderedElementsAre(AllOf(Named(
"TestClangd"), Not(Deprecated())),
2322 AllOf(Named(
"TestClangc"), Deprecated())));
2325 TEST(SignatureHelpTest, PartialSpec) {
2326 const auto Results = signatures(R
"cpp(
2327 template <typename T> struct Foo {};
2328 template <typename T> struct Foo<T*> { Foo(T); };
2329 Foo<int*> F(^);)cpp");
2330 EXPECT_THAT(Results.signatures, Contains(Sig("Foo([[T]])")));
2331 EXPECT_EQ(0,
Results.activeParameter);
2334 TEST(SignatureHelpTest, InsideArgument) {
2336 const auto Results = signatures(R
"cpp(
2338 void foo(int x, int y);
2339 int main() { foo(1+^); }
2341 EXPECT_THAT(Results.signatures,
2342 ElementsAre(Sig("foo([[int x]]) -> void"),
2343 Sig(
"foo([[int x]], [[int y]]) -> void")));
2344 EXPECT_EQ(0,
Results.activeParameter);
2347 const auto Results = signatures(R
"cpp(
2349 void foo(int x, int y);
2350 int main() { foo(1^); }
2352 EXPECT_THAT(Results.signatures,
2353 ElementsAre(Sig("foo([[int x]]) -> void"),
2354 Sig(
"foo([[int x]], [[int y]]) -> void")));
2355 EXPECT_EQ(0,
Results.activeParameter);
2358 const auto Results = signatures(R
"cpp(
2360 void foo(int x, int y);
2361 int main() { foo(1^0); }
2363 EXPECT_THAT(Results.signatures,
2364 ElementsAre(Sig("foo([[int x]]) -> void"),
2365 Sig(
"foo([[int x]], [[int y]]) -> void")));
2366 EXPECT_EQ(0,
Results.activeParameter);
2369 const auto Results = signatures(R
"cpp(
2371 void foo(int x, int y);
2372 int bar(int x, int y);
2373 int main() { bar(foo(2, 3^)); }
2375 EXPECT_THAT(Results.signatures,
2376 ElementsAre(Sig("foo([[int x]], [[int y]]) -> void")));
2377 EXPECT_EQ(1,
Results.activeParameter);
2381 TEST(SignatureHelpTest, ConstructorInitializeFields) {
2383 const auto Results = signatures(R
"cpp(
2392 EXPECT_THAT(Results.signatures,
2393 UnorderedElementsAre(Sig("A([[int]])"), Sig(
"A([[A &&]])"),
2394 Sig(
"A([[const A &]])")));
2397 const auto Results = signatures(R
"cpp(
2406 B() : c_elem(A(1^)) {}
2410 EXPECT_THAT(Results.signatures,
2411 UnorderedElementsAre(Sig("A([[int]])"), Sig(
"A([[A &&]])"),
2412 Sig(
"A([[const A &]])")));
2416 TEST(CompletionTest, IncludedCompletionKinds) {
2417 Annotations Test(R
"cpp(#include "^")cpp");
2420 TU.ExtraArgs.push_back(
"-I" +
testPath(
"sub"));
2422 auto Results = completions(TU, Test.point());
2423 EXPECT_THAT(
Results.Completions,
2428 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
2435 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
2436 clangd::CodeCompleteOptions Opts = {};
2441 void f() { na::Clangd^ }
2443 {cls("na::ClangdA"),
cls(
"nx::ClangdX"),
cls(
"Clangd3")}, Opts);
2444 EXPECT_THAT(
Results.Completions,
2445 UnorderedElementsAre(
2446 AllOf(
Qualifier(
""), Scope(
"na::"), Named(
"ClangdA"))));
2449 TEST(CompletionTest, AllScopesCompletion) {
2450 clangd::CodeCompleteOptions Opts = {};
2456 void f() { Clangd^ }
2459 {cls("nx::Clangd1"),
cls(
"ny::Clangd2"),
cls(
"Clangd3"),
2460 cls(
"na::nb::Clangd4")},
2464 UnorderedElementsAre(AllOf(
Qualifier(
"nx::"), Named(
"Clangd1")),
2465 AllOf(
Qualifier(
"ny::"), Named(
"Clangd2")),
2466 AllOf(
Qualifier(
""), Scope(
""), Named(
"Clangd3")),
2467 AllOf(
Qualifier(
"nb::"), Named(
"Clangd4"))));
2470 TEST(CompletionTest, NoQualifierIfShadowed) {
2471 clangd::CodeCompleteOptions Opts = {};
2474 auto Results = completions(R
"cpp(
2475 namespace nx { class Clangd1 {}; }
2477 void f() { Clangd^ }
2479 {cls("nx::Clangd1"),
cls(
"nx::Clangd2")}, Opts);
2482 EXPECT_THAT(
Results.Completions,
2483 UnorderedElementsAre(AllOf(
Qualifier(
""), Named(
"Clangd1")),
2484 AllOf(
Qualifier(
"nx::"), Named(
"Clangd2"))));
2487 TEST(CompletionTest, NoCompletionsForNewNames) {
2488 clangd::CodeCompleteOptions Opts;
2490 auto Results = completions(R
"cpp(
2493 {cls("naber"),
cls(
"nx::naber")}, Opts);
2494 EXPECT_THAT(
Results.Completions, UnorderedElementsAre());
2497 TEST(CompletionTest, Lambda) {
2498 clangd::CodeCompleteOptions Opts = {};
2500 auto Results = completions(R
"cpp(
2502 auto Lambda = [](int a, const double &b) {return 1.f;};
2508 ASSERT_EQ(Results.Completions.size(), 1u);
2509 const auto &A =
Results.Completions.front();
2510 EXPECT_EQ(A.Name,
"Lambda");
2511 EXPECT_EQ(A.Signature,
"(int a, const double &b) const");
2513 EXPECT_EQ(A.ReturnType,
"float");
2514 EXPECT_EQ(A.SnippetSuffix,
"(${1:int a}, ${2:const double &b})");
2517 TEST(CompletionTest, ObjectiveCMethodNoArguments) {
2518 auto Results = completions(R
"objc(
2520 @property(nonatomic, setter=setXToIgnoreComplete:) int value;
2522 Foo *foo = [Foo new]; int y = [foo v^]
2528 EXPECT_THAT(C, ElementsAre(Named(
"value")));
2530 EXPECT_THAT(C, ElementsAre(
ReturnType(
"int")));
2531 EXPECT_THAT(C, ElementsAre(
Signature(
"")));
2535 TEST(CompletionTest, ObjectiveCMethodOneArgument) {
2536 auto Results = completions(R
"objc(
2538 - (int)valueForCharacter:(char)c;
2540 Foo *foo = [Foo new]; int y = [foo v^]
2546 EXPECT_THAT(C, ElementsAre(Named(
"valueForCharacter:")));
2548 EXPECT_THAT(C, ElementsAre(
ReturnType(
"int")));
2549 EXPECT_THAT(C, ElementsAre(
Signature(
"(char)")));
2553 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
2554 auto Results = completions(R
"objc(
2556 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
2564 EXPECT_THAT(C, ElementsAre(Named(
"fooWithValue:")));
2566 EXPECT_THAT(C, ElementsAre(
ReturnType(
"id")));
2567 EXPECT_THAT(C, ElementsAre(
Signature(
"(int) fooey:(unsigned int)")));
2569 C, ElementsAre(
SnippetSuffix(
"${1:(int)} fooey:${2:(unsigned int)}")));
2572 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
2573 auto Results = completions(R
"objc(
2575 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
2577 id val = [Foo fooWithValue:10 f^]
2583 EXPECT_THAT(C, ElementsAre(Named(
"fooey:")));
2585 EXPECT_THAT(C, ElementsAre(
ReturnType(
"id")));
2586 EXPECT_THAT(C, ElementsAre(
Signature(
"(unsigned int)")));
2587 EXPECT_THAT(C, ElementsAre(
SnippetSuffix(
"${1:(unsigned int)}")));
2590 TEST(CompletionTest, CursorInSnippets) {
2591 clangd::CodeCompleteOptions Options;
2592 Options.EnableSnippets =
true;
2595 void while_foo(int a, int b);
2602 EXPECT_THAT(
Results.Completions,
2605 SnippetSuffix(
" (${1:condition}) {\n${0:statements}\n}"))));
2607 EXPECT_THAT(
Results.Completions,
2608 Contains(AllOf(Named(
"while_foo"),
2612 TEST(CompletionTest, WorksWithNullType) {
2613 auto R = completions(R
"cpp(
2615 for (auto [loopVar] : y ) { // y has to be unresolved.
2620 EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar")));
2623 TEST(CompletionTest, UsingDecl) {
2624 const char *Header(R
"cpp(
2629 const char *Source(R
"cpp(
2634 clangd::CodeCompleteOptions Opts;
2637 auto R = completions(Source, {}, Opts);
2638 EXPECT_THAT(R.Completions,
2639 ElementsAre(AllOf(Scope(
"std::"), Named(
"foo"),
2643 TEST(CompletionTest, ScopeIsUnresolved) {
2644 clangd::CodeCompleteOptions Opts = {};
2647 auto Results = completions(R
"cpp(
2652 {cls("a::b::XYZ")}, Opts);
2653 EXPECT_THAT(
Results.Completions,
2654 UnorderedElementsAre(AllOf(
Qualifier(
""), Named(
"XYZ"))));
2657 TEST(CompletionTest, NestedScopeIsUnresolved) {
2658 clangd::CodeCompleteOptions Opts = {};
2661 auto Results = completions(R
"cpp(
2664 void f() { b::c::X^ }
2667 {cls("a::b::c::XYZ")}, Opts);
2668 EXPECT_THAT(
Results.Completions,
2669 UnorderedElementsAre(AllOf(
Qualifier(
""), Named(
"XYZ"))));
2674 TEST(CompletionTest, NamespaceDoubleInsertion) {
2675 clangd::CodeCompleteOptions Opts = {};
2677 auto Results = completions(R
"cpp(
2684 {cls("foo::ns::ABCDE")}, Opts);
2685 EXPECT_THAT(
Results.Completions,
2686 UnorderedElementsAre(AllOf(
Qualifier(
""), Named(
"ABCDE"))));
2689 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
2692 auto Completions = completions(R
"cpp(
2695 double size() const;
2697 struct deque : deque_base {
2704 EXPECT_THAT(Completions,
2705 ElementsAre(AllOf(ReturnType("int"), Named(
"size"))));
2708 TEST(CompletionTest, NoCrashWithIncompleteLambda) {
2709 auto Completions = completions(
"auto&& x = []{^").Completions;
2713 EXPECT_THAT(Completions, Contains(Named(
"x")));
2715 auto Signatures = signatures(
"auto x() { x(^").signatures;
2716 EXPECT_THAT(Signatures, Contains(Sig(
"x() -> auto")));
2719 TEST(CompletionTest, DelayedTemplateParsing) {
2720 Annotations Test(R
"cpp(
2722 template <typename T> int foo() { return xx^; }
2727 TU.
ExtraArgs.push_back(
"-fdelayed-template-parsing");
2729 EXPECT_THAT(completions(TU, Test.point()).Completions,
2730 Contains(Named(
"xxx")));
2733 TEST(CompletionTest, CompletionRange) {
2734 const char *WithRange =
"auto x = [[abc]]^";
2735 auto Completions = completions(WithRange);
2736 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
2737 Completions = completionsNoCompile(WithRange);
2738 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
2740 const char *EmptyRange =
"auto x = [[]]^";
2741 Completions = completions(EmptyRange);
2742 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
2743 Completions = completionsNoCompile(EmptyRange);
2744 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
2748 const char *NoCompletion =
"/* [[]]^ */";
2749 Completions = completions(NoCompletion);
2750 EXPECT_EQ(Completions.CompletionRange,
llvm::None);
2751 Completions = completionsNoCompile(NoCompletion);
2752 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
2755 TEST(NoCompileCompletionTest, Basic) {
2756 auto Results = completionsNoCompile(R
"cpp(
2763 EXPECT_FALSE(Results.RanParser);
2764 EXPECT_THAT(Results.Completions,
2765 UnorderedElementsAre(Named("void"), Named(
"func"), Named(
"int"),
2766 Named(
"xyz"), Named(
"abc")));
2769 TEST(NoCompileCompletionTest, WithFilter) {
2770 auto Results = completionsNoCompile(R
"cpp(
2779 EXPECT_THAT(Results.Completions,
2780 UnorderedElementsAre(Named("sym1"), Named(
"sym2")));
2783 TEST(NoCompileCompletionTest, WithIndex) {
2784 std::vector<Symbol> Syms = {
func(
"xxx"),
func(
"a::xxx"),
func(
"ns::b::xxx"),
2785 func(
"c::xxx"),
func(
"ns::d::xxx")};
2786 auto Results = completionsNoCompile(
2788 // Current-scopes, unqualified completion.
2798 EXPECT_THAT(Results.Completions,
2799 UnorderedElementsAre(AllOf(Qualifier(""), Scope(
"")),
2801 AllOf(
Qualifier(
""), Scope(
"ns::b::"))));
2802 CodeCompleteOptions Opts;
2804 Results = completionsNoCompile(
2806 // All-scopes unqualified completion.
2816 EXPECT_THAT(Results.Completions,
2817 UnorderedElementsAre(AllOf(Qualifier(""), Scope(
"")),
2821 AllOf(
Qualifier(
"d::"), Scope(
"ns::d::"))));
2822 Results = completionsNoCompile(
2824 // Qualified completion.
2834 EXPECT_THAT(Results.Completions,
2835 ElementsAre(AllOf(Qualifier(""), Scope(
"ns::b::"))));
2836 Results = completionsNoCompile(
2838 // Absolutely qualified completion.
2848 EXPECT_THAT(Results.Completions,
2849 ElementsAre(AllOf(Qualifier(""), Scope(
"a::"))));
2852 TEST(AllowImplicitCompletion, All) {
2853 const char *
Yes[] = {
2857 " # include <^foo.h>",
2858 "#import <foo/^bar.h>",
2859 "#include_next \"^",
2861 const char *
No[] = {
2865 "#include <foo.h> //^",
2866 "#include \"foo.h\"^",
2870 for (
const char *Test : Yes) {
2871 llvm::Annotations A(Test);
2874 for (
const char *Test : No) {
2875 llvm::Annotations A(Test);
2880 TEST(CompletionTest, FunctionArgsExist) {
2881 clangd::CodeCompleteOptions Opts;
2883 std::string Context = R
"cpp(
2889 template <typename T>
2891 Container(int Size) {}
2894 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions,
2895 UnorderedElementsAre(
2896 AllOf(Labeled(
"foo(int A)"),
SnippetSuffix(
"(${1:int A})"))));
2898 completions(Context +
"int y = fo^(42)", {}, Opts).Completions,
2899 UnorderedElementsAre(AllOf(Labeled(
"foo(int A)"),
SnippetSuffix(
""))));
2901 EXPECT_THAT(completions(Context +
"int y = fo^o(42)", {}, Opts).Completions,
2902 UnorderedElementsAre(
2903 AllOf(Labeled(
"foo(int A)"),
SnippetSuffix(
"(${1:int A})"))));
2905 completions(Context +
"int y = ba^", {}, Opts).Completions,
2906 UnorderedElementsAre(AllOf(Labeled(
"bar()"),
SnippetSuffix(
"()"))));
2907 EXPECT_THAT(completions(Context +
"int y = ba^()", {}, Opts).Completions,
2908 UnorderedElementsAre(AllOf(Labeled(
"bar()"),
SnippetSuffix(
""))));
2910 completions(Context +
"Object o = Obj^", {}, Opts).Completions,
2911 Contains(AllOf(Labeled(
"Object(int B)"),
SnippetSuffix(
"(${1:int B})"),
2913 EXPECT_THAT(completions(Context +
"Object o = Obj^()", {}, Opts).Completions,
2917 completions(Context +
"Container c = Cont^", {}, Opts).Completions,
2918 Contains(AllOf(Labeled(
"Container<typename T>(int Size)"),
2924 completions(Context +
"Container c = Cont^()", {}, Opts).Completions,
2925 Contains(AllOf(Labeled(
"Container<typename T>(int Size)"),