Index: clangd/CodeCompleteTests.cpp =================================================================== --- clangd/CodeCompleteTests.cpp +++ clangd/CodeCompleteTests.cpp @@ -2040,6 +2040,336 @@ } } +TEST(CompletionTestNoExplicitMembers, Struct) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + struct foo {}; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + +TEST(CompletionTestNoExplicitMembers, StructTemplate) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + template struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + template struct foo {}; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + +TEST(CompletionTestNoExplicitMembers, ExplicitStructTemplateSpecialization) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo {}; template<> struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + template struct foo {}; template<> struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + template struct foo {}; template<> struct foo {}; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + +TEST(CompletionTestMethodDeclared, Struct) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + struct foo { void foomethod(); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsDot.Completions.size() == 1); + EXPECT_TRUE(ResultsDot.Completions.front().Name == "foomethod"); + + auto ResultsArrow = completions(R"cpp( + struct foo { void foomethod(); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsArrow.Completions.size() == 1); + EXPECT_TRUE(ResultsArrow.Completions.front().Name == "foomethod"); + + auto ResultsQualified = completions(R"cpp( + struct foo { void foomethod(); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualified.Completions.size() == 1); + EXPECT_TRUE(ResultsQualified.Completions.front().Name == "foomethod"); + + auto ResultsQualifiedStatic = completions(R"cpp( + struct foo { static void foomethod(); }; + void bar() { + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualifiedStatic.Completions.size() == 1); + EXPECT_TRUE(ResultsQualifiedStatic.Completions.front().Name == "foomethod"); +} + +TEST(CompletionTestMethodDeclared, StructTemplate) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo { void foomethod(); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsDot.Completions.size() == 1); + EXPECT_TRUE(ResultsDot.Completions.front().Name == "foomethod"); + + auto ResultsArrow = completions(R"cpp( + template struct foo { void foomethod(); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsArrow.Completions.size() == 1); + EXPECT_TRUE(ResultsArrow.Completions.front().Name == "foomethod"); + + auto ResultsQualified = completions(R"cpp( + template struct foo { void foomethod(); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualified.Completions.size() == 1); + EXPECT_TRUE(ResultsQualified.Completions.front().Name == "foomethod"); + + auto ResultsQualifiedStatic = completions(R"cpp( + template struct foo { static void foomethod(); }; + void bar() { + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualifiedStatic.Completions.size() == 1); + EXPECT_TRUE(ResultsQualifiedStatic.Completions.front().Name == "foomethod"); +} + +TEST(CompletionTestMethodDeclared, ExplicitStructTemplateSpecialization) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo { void foomethod_T(); }; template<> struct foo { void foomethod_bool(); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsDot.Completions.size() == 1); + EXPECT_TRUE(ResultsDot.Completions.front().Name == "foomethod_bool"); + + auto ResultsArrow = completions(R"cpp( + template struct foo { void foomethod_T(); }; template<> struct foo { void foomethod_bool(); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsArrow.Completions.size() == 1); + EXPECT_TRUE(ResultsArrow.Completions.front().Name == "foomethod_bool"); + + auto ResultsQualified = completions(R"cpp( + template struct foo { void foomethod_T(); }; template<> struct foo { void foomethod_bool(); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualified.Completions.size() == 1); + EXPECT_TRUE(ResultsQualified.Completions.front().Name == "foomethod_bool"); + + auto ResultsQualifiedStatic = completions(R"cpp( + template struct foo { static void foomethod_T(); }; template<> struct foo { static void foomethod_bool(); }; + void bar() { + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + ASSERT_TRUE(ResultsQualifiedStatic.Completions.size() == 1); + EXPECT_TRUE(ResultsQualifiedStatic.Completions.front().Name == "foomethod_bool"); +} + +TEST(CompletionTestSpecialMethodsDeclared, Struct) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + +TEST(CompletionTestSpecialMethodsDeclared, StructTemplate) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + +TEST(CompletionTestSpecialMethodsDeclared, ExplicitStructTemplateSpecialization) { + clangd::CodeCompleteOptions Opts; + Opts.Limit = 1; + auto ResultsDot = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsDot.Completions.empty()); + + auto ResultsArrow = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsArrow.Completions.empty()); + + auto ResultsQualified = completions(R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp", + /*IndexSymbols=*/{}, Opts); + + EXPECT_TRUE(ResultsQualified.Completions.empty()); +} + } // namespace } // namespace clangd } // namespace clang