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, Constructors) { 1287 std::string Top = R"cpp( 1288 struct S { 1289 S(int); 1290 S(const S &) = delete; 1291 }; 1292 )cpp"; 1293 1294 auto CheckParenInit = [&](std::string Init) { 1295 EXPECT_THAT(signatures(Top + Init).signatures, 1296 UnorderedElementsAre(sig("S([[int]])"))) 1297 << Init; 1298 }; 1299 CheckParenInit("S s(^);"); 1300 CheckParenInit("auto s = S(^);"); 1301 CheckParenInit("auto s = new S(^);"); 1302 1303 auto CheckBracedInit = [&](std::string Init) { 1304 EXPECT_THAT(signatures(Top + Init).signatures, 1305 UnorderedElementsAre(sig("S{[[int]]}"))) 1306 << Init; 1307 }; 1308 CheckBracedInit("S s{^};"); 1309 CheckBracedInit("S s = {^};"); 1310 CheckBracedInit("auto s = S{^};"); 1311 // FIXME: doesn't work: no ExpectedType set in ParseCXXNewExpression. 1312 // CheckBracedInit("auto s = new S{^};"); 1313 CheckBracedInit("int x(S); int i = x({^});"); 1314 } 1315 1316 TEST(SignatureHelpTest, Aggregates) { 1317 std::string Top = R"cpp( 1318 struct S { 1319 int a, b, c, d; 1320 }; 1321 )cpp"; 1322 auto AggregateSig = sig("S{[[int a]], [[int b]], [[int c]], [[int d]]}"); 1323 EXPECT_THAT(signatures(Top + "S s{^}").signatures, 1324 UnorderedElementsAre(AggregateSig, sig("S{}"), 1325 sig("S{[[const S &]]}"), 1326 sig("S{[[S &&]]}"))); 1327 EXPECT_THAT(signatures(Top + "S s{1,^}").signatures, 1328 ElementsAre(AggregateSig)); 1329 EXPECT_EQ(signatures(Top + "S s{1,^}").activeParameter, 1); 1330 EXPECT_THAT(signatures(Top + "S s{.c=3,^}").signatures, 1331 ElementsAre(AggregateSig)); 1332 EXPECT_EQ(signatures(Top + "S s{.c=3,^}").activeParameter, 3); 1333 } 1334 1335 TEST(SignatureHelpTest, OverloadInitListRegression) { 1336 auto Results = signatures(R"cpp( 1337 struct A {int x;}; 1338 struct B {B(A);}; 1339 void f(); 1340 int main() { 1341 B b({1}); 1342 f(^); 1343 } 1344 )cpp"); 1345 EXPECT_THAT(Results.signatures, UnorderedElementsAre(sig("f() -> void"))); 1346 } 1347 1348 TEST(SignatureHelpTest, DefaultArgs) { 1349 auto Results = signatures(R"cpp( 1350 void bar(int x, int y = 0); 1351 void bar(float x = 0, int y = 42); 1352 int main() { bar(^ 1353 )cpp"); 1354 EXPECT_THAT(Results.signatures, 1355 UnorderedElementsAre( 1356 sig("bar([[int x]], [[int y = 0]]) -> void"), 1357 sig("bar([[float x = 0]], [[int y = 42]]) -> void"))); 1358 EXPECT_EQ(0, Results.activeSignature); 1359 EXPECT_EQ(0, Results.activeParameter); 1360 } 1361 1362 TEST(SignatureHelpTest, ActiveArg) { 1363 auto Results = signatures(R"cpp( 1364 int baz(int a, int b, int c); 1365 int main() { baz(baz(1,2,3), ^); } 1366 )cpp"); 1367 EXPECT_THAT(Results.signatures, 1368 ElementsAre(sig("baz([[int a]], [[int b]], [[int c]]) -> int"))); 1369 EXPECT_EQ(0, Results.activeSignature); 1370 EXPECT_EQ(1, Results.activeParameter); 1371 } 1372 1373 TEST(SignatureHelpTest, OpeningParen) { 1374 llvm::StringLiteral Tests[] = { 1375 // Recursive function call. 1376 R"cpp( 1377 int foo(int a, int b, int c); 1378 int main() { 1379 foo(foo $p^( foo(10, 10, 10), ^ ))); 1380 })cpp", 1381 // Functional type cast. 1382 R"cpp( 1383 struct Foo { 1384 Foo(int a, int b, int c); 1385 }; 1386 int main() { 1387 Foo $p^( 10, ^ ); 1388 })cpp", 1389 // New expression. 1390 R"cpp( 1391 struct Foo { 1392 Foo(int a, int b, int c); 1393 }; 1394 int main() { 1395 new Foo $p^( 10, ^ ); 1396 })cpp", 1397 // Macro expansion. 1398 R"cpp( 1399 int foo(int a, int b, int c); 1400 #define FOO foo( 1401 1402 int main() { 1403 // Macro expansions. 1404 $p^FOO 10, ^ ); 1405 })cpp", 1406 // Macro arguments. 1407 R"cpp( 1408 int foo(int a, int b, int c); 1409 int main() { 1410 #define ID(X) X 1411 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving 1412 // the recovery expression. 1413 ID(foo $p^( 10, ^ )) 1414 })cpp", 1415 // Dependent args. 1416 R"cpp( 1417 int foo(int a, int b); 1418 template <typename T> void bar(T t) { 1419 foo$p^(t, ^t); 1420 })cpp", 1421 // Dependent args on templated func. 1422 R"cpp( 1423 template <typename T> 1424 int foo(T, T); 1425 template <typename T> void bar(T t) { 1426 foo$p^(t, ^t); 1427 })cpp", 1428 // Dependent args on member. 1429 R"cpp( 1430 struct Foo { int foo(int, int); }; 1431 template <typename T> void bar(T t) { 1432 Foo f; 1433 f.foo$p^(t, ^t); 1434 })cpp", 1435 // Dependent args on templated member. 1436 R"cpp( 1437 struct Foo { template <typename T> int foo(T, T); }; 1438 template <typename T> void bar(T t) { 1439 Foo f; 1440 f.foo$p^(t, ^t); 1441 })cpp", 1442 }; 1443 1444 for (auto Test : Tests) { 1445 Annotations Code(Test); 1446 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart, 1447 Code.point("p")) 1448 << "Test source:" << Test; 1449 } 1450 } 1451 1452 TEST(SignatureHelpTest, StalePreamble) { 1453 TestTU TU; 1454 TU.Code = ""; 1455 IgnoreDiagnostics Diags; 1456 MockFS FS; 1457 auto Inputs = TU.inputs(FS); 1458 auto CI = buildCompilerInvocation(Inputs, Diags); 1459 ASSERT_TRUE(CI); 1460 auto EmptyPreamble = buildPreamble(testPath(TU.Filename), *CI, Inputs, 1461 /*InMemory=*/true, /*Callback=*/nullptr); 1462 ASSERT_TRUE(EmptyPreamble); 1463 1464 TU.AdditionalFiles["a.h"] = "int foo(int x);"; 1465 const Annotations Test(R"cpp( 1466 #include "a.h" 1467 void bar() { foo(^2); })cpp"); 1468 TU.Code = Test.code().str(); 1469 auto Results = 1470 signatureHelp(testPath(TU.Filename), Test.point(), *EmptyPreamble, 1471 TU.inputs(FS), MarkupKind::PlainText); 1472 EXPECT_THAT(Results.signatures, ElementsAre(sig("foo([[int x]]) -> int"))); 1473 EXPECT_EQ(0, Results.activeSignature); 1474 EXPECT_EQ(0, Results.activeParameter); 1475 } 1476 1477 class IndexRequestCollector : public SymbolIndex { 1478 public: 1479 bool 1480 fuzzyFind(const FuzzyFindRequest &Req, 1481 llvm::function_ref<void(const Symbol &)> Callback) const override { 1482 std::unique_lock<std::mutex> Lock(Mut); 1483 Requests.push_back(Req); 1484 ReceivedRequestCV.notify_one(); 1485 return true; 1486 } 1487 1488 void lookup(const LookupRequest &, 1489 llvm::function_ref<void(const Symbol &)>) const override {} 1490 1491 bool refs(const RefsRequest &, 1492 llvm::function_ref<void(const Ref &)>) const override { 1493 return false; 1494 } 1495 1496 void relations(const RelationsRequest &, 1497 llvm::function_ref<void(const SymbolID &, const Symbol &)>) 1498 const override {} 1499 1500 llvm::unique_function<IndexContents(llvm::StringRef) const> 1501 indexedFiles() const override { 1502 return [](llvm::StringRef) { return IndexContents::None; }; 1503 } 1504 1505 // This is incorrect, but IndexRequestCollector is not an actual index and it 1506 // isn't used in production code. 1507 size_t estimateMemoryUsage() const override { return 0; } 1508 1509 const std::vector<FuzzyFindRequest> consumeRequests(size_t Num) const { 1510 std::unique_lock<std::mutex> Lock(Mut); 1511 EXPECT_TRUE(wait(Lock, ReceivedRequestCV, timeoutSeconds(30), 1512 [this, Num] { return Requests.size() == Num; })); 1513 auto Reqs = std::move(Requests); 1514 Requests = {}; 1515 return Reqs; 1516 } 1517 1518 private: 1519 // We need a mutex to handle async fuzzy find requests. 1520 mutable std::condition_variable ReceivedRequestCV; 1521 mutable std::mutex Mut; 1522 mutable std::vector<FuzzyFindRequest> Requests; 1523 }; 1524 1525 // Clients have to consume exactly Num requests. 1526 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code, 1527 size_t Num = 1) { 1528 clangd::CodeCompleteOptions Opts; 1529 IndexRequestCollector Requests; 1530 Opts.Index = &Requests; 1531 completions(Code, {}, Opts); 1532 const auto Reqs = Requests.consumeRequests(Num); 1533 EXPECT_EQ(Reqs.size(), Num); 1534 return Reqs; 1535 } 1536 1537 TEST(CompletionTest, UnqualifiedIdQuery) { 1538 auto Requests = captureIndexRequests(R"cpp( 1539 namespace std {} 1540 using namespace std; 1541 namespace ns { 1542 void f() { 1543 vec^ 1544 } 1545 } 1546 )cpp"); 1547 1548 EXPECT_THAT(Requests, 1549 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1550 UnorderedElementsAre("", "ns::", "std::")))); 1551 } 1552 1553 TEST(CompletionTest, EnclosingScopeComesFirst) { 1554 auto Requests = captureIndexRequests(R"cpp( 1555 namespace std {} 1556 using namespace std; 1557 namespace nx { 1558 namespace ns { 1559 namespace { 1560 void f() { 1561 vec^ 1562 } 1563 } 1564 } 1565 } 1566 )cpp"); 1567 1568 EXPECT_THAT(Requests, 1569 ElementsAre(Field( 1570 &FuzzyFindRequest::Scopes, 1571 UnorderedElementsAre("", "std::", "nx::ns::", "nx::")))); 1572 EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::"); 1573 } 1574 1575 TEST(CompletionTest, ResolvedQualifiedIdQuery) { 1576 auto Requests = captureIndexRequests(R"cpp( 1577 namespace ns1 {} 1578 namespace ns2 {} // ignore 1579 namespace ns3 { namespace nns3 {} } 1580 namespace foo { 1581 using namespace ns1; 1582 using namespace ns3::nns3; 1583 } 1584 namespace ns { 1585 void f() { 1586 foo::^ 1587 } 1588 } 1589 )cpp"); 1590 1591 EXPECT_THAT(Requests, 1592 ElementsAre(Field( 1593 &FuzzyFindRequest::Scopes, 1594 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::")))); 1595 } 1596 1597 TEST(CompletionTest, UnresolvedQualifierIdQuery) { 1598 auto Requests = captureIndexRequests(R"cpp( 1599 namespace a {} 1600 using namespace a; 1601 namespace ns { 1602 void f() { 1603 bar::^ 1604 } 1605 } // namespace ns 1606 )cpp"); 1607 1608 EXPECT_THAT(Requests, 1609 ElementsAre(Field( 1610 &FuzzyFindRequest::Scopes, 1611 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::")))); 1612 } 1613 1614 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) { 1615 auto Requests = captureIndexRequests(R"cpp( 1616 namespace a {} 1617 using namespace a; 1618 namespace ns { 1619 void f() { 1620 ::a::bar::^ 1621 } 1622 } // namespace ns 1623 )cpp"); 1624 1625 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1626 UnorderedElementsAre("a::bar::")))); 1627 } 1628 1629 TEST(CompletionTest, EmptyQualifiedQuery) { 1630 auto Requests = captureIndexRequests(R"cpp( 1631 namespace ns { 1632 void f() { 1633 ^ 1634 } 1635 } // namespace ns 1636 )cpp"); 1637 1638 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1639 UnorderedElementsAre("", "ns::")))); 1640 } 1641 1642 TEST(CompletionTest, GlobalQualifiedQuery) { 1643 auto Requests = captureIndexRequests(R"cpp( 1644 namespace ns { 1645 void f() { 1646 ::^ 1647 } 1648 } // namespace ns 1649 )cpp"); 1650 1651 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1652 UnorderedElementsAre("")))); 1653 } 1654 1655 TEST(CompletionTest, NoDuplicatedQueryScopes) { 1656 auto Requests = captureIndexRequests(R"cpp( 1657 namespace {} 1658 1659 namespace na { 1660 namespace {} 1661 namespace nb { 1662 ^ 1663 } // namespace nb 1664 } // namespace na 1665 )cpp"); 1666 1667 EXPECT_THAT(Requests, 1668 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1669 UnorderedElementsAre("na::", "na::nb::", "")))); 1670 } 1671 1672 TEST(CompletionTest, NoIndexCompletionsInsideClasses) { 1673 auto Completions = completions( 1674 R"cpp( 1675 struct Foo { 1676 int SomeNameOfField; 1677 typedef int SomeNameOfTypedefField; 1678 }; 1679 1680 Foo::^)cpp", 1681 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")}); 1682 1683 EXPECT_THAT(Completions.Completions, 1684 AllOf(Contains(labeled("SomeNameOfField")), 1685 Contains(labeled("SomeNameOfTypedefField")), 1686 Not(Contains(labeled("SomeNameInTheIndex"))))); 1687 } 1688 1689 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) { 1690 { 1691 auto Completions = completions( 1692 R"cpp( 1693 template <class T> 1694 void foo() { 1695 T::^ 1696 } 1697 )cpp", 1698 {func("::SomeNameInTheIndex")}); 1699 1700 EXPECT_THAT(Completions.Completions, 1701 Not(Contains(labeled("SomeNameInTheIndex")))); 1702 } 1703 1704 { 1705 auto Completions = completions( 1706 R"cpp( 1707 template <class T> 1708 void foo() { 1709 T::template Y<int>::^ 1710 } 1711 )cpp", 1712 {func("::SomeNameInTheIndex")}); 1713 1714 EXPECT_THAT(Completions.Completions, 1715 Not(Contains(labeled("SomeNameInTheIndex")))); 1716 } 1717 1718 { 1719 auto Completions = completions( 1720 R"cpp( 1721 template <class T> 1722 void foo() { 1723 T::foo::^ 1724 } 1725 )cpp", 1726 {func("::SomeNameInTheIndex")}); 1727 1728 EXPECT_THAT(Completions.Completions, 1729 Not(Contains(labeled("SomeNameInTheIndex")))); 1730 } 1731 } 1732 1733 TEST(CompletionTest, OverloadBundling) { 1734 clangd::CodeCompleteOptions Opts; 1735 Opts.BundleOverloads = true; 1736 1737 std::string Context = R"cpp( 1738 struct X { 1739 // Overload with int 1740 int a(int) __attribute__((deprecated("", ""))); 1741 // Overload with bool 1742 int a(bool); 1743 int b(float); 1744 1745 X(int); 1746 X(float); 1747 }; 1748 int GFuncC(int); 1749 int GFuncD(int); 1750 )cpp"; 1751 1752 // Member completions are bundled. 1753 EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions, 1754 UnorderedElementsAre(labeled("a(…)"), labeled("b(float)"))); 1755 1756 // Constructor completions are bundled. 1757 EXPECT_THAT(completions(Context + "X z = X^", {}, Opts).Completions, 1758 UnorderedElementsAre(labeled("X"), labeled("X(…)"))); 1759 1760 // Non-member completions are bundled, including index+sema. 1761 Symbol NoArgsGFunc = func("GFuncC"); 1762 EXPECT_THAT( 1763 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1764 UnorderedElementsAre(labeled("GFuncC(…)"), labeled("GFuncD(int)"))); 1765 1766 // Differences in header-to-insert suppress bundling. 1767 std::string DeclFile = URI::create(testPath("foo")).toString(); 1768 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str(); 1769 NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1); 1770 EXPECT_THAT( 1771 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1772 UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")), 1773 labeled("GFuncC(int)"), labeled("GFuncD(int)"))); 1774 1775 // Examine a bundled completion in detail. 1776 auto A = 1777 completions(Context + "int y = X().a^", {}, Opts).Completions.front(); 1778 EXPECT_EQ(A.Name, "a"); 1779 EXPECT_EQ(A.Signature, "(…)"); 1780 EXPECT_EQ(A.BundleSize, 2u); 1781 EXPECT_EQ(A.Kind, CompletionItemKind::Method); 1782 EXPECT_EQ(A.ReturnType, "int"); // All overloads return int. 1783 // For now we just return one of the doc strings arbitrarily. 1784 ASSERT_TRUE(A.Documentation); 1785 ASSERT_FALSE(A.Deprecated); // Not all overloads deprecated. 1786 EXPECT_THAT( 1787 A.Documentation->asPlainText(), 1788 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool"))); 1789 EXPECT_EQ(A.SnippetSuffix, "($0)"); 1790 } 1791 1792 TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) { 1793 clangd::CodeCompleteOptions Opts; 1794 Opts.BundleOverloads = true; 1795 1796 Symbol SymX = sym("ns::X", index::SymbolKind::Function, "@F@\\0#"); 1797 Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#"); 1798 std::string BarHeader = testPath("bar.h"); 1799 auto BarURI = URI::create(BarHeader).toString(); 1800 SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); 1801 SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); 1802 // The include header is different, but really it's the same file. 1803 SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1); 1804 SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1); 1805 1806 auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts); 1807 // Expect both results are bundled, despite the different-but-same 1808 // IncludeHeader. 1809 ASSERT_EQ(1u, Results.Completions.size()); 1810 const auto &R = Results.Completions.front(); 1811 EXPECT_EQ("X", R.Name); 1812 EXPECT_EQ(2u, R.BundleSize); 1813 } 1814 1815 TEST(CompletionTest, DocumentationFromChangedFileCrash) { 1816 MockFS FS; 1817 auto FooH = testPath("foo.h"); 1818 auto FooCpp = testPath("foo.cpp"); 1819 FS.Files[FooH] = R"cpp( 1820 // this is my documentation comment. 1821 int func(); 1822 )cpp"; 1823 FS.Files[FooCpp] = ""; 1824 1825 MockCompilationDatabase CDB; 1826 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 1827 1828 Annotations Source(R"cpp( 1829 #include "foo.h" 1830 int func() { 1831 // This makes sure we have func from header in the AST. 1832 } 1833 int a = fun^ 1834 )cpp"); 1835 Server.addDocument(FooCpp, Source.code(), "null", WantDiagnostics::Yes); 1836 // We need to wait for preamble to build. 1837 ASSERT_TRUE(Server.blockUntilIdleForTest()); 1838 1839 // Change the header file. Completion will reuse the old preamble! 1840 FS.Files[FooH] = R"cpp( 1841 int func(); 1842 )cpp"; 1843 1844 clangd::CodeCompleteOptions Opts; 1845 CodeCompleteResult Completions = 1846 cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts)); 1847 // We shouldn't crash. Unfortunately, current workaround is to not produce 1848 // comments for symbols from headers. 1849 EXPECT_THAT(Completions.Completions, 1850 Contains(AllOf(Not(isDocumented()), named("func")))); 1851 } 1852 1853 TEST(CompletionTest, NonDocComments) { 1854 const char *Text = R"cpp( 1855 // We ignore namespace comments, for rationale see CodeCompletionStrings.h. 1856 namespace comments_ns { 1857 } 1858 1859 // ------------------ 1860 int comments_foo(); 1861 1862 // A comment and a decl are separated by newlines. 1863 // Therefore, the comment shouldn't show up as doc comment. 1864 1865 int comments_bar(); 1866 1867 // this comment should be in the results. 1868 int comments_baz(); 1869 1870 1871 template <class T> 1872 struct Struct { 1873 int comments_qux(); 1874 int comments_quux(); 1875 }; 1876 1877 1878 // This comment should not be there. 1879 1880 template <class T> 1881 int Struct<T>::comments_qux() { 1882 } 1883 1884 // This comment **should** be in results. 1885 template <class T> 1886 int Struct<T>::comments_quux() { 1887 int a = comments^; 1888 } 1889 )cpp"; 1890 1891 // We should not get any of those comments in completion. 1892 EXPECT_THAT( 1893 completions(Text).Completions, 1894 UnorderedElementsAre(AllOf(Not(isDocumented()), named("comments_foo")), 1895 AllOf(isDocumented(), named("comments_baz")), 1896 AllOf(isDocumented(), named("comments_quux")), 1897 AllOf(Not(isDocumented()), named("comments_ns")), 1898 // FIXME(ibiryukov): the following items should have 1899 // empty documentation, since they are separated from 1900 // a comment with an empty line. Unfortunately, I 1901 // couldn't make Sema tests pass if we ignore those. 1902 AllOf(isDocumented(), named("comments_bar")), 1903 AllOf(isDocumented(), named("comments_qux")))); 1904 } 1905 1906 TEST(CompletionTest, CompleteOnInvalidLine) { 1907 auto FooCpp = testPath("foo.cpp"); 1908 1909 MockCompilationDatabase CDB; 1910 MockFS FS; 1911 FS.Files[FooCpp] = "// empty file"; 1912 1913 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 1914 // Run completion outside the file range. 1915 Position Pos; 1916 Pos.line = 100; 1917 Pos.character = 0; 1918 EXPECT_THAT_EXPECTED( 1919 runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()), 1920 Failed()); 1921 } 1922 1923 TEST(CompletionTest, QualifiedNames) { 1924 auto Results = completions( 1925 R"cpp( 1926 namespace ns { int local; void both(); } 1927 void f() { ::ns::^ } 1928 )cpp", 1929 {func("ns::both"), cls("ns::Index")}); 1930 // We get results from both index and sema, with no duplicates. 1931 EXPECT_THAT( 1932 Results.Completions, 1933 UnorderedElementsAre(scope("ns::"), scope("ns::"), scope("ns::"))); 1934 } 1935 1936 TEST(CompletionTest, Render) { 1937 CodeCompletion C; 1938 C.Name = "x"; 1939 C.FilterText = "x"; 1940 C.Signature = "(bool) const"; 1941 C.SnippetSuffix = "(${0:bool})"; 1942 C.ReturnType = "int"; 1943 C.RequiredQualifier = "Foo::"; 1944 C.Scope = "ns::Foo::"; 1945 C.Documentation.emplace(); 1946 C.Documentation->addParagraph().appendText("This is ").appendCode("x()"); 1947 C.Includes.emplace_back(); 1948 auto &Include = C.Includes.back(); 1949 Include.Header = "\"foo.h\""; 1950 C.Kind = CompletionItemKind::Method; 1951 C.Score.Total = 1.0; 1952 C.Score.ExcludingName = .5; 1953 C.Origin = SymbolOrigin::AST | SymbolOrigin::Static; 1954 1955 CodeCompleteOptions Opts; 1956 Opts.IncludeIndicator.Insert = "^"; 1957 Opts.IncludeIndicator.NoInsert = ""; 1958 Opts.EnableSnippets = false; 1959 1960 auto R = C.render(Opts); 1961 EXPECT_EQ(R.label, "Foo::x(bool) const"); 1962 EXPECT_EQ(R.insertText, "Foo::x"); 1963 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText); 1964 EXPECT_EQ(R.filterText, "x"); 1965 EXPECT_EQ(R.detail, "int"); 1966 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()"); 1967 EXPECT_THAT(R.additionalTextEdits, IsEmpty()); 1968 EXPECT_EQ(R.sortText, sortText(1.0, "x")); 1969 EXPECT_FALSE(R.deprecated); 1970 EXPECT_EQ(R.score, .5f); 1971 1972 C.FilterText = "xtra"; 1973 R = C.render(Opts); 1974 EXPECT_EQ(R.filterText, "xtra"); 1975 EXPECT_EQ(R.sortText, sortText(1.0, "xtra")); 1976 1977 Opts.EnableSnippets = true; 1978 R = C.render(Opts); 1979 EXPECT_EQ(R.insertText, "Foo::x(${0:bool})"); 1980 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet); 1981 1982 C.SnippetSuffix = ""; 1983 R = C.render(Opts); 1984 EXPECT_EQ(R.insertText, "Foo::x"); 1985 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText); 1986 1987 Include.Insertion.emplace(); 1988 R = C.render(Opts); 1989 EXPECT_EQ(R.label, "^Foo::x(bool) const"); 1990 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty())); 1991 1992 Opts.ShowOrigins = true; 1993 R = C.render(Opts); 1994 EXPECT_EQ(R.label, "^[AS]Foo::x(bool) const"); 1995 1996 C.BundleSize = 2; 1997 R = C.render(Opts); 1998 EXPECT_EQ(R.detail, "[2 overloads]"); 1999 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()"); 2000 2001 C.Deprecated = true; 2002 R = C.render(Opts); 2003 EXPECT_TRUE(R.deprecated); 2004 2005 Opts.DocumentationFormat = MarkupKind::Markdown; 2006 R = C.render(Opts); 2007 EXPECT_EQ(R.documentation->value, "From `\"foo.h\"` \nThis is `x()`"); 2008 } 2009 2010 TEST(CompletionTest, IgnoreRecoveryResults) { 2011 auto Results = completions( 2012 R"cpp( 2013 namespace ns { int NotRecovered() { return 0; } } 2014 void f() { 2015 // Sema enters recovery mode first and then normal mode. 2016 if (auto x = ns::NotRecover^) 2017 } 2018 )cpp"); 2019 EXPECT_THAT(Results.Completions, UnorderedElementsAre(named("NotRecovered"))); 2020 } 2021 2022 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) { 2023 auto Results = completions( 2024 R"cpp( 2025 namespace ns { 2026 class X { public: X(); int x_; }; 2027 X::X() : x_^(0) {} 2028 } 2029 )cpp"); 2030 EXPECT_THAT(Results.Completions, 2031 UnorderedElementsAre(AllOf(scope("ns::X::"), named("x_")))); 2032 } 2033 2034 // Like other class members, constructor init lists have to parse what's below, 2035 // after the completion point. 2036 // But recovering from an incomplete constructor init list is particularly 2037 // tricky because the bulk of the list is not surrounded by brackets. 2038 TEST(CompletionTest, ConstructorInitListIncomplete) { 2039 auto Results = completions( 2040 R"cpp( 2041 namespace ns { 2042 struct X { 2043 X() : x^ 2044 int xyz_; 2045 }; 2046 } 2047 )cpp"); 2048 EXPECT_THAT(Results.Completions, ElementsAre(named("xyz_"))); 2049 2050 Results = completions( 2051 R"cpp( 2052 int foo(); 2053 2054 namespace ns { 2055 struct X { 2056 X() : xyz_(fo^ 2057 int xyz_; 2058 }; 2059 } 2060 )cpp"); 2061 EXPECT_THAT(Results.Completions, ElementsAre(named("foo"))); 2062 } 2063 2064 TEST(CompletionTest, CodeCompletionContext) { 2065 auto Results = completions( 2066 R"cpp( 2067 namespace ns { 2068 class X { public: X(); int x_; }; 2069 void f() { 2070 X x; 2071 x.^; 2072 } 2073 } 2074 )cpp"); 2075 2076 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess); 2077 } 2078 2079 TEST(CompletionTest, FixItForArrowToDot) { 2080 MockFS FS; 2081 MockCompilationDatabase CDB; 2082 2083 CodeCompleteOptions Opts; 2084 Opts.IncludeFixIts = true; 2085 const char *Code = 2086 R"cpp( 2087 class Auxilary { 2088 public: 2089 void AuxFunction(); 2090 }; 2091 class ClassWithPtr { 2092 public: 2093 void MemberFunction(); 2094 Auxilary* operator->() const; 2095 Auxilary* Aux; 2096 }; 2097 void f() { 2098 ClassWithPtr x; 2099 x[[->]]^; 2100 } 2101 )cpp"; 2102 auto Results = completions(Code, {}, Opts); 2103 EXPECT_EQ(Results.Completions.size(), 3u); 2104 2105 TextEdit ReplacementEdit; 2106 ReplacementEdit.range = Annotations(Code).range(); 2107 ReplacementEdit.newText = "."; 2108 for (const auto &C : Results.Completions) { 2109 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction"); 2110 if (!C.FixIts.empty()) { 2111 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 2112 } 2113 } 2114 } 2115 2116 TEST(CompletionTest, FixItForDotToArrow) { 2117 CodeCompleteOptions Opts; 2118 Opts.IncludeFixIts = true; 2119 const char *Code = 2120 R"cpp( 2121 class Auxilary { 2122 public: 2123 void AuxFunction(); 2124 }; 2125 class ClassWithPtr { 2126 public: 2127 void MemberFunction(); 2128 Auxilary* operator->() const; 2129 Auxilary* Aux; 2130 }; 2131 void f() { 2132 ClassWithPtr x; 2133 x[[.]]^; 2134 } 2135 )cpp"; 2136 auto Results = completions(Code, {}, Opts); 2137 EXPECT_EQ(Results.Completions.size(), 3u); 2138 2139 TextEdit ReplacementEdit; 2140 ReplacementEdit.range = Annotations(Code).range(); 2141 ReplacementEdit.newText = "->"; 2142 for (const auto &C : Results.Completions) { 2143 EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction"); 2144 if (!C.FixIts.empty()) { 2145 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 2146 } 2147 } 2148 } 2149 2150 TEST(CompletionTest, RenderWithFixItMerged) { 2151 TextEdit FixIt; 2152 FixIt.range.end.character = 5; 2153 FixIt.newText = "->"; 2154 2155 CodeCompletion C; 2156 C.Name = "x"; 2157 C.RequiredQualifier = "Foo::"; 2158 C.FixIts = {FixIt}; 2159 C.CompletionTokenRange.start.character = 5; 2160 2161 CodeCompleteOptions Opts; 2162 Opts.IncludeFixIts = true; 2163 2164 auto R = C.render(Opts); 2165 EXPECT_TRUE(R.textEdit); 2166 EXPECT_EQ(R.textEdit->newText, "->Foo::x"); 2167 EXPECT_TRUE(R.additionalTextEdits.empty()); 2168 } 2169 2170 TEST(CompletionTest, RenderWithFixItNonMerged) { 2171 TextEdit FixIt; 2172 FixIt.range.end.character = 4; 2173 FixIt.newText = "->"; 2174 2175 CodeCompletion C; 2176 C.Name = "x"; 2177 C.RequiredQualifier = "Foo::"; 2178 C.FixIts = {FixIt}; 2179 C.CompletionTokenRange.start.character = 5; 2180 2181 CodeCompleteOptions Opts; 2182 Opts.IncludeFixIts = true; 2183 2184 auto R = C.render(Opts); 2185 EXPECT_TRUE(R.textEdit); 2186 EXPECT_EQ(R.textEdit->newText, "Foo::x"); 2187 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt)); 2188 } 2189 2190 TEST(CompletionTest, CompletionTokenRange) { 2191 MockFS FS; 2192 MockCompilationDatabase CDB; 2193 TestTU TU; 2194 TU.AdditionalFiles["foo/abc/foo.h"] = ""; 2195 2196 constexpr const char *TestCodes[] = { 2197 R"cpp( 2198 class Auxilary { 2199 public: 2200 void AuxFunction(); 2201 }; 2202 void f() { 2203 Auxilary x; 2204 x.[[Aux]]^; 2205 } 2206 )cpp", 2207 R"cpp( 2208 class Auxilary { 2209 public: 2210 void AuxFunction(); 2211 }; 2212 void f() { 2213 Auxilary x; 2214 x.[[]]^; 2215 } 2216 )cpp", 2217 R"cpp( 2218 #include "foo/[[a^/]]foo.h" 2219 )cpp", 2220 R"cpp( 2221 #include "foo/abc/[[fo^o.h"]] 2222 )cpp", 2223 }; 2224 for (const auto &Text : TestCodes) { 2225 Annotations TestCode(Text); 2226 TU.Code = TestCode.code().str(); 2227 auto Results = completions(TU, TestCode.point()); 2228 if (Results.Completions.size() != 1) { 2229 ADD_FAILURE() << "Results.Completions.size() != 1" << Text; 2230 continue; 2231 } 2232 EXPECT_THAT(Results.Completions.front().CompletionTokenRange, 2233 TestCode.range()); 2234 } 2235 } 2236 2237 TEST(SignatureHelpTest, OverloadsOrdering) { 2238 const auto Results = signatures(R"cpp( 2239 void foo(int x); 2240 void foo(int x, float y); 2241 void foo(float x, int y); 2242 void foo(float x, float y); 2243 void foo(int x, int y = 0); 2244 int main() { foo(^); } 2245 )cpp"); 2246 EXPECT_THAT(Results.signatures, 2247 ElementsAre(sig("foo([[int x]]) -> void"), 2248 sig("foo([[int x]], [[int y = 0]]) -> void"), 2249 sig("foo([[float x]], [[int y]]) -> void"), 2250 sig("foo([[int x]], [[float y]]) -> void"), 2251 sig("foo([[float x]], [[float y]]) -> void"))); 2252 // We always prefer the first signature. 2253 EXPECT_EQ(0, Results.activeSignature); 2254 EXPECT_EQ(0, Results.activeParameter); 2255 } 2256 2257 TEST(SignatureHelpTest, InstantiatedSignatures) { 2258 StringRef Sig0 = R"cpp( 2259 template <class T> 2260 void foo(T, T, T); 2261 2262 int main() { 2263 foo<int>(^); 2264 } 2265 )cpp"; 2266 2267 EXPECT_THAT(signatures(Sig0).signatures, 2268 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void"))); 2269 2270 StringRef Sig1 = R"cpp( 2271 template <class T> 2272 void foo(T, T, T); 2273 2274 int main() { 2275 foo(10, ^); 2276 })cpp"; 2277 2278 EXPECT_THAT(signatures(Sig1).signatures, 2279 ElementsAre(sig("foo([[T]], [[T]], [[T]]) -> void"))); 2280 2281 StringRef Sig2 = R"cpp( 2282 template <class ...T> 2283 void foo(T...); 2284 2285 int main() { 2286 foo<int>(^); 2287 } 2288 )cpp"; 2289 2290 EXPECT_THAT(signatures(Sig2).signatures, 2291 ElementsAre(sig("foo([[T...]]) -> void"))); 2292 2293 // It is debatable whether we should substitute the outer template parameter 2294 // ('T') in that case. Currently we don't substitute it in signature help, but 2295 // do substitute in code complete. 2296 // FIXME: make code complete and signature help consistent, figure out which 2297 // way is better. 2298 StringRef Sig3 = R"cpp( 2299 template <class T> 2300 struct X { 2301 template <class U> 2302 void foo(T, U); 2303 }; 2304 2305 int main() { 2306 X<int>().foo<double>(^) 2307 } 2308 )cpp"; 2309 2310 EXPECT_THAT(signatures(Sig3).signatures, 2311 ElementsAre(sig("foo([[T]], [[U]]) -> void"))); 2312 } 2313 2314 TEST(SignatureHelpTest, IndexDocumentation) { 2315 Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#"); 2316 Foo0.Documentation = "doc from the index"; 2317 Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#"); 2318 Foo1.Documentation = "doc from the index"; 2319 Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#"); 2320 2321 StringRef Sig0 = R"cpp( 2322 int foo(); 2323 int foo(double); 2324 2325 void test() { 2326 foo(^); 2327 } 2328 )cpp"; 2329 2330 EXPECT_THAT( 2331 signatures(Sig0, {Foo0}).signatures, 2332 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("doc from the index")), 2333 AllOf(sig("foo([[double]]) -> int"), sigDoc("")))); 2334 2335 StringRef Sig1 = R"cpp( 2336 int foo(); 2337 // Overriden doc from sema 2338 int foo(int); 2339 // doc from sema 2340 int foo(int, int); 2341 2342 void test() { 2343 foo(^); 2344 } 2345 )cpp"; 2346 2347 EXPECT_THAT( 2348 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures, 2349 ElementsAre( 2350 AllOf(sig("foo() -> int"), sigDoc("doc from the index")), 2351 AllOf(sig("foo([[int]]) -> int"), sigDoc("Overriden doc from sema")), 2352 AllOf(sig("foo([[int]], [[int]]) -> int"), sigDoc("doc from sema")))); 2353 } 2354 2355 TEST(SignatureHelpTest, DynamicIndexDocumentation) { 2356 MockFS FS; 2357 MockCompilationDatabase CDB; 2358 ClangdServer::Options Opts = ClangdServer::optsForTest(); 2359 Opts.BuildDynamicSymbolIndex = true; 2360 ClangdServer Server(CDB, FS, Opts); 2361 2362 FS.Files[testPath("foo.h")] = R"cpp( 2363 struct Foo { 2364 // Member doc 2365 int foo(); 2366 }; 2367 )cpp"; 2368 Annotations FileContent(R"cpp( 2369 #include "foo.h" 2370 void test() { 2371 Foo f; 2372 f.foo(^); 2373 } 2374 )cpp"); 2375 auto File = testPath("test.cpp"); 2376 Server.addDocument(File, FileContent.code()); 2377 // Wait for the dynamic index being built. 2378 ASSERT_TRUE(Server.blockUntilIdleForTest()); 2379 EXPECT_THAT(llvm::cantFail(runSignatureHelp(Server, File, FileContent.point(), 2380 MarkupKind::PlainText)) 2381 .signatures, 2382 ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc")))); 2383 } 2384 2385 TEST(CompletionTest, CompletionFunctionArgsDisabled) { 2386 CodeCompleteOptions Opts; 2387 Opts.EnableSnippets = true; 2388 Opts.EnableFunctionArgSnippets = false; 2389 2390 { 2391 auto Results = completions( 2392 R"cpp( 2393 void xfoo(); 2394 void xfoo(int x, int y); 2395 void f() { xfo^ })cpp", 2396 {}, Opts); 2397 EXPECT_THAT( 2398 Results.Completions, 2399 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("()")), 2400 AllOf(named("xfoo"), snippetSuffix("($0)")))); 2401 } 2402 { 2403 auto Results = completions( 2404 R"cpp( 2405 void xbar(); 2406 void f() { xba^ })cpp", 2407 {}, Opts); 2408 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf( 2409 named("xbar"), snippetSuffix("()")))); 2410 } 2411 { 2412 Opts.BundleOverloads = true; 2413 auto Results = completions( 2414 R"cpp( 2415 void xfoo(); 2416 void xfoo(int x, int y); 2417 void f() { xfo^ })cpp", 2418 {}, Opts); 2419 EXPECT_THAT( 2420 Results.Completions, 2421 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("($0)")))); 2422 } 2423 { 2424 auto Results = completions( 2425 R"cpp( 2426 template <class T, class U> 2427 void xfoo(int a, U b); 2428 void f() { xfo^ })cpp", 2429 {}, Opts); 2430 EXPECT_THAT( 2431 Results.Completions, 2432 UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("<$1>($0)")))); 2433 } 2434 { 2435 auto Results = completions( 2436 R"cpp( 2437 template <class T> 2438 class foo_class{}; 2439 template <class T> 2440 using foo_alias = T**; 2441 void f() { foo_^ })cpp", 2442 {}, Opts); 2443 EXPECT_THAT( 2444 Results.Completions, 2445 UnorderedElementsAre(AllOf(named("foo_class"), snippetSuffix("<$0>")), 2446 AllOf(named("foo_alias"), snippetSuffix("<$0>")))); 2447 } 2448 { 2449 auto Results = completions( 2450 R"cpp( 2451 #define FOO(x, y) x##f 2452 FO^ )cpp", 2453 {}, Opts); 2454 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf( 2455 named("FOO"), snippetSuffix("($0)")))); 2456 } 2457 } 2458 2459 TEST(CompletionTest, SuggestOverrides) { 2460 constexpr const char *const Text(R"cpp( 2461 class A { 2462 public: 2463 virtual void vfunc(bool param); 2464 virtual void vfunc(bool param, int p); 2465 void func(bool param); 2466 }; 2467 class B : public A { 2468 virtual void ttt(bool param) const; 2469 void vfunc(bool param, int p) override; 2470 }; 2471 class C : public B { 2472 public: 2473 void vfunc(bool param) override; 2474 ^ 2475 }; 2476 )cpp"); 2477 const auto Results = completions(Text); 2478 EXPECT_THAT( 2479 Results.Completions, 2480 AllOf(Contains(AllOf(labeled("void vfunc(bool param, int p) override"), 2481 nameStartsWith("vfunc"))), 2482 Contains(AllOf(labeled("void ttt(bool param) const override"), 2483 nameStartsWith("ttt"))), 2484 Not(Contains(labeled("void vfunc(bool param) override"))))); 2485 } 2486 2487 TEST(CompletionTest, OverridesNonIdentName) { 2488 // Check the completions call does not crash. 2489 completions(R"cpp( 2490 struct Base { 2491 virtual ~Base() = 0; 2492 virtual operator int() = 0; 2493 virtual Base& operator+(Base&) = 0; 2494 }; 2495 2496 struct Derived : Base { 2497 ^ 2498 }; 2499 )cpp"); 2500 } 2501 2502 TEST(CompletionTest, NoCrashOnMissingNewLineAtEOF) { 2503 auto FooCpp = testPath("foo.cpp"); 2504 2505 MockCompilationDatabase CDB; 2506 MockFS FS; 2507 Annotations F("#pragma ^ // no new line"); 2508 FS.Files[FooCpp] = F.code().str(); 2509 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 2510 runAddDocument(Server, FooCpp, F.code()); 2511 // Run completion outside the file range. 2512 EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, F.point(), 2513 clangd::CodeCompleteOptions())) 2514 .Completions, 2515 IsEmpty()); 2516 EXPECT_THAT(cantFail(runSignatureHelp(Server, FooCpp, F.point(), 2517 MarkupKind::PlainText)) 2518 .signatures, 2519 IsEmpty()); 2520 } 2521 2522 TEST(GuessCompletionPrefix, Filters) { 2523 for (llvm::StringRef Case : { 2524 "[[scope::]][[ident]]^", 2525 "[[]][[]]^", 2526 "\n[[]][[]]^", 2527 "[[]][[ab]]^", 2528 "x.[[]][[ab]]^", 2529 "x.[[]][[]]^", 2530 "[[x::]][[ab]]^", 2531 "[[x::]][[]]^", 2532 "[[::x::]][[ab]]^", 2533 "some text [[scope::more::]][[identif]]^ier", 2534 "some text [[scope::]][[mor]]^e::identifier", 2535 "weird case foo::[[::bar::]][[baz]]^", 2536 "/* [[]][[]]^ */", 2537 }) { 2538 Annotations F(Case); 2539 auto Offset = cantFail(positionToOffset(F.code(), F.point())); 2540 auto ToStringRef = [&](Range R) { 2541 return F.code().slice(cantFail(positionToOffset(F.code(), R.start)), 2542 cantFail(positionToOffset(F.code(), R.end))); 2543 }; 2544 auto WantQualifier = ToStringRef(F.ranges()[0]), 2545 WantName = ToStringRef(F.ranges()[1]); 2546 2547 auto Prefix = guessCompletionPrefix(F.code(), Offset); 2548 // Even when components are empty, check their offsets are correct. 2549 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case; 2550 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case; 2551 EXPECT_EQ(WantName, Prefix.Name) << Case; 2552 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case; 2553 } 2554 } 2555 2556 TEST(CompletionTest, EnableSpeculativeIndexRequest) { 2557 MockFS FS; 2558 MockCompilationDatabase CDB; 2559 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 2560 2561 auto File = testPath("foo.cpp"); 2562 Annotations Test(R"cpp( 2563 namespace ns1 { int abc; } 2564 namespace ns2 { int abc; } 2565 void f() { ns1::ab$1^; ns1::ab$2^; } 2566 void f2() { ns2::ab$3^; } 2567 )cpp"); 2568 runAddDocument(Server, File, Test.code()); 2569 clangd::CodeCompleteOptions Opts = {}; 2570 2571 IndexRequestCollector Requests; 2572 Opts.Index = &Requests; 2573 2574 auto CompleteAtPoint = [&](StringRef P) { 2575 cantFail(runCodeComplete(Server, File, Test.point(P), Opts)); 2576 }; 2577 2578 CompleteAtPoint("1"); 2579 auto Reqs1 = Requests.consumeRequests(1); 2580 ASSERT_EQ(Reqs1.size(), 1u); 2581 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::")); 2582 2583 CompleteAtPoint("2"); 2584 auto Reqs2 = Requests.consumeRequests(1); 2585 // Speculation succeeded. Used speculative index result. 2586 ASSERT_EQ(Reqs2.size(), 1u); 2587 EXPECT_EQ(Reqs2[0], Reqs1[0]); 2588 2589 CompleteAtPoint("3"); 2590 // Speculation failed. Sent speculative index request and the new index 2591 // request after sema. 2592 auto Reqs3 = Requests.consumeRequests(2); 2593 ASSERT_EQ(Reqs3.size(), 2u); 2594 } 2595 2596 TEST(CompletionTest, InsertTheMostPopularHeader) { 2597 std::string DeclFile = URI::create(testPath("foo")).toString(); 2598 Symbol Sym = func("Func"); 2599 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2600 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2601 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2602 2603 auto Results = completions("Fun^", {Sym}).Completions; 2604 assert(!Results.empty()); 2605 EXPECT_THAT(Results[0], AllOf(named("Func"), insertInclude("\"bar.h\""))); 2606 EXPECT_EQ(Results[0].Includes.size(), 2u); 2607 } 2608 2609 TEST(CompletionTest, NoInsertIncludeIfOnePresent) { 2610 Annotations Test(R"cpp( 2611 #include "foo.h" 2612 Fun^ 2613 )cpp"); 2614 auto TU = TestTU::withCode(Test.code()); 2615 TU.AdditionalFiles["foo.h"] = ""; 2616 2617 std::string DeclFile = URI::create(testPath("foo")).toString(); 2618 Symbol Sym = func("Func"); 2619 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2620 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2621 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2622 2623 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions, 2624 UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""), 2625 Not(insertInclude())))); 2626 } 2627 2628 TEST(CompletionTest, MergeMacrosFromIndexAndSema) { 2629 Symbol Sym; 2630 Sym.Name = "Clangd_Macro_Test"; 2631 Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test"); 2632 Sym.SymInfo.Kind = index::SymbolKind::Macro; 2633 Sym.Flags |= Symbol::IndexedForCodeCompletion; 2634 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym}) 2635 .Completions, 2636 UnorderedElementsAre(named("Clangd_Macro_Test"))); 2637 } 2638 2639 TEST(CompletionTest, MacroFromPreamble) { 2640 Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x 2641 2642 int x = 0; 2643 #define CLANGD_MAIN x 2644 void f() { CLANGD_^ } 2645 )cpp"); 2646 auto TU = TestTU::withCode(Test.code()); 2647 TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x"; 2648 auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")}); 2649 // We should get results from the main file, including the preamble section. 2650 // However no results from included files (the index should cover them). 2651 EXPECT_THAT(Results.Completions, 2652 UnorderedElementsAre(named("CLANGD_PREAMBLE_MAIN"), 2653 named("CLANGD_MAIN"), 2654 named("CLANGD_INDEX"))); 2655 } 2656 2657 TEST(CompletionTest, DeprecatedResults) { 2658 std::string Body = R"cpp( 2659 void TestClangd(); 2660 void TestClangc() __attribute__((deprecated("", ""))); 2661 )cpp"; 2662 2663 EXPECT_THAT( 2664 completions(Body + "int main() { TestClang^ }").Completions, 2665 UnorderedElementsAre(AllOf(named("TestClangd"), Not(deprecated())), 2666 AllOf(named("TestClangc"), deprecated()))); 2667 } 2668 2669 TEST(SignatureHelpTest, PartialSpec) { 2670 const auto Results = signatures(R"cpp( 2671 template <typename T> struct Foo {}; 2672 template <typename T> struct Foo<T*> { Foo(T); }; 2673 Foo<int*> F(^);)cpp"); 2674 EXPECT_THAT(Results.signatures, Contains(sig("Foo([[T]])"))); 2675 EXPECT_EQ(0, Results.activeParameter); 2676 } 2677 2678 TEST(SignatureHelpTest, InsideArgument) { 2679 { 2680 const auto Results = signatures(R"cpp( 2681 void foo(int x); 2682 void foo(int x, int y); 2683 int main() { foo(1+^); } 2684 )cpp"); 2685 EXPECT_THAT(Results.signatures, 2686 ElementsAre(sig("foo([[int x]]) -> void"), 2687 sig("foo([[int x]], [[int y]]) -> void"))); 2688 EXPECT_EQ(0, Results.activeParameter); 2689 } 2690 { 2691 const auto Results = signatures(R"cpp( 2692 void foo(int x); 2693 void foo(int x, int y); 2694 int main() { foo(1^); } 2695 )cpp"); 2696 EXPECT_THAT(Results.signatures, 2697 ElementsAre(sig("foo([[int x]]) -> void"), 2698 sig("foo([[int x]], [[int y]]) -> void"))); 2699 EXPECT_EQ(0, Results.activeParameter); 2700 } 2701 { 2702 const auto Results = signatures(R"cpp( 2703 void foo(int x); 2704 void foo(int x, int y); 2705 int main() { foo(1^0); } 2706 )cpp"); 2707 EXPECT_THAT(Results.signatures, 2708 ElementsAre(sig("foo([[int x]]) -> void"), 2709 sig("foo([[int x]], [[int y]]) -> void"))); 2710 EXPECT_EQ(0, Results.activeParameter); 2711 } 2712 { 2713 const auto Results = signatures(R"cpp( 2714 void foo(int x); 2715 void foo(int x, int y); 2716 int bar(int x, int y); 2717 int main() { bar(foo(2, 3^)); } 2718 )cpp"); 2719 EXPECT_THAT(Results.signatures, 2720 ElementsAre(sig("foo([[int x]], [[int y]]) -> void"))); 2721 EXPECT_EQ(1, Results.activeParameter); 2722 } 2723 } 2724 2725 TEST(SignatureHelpTest, ConstructorInitializeFields) { 2726 { 2727 const auto Results = signatures(R"cpp( 2728 struct A { A(int); }; 2729 struct B { 2730 B() : a_elem(^) {} 2731 A a_elem; 2732 }; 2733 )cpp"); 2734 EXPECT_THAT(Results.signatures, 2735 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"), 2736 sig("A([[const A &]])"))); 2737 } 2738 { 2739 const auto Results = signatures(R"cpp( 2740 struct A { A(int); }; 2741 struct B { 2742 B() : a_elem(^ 2743 A a_elem; 2744 }; 2745 )cpp"); 2746 // FIXME: currently the parser skips over the decl of a_elem as part of the 2747 // (broken) init list, so we don't get signatures for the first member. 2748 EXPECT_THAT(Results.signatures, IsEmpty()); 2749 } 2750 { 2751 const auto Results = signatures(R"cpp( 2752 struct A { A(int); }; 2753 struct B { 2754 B() : a_elem(^ 2755 int dummy_elem; 2756 A a_elem; 2757 }; 2758 )cpp"); 2759 EXPECT_THAT(Results.signatures, 2760 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"), 2761 sig("A([[const A &]])"))); 2762 } 2763 { 2764 const auto Results = signatures(R"cpp( 2765 struct A { 2766 A(int); 2767 }; 2768 struct C { 2769 C(int); 2770 C(A); 2771 }; 2772 struct B { 2773 B() : c_elem(A(1^)) {} 2774 C c_elem; 2775 }; 2776 )cpp"); 2777 EXPECT_THAT(Results.signatures, 2778 UnorderedElementsAre(sig("A([[int]])"), sig("A([[A &&]])"), 2779 sig("A([[const A &]])"))); 2780 } 2781 } 2782 2783 TEST(SignatureHelpTest, Variadic) { 2784 const std::string Header = R"cpp( 2785 void fun(int x, ...) {} 2786 void test() {)cpp"; 2787 const std::string ExpectedSig = "fun([[int x]], [[...]]) -> void"; 2788 2789 { 2790 const auto Result = signatures(Header + "fun(^);}"); 2791 EXPECT_EQ(0, Result.activeParameter); 2792 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2793 } 2794 { 2795 const auto Result = signatures(Header + "fun(1, ^);}"); 2796 EXPECT_EQ(1, Result.activeParameter); 2797 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2798 } 2799 { 2800 const auto Result = signatures(Header + "fun(1, 2, ^);}"); 2801 EXPECT_EQ(1, Result.activeParameter); 2802 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2803 } 2804 } 2805 2806 TEST(SignatureHelpTest, VariadicTemplate) { 2807 const std::string Header = R"cpp( 2808 template<typename T, typename ...Args> 2809 void fun(T t, Args ...args) {} 2810 void test() {)cpp"; 2811 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void"; 2812 2813 { 2814 const auto Result = signatures(Header + "fun(^);}"); 2815 EXPECT_EQ(0, Result.activeParameter); 2816 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2817 } 2818 { 2819 const auto Result = signatures(Header + "fun(1, ^);}"); 2820 EXPECT_EQ(1, Result.activeParameter); 2821 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2822 } 2823 { 2824 const auto Result = signatures(Header + "fun(1, 2, ^);}"); 2825 EXPECT_EQ(1, Result.activeParameter); 2826 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2827 } 2828 } 2829 2830 TEST(SignatureHelpTest, VariadicMethod) { 2831 const std::string Header = R"cpp( 2832 class C { 2833 template<typename T, typename ...Args> 2834 void fun(T t, Args ...args) {} 2835 }; 2836 void test() {C c; )cpp"; 2837 const std::string ExpectedSig = "fun([[T t]], [[Args args...]]) -> void"; 2838 2839 { 2840 const auto Result = signatures(Header + "c.fun(^);}"); 2841 EXPECT_EQ(0, Result.activeParameter); 2842 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2843 } 2844 { 2845 const auto Result = signatures(Header + "c.fun(1, ^);}"); 2846 EXPECT_EQ(1, Result.activeParameter); 2847 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2848 } 2849 { 2850 const auto Result = signatures(Header + "c.fun(1, 2, ^);}"); 2851 EXPECT_EQ(1, Result.activeParameter); 2852 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2853 } 2854 } 2855 2856 TEST(SignatureHelpTest, VariadicType) { 2857 const std::string Header = R"cpp( 2858 void fun(int x, ...) {} 2859 auto get_fun() { return fun; } 2860 void test() { 2861 )cpp"; 2862 const std::string ExpectedSig = "([[int]], [[...]]) -> void"; 2863 2864 { 2865 const auto Result = signatures(Header + "get_fun()(^);}"); 2866 EXPECT_EQ(0, Result.activeParameter); 2867 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2868 } 2869 { 2870 const auto Result = signatures(Header + "get_fun()(1, ^);}"); 2871 EXPECT_EQ(1, Result.activeParameter); 2872 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2873 } 2874 { 2875 const auto Result = signatures(Header + "get_fun()(1, 2, ^);}"); 2876 EXPECT_EQ(1, Result.activeParameter); 2877 EXPECT_THAT(Result.signatures, UnorderedElementsAre(sig(ExpectedSig))); 2878 } 2879 } 2880 2881 TEST(CompletionTest, IncludedCompletionKinds) { 2882 Annotations Test(R"cpp(#include "^)cpp"); 2883 auto TU = TestTU::withCode(Test.code()); 2884 TU.AdditionalFiles["sub/bar.h"] = ""; 2885 TU.ExtraArgs.push_back("-I" + testPath("sub")); 2886 2887 auto Results = completions(TU, Test.point()); 2888 EXPECT_THAT(Results.Completions, 2889 AllOf(has("sub/", CompletionItemKind::Folder), 2890 has("bar.h\"", CompletionItemKind::File))); 2891 } 2892 2893 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) { 2894 completions( 2895 R"cpp( 2896 #include "./^" 2897 )cpp"); 2898 } 2899 2900 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) { 2901 clangd::CodeCompleteOptions Opts = {}; 2902 Opts.AllScopes = true; 2903 2904 auto Results = completions( 2905 R"cpp( 2906 void f() { na::Clangd^ } 2907 )cpp", 2908 {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts); 2909 EXPECT_THAT(Results.Completions, 2910 UnorderedElementsAre( 2911 AllOf(qualifier(""), scope("na::"), named("ClangdA")))); 2912 } 2913 2914 TEST(CompletionTest, AllScopesCompletion) { 2915 clangd::CodeCompleteOptions Opts = {}; 2916 Opts.AllScopes = true; 2917 2918 auto Results = completions( 2919 R"cpp( 2920 namespace na { 2921 void f() { Clangd^ } 2922 } 2923 )cpp", 2924 {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"), 2925 cls("na::nb::Clangd4")}, 2926 Opts); 2927 EXPECT_THAT( 2928 Results.Completions, 2929 UnorderedElementsAre(AllOf(qualifier("nx::"), named("Clangd1")), 2930 AllOf(qualifier("ny::"), named("Clangd2")), 2931 AllOf(qualifier(""), scope(""), named("Clangd3")), 2932 AllOf(qualifier("nb::"), named("Clangd4")))); 2933 } 2934 2935 TEST(CompletionTest, NoQualifierIfShadowed) { 2936 clangd::CodeCompleteOptions Opts = {}; 2937 Opts.AllScopes = true; 2938 2939 auto Results = completions(R"cpp( 2940 namespace nx { class Clangd1 {}; } 2941 using nx::Clangd1; 2942 void f() { Clangd^ } 2943 )cpp", 2944 {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts); 2945 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and 2946 // needs no qualifier. 2947 EXPECT_THAT(Results.Completions, 2948 UnorderedElementsAre(AllOf(qualifier(""), named("Clangd1")), 2949 AllOf(qualifier("nx::"), named("Clangd2")))); 2950 } 2951 2952 TEST(CompletionTest, NoCompletionsForNewNames) { 2953 clangd::CodeCompleteOptions Opts; 2954 Opts.AllScopes = true; 2955 auto Results = completions(R"cpp( 2956 void f() { int n^ } 2957 )cpp", 2958 {cls("naber"), cls("nx::naber")}, Opts); 2959 EXPECT_THAT(Results.Completions, UnorderedElementsAre()); 2960 } 2961 2962 TEST(CompletionTest, Lambda) { 2963 clangd::CodeCompleteOptions Opts = {}; 2964 2965 auto Results = completions(R"cpp( 2966 void function() { 2967 auto Lambda = [](int a, const double &b) {return 1.f;}; 2968 Lam^ 2969 } 2970 )cpp", 2971 {}, Opts); 2972 2973 ASSERT_EQ(Results.Completions.size(), 1u); 2974 const auto &A = Results.Completions.front(); 2975 EXPECT_EQ(A.Name, "Lambda"); 2976 EXPECT_EQ(A.Signature, "(int a, const double &b) const"); 2977 EXPECT_EQ(A.Kind, CompletionItemKind::Variable); 2978 EXPECT_EQ(A.ReturnType, "float"); 2979 EXPECT_EQ(A.SnippetSuffix, "(${1:int a}, ${2:const double &b})"); 2980 } 2981 2982 TEST(CompletionTest, StructuredBinding) { 2983 clangd::CodeCompleteOptions Opts = {}; 2984 2985 auto Results = completions(R"cpp( 2986 struct S { 2987 using Float = float; 2988 int x; 2989 Float y; 2990 }; 2991 void function() { 2992 const auto &[xxx, yyy] = S{}; 2993 yyy^ 2994 } 2995 )cpp", 2996 {}, Opts); 2997 2998 ASSERT_EQ(Results.Completions.size(), 1u); 2999 const auto &A = Results.Completions.front(); 3000 EXPECT_EQ(A.Name, "yyy"); 3001 EXPECT_EQ(A.Kind, CompletionItemKind::Variable); 3002 EXPECT_EQ(A.ReturnType, "const Float"); 3003 } 3004 3005 TEST(CompletionTest, ObjectiveCMethodNoArguments) { 3006 auto Results = completions(R"objc( 3007 @interface Foo 3008 @property(nonatomic, setter=setXToIgnoreComplete:) int value; 3009 @end 3010 Foo *foo = [Foo new]; int y = [foo v^] 3011 )objc", 3012 /*IndexSymbols=*/{}, 3013 /*Opts=*/{}, "Foo.m"); 3014 3015 auto C = Results.Completions; 3016 EXPECT_THAT(C, ElementsAre(named("value"))); 3017 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3018 EXPECT_THAT(C, ElementsAre(returnType("int"))); 3019 EXPECT_THAT(C, ElementsAre(signature(""))); 3020 EXPECT_THAT(C, ElementsAre(snippetSuffix(""))); 3021 } 3022 3023 TEST(CompletionTest, ObjectiveCMethodOneArgument) { 3024 auto Results = completions(R"objc( 3025 @interface Foo 3026 - (int)valueForCharacter:(char)c; 3027 @end 3028 Foo *foo = [Foo new]; int y = [foo v^] 3029 )objc", 3030 /*IndexSymbols=*/{}, 3031 /*Opts=*/{}, "Foo.m"); 3032 3033 auto C = Results.Completions; 3034 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:"))); 3035 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3036 EXPECT_THAT(C, ElementsAre(returnType("int"))); 3037 EXPECT_THAT(C, ElementsAre(signature("(char)"))); 3038 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(char)}"))); 3039 } 3040 3041 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) { 3042 auto Results = completions(R"objc( 3043 @interface Foo 3044 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 3045 @end 3046 id val = [Foo foo^] 3047 )objc", 3048 /*IndexSymbols=*/{}, 3049 /*Opts=*/{}, "Foo.m"); 3050 3051 auto C = Results.Completions; 3052 EXPECT_THAT(C, ElementsAre(named("fooWithValue:"))); 3053 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3054 EXPECT_THAT(C, ElementsAre(returnType("id"))); 3055 EXPECT_THAT(C, ElementsAre(signature("(int) fooey:(unsigned int)"))); 3056 EXPECT_THAT( 3057 C, ElementsAre(snippetSuffix("${1:(int)} fooey:${2:(unsigned int)}"))); 3058 } 3059 3060 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) { 3061 auto Results = completions(R"objc( 3062 @interface Foo 3063 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 3064 @end 3065 id val = [Foo fooWithValue:10 f^] 3066 )objc", 3067 /*IndexSymbols=*/{}, 3068 /*Opts=*/{}, "Foo.m"); 3069 3070 auto C = Results.Completions; 3071 EXPECT_THAT(C, ElementsAre(named("fooey:"))); 3072 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3073 EXPECT_THAT(C, ElementsAre(returnType("id"))); 3074 EXPECT_THAT(C, ElementsAre(signature("(unsigned int)"))); 3075 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(unsigned int)}"))); 3076 } 3077 3078 TEST(CompletionTest, ObjectiveCMethodFilterOnEntireSelector) { 3079 auto Results = completions(R"objc( 3080 @interface Foo 3081 + (id)player:(id)player willRun:(id)run; 3082 @end 3083 id val = [Foo wi^] 3084 )objc", 3085 /*IndexSymbols=*/{}, 3086 /*Opts=*/{}, "Foo.m"); 3087 3088 auto C = Results.Completions; 3089 EXPECT_THAT(C, ElementsAre(named("player:"))); 3090 EXPECT_THAT(C, ElementsAre(filterText("player:willRun:"))); 3091 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3092 EXPECT_THAT(C, ElementsAre(returnType("id"))); 3093 EXPECT_THAT(C, ElementsAre(signature("(id) willRun:(id)"))); 3094 EXPECT_THAT(C, ElementsAre(snippetSuffix("${1:(id)} willRun:${2:(id)}"))); 3095 } 3096 3097 TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) { 3098 auto Results = completions(R"objc( 3099 @interface Foo 3100 - (void)foo; 3101 @end 3102 @implementation Foo 3103 fo^ 3104 @end 3105 )objc", 3106 /*IndexSymbols=*/{}, 3107 /*Opts=*/{}, "Foo.m"); 3108 3109 auto C = Results.Completions; 3110 EXPECT_THAT(C, ElementsAre(named("foo"))); 3111 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3112 EXPECT_THAT(C, ElementsAre(qualifier("- (void)"))); 3113 } 3114 3115 TEST(CompletionTest, ObjectiveCMethodDeclaration) { 3116 auto Results = completions(R"objc( 3117 @interface Foo 3118 - (int)valueForCharacter:(char)c secondArgument:(id)object; 3119 @end 3120 @implementation Foo 3121 valueFor^ 3122 @end 3123 )objc", 3124 /*IndexSymbols=*/{}, 3125 /*Opts=*/{}, "Foo.m"); 3126 3127 auto C = Results.Completions; 3128 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:"))); 3129 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3130 EXPECT_THAT(C, ElementsAre(qualifier("- (int)"))); 3131 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object"))); 3132 } 3133 3134 TEST(CompletionTest, ObjectiveCMethodDeclarationFilterOnEntireSelector) { 3135 auto Results = completions(R"objc( 3136 @interface Foo 3137 - (int)valueForCharacter:(char)c secondArgument:(id)object; 3138 @end 3139 @implementation Foo 3140 secondArg^ 3141 @end 3142 )objc", 3143 /*IndexSymbols=*/{}, 3144 /*Opts=*/{}, "Foo.m"); 3145 3146 auto C = Results.Completions; 3147 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:"))); 3148 EXPECT_THAT(C, ElementsAre(filterText("valueForCharacter:secondArgument:"))); 3149 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3150 EXPECT_THAT(C, ElementsAre(qualifier("- (int)"))); 3151 EXPECT_THAT(C, ElementsAre(signature("(char)c secondArgument:(id)object"))); 3152 } 3153 3154 TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) { 3155 auto Results = completions(R"objc( 3156 @interface Foo 3157 - (int)valueForCharacter:(char)c; 3158 @end 3159 @implementation Foo 3160 - (int)valueFor^ 3161 @end 3162 )objc", 3163 /*IndexSymbols=*/{}, 3164 /*Opts=*/{}, "Foo.m"); 3165 3166 auto C = Results.Completions; 3167 EXPECT_THAT(C, ElementsAre(named("valueForCharacter:"))); 3168 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3169 EXPECT_THAT(C, ElementsAre(signature("(char)c"))); 3170 } 3171 3172 TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) { 3173 auto Results = completions(R"objc( 3174 @interface Foo 3175 - (int)valueForCharacter:(char)c secondArgument:(id)object; 3176 @end 3177 @implementation Foo 3178 - (int)valueForCharacter:(char)c second^ 3179 @end 3180 )objc", 3181 /*IndexSymbols=*/{}, 3182 /*Opts=*/{}, "Foo.m"); 3183 3184 auto C = Results.Completions; 3185 EXPECT_THAT(C, ElementsAre(named("secondArgument:"))); 3186 EXPECT_THAT(C, ElementsAre(kind(CompletionItemKind::Method))); 3187 EXPECT_THAT(C, ElementsAre(signature("(id)object"))); 3188 } 3189 3190 TEST(CompletionTest, ObjectiveCProtocolFromIndex) { 3191 Symbol FoodClass = objcClass("FoodClass"); 3192 Symbol SymFood = objcProtocol("Food"); 3193 Symbol SymFooey = objcProtocol("Fooey"); 3194 auto Results = completions(R"objc( 3195 id<Foo^> 3196 )objc", 3197 {SymFood, FoodClass, SymFooey}, 3198 /*Opts=*/{}, "Foo.m"); 3199 3200 auto C = Results.Completions; 3201 EXPECT_THAT(C, UnorderedElementsAre(named("Food"), named("Fooey"))); 3202 } 3203 3204 TEST(CompletionTest, CursorInSnippets) { 3205 clangd::CodeCompleteOptions Options; 3206 Options.EnableSnippets = true; 3207 auto Results = completions( 3208 R"cpp( 3209 void while_foo(int a, int b); 3210 void test() { 3211 whil^ 3212 })cpp", 3213 /*IndexSymbols=*/{}, Options); 3214 3215 // Last placeholder in code patterns should be $0 to put the cursor there. 3216 EXPECT_THAT(Results.Completions, 3217 Contains(AllOf( 3218 named("while"), 3219 snippetSuffix(" (${1:condition}) {\n${0:statements}\n}")))); 3220 // However, snippets for functions must *not* end with $0. 3221 EXPECT_THAT(Results.Completions, 3222 Contains(AllOf(named("while_foo"), 3223 snippetSuffix("(${1:int a}, ${2:int b})")))); 3224 } 3225 3226 TEST(CompletionTest, WorksWithNullType) { 3227 auto R = completions(R"cpp( 3228 int main() { 3229 for (auto [loopVar] : y ) { // y has to be unresolved. 3230 int z = loopV^; 3231 } 3232 } 3233 )cpp"); 3234 EXPECT_THAT(R.Completions, ElementsAre(named("loopVar"))); 3235 } 3236 3237 TEST(CompletionTest, UsingDecl) { 3238 const char *Header(R"cpp( 3239 void foo(int); 3240 namespace std { 3241 using ::foo; 3242 })cpp"); 3243 const char *Source(R"cpp( 3244 void bar() { 3245 std::^; 3246 })cpp"); 3247 auto Index = TestTU::withHeaderCode(Header).index(); 3248 clangd::CodeCompleteOptions Opts; 3249 Opts.Index = Index.get(); 3250 Opts.AllScopes = true; 3251 auto R = completions(Source, {}, Opts); 3252 EXPECT_THAT(R.Completions, 3253 ElementsAre(AllOf(scope("std::"), named("foo"), 3254 kind(CompletionItemKind::Reference)))); 3255 } 3256 3257 TEST(CompletionTest, ScopeIsUnresolved) { 3258 clangd::CodeCompleteOptions Opts = {}; 3259 Opts.AllScopes = true; 3260 3261 auto Results = completions(R"cpp( 3262 namespace a { 3263 void f() { b::X^ } 3264 } 3265 )cpp", 3266 {cls("a::b::XYZ")}, Opts); 3267 EXPECT_THAT(Results.Completions, 3268 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ")))); 3269 } 3270 3271 TEST(CompletionTest, NestedScopeIsUnresolved) { 3272 clangd::CodeCompleteOptions Opts = {}; 3273 Opts.AllScopes = true; 3274 3275 auto Results = completions(R"cpp( 3276 namespace a { 3277 namespace b {} 3278 void f() { b::c::X^ } 3279 } 3280 )cpp", 3281 {cls("a::b::c::XYZ")}, Opts); 3282 EXPECT_THAT(Results.Completions, 3283 UnorderedElementsAre(AllOf(qualifier(""), named("XYZ")))); 3284 } 3285 3286 // Clang parser gets confused here and doesn't report the ns:: prefix. 3287 // Naive behavior is to insert it again. We examine the source and recover. 3288 TEST(CompletionTest, NamespaceDoubleInsertion) { 3289 clangd::CodeCompleteOptions Opts = {}; 3290 3291 auto Results = completions(R"cpp( 3292 namespace foo { 3293 namespace ns {} 3294 #define M(X) < X 3295 M(ns::ABC^ 3296 } 3297 )cpp", 3298 {cls("foo::ns::ABCDE")}, Opts); 3299 EXPECT_THAT(Results.Completions, 3300 UnorderedElementsAre(AllOf(qualifier(""), named("ABCDE")))); 3301 } 3302 3303 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) { 3304 // Despite the fact that base method matches the ref-qualifier better, 3305 // completion results should only include the derived method. 3306 auto Completions = completions(R"cpp( 3307 struct deque_base { 3308 float size(); 3309 double size() const; 3310 }; 3311 struct deque : deque_base { 3312 int size() const; 3313 }; 3314 3315 auto x = deque().^ 3316 )cpp") 3317 .Completions; 3318 EXPECT_THAT(Completions, 3319 ElementsAre(AllOf(returnType("int"), named("size")))); 3320 } 3321 3322 TEST(CompletionTest, NoCrashWithIncompleteLambda) { 3323 auto Completions = completions("auto&& x = []{^").Completions; 3324 // The completion of x itself can cause a problem: in the code completion 3325 // callback, its type is not known, which affects the linkage calculation. 3326 // A bad linkage value gets cached, and subsequently updated. 3327 EXPECT_THAT(Completions, Contains(named("x"))); 3328 3329 auto Signatures = signatures("auto x() { x(^").signatures; 3330 EXPECT_THAT(Signatures, Contains(sig("x() -> auto"))); 3331 } 3332 3333 TEST(CompletionTest, DelayedTemplateParsing) { 3334 Annotations Test(R"cpp( 3335 int xxx; 3336 template <typename T> int foo() { return xx^; } 3337 )cpp"); 3338 auto TU = TestTU::withCode(Test.code()); 3339 // Even though delayed-template-parsing is on, we will disable it to provide 3340 // completion in templates. 3341 TU.ExtraArgs.push_back("-fdelayed-template-parsing"); 3342 3343 EXPECT_THAT(completions(TU, Test.point()).Completions, 3344 Contains(named("xxx"))); 3345 } 3346 3347 TEST(CompletionTest, CompletionRange) { 3348 const char *WithRange = "auto x = [[abc]]^"; 3349 auto Completions = completions(WithRange); 3350 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range()); 3351 Completions = completionsNoCompile(WithRange); 3352 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range()); 3353 3354 const char *EmptyRange = "auto x = [[]]^"; 3355 Completions = completions(EmptyRange); 3356 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range()); 3357 Completions = completionsNoCompile(EmptyRange); 3358 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range()); 3359 3360 // Sema doesn't trigger at all here, while the no-sema completion runs 3361 // heuristics as normal and reports a range. It'd be nice to be consistent. 3362 const char *NoCompletion = "/* foo [[]]^ */"; 3363 Completions = completions(NoCompletion); 3364 EXPECT_EQ(Completions.CompletionRange, llvm::None); 3365 Completions = completionsNoCompile(NoCompletion); 3366 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range()); 3367 } 3368 3369 TEST(NoCompileCompletionTest, Basic) { 3370 auto Results = completionsNoCompile(R"cpp( 3371 void func() { 3372 int xyz; 3373 int abc; 3374 ^ 3375 } 3376 )cpp"); 3377 EXPECT_FALSE(Results.RanParser); 3378 EXPECT_THAT(Results.Completions, 3379 UnorderedElementsAre(named("void"), named("func"), named("int"), 3380 named("xyz"), named("abc"))); 3381 } 3382 3383 TEST(NoCompileCompletionTest, WithFilter) { 3384 auto Results = completionsNoCompile(R"cpp( 3385 void func() { 3386 int sym1; 3387 int sym2; 3388 int xyz1; 3389 int xyz2; 3390 sy^ 3391 } 3392 )cpp"); 3393 EXPECT_THAT(Results.Completions, 3394 UnorderedElementsAre(named("sym1"), named("sym2"))); 3395 } 3396 3397 TEST(NoCompileCompletionTest, WithIndex) { 3398 std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"), 3399 func("c::xxx"), func("ns::d::xxx")}; 3400 auto Results = completionsNoCompile( 3401 R"cpp( 3402 // Current-scopes, unqualified completion. 3403 using namespace a; 3404 namespace ns { 3405 using namespace b; 3406 void foo() { 3407 xx^ 3408 } 3409 } 3410 )cpp", 3411 Syms); 3412 EXPECT_THAT(Results.Completions, 3413 UnorderedElementsAre(AllOf(qualifier(""), scope("")), 3414 AllOf(qualifier(""), scope("a::")), 3415 AllOf(qualifier(""), scope("ns::b::")))); 3416 CodeCompleteOptions Opts; 3417 Opts.AllScopes = true; 3418 Results = completionsNoCompile( 3419 R"cpp( 3420 // All-scopes unqualified completion. 3421 using namespace a; 3422 namespace ns { 3423 using namespace b; 3424 void foo() { 3425 xx^ 3426 } 3427 } 3428 )cpp", 3429 Syms, Opts); 3430 EXPECT_THAT(Results.Completions, 3431 UnorderedElementsAre(AllOf(qualifier(""), scope("")), 3432 AllOf(qualifier(""), scope("a::")), 3433 AllOf(qualifier(""), scope("ns::b::")), 3434 AllOf(qualifier("c::"), scope("c::")), 3435 AllOf(qualifier("d::"), scope("ns::d::")))); 3436 Results = completionsNoCompile( 3437 R"cpp( 3438 // Qualified completion. 3439 using namespace a; 3440 namespace ns { 3441 using namespace b; 3442 void foo() { 3443 b::xx^ 3444 } 3445 } 3446 )cpp", 3447 Syms, Opts); 3448 EXPECT_THAT(Results.Completions, 3449 ElementsAre(AllOf(qualifier(""), scope("ns::b::")))); 3450 Results = completionsNoCompile( 3451 R"cpp( 3452 // Absolutely qualified completion. 3453 using namespace a; 3454 namespace ns { 3455 using namespace b; 3456 void foo() { 3457 ::a::xx^ 3458 } 3459 } 3460 )cpp", 3461 Syms, Opts); 3462 EXPECT_THAT(Results.Completions, 3463 ElementsAre(AllOf(qualifier(""), scope("a::")))); 3464 } 3465 3466 TEST(AllowImplicitCompletion, All) { 3467 const char *Yes[] = { 3468 "foo.^bar", 3469 "foo->^bar", 3470 "foo::^bar", 3471 " # include <^foo.h>", 3472 "#import <foo/^bar.h>", 3473 "#include_next \"^", 3474 }; 3475 const char *No[] = { 3476 "foo>^bar", 3477 "foo:^bar", 3478 "foo\n^bar", 3479 "#include <foo.h> //^", 3480 "#include \"foo.h\"^", 3481 "#error <^", 3482 "#<^", 3483 }; 3484 for (const char *Test : Yes) { 3485 llvm::Annotations A(Test); 3486 EXPECT_TRUE(allowImplicitCompletion(A.code(), A.point())) << Test; 3487 } 3488 for (const char *Test : No) { 3489 llvm::Annotations A(Test); 3490 EXPECT_FALSE(allowImplicitCompletion(A.code(), A.point())) << Test; 3491 } 3492 } 3493 3494 TEST(CompletionTest, FunctionArgsExist) { 3495 clangd::CodeCompleteOptions Opts; 3496 Opts.EnableSnippets = true; 3497 std::string Context = R"cpp( 3498 #define MACRO(x) 3499 int foo(int A); 3500 int bar(); 3501 struct Object { 3502 Object(int B) {} 3503 }; 3504 template <typename T> 3505 struct Container { 3506 Container(int Size) {} 3507 }; 3508 )cpp"; 3509 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions, 3510 UnorderedElementsAre( 3511 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})")))); 3512 EXPECT_THAT( 3513 completions(Context + "int y = fo^(42)", {}, Opts).Completions, 3514 UnorderedElementsAre(AllOf(labeled("foo(int A)"), snippetSuffix("")))); 3515 // FIXME(kirillbobyrev): No snippet should be produced here. 3516 EXPECT_THAT(completions(Context + "int y = fo^o(42)", {}, Opts).Completions, 3517 UnorderedElementsAre( 3518 AllOf(labeled("foo(int A)"), snippetSuffix("(${1:int A})")))); 3519 EXPECT_THAT( 3520 completions(Context + "int y = ba^", {}, Opts).Completions, 3521 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("()")))); 3522 EXPECT_THAT(completions(Context + "int y = ba^()", {}, Opts).Completions, 3523 UnorderedElementsAre(AllOf(labeled("bar()"), snippetSuffix("")))); 3524 EXPECT_THAT( 3525 completions(Context + "Object o = Obj^", {}, Opts).Completions, 3526 Contains(AllOf(labeled("Object(int B)"), snippetSuffix("(${1:int B})"), 3527 kind(CompletionItemKind::Constructor)))); 3528 EXPECT_THAT(completions(Context + "Object o = Obj^()", {}, Opts).Completions, 3529 Contains(AllOf(labeled("Object(int B)"), snippetSuffix(""), 3530 kind(CompletionItemKind::Constructor)))); 3531 EXPECT_THAT( 3532 completions(Context + "Container c = Cont^", {}, Opts).Completions, 3533 Contains(AllOf(labeled("Container<typename T>(int Size)"), 3534 snippetSuffix("<${1:typename T}>(${2:int Size})"), 3535 kind(CompletionItemKind::Constructor)))); 3536 EXPECT_THAT( 3537 completions(Context + "Container c = Cont^()", {}, Opts).Completions, 3538 Contains(AllOf(labeled("Container<typename T>(int Size)"), 3539 snippetSuffix("<${1:typename T}>"), 3540 kind(CompletionItemKind::Constructor)))); 3541 EXPECT_THAT( 3542 completions(Context + "Container c = Cont^<int>()", {}, Opts).Completions, 3543 Contains(AllOf(labeled("Container<typename T>(int Size)"), 3544 snippetSuffix(""), 3545 kind(CompletionItemKind::Constructor)))); 3546 EXPECT_THAT(completions(Context + "MAC^(2)", {}, Opts).Completions, 3547 Contains(AllOf(labeled("MACRO(x)"), snippetSuffix(""), 3548 kind(CompletionItemKind::Text)))); 3549 } 3550 3551 TEST(CompletionTest, NoCrashDueToMacroOrdering) { 3552 EXPECT_THAT(completions(R"cpp( 3553 #define ECHO(X) X 3554 #define ECHO2(X) ECHO(X) 3555 int finish_preamble = EC^HO(2);)cpp") 3556 .Completions, 3557 UnorderedElementsAre(labeled("ECHO(X)"), labeled("ECHO2(X)"))); 3558 } 3559 3560 TEST(CompletionTest, ObjCCategoryDecls) { 3561 TestTU TU; 3562 TU.ExtraArgs.push_back("-xobjective-c"); 3563 TU.HeaderCode = R"objc( 3564 @interface Foo 3565 @end 3566 3567 @interface Foo (FooExt1) 3568 @end 3569 3570 @interface Foo (FooExt2) 3571 @end 3572 3573 @interface Bar 3574 @end 3575 3576 @interface Bar (BarExt) 3577 @end)objc"; 3578 3579 { 3580 Annotations Test(R"objc( 3581 @implementation Foo (^) 3582 @end 3583 )objc"); 3584 TU.Code = Test.code().str(); 3585 auto Results = completions(TU, Test.point()); 3586 EXPECT_THAT(Results.Completions, 3587 UnorderedElementsAre(labeled("FooExt1"), labeled("FooExt2"))); 3588 } 3589 { 3590 Annotations Test(R"objc( 3591 @interface Foo (^) 3592 @end 3593 )objc"); 3594 TU.Code = Test.code().str(); 3595 auto Results = completions(TU, Test.point()); 3596 EXPECT_THAT(Results.Completions, UnorderedElementsAre(labeled("BarExt"))); 3597 } 3598 } 3599 3600 TEST(CompletionTest, PreambleCodeComplete) { 3601 llvm::StringLiteral Baseline = "\n#define MACRO 12\nint num = MACRO;"; 3602 llvm::StringLiteral ModifiedCC = 3603 "#include \"header.h\"\n#define MACRO 12\nint num = MACRO; int num2 = M^"; 3604 3605 Annotations Test(ModifiedCC); 3606 auto BaselineTU = TestTU::withCode(Baseline); 3607 auto ModifiedTU = TestTU::withCode(Test.code()); 3608 3609 MockFS FS; 3610 auto Inputs = ModifiedTU.inputs(FS); 3611 auto Result = codeComplete(testPath(ModifiedTU.Filename), Test.point(), 3612 BaselineTU.preamble().get(), Inputs, {}); 3613 EXPECT_THAT(Result.Completions, Not(testing::IsEmpty())); 3614 } 3615 3616 TEST(CompletionTest, CommentParamName) { 3617 clangd::CodeCompleteOptions Opts; 3618 const std::string Code = R"cpp( 3619 void fun(int foo, int bar); 3620 void overloaded(int param_int); 3621 void overloaded(int param_int, int param_other); 3622 void overloaded(char param_char); 3623 int main() { 3624 )cpp"; 3625 3626 EXPECT_THAT(completions(Code + "fun(/*^", {}, Opts).Completions, 3627 UnorderedElementsAre(labeled("foo="))); 3628 EXPECT_THAT(completions(Code + "fun(1, /*^", {}, Opts).Completions, 3629 UnorderedElementsAre(labeled("bar="))); 3630 EXPECT_THAT(completions(Code + "/*^", {}, Opts).Completions, IsEmpty()); 3631 // Test de-duplication. 3632 EXPECT_THAT( 3633 completions(Code + "overloaded(/*^", {}, Opts).Completions, 3634 UnorderedElementsAre(labeled("param_int="), labeled("param_char="))); 3635 // Comment already has some text in it. 3636 EXPECT_THAT(completions(Code + "fun(/* ^", {}, Opts).Completions, 3637 UnorderedElementsAre(labeled("foo="))); 3638 EXPECT_THAT(completions(Code + "fun(/* f^", {}, Opts).Completions, 3639 UnorderedElementsAre(labeled("foo="))); 3640 EXPECT_THAT(completions(Code + "fun(/* x^", {}, Opts).Completions, IsEmpty()); 3641 EXPECT_THAT(completions(Code + "fun(/* f ^", {}, Opts).Completions, 3642 IsEmpty()); 3643 } 3644 3645 TEST(CompletionTest, Concepts) { 3646 Annotations Code(R"cpp( 3647 template<class T> 3648 concept A = sizeof(T) <= 8; 3649 3650 template<$tparam^A U> 3651 int foo(); 3652 3653 template<class T> 3654 concept b = $other^A<T> && $other^sizeof(T) % 2 == 0 || $other^A<T> && sizeof(T) == 1; 3655 3656 $other^A<T> auto i = 19; 3657 )cpp"); 3658 TestTU TU; 3659 TU.Code = Code.code().str(); 3660 TU.ExtraArgs = {"-std=c++20"}; 3661 3662 std::vector<Symbol> Syms = {conceptSym("same_as")}; 3663 for (auto P : Code.points("tparam")) { 3664 ASSERT_THAT(completions(TU, P, Syms).Completions, 3665 AllOf(Contains(named("A")), Contains(named("same_as")), 3666 Contains(named("class")), Contains(named("typename")))) 3667 << "Completing template parameter at position " << P; 3668 } 3669 3670 for (auto P : Code.points("other")) { 3671 EXPECT_THAT(completions(TU, P, Syms).Completions, 3672 AllOf(Contains(named("A")), Contains(named("same_as")))) 3673 << "Completing 'requires' expression at position " << P; 3674 } 3675 } 3676 3677 TEST(SignatureHelp, DocFormat) { 3678 Annotations Code(R"cpp( 3679 // Comment `with` markup. 3680 void foo(int); 3681 void bar() { foo(^); } 3682 )cpp"); 3683 for (auto DocumentationFormat : 3684 {MarkupKind::PlainText, MarkupKind::Markdown}) { 3685 auto Sigs = signatures(Code.code(), Code.point(), /*IndexSymbols=*/{}, 3686 DocumentationFormat); 3687 ASSERT_EQ(Sigs.signatures.size(), 1U); 3688 EXPECT_EQ(Sigs.signatures[0].documentation.kind, DocumentationFormat); 3689 } 3690 } 3691 3692 TEST(SignatureHelp, TemplateArguments) { 3693 std::string Top = R"cpp( 3694 template <typename T, int> bool foo(char); 3695 template <int I, int> bool foo(float); 3696 )cpp"; 3697 3698 auto First = signatures(Top + "bool x = foo<^"); 3699 EXPECT_THAT( 3700 First.signatures, 3701 UnorderedElementsAre(sig("foo<[[typename T]], [[int]]>() -> bool"), 3702 sig("foo<[[int I]], [[int]]>() -> bool"))); 3703 EXPECT_EQ(First.activeParameter, 0); 3704 3705 auto Second = signatures(Top + "bool x = foo<1, ^"); 3706 EXPECT_THAT(Second.signatures, 3707 ElementsAre(sig("foo<[[int I]], [[int]]>() -> bool"))); 3708 EXPECT_EQ(Second.activeParameter, 1); 3709 } 3710 3711 } // namespace 3712 } // namespace clangd 3713 } // namespace clang 3714