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