1 //===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Annotations.h" 10 #include "ClangdServer.h" 11 #include "CodeComplete.h" 12 #include "Compiler.h" 13 #include "Matchers.h" 14 #include "Protocol.h" 15 #include "Quality.h" 16 #include "SourceCode.h" 17 #include "SyncAPI.h" 18 #include "TestFS.h" 19 #include "TestIndex.h" 20 #include "TestTU.h" 21 #include "Threading.h" 22 #include "index/Index.h" 23 #include "index/MemIndex.h" 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/Error.h" 29 #include "gmock/gmock.h" 30 #include "gtest/gtest.h" 31 #include <condition_variable> 32 #include <mutex> 33 34 namespace clang { 35 namespace clangd { 36 37 namespace { 38 using ::llvm::Failed; 39 using ::testing::AllOf; 40 using ::testing::Contains; 41 using ::testing::ElementsAre; 42 using ::testing::Field; 43 using ::testing::HasSubstr; 44 using ::testing::IsEmpty; 45 using ::testing::Not; 46 using ::testing::UnorderedElementsAre; 47 48 class IgnoreDiagnostics : public DiagnosticsConsumer { 49 void onDiagnosticsReady(PathRef File, 50 std::vector<Diag> Diagnostics) override {} 51 }; 52 53 // GMock helpers for matching completion items. 54 MATCHER_P(Named, Name, "") { return arg.Name == Name; } 55 MATCHER_P(NameStartsWith, Prefix, "") { 56 return llvm::StringRef(arg.Name).startswith(Prefix); 57 } 58 MATCHER_P(Scope, S, "") { return arg.Scope == S; } 59 MATCHER_P(Qualifier, Q, "") { return arg.RequiredQualifier == Q; } 60 MATCHER_P(Labeled, Label, "") { 61 return arg.RequiredQualifier + arg.Name + arg.Signature == Label; 62 } 63 MATCHER_P(SigHelpLabeled, Label, "") { return arg.label == Label; } 64 MATCHER_P(Kind, K, "") { return arg.Kind == K; } 65 MATCHER_P(Doc, D, "") { return arg.Documentation == D; } 66 MATCHER_P(ReturnType, D, "") { return arg.ReturnType == D; } 67 MATCHER_P(HasInclude, IncludeHeader, "") { 68 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader; 69 } 70 MATCHER_P(InsertInclude, IncludeHeader, "") { 71 return !arg.Includes.empty() && arg.Includes[0].Header == IncludeHeader && 72 bool(arg.Includes[0].Insertion); 73 } 74 MATCHER(InsertInclude, "") { 75 return !arg.Includes.empty() && bool(arg.Includes[0].Insertion); 76 } 77 MATCHER_P(SnippetSuffix, Text, "") { return arg.SnippetSuffix == Text; } 78 MATCHER_P(Origin, OriginSet, "") { return arg.Origin == OriginSet; } 79 MATCHER_P(Signature, S, "") { return arg.Signature == S; } 80 81 // Shorthand for Contains(Named(Name)). 82 Matcher<const std::vector<CodeCompletion> &> Has(std::string Name) { 83 return Contains(Named(std::move(Name))); 84 } 85 Matcher<const std::vector<CodeCompletion> &> Has(std::string Name, 86 CompletionItemKind K) { 87 return Contains(AllOf(Named(std::move(Name)), Kind(K))); 88 } 89 MATCHER(IsDocumented, "") { return !arg.Documentation.empty(); } 90 MATCHER(Deprecated, "") { return arg.Deprecated; } 91 92 std::unique_ptr<SymbolIndex> memIndex(std::vector<Symbol> Symbols) { 93 SymbolSlab::Builder Slab; 94 for (const auto &Sym : Symbols) 95 Slab.insert(Sym); 96 return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab()); 97 } 98 99 CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode, 100 Position Point, 101 std::vector<Symbol> IndexSymbols = {}, 102 clangd::CodeCompleteOptions Opts = {}) { 103 std::unique_ptr<SymbolIndex> OverrideIndex; 104 if (!IndexSymbols.empty()) { 105 assert(!Opts.Index && "both Index and IndexSymbols given!"); 106 OverrideIndex = memIndex(std::move(IndexSymbols)); 107 Opts.Index = OverrideIndex.get(); 108 } 109 110 auto File = testPath("foo.cpp"); 111 runAddDocument(Server, File, TestCode); 112 auto CompletionList = 113 llvm::cantFail(runCodeComplete(Server, File, Point, Opts)); 114 return CompletionList; 115 } 116 117 CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef Text, 118 std::vector<Symbol> IndexSymbols = {}, 119 clangd::CodeCompleteOptions Opts = {}, 120 PathRef FilePath = "foo.cpp") { 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(); 126 } 127 128 auto File = testPath(FilePath); 129 Annotations Test(Text); 130 runAddDocument(Server, File, Test.code()); 131 auto CompletionList = 132 llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts)); 133 return CompletionList; 134 } 135 136 // Builds a server and runs code completion. 137 // If IndexSymbols is non-empty, an index will be built and passed to opts. 138 CodeCompleteResult completions(llvm::StringRef Text, 139 std::vector<Symbol> IndexSymbols = {}, 140 clangd::CodeCompleteOptions Opts = {}, 141 PathRef FilePath = "foo.cpp") { 142 MockFSProvider FS; 143 MockCompilationDatabase CDB; 144 IgnoreDiagnostics DiagConsumer; 145 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 146 return completions(Server, Text, std::move(IndexSymbols), std::move(Opts), 147 FilePath); 148 } 149 150 // Builds a server and runs code completion. 151 // If IndexSymbols is non-empty, an index will be built and passed to opts. 152 CodeCompleteResult completionsNoCompile(llvm::StringRef Text, 153 std::vector<Symbol> IndexSymbols = {}, 154 clangd::CodeCompleteOptions Opts = {}, 155 PathRef FilePath = "foo.cpp") { 156 std::unique_ptr<SymbolIndex> OverrideIndex; 157 if (!IndexSymbols.empty()) { 158 assert(!Opts.Index && "both Index and IndexSymbols given!"); 159 OverrideIndex = memIndex(std::move(IndexSymbols)); 160 Opts.Index = OverrideIndex.get(); 161 } 162 163 MockFSProvider FS; 164 Annotations Test(Text); 165 return codeComplete(FilePath, tooling::CompileCommand(), /*Preamble=*/nullptr, 166 Test.code(), Test.point(), FS.getFileSystem(), Opts); 167 } 168 169 Symbol withReferences(int N, Symbol S) { 170 S.References = N; 171 return S; 172 } 173 174 TEST(CompletionTest, Limit) { 175 clangd::CodeCompleteOptions Opts; 176 Opts.Limit = 2; 177 auto Results = completions(R"cpp( 178 struct ClassWithMembers { 179 int AAA(); 180 int BBB(); 181 int CCC(); 182 }; 183 184 int main() { ClassWithMembers().^ } 185 )cpp", 186 /*IndexSymbols=*/{}, Opts); 187 188 EXPECT_TRUE(Results.HasMore); 189 EXPECT_THAT(Results.Completions, ElementsAre(Named("AAA"), Named("BBB"))); 190 } 191 192 TEST(CompletionTest, Filter) { 193 std::string Body = R"cpp( 194 #define MotorCar 195 int Car; 196 struct S { 197 int FooBar; 198 int FooBaz; 199 int Qux; 200 }; 201 )cpp"; 202 203 // Only items matching the fuzzy query are returned. 204 EXPECT_THAT(completions(Body + "int main() { S().Foba^ }").Completions, 205 AllOf(Has("FooBar"), Has("FooBaz"), Not(Has("Qux")))); 206 207 // Macros require prefix match. 208 EXPECT_THAT(completions(Body + "int main() { C^ }").Completions, 209 AllOf(Has("Car"), Not(Has("MotorCar")))); 210 } 211 212 void testAfterDotCompletion(clangd::CodeCompleteOptions Opts) { 213 auto Results = completions( 214 R"cpp( 215 int global_var; 216 217 int global_func(); 218 219 // Make sure this is not in preamble. 220 #define MACRO X 221 222 struct GlobalClass {}; 223 224 struct ClassWithMembers { 225 /// Doc for method. 226 int method(); 227 228 int field; 229 private: 230 int private_field; 231 }; 232 233 int test() { 234 struct LocalClass {}; 235 236 /// Doc for local_var. 237 int local_var; 238 239 ClassWithMembers().^ 240 } 241 )cpp", 242 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts); 243 244 EXPECT_TRUE(Results.RanParser); 245 // Class members. The only items that must be present in after-dot 246 // completion. 247 EXPECT_THAT(Results.Completions, 248 AllOf(Has("method"), Has("field"), Not(Has("ClassWithMembers")), 249 Not(Has("operator=")), Not(Has("~ClassWithMembers")))); 250 EXPECT_IFF(Opts.IncludeIneligibleResults, Results.Completions, 251 Has("private_field")); 252 // Global items. 253 EXPECT_THAT( 254 Results.Completions, 255 Not(AnyOf(Has("global_var"), Has("index_var"), Has("global_func"), 256 Has("global_func()"), Has("index_func"), Has("GlobalClass"), 257 Has("IndexClass"), Has("MACRO"), Has("LocalClass")))); 258 // There should be no code patterns (aka snippets) in after-dot 259 // completion. At least there aren't any we're aware of. 260 EXPECT_THAT(Results.Completions, 261 Not(Contains(Kind(CompletionItemKind::Snippet)))); 262 // Check documentation. 263 EXPECT_IFF(Opts.IncludeComments, Results.Completions, 264 Contains(IsDocumented())); 265 } 266 267 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) { 268 auto Results = completions( 269 R"cpp( 270 int global_var; 271 int global_func(); 272 273 // Make sure this is not in preamble. 274 #define MACRO X 275 276 struct GlobalClass {}; 277 278 struct ClassWithMembers { 279 /// Doc for method. 280 int method(); 281 }; 282 283 int test() { 284 struct LocalClass {}; 285 286 /// Doc for local_var. 287 int local_var; 288 289 ^ 290 } 291 )cpp", 292 {cls("IndexClass"), var("index_var"), func("index_func")}, Opts); 293 294 EXPECT_TRUE(Results.RanParser); 295 // Class members. Should never be present in global completions. 296 EXPECT_THAT(Results.Completions, 297 Not(AnyOf(Has("method"), Has("method()"), Has("field")))); 298 // Global items. 299 EXPECT_THAT(Results.Completions, 300 AllOf(Has("global_var"), Has("index_var"), Has("global_func"), 301 Has("index_func" /* our fake symbol doesn't include () */), 302 Has("GlobalClass"), Has("IndexClass"))); 303 // A macro. 304 EXPECT_IFF(Opts.IncludeMacros, Results.Completions, Has("MACRO")); 305 // Local items. Must be present always. 306 EXPECT_THAT(Results.Completions, 307 AllOf(Has("local_var"), Has("LocalClass"), 308 Contains(Kind(CompletionItemKind::Snippet)))); 309 // Check documentation. 310 EXPECT_IFF(Opts.IncludeComments, Results.Completions, 311 Contains(IsDocumented())); 312 } 313 314 TEST(CompletionTest, CompletionOptions) { 315 auto Test = [&](const clangd::CodeCompleteOptions &Opts) { 316 testAfterDotCompletion(Opts); 317 testGlobalScopeCompletion(Opts); 318 }; 319 // We used to test every combination of options, but that got too slow (2^N). 320 auto Flags = { 321 &clangd::CodeCompleteOptions::IncludeMacros, 322 &clangd::CodeCompleteOptions::IncludeComments, 323 &clangd::CodeCompleteOptions::IncludeCodePatterns, 324 &clangd::CodeCompleteOptions::IncludeIneligibleResults, 325 }; 326 // Test default options. 327 Test({}); 328 // Test with one flag flipped. 329 for (auto &F : Flags) { 330 clangd::CodeCompleteOptions O; 331 O.*F ^= true; 332 Test(O); 333 } 334 } 335 336 TEST(CompletionTest, Accessible) { 337 auto Internal = completions(R"cpp( 338 class Foo { 339 public: void pub(); 340 protected: void prot(); 341 private: void priv(); 342 }; 343 void Foo::pub() { this->^ } 344 )cpp"); 345 EXPECT_THAT(Internal.Completions, 346 AllOf(Has("priv"), Has("prot"), Has("pub"))); 347 348 auto External = completions(R"cpp( 349 class Foo { 350 public: void pub(); 351 protected: void prot(); 352 private: void priv(); 353 }; 354 void test() { 355 Foo F; 356 F.^ 357 } 358 )cpp"); 359 EXPECT_THAT(External.Completions, 360 AllOf(Has("pub"), Not(Has("prot")), Not(Has("priv")))); 361 } 362 363 TEST(CompletionTest, Qualifiers) { 364 auto Results = completions(R"cpp( 365 class Foo { 366 public: int foo() const; 367 int bar() const; 368 }; 369 class Bar : public Foo { 370 int foo() const; 371 }; 372 void test() { Bar().^ } 373 )cpp"); 374 EXPECT_THAT(Results.Completions, 375 Contains(AllOf(Qualifier(""), Named("bar")))); 376 // Hidden members are not shown. 377 EXPECT_THAT(Results.Completions, 378 Not(Contains(AllOf(Qualifier("Foo::"), Named("foo"))))); 379 // Private members are not shown. 380 EXPECT_THAT(Results.Completions, 381 Not(Contains(AllOf(Qualifier(""), Named("foo"))))); 382 } 383 384 TEST(CompletionTest, InjectedTypename) { 385 // These are suppressed when accessed as a member... 386 EXPECT_THAT(completions("struct X{}; void foo(){ X().^ }").Completions, 387 Not(Has("X"))); 388 EXPECT_THAT(completions("struct X{ void foo(){ this->^ } };").Completions, 389 Not(Has("X"))); 390 // ...but accessible in other, more useful cases. 391 EXPECT_THAT(completions("struct X{ void foo(){ ^ } };").Completions, 392 Has("X")); 393 EXPECT_THAT( 394 completions("struct Y{}; struct X:Y{ void foo(){ ^ } };").Completions, 395 Has("Y")); 396 EXPECT_THAT( 397 completions( 398 "template<class> struct Y{}; struct X:Y<int>{ void foo(){ ^ } };") 399 .Completions, 400 Has("Y")); 401 // This case is marginal (`using X::X` is useful), we allow it for now. 402 EXPECT_THAT(completions("struct X{}; void foo(){ X::^ }").Completions, 403 Has("X")); 404 } 405 406 TEST(CompletionTest, SkipInjectedWhenUnqualified) { 407 EXPECT_THAT(completions("struct X { void f() { X^ }};").Completions, 408 ElementsAre(Named("X"), Named("~X"))); 409 } 410 411 TEST(CompletionTest, Snippets) { 412 clangd::CodeCompleteOptions Opts; 413 auto Results = completions( 414 R"cpp( 415 struct fake { 416 int a; 417 int f(int i, const float f) const; 418 }; 419 int main() { 420 fake f; 421 f.^ 422 } 423 )cpp", 424 /*IndexSymbols=*/{}, Opts); 425 EXPECT_THAT( 426 Results.Completions, 427 HasSubsequence(Named("a"), 428 SnippetSuffix("(${1:int i}, ${2:const float f})"))); 429 } 430 431 TEST(CompletionTest, NoSnippetsInUsings) { 432 clangd::CodeCompleteOptions Opts; 433 Opts.EnableSnippets = true; 434 auto Results = completions( 435 R"cpp( 436 namespace ns { 437 int func(int a, int b); 438 } 439 440 using ns::^; 441 )cpp", 442 /*IndexSymbols=*/{}, Opts); 443 EXPECT_THAT(Results.Completions, 444 ElementsAre(AllOf(Named("func"), Labeled("func(int a, int b)"), 445 SnippetSuffix("")))); 446 447 // Check index completions too. 448 auto Func = func("ns::func"); 449 Func.CompletionSnippetSuffix = "(${1:int a}, ${2: int b})"; 450 Func.Signature = "(int a, int b)"; 451 Func.ReturnType = "void"; 452 453 Results = completions(R"cpp( 454 namespace ns {} 455 using ns::^; 456 )cpp", 457 /*IndexSymbols=*/{Func}, Opts); 458 EXPECT_THAT(Results.Completions, 459 ElementsAre(AllOf(Named("func"), Labeled("func(int a, int b)"), 460 SnippetSuffix("")))); 461 462 // Check all-scopes completions too. 463 Opts.AllScopes = true; 464 Results = completions(R"cpp( 465 using ^; 466 )cpp", 467 /*IndexSymbols=*/{Func}, Opts); 468 EXPECT_THAT(Results.Completions, 469 Contains(AllOf(Named("func"), Labeled("ns::func(int a, int b)"), 470 SnippetSuffix("")))); 471 } 472 473 TEST(CompletionTest, Kinds) { 474 auto Results = completions( 475 R"cpp( 476 int variable; 477 struct Struct {}; 478 int function(); 479 // make sure MACRO is not included in preamble. 480 #define MACRO 10 481 int X = ^ 482 )cpp", 483 {func("indexFunction"), var("indexVariable"), cls("indexClass")}); 484 EXPECT_THAT(Results.Completions, 485 AllOf(Has("function", CompletionItemKind::Function), 486 Has("variable", CompletionItemKind::Variable), 487 Has("int", CompletionItemKind::Keyword), 488 Has("Struct", CompletionItemKind::Class), 489 Has("MACRO", CompletionItemKind::Text), 490 Has("indexFunction", CompletionItemKind::Function), 491 Has("indexVariable", CompletionItemKind::Variable), 492 Has("indexClass", CompletionItemKind::Class))); 493 494 Results = completions("nam^"); 495 EXPECT_THAT(Results.Completions, 496 Has("namespace", CompletionItemKind::Snippet)); 497 498 // Members of anonymous unions are of kind 'field'. 499 Results = completions( 500 R"cpp( 501 struct X{ 502 union { 503 void *a; 504 }; 505 }; 506 auto u = X().^ 507 )cpp"); 508 EXPECT_THAT( 509 Results.Completions, 510 UnorderedElementsAre(AllOf(Named("a"), Kind(CompletionItemKind::Field)))); 511 512 // Completion kinds for templates should not be unknown. 513 Results = completions( 514 R"cpp( 515 template <class T> struct complete_class {}; 516 template <class T> void complete_function(); 517 template <class T> using complete_type_alias = int; 518 template <class T> int complete_variable = 10; 519 520 struct X { 521 template <class T> static int complete_static_member = 10; 522 523 static auto x = complete_^ 524 } 525 )cpp"); 526 EXPECT_THAT( 527 Results.Completions, 528 UnorderedElementsAre( 529 AllOf(Named("complete_class"), Kind(CompletionItemKind::Class)), 530 AllOf(Named("complete_function"), Kind(CompletionItemKind::Function)), 531 AllOf(Named("complete_type_alias"), 532 Kind(CompletionItemKind::Interface)), 533 AllOf(Named("complete_variable"), Kind(CompletionItemKind::Variable)), 534 AllOf(Named("complete_static_member"), 535 Kind(CompletionItemKind::Property)))); 536 } 537 538 TEST(CompletionTest, NoDuplicates) { 539 auto Results = completions( 540 R"cpp( 541 class Adapter { 542 }; 543 544 void f() { 545 Adapter^ 546 } 547 )cpp", 548 {cls("Adapter")}); 549 550 // Make sure there are no duplicate entries of 'Adapter'. 551 EXPECT_THAT(Results.Completions, ElementsAre(Named("Adapter"))); 552 } 553 554 TEST(CompletionTest, ScopedNoIndex) { 555 auto Results = completions( 556 R"cpp( 557 namespace fake { int BigBang, Babble, Box; }; 558 int main() { fake::ba^ } 559 ")cpp"); 560 // Babble is a better match than BigBang. Box doesn't match at all. 561 EXPECT_THAT(Results.Completions, 562 ElementsAre(Named("Babble"), Named("BigBang"))); 563 } 564 565 TEST(CompletionTest, Scoped) { 566 auto Results = completions( 567 R"cpp( 568 namespace fake { int Babble, Box; }; 569 int main() { fake::ba^ } 570 ")cpp", 571 {var("fake::BigBang")}); 572 EXPECT_THAT(Results.Completions, 573 ElementsAre(Named("Babble"), Named("BigBang"))); 574 } 575 576 TEST(CompletionTest, ScopedWithFilter) { 577 auto Results = completions( 578 R"cpp( 579 void f() { ns::x^ } 580 )cpp", 581 {cls("ns::XYZ"), func("ns::foo")}); 582 EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("XYZ"))); 583 } 584 585 TEST(CompletionTest, ReferencesAffectRanking) { 586 auto Results = completions("int main() { abs^ }", {ns("absl"), func("absb")}); 587 EXPECT_THAT(Results.Completions, 588 HasSubsequence(Named("absb"), Named("absl"))); 589 Results = completions("int main() { abs^ }", 590 {withReferences(10000, ns("absl")), func("absb")}); 591 EXPECT_THAT(Results.Completions, 592 HasSubsequence(Named("absl"), Named("absb"))); 593 } 594 595 TEST(CompletionTest, ContextWords) { 596 auto Results = completions(R"cpp( 597 enum class Color { RED, YELLOW, BLUE }; 598 599 // (blank lines so the definition above isn't "context") 600 601 // "It was a yellow car," he said. "Big yellow car, new." 602 auto Finish = Color::^ 603 )cpp"); 604 // Yellow would normally sort last (alphabetic). 605 // But the recent mention shuold bump it up. 606 ASSERT_THAT(Results.Completions, 607 HasSubsequence(Named("YELLOW"), Named("BLUE"))); 608 } 609 610 TEST(CompletionTest, GlobalQualified) { 611 auto Results = completions( 612 R"cpp( 613 void f() { ::^ } 614 )cpp", 615 {cls("XYZ")}); 616 EXPECT_THAT(Results.Completions, 617 AllOf(Has("XYZ", CompletionItemKind::Class), 618 Has("f", CompletionItemKind::Function))); 619 } 620 621 TEST(CompletionTest, FullyQualified) { 622 auto Results = completions( 623 R"cpp( 624 namespace ns { void bar(); } 625 void f() { ::ns::^ } 626 )cpp", 627 {cls("ns::XYZ")}); 628 EXPECT_THAT(Results.Completions, 629 AllOf(Has("XYZ", CompletionItemKind::Class), 630 Has("bar", CompletionItemKind::Function))); 631 } 632 633 TEST(CompletionTest, SemaIndexMerge) { 634 auto Results = completions( 635 R"cpp( 636 namespace ns { int local; void both(); } 637 void f() { ::ns::^ } 638 )cpp", 639 {func("ns::both"), cls("ns::Index")}); 640 // We get results from both index and sema, with no duplicates. 641 EXPECT_THAT(Results.Completions, 642 UnorderedElementsAre( 643 AllOf(Named("local"), Origin(SymbolOrigin::AST)), 644 AllOf(Named("Index"), Origin(SymbolOrigin::Static)), 645 AllOf(Named("both"), 646 Origin(SymbolOrigin::AST | SymbolOrigin::Static)))); 647 } 648 649 TEST(CompletionTest, SemaIndexMergeWithLimit) { 650 clangd::CodeCompleteOptions Opts; 651 Opts.Limit = 1; 652 auto Results = completions( 653 R"cpp( 654 namespace ns { int local; void both(); } 655 void f() { ::ns::^ } 656 )cpp", 657 {func("ns::both"), cls("ns::Index")}, Opts); 658 EXPECT_EQ(Results.Completions.size(), Opts.Limit); 659 EXPECT_TRUE(Results.HasMore); 660 } 661 662 TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) { 663 MockFSProvider FS; 664 MockCompilationDatabase CDB; 665 std::string Subdir = testPath("sub"); 666 std::string SearchDirArg = (Twine("-I") + Subdir).str(); 667 CDB.ExtraClangFlags = {SearchDirArg.c_str()}; 668 std::string BarHeader = testPath("sub/bar.h"); 669 FS.Files[BarHeader] = ""; 670 671 IgnoreDiagnostics DiagConsumer; 672 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 673 auto BarURI = URI::create(BarHeader).toString(); 674 Symbol Sym = cls("ns::X"); 675 Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); 676 Sym.IncludeHeaders.emplace_back(BarURI, 1); 677 // Shoten include path based on search dirctory and insert. 678 auto Results = completions(Server, 679 R"cpp( 680 int main() { ns::^ } 681 )cpp", 682 {Sym}); 683 EXPECT_THAT(Results.Completions, 684 ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\"")))); 685 // Can be disabled via option. 686 CodeCompleteOptions NoInsertion; 687 NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert; 688 Results = completions(Server, 689 R"cpp( 690 int main() { ns::^ } 691 )cpp", 692 {Sym}, NoInsertion); 693 EXPECT_THAT(Results.Completions, 694 ElementsAre(AllOf(Named("X"), Not(InsertInclude())))); 695 // Duplicate based on inclusions in preamble. 696 Results = completions(Server, 697 R"cpp( 698 #include "sub/bar.h" // not shortest, so should only match resolved. 699 int main() { ns::^ } 700 )cpp", 701 {Sym}); 702 EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Labeled("X"), 703 Not(InsertInclude())))); 704 } 705 706 TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) { 707 MockFSProvider FS; 708 MockCompilationDatabase CDB; 709 710 IgnoreDiagnostics DiagConsumer; 711 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 712 Symbol SymX = cls("ns::X"); 713 Symbol SymY = cls("ns::Y"); 714 std::string BarHeader = testPath("bar.h"); 715 auto BarURI = URI::create(BarHeader).toString(); 716 SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); 717 SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); 718 SymX.IncludeHeaders.emplace_back("<bar>", 1); 719 SymY.IncludeHeaders.emplace_back("<bar>", 1); 720 // Shoten include path based on search dirctory and insert. 721 auto Results = completions(Server, 722 R"cpp( 723 namespace ns { 724 class X; 725 class Y {}; 726 } 727 int main() { ns::^ } 728 )cpp", 729 {SymX, SymY}); 730 EXPECT_THAT(Results.Completions, 731 ElementsAre(AllOf(Named("X"), Not(InsertInclude())), 732 AllOf(Named("Y"), Not(InsertInclude())))); 733 } 734 735 TEST(CompletionTest, IndexSuppressesPreambleCompletions) { 736 MockFSProvider FS; 737 MockCompilationDatabase CDB; 738 IgnoreDiagnostics DiagConsumer; 739 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 740 741 FS.Files[testPath("bar.h")] = 742 R"cpp(namespace ns { struct preamble { int member; }; })cpp"; 743 auto File = testPath("foo.cpp"); 744 Annotations Test(R"cpp( 745 #include "bar.h" 746 namespace ns { int local; } 747 void f() { ns::^; } 748 void f2() { ns::preamble().$2^; } 749 )cpp"); 750 runAddDocument(Server, File, Test.code()); 751 clangd::CodeCompleteOptions Opts = {}; 752 753 auto I = memIndex({var("ns::index")}); 754 Opts.Index = I.get(); 755 auto WithIndex = cantFail(runCodeComplete(Server, File, Test.point(), Opts)); 756 EXPECT_THAT(WithIndex.Completions, 757 UnorderedElementsAre(Named("local"), Named("index"))); 758 auto ClassFromPreamble = 759 cantFail(runCodeComplete(Server, File, Test.point("2"), Opts)); 760 EXPECT_THAT(ClassFromPreamble.Completions, Contains(Named("member"))); 761 762 Opts.Index = nullptr; 763 auto WithoutIndex = 764 cantFail(runCodeComplete(Server, File, Test.point(), Opts)); 765 EXPECT_THAT(WithoutIndex.Completions, 766 UnorderedElementsAre(Named("local"), Named("preamble"))); 767 } 768 769 // This verifies that we get normal preprocessor completions in the preamble. 770 // This is a regression test for an old bug: if we override the preamble and 771 // try to complete inside it, clang kicks our completion point just outside the 772 // preamble, resulting in always getting top-level completions. 773 TEST(CompletionTest, CompletionInPreamble) { 774 auto Results = completions(R"cpp( 775 #ifnd^ef FOO_H_ 776 #define BAR_H_ 777 #include <bar.h> 778 int foo() {} 779 #endif 780 )cpp") 781 .Completions; 782 EXPECT_THAT(Results, ElementsAre(Named("ifndef"))); 783 } 784 785 TEST(CompletionTest, DynamicIndexIncludeInsertion) { 786 MockFSProvider FS; 787 MockCompilationDatabase CDB; 788 IgnoreDiagnostics DiagConsumer; 789 ClangdServer::Options Opts = ClangdServer::optsForTest(); 790 Opts.BuildDynamicSymbolIndex = true; 791 ClangdServer Server(CDB, FS, DiagConsumer, Opts); 792 793 FS.Files[testPath("foo_header.h")] = R"cpp( 794 #pragma once 795 struct Foo { 796 // Member doc 797 int foo(); 798 }; 799 )cpp"; 800 const std::string FileContent(R"cpp( 801 #include "foo_header.h" 802 int Foo::foo() { 803 return 42; 804 } 805 )cpp"); 806 Server.addDocument(testPath("foo_impl.cpp"), FileContent); 807 // Wait for the dynamic index being built. 808 ASSERT_TRUE(Server.blockUntilIdleForTest()); 809 EXPECT_THAT(completions(Server, "Foo^ foo;").Completions, 810 ElementsAre(AllOf(Named("Foo"), HasInclude("\"foo_header.h\""), 811 InsertInclude()))); 812 } 813 814 TEST(CompletionTest, DynamicIndexMultiFile) { 815 MockFSProvider FS; 816 MockCompilationDatabase CDB; 817 IgnoreDiagnostics DiagConsumer; 818 auto Opts = ClangdServer::optsForTest(); 819 Opts.BuildDynamicSymbolIndex = true; 820 ClangdServer Server(CDB, FS, DiagConsumer, Opts); 821 822 FS.Files[testPath("foo.h")] = R"cpp( 823 namespace ns { class XYZ {}; void foo(int x) {} } 824 )cpp"; 825 runAddDocument(Server, testPath("foo.cpp"), R"cpp( 826 #include "foo.h" 827 )cpp"); 828 829 auto File = testPath("bar.cpp"); 830 Annotations Test(R"cpp( 831 namespace ns { 832 class XXX {}; 833 /// Doooc 834 void fooooo() {} 835 } 836 void f() { ns::^ } 837 )cpp"); 838 runAddDocument(Server, File, Test.code()); 839 840 auto Results = cantFail(runCodeComplete(Server, File, Test.point(), {})); 841 // "XYZ" and "foo" are not included in the file being completed but are still 842 // visible through the index. 843 EXPECT_THAT(Results.Completions, Has("XYZ", CompletionItemKind::Class)); 844 EXPECT_THAT(Results.Completions, Has("foo", CompletionItemKind::Function)); 845 EXPECT_THAT(Results.Completions, Has("XXX", CompletionItemKind::Class)); 846 EXPECT_THAT(Results.Completions, 847 Contains((Named("fooooo"), Kind(CompletionItemKind::Function), 848 Doc("Doooc"), ReturnType("void")))); 849 } 850 851 TEST(CompletionTest, Documentation) { 852 auto Results = completions( 853 R"cpp( 854 // Non-doxygen comment. 855 int foo(); 856 /// Doxygen comment. 857 /// \param int a 858 int bar(int a); 859 /* Multi-line 860 block comment 861 */ 862 int baz(); 863 864 int x = ^ 865 )cpp"); 866 EXPECT_THAT(Results.Completions, 867 Contains(AllOf(Named("foo"), Doc("Non-doxygen comment.")))); 868 EXPECT_THAT( 869 Results.Completions, 870 Contains(AllOf(Named("bar"), Doc("Doxygen comment.\n\\param int a")))); 871 EXPECT_THAT(Results.Completions, 872 Contains(AllOf(Named("baz"), Doc("Multi-line\nblock comment")))); 873 } 874 875 TEST(CompletionTest, GlobalCompletionFiltering) { 876 877 Symbol Class = cls("XYZ"); 878 Class.Flags = static_cast<Symbol::SymbolFlag>( 879 Class.Flags & ~(Symbol::IndexedForCodeCompletion)); 880 Symbol Func = func("XYZ::foooo"); 881 Func.Flags = static_cast<Symbol::SymbolFlag>( 882 Func.Flags & ~(Symbol::IndexedForCodeCompletion)); 883 884 auto Results = completions(R"(// void f() { 885 XYZ::foooo^ 886 })", 887 {Class, Func}); 888 EXPECT_THAT(Results.Completions, IsEmpty()); 889 } 890 891 TEST(CodeCompleteTest, DisableTypoCorrection) { 892 auto Results = completions(R"cpp( 893 namespace clang { int v; } 894 void f() { clangd::^ 895 )cpp"); 896 EXPECT_TRUE(Results.Completions.empty()); 897 } 898 899 TEST(CodeCompleteTest, NoColonColonAtTheEnd) { 900 auto Results = completions(R"cpp( 901 namespace clang { } 902 void f() { 903 clan^ 904 } 905 )cpp"); 906 907 EXPECT_THAT(Results.Completions, Contains(Labeled("clang"))); 908 EXPECT_THAT(Results.Completions, Not(Contains(Labeled("clang::")))); 909 } 910 911 TEST(CompletionTest, BacktrackCrashes) { 912 // Sema calls code completion callbacks twice in these cases. 913 auto Results = completions(R"cpp( 914 namespace ns { 915 struct FooBarBaz {}; 916 } // namespace ns 917 918 int foo(ns::FooBar^ 919 )cpp"); 920 921 EXPECT_THAT(Results.Completions, ElementsAre(Labeled("FooBarBaz"))); 922 923 // Check we don't crash in that case too. 924 completions(R"cpp( 925 struct FooBarBaz {}; 926 void test() { 927 if (FooBarBaz * x^) {} 928 } 929 )cpp"); 930 } 931 932 TEST(CompletionTest, CompleteInMacroWithStringification) { 933 auto Results = completions(R"cpp( 934 void f(const char *, int x); 935 #define F(x) f(#x, x) 936 937 namespace ns { 938 int X; 939 int Y; 940 } // namespace ns 941 942 int f(int input_num) { 943 F(ns::^) 944 } 945 )cpp"); 946 947 EXPECT_THAT(Results.Completions, 948 UnorderedElementsAre(Named("X"), Named("Y"))); 949 } 950 951 TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) { 952 auto Results = completions(R"cpp( 953 void f(const char *, int x); 954 #define F(x) f(#x, x) 955 956 namespace ns { 957 int X; 958 959 int f(int input_num) { 960 F(^) 961 } 962 } // namespace ns 963 )cpp"); 964 965 EXPECT_THAT(Results.Completions, Contains(Named("X"))); 966 } 967 968 TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) { 969 auto Results = completions(R"cpp( 970 int bar(int param_in_bar) { 971 } 972 973 int foo(int param_in_foo) { 974 #if 0 975 // In recorvery mode, "param_in_foo" will also be suggested among many other 976 // unrelated symbols; however, this is really a special case where this works. 977 // If the #if block is outside of the function, "param_in_foo" is still 978 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't 979 // really provide useful results in excluded branches. 980 par^ 981 #endif 982 } 983 )cpp"); 984 985 EXPECT_TRUE(Results.Completions.empty()); 986 } 987 988 TEST(CompletionTest, DefaultArgs) { 989 clangd::CodeCompleteOptions Opts; 990 std::string Context = R"cpp( 991 int X(int A = 0); 992 int Y(int A, int B = 0); 993 int Z(int A, int B = 0, int C = 0, int D = 0); 994 )cpp"; 995 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions, 996 UnorderedElementsAre(Labeled("X(int A = 0)"))); 997 EXPECT_THAT(completions(Context + "int y = Y^", {}, Opts).Completions, 998 UnorderedElementsAre(AllOf(Labeled("Y(int A, int B = 0)"), 999 SnippetSuffix("(${1:int A})")))); 1000 EXPECT_THAT(completions(Context + "int y = Z^", {}, Opts).Completions, 1001 UnorderedElementsAre( 1002 AllOf(Labeled("Z(int A, int B = 0, int C = 0, int D = 0)"), 1003 SnippetSuffix("(${1:int A})")))); 1004 } 1005 1006 SignatureHelp signatures(llvm::StringRef Text, Position Point, 1007 std::vector<Symbol> IndexSymbols = {}) { 1008 std::unique_ptr<SymbolIndex> Index; 1009 if (!IndexSymbols.empty()) 1010 Index = memIndex(IndexSymbols); 1011 1012 MockFSProvider FS; 1013 MockCompilationDatabase CDB; 1014 IgnoreDiagnostics DiagConsumer; 1015 ClangdServer::Options Opts = ClangdServer::optsForTest(); 1016 Opts.StaticIndex = Index.get(); 1017 1018 ClangdServer Server(CDB, FS, DiagConsumer, Opts); 1019 auto File = testPath("foo.cpp"); 1020 runAddDocument(Server, File, Text); 1021 return llvm::cantFail(runSignatureHelp(Server, File, Point)); 1022 } 1023 1024 SignatureHelp signatures(llvm::StringRef Text, 1025 std::vector<Symbol> IndexSymbols = {}) { 1026 Annotations Test(Text); 1027 return signatures(Test.code(), Test.point(), std::move(IndexSymbols)); 1028 } 1029 1030 struct ExpectedParameter { 1031 std::string Text; 1032 std::pair<unsigned, unsigned> Offsets; 1033 }; 1034 MATCHER_P(ParamsAre, P, "") { 1035 if (P.size() != arg.parameters.size()) 1036 return false; 1037 for (unsigned I = 0; I < P.size(); ++I) { 1038 if (P[I].Text != arg.parameters[I].labelString || 1039 P[I].Offsets != arg.parameters[I].labelOffsets) 1040 return false; 1041 } 1042 return true; 1043 } 1044 MATCHER_P(SigDoc, Doc, "") { return arg.documentation == Doc; } 1045 1046 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g. 1047 /// foo([[int p1]], [[double p2]]) -> void 1048 Matcher<SignatureInformation> Sig(llvm::StringRef AnnotatedLabel) { 1049 llvm::Annotations A(AnnotatedLabel); 1050 std::string Label = A.code(); 1051 std::vector<ExpectedParameter> Parameters; 1052 for (auto Range : A.ranges()) { 1053 Parameters.emplace_back(); 1054 1055 ExpectedParameter &P = Parameters.back(); 1056 P.Text = Label.substr(Range.Begin, Range.End - Range.Begin); 1057 P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin)); 1058 P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End)); 1059 } 1060 return AllOf(SigHelpLabeled(Label), ParamsAre(Parameters)); 1061 } 1062 1063 TEST(SignatureHelpTest, Overloads) { 1064 auto Results = signatures(R"cpp( 1065 void foo(int x, int y); 1066 void foo(int x, float y); 1067 void foo(float x, int y); 1068 void foo(float x, float y); 1069 void bar(int x, int y = 0); 1070 int main() { foo(^); } 1071 )cpp"); 1072 EXPECT_THAT(Results.signatures, 1073 UnorderedElementsAre(Sig("foo([[float x]], [[float y]]) -> void"), 1074 Sig("foo([[float x]], [[int y]]) -> void"), 1075 Sig("foo([[int x]], [[float y]]) -> void"), 1076 Sig("foo([[int x]], [[int y]]) -> void"))); 1077 // We always prefer the first signature. 1078 EXPECT_EQ(0, Results.activeSignature); 1079 EXPECT_EQ(0, Results.activeParameter); 1080 } 1081 1082 TEST(SignatureHelpTest, DefaultArgs) { 1083 auto Results = signatures(R"cpp( 1084 void bar(int x, int y = 0); 1085 void bar(float x = 0, int y = 42); 1086 int main() { bar(^ 1087 )cpp"); 1088 EXPECT_THAT(Results.signatures, 1089 UnorderedElementsAre( 1090 Sig("bar([[int x]], [[int y = 0]]) -> void"), 1091 Sig("bar([[float x = 0]], [[int y = 42]]) -> void"))); 1092 EXPECT_EQ(0, Results.activeSignature); 1093 EXPECT_EQ(0, Results.activeParameter); 1094 } 1095 1096 TEST(SignatureHelpTest, ActiveArg) { 1097 auto Results = signatures(R"cpp( 1098 int baz(int a, int b, int c); 1099 int main() { baz(baz(1,2,3), ^); } 1100 )cpp"); 1101 EXPECT_THAT(Results.signatures, 1102 ElementsAre(Sig("baz([[int a]], [[int b]], [[int c]]) -> int"))); 1103 EXPECT_EQ(0, Results.activeSignature); 1104 EXPECT_EQ(1, Results.activeParameter); 1105 } 1106 1107 TEST(SignatureHelpTest, OpeningParen) { 1108 llvm::StringLiteral Tests[] = {// Recursive function call. 1109 R"cpp( 1110 int foo(int a, int b, int c); 1111 int main() { 1112 foo(foo $p^( foo(10, 10, 10), ^ ))); 1113 })cpp", 1114 // Functional type cast. 1115 R"cpp( 1116 struct Foo { 1117 Foo(int a, int b, int c); 1118 }; 1119 int main() { 1120 Foo $p^( 10, ^ ); 1121 })cpp", 1122 // New expression. 1123 R"cpp( 1124 struct Foo { 1125 Foo(int a, int b, int c); 1126 }; 1127 int main() { 1128 new Foo $p^( 10, ^ ); 1129 })cpp", 1130 // Macro expansion. 1131 R"cpp( 1132 int foo(int a, int b, int c); 1133 #define FOO foo( 1134 1135 int main() { 1136 // Macro expansions. 1137 $p^FOO 10, ^ ); 1138 })cpp", 1139 // Macro arguments. 1140 R"cpp( 1141 int foo(int a, int b, int c); 1142 int main() { 1143 #define ID(X) X 1144 ID(foo $p^( foo(10), ^ )) 1145 })cpp"}; 1146 1147 for (auto Test : Tests) { 1148 Annotations Code(Test); 1149 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart, 1150 Code.point("p")) 1151 << "Test source:" << Test; 1152 } 1153 } 1154 1155 class IndexRequestCollector : public SymbolIndex { 1156 public: 1157 bool 1158 fuzzyFind(const FuzzyFindRequest &Req, 1159 llvm::function_ref<void(const Symbol &)> Callback) const override { 1160 std::unique_lock<std::mutex> Lock(Mut); 1161 Requests.push_back(Req); 1162 ReceivedRequestCV.notify_one(); 1163 return true; 1164 } 1165 1166 void lookup(const LookupRequest &, 1167 llvm::function_ref<void(const Symbol &)>) const override {} 1168 1169 void refs(const RefsRequest &, 1170 llvm::function_ref<void(const Ref &)>) const override {} 1171 1172 void relations(const RelationsRequest &, 1173 llvm::function_ref<void(const SymbolID &, const Symbol &)>) 1174 const override {} 1175 1176 // This is incorrect, but IndexRequestCollector is not an actual index and it 1177 // isn't used in production code. 1178 size_t estimateMemoryUsage() const override { return 0; } 1179 1180 const std::vector<FuzzyFindRequest> consumeRequests(size_t Num) const { 1181 std::unique_lock<std::mutex> Lock(Mut); 1182 EXPECT_TRUE(wait(Lock, ReceivedRequestCV, timeoutSeconds(30), 1183 [this, Num] { return Requests.size() == Num; })); 1184 auto Reqs = std::move(Requests); 1185 Requests = {}; 1186 return Reqs; 1187 } 1188 1189 private: 1190 // We need a mutex to handle async fuzzy find requests. 1191 mutable std::condition_variable ReceivedRequestCV; 1192 mutable std::mutex Mut; 1193 mutable std::vector<FuzzyFindRequest> Requests; 1194 }; 1195 1196 // Clients have to consume exactly Num requests. 1197 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code, 1198 size_t Num = 1) { 1199 clangd::CodeCompleteOptions Opts; 1200 IndexRequestCollector Requests; 1201 Opts.Index = &Requests; 1202 completions(Code, {}, Opts); 1203 const auto Reqs = Requests.consumeRequests(Num); 1204 EXPECT_EQ(Reqs.size(), Num); 1205 return Reqs; 1206 } 1207 1208 TEST(CompletionTest, UnqualifiedIdQuery) { 1209 auto Requests = captureIndexRequests(R"cpp( 1210 namespace std {} 1211 using namespace std; 1212 namespace ns { 1213 void f() { 1214 vec^ 1215 } 1216 } 1217 )cpp"); 1218 1219 EXPECT_THAT(Requests, 1220 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1221 UnorderedElementsAre("", "ns::", "std::")))); 1222 } 1223 1224 TEST(CompletionTest, EnclosingScopeComesFirst) { 1225 auto Requests = captureIndexRequests(R"cpp( 1226 namespace std {} 1227 using namespace std; 1228 namespace nx { 1229 namespace ns { 1230 namespace { 1231 void f() { 1232 vec^ 1233 } 1234 } 1235 } 1236 } 1237 )cpp"); 1238 1239 EXPECT_THAT(Requests, 1240 ElementsAre(Field( 1241 &FuzzyFindRequest::Scopes, 1242 UnorderedElementsAre("", "std::", "nx::ns::", "nx::")))); 1243 EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::"); 1244 } 1245 1246 TEST(CompletionTest, ResolvedQualifiedIdQuery) { 1247 auto Requests = captureIndexRequests(R"cpp( 1248 namespace ns1 {} 1249 namespace ns2 {} // ignore 1250 namespace ns3 { namespace nns3 {} } 1251 namespace foo { 1252 using namespace ns1; 1253 using namespace ns3::nns3; 1254 } 1255 namespace ns { 1256 void f() { 1257 foo::^ 1258 } 1259 } 1260 )cpp"); 1261 1262 EXPECT_THAT(Requests, 1263 ElementsAre(Field( 1264 &FuzzyFindRequest::Scopes, 1265 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::")))); 1266 } 1267 1268 TEST(CompletionTest, UnresolvedQualifierIdQuery) { 1269 auto Requests = captureIndexRequests(R"cpp( 1270 namespace a {} 1271 using namespace a; 1272 namespace ns { 1273 void f() { 1274 bar::^ 1275 } 1276 } // namespace ns 1277 )cpp"); 1278 1279 EXPECT_THAT(Requests, 1280 ElementsAre(Field( 1281 &FuzzyFindRequest::Scopes, 1282 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::")))); 1283 } 1284 1285 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) { 1286 auto Requests = captureIndexRequests(R"cpp( 1287 namespace a {} 1288 using namespace a; 1289 namespace ns { 1290 void f() { 1291 ::a::bar::^ 1292 } 1293 } // namespace ns 1294 )cpp"); 1295 1296 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1297 UnorderedElementsAre("a::bar::")))); 1298 } 1299 1300 TEST(CompletionTest, EmptyQualifiedQuery) { 1301 auto Requests = captureIndexRequests(R"cpp( 1302 namespace ns { 1303 void f() { 1304 ^ 1305 } 1306 } // namespace ns 1307 )cpp"); 1308 1309 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1310 UnorderedElementsAre("", "ns::")))); 1311 } 1312 1313 TEST(CompletionTest, GlobalQualifiedQuery) { 1314 auto Requests = captureIndexRequests(R"cpp( 1315 namespace ns { 1316 void f() { 1317 ::^ 1318 } 1319 } // namespace ns 1320 )cpp"); 1321 1322 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1323 UnorderedElementsAre("")))); 1324 } 1325 1326 TEST(CompletionTest, NoDuplicatedQueryScopes) { 1327 auto Requests = captureIndexRequests(R"cpp( 1328 namespace {} 1329 1330 namespace na { 1331 namespace {} 1332 namespace nb { 1333 ^ 1334 } // namespace nb 1335 } // namespace na 1336 )cpp"); 1337 1338 EXPECT_THAT(Requests, 1339 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1340 UnorderedElementsAre("na::", "na::nb::", "")))); 1341 } 1342 1343 TEST(CompletionTest, NoIndexCompletionsInsideClasses) { 1344 auto Completions = completions( 1345 R"cpp( 1346 struct Foo { 1347 int SomeNameOfField; 1348 typedef int SomeNameOfTypedefField; 1349 }; 1350 1351 Foo::^)cpp", 1352 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")}); 1353 1354 EXPECT_THAT(Completions.Completions, 1355 AllOf(Contains(Labeled("SomeNameOfField")), 1356 Contains(Labeled("SomeNameOfTypedefField")), 1357 Not(Contains(Labeled("SomeNameInTheIndex"))))); 1358 } 1359 1360 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) { 1361 { 1362 auto Completions = completions( 1363 R"cpp( 1364 template <class T> 1365 void foo() { 1366 T::^ 1367 } 1368 )cpp", 1369 {func("::SomeNameInTheIndex")}); 1370 1371 EXPECT_THAT(Completions.Completions, 1372 Not(Contains(Labeled("SomeNameInTheIndex")))); 1373 } 1374 1375 { 1376 auto Completions = completions( 1377 R"cpp( 1378 template <class T> 1379 void foo() { 1380 T::template Y<int>::^ 1381 } 1382 )cpp", 1383 {func("::SomeNameInTheIndex")}); 1384 1385 EXPECT_THAT(Completions.Completions, 1386 Not(Contains(Labeled("SomeNameInTheIndex")))); 1387 } 1388 1389 { 1390 auto Completions = completions( 1391 R"cpp( 1392 template <class T> 1393 void foo() { 1394 T::foo::^ 1395 } 1396 )cpp", 1397 {func("::SomeNameInTheIndex")}); 1398 1399 EXPECT_THAT(Completions.Completions, 1400 Not(Contains(Labeled("SomeNameInTheIndex")))); 1401 } 1402 } 1403 1404 TEST(CompletionTest, OverloadBundling) { 1405 clangd::CodeCompleteOptions Opts; 1406 Opts.BundleOverloads = true; 1407 1408 std::string Context = R"cpp( 1409 struct X { 1410 // Overload with int 1411 int a(int); 1412 // Overload with bool 1413 int a(bool); 1414 int b(float); 1415 }; 1416 int GFuncC(int); 1417 int GFuncD(int); 1418 )cpp"; 1419 1420 // Member completions are bundled. 1421 EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions, 1422 UnorderedElementsAre(Labeled("a(…)"), Labeled("b(float)"))); 1423 1424 // Non-member completions are bundled, including index+sema. 1425 Symbol NoArgsGFunc = func("GFuncC"); 1426 EXPECT_THAT( 1427 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1428 UnorderedElementsAre(Labeled("GFuncC(…)"), Labeled("GFuncD(int)"))); 1429 1430 // Differences in header-to-insert suppress bundling. 1431 std::string DeclFile = URI::create(testPath("foo")).toString(); 1432 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str(); 1433 NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1); 1434 EXPECT_THAT( 1435 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1436 UnorderedElementsAre(AllOf(Named("GFuncC"), InsertInclude("<foo>")), 1437 Labeled("GFuncC(int)"), Labeled("GFuncD(int)"))); 1438 1439 // Examine a bundled completion in detail. 1440 auto A = 1441 completions(Context + "int y = X().a^", {}, Opts).Completions.front(); 1442 EXPECT_EQ(A.Name, "a"); 1443 EXPECT_EQ(A.Signature, "(…)"); 1444 EXPECT_EQ(A.BundleSize, 2u); 1445 EXPECT_EQ(A.Kind, CompletionItemKind::Method); 1446 EXPECT_EQ(A.ReturnType, "int"); // All overloads return int. 1447 // For now we just return one of the doc strings arbitrarily. 1448 EXPECT_THAT(A.Documentation, AnyOf(HasSubstr("Overload with int"), 1449 HasSubstr("Overload with bool"))); 1450 EXPECT_EQ(A.SnippetSuffix, "($0)"); 1451 } 1452 1453 TEST(CompletionTest, DocumentationFromChangedFileCrash) { 1454 MockFSProvider FS; 1455 auto FooH = testPath("foo.h"); 1456 auto FooCpp = testPath("foo.cpp"); 1457 FS.Files[FooH] = R"cpp( 1458 // this is my documentation comment. 1459 int func(); 1460 )cpp"; 1461 FS.Files[FooCpp] = ""; 1462 1463 MockCompilationDatabase CDB; 1464 IgnoreDiagnostics DiagConsumer; 1465 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1466 1467 Annotations Source(R"cpp( 1468 #include "foo.h" 1469 int func() { 1470 // This makes sure we have func from header in the AST. 1471 } 1472 int a = fun^ 1473 )cpp"); 1474 Server.addDocument(FooCpp, Source.code(), WantDiagnostics::Yes); 1475 // We need to wait for preamble to build. 1476 ASSERT_TRUE(Server.blockUntilIdleForTest()); 1477 1478 // Change the header file. Completion will reuse the old preamble! 1479 FS.Files[FooH] = R"cpp( 1480 int func(); 1481 )cpp"; 1482 1483 clangd::CodeCompleteOptions Opts; 1484 Opts.IncludeComments = true; 1485 CodeCompleteResult Completions = 1486 cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts)); 1487 // We shouldn't crash. Unfortunately, current workaround is to not produce 1488 // comments for symbols from headers. 1489 EXPECT_THAT(Completions.Completions, 1490 Contains(AllOf(Not(IsDocumented()), Named("func")))); 1491 } 1492 1493 TEST(CompletionTest, NonDocComments) { 1494 MockFSProvider FS; 1495 auto FooCpp = testPath("foo.cpp"); 1496 FS.Files[FooCpp] = ""; 1497 1498 MockCompilationDatabase CDB; 1499 IgnoreDiagnostics DiagConsumer; 1500 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1501 1502 Annotations Source(R"cpp( 1503 // We ignore namespace comments, for rationale see CodeCompletionStrings.h. 1504 namespace comments_ns { 1505 } 1506 1507 // ------------------ 1508 int comments_foo(); 1509 1510 // A comment and a decl are separated by newlines. 1511 // Therefore, the comment shouldn't show up as doc comment. 1512 1513 int comments_bar(); 1514 1515 // this comment should be in the results. 1516 int comments_baz(); 1517 1518 1519 template <class T> 1520 struct Struct { 1521 int comments_qux(); 1522 int comments_quux(); 1523 }; 1524 1525 1526 // This comment should not be there. 1527 1528 template <class T> 1529 int Struct<T>::comments_qux() { 1530 } 1531 1532 // This comment **should** be in results. 1533 template <class T> 1534 int Struct<T>::comments_quux() { 1535 int a = comments^; 1536 } 1537 )cpp"); 1538 // FIXME: Auto-completion in a template requires disabling delayed template 1539 // parsing. 1540 CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing"); 1541 runAddDocument(Server, FooCpp, Source.code(), WantDiagnostics::Yes); 1542 CodeCompleteResult Completions = cantFail(runCodeComplete( 1543 Server, FooCpp, Source.point(), clangd::CodeCompleteOptions())); 1544 1545 // We should not get any of those comments in completion. 1546 EXPECT_THAT( 1547 Completions.Completions, 1548 UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")), 1549 AllOf(IsDocumented(), Named("comments_baz")), 1550 AllOf(IsDocumented(), Named("comments_quux")), 1551 AllOf(Not(IsDocumented()), Named("comments_ns")), 1552 // FIXME(ibiryukov): the following items should have 1553 // empty documentation, since they are separated from 1554 // a comment with an empty line. Unfortunately, I 1555 // couldn't make Sema tests pass if we ignore those. 1556 AllOf(IsDocumented(), Named("comments_bar")), 1557 AllOf(IsDocumented(), Named("comments_qux")))); 1558 } 1559 1560 TEST(CompletionTest, CompleteOnInvalidLine) { 1561 auto FooCpp = testPath("foo.cpp"); 1562 1563 MockCompilationDatabase CDB; 1564 IgnoreDiagnostics DiagConsumer; 1565 MockFSProvider FS; 1566 FS.Files[FooCpp] = "// empty file"; 1567 1568 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1569 // Run completion outside the file range. 1570 Position Pos; 1571 Pos.line = 100; 1572 Pos.character = 0; 1573 EXPECT_THAT_EXPECTED( 1574 runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()), 1575 Failed()); 1576 } 1577 1578 TEST(CompletionTest, QualifiedNames) { 1579 auto Results = completions( 1580 R"cpp( 1581 namespace ns { int local; void both(); } 1582 void f() { ::ns::^ } 1583 )cpp", 1584 {func("ns::both"), cls("ns::Index")}); 1585 // We get results from both index and sema, with no duplicates. 1586 EXPECT_THAT( 1587 Results.Completions, 1588 UnorderedElementsAre(Scope("ns::"), Scope("ns::"), Scope("ns::"))); 1589 } 1590 1591 TEST(CompletionTest, Render) { 1592 CodeCompletion C; 1593 C.Name = "x"; 1594 C.Signature = "(bool) const"; 1595 C.SnippetSuffix = "(${0:bool})"; 1596 C.ReturnType = "int"; 1597 C.RequiredQualifier = "Foo::"; 1598 C.Scope = "ns::Foo::"; 1599 C.Documentation = "This is x()."; 1600 C.Includes.emplace_back(); 1601 auto &Include = C.Includes.back(); 1602 Include.Header = "\"foo.h\""; 1603 C.Kind = CompletionItemKind::Method; 1604 C.Score.Total = 1.0; 1605 C.Origin = SymbolOrigin::AST | SymbolOrigin::Static; 1606 1607 CodeCompleteOptions Opts; 1608 Opts.IncludeIndicator.Insert = "^"; 1609 Opts.IncludeIndicator.NoInsert = ""; 1610 Opts.EnableSnippets = false; 1611 1612 auto R = C.render(Opts); 1613 EXPECT_EQ(R.label, "Foo::x(bool) const"); 1614 EXPECT_EQ(R.insertText, "Foo::x"); 1615 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText); 1616 EXPECT_EQ(R.filterText, "x"); 1617 EXPECT_EQ(R.detail, "int\n\"foo.h\""); 1618 EXPECT_EQ(R.documentation, "This is x()."); 1619 EXPECT_THAT(R.additionalTextEdits, IsEmpty()); 1620 EXPECT_EQ(R.sortText, sortText(1.0, "x")); 1621 EXPECT_FALSE(R.deprecated); 1622 1623 Opts.EnableSnippets = true; 1624 R = C.render(Opts); 1625 EXPECT_EQ(R.insertText, "Foo::x(${0:bool})"); 1626 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet); 1627 1628 Include.Insertion.emplace(); 1629 R = C.render(Opts); 1630 EXPECT_EQ(R.label, "^Foo::x(bool) const"); 1631 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty())); 1632 1633 Opts.ShowOrigins = true; 1634 R = C.render(Opts); 1635 EXPECT_EQ(R.label, "^[AS]Foo::x(bool) const"); 1636 1637 C.BundleSize = 2; 1638 R = C.render(Opts); 1639 EXPECT_EQ(R.detail, "[2 overloads]\n\"foo.h\""); 1640 1641 C.Deprecated = true; 1642 R = C.render(Opts); 1643 EXPECT_TRUE(R.deprecated); 1644 } 1645 1646 TEST(CompletionTest, IgnoreRecoveryResults) { 1647 auto Results = completions( 1648 R"cpp( 1649 namespace ns { int NotRecovered() { return 0; } } 1650 void f() { 1651 // Sema enters recovery mode first and then normal mode. 1652 if (auto x = ns::NotRecover^) 1653 } 1654 )cpp"); 1655 EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("NotRecovered"))); 1656 } 1657 1658 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) { 1659 auto Results = completions( 1660 R"cpp( 1661 namespace ns { 1662 class X { public: X(); int x_; }; 1663 X::X() : x_^(0) {} 1664 } 1665 )cpp"); 1666 EXPECT_THAT(Results.Completions, 1667 UnorderedElementsAre(AllOf(Scope("ns::X::"), Named("x_")))); 1668 } 1669 1670 TEST(CompletionTest, CodeCompletionContext) { 1671 auto Results = completions( 1672 R"cpp( 1673 namespace ns { 1674 class X { public: X(); int x_; }; 1675 void f() { 1676 X x; 1677 x.^; 1678 } 1679 } 1680 )cpp"); 1681 1682 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess); 1683 } 1684 1685 TEST(CompletionTest, FixItForArrowToDot) { 1686 MockFSProvider FS; 1687 MockCompilationDatabase CDB; 1688 IgnoreDiagnostics DiagConsumer; 1689 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1690 1691 CodeCompleteOptions Opts; 1692 Opts.IncludeFixIts = true; 1693 Annotations TestCode( 1694 R"cpp( 1695 class Auxilary { 1696 public: 1697 void AuxFunction(); 1698 }; 1699 class ClassWithPtr { 1700 public: 1701 void MemberFunction(); 1702 Auxilary* operator->() const; 1703 Auxilary* Aux; 1704 }; 1705 void f() { 1706 ClassWithPtr x; 1707 x[[->]]^; 1708 } 1709 )cpp"); 1710 auto Results = 1711 completions(Server, TestCode.code(), TestCode.point(), {}, Opts); 1712 EXPECT_EQ(Results.Completions.size(), 3u); 1713 1714 TextEdit ReplacementEdit; 1715 ReplacementEdit.range = TestCode.range(); 1716 ReplacementEdit.newText = "."; 1717 for (const auto &C : Results.Completions) { 1718 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction"); 1719 if (!C.FixIts.empty()) { 1720 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 1721 } 1722 } 1723 } 1724 1725 TEST(CompletionTest, FixItForDotToArrow) { 1726 MockFSProvider FS; 1727 MockCompilationDatabase CDB; 1728 IgnoreDiagnostics DiagConsumer; 1729 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1730 1731 CodeCompleteOptions Opts; 1732 Opts.IncludeFixIts = true; 1733 Annotations TestCode( 1734 R"cpp( 1735 class Auxilary { 1736 public: 1737 void AuxFunction(); 1738 }; 1739 class ClassWithPtr { 1740 public: 1741 void MemberFunction(); 1742 Auxilary* operator->() const; 1743 Auxilary* Aux; 1744 }; 1745 void f() { 1746 ClassWithPtr x; 1747 x[[.]]^; 1748 } 1749 )cpp"); 1750 auto Results = 1751 completions(Server, TestCode.code(), TestCode.point(), {}, Opts); 1752 EXPECT_EQ(Results.Completions.size(), 3u); 1753 1754 TextEdit ReplacementEdit; 1755 ReplacementEdit.range = TestCode.range(); 1756 ReplacementEdit.newText = "->"; 1757 for (const auto &C : Results.Completions) { 1758 EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction"); 1759 if (!C.FixIts.empty()) { 1760 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 1761 } 1762 } 1763 } 1764 1765 TEST(CompletionTest, RenderWithFixItMerged) { 1766 TextEdit FixIt; 1767 FixIt.range.end.character = 5; 1768 FixIt.newText = "->"; 1769 1770 CodeCompletion C; 1771 C.Name = "x"; 1772 C.RequiredQualifier = "Foo::"; 1773 C.FixIts = {FixIt}; 1774 C.CompletionTokenRange.start.character = 5; 1775 1776 CodeCompleteOptions Opts; 1777 Opts.IncludeFixIts = true; 1778 1779 auto R = C.render(Opts); 1780 EXPECT_TRUE(R.textEdit); 1781 EXPECT_EQ(R.textEdit->newText, "->Foo::x"); 1782 EXPECT_TRUE(R.additionalTextEdits.empty()); 1783 } 1784 1785 TEST(CompletionTest, RenderWithFixItNonMerged) { 1786 TextEdit FixIt; 1787 FixIt.range.end.character = 4; 1788 FixIt.newText = "->"; 1789 1790 CodeCompletion C; 1791 C.Name = "x"; 1792 C.RequiredQualifier = "Foo::"; 1793 C.FixIts = {FixIt}; 1794 C.CompletionTokenRange.start.character = 5; 1795 1796 CodeCompleteOptions Opts; 1797 Opts.IncludeFixIts = true; 1798 1799 auto R = C.render(Opts); 1800 EXPECT_TRUE(R.textEdit); 1801 EXPECT_EQ(R.textEdit->newText, "Foo::x"); 1802 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt)); 1803 } 1804 1805 TEST(CompletionTest, CompletionTokenRange) { 1806 MockFSProvider FS; 1807 MockCompilationDatabase CDB; 1808 IgnoreDiagnostics DiagConsumer; 1809 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 1810 1811 constexpr const char *TestCodes[] = { 1812 R"cpp( 1813 class Auxilary { 1814 public: 1815 void AuxFunction(); 1816 }; 1817 void f() { 1818 Auxilary x; 1819 x.[[Aux]]^; 1820 } 1821 )cpp", 1822 R"cpp( 1823 class Auxilary { 1824 public: 1825 void AuxFunction(); 1826 }; 1827 void f() { 1828 Auxilary x; 1829 x.[[]]^; 1830 } 1831 )cpp"}; 1832 for (const auto &Text : TestCodes) { 1833 Annotations TestCode(Text); 1834 auto Results = completions(Server, TestCode.code(), TestCode.point()); 1835 1836 EXPECT_EQ(Results.Completions.size(), 1u); 1837 EXPECT_THAT(Results.Completions.front().CompletionTokenRange, 1838 TestCode.range()); 1839 } 1840 } 1841 1842 TEST(SignatureHelpTest, OverloadsOrdering) { 1843 const auto Results = signatures(R"cpp( 1844 void foo(int x); 1845 void foo(int x, float y); 1846 void foo(float x, int y); 1847 void foo(float x, float y); 1848 void foo(int x, int y = 0); 1849 int main() { foo(^); } 1850 )cpp"); 1851 EXPECT_THAT(Results.signatures, 1852 ElementsAre(Sig("foo([[int x]]) -> void"), 1853 Sig("foo([[int x]], [[int y = 0]]) -> void"), 1854 Sig("foo([[float x]], [[int y]]) -> void"), 1855 Sig("foo([[int x]], [[float y]]) -> void"), 1856 Sig("foo([[float x]], [[float y]]) -> void"))); 1857 // We always prefer the first signature. 1858 EXPECT_EQ(0, Results.activeSignature); 1859 EXPECT_EQ(0, Results.activeParameter); 1860 } 1861 1862 TEST(SignatureHelpTest, InstantiatedSignatures) { 1863 StringRef Sig0 = R"cpp( 1864 template <class T> 1865 void foo(T, T, T); 1866 1867 int main() { 1868 foo<int>(^); 1869 } 1870 )cpp"; 1871 1872 EXPECT_THAT(signatures(Sig0).signatures, 1873 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); 1874 1875 StringRef Sig1 = R"cpp( 1876 template <class T> 1877 void foo(T, T, T); 1878 1879 int main() { 1880 foo(10, ^); 1881 })cpp"; 1882 1883 EXPECT_THAT(signatures(Sig1).signatures, 1884 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); 1885 1886 StringRef Sig2 = R"cpp( 1887 template <class ...T> 1888 void foo(T...); 1889 1890 int main() { 1891 foo<int>(^); 1892 } 1893 )cpp"; 1894 1895 EXPECT_THAT(signatures(Sig2).signatures, 1896 ElementsAre(Sig("foo([[T...]]) -> void"))); 1897 1898 // It is debatable whether we should substitute the outer template parameter 1899 // ('T') in that case. Currently we don't substitute it in signature help, but 1900 // do substitute in code complete. 1901 // FIXME: make code complete and signature help consistent, figure out which 1902 // way is better. 1903 StringRef Sig3 = R"cpp( 1904 template <class T> 1905 struct X { 1906 template <class U> 1907 void foo(T, U); 1908 }; 1909 1910 int main() { 1911 X<int>().foo<double>(^) 1912 } 1913 )cpp"; 1914 1915 EXPECT_THAT(signatures(Sig3).signatures, 1916 ElementsAre(Sig("foo([[T]], [[U]]) -> void"))); 1917 } 1918 1919 TEST(SignatureHelpTest, IndexDocumentation) { 1920 Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#"); 1921 Foo0.Documentation = "Doc from the index"; 1922 Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#"); 1923 Foo1.Documentation = "Doc from the index"; 1924 Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#"); 1925 1926 StringRef Sig0 = R"cpp( 1927 int foo(); 1928 int foo(double); 1929 1930 void test() { 1931 foo(^); 1932 } 1933 )cpp"; 1934 1935 EXPECT_THAT( 1936 signatures(Sig0, {Foo0}).signatures, 1937 ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), 1938 AllOf(Sig("foo([[double]]) -> int"), SigDoc("")))); 1939 1940 StringRef Sig1 = R"cpp( 1941 int foo(); 1942 // Overriden doc from sema 1943 int foo(int); 1944 // Doc from sema 1945 int foo(int, int); 1946 1947 void test() { 1948 foo(^); 1949 } 1950 )cpp"; 1951 1952 EXPECT_THAT( 1953 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures, 1954 ElementsAre( 1955 AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), 1956 AllOf(Sig("foo([[int]]) -> int"), SigDoc("Overriden doc from sema")), 1957 AllOf(Sig("foo([[int]], [[int]]) -> int"), SigDoc("Doc from sema")))); 1958 } 1959 1960 TEST(SignatureHelpTest, DynamicIndexDocumentation) { 1961 MockFSProvider FS; 1962 MockCompilationDatabase CDB; 1963 IgnoreDiagnostics DiagConsumer; 1964 ClangdServer::Options Opts = ClangdServer::optsForTest(); 1965 Opts.BuildDynamicSymbolIndex = true; 1966 ClangdServer Server(CDB, FS, DiagConsumer, Opts); 1967 1968 FS.Files[testPath("foo.h")] = R"cpp( 1969 struct Foo { 1970 // Member doc 1971 int foo(); 1972 }; 1973 )cpp"; 1974 Annotations FileContent(R"cpp( 1975 #include "foo.h" 1976 void test() { 1977 Foo f; 1978 f.foo(^); 1979 } 1980 )cpp"); 1981 auto File = testPath("test.cpp"); 1982 Server.addDocument(File, FileContent.code()); 1983 // Wait for the dynamic index being built. 1984 ASSERT_TRUE(Server.blockUntilIdleForTest()); 1985 EXPECT_THAT( 1986 llvm::cantFail(runSignatureHelp(Server, File, FileContent.point())) 1987 .signatures, 1988 ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Member doc")))); 1989 } 1990 1991 TEST(CompletionTest, CompletionFunctionArgsDisabled) { 1992 CodeCompleteOptions Opts; 1993 Opts.EnableSnippets = true; 1994 Opts.EnableFunctionArgSnippets = false; 1995 1996 { 1997 auto Results = completions( 1998 R"cpp( 1999 void xfoo(); 2000 void xfoo(int x, int y); 2001 void f() { xfo^ })cpp", 2002 {}, Opts); 2003 EXPECT_THAT( 2004 Results.Completions, 2005 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("()")), 2006 AllOf(Named("xfoo"), SnippetSuffix("($0)")))); 2007 } 2008 { 2009 auto Results = completions( 2010 R"cpp( 2011 void xbar(); 2012 void f() { xba^ })cpp", 2013 {}, Opts); 2014 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf( 2015 Named("xbar"), SnippetSuffix("()")))); 2016 } 2017 { 2018 Opts.BundleOverloads = true; 2019 auto Results = completions( 2020 R"cpp( 2021 void xfoo(); 2022 void xfoo(int x, int y); 2023 void f() { xfo^ })cpp", 2024 {}, Opts); 2025 EXPECT_THAT( 2026 Results.Completions, 2027 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("($0)")))); 2028 } 2029 { 2030 auto Results = completions( 2031 R"cpp( 2032 template <class T, class U> 2033 void xfoo(int a, U b); 2034 void f() { xfo^ })cpp", 2035 {}, Opts); 2036 EXPECT_THAT( 2037 Results.Completions, 2038 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("<$1>($0)")))); 2039 } 2040 { 2041 auto Results = completions( 2042 R"cpp( 2043 template <class T> 2044 class foo_class{}; 2045 template <class T> 2046 using foo_alias = T**; 2047 void f() { foo_^ })cpp", 2048 {}, Opts); 2049 EXPECT_THAT( 2050 Results.Completions, 2051 UnorderedElementsAre(AllOf(Named("foo_class"), SnippetSuffix("<$0>")), 2052 AllOf(Named("foo_alias"), SnippetSuffix("<$0>")))); 2053 } 2054 } 2055 2056 TEST(CompletionTest, SuggestOverrides) { 2057 constexpr const char *const Text(R"cpp( 2058 class A { 2059 public: 2060 virtual void vfunc(bool param); 2061 virtual void vfunc(bool param, int p); 2062 void func(bool param); 2063 }; 2064 class B : public A { 2065 virtual void ttt(bool param) const; 2066 void vfunc(bool param, int p) override; 2067 }; 2068 class C : public B { 2069 public: 2070 void vfunc(bool param) override; 2071 ^ 2072 }; 2073 )cpp"); 2074 const auto Results = completions(Text); 2075 EXPECT_THAT( 2076 Results.Completions, 2077 AllOf(Contains(AllOf(Labeled("void vfunc(bool param, int p) override"), 2078 NameStartsWith("vfunc"))), 2079 Contains(AllOf(Labeled("void ttt(bool param) const override"), 2080 NameStartsWith("ttt"))), 2081 Not(Contains(Labeled("void vfunc(bool param) override"))))); 2082 } 2083 2084 TEST(CompletionTest, OverridesNonIdentName) { 2085 // Check the completions call does not crash. 2086 completions(R"cpp( 2087 struct Base { 2088 virtual ~Base() = 0; 2089 virtual operator int() = 0; 2090 virtual Base& operator+(Base&) = 0; 2091 }; 2092 2093 struct Derived : Base { 2094 ^ 2095 }; 2096 )cpp"); 2097 } 2098 2099 TEST(GuessCompletionPrefix, Filters) { 2100 for (llvm::StringRef Case : { 2101 "[[scope::]][[ident]]^", 2102 "[[]][[]]^", 2103 "\n[[]][[]]^", 2104 "[[]][[ab]]^", 2105 "x.[[]][[ab]]^", 2106 "x.[[]][[]]^", 2107 "[[x::]][[ab]]^", 2108 "[[x::]][[]]^", 2109 "[[::x::]][[ab]]^", 2110 "some text [[scope::more::]][[identif]]^ier", 2111 "some text [[scope::]][[mor]]^e::identifier", 2112 "weird case foo::[[::bar::]][[baz]]^", 2113 }) { 2114 Annotations F(Case); 2115 auto Offset = cantFail(positionToOffset(F.code(), F.point())); 2116 auto ToStringRef = [&](Range R) { 2117 return F.code().slice(cantFail(positionToOffset(F.code(), R.start)), 2118 cantFail(positionToOffset(F.code(), R.end))); 2119 }; 2120 auto WantQualifier = ToStringRef(F.ranges()[0]), 2121 WantName = ToStringRef(F.ranges()[1]); 2122 2123 auto Prefix = guessCompletionPrefix(F.code(), Offset); 2124 // Even when components are empty, check their offsets are correct. 2125 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case; 2126 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case; 2127 EXPECT_EQ(WantName, Prefix.Name) << Case; 2128 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case; 2129 } 2130 } 2131 2132 TEST(CompletionTest, EnableSpeculativeIndexRequest) { 2133 MockFSProvider FS; 2134 MockCompilationDatabase CDB; 2135 IgnoreDiagnostics DiagConsumer; 2136 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 2137 2138 auto File = testPath("foo.cpp"); 2139 Annotations Test(R"cpp( 2140 namespace ns1 { int abc; } 2141 namespace ns2 { int abc; } 2142 void f() { ns1::ab$1^; ns1::ab$2^; } 2143 void f2() { ns2::ab$3^; } 2144 )cpp"); 2145 runAddDocument(Server, File, Test.code()); 2146 clangd::CodeCompleteOptions Opts = {}; 2147 2148 IndexRequestCollector Requests; 2149 Opts.Index = &Requests; 2150 Opts.SpeculativeIndexRequest = true; 2151 2152 auto CompleteAtPoint = [&](StringRef P) { 2153 cantFail(runCodeComplete(Server, File, Test.point(P), Opts)); 2154 }; 2155 2156 CompleteAtPoint("1"); 2157 auto Reqs1 = Requests.consumeRequests(1); 2158 ASSERT_EQ(Reqs1.size(), 1u); 2159 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::")); 2160 2161 CompleteAtPoint("2"); 2162 auto Reqs2 = Requests.consumeRequests(1); 2163 // Speculation succeeded. Used speculative index result. 2164 ASSERT_EQ(Reqs2.size(), 1u); 2165 EXPECT_EQ(Reqs2[0], Reqs1[0]); 2166 2167 CompleteAtPoint("3"); 2168 // Speculation failed. Sent speculative index request and the new index 2169 // request after sema. 2170 auto Reqs3 = Requests.consumeRequests(2); 2171 ASSERT_EQ(Reqs3.size(), 2u); 2172 } 2173 2174 TEST(CompletionTest, InsertTheMostPopularHeader) { 2175 std::string DeclFile = URI::create(testPath("foo")).toString(); 2176 Symbol Sym = func("Func"); 2177 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2178 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2179 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2180 2181 auto Results = completions("Fun^", {Sym}).Completions; 2182 assert(!Results.empty()); 2183 EXPECT_THAT(Results[0], AllOf(Named("Func"), InsertInclude("\"bar.h\""))); 2184 EXPECT_EQ(Results[0].Includes.size(), 2u); 2185 } 2186 2187 TEST(CompletionTest, NoInsertIncludeIfOnePresent) { 2188 MockFSProvider FS; 2189 MockCompilationDatabase CDB; 2190 2191 std::string FooHeader = testPath("foo.h"); 2192 FS.Files[FooHeader] = ""; 2193 2194 IgnoreDiagnostics DiagConsumer; 2195 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 2196 2197 std::string DeclFile = URI::create(testPath("foo")).toString(); 2198 Symbol Sym = func("Func"); 2199 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2200 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2201 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2202 2203 EXPECT_THAT( 2204 completions(Server, "#include \"foo.h\"\nFun^", {Sym}).Completions, 2205 UnorderedElementsAre( 2206 AllOf(Named("Func"), HasInclude("\"foo.h\""), Not(InsertInclude())))); 2207 } 2208 2209 TEST(CompletionTest, MergeMacrosFromIndexAndSema) { 2210 Symbol Sym; 2211 Sym.Name = "Clangd_Macro_Test"; 2212 Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test"); 2213 Sym.SymInfo.Kind = index::SymbolKind::Macro; 2214 Sym.Flags |= Symbol::IndexedForCodeCompletion; 2215 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym}) 2216 .Completions, 2217 UnorderedElementsAre(Named("Clangd_Macro_Test"))); 2218 } 2219 2220 TEST(CompletionTest, MacroFromPreamble) { 2221 MockFSProvider FS; 2222 MockCompilationDatabase CDB; 2223 std::string FooHeader = testPath("foo.h"); 2224 FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n"; 2225 IgnoreDiagnostics DiagConsumer; 2226 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 2227 auto Results = completions( 2228 R"cpp(#include "foo.h" 2229 #define CLANGD_PREAMBLE_MAIN x 2230 2231 int x = 0; 2232 #define CLANGD_MAIN x 2233 void f() { CLANGD_^ } 2234 )cpp", 2235 {func("CLANGD_INDEX")}); 2236 // We should get results from the main file, including the preamble section. 2237 // However no results from included files (the index should cover them). 2238 EXPECT_THAT(Results.Completions, 2239 UnorderedElementsAre(Named("CLANGD_PREAMBLE_MAIN"), 2240 Named("CLANGD_MAIN"), 2241 Named("CLANGD_INDEX"))); 2242 } 2243 2244 TEST(CompletionTest, DeprecatedResults) { 2245 std::string Body = R"cpp( 2246 void TestClangd(); 2247 void TestClangc() __attribute__((deprecated("", ""))); 2248 )cpp"; 2249 2250 EXPECT_THAT( 2251 completions(Body + "int main() { TestClang^ }").Completions, 2252 UnorderedElementsAre(AllOf(Named("TestClangd"), Not(Deprecated())), 2253 AllOf(Named("TestClangc"), Deprecated()))); 2254 } 2255 2256 TEST(SignatureHelpTest, InsideArgument) { 2257 { 2258 const auto Results = signatures(R"cpp( 2259 void foo(int x); 2260 void foo(int x, int y); 2261 int main() { foo(1+^); } 2262 )cpp"); 2263 EXPECT_THAT(Results.signatures, 2264 ElementsAre(Sig("foo([[int x]]) -> void"), 2265 Sig("foo([[int x]], [[int y]]) -> void"))); 2266 EXPECT_EQ(0, Results.activeParameter); 2267 } 2268 { 2269 const auto Results = signatures(R"cpp( 2270 void foo(int x); 2271 void foo(int x, int y); 2272 int main() { foo(1^); } 2273 )cpp"); 2274 EXPECT_THAT(Results.signatures, 2275 ElementsAre(Sig("foo([[int x]]) -> void"), 2276 Sig("foo([[int x]], [[int y]]) -> void"))); 2277 EXPECT_EQ(0, Results.activeParameter); 2278 } 2279 { 2280 const auto Results = signatures(R"cpp( 2281 void foo(int x); 2282 void foo(int x, int y); 2283 int main() { foo(1^0); } 2284 )cpp"); 2285 EXPECT_THAT(Results.signatures, 2286 ElementsAre(Sig("foo([[int x]]) -> void"), 2287 Sig("foo([[int x]], [[int y]]) -> void"))); 2288 EXPECT_EQ(0, Results.activeParameter); 2289 } 2290 { 2291 const auto Results = signatures(R"cpp( 2292 void foo(int x); 2293 void foo(int x, int y); 2294 int bar(int x, int y); 2295 int main() { bar(foo(2, 3^)); } 2296 )cpp"); 2297 EXPECT_THAT(Results.signatures, 2298 ElementsAre(Sig("foo([[int x]], [[int y]]) -> void"))); 2299 EXPECT_EQ(1, Results.activeParameter); 2300 } 2301 } 2302 2303 TEST(SignatureHelpTest, ConstructorInitializeFields) { 2304 { 2305 const auto Results = signatures(R"cpp( 2306 struct A { 2307 A(int); 2308 }; 2309 struct B { 2310 B() : a_elem(^) {} 2311 A a_elem; 2312 }; 2313 )cpp"); 2314 EXPECT_THAT(Results.signatures, 2315 UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), 2316 Sig("A([[const A &]])"))); 2317 } 2318 { 2319 const auto Results = signatures(R"cpp( 2320 struct A { 2321 A(int); 2322 }; 2323 struct C { 2324 C(int); 2325 C(A); 2326 }; 2327 struct B { 2328 B() : c_elem(A(1^)) {} 2329 C c_elem; 2330 }; 2331 )cpp"); 2332 EXPECT_THAT(Results.signatures, 2333 UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), 2334 Sig("A([[const A &]])"))); 2335 } 2336 } 2337 2338 TEST(CompletionTest, IncludedCompletionKinds) { 2339 MockFSProvider FS; 2340 MockCompilationDatabase CDB; 2341 std::string Subdir = testPath("sub"); 2342 std::string SearchDirArg = (Twine("-I") + Subdir).str(); 2343 CDB.ExtraClangFlags = {SearchDirArg.c_str()}; 2344 std::string BarHeader = testPath("sub/bar.h"); 2345 FS.Files[BarHeader] = ""; 2346 IgnoreDiagnostics DiagConsumer; 2347 ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); 2348 auto Results = completions(Server, 2349 R"cpp( 2350 #include "^" 2351 )cpp"); 2352 EXPECT_THAT(Results.Completions, 2353 AllOf(Has("sub/", CompletionItemKind::Folder), 2354 Has("bar.h\"", CompletionItemKind::File))); 2355 } 2356 2357 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) { 2358 auto Results = completions( 2359 R"cpp( 2360 #include "./^" 2361 )cpp"); 2362 EXPECT_TRUE(Results.Completions.empty()); 2363 } 2364 2365 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) { 2366 clangd::CodeCompleteOptions Opts = {}; 2367 Opts.AllScopes = true; 2368 2369 auto Results = completions( 2370 R"cpp( 2371 void f() { na::Clangd^ } 2372 )cpp", 2373 {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts); 2374 EXPECT_THAT(Results.Completions, 2375 UnorderedElementsAre( 2376 AllOf(Qualifier(""), Scope("na::"), Named("ClangdA")))); 2377 } 2378 2379 TEST(CompletionTest, AllScopesCompletion) { 2380 clangd::CodeCompleteOptions Opts = {}; 2381 Opts.AllScopes = true; 2382 2383 auto Results = completions( 2384 R"cpp( 2385 namespace na { 2386 void f() { Clangd^ } 2387 } 2388 )cpp", 2389 {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"), 2390 cls("na::nb::Clangd4")}, 2391 Opts); 2392 EXPECT_THAT( 2393 Results.Completions, 2394 UnorderedElementsAre(AllOf(Qualifier("nx::"), Named("Clangd1")), 2395 AllOf(Qualifier("ny::"), Named("Clangd2")), 2396 AllOf(Qualifier(""), Scope(""), Named("Clangd3")), 2397 AllOf(Qualifier("nb::"), Named("Clangd4")))); 2398 } 2399 2400 TEST(CompletionTest, NoQualifierIfShadowed) { 2401 clangd::CodeCompleteOptions Opts = {}; 2402 Opts.AllScopes = true; 2403 2404 auto Results = completions(R"cpp( 2405 namespace nx { class Clangd1 {}; } 2406 using nx::Clangd1; 2407 void f() { Clangd^ } 2408 )cpp", 2409 {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts); 2410 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and 2411 // needs no qualifier. 2412 EXPECT_THAT(Results.Completions, 2413 UnorderedElementsAre(AllOf(Qualifier(""), Named("Clangd1")), 2414 AllOf(Qualifier("nx::"), Named("Clangd2")))); 2415 } 2416 2417 TEST(CompletionTest, NoCompletionsForNewNames) { 2418 clangd::CodeCompleteOptions Opts; 2419 Opts.AllScopes = true; 2420 auto Results = completions(R"cpp( 2421 void f() { int n^ } 2422 )cpp", 2423 {cls("naber"), cls("nx::naber")}, Opts); 2424 EXPECT_THAT(Results.Completions, UnorderedElementsAre()); 2425 } 2426 2427 TEST(CompletionTest, ObjectiveCMethodNoArguments) { 2428 auto Results = completions(R"objc( 2429 @interface Foo 2430 @property(nonatomic, setter=setXToIgnoreComplete:) int value; 2431 @end 2432 Foo *foo = [Foo new]; int y = [foo v^] 2433 )objc", 2434 /*IndexSymbols=*/{}, 2435 /*Opts=*/{}, "Foo.m"); 2436 2437 auto C = Results.Completions; 2438 EXPECT_THAT(C, ElementsAre(Named("value"))); 2439 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2440 EXPECT_THAT(C, ElementsAre(ReturnType("int"))); 2441 EXPECT_THAT(C, ElementsAre(Signature(""))); 2442 EXPECT_THAT(C, ElementsAre(SnippetSuffix(""))); 2443 } 2444 2445 TEST(CompletionTest, ObjectiveCMethodOneArgument) { 2446 auto Results = completions(R"objc( 2447 @interface Foo 2448 - (int)valueForCharacter:(char)c; 2449 @end 2450 Foo *foo = [Foo new]; int y = [foo v^] 2451 )objc", 2452 /*IndexSymbols=*/{}, 2453 /*Opts=*/{}, "Foo.m"); 2454 2455 auto C = Results.Completions; 2456 EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:"))); 2457 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2458 EXPECT_THAT(C, ElementsAre(ReturnType("int"))); 2459 EXPECT_THAT(C, ElementsAre(Signature("(char)"))); 2460 EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(char)}"))); 2461 } 2462 2463 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) { 2464 auto Results = completions(R"objc( 2465 @interface Foo 2466 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 2467 @end 2468 id val = [Foo foo^] 2469 )objc", 2470 /*IndexSymbols=*/{}, 2471 /*Opts=*/{}, "Foo.m"); 2472 2473 auto C = Results.Completions; 2474 EXPECT_THAT(C, ElementsAre(Named("fooWithValue:"))); 2475 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2476 EXPECT_THAT(C, ElementsAre(ReturnType("id"))); 2477 EXPECT_THAT(C, ElementsAre(Signature("(int) fooey:(unsigned int)"))); 2478 EXPECT_THAT( 2479 C, ElementsAre(SnippetSuffix("${1:(int)} fooey:${2:(unsigned int)}"))); 2480 } 2481 2482 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) { 2483 auto Results = completions(R"objc( 2484 @interface Foo 2485 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 2486 @end 2487 id val = [Foo fooWithValue:10 f^] 2488 )objc", 2489 /*IndexSymbols=*/{}, 2490 /*Opts=*/{}, "Foo.m"); 2491 2492 auto C = Results.Completions; 2493 EXPECT_THAT(C, ElementsAre(Named("fooey:"))); 2494 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2495 EXPECT_THAT(C, ElementsAre(ReturnType("id"))); 2496 EXPECT_THAT(C, ElementsAre(Signature("(unsigned int)"))); 2497 EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}"))); 2498 } 2499 2500 TEST(CompletionTest, CursorInSnippets) { 2501 clangd::CodeCompleteOptions Options; 2502 Options.EnableSnippets = true; 2503 auto Results = completions( 2504 R"cpp( 2505 void while_foo(int a, int b); 2506 void test() { 2507 whil^ 2508 })cpp", 2509 /*IndexSymbols=*/{}, Options); 2510 2511 // Last placeholder in code patterns should be $0 to put the cursor there. 2512 EXPECT_THAT(Results.Completions, 2513 Contains(AllOf( 2514 Named("while"), 2515 SnippetSuffix(" (${1:condition}) {\n${0:statements}\n}")))); 2516 // However, snippets for functions must *not* end with $0. 2517 EXPECT_THAT(Results.Completions, 2518 Contains(AllOf(Named("while_foo"), 2519 SnippetSuffix("(${1:int a}, ${2:int b})")))); 2520 } 2521 2522 TEST(CompletionTest, WorksWithNullType) { 2523 auto R = completions(R"cpp( 2524 int main() { 2525 for (auto [loopVar] : y ) { // y has to be unresolved. 2526 int z = loopV^; 2527 } 2528 } 2529 )cpp"); 2530 EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar"))); 2531 } 2532 2533 TEST(CompletionTest, UsingDecl) { 2534 const char *Header(R"cpp( 2535 void foo(int); 2536 namespace std { 2537 using ::foo; 2538 })cpp"); 2539 const char *Source(R"cpp( 2540 void bar() { 2541 std::^; 2542 })cpp"); 2543 auto Index = TestTU::withHeaderCode(Header).index(); 2544 clangd::CodeCompleteOptions Opts; 2545 Opts.Index = Index.get(); 2546 Opts.AllScopes = true; 2547 auto R = completions(Source, {}, Opts); 2548 EXPECT_THAT(R.Completions, 2549 ElementsAre(AllOf(Scope("std::"), Named("foo"), 2550 Kind(CompletionItemKind::Reference)))); 2551 } 2552 2553 TEST(CompletionTest, ScopeIsUnresolved) { 2554 clangd::CodeCompleteOptions Opts = {}; 2555 Opts.AllScopes = true; 2556 2557 auto Results = completions(R"cpp( 2558 namespace a { 2559 void f() { b::X^ } 2560 } 2561 )cpp", 2562 {cls("a::b::XYZ")}, Opts); 2563 EXPECT_THAT(Results.Completions, 2564 UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); 2565 } 2566 2567 TEST(CompletionTest, NestedScopeIsUnresolved) { 2568 clangd::CodeCompleteOptions Opts = {}; 2569 Opts.AllScopes = true; 2570 2571 auto Results = completions(R"cpp( 2572 namespace a { 2573 namespace b {} 2574 void f() { b::c::X^ } 2575 } 2576 )cpp", 2577 {cls("a::b::c::XYZ")}, Opts); 2578 EXPECT_THAT(Results.Completions, 2579 UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); 2580 } 2581 2582 // Clang parser gets confused here and doesn't report the ns:: prefix. 2583 // Naive behavior is to insert it again. We examine the source and recover. 2584 TEST(CompletionTest, NamespaceDoubleInsertion) { 2585 clangd::CodeCompleteOptions Opts = {}; 2586 2587 auto Results = completions(R"cpp( 2588 namespace foo { 2589 namespace ns {} 2590 #define M(X) < X 2591 M(ns::ABC^ 2592 } 2593 )cpp", 2594 {cls("foo::ns::ABCDE")}, Opts); 2595 EXPECT_THAT(Results.Completions, 2596 UnorderedElementsAre(AllOf(Qualifier(""), Named("ABCDE")))); 2597 } 2598 2599 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) { 2600 // Despite the fact that base method matches the ref-qualifier better, 2601 // completion results should only include the derived method. 2602 auto Completions = completions(R"cpp( 2603 struct deque_base { 2604 float size(); 2605 double size() const; 2606 }; 2607 struct deque : deque_base { 2608 int size() const; 2609 }; 2610 2611 auto x = deque().^ 2612 )cpp") 2613 .Completions; 2614 EXPECT_THAT(Completions, 2615 ElementsAre(AllOf(ReturnType("int"), Named("size")))); 2616 } 2617 2618 TEST(NoCompileCompletionTest, Basic) { 2619 auto Results = completionsNoCompile(R"cpp( 2620 void func() { 2621 int xyz; 2622 int abc; 2623 ^ 2624 } 2625 )cpp"); 2626 EXPECT_FALSE(Results.RanParser); 2627 EXPECT_THAT(Results.Completions, 2628 UnorderedElementsAre(Named("void"), Named("func"), Named("int"), 2629 Named("xyz"), Named("abc"))); 2630 } 2631 2632 TEST(NoCompileCompletionTest, WithFilter) { 2633 auto Results = completionsNoCompile(R"cpp( 2634 void func() { 2635 int sym1; 2636 int sym2; 2637 int xyz1; 2638 int xyz2; 2639 sy^ 2640 } 2641 )cpp"); 2642 EXPECT_THAT(Results.Completions, 2643 UnorderedElementsAre(Named("sym1"), Named("sym2"))); 2644 } 2645 2646 TEST(NoCompileCompletionTest, WithIndex) { 2647 std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"), 2648 func("c::xxx"), func("ns::d::xxx")}; 2649 auto Results = completionsNoCompile( 2650 R"cpp( 2651 // Current-scopes, unqualified completion. 2652 using namespace a; 2653 namespace ns { 2654 using namespace b; 2655 void foo() { 2656 xx^ 2657 } 2658 } 2659 )cpp", 2660 Syms); 2661 EXPECT_THAT(Results.Completions, 2662 UnorderedElementsAre(AllOf(Qualifier(""), Scope("")), 2663 AllOf(Qualifier(""), Scope("a::")), 2664 AllOf(Qualifier(""), Scope("ns::b::")))); 2665 CodeCompleteOptions Opts; 2666 Opts.AllScopes = true; 2667 Results = completionsNoCompile( 2668 R"cpp( 2669 // All-scopes unqualified completion. 2670 using namespace a; 2671 namespace ns { 2672 using namespace b; 2673 void foo() { 2674 xx^ 2675 } 2676 } 2677 )cpp", 2678 Syms, Opts); 2679 EXPECT_THAT(Results.Completions, 2680 UnorderedElementsAre(AllOf(Qualifier(""), Scope("")), 2681 AllOf(Qualifier(""), Scope("a::")), 2682 AllOf(Qualifier(""), Scope("ns::b::")), 2683 AllOf(Qualifier("c::"), Scope("c::")), 2684 AllOf(Qualifier("d::"), Scope("ns::d::")))); 2685 Results = completionsNoCompile( 2686 R"cpp( 2687 // Qualified completion. 2688 using namespace a; 2689 namespace ns { 2690 using namespace b; 2691 void foo() { 2692 b::xx^ 2693 } 2694 } 2695 )cpp", 2696 Syms, Opts); 2697 EXPECT_THAT(Results.Completions, 2698 ElementsAre(AllOf(Qualifier(""), Scope("ns::b::")))); 2699 Results = completionsNoCompile( 2700 R"cpp( 2701 // Absolutely qualified completion. 2702 using namespace a; 2703 namespace ns { 2704 using namespace b; 2705 void foo() { 2706 ::a::xx^ 2707 } 2708 } 2709 )cpp", 2710 Syms, Opts); 2711 EXPECT_THAT(Results.Completions, 2712 ElementsAre(AllOf(Qualifier(""), Scope("a::")))); 2713 } 2714 2715 } // namespace 2716 } // namespace clangd 2717 } // namespace clang 2718