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