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