| //===- unittest/Format/FormatTest.cpp - Formatting unit tests -------------===// |
| // |
| // 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" |
| |
| #include "llvm/Support/Debug.h" |
| #include "llvm/Support/MemoryBuffer.h" |
| #include "gtest/gtest.h" |
| |
| #define DEBUG_TYPE "format-test" |
| |
| using clang::tooling::ReplacementTest; |
| using clang::tooling::toReplacements; |
| using testing::ScopedTrace; |
| |
| namespace clang { |
| namespace format { |
| namespace { |
| |
| FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } |
| |
| class FormatTest : public ::testing::Test { |
| protected: |
| enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck }; |
| |
| std::string format(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle(), |
| StatusCheck CheckComplete = SC_ExpectComplete) { |
| LLVM_DEBUG(llvm::errs() << "---\n"); |
| LLVM_DEBUG(llvm::errs() << Code << "\n\n"); |
| std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); |
| FormattingAttemptStatus Status; |
| tooling::Replacements Replaces = |
| reformat(Style, Code, Ranges, "<stdin>", &Status); |
| if (CheckComplete != SC_DoNotCheck) { |
| bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete; |
| EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete) |
| << Code << "\n\n"; |
| } |
| ReplacementCount = Replaces.size(); |
| auto Result = applyAllReplacements(Code, Replaces); |
| EXPECT_TRUE(static_cast<bool>(Result)); |
| LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); |
| return *Result; |
| } |
| |
| FormatStyle getStyleWithColumns(FormatStyle Style, unsigned ColumnLimit) { |
| Style.ColumnLimit = ColumnLimit; |
| return Style; |
| } |
| |
| FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { |
| return getStyleWithColumns(getLLVMStyle(), ColumnLimit); |
| } |
| |
| FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) { |
| return getStyleWithColumns(getGoogleStyle(), ColumnLimit); |
| } |
| |
| void _verifyFormat(const char *File, int Line, llvm::StringRef Expected, |
| llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| ScopedTrace t(File, Line, ::testing::Message() << Code.str()); |
| EXPECT_EQ(Expected.str(), format(Expected, Style)) |
| << "Expected code is not stable"; |
| EXPECT_EQ(Expected.str(), format(Code, Style)); |
| if (Style.Language == FormatStyle::LK_Cpp) { |
| // 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)); |
| } |
| } |
| |
| void _verifyFormat(const char *File, int Line, llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| _verifyFormat(File, Line, Code, test::messUp(Code), Style); |
| } |
| |
| void _verifyIncompleteFormat(const char *File, int Line, llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| ScopedTrace t(File, Line, ::testing::Message() << Code.str()); |
| EXPECT_EQ(Code.str(), |
| format(test::messUp(Code), Style, SC_ExpectIncomplete)); |
| } |
| |
| void _verifyIndependentOfContext(const char *File, int Line, |
| llvm::StringRef Text, |
| const FormatStyle &Style = getLLVMStyle()) { |
| _verifyFormat(File, Line, Text, Style); |
| _verifyFormat(File, Line, llvm::Twine("void f() { " + Text + " }").str(), |
| Style); |
| } |
| |
| /// \brief Verify that clang-format does not crash on the given input. |
| void verifyNoCrash(llvm::StringRef Code, |
| const FormatStyle &Style = getLLVMStyle()) { |
| format(Code, Style, SC_DoNotCheck); |
| } |
| |
| int ReplacementCount; |
| }; |
| |
| #define verifyIndependentOfContext(...) \ |
| _verifyIndependentOfContext(__FILE__, __LINE__, __VA_ARGS__) |
| #define verifyIncompleteFormat(...) \ |
| _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__) |
| #define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) |
| #define verifyGoogleFormat(Code) verifyFormat(Code, getGoogleStyle()) |
| |
| TEST_F(FormatTest, MessUp) { |
| EXPECT_EQ("1 2 3", test::messUp("1 2 3")); |
| EXPECT_EQ("1 2 3\n", test::messUp("1\n2\n3\n")); |
| EXPECT_EQ("a\n//b\nc", test::messUp("a\n//b\nc")); |
| EXPECT_EQ("a\n#b\nc", test::messUp("a\n#b\nc")); |
| EXPECT_EQ("a\n#b c d\ne", test::messUp("a\n#b\\\nc\\\nd\ne")); |
| } |
| |
| TEST_F(FormatTest, DefaultLLVMStyleIsCpp) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, getLLVMStyle().Language); |
| } |
| |
| TEST_F(FormatTest, LLVMStyleOverride) { |
| EXPECT_EQ(FormatStyle::LK_Proto, |
| getLLVMStyle(FormatStyle::LK_Proto).Language); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Basic function tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, DoesNotChangeCorrectlyFormattedCode) { |
| EXPECT_EQ(";", format(";")); |
| } |
| |
| TEST_F(FormatTest, FormatsGlobalStatementsAt0) { |
| EXPECT_EQ("int i;", format(" int i;")); |
| EXPECT_EQ("\nint i;", format(" \n\t \v \f int i;")); |
| EXPECT_EQ("int i;\nint j;", format(" int i; int j;")); |
| EXPECT_EQ("int i;\nint j;", format(" int i;\n int j;")); |
| } |
| |
| TEST_F(FormatTest, FormatsUnwrappedLinesAtFirstFormat) { |
| EXPECT_EQ("int i;", format("int\ni;")); |
| } |
| |
| TEST_F(FormatTest, FormatsNestedBlockStatements) { |
| EXPECT_EQ("{\n {\n {}\n }\n}", format("{{{}}}")); |
| } |
| |
| TEST_F(FormatTest, FormatsNestedCall) { |
| verifyFormat("Method(f1, f2(f3));"); |
| verifyFormat("Method(f1(f2, f3()));"); |
| verifyFormat("Method(f1(f2, (f3())));"); |
| } |
| |
| TEST_F(FormatTest, NestedNameSpecifiers) { |
| verifyFormat("vector<::Type> v;"); |
| verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())"); |
| verifyFormat("static constexpr bool Bar = decltype(bar())::value;"); |
| verifyFormat("static constexpr bool Bar = typeof(bar())::value;"); |
| verifyFormat("static constexpr bool Bar = __underlying_type(bar())::value;"); |
| verifyFormat("static constexpr bool Bar = _Atomic(bar())::value;"); |
| verifyFormat("bool a = 2 < ::SomeFunction();"); |
| verifyFormat("ALWAYS_INLINE ::std::string getName();"); |
| verifyFormat("some::string getName();"); |
| } |
| |
| TEST_F(FormatTest, OnlyGeneratesNecessaryReplacements) { |
| EXPECT_EQ("if (a) {\n" |
| " f();\n" |
| "}", |
| format("if(a){f();}")); |
| EXPECT_EQ(4, ReplacementCount); |
| EXPECT_EQ("if (a) {\n" |
| " f();\n" |
| "}", |
| format("if (a) {\n" |
| " f();\n" |
| "}")); |
| EXPECT_EQ(0, ReplacementCount); |
| EXPECT_EQ("/*\r\n" |
| "\r\n" |
| "*/\r\n", |
| format("/*\r\n" |
| "\r\n" |
| "*/\r\n")); |
| EXPECT_EQ(0, ReplacementCount); |
| } |
| |
| TEST_F(FormatTest, RemovesEmptyLines) { |
| EXPECT_EQ("class C {\n" |
| " int i;\n" |
| "};", |
| format("class C {\n" |
| " int i;\n" |
| "\n" |
| "};")); |
| |
| // Don't remove empty lines at the start of namespaces or extern "C" blocks. |
| EXPECT_EQ("namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("/* something */ namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("/* something */ namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("inline namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("inline namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("/* something */ inline namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("/* something */ inline namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("export namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("export namespace N {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| EXPECT_EQ("extern /**/ \"C\" /**/ {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("extern /**/ \"C\" /**/ {\n" |
| "\n" |
| "int i;\n" |
| "}", |
| getGoogleStyle())); |
| |
| auto CustomStyle = clang::format::getLLVMStyle(); |
| CustomStyle.BreakBeforeBraces = clang::format::FormatStyle::BS_Custom; |
| CustomStyle.BraceWrapping.AfterNamespace = true; |
| CustomStyle.KeepEmptyLinesAtTheStartOfBlocks = false; |
| EXPECT_EQ("namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("namespace N\n" |
| "{\n" |
| "\n" |
| "\n" |
| "int i;\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("/* something */ namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("/* something */ namespace N {\n" |
| "\n" |
| "\n" |
| "int i;\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("inline namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("inline namespace N\n" |
| "{\n" |
| "\n" |
| "\n" |
| "int i;\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("/* something */ inline namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("/* something */ inline namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("export namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| format("export namespace N\n" |
| "{\n" |
| "\n" |
| "int i;\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("namespace a\n" |
| "{\n" |
| "namespace b\n" |
| "{\n" |
| "\n" |
| "class AA {};\n" |
| "\n" |
| "} // namespace b\n" |
| "} // namespace a\n", |
| format("namespace a\n" |
| "{\n" |
| "namespace b\n" |
| "{\n" |
| "\n" |
| "\n" |
| "class AA {};\n" |
| "\n" |
| "\n" |
| "}\n" |
| "}\n", |
| CustomStyle)); |
| EXPECT_EQ("namespace A /* comment */\n" |
| "{\n" |
| "class B {}\n" |
| "} // namespace A", |
| format("namespace A /* comment */ { class B {} }", CustomStyle)); |
| EXPECT_EQ("namespace A\n" |
| "{ /* comment */\n" |
| "class B {}\n" |
| "} // namespace A", |
| format("namespace A {/* comment */ class B {} }", CustomStyle)); |
| EXPECT_EQ("namespace A\n" |
| "{ /* comment */\n" |
| "\n" |
| "class B {}\n" |
| "\n" |
| "" |
| "} // namespace A", |
| format("namespace A { /* comment */\n" |
| "\n" |
| "\n" |
| "class B {}\n" |
| "\n" |
| "\n" |
| "}", |
| CustomStyle)); |
| EXPECT_EQ("namespace A /* comment */\n" |
| "{\n" |
| "\n" |
| "class B {}\n" |
| "\n" |
| "} // namespace A", |
| format("namespace A/* comment */ {\n" |
| "\n" |
| "\n" |
| "class B {}\n" |
| "\n" |
| "\n" |
| "}", |
| CustomStyle)); |
| |
| // ...but do keep inlining and removing empty lines for non-block extern "C" |
| // functions. |
| verifyFormat("extern \"C\" int f() { return 42; }", getGoogleStyle()); |
| EXPECT_EQ("extern \"C\" int f() {\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}", |
| format("extern \"C\" int f() {\n" |
| "\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}", |
| getGoogleStyle())); |
| |
| // Remove empty lines at the beginning and end of blocks. |
| EXPECT_EQ("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}", |
| getLLVMStyle())); |
| EXPECT_EQ("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| "\n" |
| " if (a) {\n" |
| "\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}", |
| getGoogleStyle())); |
| |
| // Don't remove empty lines in more complex control statements. |
| EXPECT_EQ("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| "\n" |
| " } else if (b) {\n" |
| " f();\n" |
| " }\n" |
| "}", |
| format("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| "\n" |
| " } else if (b) {\n" |
| " f();\n" |
| "\n" |
| " }\n" |
| "\n" |
| "}")); |
| |
| // Don't remove empty lines before namespace endings. |
| FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle(); |
| LLVMWithNoNamespaceFix.FixNamespaceComments = false; |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "\n" |
| "}", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "}", |
| LLVMWithNoNamespaceFix)); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "}", |
| format("namespace {\n" |
| "int i;\n" |
| "}", |
| LLVMWithNoNamespaceFix)); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "\n" |
| "};", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "};", |
| LLVMWithNoNamespaceFix)); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "};", |
| format("namespace {\n" |
| "int i;\n" |
| "};", |
| LLVMWithNoNamespaceFix)); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "\n" |
| "}", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "}")); |
| EXPECT_EQ("namespace {\n" |
| "int i;\n" |
| "\n" |
| "} // namespace", |
| format("namespace {\n" |
| "int i;\n" |
| "\n" |
| "} // namespace")); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| Style.MaxEmptyLinesToKeep = 2; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterClass = true; |
| Style.BraceWrapping.AfterFunction = true; |
| Style.KeepEmptyLinesAtTheStartOfBlocks = false; |
| |
| EXPECT_EQ("class Foo\n" |
| "{\n" |
| " Foo() {}\n" |
| "\n" |
| " void funk() {}\n" |
| "};", |
| format("class Foo\n" |
| "{\n" |
| " Foo()\n" |
| " {\n" |
| " }\n" |
| "\n" |
| " void funk() {}\n" |
| "};", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) { |
| verifyFormat("x = (a) and (b);"); |
| verifyFormat("x = (a) or (b);"); |
| verifyFormat("x = (a) bitand (b);"); |
| verifyFormat("x = (a) bitor (b);"); |
| verifyFormat("x = (a) not_eq (b);"); |
| verifyFormat("x = (a) and_eq (b);"); |
| verifyFormat("x = (a) or_eq (b);"); |
| verifyFormat("x = (a) xor (b);"); |
| } |
| |
| TEST_F(FormatTest, RecognizesUnaryOperatorKeywords) { |
| verifyFormat("x = compl(a);"); |
| verifyFormat("x = not(a);"); |
| verifyFormat("x = bitand(a);"); |
| // Unary operator must not be merged with the next identifier |
| verifyFormat("x = compl a;"); |
| verifyFormat("x = not a;"); |
| verifyFormat("x = bitand a;"); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Tests for control statements. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, FormatIfWithoutCompoundStatement) { |
| verifyFormat("if (true)\n f();\ng();"); |
| verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();"); |
| verifyFormat("if (a)\n if (b) {\n f();\n }\ng();"); |
| verifyFormat("if constexpr (true)\n" |
| " f();\ng();"); |
| verifyFormat("if CONSTEXPR (true)\n" |
| " f();\ng();"); |
| verifyFormat("if constexpr (a)\n" |
| " if constexpr (b)\n" |
| " if constexpr (c)\n" |
| " g();\n" |
| "h();"); |
| verifyFormat("if CONSTEXPR (a)\n" |
| " if CONSTEXPR (b)\n" |
| " if CONSTEXPR (c)\n" |
| " g();\n" |
| "h();"); |
| verifyFormat("if constexpr (a)\n" |
| " if constexpr (b) {\n" |
| " f();\n" |
| " }\n" |
| "g();"); |
| verifyFormat("if CONSTEXPR (a)\n" |
| " if CONSTEXPR (b) {\n" |
| " f();\n" |
| " }\n" |
| "g();"); |
| |
| verifyFormat("if (a)\n" |
| " g();"); |
| verifyFormat("if (a) {\n" |
| " g()\n" |
| "};"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else\n" |
| " g();"); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else\n" |
| " g();"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();"); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}"); |
| |
| FormatStyle AllowsMergedIf = getLLVMStyle(); |
| AllowsMergedIf.IfMacros.push_back("MYIF"); |
| AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| verifyFormat("if (a)\n" |
| " // comment\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("{\n" |
| " if (a)\n" |
| " label:\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("#define A \\\n" |
| " if (a) \\\n" |
| " label: \\\n" |
| " f()", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " ;", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " if (b) return;", |
| AllowsMergedIf); |
| |
| verifyFormat("if (a) // Can't merge this\n" |
| " f();\n", |
| AllowsMergedIf); |
| verifyFormat("if (a) /* still don't merge */\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("if (a) { // Never merge this\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) { /* Never merge this */\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " // comment\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("{\n" |
| " MYIF (a)\n" |
| " label:\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("#define A \\\n" |
| " MYIF (a) \\\n" |
| " label: \\\n" |
| " f()", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " ;", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " MYIF (b) return;", |
| AllowsMergedIf); |
| |
| verifyFormat("MYIF (a) // Can't merge this\n" |
| " f();\n", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) /* still don't merge */\n" |
| " f();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) { // Never merge this\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) { /* Never merge this */\n" |
| " f();\n" |
| "}", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.ColumnLimit = 14; |
| // Where line-lengths matter, a 2-letter synonym that maintains line length. |
| // Not IF to avoid any confusion that IF is somehow special. |
| AllowsMergedIf.IfMacros.push_back("FI"); |
| verifyFormat("if (a) return;", AllowsMergedIf); |
| verifyFormat("if (aaaaaaaaa)\n" |
| " return;", |
| AllowsMergedIf); |
| verifyFormat("FI (a) return;", AllowsMergedIf); |
| verifyFormat("FI (aaaaaaaaa)\n" |
| " return;", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.ColumnLimit = 13; |
| verifyFormat("if (a)\n return;", AllowsMergedIf); |
| verifyFormat("FI (a)\n return;", AllowsMergedIf); |
| |
| FormatStyle AllowsMergedIfElse = getLLVMStyle(); |
| AllowsMergedIfElse.IfMacros.push_back("MYIF"); |
| AllowsMergedIfElse.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_AllIfsAndElse; |
| verifyFormat("if (a)\n" |
| " // comment\n" |
| " f();\n" |
| "else\n" |
| " // comment\n" |
| " f();", |
| AllowsMergedIfElse); |
| verifyFormat("{\n" |
| " if (a)\n" |
| " label:\n" |
| " f();\n" |
| " else\n" |
| " label:\n" |
| " f();\n" |
| "}", |
| AllowsMergedIfElse); |
| verifyFormat("if (a)\n" |
| " ;\n" |
| "else\n" |
| " ;", |
| AllowsMergedIfElse); |
| verifyFormat("if (a) {\n" |
| "} else {\n" |
| "}", |
| AllowsMergedIfElse); |
| verifyFormat("if (a) return;\n" |
| "else if (b) return;\n" |
| "else return;", |
| AllowsMergedIfElse); |
| verifyFormat("if (a) {\n" |
| "} else return;", |
| AllowsMergedIfElse); |
| verifyFormat("if (a) {\n" |
| "} else if (b) return;\n" |
| "else return;", |
| AllowsMergedIfElse); |
| verifyFormat("if (a) return;\n" |
| "else if (b) {\n" |
| "} else return;", |
| AllowsMergedIfElse); |
| verifyFormat("if (a)\n" |
| " if (b) return;\n" |
| " else return;", |
| AllowsMergedIfElse); |
| verifyFormat("if constexpr (a)\n" |
| " if constexpr (b) return;\n" |
| " else if constexpr (c) return;\n" |
| " else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a)\n" |
| " // comment\n" |
| " f();\n" |
| "else\n" |
| " // comment\n" |
| " f();", |
| AllowsMergedIfElse); |
| verifyFormat("{\n" |
| " MYIF (a)\n" |
| " label:\n" |
| " f();\n" |
| " else\n" |
| " label:\n" |
| " f();\n" |
| "}", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a)\n" |
| " ;\n" |
| "else\n" |
| " ;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a) {\n" |
| "} else {\n" |
| "}", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a) return;\n" |
| "else MYIF (b) return;\n" |
| "else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a) {\n" |
| "} else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a) {\n" |
| "} else MYIF (b) return;\n" |
| "else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a) return;\n" |
| "else MYIF (b) {\n" |
| "} else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF (a)\n" |
| " MYIF (b) return;\n" |
| " else return;", |
| AllowsMergedIfElse); |
| verifyFormat("MYIF constexpr (a)\n" |
| " MYIF constexpr (b) return;\n" |
| " else MYIF constexpr (c) return;\n" |
| " else return;", |
| AllowsMergedIfElse); |
| } |
| |
| TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) { |
| FormatStyle AllowsMergedIf = getLLVMStyle(); |
| AllowsMergedIf.IfMacros.push_back("MYIF"); |
| AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| verifyFormat("if (a)\n" |
| " f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " f();\n" |
| "else\n" |
| " g();\n", |
| AllowsMergedIf); |
| |
| verifyFormat("if (a) g();", AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " f();\n" |
| "else\n" |
| " g();\n", |
| AllowsMergedIf); |
| |
| verifyFormat("MYIF (a) g();", AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else MYIF (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else MYIF (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a)\n" |
| " g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_OnlyFirstIf; |
| |
| verifyFormat("if (a) f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) f();\n" |
| "else {\n" |
| " if (a) f();\n" |
| " else {\n" |
| " g();\n" |
| " }\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| verifyFormat("if (a) g();", AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) f();\n" |
| "else {\n" |
| " if (a) f();\n" |
| " else {\n" |
| " g();\n" |
| " }\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| verifyFormat("MYIF (a) g();", AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b)\n" |
| " g();\n" |
| "else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else\n" |
| " g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_AllIfsAndElse; |
| |
| verifyFormat("if (a) f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) f();\n" |
| "else {\n" |
| " if (a) f();\n" |
| " else {\n" |
| " g();\n" |
| " }\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| verifyFormat("if (a) g();", AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else g();", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("if (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) f();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) f();\n" |
| "else {\n" |
| " if (a) f();\n" |
| " else {\n" |
| " g();\n" |
| " }\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| |
| verifyFormat("MYIF (a) g();", AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g()\n" |
| "};", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b) g();\n" |
| "else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else g();", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) g();\n" |
| "else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) g();\n" |
| "else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else MYIF (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| verifyFormat("MYIF (a) {\n" |
| " g();\n" |
| "} else if (b) {\n" |
| " g();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| AllowsMergedIf); |
| } |
| |
| TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) { |
| FormatStyle AllowsMergedLoops = getLLVMStyle(); |
| AllowsMergedLoops.AllowShortLoopsOnASingleLine = true; |
| verifyFormat("while (true) continue;", AllowsMergedLoops); |
| verifyFormat("for (;;) continue;", AllowsMergedLoops); |
| verifyFormat("for (int &v : vec) v *= 2;", AllowsMergedLoops); |
| verifyFormat("while (true)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " for (;;) continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;) // Can't merge this\n" |
| " continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;) /* still don't merge */\n" |
| " continue;", |
| AllowsMergedLoops); |
| verifyFormat("do a++;\n" |
| "while (true);", |
| AllowsMergedLoops); |
| verifyFormat("do /* Don't merge */\n" |
| " a++;\n" |
| "while (true);", |
| AllowsMergedLoops); |
| verifyFormat("do // Don't merge\n" |
| " a++;\n" |
| "while (true);", |
| AllowsMergedLoops); |
| verifyFormat("do\n" |
| " // Don't merge\n" |
| " a++;\n" |
| "while (true);", |
| AllowsMergedLoops); |
| // Without braces labels are interpreted differently. |
| verifyFormat("{\n" |
| " do\n" |
| " label:\n" |
| " a++;\n" |
| " while (true);\n" |
| "}", |
| AllowsMergedLoops); |
| } |
| |
| TEST_F(FormatTest, FormatShortBracedStatements) { |
| FormatStyle AllowSimpleBracedStatements = getLLVMStyle(); |
| AllowSimpleBracedStatements.IfMacros.push_back("MYIF"); |
| // Where line-lengths matter, a 2-letter synonym that maintains line length. |
| // Not IF to avoid any confusion that IF is somehow special. |
| AllowSimpleBracedStatements.IfMacros.push_back("FI"); |
| AllowSimpleBracedStatements.ColumnLimit = 40; |
| AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = |
| FormatStyle::SBS_Always; |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true; |
| |
| AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom; |
| AllowSimpleBracedStatements.BraceWrapping.AfterFunction = true; |
| AllowSimpleBracedStatements.BraceWrapping.SplitEmptyRecord = false; |
| |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEXPR (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF constexpr (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEXPR (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("while (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { fffffffffffffffffffffff(); }", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " ffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) { //\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("FI (true) { fffffffffffffffffffffff(); }", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " ffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) { //\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " f();\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| verifyFormat("struct A2 {\n" |
| " int X;\n" |
| "};", |
| AllowSimpleBracedStatements); |
| verifyFormat("typedef struct A2 {\n" |
| " int X;\n" |
| "} A2_t;", |
| AllowSimpleBracedStatements); |
| verifyFormat("template <int> struct A2 {\n" |
| " struct B {};\n" |
| "};", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_Never; |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {\n" |
| " f();\n" |
| "} else {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; |
| verifyFormat("while (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("while (true) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {}", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true; |
| AllowSimpleBracedStatements.BraceWrapping.AfterControlStatement = |
| FormatStyle::BWACS_Always; |
| |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEXPR (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF constexpr (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEXPR (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("while (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if (true) { fffffffffffffffffffffff(); }", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " ffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{ //\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " f();\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " f();\n" |
| "} else\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("FI (true) { fffffffffffffffffffffff(); }", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " ffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{ //\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " f();\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " f();\n" |
| "} else\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_Never; |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("if (true)\n" |
| "{\n" |
| " f();\n" |
| "} else\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true)\n" |
| "{\n" |
| " f();\n" |
| "} else\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false; |
| verifyFormat("while (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("while (true)\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| verifyFormat("for (;;) {}", AllowSimpleBracedStatements); |
| verifyFormat("for (;;)\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| } |
| |
| TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) { |
| FormatStyle Style = getLLVMStyleWithColumns(60); |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; |
| Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse; |
| Style.BreakBeforeBraces = FormatStyle::BS_Allman; |
| EXPECT_EQ("#define A \\\n" |
| " if (HANDLEwernufrnuLwrmviferuvnierv) \\\n" |
| " { \\\n" |
| " RET_ERR1_ANUIREUINERUIFNIOAerwfwrvnuier; \\\n" |
| " }\n" |
| "X;", |
| format("#define A \\\n" |
| " if (HANDLEwernufrnuLwrmviferuvnierv) { \\\n" |
| " RET_ERR1_ANUIREUINERUIFNIOAerwfwrvnuier; \\\n" |
| " }\n" |
| "X;", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, ParseIfElse) { |
| verifyFormat("if (true)\n" |
| " if (true)\n" |
| " if (true)\n" |
| " f();\n" |
| " else\n" |
| " g();\n" |
| " else\n" |
| " h();\n" |
| "else\n" |
| " i();"); |
| verifyFormat("if (true)\n" |
| " if (true)\n" |
| " if (true) {\n" |
| " if (true)\n" |
| " f();\n" |
| " } else {\n" |
| " g();\n" |
| " }\n" |
| " else\n" |
| " h();\n" |
| "else {\n" |
| " i();\n" |
| "}"); |
| verifyFormat("if (true)\n" |
| " if constexpr (true)\n" |
| " if (true) {\n" |
| " if constexpr (true)\n" |
| " f();\n" |
| " } else {\n" |
| " g();\n" |
| " }\n" |
| " else\n" |
| " h();\n" |
| "else {\n" |
| " i();\n" |
| "}"); |
| verifyFormat("if (true)\n" |
| " if CONSTEXPR (true)\n" |
| " if (true) {\n" |
| " if CONSTEXPR (true)\n" |
| " f();\n" |
| " } else {\n" |
| " g();\n" |
| " }\n" |
| " else\n" |
| " h();\n" |
| "else {\n" |
| " i();\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| " if (a) {\n" |
| " } else {\n" |
| " }\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, ElseIf) { |
| verifyFormat("if (a) {\n} else if (b) {\n}"); |
| verifyFormat("if (a)\n" |
| " f();\n" |
| "else if (b)\n" |
| " g();\n" |
| "else\n" |
| " h();"); |
| verifyFormat("if (a)\n" |
| " f();\n" |
| "else // comment\n" |
| " if (b) {\n" |
| " g();\n" |
| " h();\n" |
| " }"); |
| verifyFormat("if constexpr (a)\n" |
| " f();\n" |
| "else if constexpr (b)\n" |
| " g();\n" |
| "else\n" |
| " h();"); |
| verifyFormat("if CONSTEXPR (a)\n" |
| " f();\n" |
| "else if CONSTEXPR (b)\n" |
| " g();\n" |
| "else\n" |
| " h();"); |
| verifyFormat("if (a) {\n" |
| " f();\n" |
| "}\n" |
| "// or else ..\n" |
| "else {\n" |
| " g()\n" |
| "}"); |
| |
| verifyFormat("if (a) {\n" |
| "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| "} else if constexpr (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| "} else if CONSTEXPR (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" |
| "}"); |
| verifyFormat("if (a) {\n" |
| "} else if (\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(62)); |
| verifyFormat("if (a) {\n" |
| "} else if constexpr (\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(62)); |
| verifyFormat("if (a) {\n" |
| "} else if CONSTEXPR (\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(62)); |
| } |
| |
| TEST_F(FormatTest, SeparatePointerReferenceAlignment) { |
| FormatStyle Style = getLLVMStyle(); |
| // Check first the default LLVM style |
| // Style.PointerAlignment = FormatStyle::PAS_Right; |
| // Style.ReferenceAlignment = FormatStyle::RAS_Pointer; |
| verifyFormat("int *f1(int *a, int &b, int &&c);", Style); |
| verifyFormat("int &f2(int &&c, int *a, int &b);", Style); |
| verifyFormat("int &&f3(int &b, int &&c, int *a);", Style); |
| verifyFormat("int *f1(int &a) const &;", Style); |
| verifyFormat("int *f1(int &a) const & = 0;", Style); |
| verifyFormat("int *a = f1();", Style); |
| verifyFormat("int &b = f2();", Style); |
| verifyFormat("int &&c = f3();", Style); |
| |
| Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; |
| verifyFormat("Const unsigned int *c;\n" |
| "const unsigned int *d;\n" |
| "Const unsigned int &e;\n" |
| "const unsigned int &f;\n" |
| "const unsigned &&g;\n" |
| "Const unsigned h;", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| Style.ReferenceAlignment = FormatStyle::RAS_Pointer; |
| verifyFormat("int* f1(int* a, int& b, int&& c);", Style); |
| verifyFormat("int& f2(int&& c, int* a, int& b);", Style); |
| verifyFormat("int&& f3(int& b, int&& c, int* a);", Style); |
| verifyFormat("int* f1(int& a) const& = 0;", Style); |
| verifyFormat("int* a = f1();", Style); |
| verifyFormat("int& b = f2();", Style); |
| verifyFormat("int&& c = f3();", Style); |
| |
| Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; |
| verifyFormat("Const unsigned int* c;\n" |
| "const unsigned int* d;\n" |
| "Const unsigned int& e;\n" |
| "const unsigned int& f;\n" |
| "const unsigned&& g;\n" |
| "Const unsigned h;", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Right; |
| Style.ReferenceAlignment = FormatStyle::RAS_Left; |
| verifyFormat("int *f1(int *a, int& b, int&& c);", Style); |
| verifyFormat("int& f2(int&& c, int *a, int& b);", Style); |
| verifyFormat("int&& f3(int& b, int&& c, int *a);", Style); |
| verifyFormat("int *a = f1();", Style); |
| verifyFormat("int& b = f2();", Style); |
| verifyFormat("int&& c = f3();", Style); |
| |
| Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; |
| verifyFormat("Const unsigned int *c;\n" |
| "const unsigned int *d;\n" |
| "Const unsigned int& e;\n" |
| "const unsigned int& f;\n" |
| "const unsigned g;\n" |
| "Const unsigned h;", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| Style.ReferenceAlignment = FormatStyle::RAS_Middle; |
| verifyFormat("int* f1(int* a, int & b, int && c);", Style); |
| verifyFormat("int & f2(int && c, int* a, int & b);", Style); |
| verifyFormat("int && f3(int & b, int && c, int* a);", Style); |
| verifyFormat("int* a = f1();", Style); |
| verifyFormat("int & b = f2();", Style); |
| verifyFormat("int && c = f3();", Style); |
| |
| Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive; |
| verifyFormat("Const unsigned int* c;\n" |
| "const unsigned int* d;\n" |
| "Const unsigned int & e;\n" |
| "const unsigned int & f;\n" |
| "const unsigned && g;\n" |
| "Const unsigned h;", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Middle; |
| Style.ReferenceAlignment = FormatStyle::RAS_Right; |
| verifyFormat("int * f1(int * a, int &b, int &&c);", Style); |
| verifyFormat("int &f2(int &&c, int * a, int &b);", Style); |
| verifyFormat("int &&f3(int &b, int &&c, int * a);", Style); |
| verifyFormat("int * a = f1();", Style); |
| verifyFormat("int &b = f2();", Style); |
| verifyFormat("int &&c = f3();", Style); |
| |
| // FIXME: we don't handle this yet, so output may be arbitrary until it's |
| // specifically handled |
| // verifyFormat("int Add2(BTree * &Root, char * szToAdd)", Style); |
| } |
| |
| TEST_F(FormatTest, FormatsForLoop) { |
| verifyFormat( |
| "for (int VeryVeryLongLoopVariable = 0; VeryVeryLongLoopVariable < 10;\n" |
| " ++VeryVeryLongLoopVariable)\n" |
| " ;"); |
| verifyFormat("for (;;)\n" |
| " f();"); |
| verifyFormat("for (;;) {\n}"); |
| verifyFormat("for (;;) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("for (int i = 0; (i < 10); ++i) {\n}"); |
| |
| verifyFormat( |
| "for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(),\n" |
| " E = UnwrappedLines.end();\n" |
| " I != E; ++I) {\n}"); |
| |
| verifyFormat( |
| "for (MachineFun::iterator IIII = PrevIt, EEEE = F.end(); IIII != EEEE;\n" |
| " ++IIIII) {\n}"); |
| verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n" |
| " aaaaaaaaaaa != aaaaaaaaaaaaaaaaaaa; ++aaaaaaaaaaa) {\n}"); |
| verifyFormat("for (llvm::ArrayRef<NamedDecl *>::iterator\n" |
| " I = FD->getDeclsInPrototypeScope().begin(),\n" |
| " E = FD->getDeclsInPrototypeScope().end();\n" |
| " I != E; ++I) {\n}"); |
| verifyFormat("for (SmallVectorImpl<TemplateIdAnnotationn *>::iterator\n" |
| " I = Container.begin(),\n" |
| " E = Container.end();\n" |
| " I != E; ++I) {\n}", |
| getLLVMStyleWithColumns(76)); |
| |
| verifyFormat( |
| "for (aaaaaaaaaaaaaaaaa aaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa !=\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| " ++aaaaaaaaaaa) {\n}"); |
| verifyFormat("for (int i = 0; i < aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbbbb < ccccccccccccccc;\n" |
| " ++i) {\n}"); |
| verifyFormat("for (int aaaaaaaaaaa = 1; aaaaaaaaaaa <= bbbbbbbbbbbbbbb;\n" |
| " aaaaaaaaaaa++, bbbbbbbbbbbbbbbbb++) {\n" |
| "}"); |
| verifyFormat("for (some_namespace::SomeIterator iter( // force break\n" |
| " aaaaaaaaaa);\n" |
| " iter; ++iter) {\n" |
| "}"); |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbbbbbbb;\n" |
| " ++aaaaaaaaaaaaaaaaaaaaaaaaaaa) {"); |
| |
| // These should not be formatted as Objective-C for-in loops. |
| verifyFormat("for (Foo *x = 0; x != in; x++) {\n}"); |
| verifyFormat("Foo *x;\nfor (x = 0; x != in; x++) {\n}"); |
| verifyFormat("Foo *x;\nfor (x in y) {\n}"); |
| verifyFormat( |
| "for (const Foo<Bar> &baz = in.value(); !baz.at_end(); ++baz) {\n}"); |
| |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackParameters = false; |
| verifyFormat("for (int aaaaaaaaaaa = 1;\n" |
| " aaaaaaaaaaa <= aaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa);\n" |
| " aaaaaaaaaaa++, bbbbbbbbbbbbbbbbb++) {\n" |
| "}", |
| NoBinPacking); |
| verifyFormat( |
| "for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(),\n" |
| " E = UnwrappedLines.end();\n" |
| " I != E;\n" |
| " ++I) {\n}", |
| NoBinPacking); |
| |
| FormatStyle AlignLeft = getLLVMStyle(); |
| AlignLeft.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("for (A* a = start; a < end; ++a, ++value) {\n}", AlignLeft); |
| } |
| |
| TEST_F(FormatTest, RangeBasedForLoops) { |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat("for (auto aaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa, aaaaaaaaaaaaa)) {\n}"); |
| verifyFormat("for (const aaaaaaaaaaaaaaaaaaaaa &aaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat("for (aaaaaaaaa aaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaa.aaaaaaaaaaaa().aaaaaaaaa().a()) {\n}"); |
| } |
| |
| TEST_F(FormatTest, ForEachLoops) { |
| verifyFormat("void f() {\n" |
| " foreach (Item *item, itemlist) {}\n" |
| " Q_FOREACH (Item *item, itemlist) {}\n" |
| " BOOST_FOREACH (Item *item, itemlist) {}\n" |
| " UNKNOWN_FORACH(Item * item, itemlist) {}\n" |
| "}"); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.SpaceBeforeParens = |
| FormatStyle::SBPO_ControlStatementsExceptControlMacros; |
| verifyFormat("void f() {\n" |
| " foreach(Item *item, itemlist) {}\n" |
| " Q_FOREACH(Item *item, itemlist) {}\n" |
| " BOOST_FOREACH(Item *item, itemlist) {}\n" |
| " UNKNOWN_FORACH(Item * item, itemlist) {}\n" |
| "}", |
| Style); |
| |
| // As function-like macros. |
| verifyFormat("#define foreach(x, y)\n" |
| "#define Q_FOREACH(x, y)\n" |
| "#define BOOST_FOREACH(x, y)\n" |
| "#define UNKNOWN_FOREACH(x, y)\n"); |
| |
| // Not as function-like macros. |
| verifyFormat("#define foreach (x, y)\n" |
| "#define Q_FOREACH (x, y)\n" |
| "#define BOOST_FOREACH (x, y)\n" |
| "#define UNKNOWN_FOREACH (x, y)\n"); |
| |
| // handle microsoft non standard extension |
| verifyFormat("for each (char c in x->MyStringProperty)"); |
| } |
| |
| TEST_F(FormatTest, FormatsWhileLoop) { |
| verifyFormat("while (true) {\n}"); |
| verifyFormat("while (true)\n" |
| " f();"); |
| verifyFormat("while () {\n}"); |
| verifyFormat("while () {\n" |
| " f();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatsDoWhile) { |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while (something());"); |
| verifyFormat("do\n" |
| " do_something();\n" |
| "while (something());"); |
| } |
| |
| TEST_F(FormatTest, FormatsSwitchStatement) { |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| " f();\n" |
| " break;\n" |
| "case kFoo:\n" |
| "case ns::kBar:\n" |
| "case kBaz:\n" |
| " break;\n" |
| "default:\n" |
| " g();\n" |
| " break;\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " {\n" |
| " g();\n" |
| " h();\n" |
| " }\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " if (foo) {\n" |
| " g();\n" |
| " h();\n" |
| " }\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1: {\n" |
| " f();\n" |
| " g();\n" |
| "} break;\n" |
| "}"); |
| verifyFormat("switch (test)\n" |
| " ;"); |
| verifyFormat("switch (x) {\n" |
| "default: {\n" |
| " // Do nothing.\n" |
| "}\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "// comment\n" |
| "// if 1, do f()\n" |
| "case 1:\n" |
| " f();\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| " // Do amazing stuff\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| " break;\n" |
| "}"); |
| verifyFormat("#define A \\\n" |
| " switch (x) { \\\n" |
| " case a: \\\n" |
| " foo = b; \\\n" |
| " }", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("#define OPERATION_CASE(name) \\\n" |
| " case OP_name: \\\n" |
| " return operations::Operation##name\n", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("switch (x) {\n" |
| "case 1:;\n" |
| "default:;\n" |
| " int i;\n" |
| "}"); |
| |
| verifyGoogleFormat("switch (x) {\n" |
| " case 1:\n" |
| " f();\n" |
| " break;\n" |
| " case kFoo:\n" |
| " case ns::kBar:\n" |
| " case kBaz:\n" |
| " break;\n" |
| " default:\n" |
| " g();\n" |
| " break;\n" |
| "}"); |
| verifyGoogleFormat("switch (x) {\n" |
| " case 1: {\n" |
| " f();\n" |
| " break;\n" |
| " }\n" |
| "}"); |
| verifyGoogleFormat("switch (test)\n" |
| " ;"); |
| |
| verifyGoogleFormat("#define OPERATION_CASE(name) \\\n" |
| " case OP_name: \\\n" |
| " return operations::Operation##name\n"); |
| verifyGoogleFormat("Operation codeToOperation(OperationCode OpCode) {\n" |
| " // Get the correction operation class.\n" |
| " switch (OpCode) {\n" |
| " CASE(Add);\n" |
| " CASE(Subtract);\n" |
| " default:\n" |
| " return operations::Unknown;\n" |
| " }\n" |
| "#undef OPERATION_CASE\n" |
| "}"); |
| verifyFormat("DEBUG({\n" |
| " switch (x) {\n" |
| " case A:\n" |
| " f();\n" |
| " break;\n" |
| " // fallthrough\n" |
| " case B:\n" |
| " g();\n" |
| " break;\n" |
| " }\n" |
| "});"); |
| EXPECT_EQ("DEBUG({\n" |
| " switch (x) {\n" |
| " case A:\n" |
| " f();\n" |
| " break;\n" |
| " // On B:\n" |
| " case B:\n" |
| " g();\n" |
| " break;\n" |
| " }\n" |
| "});", |
| format("DEBUG({\n" |
| " switch (x) {\n" |
| " case A:\n" |
| " f();\n" |
| " break;\n" |
| " // On B:\n" |
| " case B:\n" |
| " g();\n" |
| " break;\n" |
| " }\n" |
| "});", |
| getLLVMStyle())); |
| EXPECT_EQ("switch (n) {\n" |
| "case 0: {\n" |
| " return false;\n" |
| "}\n" |
| "default: {\n" |
| " return true;\n" |
| "}\n" |
| "}", |
| format("switch (n)\n" |
| "{\n" |
| "case 0: {\n" |
| " return false;\n" |
| "}\n" |
| "default: {\n" |
| " return true;\n" |
| "}\n" |
| "}", |
| getLLVMStyle())); |
| verifyFormat("switch (a) {\n" |
| "case (b):\n" |
| " return;\n" |
| "}"); |
| |
| verifyFormat("switch (a) {\n" |
| "case some_namespace::\n" |
| " some_constant:\n" |
| " return;\n" |
| "}", |
| getLLVMStyleWithColumns(34)); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.IndentCaseLabels = true; |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterCaseLabel = true; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; |
| EXPECT_EQ("switch (n)\n" |
| "{\n" |
| " case 0:\n" |
| " {\n" |
| " return false;\n" |
| " }\n" |
| " default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| format("switch (n) {\n" |
| " case 0: {\n" |
| " return false;\n" |
| " }\n" |
| " default: {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| Style)); |
| Style.BraceWrapping.AfterCaseLabel = false; |
| EXPECT_EQ("switch (n)\n" |
| "{\n" |
| " case 0: {\n" |
| " return false;\n" |
| " }\n" |
| " default: {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| format("switch (n) {\n" |
| " case 0:\n" |
| " {\n" |
| " return false;\n" |
| " }\n" |
| " default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| Style)); |
| Style.IndentCaseLabels = false; |
| Style.IndentCaseBlocks = true; |
| EXPECT_EQ("switch (n)\n" |
| "{\n" |
| "case 0:\n" |
| " {\n" |
| " return false;\n" |
| " }\n" |
| "case 1:\n" |
| " break;\n" |
| "default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| format("switch (n) {\n" |
| "case 0: {\n" |
| " return false;\n" |
| "}\n" |
| "case 1:\n" |
| " break;\n" |
| "default: {\n" |
| " return true;\n" |
| "}\n" |
| "}", |
| Style)); |
| Style.IndentCaseLabels = true; |
| Style.IndentCaseBlocks = true; |
| EXPECT_EQ("switch (n)\n" |
| "{\n" |
| " case 0:\n" |
| " {\n" |
| " return false;\n" |
| " }\n" |
| " case 1:\n" |
| " break;\n" |
| " default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| format("switch (n) {\n" |
| "case 0: {\n" |
| " return false;\n" |
| "}\n" |
| "case 1:\n" |
| " break;\n" |
| "default: {\n" |
| " return true;\n" |
| "}\n" |
| "}", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, CaseRanges) { |
| verifyFormat("switch (x) {\n" |
| "case 'A' ... 'Z':\n" |
| "case 1 ... 5:\n" |
| "case a ... b:\n" |
| " break;\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, ShortEnums) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortEnumsOnASingleLine = true; |
| verifyFormat("enum { A, B, C } ShortEnum1, ShortEnum2;", Style); |
| Style.AllowShortEnumsOnASingleLine = false; |
| verifyFormat("enum {\n" |
| " A,\n" |
| " B,\n" |
| " C\n" |
| "} ShortEnum1, ShortEnum2;", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterEnum = true; |
| verifyFormat("enum\n" |
| "{\n" |
| " A,\n" |
| " B,\n" |
| " C\n" |
| "} ShortEnum1, ShortEnum2;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ShortCaseLabels) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortCaseLabelsOnASingleLine = true; |
| verifyFormat("switch (a) {\n" |
| "case 1: x = 1; break;\n" |
| "case 2: return;\n" |
| "case 3:\n" |
| "case 4:\n" |
| "case 5: return;\n" |
| "case 6: // comment\n" |
| " return;\n" |
| "case 7:\n" |
| " // comment\n" |
| " return;\n" |
| "case 8:\n" |
| " x = 8; // comment\n" |
| " break;\n" |
| "default: y = 1; break;\n" |
| "}", |
| Style); |
| verifyFormat("switch (a) {\n" |
| "case 0: return; // comment\n" |
| "case 1: break; // comment\n" |
| "case 2: return;\n" |
| "// comment\n" |
| "case 3: return;\n" |
| "// comment 1\n" |
| "// comment 2\n" |
| "// comment 3\n" |
| "case 4: break; /* comment */\n" |
| "case 5:\n" |
| " // comment\n" |
| " break;\n" |
| "case 6: /* comment */ x = 1; break;\n" |
| "case 7: x = /* comment */ 1; break;\n" |
| "case 8:\n" |
| " x = 1; /* comment */\n" |
| " break;\n" |
| "case 9:\n" |
| " break; // comment line 1\n" |
| " // comment line 2\n" |
| "}", |
| Style); |
| EXPECT_EQ("switch (a) {\n" |
| "case 1:\n" |
| " x = 8;\n" |
| " // fall through\n" |
| "case 2: x = 8;\n" |
| "// comment\n" |
| "case 3:\n" |
| " return; /* comment line 1\n" |
| " * comment line 2 */\n" |
| "case 4: i = 8;\n" |
| "// something else\n" |
| "#if FOO\n" |
| "case 5: break;\n" |
| "#endif\n" |
| "}", |
| format("switch (a) {\n" |
| "case 1: x = 8;\n" |
| " // fall through\n" |
| "case 2:\n" |
| " x = 8;\n" |
| "// comment\n" |
| "case 3:\n" |
| " return; /* comment line 1\n" |
| " * comment line 2 */\n" |
| "case 4:\n" |
| " i = 8;\n" |
| "// something else\n" |
| "#if FOO\n" |
| "case 5: break;\n" |
| "#endif\n" |
| "}", |
| Style)); |
| EXPECT_EQ("switch (a) {\n" |
| "case 0:\n" |
| " return; // long long long long long long long long long long " |
| "long long comment\n" |
| " // line\n" |
| "}", |
| format("switch (a) {\n" |
| "case 0: return; // long long long long long long long long " |
| "long long long long comment line\n" |
| "}", |
| Style)); |
| EXPECT_EQ("switch (a) {\n" |
| "case 0:\n" |
| " return; /* long long long long long long long long long long " |
| "long long comment\n" |
| " line */\n" |
| "}", |
| format("switch (a) {\n" |
| "case 0: return; /* long long long long long long long long " |
| "long long long long comment line */\n" |
| "}", |
| Style)); |
| verifyFormat("switch (a) {\n" |
| "#if FOO\n" |
| "case 0: return 0;\n" |
| "#endif\n" |
| "}", |
| Style); |
| verifyFormat("switch (a) {\n" |
| "case 1: {\n" |
| "}\n" |
| "case 2: {\n" |
| " return;\n" |
| "}\n" |
| "case 3: {\n" |
| " x = 1;\n" |
| " return;\n" |
| "}\n" |
| "case 4:\n" |
| " if (x)\n" |
| " return;\n" |
| "}", |
| Style); |
| Style.ColumnLimit = 21; |
| verifyFormat("switch (a) {\n" |
| "case 1: x = 1; break;\n" |
| "case 2: return;\n" |
| "case 3:\n" |
| "case 4:\n" |
| "case 5: return;\n" |
| "default:\n" |
| " y = 1;\n" |
| " break;\n" |
| "}", |
| Style); |
| Style.ColumnLimit = 80; |
| Style.AllowShortCaseLabelsOnASingleLine = false; |
| Style.IndentCaseLabels = true; |
| EXPECT_EQ("switch (n) {\n" |
| " default /*comments*/:\n" |
| " return true;\n" |
| " case 0:\n" |
| " return false;\n" |
| "}", |
| format("switch (n) {\n" |
| "default/*comments*/:\n" |
| " return true;\n" |
| "case 0:\n" |
| " return false;\n" |
| "}", |
| Style)); |
| Style.AllowShortCaseLabelsOnASingleLine = true; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterCaseLabel = true; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; |
| EXPECT_EQ("switch (n)\n" |
| "{\n" |
| " case 0:\n" |
| " {\n" |
| " return false;\n" |
| " }\n" |
| " default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| format("switch (n) {\n" |
| " case 0: {\n" |
| " return false;\n" |
| " }\n" |
| " default:\n" |
| " {\n" |
| " return true;\n" |
| " }\n" |
| "}", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsLabels) { |
| verifyFormat("void f() {\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| " {\n" |
| " some_more_code();\n" |
| " another_label:\n" |
| " some_more_code();\n" |
| " }\n" |
| "}"); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| "}"); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:;\n" |
| " int i = 0;\n" |
| "}"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.IndentGotoLabels = false; |
| verifyFormat("void f() {\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| " {\n" |
| " some_more_code();\n" |
| "another_label:\n" |
| " some_more_code();\n" |
| " }\n" |
| "}", |
| Style); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:\n" |
| " some_other_code();\n" |
| "}", |
| Style); |
| verifyFormat("{\n" |
| " some_code();\n" |
| "test_label:;\n" |
| " int i = 0;\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, MultiLineControlStatements) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Custom; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine; |
| Style.ColumnLimit = 20; |
| // Short lines should keep opening brace on same line. |
| EXPECT_EQ("if (foo) {\n" |
| " bar();\n" |
| "}", |
| format("if(foo){bar();}", Style)); |
| EXPECT_EQ("if (foo) {\n" |
| " bar();\n" |
| "} else {\n" |
| " baz();\n" |
| "}", |
| format("if(foo){bar();}else{baz();}", Style)); |
| EXPECT_EQ("if (foo && bar) {\n" |
| " baz();\n" |
| "}", |
| format("if(foo&&bar){baz();}", Style)); |
| EXPECT_EQ("if (foo) {\n" |
| " bar();\n" |
| "} else if (baz) {\n" |
| " quux();\n" |
| "}", |
| format("if(foo){bar();}else if(baz){quux();}", Style)); |
| EXPECT_EQ( |
| "if (foo) {\n" |
| " bar();\n" |
| "} else if (baz) {\n" |
| " quux();\n" |
| "} else {\n" |
| " foobar();\n" |
| "}", |
| format("if(foo){bar();}else if(baz){quux();}else{foobar();}", Style)); |
| EXPECT_EQ("for (;;) {\n" |
| " foo();\n" |
| "}", |
| format("for(;;){foo();}")); |
| EXPECT_EQ("while (1) {\n" |
| " foo();\n" |
| "}", |
| format("while(1){foo();}", Style)); |
| EXPECT_EQ("switch (foo) {\n" |
| "case bar:\n" |
| " return;\n" |
| "}", |
| format("switch(foo){case bar:return;}", Style)); |
| EXPECT_EQ("try {\n" |
| " foo();\n" |
| "} catch (...) {\n" |
| " bar();\n" |
| "}", |
| format("try{foo();}catch(...){bar();}", Style)); |
| EXPECT_EQ("do {\n" |
| " foo();\n" |
| "} while (bar &&\n" |
| " baz);", |
| format("do{foo();}while(bar&&baz);", Style)); |
| // Long lines should put opening brace on new line. |
| EXPECT_EQ("if (foo && bar &&\n" |
| " baz)\n" |
| "{\n" |
| " quux();\n" |
| "}", |
| format("if(foo&&bar&&baz){quux();}", Style)); |
| EXPECT_EQ("if (foo && bar &&\n" |
| " baz)\n" |
| "{\n" |
| " quux();\n" |
| "}", |
| format("if (foo && bar &&\n" |
| " baz) {\n" |
| " quux();\n" |
| "}", |
| Style)); |
| EXPECT_EQ("if (foo) {\n" |
| " bar();\n" |
| "} else if (baz ||\n" |
| " quux)\n" |
| "{\n" |
| " foobar();\n" |
| "}", |
| format("if(foo){bar();}else if(baz||quux){foobar();}", Style)); |
| EXPECT_EQ( |
| "if (foo) {\n" |
| " bar();\n" |
| "} else if (baz ||\n" |
| " quux)\n" |
| "{\n" |
| " foobar();\n" |
| "} else {\n" |
| " barbaz();\n" |
| "}", |
| format("if(foo){bar();}else if(baz||quux){foobar();}else{barbaz();}", |
| Style)); |
| EXPECT_EQ("for (int i = 0;\n" |
| " i < 10; ++i)\n" |
| "{\n" |
| " foo();\n" |
| "}", |
| format("for(int i=0;i<10;++i){foo();}", Style)); |
| EXPECT_EQ("foreach (int i,\n" |
| " list)\n" |
| "{\n" |
| " foo();\n" |
| "}", |
| format("foreach(int i, list){foo();}", Style)); |
| Style.ColumnLimit = |
| 40; // to concentrate at brace wrapping, not line wrap due to column limit |
| EXPECT_EQ("foreach (int i, list) {\n" |
| " foo();\n" |
| "}", |
| format("foreach(int i, list){foo();}", Style)); |
| Style.ColumnLimit = |
| 20; // to concentrate at brace wrapping, not line wrap due to column limit |
| EXPECT_EQ("while (foo || bar ||\n" |
| " baz)\n" |
| "{\n" |
| " quux();\n" |
| "}", |
| format("while(foo||bar||baz){quux();}", Style)); |
| EXPECT_EQ("switch (\n" |
| " foo = barbaz)\n" |
| "{\n" |
| "case quux:\n" |
| " return;\n" |
| "}", |
| format("switch(foo=barbaz){case quux:return;}", Style)); |
| EXPECT_EQ("try {\n" |
| " foo();\n" |
| "} catch (\n" |
| " Exception &bar)\n" |
| "{\n" |
| " baz();\n" |
| "}", |
| format("try{foo();}catch(Exception&bar){baz();}", Style)); |
| Style.ColumnLimit = |
| 40; // to concentrate at brace wrapping, not line wrap due to column limit |
| EXPECT_EQ("try {\n" |
| " foo();\n" |
| "} catch (Exception &bar) {\n" |
| " baz();\n" |
| "}", |
| format("try{foo();}catch(Exception&bar){baz();}", Style)); |
| Style.ColumnLimit = |
| 20; // to concentrate at brace wrapping, not line wrap due to column limit |
| |
| Style.BraceWrapping.BeforeElse = true; |
| EXPECT_EQ( |
| "if (foo) {\n" |
| " bar();\n" |
| "}\n" |
| "else if (baz ||\n" |
| " quux)\n" |
| "{\n" |
| " foobar();\n" |
| "}\n" |
| "else {\n" |
| " barbaz();\n" |
| "}", |
| format("if(foo){bar();}else if(baz||quux){foobar();}else{barbaz();}", |
| Style)); |
| |
| Style.BraceWrapping.BeforeCatch = true; |
| EXPECT_EQ("try {\n" |
| " foo();\n" |
| "}\n" |
| "catch (...) {\n" |
| " baz();\n" |
| "}", |
| format("try{foo();}catch(...){baz();}", Style)); |
| |
| Style.BraceWrapping.AfterFunction = true; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine; |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| Style.ColumnLimit = 80; |
| verifyFormat("void shortfunction() { bar(); }", Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| verifyFormat("void shortfunction()\n" |
| "{\n" |
| " bar();\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, BeforeWhile) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Custom; |
| |
| verifyFormat("do {\n" |
| " foo();\n" |
| "} while (1);", |
| Style); |
| Style.BraceWrapping.BeforeWhile = true; |
| verifyFormat("do {\n" |
| " foo();\n" |
| "}\n" |
| "while (1);", |
| Style); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Tests for classes, namespaces, etc. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, DoesNotBreakSemiAfterClassDecl) { |
| verifyFormat("class A {};"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsAccessSpecifiers) { |
| verifyFormat("class A {\n" |
| "public:\n" |
| "public: // comment\n" |
| "protected:\n" |
| "private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyFormat("export class A {\n" |
| "public:\n" |
| "public: // comment\n" |
| "protected:\n" |
| "private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyGoogleFormat("class A {\n" |
| " public:\n" |
| " protected:\n" |
| " private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyGoogleFormat("export class A {\n" |
| " public:\n" |
| " protected:\n" |
| " private:\n" |
| " void f() {}\n" |
| "};"); |
| verifyFormat("class A {\n" |
| "public slots:\n" |
| " void f1() {}\n" |
| "public Q_SLOTS:\n" |
| " void f2() {}\n" |
| "protected slots:\n" |
| " void f3() {}\n" |
| "protected Q_SLOTS:\n" |
| " void f4() {}\n" |
| "private slots:\n" |
| " void f5() {}\n" |
| "private Q_SLOTS:\n" |
| " void f6() {}\n" |
| "signals:\n" |
| " void g1();\n" |
| "Q_SIGNALS:\n" |
| " void g2();\n" |
| "};"); |
| |
| // Don't interpret 'signals' the wrong way. |
| verifyFormat("signals.set();"); |
| verifyFormat("for (Signals signals : f()) {\n}"); |
| verifyFormat("{\n" |
| " signals.set(); // This needs indentation.\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| "label:\n" |
| " signals.baz();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, SeparatesLogicalBlocks) { |
| EXPECT_EQ("class A {\n" |
| "public:\n" |
| " void f();\n" |
| "\n" |
| "private:\n" |
| " void g() {}\n" |
| " // test\n" |
| "protected:\n" |
| " int h;\n" |
| "};", |
| format("class A {\n" |
| "public:\n" |
| "void f();\n" |
| "private:\n" |
| "void g() {}\n" |
| "// test\n" |
| "protected:\n" |
| "int h;\n" |
| "};")); |
| EXPECT_EQ("class A {\n" |
| "protected:\n" |
| "public:\n" |
| " void f();\n" |
| "};", |
| format("class A {\n" |
| "protected:\n" |
| "\n" |
| "public:\n" |
| "\n" |
| " void f();\n" |
| "};")); |
| |
| // Even ensure proper spacing inside macros. |
| EXPECT_EQ("#define B \\\n" |
| " class A { \\\n" |
| " protected: \\\n" |
| " public: \\\n" |
| " void f(); \\\n" |
| " };", |
| format("#define B \\\n" |
| " class A { \\\n" |
| " protected: \\\n" |
| " \\\n" |
| " public: \\\n" |
| " \\\n" |
| " void f(); \\\n" |
| " };", |
| getGoogleStyle())); |
| // But don't remove empty lines after macros ending in access specifiers. |
| EXPECT_EQ("#define A private:\n" |
| "\n" |
| "int i;", |
| format("#define A private:\n" |
| "\n" |
| "int i;")); |
| } |
| |
| TEST_F(FormatTest, FormatsClasses) { |
| verifyFormat("class A : public B {};"); |
| verifyFormat("class A : public ::B {};"); |
| |
| verifyFormat( |
| "class AAAAAAAAAAAAAAAAAAAA : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};"); |
| verifyFormat("class AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" |
| " : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};"); |
| verifyFormat( |
| "class A : public B, public C, public D, public E, public F {};"); |
| verifyFormat("class AAAAAAAAAAAA : public B,\n" |
| " public C,\n" |
| " public D,\n" |
| " public E,\n" |
| " public F,\n" |
| " public G {};"); |
| |
| verifyFormat("class\n" |
| " ReallyReallyLongClassName {\n" |
| " int i;\n" |
| "};", |
| getLLVMStyleWithColumns(32)); |
| verifyFormat("struct aaaaaaaaaaaaa : public aaaaaaaaaaaaaaaaaaa< // break\n" |
| " aaaaaaaaaaaaaaaa> {};"); |
| verifyFormat("struct aaaaaaaaaaaaaaaaaaaa\n" |
| " : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa> {};"); |
| verifyFormat("template <class R, class C>\n" |
| "struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n" |
| " : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};"); |
| verifyFormat("class ::A::B {};"); |
| } |
| |
| TEST_F(FormatTest, BreakInheritanceStyle) { |
| FormatStyle StyleWithInheritanceBreakBeforeComma = getLLVMStyle(); |
| StyleWithInheritanceBreakBeforeComma.BreakInheritanceList = |
| FormatStyle::BILS_BeforeComma; |
| verifyFormat("class MyClass : public X {};", |
| StyleWithInheritanceBreakBeforeComma); |
| verifyFormat("class MyClass\n" |
| " : public X\n" |
| " , public Y {};", |
| StyleWithInheritanceBreakBeforeComma); |
| verifyFormat("class AAAAAAAAAAAAAAAAAAAAAA\n" |
| " : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n" |
| " , public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};", |
| StyleWithInheritanceBreakBeforeComma); |
| verifyFormat("struct aaaaaaaaaaaaa\n" |
| " : public aaaaaaaaaaaaaaaaaaa< // break\n" |
| " aaaaaaaaaaaaaaaa> {};", |
| StyleWithInheritanceBreakBeforeComma); |
| |
| FormatStyle StyleWithInheritanceBreakAfterColon = getLLVMStyle(); |
| StyleWithInheritanceBreakAfterColon.BreakInheritanceList = |
| FormatStyle::BILS_AfterColon; |
| verifyFormat("class MyClass : public X {};", |
| StyleWithInheritanceBreakAfterColon); |
| verifyFormat("class MyClass : public X, public Y {};", |
| StyleWithInheritanceBreakAfterColon); |
| verifyFormat("class AAAAAAAAAAAAAAAAAAAAAA :\n" |
| " public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};", |
| StyleWithInheritanceBreakAfterColon); |
| verifyFormat("struct aaaaaaaaaaaaa :\n" |
| " public aaaaaaaaaaaaaaaaaaa< // break\n" |
| " aaaaaaaaaaaaaaaa> {};", |
| StyleWithInheritanceBreakAfterColon); |
| |
| FormatStyle StyleWithInheritanceBreakAfterComma = getLLVMStyle(); |
| StyleWithInheritanceBreakAfterComma.BreakInheritanceList = |
| FormatStyle::BILS_AfterComma; |
| verifyFormat("class MyClass : public X {};", |
| StyleWithInheritanceBreakAfterComma); |
| verifyFormat("class MyClass : public X,\n" |
| " public Y {};", |
| StyleWithInheritanceBreakAfterComma); |
| verifyFormat( |
| "class AAAAAAAAAAAAAAAAAAAAAA : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" |
| " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC " |
| "{};", |
| StyleWithInheritanceBreakAfterComma); |
| verifyFormat("struct aaaaaaaaaaaaa : public aaaaaaaaaaaaaaaaaaa< // break\n" |
| " aaaaaaaaaaaaaaaa> {};", |
| StyleWithInheritanceBreakAfterComma); |
| verifyFormat("class AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" |
| " : public OnceBreak,\n" |
| " public AlwaysBreak,\n" |
| " EvenBasesFitInOneLine {};", |
| StyleWithInheritanceBreakAfterComma); |
| } |
| |
| TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) { |
| verifyFormat("class A {\n} a, b;"); |
| verifyFormat("struct A {\n} a, b;"); |
| verifyFormat("union A {\n} a;"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnum) { |
| verifyFormat("enum {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyGoogleFormat("enum {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum Enum {};"); |
| verifyFormat("enum {};"); |
| verifyFormat("enum X E {} d;"); |
| verifyFormat("enum __attribute__((...)) E {} d;"); |
| verifyFormat("enum __declspec__((...)) E {} d;"); |
| verifyFormat("enum {\n" |
| " Bar = Foo<int, int>::value\n" |
| "};", |
| getLLVMStyleWithColumns(30)); |
| |
| verifyFormat("enum ShortEnum { A, B, C };"); |
| verifyGoogleFormat("enum ShortEnum { A, B, C };"); |
| |
| EXPECT_EQ("enum KeepEmptyLines {\n" |
| " ONE,\n" |
| "\n" |
| " TWO,\n" |
| "\n" |
| " THREE\n" |
| "}", |
| format("enum KeepEmptyLines {\n" |
| " ONE,\n" |
| "\n" |
| " TWO,\n" |
| "\n" |
| "\n" |
| " THREE\n" |
| "}")); |
| verifyFormat("enum E { // comment\n" |
| " ONE,\n" |
| " TWO\n" |
| "};\n" |
| "int i;"); |
| |
| FormatStyle EightIndent = getLLVMStyle(); |
| EightIndent.IndentWidth = 8; |
| verifyFormat("enum {\n" |
| " VOID,\n" |
| " CHAR,\n" |
| " SHORT,\n" |
| " INT,\n" |
| " LONG,\n" |
| " SIGNED,\n" |
| " UNSIGNED,\n" |
| " BOOL,\n" |
| " FLOAT,\n" |
| " DOUBLE,\n" |
| " COMPLEX\n" |
| "};", |
| EightIndent); |
| |
| // Not enums. |
| verifyFormat("enum X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum X Type::f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum ::X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| verifyFormat("enum ns::X f() {\n" |
| " a();\n" |
| " return 42;\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumsWithErrors) { |
| verifyFormat("enum Type {\n" |
| " One = 0; // These semicolons should be commas.\n" |
| " Two = 1;\n" |
| "};"); |
| verifyFormat("namespace n {\n" |
| "enum Type {\n" |
| " One,\n" |
| " Two, // missing };\n" |
| " int i;\n" |
| "}\n" |
| "void g() {}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumStruct) { |
| verifyFormat("enum struct {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum struct Enum {};"); |
| verifyFormat("enum struct {};"); |
| verifyFormat("enum struct X E {} d;"); |
| verifyFormat("enum struct __attribute__((...)) E {} d;"); |
| verifyFormat("enum struct __declspec__((...)) E {} d;"); |
| verifyFormat("enum struct X f() {\n a();\n return 42;\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumClass) { |
| verifyFormat("enum class {\n" |
| " Zero,\n" |
| " One = 1,\n" |
| " Two = One + 1,\n" |
| " Three = (One + Two),\n" |
| " Four = (Zero && (One ^ Two)) | (One << Two),\n" |
| " Five = (One, Two, Three, Four, 5)\n" |
| "};"); |
| verifyFormat("enum class Enum {};"); |
| verifyFormat("enum class {};"); |
| verifyFormat("enum class X E {} d;"); |
| verifyFormat("enum class __attribute__((...)) E {} d;"); |
| verifyFormat("enum class __declspec__((...)) E {} d;"); |
| verifyFormat("enum class X f() {\n a();\n return 42;\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatsEnumTypes) { |
| verifyFormat("enum X : int {\n" |
| " A, // Force multiple lines.\n" |
| " B\n" |
| "};"); |
| verifyFormat("enum X : int { A, B };"); |
| verifyFormat("enum X : std::uint32_t { A, B };"); |
| } |
| |
| TEST_F(FormatTest, FormatsTypedefEnum) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = 40; |
| verifyFormat("typedef enum {} EmptyEnum;"); |
| verifyFormat("typedef enum { A, B, C } ShortEnum;"); |
| verifyFormat("typedef enum {\n" |
| " ZERO = 0,\n" |
| " ONE = 1,\n" |
| " TWO = 2,\n" |
| " THREE = 3\n" |
| "} LongEnum;", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterEnum = true; |
| verifyFormat("typedef enum {} EmptyEnum;"); |
| verifyFormat("typedef enum { A, B, C } ShortEnum;"); |
| verifyFormat("typedef enum\n" |
| "{\n" |
| " ZERO = 0,\n" |
| " ONE = 1,\n" |
| " TWO = 2,\n" |
| " THREE = 3\n" |
| "} LongEnum;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsNSEnums) { |
| verifyGoogleFormat("typedef NS_ENUM(NSInteger, SomeName) { AAA, BBB }"); |
| verifyGoogleFormat( |
| "typedef NS_CLOSED_ENUM(NSInteger, SomeName) { AAA, BBB }"); |
| verifyGoogleFormat("typedef NS_ENUM(NSInteger, MyType) {\n" |
| " // Information about someDecentlyLongValue.\n" |
| " someDecentlyLongValue,\n" |
| " // Information about anotherDecentlyLongValue.\n" |
| " anotherDecentlyLongValue,\n" |
| " // Information about aThirdDecentlyLongValue.\n" |
| " aThirdDecentlyLongValue\n" |
| "};"); |
| verifyGoogleFormat("typedef NS_CLOSED_ENUM(NSInteger, MyType) {\n" |
| " // Information about someDecentlyLongValue.\n" |
| " someDecentlyLongValue,\n" |
| " // Information about anotherDecentlyLongValue.\n" |
| " anotherDecentlyLongValue,\n" |
| " // Information about aThirdDecentlyLongValue.\n" |
| " aThirdDecentlyLongValue\n" |
| "};"); |
| verifyGoogleFormat("typedef NS_OPTIONS(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| verifyGoogleFormat("typedef CF_ENUM(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| verifyGoogleFormat("typedef CF_CLOSED_ENUM(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| verifyGoogleFormat("typedef CF_OPTIONS(NSInteger, MyType) {\n" |
| " a = 1,\n" |
| " b = 2,\n" |
| " c = 3,\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsBitfields) { |
| verifyFormat("struct Bitfields {\n" |
| " unsigned sClass : 8;\n" |
| " unsigned ValueKind : 2;\n" |
| "};"); |
| verifyFormat("struct A {\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa : 1,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb;\n" |
| "};"); |
| verifyFormat("struct MyStruct {\n" |
| " uchar data;\n" |
| " uchar : 8;\n" |
| " uchar : 8;\n" |
| " uchar other;\n" |
| "};"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.BitFieldColonSpacing = FormatStyle::BFCS_None; |
| verifyFormat("struct Bitfields {\n" |
| " unsigned sClass:8;\n" |
| " unsigned ValueKind:2;\n" |
| " uchar other;\n" |
| "};", |
| Style); |
| verifyFormat("struct A {\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:1,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb:2;\n" |
| "};", |
| Style); |
| Style.BitFieldColonSpacing = FormatStyle::BFCS_Before; |
| verifyFormat("struct Bitfields {\n" |
| " unsigned sClass :8;\n" |
| " unsigned ValueKind :2;\n" |
| " uchar other;\n" |
| "};", |
| Style); |
| Style.BitFieldColonSpacing = FormatStyle::BFCS_After; |
| verifyFormat("struct Bitfields {\n" |
| " unsigned sClass: 8;\n" |
| " unsigned ValueKind: 2;\n" |
| " uchar other;\n" |
| "};", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsNamespaces) { |
| FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle(); |
| LLVMWithNoNamespaceFix.FixNamespaceComments = false; |
| |
| verifyFormat("namespace some_namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("namespace N::inline D {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("namespace N::inline D::E {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("namespace [[deprecated(\"foo[bar\")]] some_namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("/* something */ namespace some_namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("/* something */ namespace {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("inline namespace X {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("/* something */ inline namespace X {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("export namespace X {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("using namespace some_namespace;\n" |
|