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 __attribute__((annotate("custom_annotation"))) 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"), 923 Doc("Annotation: custom_annotation\nNon-doxygen comment.")))); 924 EXPECT_THAT( 925 Results.Completions, 926 Contains(AllOf(Named("bar"), Doc("Doxygen comment.\n\\param int a")))); 927 EXPECT_THAT(Results.Completions, 928 Contains(AllOf(Named("baz"), Doc("Multi-line block comment")))); 929 } 930 931 TEST(CompletionTest, CommentsFromSystemHeaders) { 932 MockFS FS; 933 MockCompilationDatabase CDB; 934 935 auto Opts = ClangdServer::optsForTest(); 936 Opts.BuildDynamicSymbolIndex = true; 937 938 ClangdServer Server(CDB, FS, Opts); 939 940 FS.Files[testPath("foo.h")] = R"cpp( 941 #pragma GCC system_header 942 943 // This comment should be retained! 944 int foo(); 945 )cpp"; 946 947 auto File = testPath("foo.cpp"); 948 Annotations Test(R"cpp( 949 #include "foo.h" 950 int x = foo^ 951 )cpp"); 952 runAddDocument(Server, File, Test.code()); 953 auto CompletionList = 954 llvm::cantFail(runCodeComplete(Server, File, Test.point(), {})); 955 956 EXPECT_THAT( 957 CompletionList.Completions, 958 Contains(AllOf(Named("foo"), Doc("This comment should be retained!")))); 959 } 960 961 TEST(CompletionTest, GlobalCompletionFiltering) { 962 963 Symbol Class = cls("XYZ"); 964 Class.Flags = static_cast<Symbol::SymbolFlag>( 965 Class.Flags & ~(Symbol::IndexedForCodeCompletion)); 966 Symbol Func = func("XYZ::foooo"); 967 Func.Flags = static_cast<Symbol::SymbolFlag>( 968 Func.Flags & ~(Symbol::IndexedForCodeCompletion)); 969 970 auto Results = completions(R"(// void f() { 971 XYZ::foooo^ 972 })", 973 {Class, Func}); 974 EXPECT_THAT(Results.Completions, IsEmpty()); 975 } 976 977 TEST(CodeCompleteTest, DisableTypoCorrection) { 978 auto Results = completions(R"cpp( 979 namespace clang { int v; } 980 void f() { clangd::^ 981 )cpp"); 982 EXPECT_TRUE(Results.Completions.empty()); 983 } 984 985 TEST(CodeCompleteTest, NoColonColonAtTheEnd) { 986 auto Results = completions(R"cpp( 987 namespace clang { } 988 void f() { 989 clan^ 990 } 991 )cpp"); 992 993 EXPECT_THAT(Results.Completions, Contains(Labeled("clang"))); 994 EXPECT_THAT(Results.Completions, Not(Contains(Labeled("clang::")))); 995 } 996 997 TEST(CompletionTest, BacktrackCrashes) { 998 // Sema calls code completion callbacks twice in these cases. 999 auto Results = completions(R"cpp( 1000 namespace ns { 1001 struct FooBarBaz {}; 1002 } // namespace ns 1003 1004 int foo(ns::FooBar^ 1005 )cpp"); 1006 1007 EXPECT_THAT(Results.Completions, ElementsAre(Labeled("FooBarBaz"))); 1008 1009 // Check we don't crash in that case too. 1010 completions(R"cpp( 1011 struct FooBarBaz {}; 1012 void test() { 1013 if (FooBarBaz * x^) {} 1014 } 1015 )cpp"); 1016 } 1017 1018 TEST(CompletionTest, CompleteInMacroWithStringification) { 1019 auto Results = completions(R"cpp( 1020 void f(const char *, int x); 1021 #define F(x) f(#x, x) 1022 1023 namespace ns { 1024 int X; 1025 int Y; 1026 } // namespace ns 1027 1028 int f(int input_num) { 1029 F(ns::^) 1030 } 1031 )cpp"); 1032 1033 EXPECT_THAT(Results.Completions, 1034 UnorderedElementsAre(Named("X"), Named("Y"))); 1035 } 1036 1037 TEST(CompletionTest, CompleteInMacroAndNamespaceWithStringification) { 1038 auto Results = completions(R"cpp( 1039 void f(const char *, int x); 1040 #define F(x) f(#x, x) 1041 1042 namespace ns { 1043 int X; 1044 1045 int f(int input_num) { 1046 F(^) 1047 } 1048 } // namespace ns 1049 )cpp"); 1050 1051 EXPECT_THAT(Results.Completions, Contains(Named("X"))); 1052 } 1053 1054 TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) { 1055 auto Results = completions(R"cpp( 1056 int bar(int param_in_bar) { 1057 } 1058 1059 int foo(int param_in_foo) { 1060 #if 0 1061 // In recovery mode, "param_in_foo" will also be suggested among many other 1062 // unrelated symbols; however, this is really a special case where this works. 1063 // If the #if block is outside of the function, "param_in_foo" is still 1064 // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't 1065 // really provide useful results in excluded branches. 1066 par^ 1067 #endif 1068 } 1069 )cpp"); 1070 1071 EXPECT_TRUE(Results.Completions.empty()); 1072 } 1073 1074 TEST(CompletionTest, DefaultArgs) { 1075 clangd::CodeCompleteOptions Opts; 1076 std::string Context = R"cpp( 1077 int X(int A = 0); 1078 int Y(int A, int B = 0); 1079 int Z(int A, int B = 0, int C = 0, int D = 0); 1080 )cpp"; 1081 EXPECT_THAT(completions(Context + "int y = X^", {}, Opts).Completions, 1082 UnorderedElementsAre(Labeled("X(int A = 0)"))); 1083 EXPECT_THAT(completions(Context + "int y = Y^", {}, Opts).Completions, 1084 UnorderedElementsAre(AllOf(Labeled("Y(int A, int B = 0)"), 1085 SnippetSuffix("(${1:int A})")))); 1086 EXPECT_THAT(completions(Context + "int y = Z^", {}, Opts).Completions, 1087 UnorderedElementsAre( 1088 AllOf(Labeled("Z(int A, int B = 0, int C = 0, int D = 0)"), 1089 SnippetSuffix("(${1:int A})")))); 1090 } 1091 1092 TEST(CompletionTest, NoCrashWithTemplateParamsAndPreferredTypes) { 1093 auto Completions = completions(R"cpp( 1094 template <template <class> class TT> int foo() { 1095 int a = ^ 1096 } 1097 )cpp") 1098 .Completions; 1099 EXPECT_THAT(Completions, Contains(Named("TT"))); 1100 } 1101 1102 TEST(CompletionTest, NestedTemplateHeuristics) { 1103 auto Completions = completions(R"cpp( 1104 struct Plain { int xxx; }; 1105 template <typename T> class Templ { Plain ppp; }; 1106 template <typename T> void foo(Templ<T> &t) { 1107 // Formally ppp has DependentTy, because Templ may be specialized. 1108 // However we sholud be able to see into it using the primary template. 1109 t.ppp.^ 1110 } 1111 )cpp") 1112 .Completions; 1113 EXPECT_THAT(Completions, Contains(Named("xxx"))); 1114 } 1115 1116 TEST(CompletionTest, RecordCCResultCallback) { 1117 std::vector<CodeCompletion> RecordedCompletions; 1118 CodeCompleteOptions Opts; 1119 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC, 1120 const SymbolQualitySignals &, 1121 const SymbolRelevanceSignals &, 1122 float Score) { 1123 RecordedCompletions.push_back(CC); 1124 }; 1125 1126 completions("int xy1, xy2; int a = xy^", /*IndexSymbols=*/{}, Opts); 1127 EXPECT_THAT(RecordedCompletions, 1128 UnorderedElementsAre(Named("xy1"), Named("xy2"))); 1129 } 1130 1131 TEST(CompletionTest, ASTSignals) { 1132 struct Completion { 1133 std::string Name; 1134 unsigned MainFileRefs; 1135 unsigned ScopeRefsInFile; 1136 }; 1137 CodeCompleteOptions Opts; 1138 std::vector<Completion> RecordedCompletions; 1139 Opts.RecordCCResult = [&RecordedCompletions](const CodeCompletion &CC, 1140 const SymbolQualitySignals &, 1141 const SymbolRelevanceSignals &R, 1142 float Score) { 1143 RecordedCompletions.push_back({CC.Name, R.MainFileRefs, R.ScopeRefsInFile}); 1144 }; 1145 ASTSignals MainFileSignals; 1146 MainFileSignals.ReferencedSymbols[var("xy1").ID] = 3; 1147 MainFileSignals.ReferencedSymbols[var("xy2").ID] = 1; 1148 MainFileSignals.ReferencedSymbols[var("xyindex").ID] = 10; 1149 MainFileSignals.RelatedNamespaces["tar::"] = 5; 1150 MainFileSignals.RelatedNamespaces["bar::"] = 3; 1151 Opts.MainFileSignals = &MainFileSignals; 1152 Opts.AllScopes = true; 1153 completions( 1154 R"cpp( 1155 int xy1; 1156 int xy2; 1157 namespace bar { 1158 int xybar = 1; 1159 int a = xy^ 1160 } 1161 )cpp", 1162 /*IndexSymbols=*/{var("xyindex"), var("tar::xytar"), var("bar::xybar")}, 1163 Opts); 1164 EXPECT_THAT(RecordedCompletions, 1165 UnorderedElementsAre( 1166 AllOf(Named("xy1"), MainFileRefs(3u), ScopeRefs(0u)), 1167 AllOf(Named("xy2"), MainFileRefs(1u), ScopeRefs(0u)), 1168 AllOf(Named("xyindex"), MainFileRefs(10u), ScopeRefs(0u)), 1169 AllOf(Named("xytar"), MainFileRefs(0u), ScopeRefs(5u)), 1170 AllOf(/*both from sema and index*/ Named("xybar"), 1171 MainFileRefs(0u), ScopeRefs(3u)))); 1172 } 1173 1174 SignatureHelp signatures(llvm::StringRef Text, Position Point, 1175 std::vector<Symbol> IndexSymbols = {}) { 1176 std::unique_ptr<SymbolIndex> Index; 1177 if (!IndexSymbols.empty()) 1178 Index = memIndex(IndexSymbols); 1179 1180 auto TU = TestTU::withCode(Text); 1181 MockFS FS; 1182 auto Inputs = TU.inputs(FS); 1183 Inputs.Index = Index.get(); 1184 IgnoreDiagnostics Diags; 1185 auto CI = buildCompilerInvocation(Inputs, Diags); 1186 if (!CI) { 1187 ADD_FAILURE() << "Couldn't build CompilerInvocation"; 1188 return {}; 1189 } 1190 auto Preamble = buildPreamble(testPath(TU.Filename), *CI, Inputs, 1191 /*InMemory=*/true, /*Callback=*/nullptr); 1192 if (!Preamble) { 1193 ADD_FAILURE() << "Couldn't build Preamble"; 1194 return {}; 1195 } 1196 return signatureHelp(testPath(TU.Filename), Point, *Preamble, Inputs); 1197 } 1198 1199 SignatureHelp signatures(llvm::StringRef Text, 1200 std::vector<Symbol> IndexSymbols = {}) { 1201 Annotations Test(Text); 1202 return signatures(Test.code(), Test.point(), std::move(IndexSymbols)); 1203 } 1204 1205 struct ExpectedParameter { 1206 std::string Text; 1207 std::pair<unsigned, unsigned> Offsets; 1208 }; 1209 MATCHER_P(ParamsAre, P, "") { 1210 if (P.size() != arg.parameters.size()) 1211 return false; 1212 for (unsigned I = 0; I < P.size(); ++I) { 1213 if (P[I].Text != arg.parameters[I].labelString || 1214 P[I].Offsets != arg.parameters[I].labelOffsets) 1215 return false; 1216 } 1217 return true; 1218 } 1219 MATCHER_P(SigDoc, Doc, "") { return arg.documentation == Doc; } 1220 1221 /// \p AnnotatedLabel is a signature label with ranges marking parameters, e.g. 1222 /// foo([[int p1]], [[double p2]]) -> void 1223 Matcher<SignatureInformation> Sig(llvm::StringRef AnnotatedLabel) { 1224 llvm::Annotations A(AnnotatedLabel); 1225 std::string Label = std::string(A.code()); 1226 std::vector<ExpectedParameter> Parameters; 1227 for (auto Range : A.ranges()) { 1228 Parameters.emplace_back(); 1229 1230 ExpectedParameter &P = Parameters.back(); 1231 P.Text = Label.substr(Range.Begin, Range.End - Range.Begin); 1232 P.Offsets.first = lspLength(llvm::StringRef(Label).substr(0, Range.Begin)); 1233 P.Offsets.second = lspLength(llvm::StringRef(Label).substr(1, Range.End)); 1234 } 1235 return AllOf(SigHelpLabeled(Label), ParamsAre(Parameters)); 1236 } 1237 1238 TEST(SignatureHelpTest, Overloads) { 1239 auto Results = signatures(R"cpp( 1240 void foo(int x, int y); 1241 void foo(int x, float y); 1242 void foo(float x, int y); 1243 void foo(float x, float y); 1244 void bar(int x, int y = 0); 1245 int main() { foo(^); } 1246 )cpp"); 1247 EXPECT_THAT(Results.signatures, 1248 UnorderedElementsAre(Sig("foo([[float x]], [[float y]]) -> void"), 1249 Sig("foo([[float x]], [[int y]]) -> void"), 1250 Sig("foo([[int x]], [[float y]]) -> void"), 1251 Sig("foo([[int x]], [[int y]]) -> void"))); 1252 // We always prefer the first signature. 1253 EXPECT_EQ(0, Results.activeSignature); 1254 EXPECT_EQ(0, Results.activeParameter); 1255 } 1256 1257 TEST(SignatureHelpTest, OverloadInitListRegression) { 1258 auto Results = signatures(R"cpp( 1259 struct A {int x;}; 1260 struct B {B(A);}; 1261 void f(); 1262 int main() { 1263 B b({1}); 1264 f(^); 1265 } 1266 )cpp"); 1267 EXPECT_THAT(Results.signatures, UnorderedElementsAre(Sig("f() -> void"))); 1268 } 1269 1270 TEST(SignatureHelpTest, DefaultArgs) { 1271 auto Results = signatures(R"cpp( 1272 void bar(int x, int y = 0); 1273 void bar(float x = 0, int y = 42); 1274 int main() { bar(^ 1275 )cpp"); 1276 EXPECT_THAT(Results.signatures, 1277 UnorderedElementsAre( 1278 Sig("bar([[int x]], [[int y = 0]]) -> void"), 1279 Sig("bar([[float x = 0]], [[int y = 42]]) -> void"))); 1280 EXPECT_EQ(0, Results.activeSignature); 1281 EXPECT_EQ(0, Results.activeParameter); 1282 } 1283 1284 TEST(SignatureHelpTest, ActiveArg) { 1285 auto Results = signatures(R"cpp( 1286 int baz(int a, int b, int c); 1287 int main() { baz(baz(1,2,3), ^); } 1288 )cpp"); 1289 EXPECT_THAT(Results.signatures, 1290 ElementsAre(Sig("baz([[int a]], [[int b]], [[int c]]) -> int"))); 1291 EXPECT_EQ(0, Results.activeSignature); 1292 EXPECT_EQ(1, Results.activeParameter); 1293 } 1294 1295 TEST(SignatureHelpTest, OpeningParen) { 1296 llvm::StringLiteral Tests[] = { 1297 // Recursive function call. 1298 R"cpp( 1299 int foo(int a, int b, int c); 1300 int main() { 1301 foo(foo $p^( foo(10, 10, 10), ^ ))); 1302 })cpp", 1303 // Functional type cast. 1304 R"cpp( 1305 struct Foo { 1306 Foo(int a, int b, int c); 1307 }; 1308 int main() { 1309 Foo $p^( 10, ^ ); 1310 })cpp", 1311 // New expression. 1312 R"cpp( 1313 struct Foo { 1314 Foo(int a, int b, int c); 1315 }; 1316 int main() { 1317 new Foo $p^( 10, ^ ); 1318 })cpp", 1319 // Macro expansion. 1320 R"cpp( 1321 int foo(int a, int b, int c); 1322 #define FOO foo( 1323 1324 int main() { 1325 // Macro expansions. 1326 $p^FOO 10, ^ ); 1327 })cpp", 1328 // Macro arguments. 1329 R"cpp( 1330 int foo(int a, int b, int c); 1331 int main() { 1332 #define ID(X) X 1333 // FIXME: figure out why ID(foo (foo(10), )) doesn't work when preserving 1334 // the recovery expression. 1335 ID(foo $p^( 10, ^ )) 1336 })cpp", 1337 // Dependent args. 1338 R"cpp( 1339 int foo(int a, int b); 1340 template <typename T> void bar(T t) { 1341 foo$p^(t, ^t); 1342 })cpp", 1343 // Dependent args on templated func. 1344 R"cpp( 1345 template <typename T> 1346 int foo(T, T); 1347 template <typename T> void bar(T t) { 1348 foo$p^(t, ^t); 1349 })cpp", 1350 // Dependent args on member. 1351 R"cpp( 1352 struct Foo { int foo(int, int); }; 1353 template <typename T> void bar(T t) { 1354 Foo f; 1355 f.foo$p^(t, ^t); 1356 })cpp", 1357 // Dependent args on templated member. 1358 R"cpp( 1359 struct Foo { template <typename T> int foo(T, T); }; 1360 template <typename T> void bar(T t) { 1361 Foo f; 1362 f.foo$p^(t, ^t); 1363 })cpp", 1364 }; 1365 1366 for (auto Test : Tests) { 1367 Annotations Code(Test); 1368 EXPECT_EQ(signatures(Code.code(), Code.point()).argListStart, 1369 Code.point("p")) 1370 << "Test source:" << Test; 1371 } 1372 } 1373 1374 TEST(SignatureHelpTest, StalePreamble) { 1375 TestTU TU; 1376 TU.Code = ""; 1377 IgnoreDiagnostics Diags; 1378 MockFS FS; 1379 auto Inputs = TU.inputs(FS); 1380 auto CI = buildCompilerInvocation(Inputs, Diags); 1381 ASSERT_TRUE(CI); 1382 auto EmptyPreamble = buildPreamble(testPath(TU.Filename), *CI, Inputs, 1383 /*InMemory=*/true, /*Callback=*/nullptr); 1384 ASSERT_TRUE(EmptyPreamble); 1385 1386 TU.AdditionalFiles["a.h"] = "int foo(int x);"; 1387 const Annotations Test(R"cpp( 1388 #include "a.h" 1389 void bar() { foo(^2); })cpp"); 1390 TU.Code = Test.code().str(); 1391 auto Results = signatureHelp(testPath(TU.Filename), Test.point(), 1392 *EmptyPreamble, TU.inputs(FS)); 1393 EXPECT_THAT(Results.signatures, ElementsAre(Sig("foo([[int x]]) -> int"))); 1394 EXPECT_EQ(0, Results.activeSignature); 1395 EXPECT_EQ(0, Results.activeParameter); 1396 } 1397 1398 class IndexRequestCollector : public SymbolIndex { 1399 public: 1400 bool 1401 fuzzyFind(const FuzzyFindRequest &Req, 1402 llvm::function_ref<void(const Symbol &)> Callback) const override { 1403 std::unique_lock<std::mutex> Lock(Mut); 1404 Requests.push_back(Req); 1405 ReceivedRequestCV.notify_one(); 1406 return true; 1407 } 1408 1409 void lookup(const LookupRequest &, 1410 llvm::function_ref<void(const Symbol &)>) const override {} 1411 1412 bool refs(const RefsRequest &, 1413 llvm::function_ref<void(const Ref &)>) const override { 1414 return false; 1415 } 1416 1417 void relations(const RelationsRequest &, 1418 llvm::function_ref<void(const SymbolID &, const Symbol &)>) 1419 const override {} 1420 1421 llvm::unique_function<IndexContents(llvm::StringRef) const> 1422 indexedFiles() const override { 1423 return [](llvm::StringRef) { return IndexContents::None; }; 1424 } 1425 1426 // This is incorrect, but IndexRequestCollector is not an actual index and it 1427 // isn't used in production code. 1428 size_t estimateMemoryUsage() const override { return 0; } 1429 1430 const std::vector<FuzzyFindRequest> consumeRequests(size_t Num) const { 1431 std::unique_lock<std::mutex> Lock(Mut); 1432 EXPECT_TRUE(wait(Lock, ReceivedRequestCV, timeoutSeconds(30), 1433 [this, Num] { return Requests.size() == Num; })); 1434 auto Reqs = std::move(Requests); 1435 Requests = {}; 1436 return Reqs; 1437 } 1438 1439 private: 1440 // We need a mutex to handle async fuzzy find requests. 1441 mutable std::condition_variable ReceivedRequestCV; 1442 mutable std::mutex Mut; 1443 mutable std::vector<FuzzyFindRequest> Requests; 1444 }; 1445 1446 // Clients have to consume exactly Num requests. 1447 std::vector<FuzzyFindRequest> captureIndexRequests(llvm::StringRef Code, 1448 size_t Num = 1) { 1449 clangd::CodeCompleteOptions Opts; 1450 IndexRequestCollector Requests; 1451 Opts.Index = &Requests; 1452 completions(Code, {}, Opts); 1453 const auto Reqs = Requests.consumeRequests(Num); 1454 EXPECT_EQ(Reqs.size(), Num); 1455 return Reqs; 1456 } 1457 1458 TEST(CompletionTest, UnqualifiedIdQuery) { 1459 auto Requests = captureIndexRequests(R"cpp( 1460 namespace std {} 1461 using namespace std; 1462 namespace ns { 1463 void f() { 1464 vec^ 1465 } 1466 } 1467 )cpp"); 1468 1469 EXPECT_THAT(Requests, 1470 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1471 UnorderedElementsAre("", "ns::", "std::")))); 1472 } 1473 1474 TEST(CompletionTest, EnclosingScopeComesFirst) { 1475 auto Requests = captureIndexRequests(R"cpp( 1476 namespace std {} 1477 using namespace std; 1478 namespace nx { 1479 namespace ns { 1480 namespace { 1481 void f() { 1482 vec^ 1483 } 1484 } 1485 } 1486 } 1487 )cpp"); 1488 1489 EXPECT_THAT(Requests, 1490 ElementsAre(Field( 1491 &FuzzyFindRequest::Scopes, 1492 UnorderedElementsAre("", "std::", "nx::ns::", "nx::")))); 1493 EXPECT_EQ(Requests[0].Scopes[0], "nx::ns::"); 1494 } 1495 1496 TEST(CompletionTest, ResolvedQualifiedIdQuery) { 1497 auto Requests = captureIndexRequests(R"cpp( 1498 namespace ns1 {} 1499 namespace ns2 {} // ignore 1500 namespace ns3 { namespace nns3 {} } 1501 namespace foo { 1502 using namespace ns1; 1503 using namespace ns3::nns3; 1504 } 1505 namespace ns { 1506 void f() { 1507 foo::^ 1508 } 1509 } 1510 )cpp"); 1511 1512 EXPECT_THAT(Requests, 1513 ElementsAre(Field( 1514 &FuzzyFindRequest::Scopes, 1515 UnorderedElementsAre("foo::", "ns1::", "ns3::nns3::")))); 1516 } 1517 1518 TEST(CompletionTest, UnresolvedQualifierIdQuery) { 1519 auto Requests = captureIndexRequests(R"cpp( 1520 namespace a {} 1521 using namespace a; 1522 namespace ns { 1523 void f() { 1524 bar::^ 1525 } 1526 } // namespace ns 1527 )cpp"); 1528 1529 EXPECT_THAT(Requests, 1530 ElementsAre(Field( 1531 &FuzzyFindRequest::Scopes, 1532 UnorderedElementsAre("a::bar::", "ns::bar::", "bar::")))); 1533 } 1534 1535 TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) { 1536 auto Requests = captureIndexRequests(R"cpp( 1537 namespace a {} 1538 using namespace a; 1539 namespace ns { 1540 void f() { 1541 ::a::bar::^ 1542 } 1543 } // namespace ns 1544 )cpp"); 1545 1546 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1547 UnorderedElementsAre("a::bar::")))); 1548 } 1549 1550 TEST(CompletionTest, EmptyQualifiedQuery) { 1551 auto Requests = captureIndexRequests(R"cpp( 1552 namespace ns { 1553 void f() { 1554 ^ 1555 } 1556 } // namespace ns 1557 )cpp"); 1558 1559 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1560 UnorderedElementsAre("", "ns::")))); 1561 } 1562 1563 TEST(CompletionTest, GlobalQualifiedQuery) { 1564 auto Requests = captureIndexRequests(R"cpp( 1565 namespace ns { 1566 void f() { 1567 ::^ 1568 } 1569 } // namespace ns 1570 )cpp"); 1571 1572 EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, 1573 UnorderedElementsAre("")))); 1574 } 1575 1576 TEST(CompletionTest, NoDuplicatedQueryScopes) { 1577 auto Requests = captureIndexRequests(R"cpp( 1578 namespace {} 1579 1580 namespace na { 1581 namespace {} 1582 namespace nb { 1583 ^ 1584 } // namespace nb 1585 } // namespace na 1586 )cpp"); 1587 1588 EXPECT_THAT(Requests, 1589 ElementsAre(Field(&FuzzyFindRequest::Scopes, 1590 UnorderedElementsAre("na::", "na::nb::", "")))); 1591 } 1592 1593 TEST(CompletionTest, NoIndexCompletionsInsideClasses) { 1594 auto Completions = completions( 1595 R"cpp( 1596 struct Foo { 1597 int SomeNameOfField; 1598 typedef int SomeNameOfTypedefField; 1599 }; 1600 1601 Foo::^)cpp", 1602 {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")}); 1603 1604 EXPECT_THAT(Completions.Completions, 1605 AllOf(Contains(Labeled("SomeNameOfField")), 1606 Contains(Labeled("SomeNameOfTypedefField")), 1607 Not(Contains(Labeled("SomeNameInTheIndex"))))); 1608 } 1609 1610 TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) { 1611 { 1612 auto Completions = completions( 1613 R"cpp( 1614 template <class T> 1615 void foo() { 1616 T::^ 1617 } 1618 )cpp", 1619 {func("::SomeNameInTheIndex")}); 1620 1621 EXPECT_THAT(Completions.Completions, 1622 Not(Contains(Labeled("SomeNameInTheIndex")))); 1623 } 1624 1625 { 1626 auto Completions = completions( 1627 R"cpp( 1628 template <class T> 1629 void foo() { 1630 T::template Y<int>::^ 1631 } 1632 )cpp", 1633 {func("::SomeNameInTheIndex")}); 1634 1635 EXPECT_THAT(Completions.Completions, 1636 Not(Contains(Labeled("SomeNameInTheIndex")))); 1637 } 1638 1639 { 1640 auto Completions = completions( 1641 R"cpp( 1642 template <class T> 1643 void foo() { 1644 T::foo::^ 1645 } 1646 )cpp", 1647 {func("::SomeNameInTheIndex")}); 1648 1649 EXPECT_THAT(Completions.Completions, 1650 Not(Contains(Labeled("SomeNameInTheIndex")))); 1651 } 1652 } 1653 1654 TEST(CompletionTest, OverloadBundling) { 1655 clangd::CodeCompleteOptions Opts; 1656 Opts.BundleOverloads = true; 1657 1658 std::string Context = R"cpp( 1659 struct X { 1660 // Overload with int 1661 int a(int) __attribute__((deprecated("", ""))); 1662 // Overload with bool 1663 int a(bool); 1664 int b(float); 1665 }; 1666 int GFuncC(int); 1667 int GFuncD(int); 1668 )cpp"; 1669 1670 // Member completions are bundled. 1671 EXPECT_THAT(completions(Context + "int y = X().^", {}, Opts).Completions, 1672 UnorderedElementsAre(Labeled("a(…)"), Labeled("b(float)"))); 1673 1674 // Non-member completions are bundled, including index+sema. 1675 Symbol NoArgsGFunc = func("GFuncC"); 1676 EXPECT_THAT( 1677 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1678 UnorderedElementsAre(Labeled("GFuncC(…)"), Labeled("GFuncD(int)"))); 1679 1680 // Differences in header-to-insert suppress bundling. 1681 std::string DeclFile = URI::create(testPath("foo")).toString(); 1682 NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str(); 1683 NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1); 1684 EXPECT_THAT( 1685 completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, 1686 UnorderedElementsAre(AllOf(Named("GFuncC"), InsertInclude("<foo>")), 1687 Labeled("GFuncC(int)"), Labeled("GFuncD(int)"))); 1688 1689 // Examine a bundled completion in detail. 1690 auto A = 1691 completions(Context + "int y = X().a^", {}, Opts).Completions.front(); 1692 EXPECT_EQ(A.Name, "a"); 1693 EXPECT_EQ(A.Signature, "(…)"); 1694 EXPECT_EQ(A.BundleSize, 2u); 1695 EXPECT_EQ(A.Kind, CompletionItemKind::Method); 1696 EXPECT_EQ(A.ReturnType, "int"); // All overloads return int. 1697 // For now we just return one of the doc strings arbitrarily. 1698 ASSERT_TRUE(A.Documentation); 1699 ASSERT_FALSE(A.Deprecated); // Not all overloads deprecated. 1700 EXPECT_THAT( 1701 A.Documentation->asPlainText(), 1702 AnyOf(HasSubstr("Overload with int"), HasSubstr("Overload with bool"))); 1703 EXPECT_EQ(A.SnippetSuffix, "($0)"); 1704 } 1705 1706 TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) { 1707 clangd::CodeCompleteOptions Opts; 1708 Opts.BundleOverloads = true; 1709 1710 Symbol SymX = sym("ns::X", index::SymbolKind::Function, "@F@\\0#"); 1711 Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#"); 1712 std::string BarHeader = testPath("bar.h"); 1713 auto BarURI = URI::create(BarHeader).toString(); 1714 SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); 1715 SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); 1716 // The include header is different, but really it's the same file. 1717 SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1); 1718 SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1); 1719 1720 auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts); 1721 // Expect both results are bundled, despite the different-but-same 1722 // IncludeHeader. 1723 ASSERT_EQ(1u, Results.Completions.size()); 1724 const auto &R = Results.Completions.front(); 1725 EXPECT_EQ("X", R.Name); 1726 EXPECT_EQ(2u, R.BundleSize); 1727 } 1728 1729 TEST(CompletionTest, DocumentationFromChangedFileCrash) { 1730 MockFS FS; 1731 auto FooH = testPath("foo.h"); 1732 auto FooCpp = testPath("foo.cpp"); 1733 FS.Files[FooH] = R"cpp( 1734 // this is my documentation comment. 1735 int func(); 1736 )cpp"; 1737 FS.Files[FooCpp] = ""; 1738 1739 MockCompilationDatabase CDB; 1740 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 1741 1742 Annotations Source(R"cpp( 1743 #include "foo.h" 1744 int func() { 1745 // This makes sure we have func from header in the AST. 1746 } 1747 int a = fun^ 1748 )cpp"); 1749 Server.addDocument(FooCpp, Source.code(), "null", WantDiagnostics::Yes); 1750 // We need to wait for preamble to build. 1751 ASSERT_TRUE(Server.blockUntilIdleForTest()); 1752 1753 // Change the header file. Completion will reuse the old preamble! 1754 FS.Files[FooH] = R"cpp( 1755 int func(); 1756 )cpp"; 1757 1758 clangd::CodeCompleteOptions Opts; 1759 CodeCompleteResult Completions = 1760 cantFail(runCodeComplete(Server, FooCpp, Source.point(), Opts)); 1761 // We shouldn't crash. Unfortunately, current workaround is to not produce 1762 // comments for symbols from headers. 1763 EXPECT_THAT(Completions.Completions, 1764 Contains(AllOf(Not(IsDocumented()), Named("func")))); 1765 } 1766 1767 TEST(CompletionTest, NonDocComments) { 1768 const char *Text = R"cpp( 1769 // We ignore namespace comments, for rationale see CodeCompletionStrings.h. 1770 namespace comments_ns { 1771 } 1772 1773 // ------------------ 1774 int comments_foo(); 1775 1776 // A comment and a decl are separated by newlines. 1777 // Therefore, the comment shouldn't show up as doc comment. 1778 1779 int comments_bar(); 1780 1781 // this comment should be in the results. 1782 int comments_baz(); 1783 1784 1785 template <class T> 1786 struct Struct { 1787 int comments_qux(); 1788 int comments_quux(); 1789 }; 1790 1791 1792 // This comment should not be there. 1793 1794 template <class T> 1795 int Struct<T>::comments_qux() { 1796 } 1797 1798 // This comment **should** be in results. 1799 template <class T> 1800 int Struct<T>::comments_quux() { 1801 int a = comments^; 1802 } 1803 )cpp"; 1804 1805 // We should not get any of those comments in completion. 1806 EXPECT_THAT( 1807 completions(Text).Completions, 1808 UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")), 1809 AllOf(IsDocumented(), Named("comments_baz")), 1810 AllOf(IsDocumented(), Named("comments_quux")), 1811 AllOf(Not(IsDocumented()), Named("comments_ns")), 1812 // FIXME(ibiryukov): the following items should have 1813 // empty documentation, since they are separated from 1814 // a comment with an empty line. Unfortunately, I 1815 // couldn't make Sema tests pass if we ignore those. 1816 AllOf(IsDocumented(), Named("comments_bar")), 1817 AllOf(IsDocumented(), Named("comments_qux")))); 1818 } 1819 1820 TEST(CompletionTest, CompleteOnInvalidLine) { 1821 auto FooCpp = testPath("foo.cpp"); 1822 1823 MockCompilationDatabase CDB; 1824 MockFS FS; 1825 FS.Files[FooCpp] = "// empty file"; 1826 1827 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 1828 // Run completion outside the file range. 1829 Position Pos; 1830 Pos.line = 100; 1831 Pos.character = 0; 1832 EXPECT_THAT_EXPECTED( 1833 runCodeComplete(Server, FooCpp, Pos, clangd::CodeCompleteOptions()), 1834 Failed()); 1835 } 1836 1837 TEST(CompletionTest, QualifiedNames) { 1838 auto Results = completions( 1839 R"cpp( 1840 namespace ns { int local; void both(); } 1841 void f() { ::ns::^ } 1842 )cpp", 1843 {func("ns::both"), cls("ns::Index")}); 1844 // We get results from both index and sema, with no duplicates. 1845 EXPECT_THAT( 1846 Results.Completions, 1847 UnorderedElementsAre(Scope("ns::"), Scope("ns::"), Scope("ns::"))); 1848 } 1849 1850 TEST(CompletionTest, Render) { 1851 CodeCompletion C; 1852 C.Name = "x"; 1853 C.Signature = "(bool) const"; 1854 C.SnippetSuffix = "(${0:bool})"; 1855 C.ReturnType = "int"; 1856 C.RequiredQualifier = "Foo::"; 1857 C.Scope = "ns::Foo::"; 1858 C.Documentation.emplace(); 1859 C.Documentation->addParagraph().appendText("This is ").appendCode("x()"); 1860 C.Includes.emplace_back(); 1861 auto &Include = C.Includes.back(); 1862 Include.Header = "\"foo.h\""; 1863 C.Kind = CompletionItemKind::Method; 1864 C.Score.Total = 1.0; 1865 C.Score.ExcludingName = .5; 1866 C.Origin = SymbolOrigin::AST | SymbolOrigin::Static; 1867 1868 CodeCompleteOptions Opts; 1869 Opts.IncludeIndicator.Insert = "^"; 1870 Opts.IncludeIndicator.NoInsert = ""; 1871 Opts.EnableSnippets = false; 1872 1873 auto R = C.render(Opts); 1874 EXPECT_EQ(R.label, "Foo::x(bool) const"); 1875 EXPECT_EQ(R.insertText, "Foo::x"); 1876 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::PlainText); 1877 EXPECT_EQ(R.filterText, "x"); 1878 EXPECT_EQ(R.detail, "int"); 1879 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()"); 1880 EXPECT_THAT(R.additionalTextEdits, IsEmpty()); 1881 EXPECT_EQ(R.sortText, sortText(1.0, "x")); 1882 EXPECT_FALSE(R.deprecated); 1883 EXPECT_EQ(R.score, .5f); 1884 1885 Opts.EnableSnippets = true; 1886 R = C.render(Opts); 1887 EXPECT_EQ(R.insertText, "Foo::x(${0:bool})"); 1888 EXPECT_EQ(R.insertTextFormat, InsertTextFormat::Snippet); 1889 1890 Include.Insertion.emplace(); 1891 R = C.render(Opts); 1892 EXPECT_EQ(R.label, "^Foo::x(bool) const"); 1893 EXPECT_THAT(R.additionalTextEdits, Not(IsEmpty())); 1894 1895 Opts.ShowOrigins = true; 1896 R = C.render(Opts); 1897 EXPECT_EQ(R.label, "^[AS]Foo::x(bool) const"); 1898 1899 C.BundleSize = 2; 1900 R = C.render(Opts); 1901 EXPECT_EQ(R.detail, "[2 overloads]"); 1902 EXPECT_EQ(R.documentation->value, "From \"foo.h\"\nThis is x()"); 1903 1904 C.Deprecated = true; 1905 R = C.render(Opts); 1906 EXPECT_TRUE(R.deprecated); 1907 1908 Opts.DocumentationFormat = MarkupKind::Markdown; 1909 R = C.render(Opts); 1910 EXPECT_EQ(R.documentation->value, "From `\"foo.h\"` \nThis is `x()`"); 1911 } 1912 1913 TEST(CompletionTest, IgnoreRecoveryResults) { 1914 auto Results = completions( 1915 R"cpp( 1916 namespace ns { int NotRecovered() { return 0; } } 1917 void f() { 1918 // Sema enters recovery mode first and then normal mode. 1919 if (auto x = ns::NotRecover^) 1920 } 1921 )cpp"); 1922 EXPECT_THAT(Results.Completions, UnorderedElementsAre(Named("NotRecovered"))); 1923 } 1924 1925 TEST(CompletionTest, ScopeOfClassFieldInConstructorInitializer) { 1926 auto Results = completions( 1927 R"cpp( 1928 namespace ns { 1929 class X { public: X(); int x_; }; 1930 X::X() : x_^(0) {} 1931 } 1932 )cpp"); 1933 EXPECT_THAT(Results.Completions, 1934 UnorderedElementsAre(AllOf(Scope("ns::X::"), Named("x_")))); 1935 } 1936 1937 TEST(CompletionTest, CodeCompletionContext) { 1938 auto Results = completions( 1939 R"cpp( 1940 namespace ns { 1941 class X { public: X(); int x_; }; 1942 void f() { 1943 X x; 1944 x.^; 1945 } 1946 } 1947 )cpp"); 1948 1949 EXPECT_THAT(Results.Context, CodeCompletionContext::CCC_DotMemberAccess); 1950 } 1951 1952 TEST(CompletionTest, FixItForArrowToDot) { 1953 MockFS FS; 1954 MockCompilationDatabase CDB; 1955 1956 CodeCompleteOptions Opts; 1957 Opts.IncludeFixIts = true; 1958 const char *Code = 1959 R"cpp( 1960 class Auxilary { 1961 public: 1962 void AuxFunction(); 1963 }; 1964 class ClassWithPtr { 1965 public: 1966 void MemberFunction(); 1967 Auxilary* operator->() const; 1968 Auxilary* Aux; 1969 }; 1970 void f() { 1971 ClassWithPtr x; 1972 x[[->]]^; 1973 } 1974 )cpp"; 1975 auto Results = completions(Code, {}, Opts); 1976 EXPECT_EQ(Results.Completions.size(), 3u); 1977 1978 TextEdit ReplacementEdit; 1979 ReplacementEdit.range = Annotations(Code).range(); 1980 ReplacementEdit.newText = "."; 1981 for (const auto &C : Results.Completions) { 1982 EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction"); 1983 if (!C.FixIts.empty()) { 1984 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 1985 } 1986 } 1987 } 1988 1989 TEST(CompletionTest, FixItForDotToArrow) { 1990 CodeCompleteOptions Opts; 1991 Opts.IncludeFixIts = true; 1992 const char *Code = 1993 R"cpp( 1994 class Auxilary { 1995 public: 1996 void AuxFunction(); 1997 }; 1998 class ClassWithPtr { 1999 public: 2000 void MemberFunction(); 2001 Auxilary* operator->() const; 2002 Auxilary* Aux; 2003 }; 2004 void f() { 2005 ClassWithPtr x; 2006 x[[.]]^; 2007 } 2008 )cpp"; 2009 auto Results = completions(Code, {}, Opts); 2010 EXPECT_EQ(Results.Completions.size(), 3u); 2011 2012 TextEdit ReplacementEdit; 2013 ReplacementEdit.range = Annotations(Code).range(); 2014 ReplacementEdit.newText = "->"; 2015 for (const auto &C : Results.Completions) { 2016 EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction"); 2017 if (!C.FixIts.empty()) { 2018 EXPECT_THAT(C.FixIts, ElementsAre(ReplacementEdit)); 2019 } 2020 } 2021 } 2022 2023 TEST(CompletionTest, RenderWithFixItMerged) { 2024 TextEdit FixIt; 2025 FixIt.range.end.character = 5; 2026 FixIt.newText = "->"; 2027 2028 CodeCompletion C; 2029 C.Name = "x"; 2030 C.RequiredQualifier = "Foo::"; 2031 C.FixIts = {FixIt}; 2032 C.CompletionTokenRange.start.character = 5; 2033 2034 CodeCompleteOptions Opts; 2035 Opts.IncludeFixIts = true; 2036 2037 auto R = C.render(Opts); 2038 EXPECT_TRUE(R.textEdit); 2039 EXPECT_EQ(R.textEdit->newText, "->Foo::x"); 2040 EXPECT_TRUE(R.additionalTextEdits.empty()); 2041 } 2042 2043 TEST(CompletionTest, RenderWithFixItNonMerged) { 2044 TextEdit FixIt; 2045 FixIt.range.end.character = 4; 2046 FixIt.newText = "->"; 2047 2048 CodeCompletion C; 2049 C.Name = "x"; 2050 C.RequiredQualifier = "Foo::"; 2051 C.FixIts = {FixIt}; 2052 C.CompletionTokenRange.start.character = 5; 2053 2054 CodeCompleteOptions Opts; 2055 Opts.IncludeFixIts = true; 2056 2057 auto R = C.render(Opts); 2058 EXPECT_TRUE(R.textEdit); 2059 EXPECT_EQ(R.textEdit->newText, "Foo::x"); 2060 EXPECT_THAT(R.additionalTextEdits, UnorderedElementsAre(FixIt)); 2061 } 2062 2063 TEST(CompletionTest, CompletionTokenRange) { 2064 MockFS FS; 2065 MockCompilationDatabase CDB; 2066 TestTU TU; 2067 TU.AdditionalFiles["foo/abc/foo.h"] = ""; 2068 2069 constexpr const char *TestCodes[] = { 2070 R"cpp( 2071 class Auxilary { 2072 public: 2073 void AuxFunction(); 2074 }; 2075 void f() { 2076 Auxilary x; 2077 x.[[Aux]]^; 2078 } 2079 )cpp", 2080 R"cpp( 2081 class Auxilary { 2082 public: 2083 void AuxFunction(); 2084 }; 2085 void f() { 2086 Auxilary x; 2087 x.[[]]^; 2088 } 2089 )cpp", 2090 R"cpp( 2091 #include "foo/[[a^/]]foo.h" 2092 )cpp", 2093 R"cpp( 2094 #include "foo/abc/[[fo^o.h"]] 2095 )cpp", 2096 }; 2097 for (const auto &Text : TestCodes) { 2098 Annotations TestCode(Text); 2099 TU.Code = TestCode.code().str(); 2100 auto Results = completions(TU, TestCode.point()); 2101 if (Results.Completions.size() != 1) { 2102 ADD_FAILURE() << "Results.Completions.size() != 1" << Text; 2103 continue; 2104 } 2105 EXPECT_THAT(Results.Completions.front().CompletionTokenRange, 2106 TestCode.range()); 2107 } 2108 } 2109 2110 TEST(SignatureHelpTest, OverloadsOrdering) { 2111 const auto Results = signatures(R"cpp( 2112 void foo(int x); 2113 void foo(int x, float y); 2114 void foo(float x, int y); 2115 void foo(float x, float y); 2116 void foo(int x, int y = 0); 2117 int main() { foo(^); } 2118 )cpp"); 2119 EXPECT_THAT(Results.signatures, 2120 ElementsAre(Sig("foo([[int x]]) -> void"), 2121 Sig("foo([[int x]], [[int y = 0]]) -> void"), 2122 Sig("foo([[float x]], [[int y]]) -> void"), 2123 Sig("foo([[int x]], [[float y]]) -> void"), 2124 Sig("foo([[float x]], [[float y]]) -> void"))); 2125 // We always prefer the first signature. 2126 EXPECT_EQ(0, Results.activeSignature); 2127 EXPECT_EQ(0, Results.activeParameter); 2128 } 2129 2130 TEST(SignatureHelpTest, InstantiatedSignatures) { 2131 StringRef Sig0 = R"cpp( 2132 template <class T> 2133 void foo(T, T, T); 2134 2135 int main() { 2136 foo<int>(^); 2137 } 2138 )cpp"; 2139 2140 EXPECT_THAT(signatures(Sig0).signatures, 2141 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); 2142 2143 StringRef Sig1 = R"cpp( 2144 template <class T> 2145 void foo(T, T, T); 2146 2147 int main() { 2148 foo(10, ^); 2149 })cpp"; 2150 2151 EXPECT_THAT(signatures(Sig1).signatures, 2152 ElementsAre(Sig("foo([[T]], [[T]], [[T]]) -> void"))); 2153 2154 StringRef Sig2 = R"cpp( 2155 template <class ...T> 2156 void foo(T...); 2157 2158 int main() { 2159 foo<int>(^); 2160 } 2161 )cpp"; 2162 2163 EXPECT_THAT(signatures(Sig2).signatures, 2164 ElementsAre(Sig("foo([[T...]]) -> void"))); 2165 2166 // It is debatable whether we should substitute the outer template parameter 2167 // ('T') in that case. Currently we don't substitute it in signature help, but 2168 // do substitute in code complete. 2169 // FIXME: make code complete and signature help consistent, figure out which 2170 // way is better. 2171 StringRef Sig3 = R"cpp( 2172 template <class T> 2173 struct X { 2174 template <class U> 2175 void foo(T, U); 2176 }; 2177 2178 int main() { 2179 X<int>().foo<double>(^) 2180 } 2181 )cpp"; 2182 2183 EXPECT_THAT(signatures(Sig3).signatures, 2184 ElementsAre(Sig("foo([[T]], [[U]]) -> void"))); 2185 } 2186 2187 TEST(SignatureHelpTest, IndexDocumentation) { 2188 Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#"); 2189 Foo0.Documentation = "Doc from the index"; 2190 Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#"); 2191 Foo1.Documentation = "Doc from the index"; 2192 Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#"); 2193 2194 StringRef Sig0 = R"cpp( 2195 int foo(); 2196 int foo(double); 2197 2198 void test() { 2199 foo(^); 2200 } 2201 )cpp"; 2202 2203 EXPECT_THAT( 2204 signatures(Sig0, {Foo0}).signatures, 2205 ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), 2206 AllOf(Sig("foo([[double]]) -> int"), SigDoc("")))); 2207 2208 StringRef Sig1 = R"cpp( 2209 int foo(); 2210 // Overriden doc from sema 2211 int foo(int); 2212 // Doc from sema 2213 int foo(int, int); 2214 2215 void test() { 2216 foo(^); 2217 } 2218 )cpp"; 2219 2220 EXPECT_THAT( 2221 signatures(Sig1, {Foo0, Foo1, Foo2}).signatures, 2222 ElementsAre( 2223 AllOf(Sig("foo() -> int"), SigDoc("Doc from the index")), 2224 AllOf(Sig("foo([[int]]) -> int"), SigDoc("Overriden doc from sema")), 2225 AllOf(Sig("foo([[int]], [[int]]) -> int"), SigDoc("Doc from sema")))); 2226 } 2227 2228 TEST(SignatureHelpTest, DynamicIndexDocumentation) { 2229 MockFS FS; 2230 MockCompilationDatabase CDB; 2231 ClangdServer::Options Opts = ClangdServer::optsForTest(); 2232 Opts.BuildDynamicSymbolIndex = true; 2233 ClangdServer Server(CDB, FS, Opts); 2234 2235 FS.Files[testPath("foo.h")] = R"cpp( 2236 struct Foo { 2237 // Member doc 2238 int foo(); 2239 }; 2240 )cpp"; 2241 Annotations FileContent(R"cpp( 2242 #include "foo.h" 2243 void test() { 2244 Foo f; 2245 f.foo(^); 2246 } 2247 )cpp"); 2248 auto File = testPath("test.cpp"); 2249 Server.addDocument(File, FileContent.code()); 2250 // Wait for the dynamic index being built. 2251 ASSERT_TRUE(Server.blockUntilIdleForTest()); 2252 EXPECT_THAT( 2253 llvm::cantFail(runSignatureHelp(Server, File, FileContent.point())) 2254 .signatures, 2255 ElementsAre(AllOf(Sig("foo() -> int"), SigDoc("Member doc")))); 2256 } 2257 2258 TEST(CompletionTest, CompletionFunctionArgsDisabled) { 2259 CodeCompleteOptions Opts; 2260 Opts.EnableSnippets = true; 2261 Opts.EnableFunctionArgSnippets = false; 2262 2263 { 2264 auto Results = completions( 2265 R"cpp( 2266 void xfoo(); 2267 void xfoo(int x, int y); 2268 void f() { xfo^ })cpp", 2269 {}, Opts); 2270 EXPECT_THAT( 2271 Results.Completions, 2272 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("()")), 2273 AllOf(Named("xfoo"), SnippetSuffix("($0)")))); 2274 } 2275 { 2276 auto Results = completions( 2277 R"cpp( 2278 void xbar(); 2279 void f() { xba^ })cpp", 2280 {}, Opts); 2281 EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf( 2282 Named("xbar"), SnippetSuffix("()")))); 2283 } 2284 { 2285 Opts.BundleOverloads = true; 2286 auto Results = completions( 2287 R"cpp( 2288 void xfoo(); 2289 void xfoo(int x, int y); 2290 void f() { xfo^ })cpp", 2291 {}, Opts); 2292 EXPECT_THAT( 2293 Results.Completions, 2294 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("($0)")))); 2295 } 2296 { 2297 auto Results = completions( 2298 R"cpp( 2299 template <class T, class U> 2300 void xfoo(int a, U b); 2301 void f() { xfo^ })cpp", 2302 {}, Opts); 2303 EXPECT_THAT( 2304 Results.Completions, 2305 UnorderedElementsAre(AllOf(Named("xfoo"), SnippetSuffix("<$1>($0)")))); 2306 } 2307 { 2308 auto Results = completions( 2309 R"cpp( 2310 template <class T> 2311 class foo_class{}; 2312 template <class T> 2313 using foo_alias = T**; 2314 void f() { foo_^ })cpp", 2315 {}, Opts); 2316 EXPECT_THAT( 2317 Results.Completions, 2318 UnorderedElementsAre(AllOf(Named("foo_class"), SnippetSuffix("<$0>")), 2319 AllOf(Named("foo_alias"), SnippetSuffix("<$0>")))); 2320 } 2321 } 2322 2323 TEST(CompletionTest, SuggestOverrides) { 2324 constexpr const char *const Text(R"cpp( 2325 class A { 2326 public: 2327 virtual void vfunc(bool param); 2328 virtual void vfunc(bool param, int p); 2329 void func(bool param); 2330 }; 2331 class B : public A { 2332 virtual void ttt(bool param) const; 2333 void vfunc(bool param, int p) override; 2334 }; 2335 class C : public B { 2336 public: 2337 void vfunc(bool param) override; 2338 ^ 2339 }; 2340 )cpp"); 2341 const auto Results = completions(Text); 2342 EXPECT_THAT( 2343 Results.Completions, 2344 AllOf(Contains(AllOf(Labeled("void vfunc(bool param, int p) override"), 2345 NameStartsWith("vfunc"))), 2346 Contains(AllOf(Labeled("void ttt(bool param) const override"), 2347 NameStartsWith("ttt"))), 2348 Not(Contains(Labeled("void vfunc(bool param) override"))))); 2349 } 2350 2351 TEST(CompletionTest, OverridesNonIdentName) { 2352 // Check the completions call does not crash. 2353 completions(R"cpp( 2354 struct Base { 2355 virtual ~Base() = 0; 2356 virtual operator int() = 0; 2357 virtual Base& operator+(Base&) = 0; 2358 }; 2359 2360 struct Derived : Base { 2361 ^ 2362 }; 2363 )cpp"); 2364 } 2365 2366 TEST(GuessCompletionPrefix, Filters) { 2367 for (llvm::StringRef Case : { 2368 "[[scope::]][[ident]]^", 2369 "[[]][[]]^", 2370 "\n[[]][[]]^", 2371 "[[]][[ab]]^", 2372 "x.[[]][[ab]]^", 2373 "x.[[]][[]]^", 2374 "[[x::]][[ab]]^", 2375 "[[x::]][[]]^", 2376 "[[::x::]][[ab]]^", 2377 "some text [[scope::more::]][[identif]]^ier", 2378 "some text [[scope::]][[mor]]^e::identifier", 2379 "weird case foo::[[::bar::]][[baz]]^", 2380 "/* [[]][[]]^ */", 2381 }) { 2382 Annotations F(Case); 2383 auto Offset = cantFail(positionToOffset(F.code(), F.point())); 2384 auto ToStringRef = [&](Range R) { 2385 return F.code().slice(cantFail(positionToOffset(F.code(), R.start)), 2386 cantFail(positionToOffset(F.code(), R.end))); 2387 }; 2388 auto WantQualifier = ToStringRef(F.ranges()[0]), 2389 WantName = ToStringRef(F.ranges()[1]); 2390 2391 auto Prefix = guessCompletionPrefix(F.code(), Offset); 2392 // Even when components are empty, check their offsets are correct. 2393 EXPECT_EQ(WantQualifier, Prefix.Qualifier) << Case; 2394 EXPECT_EQ(WantQualifier.begin(), Prefix.Qualifier.begin()) << Case; 2395 EXPECT_EQ(WantName, Prefix.Name) << Case; 2396 EXPECT_EQ(WantName.begin(), Prefix.Name.begin()) << Case; 2397 } 2398 } 2399 2400 TEST(CompletionTest, EnableSpeculativeIndexRequest) { 2401 MockFS FS; 2402 MockCompilationDatabase CDB; 2403 ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); 2404 2405 auto File = testPath("foo.cpp"); 2406 Annotations Test(R"cpp( 2407 namespace ns1 { int abc; } 2408 namespace ns2 { int abc; } 2409 void f() { ns1::ab$1^; ns1::ab$2^; } 2410 void f2() { ns2::ab$3^; } 2411 )cpp"); 2412 runAddDocument(Server, File, Test.code()); 2413 clangd::CodeCompleteOptions Opts = {}; 2414 2415 IndexRequestCollector Requests; 2416 Opts.Index = &Requests; 2417 2418 auto CompleteAtPoint = [&](StringRef P) { 2419 cantFail(runCodeComplete(Server, File, Test.point(P), Opts)); 2420 }; 2421 2422 CompleteAtPoint("1"); 2423 auto Reqs1 = Requests.consumeRequests(1); 2424 ASSERT_EQ(Reqs1.size(), 1u); 2425 EXPECT_THAT(Reqs1[0].Scopes, UnorderedElementsAre("ns1::")); 2426 2427 CompleteAtPoint("2"); 2428 auto Reqs2 = Requests.consumeRequests(1); 2429 // Speculation succeeded. Used speculative index result. 2430 ASSERT_EQ(Reqs2.size(), 1u); 2431 EXPECT_EQ(Reqs2[0], Reqs1[0]); 2432 2433 CompleteAtPoint("3"); 2434 // Speculation failed. Sent speculative index request and the new index 2435 // request after sema. 2436 auto Reqs3 = Requests.consumeRequests(2); 2437 ASSERT_EQ(Reqs3.size(), 2u); 2438 } 2439 2440 TEST(CompletionTest, InsertTheMostPopularHeader) { 2441 std::string DeclFile = URI::create(testPath("foo")).toString(); 2442 Symbol Sym = func("Func"); 2443 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2444 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2445 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2446 2447 auto Results = completions("Fun^", {Sym}).Completions; 2448 assert(!Results.empty()); 2449 EXPECT_THAT(Results[0], AllOf(Named("Func"), InsertInclude("\"bar.h\""))); 2450 EXPECT_EQ(Results[0].Includes.size(), 2u); 2451 } 2452 2453 TEST(CompletionTest, NoInsertIncludeIfOnePresent) { 2454 Annotations Test(R"cpp( 2455 #include "foo.h" 2456 Fun^ 2457 )cpp"); 2458 auto TU = TestTU::withCode(Test.code()); 2459 TU.AdditionalFiles["foo.h"] = ""; 2460 2461 std::string DeclFile = URI::create(testPath("foo")).toString(); 2462 Symbol Sym = func("Func"); 2463 Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); 2464 Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); 2465 Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); 2466 2467 EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions, 2468 UnorderedElementsAre(AllOf(Named("Func"), HasInclude("\"foo.h\""), 2469 Not(InsertInclude())))); 2470 } 2471 2472 TEST(CompletionTest, MergeMacrosFromIndexAndSema) { 2473 Symbol Sym; 2474 Sym.Name = "Clangd_Macro_Test"; 2475 Sym.ID = SymbolID("c:foo.cpp@8@macro@Clangd_Macro_Test"); 2476 Sym.SymInfo.Kind = index::SymbolKind::Macro; 2477 Sym.Flags |= Symbol::IndexedForCodeCompletion; 2478 EXPECT_THAT(completions("#define Clangd_Macro_Test\nClangd_Macro_T^", {Sym}) 2479 .Completions, 2480 UnorderedElementsAre(Named("Clangd_Macro_Test"))); 2481 } 2482 2483 TEST(CompletionTest, MacroFromPreamble) { 2484 Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x 2485 2486 int x = 0; 2487 #define CLANGD_MAIN x 2488 void f() { CLANGD_^ } 2489 )cpp"); 2490 auto TU = TestTU::withCode(Test.code()); 2491 TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x"; 2492 auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")}); 2493 // We should get results from the main file, including the preamble section. 2494 // However no results from included files (the index should cover them). 2495 EXPECT_THAT(Results.Completions, 2496 UnorderedElementsAre(Named("CLANGD_PREAMBLE_MAIN"), 2497 Named("CLANGD_MAIN"), 2498 Named("CLANGD_INDEX"))); 2499 } 2500 2501 TEST(CompletionTest, DeprecatedResults) { 2502 std::string Body = R"cpp( 2503 void TestClangd(); 2504 void TestClangc() __attribute__((deprecated("", ""))); 2505 )cpp"; 2506 2507 EXPECT_THAT( 2508 completions(Body + "int main() { TestClang^ }").Completions, 2509 UnorderedElementsAre(AllOf(Named("TestClangd"), Not(Deprecated())), 2510 AllOf(Named("TestClangc"), Deprecated()))); 2511 } 2512 2513 TEST(SignatureHelpTest, PartialSpec) { 2514 const auto Results = signatures(R"cpp( 2515 template <typename T> struct Foo {}; 2516 template <typename T> struct Foo<T*> { Foo(T); }; 2517 Foo<int*> F(^);)cpp"); 2518 EXPECT_THAT(Results.signatures, Contains(Sig("Foo([[T]])"))); 2519 EXPECT_EQ(0, Results.activeParameter); 2520 } 2521 2522 TEST(SignatureHelpTest, InsideArgument) { 2523 { 2524 const auto Results = signatures(R"cpp( 2525 void foo(int x); 2526 void foo(int x, int y); 2527 int main() { foo(1+^); } 2528 )cpp"); 2529 EXPECT_THAT(Results.signatures, 2530 ElementsAre(Sig("foo([[int x]]) -> void"), 2531 Sig("foo([[int x]], [[int y]]) -> void"))); 2532 EXPECT_EQ(0, Results.activeParameter); 2533 } 2534 { 2535 const auto Results = signatures(R"cpp( 2536 void foo(int x); 2537 void foo(int x, int y); 2538 int main() { foo(1^); } 2539 )cpp"); 2540 EXPECT_THAT(Results.signatures, 2541 ElementsAre(Sig("foo([[int x]]) -> void"), 2542 Sig("foo([[int x]], [[int y]]) -> void"))); 2543 EXPECT_EQ(0, Results.activeParameter); 2544 } 2545 { 2546 const auto Results = signatures(R"cpp( 2547 void foo(int x); 2548 void foo(int x, int y); 2549 int main() { foo(1^0); } 2550 )cpp"); 2551 EXPECT_THAT(Results.signatures, 2552 ElementsAre(Sig("foo([[int x]]) -> void"), 2553 Sig("foo([[int x]], [[int y]]) -> void"))); 2554 EXPECT_EQ(0, Results.activeParameter); 2555 } 2556 { 2557 const auto Results = signatures(R"cpp( 2558 void foo(int x); 2559 void foo(int x, int y); 2560 int bar(int x, int y); 2561 int main() { bar(foo(2, 3^)); } 2562 )cpp"); 2563 EXPECT_THAT(Results.signatures, 2564 ElementsAre(Sig("foo([[int x]], [[int y]]) -> void"))); 2565 EXPECT_EQ(1, Results.activeParameter); 2566 } 2567 } 2568 2569 TEST(SignatureHelpTest, ConstructorInitializeFields) { 2570 { 2571 const auto Results = signatures(R"cpp( 2572 struct A { 2573 A(int); 2574 }; 2575 struct B { 2576 B() : a_elem(^) {} 2577 A a_elem; 2578 }; 2579 )cpp"); 2580 EXPECT_THAT(Results.signatures, 2581 UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), 2582 Sig("A([[const A &]])"))); 2583 } 2584 { 2585 const auto Results = signatures(R"cpp( 2586 struct A { 2587 A(int); 2588 }; 2589 struct C { 2590 C(int); 2591 C(A); 2592 }; 2593 struct B { 2594 B() : c_elem(A(1^)) {} 2595 C c_elem; 2596 }; 2597 )cpp"); 2598 EXPECT_THAT(Results.signatures, 2599 UnorderedElementsAre(Sig("A([[int]])"), Sig("A([[A &&]])"), 2600 Sig("A([[const A &]])"))); 2601 } 2602 } 2603 2604 TEST(CompletionTest, IncludedCompletionKinds) { 2605 Annotations Test(R"cpp(#include "^)cpp"); 2606 auto TU = TestTU::withCode(Test.code()); 2607 TU.AdditionalFiles["sub/bar.h"] = ""; 2608 TU.ExtraArgs.push_back("-I" + testPath("sub")); 2609 2610 auto Results = completions(TU, Test.point()); 2611 EXPECT_THAT(Results.Completions, 2612 AllOf(Has("sub/", CompletionItemKind::Folder), 2613 Has("bar.h\"", CompletionItemKind::File))); 2614 } 2615 2616 TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) { 2617 completions( 2618 R"cpp( 2619 #include "./^" 2620 )cpp"); 2621 } 2622 2623 TEST(CompletionTest, NoAllScopesCompletionWhenQualified) { 2624 clangd::CodeCompleteOptions Opts = {}; 2625 Opts.AllScopes = true; 2626 2627 auto Results = completions( 2628 R"cpp( 2629 void f() { na::Clangd^ } 2630 )cpp", 2631 {cls("na::ClangdA"), cls("nx::ClangdX"), cls("Clangd3")}, Opts); 2632 EXPECT_THAT(Results.Completions, 2633 UnorderedElementsAre( 2634 AllOf(Qualifier(""), Scope("na::"), Named("ClangdA")))); 2635 } 2636 2637 TEST(CompletionTest, AllScopesCompletion) { 2638 clangd::CodeCompleteOptions Opts = {}; 2639 Opts.AllScopes = true; 2640 2641 auto Results = completions( 2642 R"cpp( 2643 namespace na { 2644 void f() { Clangd^ } 2645 } 2646 )cpp", 2647 {cls("nx::Clangd1"), cls("ny::Clangd2"), cls("Clangd3"), 2648 cls("na::nb::Clangd4")}, 2649 Opts); 2650 EXPECT_THAT( 2651 Results.Completions, 2652 UnorderedElementsAre(AllOf(Qualifier("nx::"), Named("Clangd1")), 2653 AllOf(Qualifier("ny::"), Named("Clangd2")), 2654 AllOf(Qualifier(""), Scope(""), Named("Clangd3")), 2655 AllOf(Qualifier("nb::"), Named("Clangd4")))); 2656 } 2657 2658 TEST(CompletionTest, NoQualifierIfShadowed) { 2659 clangd::CodeCompleteOptions Opts = {}; 2660 Opts.AllScopes = true; 2661 2662 auto Results = completions(R"cpp( 2663 namespace nx { class Clangd1 {}; } 2664 using nx::Clangd1; 2665 void f() { Clangd^ } 2666 )cpp", 2667 {cls("nx::Clangd1"), cls("nx::Clangd2")}, Opts); 2668 // Although Clangd1 is from another namespace, Sema tells us it's in-scope and 2669 // needs no qualifier. 2670 EXPECT_THAT(Results.Completions, 2671 UnorderedElementsAre(AllOf(Qualifier(""), Named("Clangd1")), 2672 AllOf(Qualifier("nx::"), Named("Clangd2")))); 2673 } 2674 2675 TEST(CompletionTest, NoCompletionsForNewNames) { 2676 clangd::CodeCompleteOptions Opts; 2677 Opts.AllScopes = true; 2678 auto Results = completions(R"cpp( 2679 void f() { int n^ } 2680 )cpp", 2681 {cls("naber"), cls("nx::naber")}, Opts); 2682 EXPECT_THAT(Results.Completions, UnorderedElementsAre()); 2683 } 2684 2685 TEST(CompletionTest, Lambda) { 2686 clangd::CodeCompleteOptions Opts = {}; 2687 2688 auto Results = completions(R"cpp( 2689 void function() { 2690 auto Lambda = [](int a, const double &b) {return 1.f;}; 2691 Lam^ 2692 } 2693 )cpp", 2694 {}, Opts); 2695 2696 ASSERT_EQ(Results.Completions.size(), 1u); 2697 const auto &A = Results.Completions.front(); 2698 EXPECT_EQ(A.Name, "Lambda"); 2699 EXPECT_EQ(A.Signature, "(int a, const double &b) const"); 2700 EXPECT_EQ(A.Kind, CompletionItemKind::Variable); 2701 EXPECT_EQ(A.ReturnType, "float"); 2702 EXPECT_EQ(A.SnippetSuffix, "(${1:int a}, ${2:const double &b})"); 2703 } 2704 2705 TEST(CompletionTest, StructuredBinding) { 2706 clangd::CodeCompleteOptions Opts = {}; 2707 2708 auto Results = completions(R"cpp( 2709 struct S { 2710 using Float = float; 2711 int x; 2712 Float y; 2713 }; 2714 void function() { 2715 const auto &[xxx, yyy] = S{}; 2716 yyy^ 2717 } 2718 )cpp", 2719 {}, Opts); 2720 2721 ASSERT_EQ(Results.Completions.size(), 1u); 2722 const auto &A = Results.Completions.front(); 2723 EXPECT_EQ(A.Name, "yyy"); 2724 EXPECT_EQ(A.Kind, CompletionItemKind::Variable); 2725 EXPECT_EQ(A.ReturnType, "const Float"); 2726 } 2727 2728 TEST(CompletionTest, ObjectiveCMethodNoArguments) { 2729 auto Results = completions(R"objc( 2730 @interface Foo 2731 @property(nonatomic, setter=setXToIgnoreComplete:) int value; 2732 @end 2733 Foo *foo = [Foo new]; int y = [foo v^] 2734 )objc", 2735 /*IndexSymbols=*/{}, 2736 /*Opts=*/{}, "Foo.m"); 2737 2738 auto C = Results.Completions; 2739 EXPECT_THAT(C, ElementsAre(Named("value"))); 2740 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2741 EXPECT_THAT(C, ElementsAre(ReturnType("int"))); 2742 EXPECT_THAT(C, ElementsAre(Signature(""))); 2743 EXPECT_THAT(C, ElementsAre(SnippetSuffix(""))); 2744 } 2745 2746 TEST(CompletionTest, ObjectiveCMethodOneArgument) { 2747 auto Results = completions(R"objc( 2748 @interface Foo 2749 - (int)valueForCharacter:(char)c; 2750 @end 2751 Foo *foo = [Foo new]; int y = [foo v^] 2752 )objc", 2753 /*IndexSymbols=*/{}, 2754 /*Opts=*/{}, "Foo.m"); 2755 2756 auto C = Results.Completions; 2757 EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:"))); 2758 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2759 EXPECT_THAT(C, ElementsAre(ReturnType("int"))); 2760 EXPECT_THAT(C, ElementsAre(Signature("(char)"))); 2761 EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(char)}"))); 2762 } 2763 2764 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromBeginning) { 2765 auto Results = completions(R"objc( 2766 @interface Foo 2767 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 2768 @end 2769 id val = [Foo foo^] 2770 )objc", 2771 /*IndexSymbols=*/{}, 2772 /*Opts=*/{}, "Foo.m"); 2773 2774 auto C = Results.Completions; 2775 EXPECT_THAT(C, ElementsAre(Named("fooWithValue:"))); 2776 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2777 EXPECT_THAT(C, ElementsAre(ReturnType("id"))); 2778 EXPECT_THAT(C, ElementsAre(Signature("(int) fooey:(unsigned int)"))); 2779 EXPECT_THAT( 2780 C, ElementsAre(SnippetSuffix("${1:(int)} fooey:${2:(unsigned int)}"))); 2781 } 2782 2783 TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) { 2784 auto Results = completions(R"objc( 2785 @interface Foo 2786 + (id)fooWithValue:(int)value fooey:(unsigned int)fooey; 2787 @end 2788 id val = [Foo fooWithValue:10 f^] 2789 )objc", 2790 /*IndexSymbols=*/{}, 2791 /*Opts=*/{}, "Foo.m"); 2792 2793 auto C = Results.Completions; 2794 EXPECT_THAT(C, ElementsAre(Named("fooey:"))); 2795 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2796 EXPECT_THAT(C, ElementsAre(ReturnType("id"))); 2797 EXPECT_THAT(C, ElementsAre(Signature("(unsigned int)"))); 2798 EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}"))); 2799 } 2800 2801 TEST(CompletionTest, ObjectiveCSimpleMethodDeclaration) { 2802 auto Results = completions(R"objc( 2803 @interface Foo 2804 - (void)foo; 2805 @end 2806 @implementation Foo 2807 fo^ 2808 @end 2809 )objc", 2810 /*IndexSymbols=*/{}, 2811 /*Opts=*/{}, "Foo.m"); 2812 2813 auto C = Results.Completions; 2814 EXPECT_THAT(C, ElementsAre(Named("foo"))); 2815 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2816 EXPECT_THAT(C, ElementsAre(Qualifier("- (void)"))); 2817 } 2818 2819 TEST(CompletionTest, ObjectiveCMethodDeclaration) { 2820 auto Results = completions(R"objc( 2821 @interface Foo 2822 - (int)valueForCharacter:(char)c secondArgument:(id)object; 2823 @end 2824 @implementation Foo 2825 valueFor^ 2826 @end 2827 )objc", 2828 /*IndexSymbols=*/{}, 2829 /*Opts=*/{}, "Foo.m"); 2830 2831 auto C = Results.Completions; 2832 EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:"))); 2833 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2834 EXPECT_THAT(C, ElementsAre(Qualifier("- (int)"))); 2835 EXPECT_THAT(C, ElementsAre(Signature("(char)c secondArgument:(id)object"))); 2836 } 2837 2838 TEST(CompletionTest, ObjectiveCMethodDeclarationPrefixTyped) { 2839 auto Results = completions(R"objc( 2840 @interface Foo 2841 - (int)valueForCharacter:(char)c; 2842 @end 2843 @implementation Foo 2844 - (int)valueFor^ 2845 @end 2846 )objc", 2847 /*IndexSymbols=*/{}, 2848 /*Opts=*/{}, "Foo.m"); 2849 2850 auto C = Results.Completions; 2851 EXPECT_THAT(C, ElementsAre(Named("valueForCharacter:"))); 2852 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2853 EXPECT_THAT(C, ElementsAre(Signature("(char)c"))); 2854 } 2855 2856 TEST(CompletionTest, ObjectiveCMethodDeclarationFromMiddle) { 2857 auto Results = completions(R"objc( 2858 @interface Foo 2859 - (int)valueForCharacter:(char)c secondArgument:(id)object; 2860 @end 2861 @implementation Foo 2862 - (int)valueForCharacter:(char)c second^ 2863 @end 2864 )objc", 2865 /*IndexSymbols=*/{}, 2866 /*Opts=*/{}, "Foo.m"); 2867 2868 auto C = Results.Completions; 2869 EXPECT_THAT(C, ElementsAre(Named("secondArgument:"))); 2870 EXPECT_THAT(C, ElementsAre(Kind(CompletionItemKind::Method))); 2871 EXPECT_THAT(C, ElementsAre(Signature("(id)object"))); 2872 } 2873 2874 TEST(CompletionTest, CursorInSnippets) { 2875 clangd::CodeCompleteOptions Options; 2876 Options.EnableSnippets = true; 2877 auto Results = completions( 2878 R"cpp( 2879 void while_foo(int a, int b); 2880 void test() { 2881 whil^ 2882 })cpp", 2883 /*IndexSymbols=*/{}, Options); 2884 2885 // Last placeholder in code patterns should be $0 to put the cursor there. 2886 EXPECT_THAT(Results.Completions, 2887 Contains(AllOf( 2888 Named("while"), 2889 SnippetSuffix(" (${1:condition}) {\n${0:statements}\n}")))); 2890 // However, snippets for functions must *not* end with $0. 2891 EXPECT_THAT(Results.Completions, 2892 Contains(AllOf(Named("while_foo"), 2893 SnippetSuffix("(${1:int a}, ${2:int b})")))); 2894 } 2895 2896 TEST(CompletionTest, WorksWithNullType) { 2897 auto R = completions(R"cpp( 2898 int main() { 2899 for (auto [loopVar] : y ) { // y has to be unresolved. 2900 int z = loopV^; 2901 } 2902 } 2903 )cpp"); 2904 EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar"))); 2905 } 2906 2907 TEST(CompletionTest, UsingDecl) { 2908 const char *Header(R"cpp( 2909 void foo(int); 2910 namespace std { 2911 using ::foo; 2912 })cpp"); 2913 const char *Source(R"cpp( 2914 void bar() { 2915 std::^; 2916 })cpp"); 2917 auto Index = TestTU::withHeaderCode(Header).index(); 2918 clangd::CodeCompleteOptions Opts; 2919 Opts.Index = Index.get(); 2920 Opts.AllScopes = true; 2921 auto R = completions(Source, {}, Opts); 2922 EXPECT_THAT(R.Completions, 2923 ElementsAre(AllOf(Scope("std::"), Named("foo"), 2924 Kind(CompletionItemKind::Reference)))); 2925 } 2926 2927 TEST(CompletionTest, ScopeIsUnresolved) { 2928 clangd::CodeCompleteOptions Opts = {}; 2929 Opts.AllScopes = true; 2930 2931 auto Results = completions(R"cpp( 2932 namespace a { 2933 void f() { b::X^ } 2934 } 2935 )cpp", 2936 {cls("a::b::XYZ")}, Opts); 2937 EXPECT_THAT(Results.Completions, 2938 UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); 2939 } 2940 2941 TEST(CompletionTest, NestedScopeIsUnresolved) { 2942 clangd::CodeCompleteOptions Opts = {}; 2943 Opts.AllScopes = true; 2944 2945 auto Results = completions(R"cpp( 2946 namespace a { 2947 namespace b {} 2948 void f() { b::c::X^ } 2949 } 2950 )cpp", 2951 {cls("a::b::c::XYZ")}, Opts); 2952 EXPECT_THAT(Results.Completions, 2953 UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); 2954 } 2955 2956 // Clang parser gets confused here and doesn't report the ns:: prefix. 2957 // Naive behavior is to insert it again. We examine the source and recover. 2958 TEST(CompletionTest, NamespaceDoubleInsertion) { 2959 clangd::CodeCompleteOptions Opts = {}; 2960 2961 auto Results = completions(R"cpp( 2962 namespace foo { 2963 namespace ns {} 2964 #define M(X) < X 2965 M(ns::ABC^ 2966 } 2967 )cpp", 2968 {cls("foo::ns::ABCDE")}, Opts); 2969 EXPECT_THAT(Results.Completions, 2970 UnorderedElementsAre(AllOf(Qualifier(""), Named("ABCDE")))); 2971 } 2972 2973 TEST(CompletionTest, DerivedMethodsAreAlwaysVisible) { 2974 // Despite the fact that base method matches the ref-qualifier better, 2975 // completion results should only include the derived method. 2976 auto Completions = completions(R"cpp( 2977 struct deque_base { 2978 float size(); 2979 double size() const; 2980 }; 2981 struct deque : deque_base { 2982 int size() const; 2983 }; 2984 2985 auto x = deque().^ 2986 )cpp") 2987 .Completions; 2988 EXPECT_THAT(Completions, 2989 ElementsAre(AllOf(ReturnType("int"), Named("size")))); 2990 } 2991 2992 TEST(CompletionTest, NoCrashWithIncompleteLambda) { 2993 auto Completions = completions("auto&& x = []{^").Completions; 2994 // The completion of x itself can cause a problem: in the code completion 2995 // callback, its type is not known, which affects the linkage calculation. 2996 // A bad linkage value gets cached, and subsequently updated. 2997 EXPECT_THAT(Completions, Contains(Named("x"))); 2998 2999 auto Signatures = signatures("auto x() { x(^").signatures; 3000 EXPECT_THAT(Signatures, Contains(Sig("x() -> auto"))); 3001 } 3002 3003 TEST(CompletionTest, DelayedTemplateParsing) { 3004 Annotations Test(R"cpp( 3005 int xxx; 3006 template <typename T> int foo() { return xx^; } 3007 )cpp"); 3008 auto TU = TestTU::withCode(Test.code()); 3009 // Even though delayed-template-parsing is on, we will disable it to provide 3010 // completion in templates. 3011 TU.ExtraArgs.push_back("-fdelayed-template-parsing"); 3012 3013 EXPECT_THAT(completions(TU, Test.point()).Completions, 3014 Contains(Named("xxx"))); 3015 } 3016 3017 TEST(CompletionTest, CompletionRange) { 3018 const char *WithRange = "auto x = [[abc]]^"; 3019 auto Completions = completions(WithRange); 3020 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range()); 3021 Completions = completionsNoCompile(WithRange); 3022 EXPECT_EQ(Completions.CompletionRange, Annotations(WithRange).range()); 3023 3024 const char *EmptyRange = "auto x = [[]]^"; 3025 Completions = completions(EmptyRange); 3026 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range()); 3027 Completions = completionsNoCompile(EmptyRange); 3028 EXPECT_EQ(Completions.CompletionRange, Annotations(EmptyRange).range()); 3029 3030 // Sema doesn't trigger at all here, while the no-sema completion runs 3031 // heuristics as normal and reports a range. It'd be nice to be consistent. 3032 const char *NoCompletion = "/* [[]]^ */"; 3033 Completions = completions(NoCompletion); 3034 EXPECT_EQ(Completions.CompletionRange, llvm::None); 3035 Completions = completionsNoCompile(NoCompletion); 3036 EXPECT_EQ(Completions.CompletionRange, Annotations(NoCompletion).range()); 3037 } 3038 3039 TEST(NoCompileCompletionTest, Basic) { 3040 auto Results = completionsNoCompile(R"cpp( 3041 void func() { 3042 int xyz; 3043 int abc; 3044 ^ 3045 } 3046 )cpp"); 3047 EXPECT_FALSE(Results.RanParser); 3048 EXPECT_THAT(Results.Completions, 3049 UnorderedElementsAre(Named("void"), Named("func"), Named("int"), 3050 Named("xyz"), Named("abc"))); 3051 } 3052 3053 TEST(NoCompileCompletionTest, WithFilter) { 3054 auto Results = completionsNoCompile(R"cpp( 3055 void func() { 3056 int sym1; 3057 int sym2; 3058 int xyz1; 3059 int xyz2; 3060 sy^ 3061 } 3062 )cpp"); 3063 EXPECT_THAT(Results.Completions, 3064 UnorderedElementsAre(Named("sym1"), Named("sym2"))); 3065 } 3066 3067 TEST(NoCompileCompletionTest, WithIndex) { 3068 std::vector<Symbol> Syms = {func("xxx"), func("a::xxx"), func("ns::b::xxx"), 3069 func("c::xxx"), func("ns::d::xxx")}; 3070 auto Results = completionsNoCompile( 3071 R"cpp( 3072 // Current-scopes, unqualified completion. 3073 using namespace a; 3074 namespace ns { 3075 using namespace b; 3076 void foo() { 3077 xx^ 3078 } 3079 } 3080 )cpp", 3081 Syms); 3082 EXPECT_THAT(Results.Completions, 3083 UnorderedElementsAre(AllOf(Qualifier(""), Scope("")), 3084 AllOf(Qualifier(""), Scope("a::")), 3085 AllOf(Qualifier(""), Scope("ns::b::")))); 3086 CodeCompleteOptions Opts; 3087 Opts.AllScopes = true; 3088 Results = completionsNoCompile( 3089 R"cpp( 3090 // All-scopes unqualified completion. 3091 using namespace a; 3092 namespace ns { 3093 using namespace b; 3094 void foo() { 3095 xx^ 3096 } 3097 } 3098 )cpp", 3099 Syms, Opts); 3100 EXPECT_THAT(Results.Completions, 3101 UnorderedElementsAre(AllOf(Qualifier(""), Scope("")), 3102 AllOf(Qualifier(""), Scope("a::")), 3103 AllOf(Qualifier(""), Scope("ns::b::")), 3104 AllOf(Qualifier("c::"), Scope("c::")), 3105 AllOf(Qualifier("d::"), Scope("ns::d::")))); 3106 Results = completionsNoCompile( 3107 R"cpp( 3108 // Qualified completion. 3109 using namespace a; 3110 namespace ns { 3111 using namespace b; 3112 void foo() { 3113 b::xx^ 3114 } 3115 } 3116 )cpp", 3117 Syms, Opts); 3118 EXPECT_THAT(Results.Completions, 3119 ElementsAre(AllOf(Qualifier(""), Scope("ns::b::")))); 3120 Results = completionsNoCompile( 3121 R"cpp( 3122 // Absolutely qualified completion. 3123 using namespace a; 3124 namespace ns { 3125 using namespace b; 3126 void foo() { 3127 ::a::xx^ 3128 } 3129 } 3130 )cpp", 3131 Syms, Opts); 3132 EXPECT_THAT(Results.Completions, 3133 ElementsAre(AllOf(Qualifier(""), Scope("a::")))); 3134 } 3135 3136 TEST(AllowImplicitCompletion, All) { 3137 const char *Yes[] = { 3138 "foo.^bar", 3139 "foo->^bar", 3140 "foo::^bar", 3141 " # include <^foo.h>", 3142 "#import <foo/^bar.h>", 3143 "#include_next \"^", 3144 }; 3145 const char *No[] = { 3146 "foo>^bar", 3147 "foo:^bar", 3148 "foo\n^bar", 3149 "#include <foo.h> //^", 3150 "#include \"foo.h\"^", 3151 "#error <^", 3152 "#<^", 3153 }; 3154 for (const char *Test : Yes) { 3155 llvm::Annotations A(Test); 3156 EXPECT_TRUE(allowImplicitCompletion(A.code(), A.point())) << Test; 3157 } 3158 for (const char *Test : No) { 3159 llvm::Annotations A(Test); 3160 EXPECT_FALSE(allowImplicitCompletion(A.code(), A.point())) << Test; 3161 } 3162 } 3163 3164 TEST(CompletionTest, FunctionArgsExist) { 3165 clangd::CodeCompleteOptions Opts; 3166 Opts.EnableSnippets = true; 3167 std::string Context = R"cpp( 3168 int foo(int A); 3169 int bar(); 3170 struct Object { 3171 Object(int B) {} 3172 }; 3173 template <typename T> 3174 struct Container { 3175 Container(int Size) {} 3176 }; 3177 )cpp"; 3178 EXPECT_THAT(completions(Context + "int y = fo^", {}, Opts).Completions, 3179 UnorderedElementsAre( 3180 AllOf(Labeled("foo(int A)"), SnippetSuffix("(${1:int A})")))); 3181 EXPECT_THAT( 3182 completions(Context + "int y = fo^(42)", {}, Opts).Completions, 3183 UnorderedElementsAre(AllOf(Labeled("foo(int A)"), SnippetSuffix("")))); 3184 // FIXME(kirillbobyrev): No snippet should be produced here. 3185 EXPECT_THAT(completions(Context + "int y = fo^o(42)", {}, Opts).Completions, 3186 UnorderedElementsAre( 3187 AllOf(Labeled("foo(int A)"), SnippetSuffix("(${1:int A})")))); 3188 EXPECT_THAT( 3189 completions(Context + "int y = ba^", {}, Opts).Completions, 3190 UnorderedElementsAre(AllOf(Labeled("bar()"), SnippetSuffix("()")))); 3191 EXPECT_THAT(completions(Context + "int y = ba^()", {}, Opts).Completions, 3192 UnorderedElementsAre(AllOf(Labeled("bar()"), SnippetSuffix("")))); 3193 EXPECT_THAT( 3194 completions(Context + "Object o = Obj^", {}, Opts).Completions, 3195 Contains(AllOf(Labeled("Object(int B)"), SnippetSuffix("(${1:int B})"), 3196 Kind(CompletionItemKind::Constructor)))); 3197 EXPECT_THAT(completions(Context + "Object o = Obj^()", {}, Opts).Completions, 3198 Contains(AllOf(Labeled("Object(int B)"), SnippetSuffix(""), 3199 Kind(CompletionItemKind::Constructor)))); 3200 EXPECT_THAT( 3201 completions(Context + "Container c = Cont^", {}, Opts).Completions, 3202 Contains(AllOf(Labeled("Container<typename T>(int Size)"), 3203 SnippetSuffix("<${1:typename T}>(${2:int Size})"), 3204 Kind(CompletionItemKind::Constructor)))); 3205 EXPECT_THAT( 3206 completions(Context + "Container c = Cont^()", {}, Opts).Completions, 3207 Contains(AllOf(Labeled("Container<typename T>(int Size)"), 3208 SnippetSuffix("<${1:typename T}>"), 3209 Kind(CompletionItemKind::Constructor)))); 3210 EXPECT_THAT( 3211 completions(Context + "Container c = Cont^<int>()", {}, Opts).Completions, 3212 Contains(AllOf(Labeled("Container<typename T>(int Size)"), 3213 SnippetSuffix(""), 3214 Kind(CompletionItemKind::Constructor)))); 3215 } 3216 3217 TEST(CompletionTest, NoCrashDueToMacroOrdering) { 3218 EXPECT_THAT(completions(R"cpp( 3219 #define ECHO(X) X 3220 #define ECHO2(X) ECHO(X) 3221 int finish_preamble = EC^HO(2);)cpp") 3222 .Completions, 3223 UnorderedElementsAre(Labeled("ECHO(X)"), Labeled("ECHO2(X)"))); 3224 } 3225 3226 TEST(CompletionTest, ObjCCategoryDecls) { 3227 TestTU TU; 3228 TU.ExtraArgs.push_back("-xobjective-c"); 3229 TU.HeaderCode = R"objc( 3230 @interface Foo 3231 @end 3232 3233 @interface Foo (FooExt1) 3234 @end 3235 3236 @interface Foo (FooExt2) 3237 @end 3238 3239 @interface Bar 3240 @end 3241 3242 @interface Bar (BarExt) 3243 @end)objc"; 3244 3245 { 3246 Annotations Test(R"objc( 3247 @implementation Foo (^) 3248 @end 3249 )objc"); 3250 TU.Code = Test.code().str(); 3251 auto Results = completions(TU, Test.point()); 3252 EXPECT_THAT(Results.Completions, 3253 UnorderedElementsAre(Labeled("FooExt1"), Labeled("FooExt2"))); 3254 } 3255 { 3256 Annotations Test(R"objc( 3257 @interface Foo (^) 3258 @end 3259 )objc"); 3260 TU.Code = Test.code().str(); 3261 auto Results = completions(TU, Test.point()); 3262 EXPECT_THAT(Results.Completions, UnorderedElementsAre(Labeled("BarExt"))); 3263 } 3264 } 3265 } // namespace 3266 } // namespace clangd 3267 } // namespace clang 3268