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