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