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