Index: unittests/clang-tidy/CMakeLists.txt =================================================================== --- unittests/clang-tidy/CMakeLists.txt +++ unittests/clang-tidy/CMakeLists.txt @@ -12,6 +12,7 @@ IncludeInserterTest.cpp GoogleModuleTest.cpp LLVMModuleTest.cpp + ModernizerModuleTest.cpp NamespaceAliaserTest.cpp ObjCModuleTest.cpp OverlappingReplacementsTest.cpp @@ -29,6 +30,7 @@ clangTidyAndroidModule clangTidyGoogleModule clangTidyLLVMModule + clangTidyModernizeModule clangTidyObjCModule clangTidyReadabilityModule clangTidyUtils Index: unittests/clang-tidy/ClangTidyTest.h =================================================================== --- unittests/clang-tidy/ClangTidyTest.h +++ unittests/clang-tidy/ClangTidyTest.h @@ -13,6 +13,7 @@ #include "ClangTidy.h" #include "ClangTidyDiagnosticConsumer.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/Refactoring.h" @@ -140,7 +141,32 @@ } if (Errors) *Errors = Context.getErrors(); - auto Result = tooling::applyAllReplacements(Code, Fixes); + + if (Options.FormatStyle) { + llvm::Expected Style = format::getStyle( + *Options.FormatStyle, Filename.getSingleStringRef(), "LLVM"); + + llvm::Expected CleannedReplacements = + format::cleanupAroundReplacements(Code, Fixes, *Style); + if (!CleannedReplacements) { + llvm::errs() << llvm::toString(CleannedReplacements.takeError()) << "\n"; + return ""; + } + if (llvm::Expected FormattedReplacements = + format::formatReplacements(Code, *CleannedReplacements, *Style)) { + CleannedReplacements = std::move(FormattedReplacements); + if (!CleannedReplacements) + return ""; + } else { + llvm::errs() << llvm::toString(FormattedReplacements.takeError()) + << ". Skipping formatting.\n"; + return ""; + } + Fixes = *CleannedReplacements; + } + + llvm::Expected Result = + tooling::applyAllReplacements(Code, Fixes); if (!Result) { // FIXME: propogate the error. llvm::consumeError(Result.takeError()); @@ -149,6 +175,21 @@ return *Result; } +template +std::string runCheckAndFormatOnCode( + StringRef Code, StringRef FormatStyle = "llvm", + std::vector *Errors = nullptr, + const Twine &Filename = "input.cc", ArrayRef ExtraArgs = None, + const ClangTidyOptions &ExtraOptions = ClangTidyOptions(), + std::map PathsToContent = + std::map()) { + + ClangTidyOptions Options = ExtraOptions; + Options.FormatStyle = FormatStyle; + return runCheckOnCode(Code, Errors, Filename, ExtraArgs, + Options, PathsToContent); +} + #define EXPECT_NO_CHANGES(Check, Code) \ EXPECT_EQ(Code, runCheckOnCode(Code)) Index: unittests/clang-tidy/ModernizerModuleTest.cpp =================================================================== --- /dev/null +++ unittests/clang-tidy/ModernizerModuleTest.cpp @@ -0,0 +1,92 @@ +#include "ClangTidyTest.h" +#include "modernize/UseDefaultMemberInitCheck.h" +#include "gtest/gtest.h" + +using namespace clang::tidy::modernize; + +namespace clang { +namespace tidy { +namespace test { + +TEST(UseDefaultMemberInitCheckTest, NoChanges) { + EXPECT_NO_CHANGES( + UseDefaultMemberInitCheck, + "struct S { S() = default; bool a_ = false; bool b_ = false; };"); + EXPECT_NO_CHANGES(UseDefaultMemberInitCheck, "struct S { S() : a_(true), " + "b_(true) {} bool a_{false}; " + "bool b_{false}; };"); +} + +TEST(UseDefaultMemberInitCheckTest, Basic) { + EXPECT_EQ("struct S {\n" + " S() {}\n" + " bool a_{false};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() : a_(false) {} bool a_; };")); +} + +TEST(UseDefaultMemberInitCheckTest, SeveralInitializers) { + EXPECT_EQ( + "struct S {\n" + " S() {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() : a_(false), b_(true) {} bool a_; bool b_; };")); +} + +TEST(UseDefaultMemberInitCheckTest, ExceptSpec) { + EXPECT_EQ( + "struct S {\n" + " S() noexcept(true) {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() noexcept(true) : a_(false), b_(true) {} bool a_; " + "bool b_; };")); + EXPECT_EQ( + "#define NOEXCEPT_(X) noexcept(X)\n" + "struct S {\n" + " S() NOEXCEPT_(true) {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "#define NOEXCEPT_(X) noexcept(X)\n" + "struct S { S() NOEXCEPT_(true) : a_(false), b_(true) {} bool a_; " + "bool b_; };")); +} + +TEST(UseDefaultMemberInitCheckTest, OnExisting) { + EXPECT_EQ("struct S {\n" + " S() {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() : a_(false), b_(true) {} bool a_{false}; bool " + "b_{true}; };")); + EXPECT_EQ("struct S {\n" + " S() : a_(true) {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() : a_(true), b_(true) {} bool a_{false}; bool " + "b_{true}; };")); + EXPECT_EQ("struct S {\n" + " S() : b_(false) {}\n" + " bool a_{false};\n" + " bool b_{true};\n" + "};", + runCheckAndFormatOnCode( + "struct S { S() : a_(false), b_(false) {} bool a_{false}; bool " + "b_{true}; };")); +} + +} // namespace test +} // namespace tidy +} // namespace clang