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