diff --git a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp @@ -8,10 +8,7 @@ #include "ParsedAST.h" #include "refactor/InsertionPoint.h" #include "refactor/Tweak.h" -#include "support/Logger.h" #include "clang/AST/DeclCXX.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "clang/Sema/Sema.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/StringRef.h" @@ -84,7 +81,7 @@ // - to understand the implicit behavior // - to avoid relying on the implicit behavior // - as a baseline for explicit modification -class DeclareCopyMove : public Tweak { +class SpecialMembers : public Tweak { public: const char *id() const final; llvm::StringLiteral kind() const override { @@ -103,7 +100,7 @@ // Trigger only on class definitions. if (auto *N = Inputs.ASTSelection.commonAncestor()) Class = const_cast(N->ASTNode.get()); - if (!Class || !Class->isThisDeclarationADefinition()) + if (!Class || !Class->isThisDeclarationADefinition() || Class->isUnion()) return false; // Tweak is only available if some members are missing. @@ -146,7 +143,7 @@ bool NeedCopy = false, NeedMove = false; CXXRecordDecl *Class = nullptr; }; -REGISTER_TWEAK(DeclareCopyMove) +REGISTER_TWEAK(SpecialMembers) } // namespace } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -104,12 +104,13 @@ support/CancellationTests.cpp support/ContextTests.cpp + support/FileCacheTests.cpp support/FunctionTests.cpp support/MarkupTests.cpp support/MemoryTreeTests.cpp support/PathTests.cpp - support/ThreadingTests.cpp support/TestTracer.cpp + support/ThreadingTests.cpp support/TraceTests.cpp tweaks/AddUsingTests.cpp @@ -130,6 +131,7 @@ tweaks/RawStringLiteralTests.cpp tweaks/RemoveUsingNamespaceTests.cpp tweaks/ShowSelectionTreeTests.cpp + tweaks/SpecialMembersTests.cpp tweaks/SwapIfBranchesTests.cpp tweaks/TweakTesting.cpp tweaks/TweakTests.cpp diff --git a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp --- a/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp +++ b/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp @@ -11,9 +11,9 @@ #include "TestFS.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include #include #include +#include namespace clang { namespace clangd { @@ -34,10 +34,10 @@ FS.Files.erase(testPath("foo.cc")); } - std::string get(std::chrono::steady_clock::time_point FreshTime, - bool ExpectParse) const { + std::pair + get(std::chrono::steady_clock::time_point FreshTime) const { bool GotParse = false; - bool GotRead; + bool GotRead = false; std::string Result; read( FS, FreshTime, @@ -49,12 +49,14 @@ GotRead = true; Result = Value; }); - EXPECT_EQ(GotParse, ExpectParse); EXPECT_TRUE(GotRead); - return Result; + return {Result, GotParse}; } }; +MATCHER_P(Parsed, Value, "") { return arg.second && arg.first == Value; } +MATCHER_P(Cached, Value, "") { return !arg.second && arg.first == Value; } + TEST(FileCacheTest, Invalidation) { TestCache C; @@ -62,20 +64,20 @@ auto MustBeFresh = StaleOK + std::chrono::hours(1); C.setContents("a"); - EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/true)) << "Parsed first time"; - EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; - EXPECT_EQ("a", C.get(MustBeFresh, /*ExpectParse=*/false)) << "Cached (stat)"; + EXPECT_THAT(C.get(StaleOK), Parsed("a")) << "Parsed first time"; + EXPECT_THAT(C.get(StaleOK), Cached("a")) << "Cached (time)"; + EXPECT_THAT(C.get(MustBeFresh), Cached("a")) << "Cached (stat)"; C.setContents("bb"); - EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; - EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Size changed"; - EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Cached (stat)"; + EXPECT_THAT(C.get(StaleOK), Cached("a")) << "Cached (time)"; + EXPECT_THAT(C.get(MustBeFresh), Parsed("bb")) << "Size changed"; + EXPECT_THAT(C.get(MustBeFresh), Cached("bb")) << "Cached (stat)"; C.setContents(nullptr); - EXPECT_EQ("bb", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; - EXPECT_EQ("", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Stat failed"; - EXPECT_EQ("", C.get(MustBeFresh, /*ExpectParse=*/false)) << "Cached (404)"; + EXPECT_THAT(C.get(StaleOK), Cached("bb")) << "Cached (time)"; + EXPECT_THAT(C.get(MustBeFresh), Parsed("")) << "stat failed"; + EXPECT_THAT(C.get(MustBeFresh), Cached("")) << "Cached (404)"; C.setContents("bb"); // Match the previous stat values! - EXPECT_EQ("", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; - EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Size changed"; + EXPECT_THAT(C.get(StaleOK), Cached("")) << "Cached (time)"; + EXPECT_THAT(C.get(MustBeFresh), Parsed("bb")) << "Size changed"; } } // namespace diff --git a/clang-tools-extra/clangd/unittests/tweaks/SpecialMembersTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/SpecialMembersTests.cpp --- a/clang-tools-extra/clangd/unittests/tweaks/SpecialMembersTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/SpecialMembersTests.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// #include "TweakTesting.h" -#include "gmock/gmock-matchers.h" -#include "gmock/gmock.h" #include "gtest/gtest.h" namespace clang { @@ -27,17 +25,17 @@ "S &operator=(S&&); S &operator=(const S&);" "};"); - const char *Output = R"cpp(struct S{S(const S &) = default; - S(S &&) = default; - S &operator=(const S &) = default; - S &operator=(S &&) = default; + const char *Output = R"cpp(struct S{S(const S&) = default; +S(S&&) = default; +S &operator=(const S&) = default; +S &operator=(S&&) = default; };)cpp"; EXPECT_EQ(apply("struct ^S{};"), Output); - Output = R"cpp(struct S{S(const S &) = default; -S(S &&) = default; -S &operator=(const S &) = delete; -S &operator=(S &&) = delete; + Output = R"cpp(struct S{S(const S&) = default; +S(S&&) = default; +S &operator=(const S&) = delete; +S &operator=(S&&) = delete; int& ref;};)cpp"; EXPECT_EQ(apply("struct ^S{int& ref;};"), Output); }