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;
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;
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.CompletionTokenRange ==
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) {
110 SymbolSlab::Builder Slab;
111 for (
const auto &Sym :
Symbols)
113 return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
118CodeCompleteResult completions(
const TestTU &TU, Position Point,
119 std::vector<Symbol> IndexSymbols = {},
120 clangd::CodeCompleteOptions Opts = {}) {
121 std::unique_ptr<SymbolIndex> OverrideIndex;
122 if (!IndexSymbols.empty()) {
123 assert(!Opts.
Index &&
"both Index and IndexSymbols given!");
124 OverrideIndex = memIndex(std::move(IndexSymbols));
125 Opts.
Index = OverrideIndex.get();
129 auto Inputs = TU.inputs(FS);
130 IgnoreDiagnostics Diags;
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") {
147 Annotations Test(
Text);
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();
168 Annotations Test(
Text);
169 ParseInputs
ParseInput{tooling::CompileCommand(), &FS, Test.code().str()};
174Symbol withReferences(
int N, Symbol S) {
179#if CLANGD_DECISION_FOREST
180TEST(DecisionForestRankingModel, NameMatchSanityTest) {
181 clangd::CodeCompleteOptions Opts;
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;
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;
220 const SymbolRelevanceSignals &,
float Base) {
221 DecisionForestScores Scores;
222 Scores.Total = MagicNumber;
223 Scores.ExcludingName = MagicNumber;
226 llvm::StringRef Code =
"int func() { int xyz; xy^ }";
227 auto Results = completions(Code,
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);
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().^ }
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"))));
276 Symbol Sym =
var(
"MotorCarIndex");
277 Sym.SymInfo.Kind = index::SymbolKind::Macro;
279 completions(Body +
"int main() { C^ }", {Sym}).Completions,
280 AllOf(has(
"Car"), Not(has(
"MotorCar")), Not(has(
"MotorCarIndex"))));
281 EXPECT_THAT(completions(Body +
"int main() { M^ }", {Sym}).Completions,
282 AllOf(has(
"MotorCar"), has(
"MotorCarIndex")));
285void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) {
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"))));
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) {
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);
397 for (
auto &F :
Flags) {
398 clangd::CodeCompleteOptions O;
404TEST(CompletionTest, Accessible) {
405 auto Internal = completions(R
"cpp(
408 protected: void prot();
409 private: void priv();
411 void Foo::pub() { this->^ }
413 EXPECT_THAT(Internal.Completions,
414 AllOf(has("priv"), has(
"prot"), has(
"pub")));
416 auto External = completions(R
"cpp(
419 protected: void prot();
420 private: void priv();
427 EXPECT_THAT(External.Completions,
428 AllOf(has("pub"), Not(has(
"prot")), Not(has(
"priv"))));
430 auto Results = completions(R
"cpp(
433 protected: void prot();
434 private: void priv();
436 struct Bar : public Foo {
437 private: using Foo::pub;
444 EXPECT_THAT(Results.Completions,
445 AllOf(Not(has("priv")), Not(has(
"prot")), Not(has(
"pub"))));
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;
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;
532 Annotations Code(R
"cpp(
534 static int staticMethod(int);
535 int method(int) const;
536 template <typename T, typename U, typename V = int>
538 template <typename T, int U>
539 static T staticGeneric();
547 struct Derived : Foo {
560 ; // Prevent parsing as 'f.f'
566 d.Derived::$canBeCall^
574 ; // Prevent parsing as 'f.f'
580 d.Derived::$canBeCall^
585 for (
const auto &P : Code.points(
"canNotBeCall")) {
586 auto Results = completions(TU, P, {}, Opts);
587 EXPECT_THAT(
Results.Completions,
588 Contains(AllOf(named(
"method"), signature(
"(int) const"),
589 snippetSuffix(
""))));
594 Contains(AllOf(named(
"generic"),
595 signature(
"<typename T, typename U>(U, V)"),
596 snippetSuffix(
"<${1:typename T}, ${2:typename U}>"))));
599 for (
const auto &P : Code.points(
"canBeCall")) {
600 auto Results = completions(TU, P, {}, Opts);
601 EXPECT_THAT(
Results.Completions,
602 Contains(AllOf(named(
"method"), signature(
"(int) const"),
603 snippetSuffix(
"(${1:int})"))));
606 Contains(AllOf(named(
"generic"), signature(
"<typename T>(U, V)"),
607 snippetSuffix(
"<${1:typename T}>(${2:U}, ${3:V})"))));
611 for (
const auto &P : Code.points()) {
612 auto Results = completions(TU, P, {}, Opts);
613 EXPECT_THAT(
Results.Completions,
614 Contains(AllOf(named(
"staticMethod"), signature(
"(int)"),
615 snippetSuffix(
"(${1:int})"))));
616 EXPECT_THAT(
Results.Completions,
618 named(
"staticGeneric"), signature(
"<typename T, int U>()"),
619 snippetSuffix(
"<${1:typename T}, ${2:int U}>()"))));
623TEST(CompletionTest, NoSnippetsInUsings) {
624 clangd::CodeCompleteOptions Opts;
629 int func(int a, int b);
635 EXPECT_THAT(
Results.Completions,
636 ElementsAre(AllOf(named(
"func"), labeled(
"func(int a, int b)"),
637 snippetSuffix(
""))));
640 auto Func =
func(
"ns::func");
641 Func.CompletionSnippetSuffix =
"(${1:int a}, ${2: int b})";
642 Func.Signature =
"(int a, int b)";
643 Func.ReturnType =
"void";
650 EXPECT_THAT(
Results.Completions,
651 ElementsAre(AllOf(named(
"func"), labeled(
"func(int a, int b)"),
652 snippetSuffix(
""))));
660 EXPECT_THAT(
Results.Completions,
661 Contains(AllOf(named(
"func"), labeled(
"ns::func(int a, int b)"),
662 snippetSuffix(
""))));
665TEST(CompletionTest, Kinds) {
671 // make sure MACRO is not included in preamble.
675 {func("indexFunction"),
var(
"indexVariable"),
cls(
"indexClass"),
676 macro(
"indexObjMacro"),
macro(
"indexFuncMacro",
"(x, y)")});
677 EXPECT_THAT(
Results.Completions,
690 EXPECT_THAT(
Results.Completions,
710 template <class T> struct complete_class {};
711 template <class T> void complete_function();
712 template <class T> using complete_type_alias = int;
713 template <class T> int complete_variable = 10;
716 template <class T> static int complete_static_member = 10;
718 static auto x = complete_^
723 UnorderedElementsAre(
726 AllOf(named(
"complete_type_alias"),
729 AllOf(named(
"complete_static_member"),
744TEST(CompletionTest, NoDuplicates) {
757 EXPECT_THAT(
Results.Completions, ElementsAre(named(
"Adapter")));
760TEST(CompletionTest, ScopedNoIndex) {
763 namespace fake { int BigBang, Babble, Box; };
764 int main() { fake::ba^ }
767 EXPECT_THAT(
Results.Completions,
768 ElementsAre(named(
"Babble"), named(
"BigBang")));
771TEST(CompletionTest, Scoped) {
774 namespace fake { int Babble, Box; };
775 int main() { fake::ba^ }
777 {var("fake::BigBang")});
778 EXPECT_THAT(
Results.Completions,
779 ElementsAre(named(
"Babble"), named(
"BigBang")));
782TEST(CompletionTest, ScopedWithFilter) {
787 {cls("ns::XYZ"),
func(
"ns::foo")});
788 EXPECT_THAT(
Results.Completions, UnorderedElementsAre(named(
"XYZ")));
791TEST(CompletionTest, ReferencesAffectRanking) {
792 EXPECT_THAT(completions(
"int main() { abs^ }", {
func(
"absA"),
func(
"absB")})
795 EXPECT_THAT(completions(
"int main() { abs^ }",
796 {
func(
"absA"), withReferences(1000,
func(
"absB"))})
801TEST(CompletionTest, ContextWords) {
802 auto Results = completions(R
"cpp(
803 enum class Color { RED, YELLOW, BLUE };
805 // (blank lines so the definition above isn't "context")
807 // "It was a yellow car," he said. "Big yellow car, new."
808 auto Finish = Color::^
812 ASSERT_THAT(
Results.Completions,
816TEST(CompletionTest, GlobalQualified) {
822 EXPECT_THAT(
Results.Completions,
827TEST(CompletionTest, FullyQualified) {
830 namespace ns { void bar(); }
834 EXPECT_THAT(
Results.Completions,
839TEST(CompletionTest, SemaIndexMerge) {
842 namespace ns { int local; void both(); }
845 {func("ns::both"),
cls(
"ns::Index")});
847 EXPECT_THAT(
Results.Completions,
848 UnorderedElementsAre(
855TEST(CompletionTest, SemaIndexMergeWithLimit) {
856 clangd::CodeCompleteOptions Opts;
860 namespace ns { int local; void both(); }
863 {func("ns::both"),
cls(
"ns::Index")}, Opts);
868TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
870 TU.ExtraArgs.push_back(
"-I" +
testPath(
"sub"));
871 TU.AdditionalFiles[
"sub/bar.h"] =
"";
874 Symbol Sym =
cls(
"ns::X");
875 Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
878 Annotations Test(
"int main() { ns::^ }");
879 TU.Code = Test.code().str();
880 auto Results = completions(TU, Test.point(), {Sym});
881 EXPECT_THAT(
Results.Completions,
882 ElementsAre(AllOf(named(
"X"), insertInclude(
"\"bar.h\""))));
884 CodeCompleteOptions NoInsertion;
886 Results = completions(TU, Test.point(), {Sym}, NoInsertion);
887 EXPECT_THAT(
Results.Completions,
888 ElementsAre(AllOf(named(
"X"), Not(insertInclude()))));
890 Test = Annotations(R
"cpp(
891 #include "sub/bar.h" // not shortest, so should only match resolved.
894 TU.Code = Test.code().str();
895 Results = completions(TU, Test.point(), {Sym});
896 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(named("X"), labeled(
"X"),
897 Not(insertInclude()))));
900TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
901 Symbol SymX =
cls(
"ns::X");
902 Symbol SymY =
cls(
"ns::Y");
903 std::string BarHeader =
testPath(
"bar.h");
905 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
906 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
910 auto Results = completions(R
"cpp(
918 EXPECT_THAT(Results.Completions,
919 ElementsAre(AllOf(named("X"), Not(insertInclude())),
920 AllOf(named(
"Y"), Not(insertInclude()))));
923TEST(CompletionTest, IndexSuppressesPreambleCompletions) {
924 Annotations Test(R
"cpp(
926 namespace ns { int local; }
928 void f2() { ns::preamble().$2^; }
931 TU.AdditionalFiles[
"bar.h"] =
932 R
"cpp(namespace ns { struct preamble { int member; }; })cpp";
934 clangd::CodeCompleteOptions Opts = {};
935 auto I = memIndex({
var(
"ns::index")});
936 Opts.
Index = I.get();
937 auto WithIndex = completions(TU, Test.point(), {}, Opts);
938 EXPECT_THAT(WithIndex.Completions,
939 UnorderedElementsAre(named(
"local"), named(
"index")));
940 auto ClassFromPreamble = completions(TU, Test.point(
"2"), {}, Opts);
941 EXPECT_THAT(ClassFromPreamble.Completions, Contains(named(
"member")));
943 Opts.
Index =
nullptr;
944 auto WithoutIndex = completions(TU, Test.point(), {}, Opts);
945 EXPECT_THAT(WithoutIndex.Completions,
946 UnorderedElementsAre(named(
"local"), named(
"preamble")));
953TEST(CompletionTest, CompletionInPreamble) {
954 auto Results = completions(R
"cpp(
962 EXPECT_THAT(Results, ElementsAre(named("ifndef")));
965TEST(CompletionTest, CompletionRecoveryASTType) {
966 auto Results = completions(R
"cpp(
967 struct S { int member; };
970 // No overload matches, but we have recovery-expr with the correct type.
974 EXPECT_THAT(Results, ElementsAre(named("member")));
977TEST(CompletionTest, DynamicIndexIncludeInsertion) {
979 MockCompilationDatabase CDB;
981 Opts.BuildDynamicSymbolIndex =
true;
982 ClangdServer Server(CDB, FS, Opts);
984 FS.Files[
testPath(
"foo_header.h")] = R
"cpp(
991 const std::string FileContent(R
"cpp(
992 #include "foo_header.h"
997 Server.addDocument(testPath("foo_impl.cpp"), FileContent);
999 ASSERT_TRUE(Server.blockUntilIdleForTest());
1002 Annotations Test(
"Foo^ foo;");
1004 auto CompletionList =
1007 EXPECT_THAT(CompletionList.Completions,
1008 ElementsAre(AllOf(named(
"Foo"), hasInclude(
"\"foo_header.h\""),
1012TEST(CompletionTest, DynamicIndexMultiFile) {
1014 MockCompilationDatabase CDB;
1016 Opts.BuildDynamicSymbolIndex =
true;
1017 ClangdServer Server(CDB, FS, Opts);
1019 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1020 namespace ns { class XYZ {}; void foo(int x) {} }
1027 Annotations Test(R
"cpp(
1043 EXPECT_THAT(
Results.Completions,
1045 doc(
"Doooc"), returnType(
"void"))));
1048TEST(CompletionTest, Documentation) {
1051 // Non-doxygen comment.
1052 __attribute__((annotate("custom_annotation"))) int foo();
1063 EXPECT_THAT(
Results.Completions,
1066 doc(
"Annotation: custom_annotation\nNon-doxygen comment."))));
1069 Contains(AllOf(named(
"bar"), doc(
"Doxygen comment.\n\\param int a"))));
1070 EXPECT_THAT(
Results.Completions,
1071 Contains(AllOf(named(
"baz"), doc(
"Multi-line block comment"))));
1074TEST(CompletionTest, CommentsFromSystemHeaders) {
1076 MockCompilationDatabase CDB;
1079 Opts.BuildDynamicSymbolIndex =
true;
1081 ClangdServer Server(CDB, FS, Opts);
1083 FS.Files[
testPath(
"foo.h")] = R
"cpp(
1084 #pragma GCC system_header
1086 // This comment should be retained!
1091 Annotations Test(R
"cpp(
1096 auto CompletionList =
1100 CompletionList.Completions,
1101 Contains(AllOf(named(
"foo"), doc(
"This comment should be retained!"))));
1104TEST(CompletionTest, GlobalCompletionFiltering) {
1109 Symbol Func =
func(
"XYZ::foooo");
1113 auto Results = completions(R
"(// void f() {
1117 EXPECT_THAT(Results.Completions, IsEmpty());
1120TEST(CodeCompleteTest, DisableTypoCorrection) {
1121 auto Results = completions(R
"cpp(
1122 namespace clang { int v; }
1123 void f() { clangd::^
1125 EXPECT_TRUE(Results.Completions.empty());
1128TEST(CodeCompleteTest, NoColonColonAtTheEnd) {
1129 auto Results = completions(R
"cpp(
1136 EXPECT_THAT(Results.Completions, Contains(labeled("clang")));
1137 EXPECT_THAT(
Results.Completions, Not(Contains(labeled(
"clang::"))));
1140TEST(CompletionTests, EmptySnippetDoesNotCrash) {
1142 auto Results = completions(R
"cpp(
1144 auto w = [&](auto &&f) { return f(f); };
1145 auto f = w([&](auto &&f) {
1146 return [&](auto &&n) {
1150 return n * ^(f)(n - 1);
1157TEST(CompletionTest, Issue1427Crash) {
1161 ASTSignals MainFileSignals;
1162 CodeCompleteOptions Opts;
1172TEST(CompletionTest, BacktrackCrashes) {
1174 auto Results = completions(R
"cpp(
1176 struct FooBarBaz {};
1182 EXPECT_THAT(Results.Completions, ElementsAre(labeled("FooBarBaz")));
1186 struct FooBarBaz {};
1188 if (FooBarBaz * x^) {}
1193TEST(CompletionTest, CompleteInMacroWithStringification) {
1194 auto Results = completions(R
"cpp(
1195void f(const char *, int x);
1196#define F(x) f(#x, x)
1203int f(int input_num) {
1208 EXPECT_THAT(Results.Completions,
1209 UnorderedElementsAre(named("X"), named(
"Y")));
1212TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) {
1213 auto Results = completions(R
"cpp(
1214void f(const char *, int x);
1215#define F(x) f(#x, x)
1220int f(int input_num) {
1226 EXPECT_THAT(Results.Completions, Contains(named("X")));
1229TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) {
1230 auto Results = completions(R
"cpp(
1231 int bar(int param_in_bar) {
1234 int foo(int param_in_foo) {
1236 // In recovery mode, "param_in_foo" will also be suggested among many other
1237 // unrelated symbols; however, this is really a special case where this works.
1238 // If the #if block is outside of the function, "param_in_foo" is still
1239 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't
1240 // really provide useful results in excluded branches.
1246 EXPECT_TRUE(Results.Completions.empty());
1249TEST(CompletionTest, DefaultArgs) {
1250 clangd::CodeCompleteOptions Opts;
1251 std::string Context = R"cpp(
1253 int Y(int A, int B = 0);
1254 int Z(int A, int B = 0, int C = 0, int D = 0);
1256 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions,
1257 UnorderedElementsAre(labeled(
"X(int A = 0)")));
1258 EXPECT_THAT(completions(Context +
"int y = Y^", {}, Opts).Completions,
1259 UnorderedElementsAre(AllOf(labeled(
"Y(int A, int B = 0)"),
1260 snippetSuffix(
"(${1:int A})"))));
1261 EXPECT_THAT(completions(Context +
"int y = Z^", {}, Opts).Completions,
1262 UnorderedElementsAre(
1263 AllOf(labeled(
"Z(int A, int B = 0, int C = 0, int D = 0)"),
1264 snippetSuffix(
"(${1:int A})"))));
1267TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) {
1268 auto Completions = completions(R
"cpp(
1269template <template <class> class TT> int foo() {
1274 EXPECT_THAT(Completions, Contains(named("TT")));
1277TEST(CompletionTest, NestedTemplateHeuristics) {
1278 auto Completions = completions(R
"cpp(
1279struct Plain { int xxx; };
1280template <typename T> class Templ { Plain ppp; };
1281template <typename T> void foo(Templ<T> &t) {
1282 // Formally ppp has DependentTy, because Templ may be specialized.
1283 // However we sholud be able to see into it using the primary template.
1288 EXPECT_THAT(Completions, Contains(named("xxx")));
1291TEST(CompletionTest, RecordCCResultCallback) {
1292 std::vector<CodeCompletion> RecordedCompletions;
1293 CodeCompleteOptions Opts;
1295 const SymbolQualitySignals &,
1296 const SymbolRelevanceSignals &,
1298 RecordedCompletions.push_back(
CC);
1301 completions(
"int xy1, xy2; int a = xy^", {}, Opts);
1302 EXPECT_THAT(RecordedCompletions,
1303 UnorderedElementsAre(named(
"xy1"), named(
"xy2")));
1306TEST(CompletionTest, ASTSignals) {
1309 unsigned MainFileRefs;
1310 unsigned ScopeRefsInFile;
1312 CodeCompleteOptions Opts;
1313 std::vector<Completion> RecordedCompletions;
1315 const SymbolQualitySignals &,
1316 const SymbolRelevanceSignals &R,
1318 RecordedCompletions.push_back({
CC.Name, R.MainFileRefs, R.ScopeRefsInFile});
1320 ASTSignals MainFileSignals;
1321 MainFileSignals.ReferencedSymbols[
var(
"xy1").
ID] = 3;
1322 MainFileSignals.ReferencedSymbols[
var(
"xy2").
ID] = 1;
1323 MainFileSignals.ReferencedSymbols[
var(
"xyindex").
ID] = 10;
1324 MainFileSignals.RelatedNamespaces[
"tar::"] = 5;
1325 MainFileSignals.RelatedNamespaces[
"bar::"] = 3;
1337 {
var(
"xyindex"),
var(
"tar::xytar"),
var(
"bar::xybar")},
1339 EXPECT_THAT(RecordedCompletions,
1340 UnorderedElementsAre(
1341 AllOf(named(
"xy1"), mainFileRefs(3u), scopeRefs(0u)),
1342 AllOf(named(
"xy2"), mainFileRefs(1u), scopeRefs(0u)),
1343 AllOf(named(
"xyindex"), mainFileRefs(10u), scopeRefs(0u)),
1344 AllOf(named(
"xytar"), mainFileRefs(0u), scopeRefs(5u)),
1345 AllOf( named(
"xybar"),
1346 mainFileRefs(0u), scopeRefs(3u))));
1350signatures(llvm::StringRef
Text, Position Point,
1351 std::vector<Symbol> IndexSymbols = {},
1353 std::unique_ptr<SymbolIndex> Index;
1354 if (!IndexSymbols.empty())
1355 Index = memIndex(IndexSymbols);
1359 auto Inputs = TU.inputs(FS);
1360 Inputs.
Index = Index.get();
1361 IgnoreDiagnostics Diags;
1364 ADD_FAILURE() <<
"Couldn't build CompilerInvocation";
1370 ADD_FAILURE() <<
"Couldn't build Preamble";
1374 DocumentationFormat);
1378signatures(llvm::StringRef
Text, std::vector<Symbol> IndexSymbols = {},
1380 Annotations Test(
Text);
1381 return signatures(Test.code(), Test.point(), std::move(IndexSymbols),
1382 DocumentationFormat);
1385struct ExpectedParameter {
1387 std::pair<unsigned, unsigned> Offsets;
1390 const ExpectedParameter &P) {
1391 return OS << P.Text;
1394 if (P.size() != arg.parameters.size())
1396 for (
unsigned I = 0; I < P.size(); ++I) {
1397 if (P[I].
Text != arg.parameters[I].labelString ||
1398 P[I].Offsets != arg.parameters[I].labelOffsets)
1403MATCHER_P(sigDoc, doc,
"") {
return arg.documentation.value == doc; }
1407Matcher<SignatureInformation> sig(llvm::StringRef AnnotatedLabel) {
1408 llvm::Annotations
A(AnnotatedLabel);
1409 std::string
Label = std::string(
A.code());
1411 for (
auto Range :
A.ranges()) {
1422TEST(SignatureHelpTest, Overloads) {
1423 auto Results = signatures(R
"cpp(
1424 void foo(int x, int y);
1425 void foo(int x, float y);
1426 void foo(float x, int y);
1427 void foo(float x, float y);
1428 void bar(int x, int y = 0);
1429 int main() { foo(^); }
1431 EXPECT_THAT(Results.signatures,
1432 UnorderedElementsAre(sig("foo([[float x]], [[float y]]) -> void"),
1433 sig(
"foo([[float x]], [[int y]]) -> void"),
1434 sig(
"foo([[int x]], [[float y]]) -> void"),
1435 sig(
"foo([[int x]], [[int y]]) -> void")));
1437 EXPECT_EQ(0,
Results.activeSignature);
1438 EXPECT_EQ(0,
Results.activeParameter);
1441TEST(SignatureHelpTest, FunctionPointers) {
1442 llvm::StringLiteral Tests[] = {
1445 void (*foo)(int x, int y);
1446 int main() { foo(^); }
1450 void (__stdcall *foo)(int x, int y);
1451 int main() { foo(^); }
1455 void (__attribute__(stdcall) *foo)(int x, int y);
1456 int main() { foo(^); },
1460 typedef void (*fn)(int x, int y);
1462 int main() { foo(^); }
1466 typedef void (__stdcall *fn)(int x, int y);
1468 int main() { foo(^); }
1473 void (*foo)(int x, int y);
1476 int main() { s.foo(^); }
1480 typedef void (*fn)(int x, int y);
1485 int main() { s.foo(^); }
1487 for (
auto Test : Tests)
1488 EXPECT_THAT(signatures(Test).signatures,
1489 UnorderedElementsAre(sig(
"([[int x]], [[int y]]) -> void")));
1492TEST(SignatureHelpTest, Constructors) {
1493 std::string Top = R
"cpp(
1496 S(const S &) = delete;
1500 auto CheckParenInit = [&](std::string Init) {
1501 EXPECT_THAT(signatures(Top + Init).signatures,
1502 UnorderedElementsAre(sig(
"S([[int]])")))
1505 CheckParenInit(
"S s(^);");
1506 CheckParenInit(
"auto s = S(^);");
1507 CheckParenInit(
"auto s = new S(^);");
1509 auto CheckBracedInit = [&](std::string Init) {
1510 EXPECT_THAT(signatures(Top + Init).signatures,
1511 UnorderedElementsAre(sig(
"S{[[int]]}")))
1514 CheckBracedInit(
"S s{^};");
1515 CheckBracedInit(
"S s = {^};");
1516 CheckBracedInit(
"auto s = S{^};");
1519 CheckBracedInit(
"int x(S); int i = x({^});");
1522TEST(SignatureHelpTest, Aggregates) {
1523 std::string Top = R
"cpp(
1528 auto AggregateSig = sig(
"S{[[int a]], [[int b]], [[int c]], [[int d]]}");
1529 EXPECT_THAT(signatures(Top +
"S s{^}").signatures,
1530 UnorderedElementsAre(AggregateSig, sig(
"S{}"),
1531 sig(
"S{[[const S &]]}"),
1532 sig(
"S{[[S &&]]}")));
1533 EXPECT_THAT(signatures(Top +
"S s{1,^}").signatures,
1534 ElementsAre(AggregateSig));
1535 EXPECT_EQ(signatures(Top +
"S s{1,^}").activeParameter, 1);
1536 EXPECT_THAT(signatures(Top +
"S s{.c=3,^}").signatures,
1537 ElementsAre(AggregateSig));
1538 EXPECT_EQ(signatures(Top +
"S s{.c=3,^}").activeParameter, 3);
1541TEST(SignatureHelpTest, OverloadInitListRegression) {
1542 auto Results = signatures(R
"cpp(
1551 EXPECT_THAT(Results.signatures, UnorderedElementsAre(sig("f() -> void")));
1554TEST(SignatureHelpTest, DefaultArgs) {
1555 auto Results = signatures(R
"cpp(
1556 void bar(int x, int y = 0);
1557 void bar(float x = 0, int y = 42);
1560 EXPECT_THAT(Results.signatures,
1561 UnorderedElementsAre(
1562 sig("bar([[int x]], [[int y = 0]]) -> void"),
1563 sig(
"bar([[float x = 0]], [[int y = 42]]) -> void")));
1564 EXPECT_EQ(0,
Results.activeSignature);
1565 EXPECT_EQ(0,
Results.activeParameter);
1568TEST(SignatureHelpTest, ActiveArg) {
1569 auto Results = signatures(R
"cpp(
1570 int baz(int a, int b, int c);
1571 int main() { baz(baz(1,2,3), ^); }
1573 EXPECT_THAT(Results.signatures,
1574 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int")));
1575 EXPECT_EQ(0,
Results.activeSignature);
1576 EXPECT_EQ(1,
Results.activeParameter);
1579TEST(SignatureHelpTest, OpeningParen) {
1580 llvm::StringLiteral Tests[] = {
1583 int foo(int a, int b, int c);
1585 foo(foo $p^( foo(10, 10, 10), ^ )));
1590 Foo(int a, int b, int c);
1598 Foo(int a, int b, int c);
1601 new Foo $p^( 10, ^ );
1605 int foo(int a, int b, int c);
1609 // Macro expansions.
1614 int foo(int a, int b, int c);
1617 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving
1618 // the recovery expression.
1619 ID(foo $p^( 10, ^ ))
1623 int foo(int a, int b);
1624 template <typename T> void bar(T t) {
1629 template <typename T>
1631 template <typename T> void bar(T t) {
1636 struct Foo { int foo(int, int); };
1637 template <typename T> void bar(T t) {
1643 struct Foo { template <typename T> int foo(T, T); };
1644 template <typename T> void bar(T t) {
1650 for (
auto Test : Tests) {
1651 Annotations Code(Test);
1652 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart,
1654 <<
"Test source:" << Test;
1658TEST(SignatureHelpTest, StalePreamble) {
1661 IgnoreDiagnostics Diags;
1663 auto Inputs = TU.inputs(FS);
1668 ASSERT_TRUE(EmptyPreamble);
1670 TU.AdditionalFiles[
"a.h"] =
"int foo(int x);";
1671 const Annotations Test(R
"cpp(
1673 void bar() { foo(^2); })cpp");
1674 TU.Code = Test.code().str();
1678 EXPECT_THAT(
Results.signatures, ElementsAre(sig(
"foo([[int x]]) -> int")));
1679 EXPECT_EQ(0,
Results.activeSignature);
1680 EXPECT_EQ(0,
Results.activeParameter);
1683class IndexRequestCollector :
public SymbolIndex {
1685 IndexRequestCollector(std::vector<Symbol> Syms = {}) : Symbols(Syms) {}
1688 fuzzyFind(
const FuzzyFindRequest &Req,
1689 llvm::function_ref<
void(
const Symbol &)> Callback)
const override {
1690 std::unique_lock<std::mutex> Lock(Mut);
1691 Requests.push_back(Req);
1692 ReceivedRequestCV.notify_one();
1693 for (
const auto &Sym : Symbols)
1698 void lookup(
const LookupRequest &,
1699 llvm::function_ref<
void(
const Symbol &)>)
const override {}
1701 bool refs(
const RefsRequest &,
1702 llvm::function_ref<
void(
const Ref &)>)
const override {
1707 const ContainedRefsRequest &,
1708 llvm::function_ref<
void(
const ContainedRefsResult &)>)
const override {
1712 void relations(
const RelationsRequest &,
1713 llvm::function_ref<
void(
const SymbolID &,
const Symbol &)>)
1717 indexedFiles()
const override {
1718 return [](llvm::StringRef) {
return IndexContents::None; };
1723 size_t estimateMemoryUsage()
const override {
return 0; }
1725 const std::vector<FuzzyFindRequest> consumeRequests(
size_t Num)
const {
1726 std::unique_lock<std::mutex> Lock(Mut);
1728 [
this, Num] {
return Requests.size() == Num; }));
1729 auto Reqs = std::move(Requests);
1735 std::vector<Symbol> Symbols;
1737 mutable std::condition_variable ReceivedRequestCV;
1738 mutable std::mutex Mut;
1739 mutable std::vector<FuzzyFindRequest> Requests;
1743std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code,
1745 clangd::CodeCompleteOptions Opts;
1746 IndexRequestCollector Requests;
1747 Opts.
Index = &Requests;
1748 completions(Code, {}, Opts);
1749 const auto Reqs = Requests.consumeRequests(Num);
1750 EXPECT_EQ(Reqs.size(), Num);
1754TEST(CompletionTest, UnqualifiedIdQuery) {
1755 auto Requests = captureIndexRequests(R
"cpp(
1757 using namespace std;
1765 EXPECT_THAT(Requests,
1767 UnorderedElementsAre("",
"ns::",
"std::"))));
1770TEST(CompletionTest, EnclosingScopeComesFirst) {
1771 auto Requests = captureIndexRequests(R
"cpp(
1773 using namespace std;
1785 EXPECT_THAT(Requests,
1788 UnorderedElementsAre("",
"std::",
"nx::ns::",
"nx::"))));
1789 EXPECT_EQ(Requests[0].Scopes[0],
"nx::ns::");
1792TEST(CompletionTest, ResolvedQualifiedIdQuery) {
1793 auto Requests = captureIndexRequests(R
"cpp(
1795 namespace ns2 {} // ignore
1796 namespace ns3 { namespace nns3 {} }
1798 using namespace ns1;
1799 using namespace ns3::nns3;
1808 EXPECT_THAT(Requests,
1811 UnorderedElementsAre("foo::",
"ns1::",
"ns3::nns3::"))));
1814TEST(CompletionTest, UnresolvedQualifierIdQuery) {
1815 auto Requests = captureIndexRequests(R
"cpp(
1825 EXPECT_THAT(Requests,
1828 UnorderedElementsAre("a::bar::",
"ns::bar::",
"bar::"))));
1831TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) {
1832 auto Requests = captureIndexRequests(R
"cpp(
1843 UnorderedElementsAre("a::bar::"))));
1846TEST(CompletionTest, EmptyQualifiedQuery) {
1847 auto Requests = captureIndexRequests(R
"cpp(
1856 UnorderedElementsAre("",
"ns::"))));
1859TEST(CompletionTest, GlobalQualifiedQuery) {
1860 auto Requests = captureIndexRequests(R
"cpp(
1869 UnorderedElementsAre(""))));
1872TEST(CompletionTest, NoDuplicatedQueryScopes) {
1873 auto Requests = captureIndexRequests(R
"cpp(
1884 EXPECT_THAT(Requests,
1886 UnorderedElementsAre("na::",
"na::nb::",
""))));
1889TEST(CompletionTest, NoIndexCompletionsInsideClasses) {
1890 auto Completions = completions(
1893 int SomeNameOfField;
1894 typedef int SomeNameOfTypedefField;
1898 {func("::SomeNameInTheIndex"),
func(
"::Foo::SomeNameInTheIndex")});
1900 EXPECT_THAT(Completions.Completions,
1901 AllOf(Contains(labeled(
"SomeNameOfField")),
1902 Contains(labeled(
"SomeNameOfTypedefField")),
1903 Not(Contains(labeled(
"SomeNameInTheIndex")))));
1906TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) {
1908 auto Completions = completions(
1915 {func("::SomeNameInTheIndex")});
1917 EXPECT_THAT(Completions.Completions,
1918 Not(Contains(labeled(
"SomeNameInTheIndex"))));
1922 auto Completions = completions(
1926 T::template Y<int>::^
1929 {func("::SomeNameInTheIndex")});
1931 EXPECT_THAT(Completions.Completions,
1932 Not(Contains(labeled(
"SomeNameInTheIndex"))));
1936 auto Completions = completions(
1943 {func("::SomeNameInTheIndex")});
1945 EXPECT_THAT(Completions.Completions,
1946 Not(Contains(labeled(
"SomeNameInTheIndex"))));
1950TEST(CompletionTest, OverloadBundling) {
1951 clangd::CodeCompleteOptions Opts;
1954 std::string Context = R
"cpp(
1956 // Overload with int
1957 int a(int) __attribute__((deprecated("", "")));
1958 // Overload with bool
1970 EXPECT_THAT(completions(Context +
"int y = X().^", {}, Opts).Completions,
1971 UnorderedElementsAre(labeled(
"a(…)"), labeled(
"b(float)")));
1974 EXPECT_THAT(completions(Context +
"X z = X^", {}, Opts).Completions,
1975 UnorderedElementsAre(labeled(
"X"), labeled(
"X(…)")));
1978 Symbol NoArgsGFunc =
func(
"GFuncC");
1980 completions(Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1981 UnorderedElementsAre(labeled(
"GFuncC(…)"), labeled(
"GFuncD(int)")));
1985 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
1988 completions(Context +
"int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
1989 UnorderedElementsAre(AllOf(named(
"GFuncC"), insertInclude(
"<foo>")),
1990 labeled(
"GFuncC(int)"), labeled(
"GFuncD(int)")));
1994 completions(Context +
"int y = X().a^", {}, Opts).Completions.front();
1995 EXPECT_EQ(
A.Name,
"a");
1996 EXPECT_EQ(
A.Signature,
"(…)");
1997 EXPECT_EQ(
A.BundleSize, 2u);
1999 EXPECT_EQ(
A.ReturnType,
"int");
2001 ASSERT_TRUE(
A.Documentation);
2002 ASSERT_FALSE(
A.Deprecated);
2004 A.Documentation->asPlainText(),
2005 AnyOf(HasSubstr(
"Overload with int"), HasSubstr(
"Overload with bool")));
2006 EXPECT_EQ(
A.SnippetSuffix,
"($0)");
2009TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
2010 clangd::CodeCompleteOptions Opts;
2013 Symbol SymX =
sym(
"ns::X", index::SymbolKind::Function,
"@F@\\0#");
2014 Symbol SymY =
sym(
"ns::X", index::SymbolKind::Function,
"@F@\\0#I#");
2015 std::string BarHeader =
testPath(
"bar.h");
2017 SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
2018 SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
2023 auto Results = completions(
"void f() { ::ns::^ }", {SymX, SymY}, Opts);
2026 ASSERT_EQ(1u,
Results.Completions.size());
2027 const auto &R =
Results.Completions.front();
2028 EXPECT_EQ(
"X", R.Name);
2029 EXPECT_EQ(2u, R.BundleSize);
2032TEST(CompletionTest, DocumentationFromChangedFileCrash) {
2036 FS.Files[FooH] = R
"cpp(
2037 // this is my documentation comment.
2040 FS.Files[FooCpp] = "";
2042 MockCompilationDatabase CDB;
2045 Annotations Source(R
"cpp(
2048 // This makes sure we have func from header in the AST.
2054 ASSERT_TRUE(Server.blockUntilIdleForTest());
2057 FS.Files[FooH] = R
"cpp(
2061 clangd::CodeCompleteOptions Opts;
2062 CodeCompleteResult Completions =
2066 EXPECT_THAT(Completions.Completions,
2067 Contains(AllOf(Not(isDocumented()), named(
"func"))));
2070TEST(CompletionTest, NonDocComments) {
2071 const char *
Text = R
"cpp(
2072 // We ignore namespace comments, for rationale see CodeCompletionStrings.h.
2073 namespace comments_ns {
2076 // ------------------
2079 // A comment and a decl are separated by newlines.
2080 // Therefore, the comment shouldn't show up as doc comment.
2084 // this comment should be in the results.
2091 int comments_quux();
2095 // This comment should not be there.
2098 int Struct<T>::comments_qux() {
2101 // This comment **should** be in results.
2103 int Struct<T>::comments_quux() {
2110 completions(
Text).Completions,
2111 UnorderedElementsAre(AllOf(Not(isDocumented()), named(
"comments_foo")),
2112 AllOf(isDocumented(), named(
"comments_baz")),
2113 AllOf(isDocumented(), named(
"comments_quux")),
2114 AllOf(Not(isDocumented()), named(
"comments_ns")),
2119 AllOf(isDocumented(), named(
"comments_bar")),
2120 AllOf(isDocumented(), named(
"comments_qux"))));
2123TEST(CompletionTest, CompleteOnInvalidLine) {
2126 MockCompilationDatabase CDB;
2128 FS.Files[FooCpp] =
"// empty file";
2135 EXPECT_THAT_EXPECTED(
2140TEST(CompletionTest, QualifiedNames) {
2143 namespace ns { int local; void both(); }
2144 void f() { ::ns::^ }
2146 {func("ns::both"),
cls(
"ns::Index")});
2150 UnorderedElementsAre(scope(
"ns::"), scope(
"ns::"), scope(
"ns::")));
2153TEST(CompletionTest, Render) {
2157 C.Signature =
"(bool) const";
2158 C.SnippetSuffix =
"(${0:bool})";
2159 C.ReturnType =
"int";
2160 C.RequiredQualifier =
"Foo::";
2161 C.Scope =
"ns::Foo::";
2162 C.Documentation.emplace();
2163 C.Documentation->addParagraph().appendText(
"This is ").appendCode(
"x()");
2164 C.Includes.emplace_back();
2165 auto &Include =
C.Includes.back();
2166 Include.Header =
"\"foo.h\"";
2168 C.Score.Total = 1.0;
2169 C.Score.ExcludingName = .5;
2172 CodeCompleteOptions Opts;
2177 auto R =
C.render(Opts);
2178 EXPECT_EQ(R.label,
"Foo::x");
2179 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2180 EXPECT_EQ(R.insertText,
"Foo::x");
2182 EXPECT_EQ(R.filterText,
"x");
2183 EXPECT_EQ(R.detail,
"int");
2184 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\nThis is x()");
2185 EXPECT_THAT(R.additionalTextEdits, IsEmpty());
2186 EXPECT_EQ(R.sortText,
sortText(1.0,
"x"));
2187 EXPECT_FALSE(R.deprecated);
2188 EXPECT_EQ(R.score, .5f);
2190 C.FilterText =
"xtra";
2192 EXPECT_EQ(R.filterText,
"xtra");
2193 EXPECT_EQ(R.sortText,
sortText(1.0,
"xtra"));
2197 EXPECT_EQ(R.insertText,
"Foo::x(${0:bool})");
2200 C.SnippetSuffix =
"";
2202 EXPECT_EQ(R.insertText,
"Foo::x");
2205 Include.Insertion.emplace();
2207 EXPECT_EQ(R.label,
"^Foo::x");
2208 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2209 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty()));
2213 EXPECT_EQ(R.label,
"^[AS]Foo::x");
2214 EXPECT_EQ(R.labelDetails->detail,
"(bool) const");
2218 EXPECT_EQ(R.detail,
"[2 overloads]");
2219 EXPECT_EQ(R.documentation->value,
"From \"foo.h\"\nThis is x()");
2221 C.Deprecated =
true;
2223 EXPECT_TRUE(R.deprecated);
2227 EXPECT_EQ(R.documentation->value,
"From `\"foo.h\"` \nThis is `x()`");
2230TEST(CompletionTest, IgnoreRecoveryResults) {
2233 namespace ns { int NotRecovered() { return 0; } }
2235 // Sema enters recovery mode first and then normal mode.
2236 if (auto x = ns::NotRecover^)
2239 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("NotRecovered")));
2242TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) {
2246 class X { public: X(); int x_; };
2250 EXPECT_THAT(Results.Completions,
2251 UnorderedElementsAre(AllOf(scope("ns::X::"), named(
"x_"))));
2258TEST(CompletionTest, ConstructorInitListIncomplete) {
2268 EXPECT_THAT(Results.Completions, ElementsAre(named("xyz_")));
2281 EXPECT_THAT(Results.Completions, ElementsAre(named("foo")));
2284TEST(CompletionTest, CodeCompletionContext) {
2288 class X { public: X(); int x_; };
2296 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess);
2299TEST(CompletionTest, FixItForArrowToDot) {
2301 MockCompilationDatabase CDB;
2303 CodeCompleteOptions Opts;
2311 class ClassWithPtr {
2313 void MemberFunction();
2314 Auxilary* operator->() const;
2322 auto Results = completions(Code, {}, Opts);
2323 EXPECT_EQ(
Results.Completions.size(), 3u);
2325 TextEdit ReplacementEdit;
2326 ReplacementEdit.range = Annotations(Code).range();
2327 ReplacementEdit.newText =
".";
2328 for (
const auto &
C :
Results.Completions) {
2329 EXPECT_TRUE(
C.FixIts.size() == 1u ||
C.Name ==
"AuxFunction");
2330 if (!
C.FixIts.empty()) {
2331 EXPECT_THAT(
C.FixIts, ElementsAre(ReplacementEdit));
2336TEST(CompletionTest, FixItForDotToArrow) {
2337 CodeCompleteOptions Opts;
2345 class ClassWithPtr {
2347 void MemberFunction();
2348 Auxilary* operator->() const;
2356 auto Results = completions(Code, {}, Opts);
2357 EXPECT_EQ(
Results.Completions.size(), 3u);
2359 TextEdit ReplacementEdit;
2360 ReplacementEdit.range = Annotations(Code).range();
2361 ReplacementEdit.newText =
"->";
2362 for (
const auto &
C :
Results.Completions) {
2363 EXPECT_TRUE(
C.FixIts.empty() ||
C.Name ==
"AuxFunction");
2364 if (!
C.FixIts.empty()) {
2365 EXPECT_THAT(
C.FixIts, ElementsAre(ReplacementEdit));
2370TEST(CompletionTest, RenderWithFixItMerged) {
2372 FixIt.range.end.character = 5;
2373 FixIt.newText =
"->";
2377 C.RequiredQualifier =
"Foo::";
2379 C.CompletionTokenRange.start.character = 5;
2381 CodeCompleteOptions Opts;
2384 auto R =
C.render(Opts);
2385 EXPECT_TRUE(R.textEdit);
2386 EXPECT_EQ(R.textEdit->newText,
"->Foo::x");
2387 EXPECT_TRUE(R.additionalTextEdits.empty());
2390TEST(CompletionTest, RenderWithFixItNonMerged) {
2392 FixIt.range.end.character = 4;
2393 FixIt.newText =
"->";
2397 C.RequiredQualifier =
"Foo::";
2399 C.CompletionTokenRange.start.character = 5;
2401 CodeCompleteOptions Opts;
2404 auto R =
C.render(Opts);
2405 EXPECT_TRUE(R.textEdit);
2406 EXPECT_EQ(R.textEdit->newText,
"Foo::x");
2407 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(
FixIt));
2410TEST(CompletionTest, CompletionTokenRange) {
2412 MockCompilationDatabase CDB;
2414 TU.AdditionalFiles[
"foo/abc/foo.h"] =
"";
2416 constexpr const char *TestCodes[] = {
2438 #include "foo/[[a^/]]foo.h"
2441 #include "foo/abc/[[fo^o.h"]]
2444 for (
const auto &
Text : TestCodes) {
2445 Annotations TestCode(
Text);
2446 TU.Code = TestCode.code().str();
2447 auto Results = completions(TU, TestCode.point());
2448 if (
Results.Completions.size() != 1) {
2449 ADD_FAILURE() <<
"Results.Completions.size() != 1" <<
Text;
2452 EXPECT_THAT(
Results.Completions.front().CompletionTokenRange,
2457TEST(SignatureHelpTest, OverloadsOrdering) {
2458 const auto Results = signatures(R
"cpp(
2460 void foo(int x, float y);
2461 void foo(float x, int y);
2462 void foo(float x, float y);
2463 void foo(int x, int y = 0);
2464 int main() { foo(^); }
2466 EXPECT_THAT(Results.signatures,
2467 ElementsAre(sig("foo([[int x]]) -> void"),
2468 sig(
"foo([[int x]], [[int y = 0]]) -> void"),
2469 sig(
"foo([[float x]], [[int y]]) -> void"),
2470 sig(
"foo([[int x]], [[float y]]) -> void"),
2471 sig(
"foo([[float x]], [[float y]]) -> void")));
2473 EXPECT_EQ(0,
Results.activeSignature);
2474 EXPECT_EQ(0,
Results.activeParameter);
2477TEST(SignatureHelpTest, InstantiatedSignatures) {
2478 StringRef Sig0 = R
"cpp(
2487 EXPECT_THAT(signatures(Sig0).signatures,
2488 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2490 StringRef Sig1 = R
"cpp(
2498 EXPECT_THAT(signatures(Sig1).signatures,
2499 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void")));
2501 StringRef Sig2 = R
"cpp(
2502 template <class ...T>
2510 EXPECT_THAT(signatures(Sig2).signatures,
2511 ElementsAre(sig("foo([[T...]]) -> void")));
2518 StringRef Sig3 = R
"cpp(
2526 X<int>().foo<double>(^)
2530 EXPECT_THAT(signatures(Sig3).signatures,
2531 ElementsAre(sig("foo([[T]], [[U]]) -> void")));
2534TEST(SignatureHelpTest, IndexDocumentation) {
2535 Symbol Foo0 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#");
2536 Foo0.Documentation =
"doc from the index";
2537 Symbol Foo1 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#");
2538 Foo1.Documentation =
"doc from the index";
2539 Symbol Foo2 =
sym(
"foo", index::SymbolKind::Function,
"@F@\\0#I#I#");
2541 StringRef Sig0 = R
"cpp(
2551 signatures(Sig0, {Foo0}).signatures,
2552 ElementsAre(AllOf(sig("foo() -> int"), sigDoc(
"doc from the index")),
2553 AllOf(sig(
"foo([[double]]) -> int"), sigDoc(
""))));
2555 StringRef Sig1 = R
"cpp(
2557 // Overriden doc from sema
2568 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures,
2570 AllOf(sig("foo() -> int"), sigDoc(
"doc from the index")),
2571 AllOf(sig(
"foo([[int]]) -> int"), sigDoc(
"Overriden doc from sema")),
2572 AllOf(sig(
"foo([[int]], [[int]]) -> int"), sigDoc(
"doc from sema"))));
2575TEST(SignatureHelpTest, DynamicIndexDocumentation) {
2577 MockCompilationDatabase CDB;
2579 Opts.BuildDynamicSymbolIndex =
true;
2580 ClangdServer Server(CDB, FS, Opts);
2582 FS.Files[
testPath(
"foo.h")] = R
"cpp(
2588 Annotations FileContent(R"cpp(
2596 Server.addDocument(
File, FileContent.code());
2598 ASSERT_TRUE(Server.blockUntilIdleForTest());
2602 ElementsAre(AllOf(sig(
"foo() -> int"), sigDoc(
"Member doc"))));
2605TEST(CompletionTest, ArgumentListsPolicy) {
2606 CodeCompleteOptions Opts;
2614 void xfoo(int x, int y);
2615 void f() { xfo^ })cpp",
2619 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"()")),
2620 AllOf(named(
"xfoo"), snippetSuffix(
"($0)"))));
2626 void f() { xba^ })cpp",
2628 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2629 named("xbar"), snippetSuffix(
"()"))));
2636 void xfoo(int x, int y);
2637 void f() { xfo^ })cpp",
2641 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"($0)"))));
2646 template <class T, class U>
2647 void xfoo(int a, U b);
2648 void f() { xfo^ })cpp",
2652 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"<$1>($0)"))));
2660 using foo_alias = T**;
2663 void f() { foo_^ })cpp",
2667 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix(
"<$0>")),
2668 AllOf(named(
"foo_alias"), snippetSuffix(
"<$0>")),
2669 AllOf(named(
"foo_var"), snippetSuffix(
"<$0>"))));
2674 #define FOO(x, y) x##f
2677 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
2678 named("FOO"), snippetSuffix(
"($0)"))));
2684 void xfoo(int x, int y);
2685 void f() { xfo^ })cpp",
2687 EXPECT_THAT(Results.Completions,
2688 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
""))));
2694 void xfoo(int x, int y);
2695 void f() { xfo^ })cpp",
2697 EXPECT_THAT(Results.Completions,
2698 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(
"("))));
2702TEST(CompletionTest, SuggestOverrides) {
2703 constexpr const char *
const Text(R
"cpp(
2706 virtual void vfunc(bool param);
2707 virtual void vfunc(bool param, int p);
2708 void func(bool param);
2710 class B : public A {
2711 virtual void ttt(bool param) const;
2712 void vfunc(bool param, int p) override;
2714 class C : public B {
2716 void vfunc(bool param) override;
2723 AllOf(Contains(AllOf(labeled(
"void vfunc(bool param, int p) override"),
2724 nameStartsWith(
"vfunc"))),
2725 Contains(AllOf(labeled(
"void ttt(bool param) const override"),
2726 nameStartsWith(
"ttt"))),
2727 Not(Contains(labeled(
"void vfunc(bool param) override")))));
2730TEST(CompletionTest, OverridesNonIdentName) {
2734 virtual ~Base() = 0;
2735 virtual operator int() = 0;
2736 virtual Base& operator+(Base&) = 0;
2739 struct Derived : Base {
2745TEST(CompletionTest, NoCrashOnMissingNewLineAtEOF) {
2748 MockCompilationDatabase CDB;
2750 Annotations F(
"#pragma ^ // no new line");
2751 FS.Files[FooCpp] = F.code().str();
2756 clangd::CodeCompleteOptions()))
2765TEST(GuessCompletionPrefix, Filters) {
2766 for (llvm::StringRef Case : {
2767 "[[scope::]][[ident]]^",
2776 "some text [[scope::more::]][[identif]]^ier",
2777 "some text [[scope::]][[mor]]^e::identifier",
2778 "weird case foo::[[::bar::]][[baz]]^",
2781 Annotations F(Case);
2783 auto ToStringRef = [&](
Range R) {
2787 auto WantQualifier = ToStringRef(F.ranges()[0]),
2788 WantName = ToStringRef(F.ranges()[1]);
2792 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case;
2793 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case;
2794 EXPECT_EQ(WantName, Prefix.Name) << Case;
2795 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case;
2799TEST(CompletionTest, EnableSpeculativeIndexRequest) {
2801 MockCompilationDatabase CDB;
2805 Annotations Test(R
"cpp(
2806 namespace ns1 { int abc; }
2807 namespace ns2 { int abc; }
2808 void f() { ns1::ab$1^; ns1::ab$2^; }
2809 void f2() { ns2::ab$3^; }
2812 clangd::CodeCompleteOptions Opts = {};
2814 IndexRequestCollector Requests;
2815 Opts.Index = &Requests;
2817 auto CompleteAtPoint = [&](StringRef P) {
2819 EXPECT_TRUE(CCR.HasMore);
2822 CompleteAtPoint(
"1");
2823 auto Reqs1 = Requests.consumeRequests(1);
2824 ASSERT_EQ(Reqs1.size(), 1u);
2825 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre(
"ns1::"));
2827 CompleteAtPoint(
"2");
2828 auto Reqs2 = Requests.consumeRequests(1);
2830 ASSERT_EQ(Reqs2.size(), 1u);
2831 EXPECT_EQ(Reqs2[0], Reqs1[0]);
2833 CompleteAtPoint(
"3");
2836 auto Reqs3 = Requests.consumeRequests(2);
2837 ASSERT_EQ(Reqs3.size(), 2u);
2840TEST(CompletionTest, InsertTheMostPopularHeader) {
2842 Symbol Sym =
func(
"Func");
2843 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2847 auto Results = completions(
"Fun^", {Sym}).Completions;
2849 EXPECT_THAT(
Results[0], AllOf(named(
"Func"), insertInclude(
"\"bar.h\"")));
2850 EXPECT_EQ(
Results[0].Includes.size(), 2u);
2853TEST(CompletionTest, InsertIncludeOrImport) {
2855 Symbol Sym =
func(
"Func");
2856 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2857 Sym.IncludeHeaders.emplace_back(
"\"bar.h\"", 1000,
2859 CodeCompleteOptions Opts;
2862 auto Results = completions(
"Fun^", {Sym}, Opts).Completions;
2865 AllOf(named(
"Func"), insertIncludeText(
"#include \"bar.h\"\n")));
2870 Results = completions(
"Fun^", {Sym}, Opts,
"Foo.m").Completions;
2873 AllOf(named(
"Func"), insertIncludeText(
"#import \"bar.h\"\n")));
2876 Results = completions(
"Fun^", {Sym}).Completions;
2878 EXPECT_THAT(
Results[0], AllOf(named(
"Func"), Not(insertInclude())));
2881TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
2882 Annotations Test(R
"cpp(
2887 TU.AdditionalFiles[
"foo.h"] =
"";
2890 Symbol Sym =
func(
"Func");
2891 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
2895 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions,
2896 UnorderedElementsAre(AllOf(named(
"Func"), hasInclude(
"\"foo.h\""),
2897 Not(insertInclude()))));
2900TEST(CompletionTest, MergeMacrosFromIndexAndSema) {
2902 Sym.Name =
"Clangd_Macro_Test";
2903 Sym.ID =
SymbolID(
"c:foo.cpp@8@macro@Clangd_Macro_Test");
2904 Sym.SymInfo.Kind = index::SymbolKind::Macro;
2906 EXPECT_THAT(completions(
"#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym})
2908 UnorderedElementsAre(named(
"Clangd_Macro_Test")));
2911TEST(CompletionTest, MacroFromPreamble) {
2912 Annotations Test(R
"cpp(#define CLANGD_PREAMBLE_MAIN x
2915 #define CLANGD_MAIN x
2916 void f() { CLANGD_^ }
2919 TU.HeaderCode =
"#define CLANGD_PREAMBLE_HEADER x";
2920 auto Results = completions(TU, Test.point(), {func(
"CLANGD_INDEX")});
2923 EXPECT_THAT(
Results.Completions,
2924 UnorderedElementsAre(named(
"CLANGD_PREAMBLE_MAIN"),
2925 named(
"CLANGD_MAIN"),
2926 named(
"CLANGD_INDEX")));
2929TEST(CompletionTest, DeprecatedResults) {
2930 std::string Body = R
"cpp(
2932 void TestClangc() __attribute__((deprecated("", "")));
2936 completions(Body + "int main() { TestClang^ }").Completions,
2937 UnorderedElementsAre(AllOf(named(
"TestClangd"), Not(deprecated())),
2938 AllOf(named(
"TestClangc"), deprecated())));
2941TEST(SignatureHelpTest, PartialSpec) {
2942 const auto Results = signatures(R
"cpp(
2943 template <typename T> struct Foo {};
2944 template <typename T> struct Foo<T*> { Foo(T); };
2945 Foo<int*> F(^);)cpp");
2946 EXPECT_THAT(Results.signatures, Contains(sig("Foo([[T]])")));
2947 EXPECT_EQ(0,
Results.activeParameter);
2950TEST(SignatureHelpTest, InsideArgument) {
2952 const auto Results = signatures(R
"cpp(
2954 void foo(int x, int y);
2955 int main() { foo(1+^); }
2957 EXPECT_THAT(Results.signatures,
2958 ElementsAre(sig("foo([[int x]]) -> void"),
2959 sig(
"foo([[int x]], [[int y]]) -> void")));
2960 EXPECT_EQ(0,
Results.activeParameter);
2963 const auto Results = signatures(R
"cpp(
2965 void foo(int x, int y);
2966 int main() { foo(1^); }
2968 EXPECT_THAT(Results.signatures,
2969 ElementsAre(sig("foo([[int x]]) -> void"),
2970 sig(
"foo([[int x]], [[int y]]) -> void")));
2971 EXPECT_EQ(0,
Results.activeParameter);
2974 const auto Results = signatures(R
"cpp(
2976 void foo(int x, int y);
2977 int main() { foo(1^0); }
2979 EXPECT_THAT(Results.signatures,
2980 ElementsAre(sig("foo([[int x]]) -> void"),
2981 sig(
"foo([[int x]], [[int y]]) -> void")));
2982 EXPECT_EQ(0,
Results.activeParameter);
2985 const auto Results = signatures(R
"cpp(
2987 void foo(int x, int y);
2988 int bar(int x, int y);
2989 int main() { bar(foo(2, 3^)); }
2991 EXPECT_THAT(Results.signatures,
2992 ElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
2993 EXPECT_EQ(1,
Results.activeParameter);
2997TEST(SignatureHelpTest, ConstructorInitializeFields) {
2999 const auto Results = signatures(R
"cpp(
3000 struct A { A(int); };
3006 EXPECT_THAT(Results.signatures,
3007 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3008 sig(
"A([[const A &]])")));
3011 const auto Results = signatures(R
"cpp(
3012 struct A { A(int); };
3020 EXPECT_THAT(
Results.signatures, IsEmpty());
3023 const auto Results = signatures(R
"cpp(
3024 struct A { A(int); };
3031 EXPECT_THAT(Results.signatures,
3032 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3033 sig(
"A([[const A &]])")));
3036 const auto Results = signatures(R
"cpp(
3045 B() : c_elem(A(1^)) {}
3049 EXPECT_THAT(Results.signatures,
3050 UnorderedElementsAre(sig("A([[int]])"), sig(
"A([[A &&]])"),
3051 sig(
"A([[const A &]])")));
3055TEST(SignatureHelpTest, Variadic) {
3056 const std::string Header = R
"cpp(
3057 void fun(int x, ...) {}
3059 const std::string ExpectedSig =
"fun([[int x]], [[...]]) -> void";
3062 const auto Result = signatures(Header +
"fun(^);}");
3063 EXPECT_EQ(0, Result.activeParameter);
3064 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3067 const auto Result = signatures(Header +
"fun(1, ^);}");
3068 EXPECT_EQ(1, Result.activeParameter);
3069 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3072 const auto Result = signatures(Header +
"fun(1, 2, ^);}");
3073 EXPECT_EQ(1, Result.activeParameter);
3074 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3078TEST(SignatureHelpTest, VariadicTemplate) {
3079 const std::string Header = R
"cpp(
3080 template<typename T, typename ...Args>
3081 void fun(T t, Args ...args) {}
3083 const std::string ExpectedSig =
"fun([[T t]], [[Args args...]]) -> void";
3086 const auto Result = signatures(Header +
"fun(^);}");
3087 EXPECT_EQ(0, Result.activeParameter);
3088 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3091 const auto Result = signatures(Header +
"fun(1, ^);}");
3092 EXPECT_EQ(1, Result.activeParameter);
3093 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3096 const auto Result = signatures(Header +
"fun(1, 2, ^);}");
3097 EXPECT_EQ(1, Result.activeParameter);
3098 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3102TEST(SignatureHelpTest, VariadicMethod) {
3103 const std::string Header = R
"cpp(
3105 template<typename T, typename ...Args>
3106 void fun(T t, Args ...args) {}
3108 void test() {C c; )cpp";
3109 const std::string ExpectedSig =
"fun([[T t]], [[Args args...]]) -> void";
3112 const auto Result = signatures(Header +
"c.fun(^);}");
3113 EXPECT_EQ(0, Result.activeParameter);
3114 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3117 const auto Result = signatures(Header +
"c.fun(1, ^);}");
3118 EXPECT_EQ(1, Result.activeParameter);
3119 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3122 const auto Result = signatures(Header +
"c.fun(1, 2, ^);}");
3123 EXPECT_EQ(1, Result.activeParameter);
3124 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3128TEST(SignatureHelpTest, VariadicType) {
3129 const std::string Header = R
"cpp(
3130 void fun(int x, ...) {}
3131 auto get_fun() { return fun; }
3134 const std::string ExpectedSig =
"([[int]], [[...]]) -> void";
3137 const auto Result = signatures(Header +
"get_fun()(^);}");
3138 EXPECT_EQ(0, Result.activeParameter);
3139 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3142 const auto Result = signatures(Header +
"get_fun()(1, ^);}");
3143 EXPECT_EQ(1, Result.activeParameter);
3144 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3147 const auto Result = signatures(Header +
"get_fun()(1, 2, ^);}");
3148 EXPECT_EQ(1, Result.activeParameter);
3149 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig)));
3153TEST(CompletionTest, IncludedCompletionKinds) {
3154 Annotations Test(R
"cpp(#include "^)cpp");
3156 TU.AdditionalFiles[
"sub/bar.h"] =
"";
3157 TU.ExtraArgs.push_back(
"-I" +
testPath(
"sub"));
3159 auto Results = completions(TU, Test.point());
3160 EXPECT_THAT(
Results.Completions,
3165TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) {
3172TEST(CompletionTest, NoAllScopesCompletionWhenQualified) {
3173 clangd::CodeCompleteOptions Opts = {};
3178 void f() { na::Clangd^ }
3180 {cls("na::ClangdA"),
cls(
"nx::ClangdX"),
cls(
"Clangd3")}, Opts);
3181 EXPECT_THAT(
Results.Completions,
3182 UnorderedElementsAre(
3183 AllOf(qualifier(
""), scope(
"na::"), named(
"ClangdA"))));
3186TEST(CompletionTest, AllScopesCompletion) {
3187 clangd::CodeCompleteOptions Opts = {};
3193 void f() { Clangd^ }
3196 {cls("nx::Clangd1"),
cls(
"ny::Clangd2"),
cls(
"Clangd3"),
3201 UnorderedElementsAre(AllOf(qualifier(
"nx::"), named(
"Clangd1"),
3203 AllOf(qualifier(
"ny::"), named(
"Clangd2"),
3205 AllOf(qualifier(
""), scope(
""), named(
"Clangd3"),
3207 AllOf(qualifier(
"nb::"), named(
"Clangd4"),
3209 AllOf(qualifier(
"C::"), named(
"Clangd5"),
3213TEST(CompletionTest, NoQualifierIfShadowed) {
3214 clangd::CodeCompleteOptions Opts = {};
3217 auto Results = completions(R
"cpp(
3218 namespace nx { class Clangd1 {}; }
3220 void f() { Clangd^ }
3222 {cls("nx::Clangd1"),
cls(
"nx::Clangd2")}, Opts);
3225 EXPECT_THAT(
Results.Completions,
3226 UnorderedElementsAre(AllOf(qualifier(
""), named(
"Clangd1")),
3227 AllOf(qualifier(
"nx::"), named(
"Clangd2"))));
3230TEST(CompletionTest, NoCompletionsForNewNames) {
3231 clangd::CodeCompleteOptions Opts;
3233 auto Results = completions(R
"cpp(
3236 {cls("naber"),
cls(
"nx::naber")}, Opts);
3237 EXPECT_THAT(
Results.Completions, UnorderedElementsAre());
3240TEST(CompletionTest, Lambda) {
3241 clangd::CodeCompleteOptions Opts = {};
3243 auto Results = completions(R
"cpp(
3245 auto Lambda = [](int a, const double &b) {return 1.f;};
3251 ASSERT_EQ(Results.Completions.size(), 1u);
3252 const auto &
A =
Results.Completions.front();
3253 EXPECT_EQ(
A.Name,
"Lambda");
3254 EXPECT_EQ(
A.Signature,
"(int a, const double &b) const");
3256 EXPECT_EQ(
A.ReturnType,
"float");
3257 EXPECT_EQ(
A.SnippetSuffix,
"(${1:int a}, ${2:const double &b})");
3260TEST(CompletionTest, StructuredBinding) {
3261 clangd::CodeCompleteOptions Opts = {};
3263 auto Results = completions(R
"cpp(
3265 using Float = float;
3270 const auto &[xxx, yyy] = S{};
3276 ASSERT_EQ(Results.Completions.size(), 1u);
3277 const auto &
A =
Results.Completions.front();
3278 EXPECT_EQ(
A.Name,
"yyy");
3280 EXPECT_EQ(
A.ReturnType,
"const Float");
3283TEST(CompletionTest, ObjectiveCMethodNoArguments) {
3284 auto Results = completions(R
"objc(
3286 @property(nonatomic, setter=setXToIgnoreComplete:) int value;
3288 Foo *foo = [Foo new]; int y = [foo v^]
3294 EXPECT_THAT(
C, ElementsAre(named(
"value")));
3296 EXPECT_THAT(
C, ElementsAre(returnType(
"int")));
3297 EXPECT_THAT(
C, ElementsAre(signature(
"")));
3298 EXPECT_THAT(
C, ElementsAre(snippetSuffix(
"")));
3301TEST(CompletionTest, ObjectiveCMethodOneArgument) {
3302 auto Results = completions(R
"objc(
3304 - (int)valueForCharacter:(char)c;
3306 Foo *foo = [Foo new]; int y = [foo v^]
3312 EXPECT_THAT(
C, ElementsAre(named(
"valueForCharacter:")));
3314 EXPECT_THAT(
C, ElementsAre(returnType(
"int")));
3315 EXPECT_THAT(
C, ElementsAre(signature(
"(char)")));
3316 EXPECT_THAT(
C, ElementsAre(snippetSuffix(
"${1:(char)}")));
3319TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) {
3320 auto Results = completions(R
"objc(
3322 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3330 EXPECT_THAT(
C, ElementsAre(named(
"fooWithValue:")));
3332 EXPECT_THAT(
C, ElementsAre(returnType(
"id")));
3333 EXPECT_THAT(
C, ElementsAre(signature(
"(int) fooey:(unsigned int)")));
3335 C, ElementsAre(snippetSuffix(
"${1:(int)} fooey:${2:(unsigned int)}")));
3338TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
3339 auto Results = completions(R
"objc(
3341 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey;
3343 id val = [Foo fooWithValue:10 f^]
3349 EXPECT_THAT(
C, ElementsAre(named(
"fooey:")));
3351 EXPECT_THAT(
C, ElementsAre(returnType(
"id")));
3352 EXPECT_THAT(
C, ElementsAre(signature(
"(unsigned int)")));
3353 EXPECT_THAT(
C, ElementsAre(snippetSuffix(
"${1:(unsigned int)}")));
3356TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) {
3357 auto Results = completions(R
"objc(
3359 + (id)player:(id)player willRun:(id)run;
3367 EXPECT_THAT(
C, ElementsAre(named(
"player:")));
3368 EXPECT_THAT(
C, ElementsAre(filterText(
"player:willRun:")));
3370 EXPECT_THAT(
C, ElementsAre(returnType(
"id")));
3371 EXPECT_THAT(
C, ElementsAre(signature(
"(id) willRun:(id)")));
3372 EXPECT_THAT(
C, ElementsAre(snippetSuffix(
"${1:(id)} willRun:${2:(id)}")));
3375TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) {
3376 auto Results = completions(R
"objc(
3388 EXPECT_THAT(
C, ElementsAre(named(
"foo")));
3390 EXPECT_THAT(
C, ElementsAre(qualifier(
"- (void)")));
3393TEST(CompletionTest, ObjectiveCMethodDeclaration) {
3394 auto Results = completions(R
"objc(
3396 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3406 EXPECT_THAT(
C, ElementsAre(named(
"valueForCharacter:")));
3408 EXPECT_THAT(
C, ElementsAre(qualifier(
"- (int)")));
3409 EXPECT_THAT(
C, ElementsAre(signature(
"(char)c secondArgument:(id)object")));
3412TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) {
3413 auto Results = completions(R
"objc(
3415 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3425 EXPECT_THAT(
C, ElementsAre(named(
"valueForCharacter:")));
3426 EXPECT_THAT(
C, ElementsAre(filterText(
"valueForCharacter:secondArgument:")));
3428 EXPECT_THAT(
C, ElementsAre(qualifier(
"- (int)")));
3429 EXPECT_THAT(
C, ElementsAre(signature(
"(char)c secondArgument:(id)object")));
3432TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) {
3433 auto Results = completions(R
"objc(
3435 - (int)valueForCharacter:(char)c;
3445 EXPECT_THAT(
C, ElementsAre(named(
"valueForCharacter:")));
3447 EXPECT_THAT(
C, ElementsAre(signature(
"(char)c")));
3450TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) {
3451 auto Results = completions(R
"objc(
3453 - (int)valueForCharacter:(char)c secondArgument:(id)object;
3456 - (int)valueForCharacter:(char)c second^
3463 EXPECT_THAT(
C, ElementsAre(named(
"secondArgument:")));
3465 EXPECT_THAT(
C, ElementsAre(signature(
"(id)object")));
3468TEST(CompletionTest, ObjectiveCProtocolFromIndex) {
3469 Symbol FoodClass =
objcClass(
"FoodClass");
3472 auto Results = completions(
"id<Foo^>", {SymFood, FoodClass, SymFooey},
3476 EXPECT_THAT(
Results.Completions,
3477 UnorderedElementsAre(
3481 Results = completions(
"Fo^", {SymFood, FoodClass, SymFooey},
3489TEST(CompletionTest, ObjectiveCProtocolFromIndexSpeculation) {
3491 MockCompilationDatabase CDB;
3495 Annotations Test(R
"cpp(
3502 clangd::CodeCompleteOptions Opts = {};
3504 Symbol FoodClass = objcClass("FoodClass");
3505 IndexRequestCollector Requests({FoodClass});
3506 Opts.
Index = &Requests;
3508 auto CompleteAtPoint = [&](StringRef P) {
3513 auto C = CompleteAtPoint(
"1");
3514 auto Reqs1 = Requests.consumeRequests(1);
3515 ASSERT_EQ(Reqs1.size(), 1u);
3516 EXPECT_THAT(
C, ElementsAre(AllOf(named(
"Food"),
3519 C = CompleteAtPoint(
"2");
3520 auto Reqs2 = Requests.consumeRequests(1);
3523 ASSERT_EQ(Reqs2.size(), 1u);
3524 EXPECT_EQ(Reqs2[0], Reqs1[0]);
3525 EXPECT_THAT(
C, ElementsAre(AllOf(named(
"FoodClass"),
3529TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
3530 Symbol FoodCategory =
objcCategory(
"FoodClass",
"Extension");
3531 auto Results = completions(R
"objc(
3539 EXPECT_THAT(
Results.Completions, IsEmpty());
3542TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3543 Symbol FoodClass =
objcClass(
"FoodClass");
3544 FoodClass.IncludeHeaders.emplace_back(
"\"Foo.h\"", 2,
Symbol::Import);
3546 auto Results = completions(
"@class Foo^", {SymFood, FoodClass},
3550 EXPECT_THAT(
Results.Completions,
3551 UnorderedElementsAre(AllOf(named(
"FoodClass"),
3553 Not(insertInclude()))));
3556TEST(CompletionTest, CursorInSnippets) {
3557 clangd::CodeCompleteOptions Options;
3558 Options.EnableSnippets =
true;
3561 void while_foo(int a, int b);
3568 EXPECT_THAT(
Results.Completions,
3569 Contains(AllOf(named(
"while"),
3570 snippetSuffix(
" (${1:condition}) {\n$0\n}"))));
3572 EXPECT_THAT(
Results.Completions,
3573 Contains(AllOf(named(
"while_foo"),
3574 snippetSuffix(
"(${1:int a}, ${2:int b})"))));
3578 Base(int a, int b) {}
3581 struct Derived : Base {
3588 EXPECT_THAT(
Results.Completions,
3589 Contains(AllOf(named(
"Base"),
3590 snippetSuffix(
"(${1:int a}, ${2:int b})"))));
3593TEST(CompletionTest, WorksWithNullType) {
3594 auto R = completions(R
"cpp(
3596 for (auto [loopVar] : y ) { // y has to be unresolved.
3601 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar")));
3604TEST(CompletionTest, UsingDecl) {
3605 const char *Header(R
"cpp(
3610 const char *Source(R
"cpp(
3615 clangd::CodeCompleteOptions Opts;
3616 Opts.
Index = Index.get();
3618 auto R = completions(Source, {}, Opts);
3619 EXPECT_THAT(R.Completions,
3620 ElementsAre(AllOf(scope(
"std::"), named(
"foo"),
3624TEST(CompletionTest, Enums) {
3625 const char *Header(R
"cpp(
3627 enum Unscoped { Clangd1 };
3629 enum Unscoped { Clangd2 };
3631 enum class Scoped { Clangd3 };
3633 const char *Source(R
"cpp(
3638 clangd::CodeCompleteOptions Opts;
3639 Opts.
Index = Index.get();
3641 auto R = completions(Source, {}, Opts);
3642 EXPECT_THAT(R.Completions, UnorderedElementsAre(
3643 AllOf(scope(
"ns::"), named(
"Clangd1"),
3645 AllOf(scope(
"ns::C::"), named(
"Clangd2"),
3647 AllOf(scope(
"ns::Scoped::"), named(
"Clangd3"),
3651TEST(CompletionTest, ScopeIsUnresolved) {
3652 clangd::CodeCompleteOptions Opts = {};
3655 auto Results = completions(R
"cpp(
3660 {cls("a::b::XYZ")}, Opts);
3661 EXPECT_THAT(
Results.Completions,
3662 UnorderedElementsAre(AllOf(qualifier(
""), named(
"XYZ"))));
3665TEST(CompletionTest, NestedScopeIsUnresolved) {
3666 clangd::CodeCompleteOptions Opts = {};
3669 auto Results = completions(R
"cpp(
3672 void f() { b::c::X^ }
3675 {cls("a::b::c::XYZ")}, Opts);
3676 EXPECT_THAT(
Results.Completions,
3677 UnorderedElementsAre(AllOf(qualifier(
""), named(
"XYZ"))));
3682TEST(CompletionTest, NamespaceDoubleInsertion) {
3683 clangd::CodeCompleteOptions Opts = {};
3685 auto Results = completions(R
"cpp(
3692 {cls("foo::ns::ABCDE")}, Opts);
3693 EXPECT_THAT(
Results.Completions,
3694 UnorderedElementsAre(AllOf(qualifier(
""), named(
"ABCDE"))));
3697TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) {
3700 auto Completions = completions(R
"cpp(
3703 double size() const;
3705 struct deque : deque_base {
3712 EXPECT_THAT(Completions,
3713 ElementsAre(AllOf(returnType("int"), named(
"size"))));
3716TEST(CompletionTest, NoCrashWithIncompleteLambda) {
3717 auto Completions = completions(
"auto&& x = []{^").Completions;
3721 EXPECT_THAT(Completions, Contains(named(
"x")));
3723 auto Signatures = signatures(
"auto x() { x(^").signatures;
3724 EXPECT_THAT(Signatures, Contains(sig(
"x() -> auto")));
3727TEST(CompletionTest, DelayedTemplateParsing) {
3728 Annotations Test(R
"cpp(
3730 template <typename T> int foo() { return xx^; }
3735 TU.ExtraArgs.push_back(
"-fdelayed-template-parsing");
3737 EXPECT_THAT(completions(TU, Test.point()).Completions,
3738 Contains(named(
"xxx")));
3741TEST(CompletionTest, CompletionRange) {
3742 const char *WithRange =
"auto x = [[abc]]^";
3743 auto Completions = completions(WithRange);
3744 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3745 Completions = completionsNoCompile(WithRange);
3746 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range());
3748 const char *EmptyRange =
"auto x = [[]]^";
3749 Completions = completions(EmptyRange);
3750 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3751 Completions = completionsNoCompile(EmptyRange);
3752 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range());
3756 const char *NoCompletion =
"/* foo [[]]^ */";
3757 Completions = completions(NoCompletion);
3758 EXPECT_EQ(Completions.CompletionRange, std::nullopt);
3759 Completions = completionsNoCompile(NoCompletion);
3760 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range());
3763TEST(NoCompileCompletionTest, Basic) {
3764 auto Results = completionsNoCompile(R
"cpp(
3771 EXPECT_FALSE(Results.RanParser);
3772 EXPECT_THAT(Results.Completions,
3773 UnorderedElementsAre(named("void"), named(
"func"), named(
"int"),
3774 named(
"xyz"), named(
"abc")));
3777TEST(NoCompileCompletionTest, WithFilter) {
3778 auto Results = completionsNoCompile(R
"cpp(
3787 EXPECT_THAT(Results.Completions,
3788 UnorderedElementsAre(named("sym1"), named(
"sym2")));
3791TEST(NoCompileCompletionTest, WithIndex) {
3792 std::vector<Symbol> Syms = {
func(
"xxx"),
func(
"a::xxx"),
func(
"ns::b::xxx"),
3793 func(
"c::xxx"),
func(
"ns::d::xxx")};
3794 auto Results = completionsNoCompile(
3796 // Current-scopes, unqualified completion.
3806 EXPECT_THAT(Results.Completions,
3807 UnorderedElementsAre(AllOf(qualifier(""), scope(
"")),
3808 AllOf(qualifier(
""), scope(
"a::")),
3809 AllOf(qualifier(
""), scope(
"ns::b::"))));
3810 CodeCompleteOptions Opts;
3812 Results = completionsNoCompile(
3814 // All-scopes unqualified completion.
3824 EXPECT_THAT(Results.Completions,
3825 UnorderedElementsAre(AllOf(qualifier(""), scope(
"")),
3826 AllOf(qualifier(
""), scope(
"a::")),
3827 AllOf(qualifier(
""), scope(
"ns::b::")),
3828 AllOf(qualifier(
"c::"), scope(
"c::")),
3829 AllOf(qualifier(
"d::"), scope(
"ns::d::"))));
3830 Results = completionsNoCompile(
3832 // Qualified completion.
3842 EXPECT_THAT(Results.Completions,
3843 ElementsAre(AllOf(qualifier(""), scope(
"ns::b::"))));
3844 Results = completionsNoCompile(
3846 // Absolutely qualified completion.
3856 EXPECT_THAT(Results.Completions,
3857 ElementsAre(AllOf(qualifier(""), scope(
"a::"))));
3860TEST(AllowImplicitCompletion,
All) {
3861 const char *
Yes[] = {
3865 " # include <^foo.h>",
3866 "#import <foo/^bar.h>",
3867 "#include_next \"^",
3869 const char *
No[] = {
3873 "#include <foo.h> //^",
3874 "#include \"foo.h\"^",
3878 for (
const char *Test :
Yes) {
3879 llvm::Annotations
A(Test);
3882 for (
const char *Test :
No) {
3883 llvm::Annotations
A(Test);
3888TEST(CompletionTest, FunctionArgsExist) {
3889 clangd::CodeCompleteOptions Opts;
3891 std::string Context = R
"cpp(
3898 template <typename T>
3900 Container(int Size) {}
3903 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions,
3904 UnorderedElementsAre(
3905 AllOf(labeled(
"foo(int A)"), snippetSuffix(
"(${1:int A})"))));
3907 completions(Context +
"int y = fo^(42)", {}, Opts).Completions,
3908 UnorderedElementsAre(AllOf(labeled(
"foo(int A)"), snippetSuffix(
""))));
3910 EXPECT_THAT(completions(Context +
"int y = fo^o(42)", {}, Opts).Completions,
3911 UnorderedElementsAre(
3912 AllOf(labeled(
"foo(int A)"), snippetSuffix(
"(${1:int A})"))));
3914 completions(Context +
"int y = ba^", {}, Opts).Completions,
3915 UnorderedElementsAre(AllOf(labeled(
"bar()"), snippetSuffix(
"()"))));
3916 EXPECT_THAT(completions(Context +
"int y = ba^()", {}, Opts).Completions,
3917 UnorderedElementsAre(AllOf(labeled(
"bar()"), snippetSuffix(
""))));
3919 completions(Context +
"Object o = Obj^", {}, Opts).Completions,
3920 Contains(AllOf(labeled(
"Object(int B)"), snippetSuffix(
"(${1:int B})"),
3922 EXPECT_THAT(completions(Context +
"Object o = Obj^()", {}, Opts).Completions,
3923 Contains(AllOf(labeled(
"Object(int B)"), snippetSuffix(
""),
3926 completions(Context +
"Container c = Cont^", {}, Opts).Completions,
3927 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
3928 snippetSuffix(
"<${1:typename T}>(${2:int Size})"),
3931 completions(Context +
"Container c = Cont^()", {}, Opts).Completions,
3932 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
3933 snippetSuffix(
"<${1:typename T}>"),
3936 completions(Context +
"Container c = Cont^<int>()", {}, Opts).Completions,
3937 Contains(AllOf(labeled(
"Container<typename T>(int Size)"),
3940 EXPECT_THAT(completions(Context +
"MAC^(2)", {}, Opts).Completions,
3941 Contains(AllOf(labeled(
"MACRO(x)"), snippetSuffix(
""),
3945TEST(CompletionTest, FunctionArgsExist_Issue1785) {
3949 clangd::CodeCompleteOptions Opts;
3952 std::string Code = R
"cpp(
3964 completions(Code, {}, Opts).Completions,
3965 Contains(AllOf(labeled("waldo(int)"), snippetSuffix(
"(${1:int})"))));
3968TEST(CompletionTest, NoCrashDueToMacroOrdering) {
3969 EXPECT_THAT(completions(R
"cpp(
3971 #define ECHO2(X) ECHO(X)
3972 int finish_preamble = EC^HO(2);)cpp")
3974 UnorderedElementsAre(labeled("ECHO(X)"), labeled(
"ECHO2(X)")));
3977TEST(CompletionTest, ObjCCategoryDecls) {
3979 TU.ExtraArgs.push_back(
"-xobjective-c");
3980 TU.HeaderCode = R
"objc(
3984 @interface Foo (FooExt1)
3987 @interface Foo (FooExt2)
3993 @interface Bar (BarExt)
3997 Annotations Test(R"objc(
3998 @implementation Foo (^)
4001 TU.Code = Test.code().str();
4002 auto Results = completions(TU, Test.point());
4003 EXPECT_THAT(
Results.Completions,
4004 UnorderedElementsAre(labeled(
"FooExt1"), labeled(
"FooExt2")));
4007 Annotations Test(R
"objc(
4011 TU.Code = Test.code().str();
4012 auto Results = completions(TU, Test.point());
4013 EXPECT_THAT(
Results.Completions, UnorderedElementsAre(labeled(
"BarExt")));
4017TEST(CompletionTest, PreambleCodeComplete) {
4018 llvm::StringLiteral Baseline =
"\n#define MACRO 12\nint num = MACRO;";
4019 llvm::StringLiteral ModifiedCC =
4020 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^";
4022 Annotations Test(ModifiedCC);
4027 auto Inputs = ModifiedTU.inputs(FS);
4029 BaselineTU.preamble().get(), Inputs, {});
4030 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
4033TEST(CompletionTest, CommentParamName) {
4034 const std::string Code = R
"cpp(
4035 void fun(int foo, int bar);
4036 void overloaded(int param_int);
4037 void overloaded(int param_int, int param_other);
4038 void overloaded(char param_char);
4042 EXPECT_THAT(completions(Code + "fun(/*^").Completions,
4043 UnorderedElementsAre(labeled(
"foo=*/")));
4044 EXPECT_THAT(completions(Code +
"fun(1, /*^").Completions,
4045 UnorderedElementsAre(labeled(
"bar=*/")));
4046 EXPECT_THAT(completions(Code +
"/*^").Completions, IsEmpty());
4049 completions(Code +
"overloaded(/*^").Completions,
4050 UnorderedElementsAre(labeled(
"param_int=*/"), labeled(
"param_char=*/")));
4052 EXPECT_THAT(completions(Code +
"fun(/* ^").Completions,
4053 UnorderedElementsAre(labeled(
"foo=*/")));
4054 EXPECT_THAT(completions(Code +
"fun(/* f^").Completions,
4055 UnorderedElementsAre(labeled(
"foo=*/")));
4056 EXPECT_THAT(completions(Code +
"fun(/* x^").Completions, IsEmpty());
4057 EXPECT_THAT(completions(Code +
"fun(/* f ^").Completions, IsEmpty());
4061 std::string CompletionRangeTest(Code +
"fun(/*[[^]]");
4062 auto Results = completions(CompletionRangeTest);
4063 EXPECT_THAT(
Results.CompletionRange,
4064 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
4068 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
4072 std::string CompletionRangeTest(Code +
"fun(/*[[fo^]]");
4073 auto Results = completions(CompletionRangeTest);
4074 EXPECT_THAT(
Results.CompletionRange,
4075 llvm::ValueIs(Annotations(CompletionRangeTest).range()));
4079 AllOf(replacesRange(Annotations(CompletionRangeTest).range()),
4084TEST(CompletionTest, Concepts) {
4085 Annotations Code(R
"cpp(
4087 concept A = sizeof(T) <= 8;
4089 template<$tparam^A U>
4092 template<typename T>
4093 int bar(T t) requires $expr^A<int>;
4096 concept b = $expr^A && $expr^sizeof(T) % 2 == 0 || $expr^A && sizeof(T) == 1;
4098 $toplevel^A auto i = 19;
4100 template<$toplevel^A auto i> void constrainedNTTP();
4102 // FIXME: The first parameter should be dropped in this case.
4103 void abbreviated($expr^A auto x) {}
4106 TU.Code = Code.code().str();
4107 TU.ExtraArgs = {"-std=c++20"};
4110 Sym.Signature =
"<typename Tp, typename Up>";
4111 Sym.CompletionSnippetSuffix =
"<${1:typename Tp}, ${2:typename Up}>";
4112 std::vector<Symbol> Syms = {Sym};
4113 for (
auto P : Code.points(
"tparam")) {
4115 completions(TU, P, Syms).Completions,
4116 AllOf(Contains(AllOf(named(
"A"), signature(
""), snippetSuffix(
""))),
4117 Contains(AllOf(named(
"same_as"), signature(
"<typename Up>"),
4118 snippetSuffix(
"<${2:typename Up}>"))),
4119 Contains(named(
"class")), Contains(named(
"typename"))))
4120 <<
"Completing template parameter at position " << P;
4123 for (
auto P : Code.points(
"toplevel")) {
4125 completions(TU, P, Syms).Completions,
4126 AllOf(Contains(AllOf(named(
"A"), signature(
""), snippetSuffix(
""))),
4127 Contains(AllOf(named(
"same_as"), signature(
"<typename Up>"),
4128 snippetSuffix(
"<${2:typename Up}>")))))
4129 <<
"Completing 'requires' expression at position " << P;
4132 for (
auto P : Code.points(
"expr")) {
4134 completions(TU, P, Syms).Completions,
4135 AllOf(Contains(AllOf(named(
"A"), signature(
"<class T>"),
4136 snippetSuffix(
"<${1:class T}>"))),
4138 named(
"same_as"), signature(
"<typename Tp, typename Up>"),
4139 snippetSuffix(
"<${1:typename Tp}, ${2:typename Up}>")))))
4140 <<
"Completing 'requires' expression at position " << P;
4144TEST(SignatureHelp, DocFormat) {
4145 Annotations Code(R
"cpp(
4146 // Comment `with` markup.
4148 void bar() { foo(^); }
4150 for (
auto DocumentationFormat :
4152 auto Sigs = signatures(Code.code(), Code.point(), {},
4153 DocumentationFormat);
4154 ASSERT_EQ(Sigs.signatures.size(), 1U);
4155 EXPECT_EQ(Sigs.signatures[0].documentation.kind, DocumentationFormat);
4159TEST(SignatureHelp, TemplateArguments) {
4160 std::string Top = R
"cpp(
4161 template <typename T, int> bool foo(char);
4162 template <int I, int> bool foo(float);
4165 auto First = signatures(Top +
"bool x = foo<^");
4168 UnorderedElementsAre(sig(
"foo<[[typename T]], [[int]]>() -> bool"),
4169 sig(
"foo<[[int I]], [[int]]>() -> bool")));
4170 EXPECT_EQ(First.activeParameter, 0);
4172 auto Second = signatures(Top +
"bool x = foo<1, ^");
4173 EXPECT_THAT(Second.signatures,
4174 ElementsAre(sig(
"foo<[[int I]], [[int]]>() -> bool")));
4175 EXPECT_EQ(Second.activeParameter, 1);
4178TEST(CompletionTest, DoNotCrash) {
4179 llvm::StringLiteral Cases[] = {
4181 template <typename = int> struct Foo {};
4182 auto a = [x(3)](Foo<^>){};
4185 for (
auto Case : Cases) {
4187 auto Completions = completions(Case);
4190TEST(CompletionTest, PreambleFromDifferentTarget) {
4191 constexpr std::string_view PreambleTarget =
"x86_64";
4192 constexpr std::string_view Contents =
4193 "int foo(int); int num; int num2 = foo(n^";
4195 Annotations Test(Contents);
4197 TU.ExtraArgs.emplace_back(
"-target");
4198 TU.ExtraArgs.emplace_back(PreambleTarget);
4202 TU.ExtraArgs.pop_back();
4203 TU.ExtraArgs.emplace_back(
"wasm32");
4206 auto Inputs = TU.inputs(FS);
4213 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty()));
4214 EXPECT_THAT(Signatures.signatures, Not(testing::IsEmpty()));
ArrayRef< const ParmVarDecl * > Parameters
llvm::SmallString< 256U > Name
const ParseInputs & ParseInput
std::vector< CodeCompletionResult > Results
std::optional< float > Score
CharSourceRange Range
SourceRange for the file name.
std::unique_ptr< CompilerInvocation > CI
std::optional< FixItHint > FixIt
#define EXPECT_IFF(condition, value, matcher)
static Options optsForTest()
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
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::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)
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
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)
@ 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.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
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)
std::array< uint8_t, 20 > SymbolID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::function< void(const CodeCompletion &, const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Score)> RecordCCResult
Callback invoked on all CompletionCandidate after they are scored and before they are ranked (by -Sco...
MarkupKind DocumentationFormat
Whether to present doc comments as plain-text or markdown.
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
Config::ArgumentListsPolicy ArgumentLists
The way argument list on calls '()' and generics '<>' are handled.
const SymbolIndex * Index
If Index is set, it is used to augment the code completion results.
const ASTSignals * MainFileSignals
std::function< DecisionForestScores(const SymbolQualitySignals &, const SymbolRelevanceSignals &, float Base)> DecisionForestScorer
Callback used to score a CompletionCandidate if DecisionForest ranking model is enabled.
CodeCompletionRankingModel RankingModel
bool ImportInsertions
Whether include insertions for Objective-C code should use #import instead of #include.
bool AllScopes
Whether to include index symbols that are not defined in the scopes visible from the code completion ...
size_t Limit
Limit the number of results returned (0 means no limit).
std::optional< bool > BundleOverloads
Combine overloads into a single completion item where possible.
bool IncludeFixIts
Include completions that require small corrections, e.g.
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
bool EnableSnippets
When true, completion items will contain expandable code snippets in completion (e....
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
@ None
nothing, no argument list and also NO Delimiters "()" or "<>".
@ Delimiters
empty pair of delimiters "()" or "<>".
@ OpenDelimiter
open, only opening delimiter "(" or "<".
std::vector< std::string > Scopes
If this is non-empty, symbols must be in at least one of the scopes (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.
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
static TestTU withCode(llvm::StringRef Code)
std::unique_ptr< SymbolIndex > index() const