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