diff --git a/clang/unittests/Format/BracesInserterTest.cpp b/clang/unittests/Format/BracesInserterTest.cpp new file mode 100644 index 0000000000000..c685907451835 --- /dev/null +++ b/clang/unittests/Format/BracesInserterTest.cpp @@ -0,0 +1,336 @@ +//===- unittest/Format/BracesInserterTest.cpp -----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Format/Format.h" + +#include "../Tooling/ReplacementTest.h" +#include "FormatTestUtils.h" + +#define DEBUG_TYPE "braces-inserter-test" + +namespace clang { +namespace format { +namespace { + +class BracesInserterTest : public ::testing::Test { +protected: + std::string format(llvm::StringRef Code, const FormatStyle &Style, + const std::vector &Ranges) { + LLVM_DEBUG(llvm::errs() << "---\n"); + LLVM_DEBUG(llvm::errs() << Code << "\n\n"); + auto NonEmptyRanges = Ranges; + if (Ranges.empty()) + NonEmptyRanges = {1, tooling::Range(0, Code.size())}; + FormattingAttemptStatus Status; + tooling::Replacements Replaces = + reformat(Style, Code, NonEmptyRanges, "", &Status); + EXPECT_EQ(true, Status.FormatComplete) << Code << "\n\n"; + ReplacementCount = Replaces.size(); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast(Result)); + LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, + llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle(), + const std::vector &Ranges = {}) { + testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); + EXPECT_EQ(Expected.str(), format(Expected, Style, Ranges)) + << "Expected code is not stable"; + EXPECT_EQ(Expected.str(), format(Code, Style, Ranges)); + if (Style.Language == FormatStyle::LK_Cpp && Ranges.empty()) { + // Objective-C++ is a superset of C++, so everything checked for C++ + // needs to be checked for Objective-C++ as well. + FormatStyle ObjCStyle = Style; + ObjCStyle.Language = FormatStyle::LK_ObjC; + EXPECT_EQ(Expected.str(), format(test::messUp(Code), ObjCStyle, Ranges)); + } + } + + void _verifyFormat(const char *File, int Line, llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle(), + const std::vector &Ranges = {}) { + _verifyFormat(File, Line, Code, Code, Style, Ranges); + } + + int ReplacementCount; +}; + +#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) + +TEST_F(BracesInserterTest, InsertBraces) { + FormatStyle Style = getLLVMStyle(); + Style.InsertBraces = true; + + verifyFormat("// clang-format off\n" + "// comment\n" + "if (a) f();\n" + "// clang-format on\n" + "if (b) {\n" + " g();\n" + "}", + "// clang-format off\n" + "// comment\n" + "if (a) f();\n" + "// clang-format on\n" + "if (b) g();", + Style); + + verifyFormat("if (a) {\n" + " switch (b) {\n" + " case 1:\n" + " c = 0;\n" + " break;\n" + " default:\n" + " c = 1;\n" + " }\n" + "}", + "if (a)\n" + " switch (b) {\n" + " case 1:\n" + " c = 0;\n" + " break;\n" + " default:\n" + " c = 1;\n" + " }", + Style); + + verifyFormat("for (auto node : nodes) {\n" + " if (node) {\n" + " break;\n" + " }\n" + "}", + "for (auto node : nodes)\n" + " if (node)\n" + " break;", + Style); + + verifyFormat("for (auto node : nodes) {\n" + " if (node)\n" + "}", + "for (auto node : nodes)\n" + " if (node)", + Style); + + verifyFormat("do {\n" + " --a;\n" + "} while (a);", + "do\n" + " --a;\n" + "while (a);", + Style); + + verifyFormat("if (i) {\n" + " ++i;\n" + "} else {\n" + " --i;\n" + "}", + "if (i)\n" + " ++i;\n" + "else {\n" + " --i;\n" + "}", + Style); + + verifyFormat("void f() {\n" + " while (j--) {\n" + " while (i) {\n" + " --i;\n" + " }\n" + " }\n" + "}", + "void f() {\n" + " while (j--)\n" + " while (i)\n" + " --i;\n" + "}", + Style); + + verifyFormat("f({\n" + " if (a) {\n" + " g();\n" + " }\n" + "});", + "f({\n" + " if (a)\n" + " g();\n" + "});", + Style); + + verifyFormat("if (a) {\n" + " f();\n" + "} else if (b) {\n" + " g();\n" + "} else {\n" + " h();\n" + "}", + "if (a)\n" + " f();\n" + "else if (b)\n" + " g();\n" + "else\n" + " h();", + Style); + + verifyFormat("if (a) {\n" + " f();\n" + "}\n" + "// comment\n" + "/* comment */", + "if (a)\n" + " f();\n" + "// comment\n" + "/* comment */", + Style); + + verifyFormat("if (a) {\n" + " // foo\n" + " // bar\n" + " f();\n" + "}", + "if (a)\n" + " // foo\n" + " // bar\n" + " f();", + Style); + + verifyFormat("if (a) { //\n" + " b = 1;\n" + "}", + "if (a) //\n" + " b = 1;", + Style); + + verifyFormat("if (a) { // comment\n" + " // comment\n" + " f();\n" + "}", + "if (a) // comment\n" + " // comment\n" + " f();", + Style); + + verifyFormat("if (a) {\n" + " f(); // comment\n" + "}", + "if (a)\n" + " f(); // comment", + Style); + + verifyFormat("if (a) {\n" + " f();\n" + "}\n" + "#undef A\n" + "#undef B", + "if (a)\n" + " f();\n" + "#undef A\n" + "#undef B", + Style); + + verifyFormat("if (a)\n" + "#ifdef A\n" + " f();\n" + "#else\n" + " g();\n" + "#endif", + Style); + + verifyFormat("#if 0\n" + "#elif 1\n" + "#endif\n" + "void f() {\n" + " if (a) {\n" + " g();\n" + " }\n" + "}", + "#if 0\n" + "#elif 1\n" + "#endif\n" + "void f() {\n" + " if (a) g();\n" + "}", + Style); + + verifyFormat("do {\n" + "#if 0\n" + "#else\n" + " if (b) {\n" + "#endif\n" + " }\n" + "} while (0);", + Style); + + Style.RemoveBracesLLVM = true; + verifyFormat("if (a) //\n" + " return b;", + Style); + Style.RemoveBracesLLVM = false; + + Style.ColumnLimit = 15; + + verifyFormat("#define A \\\n" + " if (a) \\\n" + " f();", + Style); + + verifyFormat("if (a + b >\n" + " c) {\n" + " f();\n" + "}", + "if (a + b > c)\n" + " f();", + Style); + + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; + + verifyFormat("if (a) //\n" + "{\n" + " b = 1;\n" + "}", + "if (a) //\n" + " b = 1;", + Style); +} + +TEST_F(BracesInserterTest, InsertBracesRange) { + FormatStyle Style = getLLVMStyle(); + Style.InsertBraces = true; + + const StringRef Code("while (a)\n" + " if (b)\n" + " return;"); + + verifyFormat("while (a) {\n" + " if (b)\n" + " return;\n" + "}", + Code, Style, {tooling::Range(0, 9)}); // line 1 + + verifyFormat("while (a) {\n" + " if (b) {\n" + " return;\n" + " }\n" + "}", + Code, Style, {tooling::Range(0, 18)}); // lines 1-2 + + verifyFormat("while (a)\n" + " if (b) {\n" + " return;\n" + " }", + Code, Style, {tooling::Range(10, 8)}); // line 2 + + verifyFormat(Code, Style, {tooling::Range(19, 11)}); // line 3 +} + +} // namespace +} // namespace format +} // namespace clang diff --git a/clang/unittests/Format/CMakeLists.txt b/clang/unittests/Format/CMakeLists.txt index 715aec4ed5853..0d5d5c333f432 100644 --- a/clang/unittests/Format/CMakeLists.txt +++ b/clang/unittests/Format/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_unittest(FormatTests + BracesInserterTest.cpp CleanupTest.cpp DefinitionBlockSeparatorTest.cpp FormatTest.cpp diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index fa26ba0954026..8052eae7822ab 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25465,242 +25465,6 @@ TEST_F(FormatTest, ShortTemplatedArgumentLists) { verifyFormat("template struct Foo {};", Style); } -TEST_F(FormatTest, InsertBraces) { - FormatStyle Style = getLLVMStyle(); - Style.InsertBraces = true; - - verifyFormat("// clang-format off\n" - "// comment\n" - "if (a) f();\n" - "// clang-format on\n" - "if (b) {\n" - " g();\n" - "}", - "// clang-format off\n" - "// comment\n" - "if (a) f();\n" - "// clang-format on\n" - "if (b) g();", - Style); - - verifyFormat("if (a) {\n" - " switch (b) {\n" - " case 1:\n" - " c = 0;\n" - " break;\n" - " default:\n" - " c = 1;\n" - " }\n" - "}", - "if (a)\n" - " switch (b) {\n" - " case 1:\n" - " c = 0;\n" - " break;\n" - " default:\n" - " c = 1;\n" - " }", - Style); - - verifyFormat("for (auto node : nodes) {\n" - " if (node) {\n" - " break;\n" - " }\n" - "}", - "for (auto node : nodes)\n" - " if (node)\n" - " break;", - Style); - - verifyFormat("for (auto node : nodes) {\n" - " if (node)\n" - "}", - "for (auto node : nodes)\n" - " if (node)", - Style); - - verifyFormat("do {\n" - " --a;\n" - "} while (a);", - "do\n" - " --a;\n" - "while (a);", - Style); - - verifyFormat("if (i) {\n" - " ++i;\n" - "} else {\n" - " --i;\n" - "}", - "if (i)\n" - " ++i;\n" - "else {\n" - " --i;\n" - "}", - Style); - - verifyFormat("void f() {\n" - " while (j--) {\n" - " while (i) {\n" - " --i;\n" - " }\n" - " }\n" - "}", - "void f() {\n" - " while (j--)\n" - " while (i)\n" - " --i;\n" - "}", - Style); - - verifyFormat("f({\n" - " if (a) {\n" - " g();\n" - " }\n" - "});", - "f({\n" - " if (a)\n" - " g();\n" - "});", - Style); - - verifyFormat("if (a) {\n" - " f();\n" - "} else if (b) {\n" - " g();\n" - "} else {\n" - " h();\n" - "}", - "if (a)\n" - " f();\n" - "else if (b)\n" - " g();\n" - "else\n" - " h();", - Style); - - verifyFormat("if (a) {\n" - " f();\n" - "}\n" - "// comment\n" - "/* comment */", - "if (a)\n" - " f();\n" - "// comment\n" - "/* comment */", - Style); - - verifyFormat("if (a) {\n" - " // foo\n" - " // bar\n" - " f();\n" - "}", - "if (a)\n" - " // foo\n" - " // bar\n" - " f();", - Style); - - verifyFormat("if (a) { //\n" - " b = 1;\n" - "}", - "if (a) //\n" - " b = 1;", - Style); - - verifyFormat("if (a) { // comment\n" - " // comment\n" - " f();\n" - "}", - "if (a) // comment\n" - " // comment\n" - " f();", - Style); - - verifyFormat("if (a) {\n" - " f(); // comment\n" - "}", - "if (a)\n" - " f(); // comment", - Style); - - verifyFormat("if (a) {\n" - " f();\n" - "}\n" - "#undef A\n" - "#undef B", - "if (a)\n" - " f();\n" - "#undef A\n" - "#undef B", - Style); - - verifyFormat("if (a)\n" - "#ifdef A\n" - " f();\n" - "#else\n" - " g();\n" - "#endif", - Style); - - verifyFormat("#if 0\n" - "#elif 1\n" - "#endif\n" - "void f() {\n" - " if (a) {\n" - " g();\n" - " }\n" - "}", - "#if 0\n" - "#elif 1\n" - "#endif\n" - "void f() {\n" - " if (a) g();\n" - "}", - Style); - - verifyFormat("do {\n" - "#if 0\n" - "#else\n" - " if (b) {\n" - "#endif\n" - " }\n" - "} while (0);", - Style); - - Style.RemoveBracesLLVM = true; - verifyFormat("if (a) //\n" - " return b;", - Style); - Style.RemoveBracesLLVM = false; - - Style.ColumnLimit = 15; - - verifyFormat("#define A \\\n" - " if (a) \\\n" - " f();", - Style); - - verifyFormat("if (a + b >\n" - " c) {\n" - " f();\n" - "}", - "if (a + b > c)\n" - " f();", - Style); - - Style.BreakBeforeBraces = FormatStyle::BS_Custom; - Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; - - verifyFormat("if (a) //\n" - "{\n" - " b = 1;\n" - "}", - "if (a) //\n" - " b = 1;", - Style); -} - TEST_F(FormatTest, RemoveBraces) { FormatStyle Style = getLLVMStyle(); Style.RemoveBracesLLVM = true;