| //===- 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 = getLLVMStyle(); |
| CustomStyle.BreakBeforeBraces = 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 consteval {\n}"); |
| verifyFormat("if !consteval {\n}"); |
| verifyFormat("if not consteval {\n}"); |
| verifyFormat("if consteval {\n} else {\n}"); |
| verifyFormat("if !consteval {\n} else {\n}"); |
| verifyFormat("if consteval {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("if !consteval {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("if consteval {\n" |
| " f();\n" |
| "} else {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("if CONSTEVAL {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("if !CONSTEVAL {\n" |
| " f();\n" |
| "}"); |
| |
| 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("BOOST_FOREACH (int &v, vec) v *= 2;", AllowsMergedLoops); |
| verifyFormat("while (true)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " ;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " for (;;) continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " while (true) continue;", |
| AllowsMergedLoops); |
| verifyFormat("while (true)\n" |
| " for (;;) continue;", |
| AllowsMergedLoops); |
| verifyFormat("BOOST_FOREACH (int &v, vec)\n" |
| " for (;;) continue;", |
| AllowsMergedLoops); |
| verifyFormat("for (;;)\n" |
| " BOOST_FOREACH (int &v, vec) 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(); |
| EXPECT_EQ(AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine, false); |
| EXPECT_EQ(AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_Never); |
| EXPECT_EQ(AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine, false); |
| EXPECT_EQ(AllowSimpleBracedStatements.BraceWrapping.AfterFunction, false); |
| verifyFormat("for (;;) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("/*comment*/ for (;;) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("BOOST_FOREACH (int v, vec) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("/*comment*/ BOOST_FOREACH (int v, vec) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("while (true) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("/*comment*/ while (true) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("if (true) {\n" |
| " f();\n" |
| "}"); |
| verifyFormat("/*comment*/ if (true) {\n" |
| " f();\n" |
| "}"); |
| |
| AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = |
| FormatStyle::SBS_Empty; |
| AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| verifyFormat("if (true) {}", AllowSimpleBracedStatements); |
| verifyFormat("if (i) break;", AllowSimpleBracedStatements); |
| verifyFormat("if (i > 0) {\n" |
| " return i;\n" |
| "}", |
| AllowSimpleBracedStatements); |
| |
| 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.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("if consteval {}", AllowSimpleBracedStatements); |
| verifyFormat("if !consteval {}", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEVAL {}", 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("if consteval { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("if CONSTEVAL { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF consteval { f(); }", AllowSimpleBracedStatements); |
| verifyFormat("MYIF CONSTEVAL { 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); |
| verifyFormat("BOOST_FOREACH (int v, vec) {}", AllowSimpleBracedStatements); |
| verifyFormat("BOOST_FOREACH (int v, vec) {\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); |
| verifyFormat("BOOST_FOREACH (int v, vec) {}", AllowSimpleBracedStatements); |
| verifyFormat("BOOST_FOREACH (int v, vec)\n" |
| "{\n" |
| " f();\n" |
| "}", |
| AllowSimpleBracedStatements); |
| } |
| |
| TEST_F(FormatTest, UnderstandsMacros) { |
| verifyFormat("#define A (parentheses)"); |
| verifyFormat("/* comment */ #define A (parentheses)"); |
| verifyFormat("/* comment */ /* another comment */ #define A (parentheses)"); |
| // Even the partial code should never be merged. |
| EXPECT_EQ("/* comment */ #define A (parentheses)\n" |
| "#", |
| format("/* comment */ #define A (parentheses)\n" |
| "#")); |
| verifyFormat("/* comment */ #define A (parentheses)\n" |
| "#\n"); |
| verifyFormat("/* comment */ #define A (parentheses)\n" |
| "#define B (parentheses)"); |
| verifyFormat("#define true ((int)1)"); |
| verifyFormat("#define and(x)"); |
| verifyFormat("#define if(x) x"); |
| verifyFormat("#define return(x) (x)"); |
| verifyFormat("#define while(x) for (; x;)"); |
| verifyFormat("#define xor(x) (^(x))"); |
| verifyFormat("#define __except(x)"); |
| verifyFormat("#define __try(x)"); |
| |
| // https://llvm.org/PR54348. |
| verifyFormat( |
| "#define A" |
| " " |
| "\\\n" |
| " class & {}"); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| // Test that a macro definition never gets merged with the following |
| // definition. |
| // FIXME: The AAA macro definition probably should not be split into 3 lines. |
| verifyFormat("#define AAA " |
| " \\\n" |
| " N " |
| " \\\n" |
| " {\n" |
| "#define BBB }\n", |
| Style); |
| // verifyFormat("#define AAA N { //\n", Style); |
| |
| verifyFormat("MACRO(return)"); |
| verifyFormat("MACRO(co_await)"); |
| verifyFormat("MACRO(co_return)"); |
| verifyFormat("MACRO(co_yield)"); |
| verifyFormat("MACRO(return, something)"); |
| verifyFormat("MACRO(co_return, something)"); |
| verifyFormat("MACRO(something##something)"); |
| verifyFormat("MACRO(return##something)"); |
| verifyFormat("MACRO(co_return##something)"); |
| } |
| |
| 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(); |
| EXPECT_EQ(Style.PointerAlignment, FormatStyle::PAS_Right); |
| EXPECT_EQ(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); |
| verifyFormat("for (auto a = 0, b = 0; const auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const int &c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo &c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo *c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const int &c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const Foo &c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const int &c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo &c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; int &c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; int &c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); auto &c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); int &c : {1, 2, 3})", Style); |
| verifyFormat( |
| "function<int(int &)> res1 = [](int &a) { return 0000000000000; },\n" |
| " res2 = [](int &a) { return 0000000000000; };", |
| Style); |
| |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| 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); |
| verifyFormat("for (auto a = 0, b = 0; const auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const int& c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo& c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo* c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const int& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const Foo& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const Foo* c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const int& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo& c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo* c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; int& c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; int& c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); auto& c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); int& c : {1, 2, 3})", Style); |
| verifyFormat( |
| "function<int(int&)> res1 = [](int& a) { return 0000000000000; },\n" |
| " res2 = [](int& a) { return 0000000000000; };", |
| Style); |
| |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| 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); |
| verifyFormat("for (auto a = 0, b = 0; const Foo *c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style); |
| |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| 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); |
| verifyFormat("for (auto a = 0, b = 0; const auto & c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const int & c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo & c : {1, 2, 3})", Style); |
| verifyFormat("for (auto a = 0, b = 0; const Foo* c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const auto & c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const int & c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo & c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo* c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; auto & c : {1, 2, 3})", Style); |
| verifyFormat("for (auto x = 0; int & c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; auto & c : {1, 2, 3})", Style); |
| verifyFormat("for (int x = 0; int & c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); auto & c : {1, 2, 3})", Style); |
| verifyFormat("for (f(); int & c : {1, 2, 3})", Style); |
| verifyFormat( |
| "function<int(int &)> res1 = [](int & a) { return 0000000000000; },\n" |
| " res2 = [](int & a) { return 0000000000000; };", |
| Style); |
| |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| 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); |
| verifyFormat("for (auto a = 0, b = 0; const Foo * c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b = 0; const Foo * c : {1, 2, 3})", Style); |
| verifyFormat("for (int a = 0, b++; const Foo * c : {1, 2, 3})", 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) { |
| FormatStyle Style = getLLVMStyle(); |
| EXPECT_EQ(Style.AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); |
| EXPECT_EQ(Style.AllowShortLoopsOnASingleLine, false); |
| verifyFormat("void f() {\n" |
| " for (;;) {\n" |
| " }\n" |
| " foreach (Item *item, itemlist) {\n" |
| " }\n" |
| " Q_FOREACH (Item *item, itemlist) {\n" |
| " }\n" |
| " BOOST_FOREACH (Item *item, itemlist) {\n" |
| " }\n" |
| " UNKNOWN_FOREACH(Item * item, itemlist) {}\n" |
| "}", |
| Style); |
| verifyFormat("void f() {\n" |
| " for (;;)\n" |
| " int j = 1;\n" |
| " Q_FOREACH (int v, vec)\n" |
| " v *= 2;\n" |
| " for (;;) {\n" |
| " int j = 1;\n" |
| " }\n" |
| " Q_FOREACH (int v, vec) {\n" |
| " v *= 2;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| FormatStyle ShortBlocks = getLLVMStyle(); |
| ShortBlocks.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; |
| EXPECT_EQ(ShortBlocks.AllowShortLoopsOnASingleLine, false); |
| verifyFormat("void f() {\n" |
| " for (;;)\n" |
| " int j = 1;\n" |
| " Q_FOREACH (int &v, vec)\n" |
| " v *= 2;\n" |
| " for (;;) {\n" |
| " int j = 1;\n" |
| " }\n" |
| " Q_FOREACH (int &v, vec) {\n" |
| " int j = 1;\n" |
| " }\n" |
| "}", |
| ShortBlocks); |
| |
| FormatStyle ShortLoops = getLLVMStyle(); |
| ShortLoops.AllowShortLoopsOnASingleLine = true; |
| EXPECT_EQ(ShortLoops.AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); |
| verifyFormat("void f() {\n" |
| " for (;;) int j = 1;\n" |
| " Q_FOREACH (int &v, vec) int j = 1;\n" |
| " for (;;) {\n" |
| " int j = 1;\n" |
| " }\n" |
| " Q_FOREACH (int &v, vec) {\n" |
| " int j = 1;\n" |
| " }\n" |
| "}", |
| ShortLoops); |
| |
| FormatStyle ShortBlocksAndLoops = getLLVMStyle(); |
| ShortBlocksAndLoops.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; |
| ShortBlocksAndLoops.AllowShortLoopsOnASingleLine = true; |
| verifyFormat("void f() {\n" |
| " for (;;) int j = 1;\n" |
| " Q_FOREACH (int &v, vec) int j = 1;\n" |
| " for (;;) { int j = 1; }\n" |
| " Q_FOREACH (int &v, vec) { int j = 1; }\n" |
| "}", |
| ShortBlocksAndLoops); |
| |
| Style.SpaceBeforeParens = |
| FormatStyle::SBPO_ControlStatementsExceptControlMacros; |
| verifyFormat("void f() {\n" |
| " for (;;) {\n" |
| " }\n" |
| " foreach(Item *item, itemlist) {\n" |
| " }\n" |
| " Q_FOREACH(Item *item, itemlist) {\n" |
| " }\n" |
| " BOOST_FOREACH(Item *item, itemlist) {\n" |
| " }\n" |
| " UNKNOWN_FOREACH(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)); |
| |
| verifyFormat("switch (a) {\n" |
| "[[likely]] case 1:\n" |
| " return;\n" |
| "}"); |
| verifyFormat("switch (a) {\n" |
| "[[likely]] [[other::likely]] case 1:\n" |
| " return;\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| " return;\n" |
| "[[likely]] case 2:\n" |
| " return;\n" |
| "}"); |
| verifyFormat("switch (a) {\n" |
| "case 1:\n" |
| "[[likely]] case 2:\n" |
| " return;\n" |
| "}"); |
| FormatStyle Attributes = getLLVMStyle(); |
| Attributes.AttributeMacros.push_back("LIKELY"); |
| Attributes.AttributeMacros.push_back("OTHER_LIKELY"); |
| verifyFormat("switch (a) {\n" |
| "LIKELY case b:\n" |
| " return;\n" |
| "}", |
| Attributes); |
| verifyFormat("switch (a) {\n" |
| "LIKELY OTHER_LIKELY() case b:\n" |
| " return;\n" |
| "}", |
| Attributes); |
| verifyFormat("switch (a) {\n" |
| "case 1:\n" |
| " return;\n" |
| "LIKELY case 2:\n" |
| " return;\n" |
| "}", |
| Attributes); |
| verifyFormat("switch (a) {\n" |
| "case 1:\n" |
| "LIKELY case 2:\n" |
| " return;\n" |
| "}", |
| Attributes); |
| |
| 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(); |
| EXPECT_TRUE(Style.AllowShortEnumsOnASingleLine); |
| EXPECT_FALSE(Style.BraceWrapping.AfterEnum); |
| verifyFormat("enum { A, B, C } ShortEnum1, ShortEnum2;", Style); |
| verifyFormat("typedef enum { A, B, C } ShortEnum1, ShortEnum2;", Style); |
| Style.AllowShortEnumsOnASingleLine = false; |
| verifyFormat("enum {\n" |
| " A,\n" |
| " B,\n" |
| " C\n" |
| "} ShortEnum1, ShortEnum2;", |
| Style); |
| verifyFormat("typedef enum {\n" |
| " A,\n" |
| " B,\n" |
| " C\n" |
| "} ShortEnum1, ShortEnum2;", |
| Style); |
| verifyFormat("enum {\n" |
| " A,\n" |
| "} ShortEnum1, ShortEnum2;", |
| Style); |
| verifyFormat("typedef enum {\n" |
| " A,\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); |
| verifyFormat("typedef 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 = getLLVMStyleWithColumns(20); |
| Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Custom; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine; |
| // 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. |
| verifyFormat("void f() {\n" |
| " if (a1 && a2 &&\n" |
| " a3)\n" |
| " {\n" |
| " quux();\n" |
| " }\n" |
| "}", |
| "void f(){if(a1&&a2&&a3){quux();}}", Style); |
| 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" |
| "}"); |
| verifyFormat("private[1];"); |
| verifyFormat("testArray[public] = 1;"); |
| verifyFormat("public();"); |
| verifyFormat("myFunc(public);"); |
| verifyFormat("std::vector<int> testVec = {private};"); |
| verifyFormat("private.p = 1;"); |
| verifyFormat("void function(private...){};"); |
| verifyFormat("if (private && public)\n"); |
| verifyFormat("private &= true;"); |
| verifyFormat("int x = private * public;"); |
| verifyFormat("public *= private;"); |
| verifyFormat("int x = public + private;"); |
| verifyFormat("private++;"); |
| verifyFormat("++private;"); |
| verifyFormat("public += private;"); |
| verifyFormat("public = public - private;"); |
| verifyFormat("public->foo();"); |
| verifyFormat("private--;"); |
| verifyFormat("--private;"); |
| verifyFormat("public -= 1;"); |
| verifyFormat("if (!private && !public)\n"); |
| verifyFormat("public != private;"); |
| verifyFormat("int x = public / private;"); |
| verifyFormat("public /= 2;"); |
| verifyFormat("public = public % 2;"); |
| verifyFormat("public %= 2;"); |
| verifyFormat("if (public < private)\n"); |
| verifyFormat("public << private;"); |
| verifyFormat("public <<= private;"); |
| verifyFormat("if (public > private)\n"); |
| verifyFormat("public >> private;"); |
| verifyFormat("public >>= private;"); |
| verifyFormat("public ^ private;"); |
| verifyFormat("public ^= private;"); |
| verifyFormat("public | private;"); |
| verifyFormat("public |= private;"); |
| verifyFormat("auto x = private ? 1 : 2;"); |
| verifyFormat("if (public == private)\n"); |
| verifyFormat("void foo(public, private)"); |
| verifyFormat("public::foo();"); |
| |
| verifyFormat("class A {\n" |
| "public:\n" |
| " std::unique_ptr<int *[]> b() { return nullptr; }\n" |
| "\n" |
| "private:\n" |
| " int c;\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, FormatsVariableDeclarationsAfterRecord) { |
| verifyFormat("class A {\n} a, b;"); |
| verifyFormat("struct A {\n} a, b;"); |
| verifyFormat("union A {\n} a, b;"); |
| |
| verifyFormat("constexpr class A {\n} a, b;"); |
| verifyFormat("constexpr struct A {\n} a, b;"); |
| verifyFormat("constexpr union A {\n} a, b;"); |
| |
| verifyFormat("namespace {\nclass A {\n} a, b;\n} // namespace"); |
| verifyFormat("namespace {\nstruct A {\n} a, b;\n} // namespace"); |
| verifyFormat("namespace {\nunion A {\n} a, b;\n} // namespace"); |
| |
| verifyFormat("namespace {\nconstexpr class A {\n} a, b;\n} // namespace"); |
| verifyFormat("namespace {\nconstexpr struct A {\n} a, b;\n} // namespace"); |
| verifyFormat("namespace {\nconstexpr union A {\n} a, b;\n} // namespace"); |
| |
| verifyFormat("namespace ns {\n" |
| "class {\n" |
| "} a, b;\n" |
| "} // namespace ns"); |
| verifyFormat("namespace ns {\n" |
| "const class {\n" |
| "} a, b;\n" |
| "} // namespace ns"); |
| verifyFormat("namespace ns {\n" |
| "constexpr class C {\n" |
| "} a, b;\n" |
| "} // namespace ns"); |
| verifyFormat("namespace ns {\n" |
| "class { /* comment */\n" |
| "} a, b;\n" |
| "} // namespace ns"); |
| verifyFormat("namespace ns {\n" |
| "const class { /* comment */\n" |
| "} a, b;\n" |
| "} // namespace ns"); |
| } |
| |
| 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 [[nodiscard]] 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); |
| |
| verifyFormat("enum [[nodiscard]] E {\n" |
| " ONE,\n" |
| " TWO,\n" |
| "};"); |
| verifyFormat("enum [[nodiscard]] E {\n" |
| " // Comment 1\n" |
| " ONE,\n" |
| " // Comment 2\n" |
| " TWO,\n" |
| "};"); |
| |
| // 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 [[nodiscard]] E {} d;"); |
| verifyFormat("enum struct X f() {\n a();\n return 42;\n}"); |
| |
| verifyFormat("enum struct [[nodiscard]] E {\n" |
| " ONE,\n" |
| " TWO,\n" |
| "};"); |
| verifyFormat("enum struct [[nodiscard]] E {\n" |
| " // Comment 1\n" |
| " ONE,\n" |
| " // Comment 2\n" |
| " TWO,\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 [[nodiscard]] E {} d;"); |
| verifyFormat("enum class X f() {\n a();\n return 42;\n}"); |
| |
| verifyFormat("enum class [[nodiscard]] E {\n" |
| " ONE,\n" |
| " TWO,\n" |
| "};"); |
| verifyFormat("enum class [[nodiscard]] E {\n" |
| " // Comment 1\n" |
| " ONE,\n" |
| " // Comment 2\n" |
| " TWO,\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 = getLLVMStyleWithColumns(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("#define M(x) x##x\n" |
| "namespace M(x) {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("#define M(x) x##x\n" |
| "namespace N::inline M(x) {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("#define M(x) x##x\n" |
| "namespace M(x)::inline N {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("#define M(x) x##x\n" |
| "namespace N::M(x) {\n" |
| "class A {};\n" |
| "void f() { f(); }\n" |
| "}", |
| LLVMWithNoNamespaceFix); |
| verifyFormat("#define M(x) x##x\n" |
| "namespace M::N(x) {\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" |
| "class A {};\n" |
| "void f() { f(); }", |
| LLVMWithNoNamespaceFix); |
| |
| // This code is more common than we thought; if we |
| // layout this correctly the semicolon will go into |
| // its own line, which is undesirable. |
| verifyFormat("namespace {};", LLVMWithNoNamespaceFix); |
| verifyFormat("namespace {\n" |
| "class A {};\n" |
| "};", |
| LLVMWithNoNamespaceFix); |
| |
| verifyFormat("namespace {\n" |
| "int SomeVariable = 0; // comment\n" |
| "} // namespace", |
| LLVMWithNoNamespaceFix); |
| EXPECT_EQ("#ifndef HEADER_GUARD\n" |
| "#define HEADER_GUARD\n" |
| "namespace my_namespace {\n" |
| "int i;\n" |
| "} // my_namespace\n" |
| "#endif // HEADER_GUARD", |
| format("#ifndef HEADER_GUARD\n" |
| " #define HEADER_GUARD\n" |
| " namespace my_namespace {\n" |
| "int i;\n" |
| "} // my_namespace\n" |
| "#endif // HEADER_GUARD", |
| LLVMWithNoNamespaceFix)); |
| |
| EXPECT_EQ("namespace A::B {\n" |
| "class C {};\n" |
| "}", |
| format("namespace A::B {\n" |
| "class C {};\n" |
| "}", |
| LLVMWithNoNamespaceFix)); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.NamespaceIndentation = FormatStyle::NI_All; |
| EXPECT_EQ("namespace out {\n" |
| " int i;\n" |
| " namespace in {\n" |
| " int i;\n" |
| " } // namespace in\n" |
| "} // namespace out", |
| format("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| |
| FormatStyle ShortInlineFunctions = getLLVMStyle(); |
| ShortInlineFunctions.NamespaceIndentation = FormatStyle::NI_All; |
| ShortInlineFunctions.AllowShortFunctionsOnASingleLine = |
| FormatStyle::SFS_Inline; |
| verifyFormat("namespace {\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace { /* comment */\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace { // comment\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " int some_int;\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace interface {\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace interface\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " class X {\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " class X { /* comment */\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " class X { // comment\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " struct X {\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " union X {\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("extern \"C\" {\n" |
| "void f() {\n" |
| " return;\n" |
| "}\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " class X {\n" |
| " void f() { return; }\n" |
| " } x;\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " [[nodiscard]] class X {\n" |
| " void f() { return; }\n" |
| " };\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " static class X {\n" |
| " void f() { return; }\n" |
| " } x;\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| verifyFormat("namespace {\n" |
| " constexpr class X {\n" |
| " void f() { return; }\n" |
| " } x;\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| |
| ShortInlineFunctions.IndentExternBlock = FormatStyle::IEBS_Indent; |
| verifyFormat("extern \"C\" {\n" |
| " void f() {\n" |
| " return;\n" |
| " }\n" |
| "} // namespace\n", |
| ShortInlineFunctions); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_Inner; |
| EXPECT_EQ("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| " int i;\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| format("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_None; |
| verifyFormat("template <class T>\n" |
| "concept a_concept = X<>;\n" |
| "namespace B {\n" |
| "struct b_struct {};\n" |
| "} // namespace B\n", |
| Style); |
| verifyFormat("template <int I>\n" |
| "constexpr void foo()\n" |
| " requires(I == 42)\n" |
| "{}\n" |
| "namespace ns {\n" |
| "void foo() {}\n" |
| "} // namespace ns\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, NamespaceMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.NamespaceMacros.push_back("TESTSUITE"); |
| |
| verifyFormat("TESTSUITE(A) {\n" |
| "int foo();\n" |
| "} // TESTSUITE(A)", |
| Style); |
| |
| verifyFormat("TESTSUITE(A, B) {\n" |
| "int foo();\n" |
| "} // TESTSUITE(A)", |
| Style); |
| |
| // Properly indent according to NamespaceIndentation style |
| Style.NamespaceIndentation = FormatStyle::NI_All; |
| verifyFormat("TESTSUITE(A) {\n" |
| " int foo();\n" |
| "} // TESTSUITE(A)", |
| Style); |
| verifyFormat("TESTSUITE(A) {\n" |
| " namespace B {\n" |
| " int foo();\n" |
| " } // namespace B\n" |
| "} // TESTSUITE(A)", |
| Style); |
| verifyFormat("namespace A {\n" |
| " TESTSUITE(B) {\n" |
| " int foo();\n" |
| " } // TESTSUITE(B)\n" |
| "} // namespace A", |
| Style); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_Inner; |
| verifyFormat("TESTSUITE(A) {\n" |
| "TESTSUITE(B) {\n" |
| " int foo();\n" |
| "} // TESTSUITE(B)\n" |
| "} // TESTSUITE(A)", |
| Style); |
| verifyFormat("TESTSUITE(A) {\n" |
| "namespace B {\n" |
| " int foo();\n" |
| "} // namespace B\n" |
| "} // TESTSUITE(A)", |
| Style); |
| verifyFormat("namespace A {\n" |
| "TESTSUITE(B) {\n" |
| " int foo();\n" |
| "} // TESTSUITE(B)\n" |
| "} // namespace A", |
| Style); |
| |
| // Properly merge namespace-macros blocks in CompactNamespaces mode |
| Style.NamespaceIndentation = FormatStyle::NI_None; |
| Style.CompactNamespaces = true; |
| verifyFormat("TESTSUITE(A) { TESTSUITE(B) {\n" |
| "}} // TESTSUITE(A::B)", |
| Style); |
| |
| EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n" |
| "}} // TESTSUITE(out::in)", |
| format("TESTSUITE(out) {\n" |
| "TESTSUITE(in) {\n" |
| "} // TESTSUITE(in)\n" |
| "} // TESTSUITE(out)", |
| Style)); |
| |
| EXPECT_EQ("TESTSUITE(out) { TESTSUITE(in) {\n" |
| "}} // TESTSUITE(out::in)", |
| format("TESTSUITE(out) {\n" |
| "TESTSUITE(in) {\n" |
| "} // TESTSUITE(in)\n" |
| "} // TESTSUITE(out)", |
| Style)); |
| |
| // Do not merge different namespaces/macros |
| EXPECT_EQ("namespace out {\n" |
| "TESTSUITE(in) {\n" |
| "} // TESTSUITE(in)\n" |
| "} // namespace out", |
| format("namespace out {\n" |
| "TESTSUITE(in) {\n" |
| "} // TESTSUITE(in)\n" |
| "} // namespace out", |
| Style)); |
| EXPECT_EQ("TESTSUITE(out) {\n" |
| "namespace in {\n" |
| "} // namespace in\n" |
| "} // TESTSUITE(out)", |
| format("TESTSUITE(out) {\n" |
| "namespace in {\n" |
| "} // namespace in\n" |
| "} // TESTSUITE(out)", |
| Style)); |
| Style.NamespaceMacros.push_back("FOOBAR"); |
| EXPECT_EQ("TESTSUITE(out) {\n" |
| "FOOBAR(in) {\n" |
| "} // FOOBAR(in)\n" |
| "} // TESTSUITE(out)", |
| format("TESTSUITE(out) {\n" |
| "FOOBAR(in) {\n" |
| "} // FOOBAR(in)\n" |
| "} // TESTSUITE(out)", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsCompactNamespaces) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.CompactNamespaces = true; |
| Style.NamespaceMacros.push_back("TESTSUITE"); |
| |
| verifyFormat("namespace A { namespace B {\n" |
| "}} // namespace A::B", |
| Style); |
| |
| EXPECT_EQ("namespace out { namespace in {\n" |
| "}} // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| |
| // Only namespaces which have both consecutive opening and end get compacted |
| EXPECT_EQ("namespace out {\n" |
| "namespace in1 {\n" |
| "} // namespace in1\n" |
| "namespace in2 {\n" |
| "} // namespace in2\n" |
| "} // namespace out", |
| format("namespace out {\n" |
| "namespace in1 {\n" |
| "} // namespace in1\n" |
| "namespace in2 {\n" |
| "} // namespace in2\n" |
| "} // namespace out", |
| Style)); |
| |
| EXPECT_EQ("namespace out {\n" |
| "int i;\n" |
| "namespace in {\n" |
| "int j;\n" |
| "} // namespace in\n" |
| "int k;\n" |
| "} // namespace out", |
| format("namespace out { int i;\n" |
| "namespace in { int j; } // namespace in\n" |
| "int k; } // namespace out", |
| Style)); |
| |
| EXPECT_EQ("namespace A { namespace B { namespace C {\n" |
| "}}} // namespace A::B::C\n", |
| format("namespace A { namespace B {\n" |
| "namespace C {\n" |
| "}} // namespace B::C\n" |
| "} // namespace A\n", |
| Style)); |
| |
| Style.ColumnLimit = 40; |
| EXPECT_EQ("namespace aaaaaaaaaa {\n" |
| "namespace bbbbbbbbbb {\n" |
| "}} // namespace aaaaaaaaaa::bbbbbbbbbb", |
| format("namespace aaaaaaaaaa {\n" |
| "namespace bbbbbbbbbb {\n" |
| "} // namespace bbbbbbbbbb\n" |
| "} // namespace aaaaaaaaaa", |
| Style)); |
| |
| EXPECT_EQ("namespace aaaaaa { namespace bbbbbb {\n" |
| "namespace cccccc {\n" |
| "}}} // namespace aaaaaa::bbbbbb::cccccc", |
| format("namespace aaaaaa {\n" |
| "namespace bbbbbb {\n" |
| "namespace cccccc {\n" |
| "} // namespace cccccc\n" |
| "} // namespace bbbbbb\n" |
| "} // namespace aaaaaa", |
| Style)); |
| Style.ColumnLimit = 80; |
| |
| // Extra semicolon after 'inner' closing brace prevents merging |
| EXPECT_EQ("namespace out { namespace in {\n" |
| "}; } // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "}; // namespace in\n" |
| "} // namespace out", |
| Style)); |
| |
| // Extra semicolon after 'outer' closing brace is conserved |
| EXPECT_EQ("namespace out { namespace in {\n" |
| "}}; // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "} // namespace in\n" |
| "}; // namespace out", |
| Style)); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_All; |
| EXPECT_EQ("namespace out { namespace in {\n" |
| " int i;\n" |
| "}} // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| EXPECT_EQ("namespace out { namespace mid {\n" |
| " namespace in {\n" |
| " int j;\n" |
| " } // namespace in\n" |
| " int k;\n" |
| "}} // namespace out::mid", |
| format("namespace out { namespace mid {\n" |
| "namespace in { int j; } // namespace in\n" |
| "int k; }} // namespace out::mid", |
| Style)); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_Inner; |
| EXPECT_EQ("namespace out { namespace in {\n" |
| " int i;\n" |
| "}} // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| EXPECT_EQ("namespace out { namespace mid { namespace in {\n" |
| " int i;\n" |
| "}}} // namespace out::mid::in", |
| format("namespace out {\n" |
| "namespace mid {\n" |
| "namespace in {\n" |
| "int i;\n" |
| "} // namespace in\n" |
| "} // namespace mid\n" |
| "} // namespace out", |
| Style)); |
| |
| Style.CompactNamespaces = true; |
| Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.BeforeLambdaBody = true; |
| verifyFormat("namespace out { namespace in {\n" |
| "}} // namespace out::in", |
| Style); |
| EXPECT_EQ("namespace out { namespace in {\n" |
| "}} // namespace out::in", |
| format("namespace out {\n" |
| "namespace in {\n" |
| "} // namespace in\n" |
| "} // namespace out", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsExternC) { |
| verifyFormat("extern \"C\" {\nint a;"); |
| verifyFormat("extern \"C\" {}"); |
| verifyFormat("extern \"C\" {\n" |
| "int foo();\n" |
| "}"); |
| verifyFormat("extern \"C\" int foo() {}"); |
| verifyFormat("extern \"C\" int foo();"); |
| verifyFormat("extern \"C\" int foo() {\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}"); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| verifyFormat("extern \"C\" int foo() {}", Style); |
| verifyFormat("extern \"C\" int foo();", Style); |
| verifyFormat("extern \"C\" int foo()\n" |
| "{\n" |
| " int i = 42;\n" |
| " return i;\n" |
| "}", |
| Style); |
| |
| Style.BraceWrapping.AfterExternBlock = true; |
| Style.BraceWrapping.SplitEmptyRecord = false; |
| verifyFormat("extern \"C\"\n" |
| "{}", |
| Style); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| " int foo();\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, IndentExternBlockStyle) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.IndentWidth = 2; |
| |
| Style.IndentExternBlock = FormatStyle::IEBS_Indent; |
| verifyFormat("extern \"C\" { /*9*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\" {\n" |
| " int foo10();\n" |
| "}", |
| Style); |
| |
| Style.IndentExternBlock = FormatStyle::IEBS_NoIndent; |
| verifyFormat("extern \"C\" { /*11*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\" {\n" |
| "int foo12();\n" |
| "}", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterExternBlock = true; |
| Style.IndentExternBlock = FormatStyle::IEBS_Indent; |
| verifyFormat("extern \"C\"\n" |
| "{ /*13*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\"\n{\n" |
| " int foo14();\n" |
| "}", |
| Style); |
| |
| Style.BraceWrapping.AfterExternBlock = false; |
| Style.IndentExternBlock = FormatStyle::IEBS_NoIndent; |
| verifyFormat("extern \"C\" { /*15*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\" {\n" |
| "int foo16();\n" |
| "}", |
| Style); |
| |
| Style.BraceWrapping.AfterExternBlock = true; |
| verifyFormat("extern \"C\"\n" |
| "{ /*13*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| "int foo14();\n" |
| "}", |
| Style); |
| |
| Style.IndentExternBlock = FormatStyle::IEBS_Indent; |
| verifyFormat("extern \"C\"\n" |
| "{ /*13*/\n" |
| "}", |
| Style); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| " int foo14();\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsInlineASM) { |
| verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));"); |
| verifyFormat("asm(\"nop\" ::: \"memory\");"); |
| verifyFormat( |
| "asm(\"movq\\t%%rbx, %%rsi\\n\\t\"\n" |
| " \"cpuid\\n\\t\"\n" |
| " \"xchgq\\t%%rbx, %%rsi\\n\\t\"\n" |
| " : \"=a\"(*rEAX), \"=S\"(*rEBX), \"=c\"(*rECX), \"=d\"(*rEDX)\n" |
| " : \"a\"(value));"); |
| EXPECT_EQ( |
| "void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" |
| " __asm {\n" |
| " mov edx,[that] // vtable in edx\n" |
| " mov eax,methodIndex\n" |
| " call [edx][eax*4] // stdcall\n" |
| " }\n" |
| "}", |
| format("void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" |
| " __asm {\n" |
| " mov edx,[that] // vtable in edx\n" |
| " mov eax,methodIndex\n" |
| " call [edx][eax*4] // stdcall\n" |
| " }\n" |
| "}")); |
| EXPECT_EQ("_asm {\n" |
| " xor eax, eax;\n" |
| " cpuid;\n" |
| "}", |
| format("_asm {\n" |
| " xor eax, eax;\n" |
| " cpuid;\n" |
| "}")); |
| verifyFormat("void function() {\n" |
| " // comment\n" |
| " asm(\"\");\n" |
| "}"); |
| EXPECT_EQ("__asm {\n" |
| "}\n" |
| "int i;", |
| format("__asm {\n" |
| "}\n" |
| "int i;")); |
| } |
| |
| TEST_F(FormatTest, FormatTryCatch) { |
| verifyFormat("try {\n" |
| " throw a * b;\n" |
| "} catch (int a) {\n" |
| " // Do nothing.\n" |
| "} catch (...) {\n" |
| " exit(42);\n" |
| "}"); |
| |
| // Function-level try statements. |
| verifyFormat("int f() try { return 4; } catch (...) {\n" |
| " return 5;\n" |
| "}"); |
| verifyFormat("class A {\n" |
| " int a;\n" |
| " A() try : a(0) {\n" |
| " } catch (...) {\n" |
| " throw;\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("class A {\n" |
| " int a;\n" |
| " A() try : a(0), b{1} {\n" |
| " } catch (...) {\n" |
| " throw;\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("class A {\n" |
| " int a;\n" |
| " A() try : a(0), b{1}, c{2} {\n" |
| " } catch (...) {\n" |
| " throw;\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("class A {\n" |
| " int a;\n" |
| " A() try : a(0), b{1}, c{2} {\n" |
| " { // New scope.\n" |
| " }\n" |
| " } catch (...) {\n" |
| " throw;\n" |
| " }\n" |
| "};\n"); |
| |
| // Incomplete try-catch blocks. |
| verifyIncompleteFormat("try {} catch ("); |
| } |
| |
| TEST_F(FormatTest, FormatTryAsAVariable) { |
| verifyFormat("int try;"); |
| verifyFormat("int try, size;"); |
| verifyFormat("try = foo();"); |
| verifyFormat("if (try < size) {\n return true;\n}"); |
| |
| verifyFormat("int catch;"); |
| verifyFormat("int catch, size;"); |
| verifyFormat("catch = foo();"); |
| verifyFormat("if (catch < size) {\n return true;\n}"); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| Style.BraceWrapping.BeforeCatch = true; |
| verifyFormat("try {\n" |
| " int bar = 1;\n" |
| "}\n" |
| "catch (...) {\n" |
| " int bar = 1;\n" |
| "}", |
| Style); |
| verifyFormat("#if NO_EX\n" |
| "try\n" |
| "#endif\n" |
| "{\n" |
| "}\n" |
| "#if NO_EX\n" |
| "catch (...) {\n" |
| "}", |
| Style); |
| verifyFormat("try /* abc */ {\n" |
| " int bar = 1;\n" |
| "}\n" |
| "catch (...) {\n" |
| " int bar = 1;\n" |
| "}", |
| Style); |
| verifyFormat("try\n" |
| "// abc\n" |
| "{\n" |
| " int bar = 1;\n" |
| "}\n" |
| "catch (...) {\n" |
| " int bar = 1;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatSEHTryCatch) { |
| verifyFormat("__try {\n" |
| " int a = b * c;\n" |
| "} __except (EXCEPTION_EXECUTE_HANDLER) {\n" |
| " // Do nothing.\n" |
| "}"); |
| |
| verifyFormat("__try {\n" |
| " int a = b * c;\n" |
| "} __finally {\n" |
| " // Do nothing.\n" |
| "}"); |
| |
| verifyFormat("DEBUG({\n" |
| " __try {\n" |
| " } __finally {\n" |
| " }\n" |
| "});\n"); |
| } |
| |
| TEST_F(FormatTest, IncompleteTryCatchBlocks) { |
| verifyFormat("try {\n" |
| " f();\n" |
| "} catch {\n" |
| " g();\n" |
| "}"); |
| verifyFormat("try {\n" |
| " f();\n" |
| "} catch (A a) MACRO(x) {\n" |
| " g();\n" |
| "} catch (B b) MACRO(x) {\n" |
| " g();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, FormatTryCatchBraceStyles) { |
| FormatStyle Style = getLLVMStyle(); |
| for (auto BraceStyle : {FormatStyle::BS_Attach, FormatStyle::BS_Mozilla, |
| FormatStyle::BS_WebKit}) { |
| Style.BreakBeforeBraces = BraceStyle; |
| verifyFormat("try {\n" |
| " // something\n" |
| "} catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| } |
| Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; |
| verifyFormat("try {\n" |
| " // something\n" |
| "}\n" |
| "catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| verifyFormat("__try {\n" |
| " // something\n" |
| "}\n" |
| "__finally {\n" |
| " // something\n" |
| "}", |
| Style); |
| verifyFormat("@try {\n" |
| " // something\n" |
| "}\n" |
| "@finally {\n" |
| " // something\n" |
| "}", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Allman; |
| verifyFormat("try\n" |
| "{\n" |
| " // something\n" |
| "}\n" |
| "catch (...)\n" |
| "{\n" |
| " // something\n" |
| "}", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths; |
| verifyFormat("try\n" |
| " {\n" |
| " // something white\n" |
| " }\n" |
| "catch (...)\n" |
| " {\n" |
| " // something white\n" |
| " }", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_GNU; |
| verifyFormat("try\n" |
| " {\n" |
| " // something\n" |
| " }\n" |
| "catch (...)\n" |
| " {\n" |
| " // something\n" |
| " }", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.BeforeCatch = true; |
| verifyFormat("try {\n" |
| " // something\n" |
| "}\n" |
| "catch (...) {\n" |
| " // something\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, StaticInitializers) { |
| verifyFormat("static SomeClass SC = {1, 'a'};"); |
| |
| verifyFormat("static SomeClass WithALoooooooooooooooooooongName = {\n" |
| " 100000000, " |
| "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"};"); |
| |
| // Here, everything other than the "}" would fit on a line. |
| verifyFormat("static int LooooooooooooooooooooooooongVariable[1] = {\n" |
| " 10000000000000000000000000};"); |
| EXPECT_EQ("S s = {a,\n" |
| "\n" |
| " b};", |
| format("S s = {\n" |
| " a,\n" |
| "\n" |
| " b\n" |
| "};")); |
| |
| // FIXME: This would fit into the column limit if we'd fit "{ {" on the first |
| // line. However, the formatting looks a bit off and this probably doesn't |
| // happen often in practice. |
| verifyFormat("static int Variable[1] = {\n" |
| " {1000000000000000000000000000000000000}};", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, DesignatedInitializers) { |
| verifyFormat("const struct A a = {.a = 1, .b = 2};"); |
| verifyFormat("const struct A a = {.aaaaaaaaaa = 1,\n" |
| " .bbbbbbbbbb = 2,\n" |
| " .cccccccccc = 3,\n" |
| " .dddddddddd = 4,\n" |
| " .eeeeeeeeee = 5};"); |
| verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaa = 1,\n" |
| " .bbbbbbbbbbbbbbbbbbbbbbbbbbb = 2,\n" |
| " .ccccccccccccccccccccccccccc = 3,\n" |
| " .ddddddddddddddddddddddddddd = 4,\n" |
| " .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};"); |
| |
| verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};"); |
| |
| verifyFormat("const struct A a = {[0] = 1, [1] = 2};"); |
| verifyFormat("const struct A a = {[1] = aaaaaaaaaa,\n" |
| " [2] = bbbbbbbbbb,\n" |
| " [3] = cccccccccc,\n" |
| " [4] = dddddddddd,\n" |
| " [5] = eeeeeeeeee};"); |
| verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n" |
| " [1] = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " [2] = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" |
| " [3] = cccccccccccccccccccccccccccccccccccccc,\n" |
| " [4] = dddddddddddddddddddddddddddddddddddddd,\n" |
| " [5] = eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee};"); |
| } |
| |
| TEST_F(FormatTest, NestedStaticInitializers) { |
| verifyFormat("static A x = {{{}}};\n"); |
| verifyFormat("static A x = {{{init1, init2, init3, init4},\n" |
| " {init1, init2, init3, init4}}};", |
| getLLVMStyleWithColumns(50)); |
| |
| verifyFormat("somes Status::global_reps[3] = {\n" |
| " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};", |
| getLLVMStyleWithColumns(60)); |
| verifyGoogleFormat("SomeType Status::global_reps[3] = {\n" |
| " {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n" |
| " {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};"); |
| verifyFormat("CGRect cg_rect = {{rect.fLeft, rect.fTop},\n" |
| " {rect.fRight - rect.fLeft, rect.fBottom - " |
| "rect.fTop}};"); |
| |
| verifyFormat( |
| "SomeArrayOfSomeType a = {\n" |
| " {{1, 2, 3},\n" |
| " {1, 2, 3},\n" |
| " {111111111111111111111111111111, 222222222222222222222222222222,\n" |
| " 333333333333333333333333333333},\n" |
| " {1, 2, 3},\n" |
| " {1, 2, 3}}};"); |
| verifyFormat( |
| "SomeArrayOfSomeType a = {\n" |
| " {{1, 2, 3}},\n" |
| " {{1, 2, 3}},\n" |
| " {{111111111111111111111111111111, 222222222222222222222222222222,\n" |
| " 333333333333333333333333333333}},\n" |
| " {{1, 2, 3}},\n" |
| " {{1, 2, 3}}};"); |
| |
| verifyFormat("struct {\n" |
| " unsigned bit;\n" |
| " const char *const name;\n" |
| "} kBitsToOs[] = {{kOsMac, \"Mac\"},\n" |
| " {kOsWin, \"Windows\"},\n" |
| " {kOsLinux, \"Linux\"},\n" |
| " {kOsCrOS, \"Chrome OS\"}};"); |
| verifyFormat("struct {\n" |
| " unsigned bit;\n" |
| " const char *const name;\n" |
| "} kBitsToOs[] = {\n" |
| " {kOsMac, \"Mac\"},\n" |
| " {kOsWin, \"Windows\"},\n" |
| " {kOsLinux, \"Linux\"},\n" |
| " {kOsCrOS, \"Chrome OS\"},\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) { |
| verifyFormat("#define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| " \\\n" |
| " aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)"); |
| } |
| |
| TEST_F(FormatTest, DoesNotBreakPureVirtualFunctionDefinition) { |
| verifyFormat("virtual void write(ELFWriter *writerrr,\n" |
| " OwningPtr<FileOutputBuffer> &buffer) = 0;"); |
| |
| // Do break defaulted and deleted functions. |
| verifyFormat("virtual void ~Deeeeeeeestructor() =\n" |
| " default;", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("virtual void ~Deeeeeeeestructor() =\n" |
| " delete;", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralsOnlyInDefine) { |
| verifyFormat("# 1111 \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\" 2 3", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("#line 11111 \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\"", |
| getLLVMStyleWithColumns(40)); |
| EXPECT_EQ("#define Q \\\n" |
| " \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/\" \\\n" |
| " \"aaaaaaaa.cpp\"", |
| format("#define Q \"/aaaaaaaaa/aaaaaaaaaaaaaaaaaaa/aaaaaaaa.cpp\"", |
| getLLVMStyleWithColumns(40))); |
| } |
| |
| TEST_F(FormatTest, UnderstandsLinePPDirective) { |
| EXPECT_EQ("# 123 \"A string literal\"", |
| format(" # 123 \"A string literal\"")); |
| } |
| |
| TEST_F(FormatTest, LayoutUnknownPPDirective) { |
| EXPECT_EQ("#;", format("#;")); |
| verifyFormat("#\n;\n;\n;"); |
| } |
| |
| TEST_F(FormatTest, UnescapedEndOfLineEndsPPDirective) { |
| EXPECT_EQ("#line 42 \"test\"\n", |
| format("# \\\n line \\\n 42 \\\n \"test\"\n")); |
| EXPECT_EQ("#define A B\n", format("# \\\n define \\\n A \\\n B\n", |
| getLLVMStyleWithColumns(12))); |
| } |
| |
| TEST_F(FormatTest, EndOfFileEndsPPDirective) { |
| EXPECT_EQ("#line 42 \"test\"", |
| format("# \\\n line \\\n 42 \\\n \"test\"")); |
| EXPECT_EQ("#define A B", format("# \\\n define \\\n A \\\n B")); |
| } |
| |
| TEST_F(FormatTest, DoesntRemoveUnknownTokens) { |
| verifyFormat("#define A \\x20"); |
| verifyFormat("#define A \\ x20"); |
| EXPECT_EQ("#define A \\ x20", format("#define A \\ x20")); |
| verifyFormat("#define A ''"); |
| verifyFormat("#define A ''qqq"); |
| verifyFormat("#define A `qqq"); |
| verifyFormat("f(\"aaaa, bbbb, \"\\\"ccccc\\\"\");"); |
| EXPECT_EQ("const char *c = STRINGIFY(\n" |
| "\\na : b);", |
| format("const char * c = STRINGIFY(\n" |
| "\\na : b);")); |
| |
| verifyFormat("a\r\\"); |
| verifyFormat("a\v\\"); |
| verifyFormat("a\f\\"); |
| } |
| |
| TEST_F(FormatTest, IndentsPPDirectiveWithPPIndentWidth) { |
| FormatStyle style = getChromiumStyle(FormatStyle::LK_Cpp); |
| style.IndentWidth = 4; |
| style.PPIndentWidth = 1; |
| |
| style.IndentPPDirectives = FormatStyle::PPDIS_None; |
| verifyFormat("#ifdef __linux__\n" |
| "void foo() {\n" |
| " int x = 0;\n" |
| "}\n" |
| "#define FOO\n" |
| "#endif\n" |
| "void bar() {\n" |
| " int y = 0;\n" |
| "}\n", |
| style); |
| |
| style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash; |
| verifyFormat("#ifdef __linux__\n" |
| "void foo() {\n" |
| " int x = 0;\n" |
| "}\n" |
| "# define FOO foo\n" |
| "#endif\n" |
| "void bar() {\n" |
| " int y = 0;\n" |
| "}\n", |
| style); |
| |
| style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash; |
| verifyFormat("#ifdef __linux__\n" |
| "void foo() {\n" |
| " int x = 0;\n" |
| "}\n" |
| " #define FOO foo\n" |
| "#endif\n" |
| "void bar() {\n" |
| " int y = 0;\n" |
| "}\n", |
| style); |
| } |
| |
| TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { |
| verifyFormat("#define A(BB)", getLLVMStyleWithColumns(13)); |
| verifyFormat("#define A( \\\n BB)", getLLVMStyleWithColumns(12)); |
| verifyFormat("#define A( \\\n A, B)", getLLVMStyleWithColumns(12)); |
| // FIXME: We never break before the macro name. |
| verifyFormat("#define AA( \\\n B)", getLLVMStyleWithColumns(12)); |
| |
| verifyFormat("#define A A\n#define A A"); |
| verifyFormat("#define A(X) A\n#define A A"); |
| |
| verifyFormat("#define Something Other", getLLVMStyleWithColumns(23)); |
| verifyFormat("#define Something \\\n Other", getLLVMStyleWithColumns(22)); |
| } |
| |
| TEST_F(FormatTest, HandlePreprocessorDirectiveContext) { |
| EXPECT_EQ("// somecomment\n" |
| "#include \"a.h\"\n" |
| "#define A( \\\n" |
| " A, B)\n" |
| "#include \"b.h\"\n" |
| "// somecomment\n", |
| format(" // somecomment\n" |
| " #include \"a.h\"\n" |
| "#define A(A,\\\n" |
| " B)\n" |
| " #include \"b.h\"\n" |
| " // somecomment\n", |
| getLLVMStyleWithColumns(13))); |
| } |
| |
| TEST_F(FormatTest, LayoutSingleHash) { EXPECT_EQ("#\na;", format("#\na;")); } |
| |
| TEST_F(FormatTest, LayoutCodeInMacroDefinitions) { |
| EXPECT_EQ("#define A \\\n" |
| " c; \\\n" |
| " e;\n" |
| "f;", |
| format("#define A c; e;\n" |
| "f;", |
| getLLVMStyleWithColumns(14))); |
| } |
| |
| TEST_F(FormatTest, LayoutRemainingTokens) { EXPECT_EQ("{}", format("{}")); } |
| |
| TEST_F(FormatTest, MacroDefinitionInsideStatement) { |
| EXPECT_EQ("int x,\n" |
| "#define A\n" |
| " y;", |
| format("int x,\n#define A\ny;")); |
| } |
| |
| TEST_F(FormatTest, HashInMacroDefinition) { |
| EXPECT_EQ("#define A(c) L#c", format("#define A(c) L#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) u#c", format("#define A(c) u#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) U#c", format("#define A(c) U#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) u8#c", format("#define A(c) u8#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) LR#c", format("#define A(c) LR#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) uR#c", format("#define A(c) uR#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) UR#c", format("#define A(c) UR#c", getLLVMStyle())); |
| EXPECT_EQ("#define A(c) u8R#c", format("#define A(c) u8R#c", getLLVMStyle())); |
| verifyFormat("#define A \\\n b #c;", getLLVMStyleWithColumns(11)); |
| verifyFormat("#define A \\\n" |
| " { \\\n" |
| " f(#c); \\\n" |
| " }", |
| getLLVMStyleWithColumns(11)); |
| |
| verifyFormat("#define A(X) \\\n" |
| " void function##X()", |
| getLLVMStyleWithColumns(22)); |
| |
| verifyFormat("#define A(a, b, c) \\\n" |
| " void a##b##c()", |
| getLLVMStyleWithColumns(22)); |
| |
| verifyFormat("#define A void # ## #", getLLVMStyleWithColumns(22)); |
| } |
| |
| TEST_F(FormatTest, RespectWhitespaceInMacroDefinitions) { |
| EXPECT_EQ("#define A (x)", format("#define A (x)")); |
| EXPECT_EQ("#define A(x)", format("#define A(x)")); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.SpaceBeforeParens = FormatStyle::SBPO_Never; |
| verifyFormat("#define true ((foo)1)", Style); |
| Style.SpaceBeforeParens = FormatStyle::SBPO_Always; |
| verifyFormat("#define false((foo)0)", Style); |
| } |
| |
| TEST_F(FormatTest, EmptyLinesInMacroDefinitions) { |
| EXPECT_EQ("#define A b;", format("#define A \\\n" |
| " \\\n" |
| " b;", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("#define A \\\n" |
| " \\\n" |
| " a; \\\n" |
| " b;", |
| format("#define A \\\n" |
| " \\\n" |
| " a; \\\n" |
| " b;", |
| getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("#define A \\\n" |
| " a; \\\n" |
| " \\\n" |
| " b;", |
| format("#define A \\\n" |
| " a; \\\n" |
| " \\\n" |
| " b;", |
| getLLVMStyleWithColumns(11))); |
| } |
| |
| TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) { |
| verifyIncompleteFormat("#define A :"); |
| verifyFormat("#define SOMECASES \\\n" |
| " case 1: \\\n" |
| " case 2\n", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("#define MACRO(a) \\\n" |
| " if (a) \\\n" |
| " f(); \\\n" |
| " else \\\n" |
| " g()", |
| getLLVMStyleWithColumns(18)); |
| verifyFormat("#define A template <typename T>"); |
| verifyIncompleteFormat("#define STR(x) #x\n" |
| "f(STR(this_is_a_string_literal{));"); |
| verifyFormat("#pragma omp threadprivate( \\\n" |
| " y)), // expected-warning", |
| getLLVMStyleWithColumns(28)); |
| verifyFormat("#d, = };"); |
| verifyFormat("#if \"a"); |
| verifyIncompleteFormat("({\n" |
| "#define b \\\n" |
| " } \\\n" |
| " a\n" |
| "a", |
| getLLVMStyleWithColumns(15)); |
| verifyFormat("#define A \\\n" |
| " { \\\n" |
| " {\n" |
| "#define B \\\n" |
| " } \\\n" |
| " }", |
| getLLVMStyleWithColumns(15)); |
| verifyNoCrash("#if a\na(\n#else\n#endif\n{a"); |
| verifyNoCrash("a={0,1\n#if a\n#else\n;\n#endif\n}"); |
| verifyNoCrash("#if a\na(\n#else\n#endif\n) a {a,b,c,d,f,g};"); |
| verifyNoCrash("#ifdef A\n a(\n #else\n #endif\n) = []() { \n)}"); |
| } |
| |
| TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { |
| verifyFormat("SOME_TYPE_NAME abc;"); // Gated on the newline. |
| EXPECT_EQ("class A : public QObject {\n" |
| " Q_OBJECT\n" |
| "\n" |
| " A() {}\n" |
| "};", |
| format("class A : public QObject {\n" |
| " Q_OBJECT\n" |
| "\n" |
| " A() {\n}\n" |
| "} ;")); |
| EXPECT_EQ("MACRO\n" |
| "/*static*/ int i;", |
| format("MACRO\n" |
| " /*static*/ int i;")); |
| EXPECT_EQ("SOME_MACRO\n" |
| "namespace {\n" |
| "void f();\n" |
| "} // namespace", |
| format("SOME_MACRO\n" |
| " namespace {\n" |
| "void f( );\n" |
| "} // namespace")); |
| // Only if the identifier contains at least 5 characters. |
| EXPECT_EQ("HTTP f();", format("HTTP\nf();")); |
| EXPECT_EQ("MACRO\nf();", format("MACRO\nf();")); |
| // Only if everything is upper case. |
| EXPECT_EQ("class A : public QObject {\n" |
| " Q_Object A() {}\n" |
| "};", |
| format("class A : public QObject {\n" |
| " Q_Object\n" |
| " A() {\n}\n" |
| "} ;")); |
| |
| // Only if the next line can actually start an unwrapped line. |
| EXPECT_EQ("SOME_WEIRD_LOG_MACRO << SomeThing;", |
| format("SOME_WEIRD_LOG_MACRO\n" |
| "<< SomeThing;")); |
| |
| verifyFormat("VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), " |
| "(n, buffers))\n", |
| getChromiumStyle(FormatStyle::LK_Cpp)); |
| |
| // See PR41483 |
| EXPECT_EQ("/**/ FOO(a)\n" |
| "FOO(b)", |
| format("/**/ FOO(a)\n" |
| "FOO(b)")); |
| } |
| |
| TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) { |
| EXPECT_EQ("INITIALIZE_PASS_BEGIN(ScopDetection, \"polly-detect\")\n" |
| "INITIALIZE_AG_DEPENDENCY(AliasAnalysis)\n" |
| "INITIALIZE_PASS_DEPENDENCY(DominatorTree)\n" |
| "class X {};\n" |
| "INITIALIZE_PASS_END(ScopDetection, \"polly-detect\")\n" |
| "int *createScopDetectionPass() { return 0; }", |
| format(" INITIALIZE_PASS_BEGIN(ScopDetection, \"polly-detect\")\n" |
| " INITIALIZE_AG_DEPENDENCY(AliasAnalysis)\n" |
| " INITIALIZE_PASS_DEPENDENCY(DominatorTree)\n" |
| " class X {};\n" |
| " INITIALIZE_PASS_END(ScopDetection, \"polly-detect\")\n" |
| " int *createScopDetectionPass() { return 0; }")); |
| // FIXME: We could probably treat IPC_BEGIN_MESSAGE_MAP/IPC_END_MESSAGE_MAP as |
| // braces, so that inner block is indented one level more. |
| EXPECT_EQ("int q() {\n" |
| " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" |
| " IPC_MESSAGE_HANDLER(xxx, qqq)\n" |
| " IPC_END_MESSAGE_MAP()\n" |
| "}", |
| format("int q() {\n" |
| " IPC_BEGIN_MESSAGE_MAP(WebKitTestController, message)\n" |
| " IPC_MESSAGE_HANDLER(xxx, qqq)\n" |
| " IPC_END_MESSAGE_MAP()\n" |
| "}")); |
| |
| // Same inside macros. |
| EXPECT_EQ("#define LIST(L) \\\n" |
| " L(A) \\\n" |
| " L(B) \\\n" |
| " L(C)", |
| format("#define LIST(L) \\\n" |
| " L(A) \\\n" |
| " L(B) \\\n" |
| " L(C)", |
| getGoogleStyle())); |
| |
| // These must not be recognized as macros. |
| EXPECT_EQ("int q() {\n" |
| " f(x);\n" |
| " f(x) {}\n" |
| " f(x)->g();\n" |
| " f(x)->*g();\n" |
| " f(x).g();\n" |
| " f(x) = x;\n" |
| " f(x) += x;\n" |
| " f(x) -= x;\n" |
| " f(x) *= x;\n" |
| " f(x) /= x;\n" |
| " f(x) %= x;\n" |
| " f(x) &= x;\n" |
| " f(x) |= x;\n" |
| " f(x) ^= x;\n" |
| " f(x) >>= x;\n" |
| " f(x) <<= x;\n" |
| " f(x)[y].z();\n" |
| " LOG(INFO) << x;\n" |
| " ifstream(x) >> x;\n" |
| "}\n", |
| format("int q() {\n" |
| " f(x)\n;\n" |
| " f(x)\n {}\n" |
| " f(x)\n->g();\n" |
| " f(x)\n->*g();\n" |
| " f(x)\n.g();\n" |
| " f(x)\n = x;\n" |
| " f(x)\n += x;\n" |
| " f(x)\n -= x;\n" |
| " f(x)\n *= x;\n" |
| " f(x)\n /= x;\n" |
| " f(x)\n %= x;\n" |
| " f(x)\n &= x;\n" |
| " f(x)\n |= x;\n" |
| " f(x)\n ^= x;\n" |
| " f(x)\n >>= x;\n" |
| " f(x)\n <<= x;\n" |
| " f(x)\n[y].z();\n" |
| " LOG(INFO)\n << x;\n" |
| " ifstream(x)\n >> x;\n" |
| "}\n")); |
| EXPECT_EQ("int q() {\n" |
| " F(x)\n" |
| " if (1) {\n" |
| " }\n" |
| " F(x)\n" |
| " while (1) {\n" |
| " }\n" |
| " F(x)\n" |
| " G(x);\n" |
| " F(x)\n" |
| " try {\n" |
| " Q();\n" |
| " } catch (...) {\n" |
| " }\n" |
| "}\n", |
| format("int q() {\n" |
| "F(x)\n" |
| "if (1) {}\n" |
| "F(x)\n" |
| "while (1) {}\n" |
| "F(x)\n" |
| "G(x);\n" |
| "F(x)\n" |
| "try { Q(); } catch (...) {}\n" |
| "}\n")); |
| EXPECT_EQ("class A {\n" |
| " A() : t(0) {}\n" |
| " A(int i) noexcept() : {}\n" |
| " A(X x)\n" // FIXME: function-level try blocks are broken. |
| " try : t(0) {\n" |
| " } catch (...) {\n" |
| " }\n" |
| "};", |
| format("class A {\n" |
| " A()\n : t(0) {}\n" |
| " A(int i)\n noexcept() : {}\n" |
| " A(X x)\n" |
| " try : t(0) {} catch (...) {}\n" |
| "};")); |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; |
| Style.BraceWrapping.AfterFunction = true; |
| EXPECT_EQ("void f()\n" |
| "try\n" |
| "{\n" |
| "}", |
| format("void f() try {\n" |
| "}", |
| Style)); |
| EXPECT_EQ("class SomeClass {\n" |
| "public:\n" |
| " SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| format("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};")); |
| EXPECT_EQ("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| format("class SomeClass {\n" |
| "public:\n" |
| " SomeClass()\n" |
| " EXCLUSIVE_LOCK_FUNCTION(mu_);\n" |
| "};", |
| getLLVMStyleWithColumns(40))); |
| |
| verifyFormat("MACRO(>)"); |
| |
| // Some macros contain an implicit semicolon. |
| Style = getLLVMStyle(); |
| Style.StatementMacros.push_back("FOO"); |
| verifyFormat("FOO(a) int b = 0;"); |
| verifyFormat("FOO(a)\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("FOO(a);\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("FOO(argc, argv, \"4.0.2\")\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("FOO()\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("FOO\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("void f() {\n" |
| " FOO(a)\n" |
| " return a;\n" |
| "}", |
| Style); |
| verifyFormat("FOO(a)\n" |
| "FOO(b)", |
| Style); |
| verifyFormat("int a = 0;\n" |
| "FOO(b)\n" |
| "int c = 0;", |
| Style); |
| verifyFormat("int a = 0;\n" |
| "int x = FOO(a)\n" |
| "int b = 0;", |
| Style); |
| verifyFormat("void foo(int a) { FOO(a) }\n" |
| "uint32_t bar() {}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsMacrosWithZeroColumnWidth) { |
| FormatStyle ZeroColumn = getLLVMStyleWithColumns(0); |
| |
| verifyFormat("#define A LOOOOOOOOOOOOOOOOOOONG() LOOOOOOOOOOOOOOOOOOONG()", |
| ZeroColumn); |
| } |
| |
| TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) { |
| verifyFormat("#define A \\\n" |
| " f({ \\\n" |
| " g(); \\\n" |
| " });", |
| getLLVMStyleWithColumns(11)); |
| } |
| |
| TEST_F(FormatTest, IndentPreprocessorDirectives) { |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| Style.IndentPPDirectives = FormatStyle::PPDIS_None; |
| verifyFormat("#ifdef _WIN32\n" |
| "#define A 0\n" |
| "#ifdef VAR2\n" |
| "#define B 1\n" |
| "#include <someheader.h>\n" |
| "#define MACRO \\\n" |
| " some_very_long_func_aaaaaaaaaa();\n" |
| "#endif\n" |
| "#else\n" |
| "#define A 1\n" |
| "#endif", |
| Style); |
| Style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash; |
| verifyFormat("#if 1\n" |
| "# define __STR(x) #x\n" |
| "#endif", |
| Style); |
| verifyFormat("#ifdef _WIN32\n" |
| "# define A 0\n" |
| "# ifdef VAR2\n" |
| "# define B 1\n" |
| "# include <someheader.h>\n" |
| "# define MACRO \\\n" |
| " some_very_long_func_aaaaaaaaaa();\n" |
| "# endif\n" |
| "#else\n" |
| "# define A 1\n" |
| "#endif", |
| Style); |
| verifyFormat("#if A\n" |
| "# define MACRO \\\n" |
| " void a(int x) { \\\n" |
| " b(); \\\n" |
| " c(); \\\n" |
| " d(); \\\n" |
| " e(); \\\n" |
| " f(); \\\n" |
| " }\n" |
| "#endif", |
| Style); |
| // Comments before include guard. |
| verifyFormat("// file comment\n" |
| "// file comment\n" |
| "#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| Style); |
| // Test with include guards. |
| verifyFormat("#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| Style); |
| // Include guards must have a #define with the same variable immediately |
| // after #ifndef. |
| verifyFormat("#ifndef NOT_GUARD\n" |
| "# define FOO\n" |
| "code();\n" |
| "#endif", |
| Style); |
| |
| // Include guards must cover the entire file. |
| verifyFormat("code();\n" |
| "code();\n" |
| "#ifndef NOT_GUARD\n" |
| "# define NOT_GUARD\n" |
| "code();\n" |
| "#endif", |
| Style); |
| verifyFormat("#ifndef NOT_GUARD\n" |
| "# define NOT_GUARD\n" |
| "code();\n" |
| "#endif\n" |
| "code();", |
| Style); |
| // Test with trailing blank lines. |
| verifyFormat("#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "code();\n" |
| "#endif\n", |
| Style); |
| // Include guards don't have #else. |
| verifyFormat("#ifndef NOT_GUARD\n" |
| "# define NOT_GUARD\n" |
| "code();\n" |
| "#else\n" |
| "#endif", |
| Style); |
| verifyFormat("#ifndef NOT_GUARD\n" |
| "# define NOT_GUARD\n" |
| "code();\n" |
| "#elif FOO\n" |
| "#endif", |
| Style); |
| // Non-identifier #define after potential include guard. |
| verifyFormat("#ifndef FOO\n" |
| "# define 1\n" |
| "#endif\n", |
| Style); |
| // #if closes past last non-preprocessor line. |
| verifyFormat("#ifndef FOO\n" |
| "#define FOO\n" |
| "#if 1\n" |
| "int i;\n" |
| "# define A 0\n" |
| "#endif\n" |
| "#endif\n", |
| Style); |
| // Don't crash if there is an #elif directive without a condition. |
| verifyFormat("#if 1\n" |
| "int x;\n" |
| "#elif\n" |
| "int y;\n" |
| "#else\n" |
| "int z;\n" |
| "#endif", |
| Style); |
| // FIXME: This doesn't handle the case where there's code between the |
| // #ifndef and #define but all other conditions hold. This is because when |
| // the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the |
| // previous code line yet, so we can't detect it. |
| EXPECT_EQ("#ifndef NOT_GUARD\n" |
| "code();\n" |
| "#define NOT_GUARD\n" |
| "code();\n" |
| "#endif", |
| format("#ifndef NOT_GUARD\n" |
| "code();\n" |
| "# define NOT_GUARD\n" |
| "code();\n" |
| "#endif", |
| Style)); |
| // FIXME: This doesn't handle cases where legitimate preprocessor lines may |
| // be outside an include guard. Examples are #pragma once and |
| // #pragma GCC diagnostic, or anything else that does not change the meaning |
| // of the file if it's included multiple times. |
| EXPECT_EQ("#ifdef WIN32\n" |
| "# pragma once\n" |
| "#endif\n" |
| "#ifndef HEADER_H\n" |
| "# define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| format("#ifdef WIN32\n" |
| "# pragma once\n" |
| "#endif\n" |
| "#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| Style)); |
| // FIXME: This does not detect when there is a single non-preprocessor line |
| // in front of an include-guard-like structure where other conditions hold |
| // because ScopedLineState hides the line. |
| EXPECT_EQ("code();\n" |
| "#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| format("code();\n" |
| "#ifndef HEADER_H\n" |
| "# define HEADER_H\n" |
| "code();\n" |
| "#endif", |
| Style)); |
| // Keep comments aligned with #, otherwise indent comments normally. These |
| // tests cannot use verifyFormat because messUp manipulates leading |
| // whitespace. |
| { |
| const char *Expected = "" |
| "void f() {\n" |
| "#if 1\n" |
| "// Preprocessor aligned.\n" |
| "# define A 0\n" |
| " // Code. Separated by blank line.\n" |
| "\n" |
| "# define B 0\n" |
| " // Code. Not aligned with #\n" |
| "# define C 0\n" |
| "#endif"; |
| const char *ToFormat = "" |
| "void f() {\n" |
| "#if 1\n" |
| "// Preprocessor aligned.\n" |
| "# define A 0\n" |
| "// Code. Separated by blank line.\n" |
| "\n" |
| "# define B 0\n" |
| " // Code. Not aligned with #\n" |
| "# define C 0\n" |
| "#endif"; |
| EXPECT_EQ(Expected, format(ToFormat, Style)); |
| EXPECT_EQ(Expected, format(Expected, Style)); |
| } |
| // Keep block quotes aligned. |
| { |
| const char *Expected = "" |
| "void f() {\n" |
| "#if 1\n" |
| "/* Preprocessor aligned. */\n" |
| "# define A 0\n" |
| " /* Code. Separated by blank line. */\n" |
| "\n" |
| "# define B 0\n" |
| " /* Code. Not aligned with # */\n" |
| "# define C 0\n" |
| "#endif"; |
| const char *ToFormat = "" |
| "void f() {\n" |
| "#if 1\n" |
| "/* Preprocessor aligned. */\n" |
| "# define A 0\n" |
| "/* Code. Separated by blank line. */\n" |
| "\n" |
| "# define B 0\n" |
| " /* Code. Not aligned with # */\n" |
| "# define C 0\n" |
| "#endif"; |
| EXPECT_EQ(Expected, format(ToFormat, Style)); |
| EXPECT_EQ(Expected, format(Expected, Style)); |
| } |
| // Keep comments aligned with un-indented directives. |
| { |
| const char *Expected = "" |
| "void f() {\n" |
| "// Preprocessor aligned.\n" |
| "#define A 0\n" |
| " // Code. Separated by blank line.\n" |
| "\n" |
| "#define B 0\n" |
| " // Code. Not aligned with #\n" |
| "#define C 0\n"; |
| const char *ToFormat = "" |
| "void f() {\n" |
| "// Preprocessor aligned.\n" |
| "#define A 0\n" |
| "// Code. Separated by blank line.\n" |
| "\n" |
| "#define B 0\n" |
| " // Code. Not aligned with #\n" |
| "#define C 0\n"; |
| EXPECT_EQ(Expected, format(ToFormat, Style)); |
| EXPECT_EQ(Expected, format(Expected, Style)); |
| } |
| // Test AfterHash with tabs. |
| { |
| FormatStyle Tabbed = Style; |
| Tabbed.UseTab = FormatStyle::UT_Always; |
| Tabbed.IndentWidth = 8; |
| Tabbed.TabWidth = 8; |
| verifyFormat("#ifdef _WIN32\n" |
| "#\tdefine A 0\n" |
| "#\tifdef VAR2\n" |
| "#\t\tdefine B 1\n" |
| "#\t\tinclude <someheader.h>\n" |
| "#\t\tdefine MACRO \\\n" |
| "\t\t\tsome_very_long_func_aaaaaaaaaa();\n" |
| "#\tendif\n" |
| "#else\n" |
| "#\tdefine A 1\n" |
| "#endif", |
| Tabbed); |
| } |
| |
| // Regression test: Multiline-macro inside include guards. |
| verifyFormat("#ifndef HEADER_H\n" |
| "#define HEADER_H\n" |
| "#define A() \\\n" |
| " int i; \\\n" |
| " int j;\n" |
| "#endif // HEADER_H", |
| getLLVMStyleWithColumns(20)); |
| |
| Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash; |
| // Basic before hash indent tests |
| verifyFormat("#ifdef _WIN32\n" |
| " #define A 0\n" |
| " #ifdef VAR2\n" |
| " #define B 1\n" |
| " #include <someheader.h>\n" |
| " #define MACRO \\\n" |
| " some_very_long_func_aaaaaaaaaa();\n" |
| " #endif\n" |
| "#else\n" |
| " #define A 1\n" |
| "#endif", |
| Style); |
| verifyFormat("#if A\n" |
| " #define MACRO \\\n" |
| " void a(int x) { \\\n" |
| " b(); \\\n" |
| " c(); \\\n" |
| " d(); \\\n" |
| " e(); \\\n" |
| " f(); \\\n" |
| " }\n" |
| "#endif", |
| Style); |
| // Keep comments aligned with indented directives. These |
| // tests cannot use verifyFormat because messUp manipulates leading |
| // whitespace. |
| { |
| const char *Expected = "void f() {\n" |
| "// Aligned to preprocessor.\n" |
| "#if 1\n" |
| " // Aligned to code.\n" |
| " int a;\n" |
| " #if 1\n" |
| " // Aligned to preprocessor.\n" |
| " #define A 0\n" |
| " // Aligned to code.\n" |
| " int b;\n" |
| " #endif\n" |
| "#endif\n" |
| "}"; |
| const char *ToFormat = "void f() {\n" |
| "// Aligned to preprocessor.\n" |
| "#if 1\n" |
| "// Aligned to code.\n" |
| "int a;\n" |
| "#if 1\n" |
| "// Aligned to preprocessor.\n" |
| "#define A 0\n" |
| "// Aligned to code.\n" |
| "int b;\n" |
| "#endif\n" |
| "#endif\n" |
| "}"; |
| EXPECT_EQ(Expected, format(ToFormat, Style)); |
| EXPECT_EQ(Expected, format(Expected, Style)); |
| } |
| { |
| const char *Expected = "void f() {\n" |
| "/* Aligned to preprocessor. */\n" |
| "#if 1\n" |
| " /* Aligned to code. */\n" |
| " int a;\n" |
| " #if 1\n" |
| " /* Aligned to preprocessor. */\n" |
| " #define A 0\n" |
| " /* Aligned to code. */\n" |
| " int b;\n" |
| " #endif\n" |
| "#endif\n" |
| "}"; |
| const char *ToFormat = "void f() {\n" |
| "/* Aligned to preprocessor. */\n" |
| "#if 1\n" |
| "/* Aligned to code. */\n" |
| "int a;\n" |
| "#if 1\n" |
| "/* Aligned to preprocessor. */\n" |
| "#define A 0\n" |
| "/* Aligned to code. */\n" |
| "int b;\n" |
| "#endif\n" |
| "#endif\n" |
| "}"; |
| EXPECT_EQ(Expected, format(ToFormat, Style)); |
| EXPECT_EQ(Expected, format(Expected, Style)); |
| } |
| |
| // Test single comment before preprocessor |
| verifyFormat("// Comment\n" |
| "\n" |
| "#if 1\n" |
| "#endif", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) { |
| verifyFormat("{\n { a #c; }\n}"); |
| } |
| |
| TEST_F(FormatTest, FormatUnbalancedStructuralElements) { |
| EXPECT_EQ("#define A \\\n { \\\n {\nint i;", |
| format("#define A { {\nint i;", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("#define A \\\n } \\\n }\nint i;", |
| format("#define A } }\nint i;", getLLVMStyleWithColumns(11))); |
| } |
| |
| TEST_F(FormatTest, EscapedNewlines) { |
| FormatStyle Narrow = getLLVMStyleWithColumns(11); |
| EXPECT_EQ("#define A \\\n int i; \\\n int j;", |
| format("#define A \\\nint i;\\\n int j;", Narrow)); |
| EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;")); |
| EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); |
| EXPECT_EQ("/* \\ \\ \\\n */", format("\\\n/* \\ \\ \\\n */")); |
| EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>")); |
| |
| FormatStyle AlignLeft = getLLVMStyle(); |
| AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| EXPECT_EQ("#define MACRO(x) \\\n" |
| "private: \\\n" |
| " int x(int a);\n", |
| format("#define MACRO(x) \\\n" |
| "private: \\\n" |
| " int x(int a);\n", |
| AlignLeft)); |
| |
| // CRLF line endings |
| EXPECT_EQ("#define A \\\r\n int i; \\\r\n int j;", |
| format("#define A \\\r\nint i;\\\r\n int j;", Narrow)); |
| EXPECT_EQ("#define A\r\n\r\nint i;", format("#define A \\\r\n\r\n int i;")); |
| EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); |
| EXPECT_EQ("/* \\ \\ \\\r\n */", format("\\\r\n/* \\ \\ \\\r\n */")); |
| EXPECT_EQ("<a\r\n\\\\\r\n>", format("<a\r\n\\\\\r\n>")); |
| EXPECT_EQ("#define MACRO(x) \\\r\n" |
| "private: \\\r\n" |
| " int x(int a);\r\n", |
| format("#define MACRO(x) \\\r\n" |
| "private: \\\r\n" |
| " int x(int a);\r\n", |
| AlignLeft)); |
| |
| FormatStyle DontAlign = getLLVMStyle(); |
| DontAlign.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; |
| DontAlign.MaxEmptyLinesToKeep = 3; |
| // FIXME: can't use verifyFormat here because the newline before |
| // "public:" is not inserted the first time it's reformatted |
| EXPECT_EQ("#define A \\\n" |
| " class Foo { \\\n" |
| " void bar(); \\\n" |
| "\\\n" |
| "\\\n" |
| "\\\n" |
| " public: \\\n" |
| " void baz(); \\\n" |
| " };", |
| format("#define A \\\n" |
| " class Foo { \\\n" |
| " void bar(); \\\n" |
| "\\\n" |
| "\\\n" |
| "\\\n" |
| " public: \\\n" |
| " void baz(); \\\n" |
| " };", |
| DontAlign)); |
| } |
| |
| TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) { |
| verifyFormat("#define A \\\n" |
| " int v( \\\n" |
| " a); \\\n" |
| " int i;", |
| getLLVMStyleWithColumns(11)); |
| } |
| |
| TEST_F(FormatTest, MixingPreprocessorDirectivesAndNormalCode) { |
| EXPECT_EQ( |
| "#define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| " \\\n" |
| " aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)\n" |
| "\n" |
| "AlooooooooooooooooooooooooooooooooooooooongCaaaaaaaaaal(\n" |
| " aLooooooooooooooooooooooonPaaaaaaaaaaaaaaaaaaaaarmmmm);\n", |
| format(" #define ALooooooooooooooooooooooooooooooooooooooongMacro(" |
| "\\\n" |
| "aLoooooooooooooooooooooooongFuuuuuuuuuuuuuunctiooooooooo)\n" |
| " \n" |
| " AlooooooooooooooooooooooooooooooooooooooongCaaaaaaaaaal(\n" |
| " aLooooooooooooooooooooooonPaaaaaaaaaaaaaaaaaaaaarmmmm);\n")); |
| } |
| |
| TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { |
| EXPECT_EQ("int\n" |
| "#define A\n" |
| " a;", |
| format("int\n#define A\na;")); |
| verifyFormat("functionCallTo(\n" |
| " someOtherFunction(\n" |
| " withSomeParameters, whichInSequence,\n" |
| " areLongerThanALine(andAnotherCall,\n" |
| "#define A B\n" |
| " withMoreParamters,\n" |
| " whichStronglyInfluenceTheLayout),\n" |
| " andMoreParameters),\n" |
| " trailing);", |
| getLLVMStyleWithColumns(69)); |
| verifyFormat("Foo::Foo()\n" |
| "#ifdef BAR\n" |
| " : baz(0)\n" |
| "#endif\n" |
| "{\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| " if (true)\n" |
| "#ifdef A\n" |
| " f(42);\n" |
| " x();\n" |
| "#else\n" |
| " g();\n" |
| " x();\n" |
| "#endif\n" |
| "}"); |
| verifyFormat("void f(param1, param2,\n" |
| " param3,\n" |
| "#ifdef A\n" |
| " param4(param5,\n" |
| "#ifdef A1\n" |
| " param6,\n" |
| "#ifdef A2\n" |
| " param7),\n" |
| "#else\n" |
| " param8),\n" |
| " param9,\n" |
| "#endif\n" |
| " param10,\n" |
| "#endif\n" |
| " param11)\n" |
| "#else\n" |
| " param12)\n" |
| "#endif\n" |
| "{\n" |
| " x();\n" |
| "}", |
| getLLVMStyleWithColumns(28)); |
| verifyFormat("#if 1\n" |
| "int i;"); |
| verifyFormat("#if 1\n" |
| "#endif\n" |
| "#if 1\n" |
| "#else\n" |
| "#endif\n"); |
| verifyFormat("DEBUG({\n" |
| " return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n" |
| "});\n" |
| "#if a\n" |
| "#else\n" |
| "#endif"); |
| |
| verifyIncompleteFormat("void f(\n" |
| "#if A\n" |
| ");\n" |
| "#else\n" |
| "#endif"); |
| } |
| |
| TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) { |
| verifyFormat("#endif\n" |
| "#if B"); |
| } |
| |
| TEST_F(FormatTest, FormatsJoinedLinesOnSubsequentRuns) { |
| FormatStyle SingleLine = getLLVMStyle(); |
| SingleLine.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse; |
| verifyFormat("#if 0\n" |
| "#elif 1\n" |
| "#endif\n" |
| "void foo() {\n" |
| " if (test) foo2();\n" |
| "}", |
| SingleLine); |
| } |
| |
| TEST_F(FormatTest, LayoutBlockInsideParens) { |
| verifyFormat("functionCall({ int i; });"); |
| verifyFormat("functionCall({\n" |
| " int i;\n" |
| " int j;\n" |
| "});"); |
| verifyFormat("functionCall(\n" |
| " {\n" |
| " int i;\n" |
| " int j;\n" |
| " },\n" |
| " aaaa, bbbb, cccc);"); |
| verifyFormat("functionA(functionB({\n" |
| " int i;\n" |
| " int j;\n" |
| " }),\n" |
| " aaaa, bbbb, cccc);"); |
| verifyFormat("functionCall(\n" |
| " {\n" |
| " int i;\n" |
| " int j;\n" |
| " },\n" |
| " aaaa, bbbb, // comment\n" |
| " cccc);"); |
| verifyFormat("functionA(functionB({\n" |
| " int i;\n" |
| " int j;\n" |
| " }),\n" |
| " aaaa, bbbb, // comment\n" |
| " cccc);"); |
| verifyFormat("functionCall(aaaa, bbbb, { int i; });"); |
| verifyFormat("functionCall(aaaa, bbbb, {\n" |
| " int i;\n" |
| " int j;\n" |
| "});"); |
| verifyFormat( |
| "Aaa(\n" // FIXME: There shouldn't be a linebreak here. |
| " {\n" |
| " int i; // break\n" |
| " },\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" |
| " ccccccccccccccccc));"); |
| verifyFormat("DEBUG({\n" |
| " if (a)\n" |
| " f();\n" |
| "});"); |
| } |
| |
| TEST_F(FormatTest, LayoutBlockInsideStatement) { |
| EXPECT_EQ("SOME_MACRO { int i; }\n" |
| "int i;", |
| format(" SOME_MACRO {int i;} int i;")); |
| } |
| |
| TEST_F(FormatTest, LayoutNestedBlocks) { |
| verifyFormat("void AddOsStrings(unsigned bitmask) {\n" |
| " struct s {\n" |
| " int i;\n" |
| " };\n" |
| " s kBitsToOs[] = {{10}};\n" |
| " for (int i = 0; i < 10; ++i)\n" |
| " return;\n" |
| "}"); |
| verifyFormat("call(parameter, {\n" |
| " something();\n" |
| " // Comment using all columns.\n" |
| " somethingelse();\n" |
| "});", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("DEBUG( //\n" |
| " { f(); }, a);"); |
| verifyFormat("DEBUG( //\n" |
| " {\n" |
| " f(); //\n" |
| " },\n" |
| " a);"); |
| |
| EXPECT_EQ("call(parameter, {\n" |
| " something();\n" |
| " // Comment too\n" |
| " // looooooooooong.\n" |
| " somethingElse();\n" |
| "});", |
| format("call(parameter, {\n" |
| " something();\n" |
| " // Comment too looooooooooong.\n" |
| " somethingElse();\n" |
| "});", |
| getLLVMStyleWithColumns(29))); |
| EXPECT_EQ("DEBUG({ int i; });", format("DEBUG({ int i; });")); |
| EXPECT_EQ("DEBUG({ // comment\n" |
| " int i;\n" |
| "});", |
| format("DEBUG({ // comment\n" |
| "int i;\n" |
| "});")); |
| EXPECT_EQ("DEBUG({\n" |
| " int i;\n" |
| "\n" |
| " // comment\n" |
| " int j;\n" |
| "});", |
| format("DEBUG({\n" |
| " int i;\n" |
| "\n" |
| " // comment\n" |
| " int j;\n" |
| "});")); |
| |
| verifyFormat("DEBUG({\n" |
| " if (a)\n" |
| " return;\n" |
| "});"); |
| verifyGoogleFormat("DEBUG({\n" |
| " if (a) return;\n" |
| "});"); |
| FormatStyle Style = getGoogleStyle(); |
| Style.ColumnLimit = 45; |
| verifyFormat("Debug(\n" |
| " aaaaa,\n" |
| " {\n" |
| " if (aaaaaaaaaaaaaaaaaaaaaaaa) return;\n" |
| " },\n" |
| " a);", |
| Style); |
| |
| verifyFormat("SomeFunction({MACRO({ return output; }), b});"); |
| |
| verifyNoCrash("^{v^{a}}"); |
| } |
| |
| TEST_F(FormatTest, FormatNestedBlocksInMacros) { |
| EXPECT_EQ("#define MACRO() \\\n" |
| " Debug(aaa, /* force line break */ \\\n" |
| " { \\\n" |
| " int i; \\\n" |
| " int j; \\\n" |
| " })", |
| format("#define MACRO() Debug(aaa, /* force line break */ \\\n" |
| " { int i; int j; })", |
| getGoogleStyle())); |
| |
| EXPECT_EQ("#define A \\\n" |
| " [] { \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n" |
| " }", |
| format("#define A [] { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); }", |
| getGoogleStyle())); |
| } |
| |
| TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) { |
| EXPECT_EQ("{}", format("{}")); |
| verifyFormat("enum E {};"); |
| verifyFormat("enum E {}"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.SpaceInEmptyBlock = true; |
| EXPECT_EQ("void f() { }", format("void f() {}", Style)); |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; |
| EXPECT_EQ("while (true) { }", format("while (true) {}", Style)); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.BeforeElse = false; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; |
| verifyFormat("if (a)\n" |
| "{\n" |
| "} else if (b)\n" |
| "{\n" |
| "} else\n" |
| "{ }", |
| Style); |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never; |
| verifyFormat("if (a) {\n" |
| "} else if (b) {\n" |
| "} else {\n" |
| "}", |
| Style); |
| Style.BraceWrapping.BeforeElse = true; |
| verifyFormat("if (a) { }\n" |
| "else if (b) { }\n" |
| "else { }", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatBeginBlockEndMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.MacroBlockBegin = "^[A-Z_]+_BEGIN$"; |
| Style.MacroBlockEnd = "^[A-Z_]+_END$"; |
| verifyFormat("FOO_BEGIN\n" |
| " FOO_ENTRY\n" |
| "FOO_END", |
| Style); |
| verifyFormat("FOO_BEGIN\n" |
| " NESTED_FOO_BEGIN\n" |
| " NESTED_FOO_ENTRY\n" |
| " NESTED_FOO_END\n" |
| "FOO_END", |
| Style); |
| verifyFormat("FOO_BEGIN(Foo, Bar)\n" |
| " int x;\n" |
| " x = 1;\n" |
| "FOO_END(Baz)", |
| Style); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Line break tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, PreventConfusingIndents) { |
| verifyFormat( |
| "void f() {\n" |
| " SomeLongMethodName(SomeReallyLongMethod(CallOtherReallyLongMethod(\n" |
| " parameter, parameter, parameter)),\n" |
| " SecondLongCall(parameter));\n" |
| "}"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaa]];"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa>;"); |
| verifyFormat("int a = bbbb && ccc &&\n" |
| " fffff(\n" |
| "#define A Just forcing a new line\n" |
| " ddd);"); |
| } |
| |
| TEST_F(FormatTest, LineBreakingInBinaryExpressions) { |
| verifyFormat( |
| "bool aaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() ||\n" |
| " bbbbbbbb();"); |
| verifyFormat( |
| "bool aaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() or\n" |
| " bbbbbbbb();"); |
| |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb &&\n" |
| " ccccccccc == ddddddddddd;"); |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb and\n" |
| " ccccccccc == ddddddddddd;"); |
| verifyFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa not_eq bbbbbbbbbbbbbbbbbb and\n" |
| " ccccccccc == ddddddddddd;"); |
| |
| verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n" |
| " aaaaaa) &&\n" |
| " bbbbbb && cccccc;"); |
| verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n" |
| " aaaaaa) >>\n" |
| " bbbbbb;"); |
| verifyFormat("aa = Whitespaces.addUntouchableComment(\n" |
| " SourceMgr.getSpellingColumnNumber(\n" |
| " TheLine.Last->FormatTok.Tok.getLocation()) -\n" |
| " 1);"); |
| |
| verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaaaaaaa\n" |
| " cccccc) {\n}"); |
| verifyFormat("if constexpr ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaa\n" |
| " cccccc) {\n}"); |
| verifyFormat("if CONSTEXPR ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbb) && // aaaaaaaaaaa\n" |
| " cccccc) {\n}"); |
| verifyFormat("b = a &&\n" |
| " // Comment\n" |
| " b.c && d;"); |
| |
| // If the LHS of a comparison is not a binary expression itself, the |
| // additional linebreak confuses many people. |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) > 5) {\n" |
| "}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) <=> 5) {\n" |
| "}"); |
| // Even explicit parentheses stress the precedence enough to make the |
| // additional break unnecessary. |
| verifyFormat("if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" |
| "}"); |
| // This cases is borderline, but with the indentation it is still readable. |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaa) > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}", |
| getLLVMStyleWithColumns(75)); |
| |
| // If the LHS is a binary expression, we should still use the additional break |
| // as otherwise the formatting hides the operator precedence. |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " 5) {\n" |
| "}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa <=>\n" |
| " 5) {\n" |
| "}"); |
| |
| FormatStyle OnePerLine = getLLVMStyle(); |
| OnePerLine.BinPackParameters = false; |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}", |
| OnePerLine); |
| |
| verifyFormat("int i = someFunction(aaaaaaa, 0)\n" |
| " .aaa(aaaaaaaaaaaaa) *\n" |
| " aaaaaaa +\n" |
| " aaaaaaa;", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, ExpressionIndentation) { |
| verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb &&\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\n" |
| " ccccccccccccccccccccccccccccccccccccccccc;"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ==\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}"); |
| verifyFormat("if () {\n" |
| "} else if (aaaaa && bbbbb > // break\n" |
| " ccccc) {\n" |
| "}"); |
| verifyFormat("if () {\n" |
| "} else if constexpr (aaaaa && bbbbb > // break\n" |
| " ccccc) {\n" |
| "}"); |
| verifyFormat("if () {\n" |
| "} else if CONSTEXPR (aaaaa && bbbbb > // break\n" |
| " ccccc) {\n" |
| "}"); |
| verifyFormat("if () {\n" |
| "} else if (aaaaa &&\n" |
| " bbbbb > // break\n" |
| " ccccc &&\n" |
| " ddddd) {\n" |
| "}"); |
| |
| // Presence of a trailing comment used to change indentation of b. |
| verifyFormat("return aaaaaaaaaaaaaaaaaaa +\n" |
| " b;\n" |
| "return aaaaaaaaaaaaaaaaaaa +\n" |
| " b; //", |
| getLLVMStyleWithColumns(30)); |
| } |
| |
| TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { |
| // Not sure what the best system is here. Like this, the LHS can be found |
| // immediately above an operator (everything with the same or a higher |
| // indent). The RHS is aligned right of the operator and so compasses |
| // everything until something with the same indent as the operator is found. |
| // FIXME: Is this a good system? |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat( |
| "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " > ccccccccccccccccccccccccccccccccccccccccc;", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if () {\n" |
| "} else if (aaaaa\n" |
| " && bbbbb // break\n" |
| " > ccccc) {\n" |
| "}", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " && bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", |
| Style); |
| verifyFormat("return (a)\n" |
| " // comment\n" |
| " + b;", |
| Style); |
| verifyFormat( |
| "int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + cc;", |
| Style); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " = aaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| Style); |
| |
| // Forced by comments. |
| verifyFormat( |
| "unsigned ContentSize =\n" |
| " sizeof(int16_t) // DWARF ARange version number\n" |
| " + sizeof(int32_t) // Offset of CU in the .debug_info section\n" |
| " + sizeof(int8_t) // Pointer Size (in bytes)\n" |
| " + sizeof(int8_t); // Segment Size (in bytes)"); |
| |
| verifyFormat("return boost::fusion::at_c<0>(iiii).second\n" |
| " == boost::fusion::at_c<1>(iiii).second;", |
| Style); |
| |
| Style.ColumnLimit = 60; |
| verifyFormat("zzzzzzzzzz\n" |
| " = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " >> aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| |
| Style.ColumnLimit = 80; |
| Style.IndentWidth = 4; |
| Style.TabWidth = 4; |
| Style.UseTab = FormatStyle::UT_Always; |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| Style.AlignOperands = FormatStyle::OAS_DontAlign; |
| EXPECT_EQ("return someVeryVeryLongConditionThatBarelyFitsOnALine\n" |
| "\t&& (someOtherLongishConditionPart1\n" |
| "\t\t|| someOtherEvenLongerNestedConditionPart2);", |
| format("return someVeryVeryLongConditionThatBarelyFitsOnALine && " |
| "(someOtherLongishConditionPart1 || " |
| "someOtherEvenLongerNestedConditionPart2);", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, ExpressionIndentationStrictAlign) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| Style.AlignOperands = FormatStyle::OAS_AlignAfterOperator; |
| |
| verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " > ccccccccccccccccccccccccccccccccccccccccc;", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", |
| Style); |
| verifyFormat("if () {\n" |
| "} else if (aaaaa\n" |
| " && bbbbb // break\n" |
| " > ccccc) {\n" |
| "}", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " && bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", |
| Style); |
| verifyFormat("return (a)\n" |
| " // comment\n" |
| " + b;", |
| Style); |
| verifyFormat( |
| "int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + cc;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : ccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee)\n" |
| " : bbbbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " = aaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| Style); |
| |
| verifyFormat("return boost::fusion::at_c<0>(iiii).second\n" |
| " == boost::fusion::at_c<1>(iiii).second;", |
| Style); |
| |
| Style.ColumnLimit = 60; |
| verifyFormat("zzzzzzzzzzzzz\n" |
| " = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " >> aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| |
| // Forced by comments. |
| Style.ColumnLimit = 80; |
| verifyFormat( |
| "unsigned ContentSize\n" |
| " = sizeof(int16_t) // DWARF ARange version number\n" |
| " + sizeof(int32_t) // Offset of CU in the .debug_info section\n" |
| " + sizeof(int8_t) // Pointer Size (in bytes)\n" |
| " + sizeof(int8_t); // Segment Size (in bytes)", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; |
| verifyFormat( |
| "unsigned ContentSize =\n" |
| " sizeof(int16_t) // DWARF ARange version number\n" |
| " + sizeof(int32_t) // Offset of CU in the .debug_info section\n" |
| " + sizeof(int8_t) // Pointer Size (in bytes)\n" |
| " + sizeof(int8_t); // Segment Size (in bytes)", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat( |
| "unsigned ContentSize =\n" |
| " sizeof(int16_t) // DWARF ARange version number\n" |
| " + sizeof(int32_t) // Offset of CU in the .debug_info section\n" |
| " + sizeof(int8_t) // Pointer Size (in bytes)\n" |
| " + sizeof(int8_t); // Segment Size (in bytes)", |
| Style); |
| } |
| |
| TEST_F(FormatTest, EnforcedOperatorWraps) { |
| // Here we'd like to wrap after the || operators, but a comment is forcing an |
| // earlier wrap. |
| verifyFormat("bool x = aaaaa //\n" |
| " || bbbbb\n" |
| " //\n" |
| " || cccc;"); |
| } |
| |
| TEST_F(FormatTest, NoOperandAlignment) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AlignOperands = FormatStyle::OAS_DontAlign; |
| verifyFormat("aaaaaaaaaaaaaa(aaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; |
| verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " > ccccccccccccccccccccccccccccccccccccccccc;", |
| Style); |
| |
| verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " + cc;", |
| Style); |
| verifyFormat("int a = aa\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " * cccccccccccccccccccccccccccccccccccc;\n", |
| Style); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| verifyFormat("return (a > b\n" |
| " // comment1\n" |
| " // comment2\n" |
| " || c);", |
| Style); |
| } |
| |
| TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; |
| verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AllowBinPackingInsideArguments) { |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; |
| Style.BinPackArguments = false; |
| verifyFormat("void test() {\n" |
| " someFunction(\n" |
| " this + argument + is + quite\n" |
| " + long + so + it + gets + wrapped\n" |
| " + but + remains + bin - packed);\n" |
| "}", |
| Style); |
| verifyFormat("void test() {\n" |
| " someFunction(arg1,\n" |
| " this + argument + is\n" |
| " + quite + long + so\n" |
| " + it + gets + wrapped\n" |
| " + but + remains + bin\n" |
| " - packed,\n" |
| " arg3);\n" |
| "}", |
| Style); |
| verifyFormat("void test() {\n" |
| " someFunction(\n" |
| " arg1,\n" |
| " this + argument + has\n" |
| " + anotherFunc(nested,\n" |
| " calls + whose\n" |
| " + arguments\n" |
| " + are + also\n" |
| " + wrapped,\n" |
| " in + addition)\n" |
| " + to + being + bin - packed,\n" |
| " arg3);\n" |
| "}", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat("void test() {\n" |
| " someFunction(\n" |
| " arg1,\n" |
| " this + argument + has +\n" |
| " anotherFunc(nested,\n" |
| " calls + whose +\n" |
| " arguments +\n" |
| " are + also +\n" |
| " wrapped,\n" |
| " in + addition) +\n" |
| " to + being + bin - packed,\n" |
| " arg3);\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, BreakBinaryOperatorsInPresenceOfTemplates) { |
| auto Style = getLLVMStyleWithColumns(45); |
| EXPECT_EQ(Style.BreakBeforeBinaryOperators, FormatStyle::BOS_None); |
| verifyFormat("bool b =\n" |
| " is_default_constructible_v<hash<T>> and\n" |
| " is_copy_constructible_v<hash<T>> and\n" |
| " is_move_constructible_v<hash<T>> and\n" |
| " is_copy_assignable_v<hash<T>> and\n" |
| " is_move_assignable_v<hash<T>> and\n" |
| " is_destructible_v<hash<T>> and\n" |
| " is_swappable_v<hash<T>> and\n" |
| " is_callable_v<hash<T>(T)>;", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; |
| verifyFormat("bool b = is_default_constructible_v<hash<T>>\n" |
| " and is_copy_constructible_v<hash<T>>\n" |
| " and is_move_constructible_v<hash<T>>\n" |
| " and is_copy_assignable_v<hash<T>>\n" |
| " and is_move_assignable_v<hash<T>>\n" |
| " and is_destructible_v<hash<T>>\n" |
| " and is_swappable_v<hash<T>>\n" |
| " and is_callable_v<hash<T>(T)>;", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat("bool b = is_default_constructible_v<hash<T>>\n" |
| " and is_copy_constructible_v<hash<T>>\n" |
| " and is_move_constructible_v<hash<T>>\n" |
| " and is_copy_assignable_v<hash<T>>\n" |
| " and is_move_assignable_v<hash<T>>\n" |
| " and is_destructible_v<hash<T>>\n" |
| " and is_swappable_v<hash<T>>\n" |
| " and is_callable_v<hash<T>(T)>;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ConstructorInitializers) { |
| verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}"); |
| verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}", |
| getLLVMStyleWithColumns(45)); |
| verifyFormat("Constructor()\n" |
| " : Inttializer(FitsOnTheLine) {}", |
| getLLVMStyleWithColumns(44)); |
| verifyFormat("Constructor()\n" |
| " : Inttializer(FitsOnTheLine) {}", |
| getLLVMStyleWithColumns(43)); |
| |
| verifyFormat("template <typename T>\n" |
| "Constructor() : Initializer(FitsOnTheLine) {}", |
| getLLVMStyleWithColumns(45)); |
| |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}"); |
| |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}"); |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}"); |
| verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " : aaaaaaaaaa(aaaaaa) {}"); |
| |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa() {}"); |
| |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}"); |
| |
| verifyFormat("Constructor(int Parameter = 0)\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}"); |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n" |
| "}", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}"); |
| |
| // Here a line could be saved by splitting the second initializer onto two |
| // lines, but that is not desirable. |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaa(aaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}"); |
| |
| FormatStyle OnePerLine = getLLVMStyle(); |
| OnePerLine.PackConstructorInitializers = FormatStyle::PCIS_Never; |
| verifyFormat("MyClass::MyClass()\n" |
| " : a(a),\n" |
| " b(b),\n" |
| " c(c) {}", |
| OnePerLine); |
| verifyFormat("MyClass::MyClass()\n" |
| " : a(a), // comment\n" |
| " b(b),\n" |
| " c(c) {}", |
| OnePerLine); |
| verifyFormat("MyClass::MyClass(int a)\n" |
| " : b(a), // comment\n" |
| " c(a + 1) { // lined up\n" |
| "}", |
| OnePerLine); |
| verifyFormat("Constructor()\n" |
| " : a(b, b, b) {}", |
| OnePerLine); |
| OnePerLine.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| OnePerLine.AllowAllParametersOfDeclarationOnNextLine = false; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), // Some comment\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| verifyFormat("MyClass::MyClass(int var)\n" |
| " : some_var_(var), // 4 space indent\n" |
| " some_other_var_(var + 1) { // lined up\n" |
| "}", |
| OnePerLine); |
| verifyFormat("Constructor()\n" |
| " : aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa) {}", |
| OnePerLine); |
| verifyFormat("Constructor()\n" |
| " : aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| OnePerLine.BinPackParameters = false; |
| verifyFormat( |
| "Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaa().aaa(),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| OnePerLine.ColumnLimit = 60; |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbb(b) {}", |
| OnePerLine); |
| |
| EXPECT_EQ("Constructor()\n" |
| " : // Comment forcing unwanted break.\n" |
| " aaaa(aaaa) {}", |
| format("Constructor() :\n" |
| " // Comment forcing unwanted break.\n" |
| " aaaa(aaaa) {}")); |
| } |
| |
| TEST_F(FormatTest, AllowAllConstructorInitializersOnNextLine) { |
| FormatStyle Style = getLLVMStyleWithColumns(60); |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; |
| Style.BinPackParameters = false; |
| |
| for (int i = 0; i < 4; ++i) { |
| // Test all combinations of parameters that should not have an effect. |
| Style.AllowAllParametersOfDeclarationOnNextLine = i & 1; |
| Style.AllowAllArgumentsOnNextLine = i & 2; |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| verifyFormat("Constructor() : a(a), b(b) {}", Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a)\n" |
| " , bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| verifyFormat("Constructor() : a(a), b(b) {}", Style); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| } |
| |
| // Test interactions between AllowAllParametersOfDeclarationOnNextLine and |
| // AllowAllConstructorInitializersOnNextLine in all |
| // BreakConstructorInitializers modes |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; |
| Style.AllowAllParametersOfDeclarationOnNextLine = true; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a)\n" |
| " , bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb,\n" |
| " int cccccccccccccccc)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.AllowAllParametersOfDeclarationOnNextLine = false; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a)\n" |
| " , bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; |
| |
| Style.AllowAllParametersOfDeclarationOnNextLine = true; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb,\n" |
| " int cccccccccccccccc)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.AllowAllParametersOfDeclarationOnNextLine = false; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb)\n" |
| " : aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; |
| Style.AllowAllParametersOfDeclarationOnNextLine = true; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb) :\n" |
| " aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb,\n" |
| " int cccccccccccccccc) :\n" |
| " aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| |
| Style.AllowAllParametersOfDeclarationOnNextLine = false; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("SomeClassWithALongName::Constructor(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb) :\n" |
| " aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbb(b) {}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AllowAllArgumentsOnNextLine) { |
| FormatStyle Style = getLLVMStyleWithColumns(60); |
| Style.BinPackArguments = false; |
| for (int i = 0; i < 4; ++i) { |
| // Test all combinations of parameters that should not have an effect. |
| Style.AllowAllParametersOfDeclarationOnNextLine = i & 1; |
| Style.PackConstructorInitializers = |
| i & 2 ? FormatStyle::PCIS_BinPack : FormatStyle::PCIS_Never; |
| |
| Style.AllowAllArgumentsOnNextLine = true; |
| verifyFormat("void foo() {\n" |
| " FunctionCallWithReallyLongName(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb);\n" |
| "}", |
| Style); |
| Style.AllowAllArgumentsOnNextLine = false; |
| verifyFormat("void foo() {\n" |
| " FunctionCallWithReallyLongName(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbbbbbbbbbb);\n" |
| "}", |
| Style); |
| |
| Style.AllowAllArgumentsOnNextLine = true; |
| verifyFormat("void foo() {\n" |
| " auto VariableWithReallyLongName = {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb};\n" |
| "}", |
| Style); |
| Style.AllowAllArgumentsOnNextLine = false; |
| verifyFormat("void foo() {\n" |
| " auto VariableWithReallyLongName = {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbbbbbbbbbb};\n" |
| "}", |
| Style); |
| } |
| |
| // This parameter should not affect declarations. |
| Style.BinPackParameters = false; |
| Style.AllowAllArgumentsOnNextLine = false; |
| Style.AllowAllParametersOfDeclarationOnNextLine = true; |
| verifyFormat("void FunctionCallWithReallyLongName(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbb);", |
| Style); |
| Style.AllowAllParametersOfDeclarationOnNextLine = false; |
| verifyFormat("void FunctionCallWithReallyLongName(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbb);", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) { |
| // Check that AllowAllArgumentsOnNextLine is respected for both BAS_DontAlign |
| // and BAS_Align. |
| FormatStyle Style = getLLVMStyleWithColumns(35); |
| StringRef Input = "functionCall(paramA, paramB, paramC);\n" |
| "void functionDecl(int A, int B, int C);"; |
| Style.AllowAllArgumentsOnNextLine = false; |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| EXPECT_EQ(StringRef("functionCall(paramA, paramB,\n" |
| " paramC);\n" |
| "void functionDecl(int A, int B,\n" |
| " int C);"), |
| format(Input, Style)); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; |
| EXPECT_EQ(StringRef("functionCall(paramA, paramB,\n" |
| " paramC);\n" |
| "void functionDecl(int A, int B,\n" |
| " int C);"), |
| format(Input, Style)); |
| // However, BAS_AlwaysBreak should take precedence over |
| // AllowAllArgumentsOnNextLine. |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| EXPECT_EQ(StringRef("functionCall(\n" |
| " paramA, paramB, paramC);\n" |
| "void functionDecl(\n" |
| " int A, int B, int C);"), |
| format(Input, Style)); |
| |
| // When AllowAllArgumentsOnNextLine is set, we prefer breaking before the |
| // first argument. |
| Style.AllowAllArgumentsOnNextLine = true; |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| EXPECT_EQ(StringRef("functionCall(\n" |
| " paramA, paramB, paramC);\n" |
| "void functionDecl(\n" |
| " int A, int B, int C);"), |
| format(Input, Style)); |
| // It wouldn't fit on one line with aligned parameters so this setting |
| // doesn't change anything for BAS_Align. |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; |
| EXPECT_EQ(StringRef("functionCall(paramA, paramB,\n" |
| " paramC);\n" |
| "void functionDecl(int A, int B,\n" |
| " int C);"), |
| format(Input, Style)); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| EXPECT_EQ(StringRef("functionCall(\n" |
| " paramA, paramB, paramC);\n" |
| "void functionDecl(\n" |
| " int A, int B, int C);"), |
| format(Input, Style)); |
| } |
| |
| TEST_F(FormatTest, BreakConstructorInitializersAfterColon) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; |
| |
| verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}"); |
| verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}", |
| getStyleWithColumns(Style, 45)); |
| verifyFormat("Constructor() :\n" |
| " Initializer(FitsOnTheLine) {}", |
| getStyleWithColumns(Style, 44)); |
| verifyFormat("Constructor() :\n" |
| " Initializer(FitsOnTheLine) {}", |
| getStyleWithColumns(Style, 43)); |
| |
| verifyFormat("template <typename T>\n" |
| "Constructor() : Initializer(FitsOnTheLine) {}", |
| getStyleWithColumns(Style, 50)); |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| verifyFormat( |
| "SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat( |
| "SomeClass::Constructor() : // NOLINT\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack; |
| verifyFormat( |
| "SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", |
| Style); |
| |
| verifyFormat( |
| "SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat( |
| "SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n" |
| " aaaaaaaaaa(aaaaaa) {}", |
| Style); |
| |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa() {}", |
| Style); |
| |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| |
| verifyFormat("Constructor(int Parameter = 0) :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n" |
| "}", |
| getStyleWithColumns(Style, 60)); |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}", |
| Style); |
| |
| // Here a line could be saved by splitting the second initializer onto two |
| // lines, but that is not desirable. |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaa(aaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| |
| FormatStyle OnePerLine = Style; |
| OnePerLine.PackConstructorInitializers = FormatStyle::PCIS_CurrentLine; |
| verifyFormat("SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| verifyFormat("SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), // Some comment\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| verifyFormat("Foo::Foo(int i, int j) : // NOLINT\n" |
| " i(i), // comment\n" |
| " j(j) {}", |
| OnePerLine); |
| verifyFormat("MyClass::MyClass(int var) :\n" |
| " some_var_(var), // 4 space indent\n" |
| " some_other_var_(var + 1) { // lined up\n" |
| "}", |
| OnePerLine); |
| verifyFormat("Constructor() :\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa),\n" |
| " aaaaa(aaaaaa) {}", |
| OnePerLine); |
| verifyFormat("Constructor() :\n" |
| " aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| OnePerLine.BinPackParameters = false; |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaa().aaa(),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| OnePerLine); |
| OnePerLine.ColumnLimit = 60; |
| verifyFormat("Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaa(a),\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbb(b) {}", |
| OnePerLine); |
| |
| verifyFormat("Constructor() :\n" |
| " // Comment forcing unwanted break.\n" |
| " aaaa(aaaa) {}", |
| Style); |
| verifyFormat("Constructor() : // NOLINT\n" |
| " aaaa(aaaa) {}", |
| Style); |
| verifyFormat("Constructor() : // A very long trailing comment that cannot fit" |
| " on a single\n" |
| " // line.\n" |
| " aaaa(aaaa) {}", |
| "Constructor() : // A very long trailing comment that cannot fit" |
| " on a single line.\n" |
| " aaaa(aaaa) {}", |
| Style); |
| |
| Style.ColumnLimit = 0; |
| verifyFormat("SomeClass::Constructor() :\n" |
| " a(a) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor() noexcept :\n" |
| " a(a) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor() :\n" |
| " a(a), b(b), c(c) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor() :\n" |
| " a(a) {\n" |
| " foo();\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| verifyFormat("SomeClass::Constructor() :\n" |
| " a(a), b(b), c(c) {\n" |
| "}", |
| Style); |
| verifyFormat("SomeClass::Constructor() :\n" |
| " a(a) {\n" |
| "}", |
| Style); |
| |
| Style.ColumnLimit = 80; |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| Style.ConstructorInitializerIndentWidth = 2; |
| verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", Style); |
| verifyFormat("SomeClass::Constructor() :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {}", |
| Style); |
| |
| // `ConstructorInitializerIndentWidth` actually applies to InheritanceList as |
| // well |
| Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon; |
| verifyFormat( |
| "class SomeClass\n" |
| " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", |
| Style); |
| Style.BreakInheritanceList = FormatStyle::BILS_BeforeComma; |
| verifyFormat( |
| "class SomeClass\n" |
| " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " , public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", |
| Style); |
| Style.BreakInheritanceList = FormatStyle::BILS_AfterColon; |
| verifyFormat( |
| "class SomeClass :\n" |
| " public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", |
| Style); |
| Style.BreakInheritanceList = FormatStyle::BILS_AfterComma; |
| verifyFormat( |
| "class SomeClass\n" |
| " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", |
| Style); |
| } |
| |
| #ifndef EXPENSIVE_CHECKS |
| // Expensive checks enables libstdc++ checking which includes validating the |
| // state of ranges used in std::priority_queue - this blows out the |
| // runtime/scalability of the function and makes this test unacceptably slow. |
| TEST_F(FormatTest, MemoizationTests) { |
| // This breaks if the memoization lookup does not take \c Indent and |
| // \c LastSpace into account. |
| verifyFormat( |
| "extern CFRunLoopTimerRef\n" |
| "CFRunLoopTimerCreate(CFAllocatorRef allocato, CFAbsoluteTime fireDate,\n" |
| " CFTimeInterval interval, CFOptionFlags flags,\n" |
| " CFIndex order, CFRunLoopTimerCallBack callout,\n" |
| " CFRunLoopTimerContext *context) {}"); |
| |
| // Deep nesting somewhat works around our memoization. |
| verifyFormat( |
| "aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(\n" |
| " aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(\n" |
| " aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(\n" |
| " aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(\n" |
| " aaaaa())))))))))))))))))))))))))))))))))))))));", |
| getLLVMStyleWithColumns(65)); |
| verifyFormat( |
| "aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa(\n" |
| " aaaaa,\n" |
| " aaaaa))))))))))));", |
| getLLVMStyleWithColumns(65)); |
| verifyFormat( |
| "a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(), a), a), a), a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a),\n" |
| " a)", |
| getLLVMStyleWithColumns(65)); |
| |
| // This test takes VERY long when memoization is broken. |
| FormatStyle OnePerLine = getLLVMStyle(); |
| OnePerLine.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| OnePerLine.BinPackParameters = false; |
| std::string input = "Constructor()\n" |
| " : aaaa(a,\n"; |
| for (unsigned i = 0, e = 80; i != e; ++i) |
| input += " a,\n"; |
| input += " a) {}"; |
| verifyFormat(input, OnePerLine); |
| } |
| #endif |
| |
| TEST_F(FormatTest, BreaksAsHighAsPossible) { |
| verifyFormat( |
| "void f() {\n" |
| " if ((aaaaaaaaaaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaaaaaaaaaaaaa) ||\n" |
| " (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb && bbbbbbbbbbbbbbbbbbbbbbbbbb))\n" |
| " f();\n" |
| "}"); |
| verifyFormat("if (Intervals[i].getRange().getFirst() <\n" |
| " Intervals[i - 1].getRange().getLast()) {\n}"); |
| } |
| |
| TEST_F(FormatTest, BreaksFunctionDeclarations) { |
| // Principially, we break function declarations in a certain order: |
| // 1) break amongst arguments. |
| verifyFormat("Aaaaaaaaaaaaaa bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccc,\n" |
| " Cccccccccccccc cccccccccccccc);"); |
| verifyFormat("template <class TemplateIt>\n" |
| "SomeReturnType SomeFunction(TemplateIt begin, TemplateIt end,\n" |
| " TemplateIt *stop) {}"); |
| |
| // 2) break after return type. |
| verifyFormat( |
| "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccccccccccccccc);", |
| getGoogleStyle()); |
| |
| // 3) break after (. |
| verifyFormat( |
| "Aaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbb(\n" |
| " Cccccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccc);", |
| getGoogleStyle()); |
| |
| // 4) break before after nested name specifiers. |
| verifyFormat( |
| "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "SomeClasssssssssssssssssssssssssssssssssssssss::\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc);", |
| getGoogleStyle()); |
| |
| // However, there are exceptions, if a sufficient amount of lines can be |
| // saved. |
| // FIXME: The precise cut-offs wrt. the number of saved lines might need some |
| // more adjusting. |
| verifyFormat("Aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb(Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc);"); |
| verifyFormat( |
| "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "bbbbbbbbbbb(Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);", |
| getGoogleStyle()); |
| verifyFormat( |
| "Aaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc);"); |
| verifyFormat("Aaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n" |
| " Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);"); |
| |
| // Break after multi-line parameters. |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbb bbbb);"); |
| verifyFormat("void SomeLoooooooooooongFunction(\n" |
| " std::unique_ptr<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbb);"); |
| |
| // Treat overloaded operators like other functions. |
| verifyFormat("SomeLoooooooooooooooooooooooooogType\n" |
| "operator>(const SomeLoooooooooooooooooooooooooogType &other);"); |
| verifyFormat("SomeLoooooooooooooooooooooooooogType\n" |
| "operator>>(const SomeLooooooooooooooooooooooooogType &other);"); |
| verifyFormat("SomeLoooooooooooooooooooooooooogType\n" |
| "operator<<(const SomeLooooooooooooooooooooooooogType &other);"); |
| verifyGoogleFormat( |
| "SomeLoooooooooooooooooooooooooooooogType operator>>(\n" |
| " const SomeLooooooooogType &a, const SomeLooooooooogType &b);"); |
| verifyGoogleFormat( |
| "SomeLoooooooooooooooooooooooooooooogType operator<<(\n" |
| " const SomeLooooooooogType &a, const SomeLooooooooogType &b);"); |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 1);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaa\n" |
| "aaaaaaaaaaaaaaaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaa = 1);"); |
| verifyGoogleFormat( |
| "typename aaaaaaaaaa<aaaaaa>::aaaaaaaaaaa\n" |
| "aaaaaaaaaa<aaaaaa>::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " bool *aaaaaaaaaaaaaaaaaa, bool *aa) {}"); |
| verifyGoogleFormat("template <typename T>\n" |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "aaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa);"); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa* const aaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat("void aaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, DontBreakBeforeQualifiedOperator) { |
| // Regression test for https://bugs.llvm.org/show_bug.cgi?id=40516: |
| // Prefer keeping `::` followed by `operator` together. |
| EXPECT_EQ("const aaaa::bbbbbbb &\n" |
| "ccccccccc::operator++() {\n" |
| " stuff();\n" |
| "}", |
| format("const aaaa::bbbbbbb\n" |
| "&ccccccccc::operator++() { stuff(); }", |
| getLLVMStyleWithColumns(40))); |
| } |
| |
| TEST_F(FormatTest, TrailingReturnType) { |
| verifyFormat("auto foo() -> int;\n"); |
| // correct trailing return type spacing |
| verifyFormat("auto operator->() -> int;\n"); |
| verifyFormat("auto operator++(int) -> int;\n"); |
| |
| verifyFormat("struct S {\n" |
| " auto bar() const -> int;\n" |
| "};"); |
| verifyFormat("template <size_t Order, typename T>\n" |
| "auto load_img(const std::string &filename)\n" |
| " -> alias::tensor<Order, T, mem::tag::cpu> {}"); |
| verifyFormat("auto SomeFunction(A aaaaaaaaaaaaaaaaaaaaa) const\n" |
| " -> decltype(f(aaaaaaaaaaaaaaaaaaaaa)) {}"); |
| verifyFormat("auto doSomething(Aaaaaa *aaaaaa) -> decltype(aaaaaa->f()) {}"); |
| verifyFormat("template <typename T>\n" |
| "auto aaaaaaaaaaaaaaaaaaaaaa(T t)\n" |
| " -> decltype(eaaaaaaaaaaaaaaa<T>(t.a).aaaaaaaa());"); |
| |
| // Not trailing return types. |
| verifyFormat("void f() { auto a = b->c(); }"); |
| verifyFormat("auto a = p->foo();"); |
| verifyFormat("int a = p->foo();"); |
| verifyFormat("auto lmbd = [] NOEXCEPT -> int { return 0; };"); |
| } |
| |
| TEST_F(FormatTest, DeductionGuides) { |
| verifyFormat("template <class T> A(const T &, const T &) -> A<T &>;"); |
| verifyFormat("template <class T> explicit A(T &, T &&) -> A<T>;"); |
| verifyFormat("template <class... Ts> S(Ts...) -> S<Ts...>;"); |
| verifyFormat( |
| "template <class... T>\n" |
| "array(T &&...t) -> array<std::common_type_t<T...>, sizeof...(T)>;"); |
| verifyFormat("template <class T> A() -> A<decltype(p->foo<3>())>;"); |
| verifyFormat("template <class T> A() -> A<decltype(foo<traits<1>>)>;"); |
| verifyFormat("template <class T> A() -> A<sizeof(p->foo<1>)>;"); |
| verifyFormat("template <class T> A() -> A<(3 < 2)>;"); |
| verifyFormat("template <class T> A() -> A<((3) < (2))>;"); |
| verifyFormat("template <class T> x() -> x<1>;"); |
| verifyFormat("template <class T> explicit x(T &) -> x<1>;"); |
| |
| // Ensure not deduction guides. |
| verifyFormat("c()->f<int>();"); |
| verifyFormat("x()->foo<1>;"); |
| verifyFormat("x = p->foo<3>();"); |
| verifyFormat("x()->x<1>();"); |
| verifyFormat("x()->x<1>;"); |
| } |
| |
| TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { |
| // Avoid breaking before trailing 'const' or other trailing annotations, if |
| // they are not function-like. |
| FormatStyle Style = getGoogleStyleWithColumns(47); |
| verifyFormat("void someLongFunction(\n" |
| " int someLoooooooooooooongParameter) const {\n}", |
| getLLVMStyleWithColumns(47)); |
| verifyFormat("LoooooongReturnType\n" |
| "someLoooooooongFunction() const {}", |
| getLLVMStyleWithColumns(47)); |
| verifyFormat("LoooooongReturnType someLoooooooongFunction()\n" |
| " const {}", |
| Style); |
| verifyFormat("void SomeFunction(aaaaa aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaa aaaaaaaaaaaaaaaaaaaa) OVERRIDE;"); |
| verifyFormat("void SomeFunction(aaaaa aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaa aaaaaaaaaaaaaaaaaaaa) OVERRIDE FINAL;"); |
| verifyFormat("void SomeFunction(aaaaa aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaa aaaaaaaaaaaaaaaaaaaa) override final;"); |
| verifyFormat("virtual void aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa aaaa,\n" |
| " aaaaaaaaaaa aaaaa) const override;"); |
| verifyGoogleFormat( |
| "virtual void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " const override;"); |
| |
| // Even if the first parameter has to be wrapped. |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) const {}", |
| getLLVMStyleWithColumns(46)); |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) const {}", |
| Style); |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) override {}", |
| Style); |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) OVERRIDE {}", |
| Style); |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) final {}", |
| Style); |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) FINAL {}", |
| Style); |
| verifyFormat("void someLongFunction(\n" |
| " int parameter) const override {}", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Allman; |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) const\n" |
| "{\n" |
| "}", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths; |
| verifyFormat("void someLongFunction(\n" |
| " int someLongParameter) const\n" |
| " {\n" |
| " }", |
| Style); |
| |
| // Unless these are unknown annotations. |
| verifyFormat("void SomeFunction(aaaaaaaaaa aaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " LONG_AND_UGLY_ANNOTATION;"); |
| |
| // Breaking before function-like trailing annotations is fine to keep them |
| // close to their arguments. |
| verifyFormat("void aaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " LOCKS_EXCLUDED(aaaaaaaaaaaaa);"); |
| verifyFormat("void aaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) const\n" |
| " LOCKS_EXCLUDED(aaaaaaaaaaaaa);"); |
| verifyFormat("void aaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) const\n" |
| " LOCKS_EXCLUDED(aaaaaaaaaaaaa) {}"); |
| verifyGoogleFormat("void aaaaaaaaaaaaaa(aaaaaaaa aaa) override\n" |
| " AAAAAAAAAAAAAAAAAAAAAAAA(aaaaaaaaaaaaaaa);"); |
| verifyFormat("SomeFunction([](int i) LOCKS_EXCLUDED(a) {});"); |
| |
| verifyFormat( |
| "void aaaaaaaaaaaaaaaaaa()\n" |
| " __attribute__((aaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " __attribute__((unused));"); |
| verifyGoogleFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " GUARDED_BY(aaaaaaaaaaaa);"); |
| verifyGoogleFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " GUARDED_BY(aaaaaaaaaaaa);"); |
| verifyGoogleFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n" |
| " aaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyGoogleFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| } |
| |
| TEST_F(FormatTest, FunctionAnnotations) { |
| verifyFormat("DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" |
| "int OldFunction(const string ¶meter) {}"); |
| verifyFormat("DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" |
| "string OldFunction(const string ¶meter) {}"); |
| verifyFormat("template <typename T>\n" |
| "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n" |
| "string OldFunction(const string ¶meter) {}"); |
| |
| // Not function annotations. |
| verifyFormat("ASSERT(\"aaaaa\") << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); |
| verifyFormat("TEST_F(ThisIsATestFixtureeeeeeeeeeeee,\n" |
| " ThisIsATestWithAReallyReallyReallyReallyLongName) {}"); |
| verifyFormat("MACRO(abc).function() // wrap\n" |
| " << abc;"); |
| verifyFormat("MACRO(abc)->function() // wrap\n" |
| " << abc;"); |
| verifyFormat("MACRO(abc)::function() // wrap\n" |
| " << abc;"); |
| } |
| |
| TEST_F(FormatTest, BreaksDesireably) { |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" |
| " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa) ||\n" |
| " aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa)) {\n}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" |
| "}"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| |
| verifyFormat( |
| "aaaaaaaa(aaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n" |
| " aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)));"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat( |
| "void f() {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| "}"); |
| verifyFormat( |
| "aaaaaa(new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| verifyFormat( |
| "aaaaaa(aaa, new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| verifyFormat( |
| "aaaaaa(aaa,\n" |
| " new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaa);"); |
| verifyFormat("aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| // Indent consistently independent of call expression and unary operator. |
| verifyFormat("aaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" |
| " dddddddddddddddddddddddddddddd));"); |
| verifyFormat("aaaaaaaaaaa(!bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" |
| " dddddddddddddddddddddddddddddd));"); |
| verifyFormat("aaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccc(\n" |
| " dddddddddddddddddddddddddddddd));"); |
| |
| // This test case breaks on an incorrect memoization, i.e. an optimization not |
| // taking into account the StopAt value. |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaa(aaaaaaaaa) || aaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("{\n {\n {\n" |
| " Annotation.SpaceRequiredBefore =\n" |
| " Line.Tokens[i - 1].Tok.isNot(tok::l_paren) &&\n" |
| " Line.Tokens[i - 1].Tok.isNot(tok::l_square);\n" |
| " }\n }\n}"); |
| |
| // Break on an outer level if there was a break on an inner level. |
| EXPECT_EQ("f(g(h(a, // comment\n" |
| " b, c),\n" |
| " d, e),\n" |
| " x, y);", |
| format("f(g(h(a, // comment\n" |
| " b, c), d, e), x, y);")); |
| |
| // Prefer breaking similar line breaks. |
| verifyFormat( |
| "const int kTrackingOptions = NSTrackingMouseMoved |\n" |
| " NSTrackingMouseEnteredAndExited |\n" |
| " NSTrackingActiveAlways;"); |
| } |
| |
| TEST_F(FormatTest, FormatsDeclarationsOnePerLine) { |
| FormatStyle NoBinPacking = getGoogleStyle(); |
| NoBinPacking.BinPackParameters = false; |
| NoBinPacking.BinPackArguments = true; |
| verifyFormat("void f() {\n" |
| " f(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| "}", |
| NoBinPacking); |
| verifyFormat("void f(int aaaaaaaaaaaaaaaaaaaa,\n" |
| " int aaaaaaaaaaaaaaaaaaaa,\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| NoBinPacking); |
| |
| NoBinPacking.AllowAllParametersOfDeclarationOnNextLine = false; |
| verifyFormat("void aaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " vector<int> bbbbbbbbbbbbbbb);", |
| NoBinPacking); |
| // FIXME: This behavior difference is probably not wanted. However, currently |
| // we cannot distinguish BreakBeforeParameter being set because of the wrapped |
| // template arguments from BreakBeforeParameter being set because of the |
| // one-per-line formatting. |
| verifyFormat( |
| "void fffffffffff(aaaaaaaaaaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaa> aaaaaaaaaa);", |
| NoBinPacking); |
| verifyFormat( |
| "void fffffffffff(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaa>\n" |
| " aaaaaaaaaa);"); |
| } |
| |
| TEST_F(FormatTest, FormatsOneParameterPerLineIfNecessary) { |
| FormatStyle NoBinPacking = getGoogleStyle(); |
| NoBinPacking.BinPackParameters = false; |
| NoBinPacking.BinPackArguments = false; |
| verifyFormat("f(aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaa);", |
| NoBinPacking); |
| verifyFormat("aaaaaaa(aaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa));", |
| NoBinPacking); |
| verifyFormat( |
| "aaaaaaaa(aaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n" |
| " aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)));", |
| NoBinPacking); |
| verifyFormat("aaaaaaaaaaaaaaa(aaaaaaaaa, aaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaaaaa();", |
| NoBinPacking); |
| verifyFormat("void f() {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaa, aaaaaaaaaa, aaaaaaaaaa, aaaaaaaaaaa);\n" |
| "}", |
| NoBinPacking); |
| |
| verifyFormat( |
| "aaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaa);", |
| NoBinPacking); |
| verifyFormat( |
| "somefunction(someotherFunction(ddddddddddddddddddddddddddddddddddd,\n" |
| " ddddddddddddddddddddddddddddd),\n" |
| " test);", |
| NoBinPacking); |
| |
| verifyFormat("std::vector<aaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa>\n" |
| " aaaaaaaaaaaaaaaaaa;", |
| NoBinPacking); |
| verifyFormat("a(\"a\"\n" |
| " \"a\",\n" |
| " a);"); |
| |
| NoBinPacking.AllowAllParametersOfDeclarationOnNextLine = false; |
| verifyFormat("void aaaaaaaaaa(aaaaaaaaa,\n" |
| " aaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| NoBinPacking); |
| verifyFormat( |
| "void f() {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaa, aaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaa();\n" |
| "}", |
| NoBinPacking); |
| verifyFormat( |
| "template <class SomeType, class SomeOtherType>\n" |
| "SomeType SomeFunction(SomeType Type, SomeOtherType OtherType) {}", |
| NoBinPacking); |
| } |
| |
| TEST_F(FormatTest, AdaptiveOnePerLineFormatting) { |
| FormatStyle Style = getLLVMStyleWithColumns(15); |
| Style.ExperimentalAutoDetectBinPacking = true; |
| EXPECT_EQ("aaa(aaaa,\n" |
| " aaaa,\n" |
| " aaaa);\n" |
| "aaa(aaaa,\n" |
| " aaaa,\n" |
| " aaaa);", |
| format("aaa(aaaa,\n" // one-per-line |
| " aaaa,\n" |
| " aaaa );\n" |
| "aaa(aaaa, aaaa, aaaa);", // inconclusive |
| Style)); |
| EXPECT_EQ("aaa(aaaa, aaaa,\n" |
| " aaaa);\n" |
| "aaa(aaaa, aaaa,\n" |
| " aaaa);", |
| format("aaa(aaaa, aaaa,\n" // bin-packed |
| " aaaa );\n" |
| "aaa(aaaa, aaaa, aaaa);", // inconclusive |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsBuilderPattern) { |
| verifyFormat("return llvm::StringSwitch<Reference::Kind>(name)\n" |
| " .StartsWith(\".eh_frame_hdr\", ORDER_EH_FRAMEHDR)\n" |
| " .StartsWith(\".eh_frame\", ORDER_EH_FRAME)\n" |
| " .StartsWith(\".init\", ORDER_INIT)\n" |
| " .StartsWith(\".fini\", ORDER_FINI)\n" |
| " .StartsWith(\".hash\", ORDER_HASH)\n" |
| " .Default(ORDER_TEXT);\n"); |
| |
| verifyFormat("return aaaaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa() <\n" |
| " aaaaaaaaaaaaaaa->aaaaa().aaaaaaaaaaaaa().aaaaaa();"); |
| verifyFormat("aaaaaaa->aaaaaaa\n" |
| " ->aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " ->aaaaaaaa(aaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaa->aaaaaaa\n" |
| " ->aaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " ->aaaaaaaa(aaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaa()->aaaaaa(bbbbb)->aaaaaaaaaaaaaaaaaaa( // break\n" |
| " aaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaa *aaaaaaaaa =\n" |
| " aaaaaa->aaaaaaaaaaaa()\n" |
| " ->aaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " ->aaaaaaaaaaaaaaaaa();"); |
| verifyGoogleFormat( |
| "void f() {\n" |
| " someo->Add((new util::filetools::Handler(dir))\n" |
| " ->OnEvent1(NewPermanentCallback(\n" |
| " this, &HandlerHolderClass::EventHandlerCBA))\n" |
| " ->OnEvent2(NewPermanentCallback(\n" |
| " this, &HandlerHolderClass::EventHandlerCBB))\n" |
| " ->OnEvent3(NewPermanentCallback(\n" |
| " this, &HandlerHolderClass::EventHandlerCBC))\n" |
| " ->OnEvent5(NewPermanentCallback(\n" |
| " this, &HandlerHolderClass::EventHandlerCBD))\n" |
| " ->OnEvent6(NewPermanentCallback(\n" |
| " this, &HandlerHolderClass::EventHandlerCBE)));\n" |
| "}"); |
| |
| verifyFormat( |
| "aaaaaaaaaaa().aaaaaaaaaaa().aaaaaaaaaaa().aaaaaaaaaaa().aaaaaaaaaaa();"); |
| verifyFormat("aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa();"); |
| verifyFormat("aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa();"); |
| verifyFormat("aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaa();"); |
| verifyFormat("aaaaaaaaaaaaa->aaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " ->aaaaaaaaaaaaaae(0)\n" |
| " ->aaaaaaaaaaaaaaa();"); |
| |
| // Don't linewrap after very short segments. |
| verifyFormat("a().aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("aa().aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("aaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " .has<bbbbbbbbbbbbbbbbbbbbb>();"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaa()\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>();"); |
| |
| // Prefer not to break after empty parentheses. |
| verifyFormat("FirstToken->WhitespaceRange.getBegin().getLocWithOffset(\n" |
| " First->LastNewlineOffset);"); |
| |
| // Prefer not to create "hanging" indents. |
| verifyFormat( |
| "return !soooooooooooooome_map\n" |
| " .insert(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .second;"); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa)\n" |
| " .aaaa(aaaaaaaaaaaaaa);"); |
| // No hanging indent here. |
| verifyFormat("aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaa.aaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaa().aaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("aaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| getLLVMStyleWithColumns(59)); |
| verifyFormat("aaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| // Dont break if only closing statements before member call |
| verifyFormat("test() {\n" |
| " ([]() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " }).foo();\n" |
| "}"); |
| verifyFormat("test() {\n" |
| " (\n" |
| " []() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " },\n" |
| " foo, bar)\n" |
| " .foo();\n" |
| "}"); |
| verifyFormat("test() {\n" |
| " ([]() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " })\n" |
| " .foo()\n" |
| " .bar();\n" |
| "}"); |
| verifyFormat("test() {\n" |
| " ([]() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " })\n" |
| " .foo(\"aaaaaaaaaaaaaaaaa\"\n" |
| " \"bbbb\");\n" |
| "}", |
| getLLVMStyleWithColumns(30)); |
| } |
| |
| TEST_F(FormatTest, BreaksAccordingToOperatorPrecedence) { |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb && ccccccccccccccccccccccccc) {\n}"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaa or\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb and cccccccccccccccccccccccc) {\n}"); |
| |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa && bbbbbbbbbbbbbbbbbbbbbbbbb ||\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbbb or\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb ||\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb or\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| |
| verifyFormat( |
| "if ((aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb) &&\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| verifyFormat( |
| "if ((aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb) and\n" |
| " ccccccccccccccccccccccccc) {\n}"); |
| |
| verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ||\n" |
| " bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB ||\n" |
| " cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC ||\n" |
| " dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;"); |
| verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA or\n" |
| " bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB or\n" |
| " cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC or\n" |
| " dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;"); |
| |
| verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa ||\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) &&\n" |
| " aaaaaaaaaaaaaaa != aa) {\n}"); |
| verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa or\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) and\n" |
| " aaaaaaaaaaaaaaa != aa) {\n}"); |
| } |
| |
| TEST_F(FormatTest, BreaksAfterAssignments) { |
| verifyFormat( |
| "unsigned Cost =\n" |
| " TTI.getMemoryOpCost(I->getOpcode(), VectorTy, SI->getAlignment(),\n" |
| " SI->getPointerAddressSpaceee());\n"); |
| verifyFormat( |
| "CharSourceRange LineRange = CharSourceRange::getTokenRange(\n" |
| " Line.Tokens.front().Tok.getLo(), Line.Tokens.back().Tok.getLoc());"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaa aaaa = aaaaaaaaaaaaaa(0).aaaa().aaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaa::aaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("unsigned OriginalStartColumn =\n" |
| " SourceMgr.getSpellingColumnNumber(\n" |
| " Current.FormatTok.getStartOfNonWhitespace()) -\n" |
| " 1;"); |
| } |
| |
| TEST_F(FormatTest, ConfigurableBreakAssignmentPenalty) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccccccc;", |
| Style); |
| |
| Style.PenaltyBreakAssignment = 20; |
| verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbb +\n" |
| " cccccccccccccccccccccccccc;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AlignsAfterAssignments) { |
| verifyFormat( |
| "int Result = aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "Result += aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "Result >>= aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "int Result = (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "double LooooooooooooooooooooooooongResult = aaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa;"); |
| } |
| |
| TEST_F(FormatTest, AlignsAfterReturn) { |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "return (aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >=\n" |
| " aaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat( |
| "return (aaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >=\n" |
| " aaaaaaaaaaaaaaaaaaaaaa());"); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) &&\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("return\n" |
| " // true if code is one of a or b.\n" |
| " code == a || code == b;"); |
| } |
| |
| TEST_F(FormatTest, AlignsAfterOpenBracket) { |
| verifyFormat( |
| "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaa aaaaaaaa,\n" |
| " aaaaaaaaa aaaaaaa) {}"); |
| verifyFormat( |
| "SomeLongVariableName->someVeryLongFunctionName(aaaaaaaaaaa aaaaaaaaa,\n" |
| " aaaaaaaaaaa aaaaaaaaa);"); |
| verifyFormat( |
| "SomeLongVariableName->someFunction(foooooooo(aaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaa));"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaa aaaaaaaa, aaaaaaaaa aaaaaaa) {}", |
| Style); |
| verifyFormat("SomeLongVariableName->someVeryLongFunctionName(\n" |
| " aaaaaaaaaaa aaaaaaaaa, aaaaaaaaaaa aaaaaaaaa);", |
| Style); |
| verifyFormat("SomeLongVariableName->someFunction(\n" |
| " foooooooo(aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaa));", |
| Style); |
| verifyFormat( |
| "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaa aaaaaaaa,\n" |
| " aaaaaaaaa aaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat( |
| "SomeLongVariableName->someVeryLongFunctionName(aaaaaaaaaaa aaaaaaaaa,\n" |
| " aaaaaaaaaaa aaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "SomeLongVariableName->someFunction(foooooooo(aaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));", |
| Style); |
| |
| verifyFormat("bbbbbbbbbbbb(aaaaaaaaaaaaaaaaaaaaaaaa, //\n" |
| " ccccccc(aaaaaaaaaaaaaaaaa, //\n" |
| " b));", |
| Style); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| Style.BinPackArguments = false; |
| Style.BinPackParameters = false; |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaa aaaaaaaa,\n" |
| " aaaaaaaaa aaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| verifyFormat("SomeLongVariableName->someVeryLongFunctionName(\n" |
| " aaaaaaaaaaa aaaaaaaaa,\n" |
| " aaaaaaaaaaa aaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("SomeLongVariableName->someFunction(foooooooo(\n" |
| " aaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)));", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaa.aaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)));", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)),\n" |
| " aaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)) &&\n" |
| " aaaaaaaaaaaaaaaa);", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ParenthesesAndOperandAlignment) { |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " bbbbbbbbbbbbbbbbbbbbbb);", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_Align; |
| Style.AlignOperands = FormatStyle::OAS_DontAlign; |
| verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " bbbbbbbbbbbbbbbbbbbbbb);", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| Style.AlignOperands = FormatStyle::OAS_Align; |
| verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " bbbbbbbbbbbbbbbbbbbbbb);", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| Style.AlignOperands = FormatStyle::OAS_DontAlign; |
| verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " bbbbbbbbbbbbbbbbbbbbbb);", |
| Style); |
| } |
| |
| TEST_F(FormatTest, BreaksConditionalExpressions) { |
| verifyFormat( |
| "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaa(aaaaaaaaaa, aaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaa(aaaaaaaaa, aaaaaaaaa,\n" |
| " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa ? aaaa(aaaaaa)\n" |
| " : aaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa);"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa ?: aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ?: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaa;"); |
| verifyFormat("f(aaaaaaaaaaaaaaaa == // force break\n" |
| " aaaaaaaaa\n" |
| " ? b\n" |
| " : c);"); |
| verifyFormat("return aaaa == bbbb\n" |
| " // comment\n" |
| " ? aaaa\n" |
| " : bbbb;"); |
| verifyFormat("unsigned Indent =\n" |
| " format(TheLine.First,\n" |
| " IndentForLevel[TheLine.Level] >= 0\n" |
| " ? IndentForLevel[TheLine.Level]\n" |
| " : TheLine * 2,\n" |
| " TheLine.InPPDirective, PreviousEndOfLineColumn);", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("bool aaaaaa = aaaaaaaaaaaaa //\n" |
| " ? aaaaaaaaaaaaaaa\n" |
| " : bbbbbbbbbbbbbbb //\n" |
| " ? ccccccccccccccc\n" |
| " : ddddddddddddddd;"); |
| verifyFormat("bool aaaaaa = aaaaaaaaaaaaa //\n" |
| " ? aaaaaaaaaaaaaaa\n" |
| " : (bbbbbbbbbbbbbbb //\n" |
| " ? ccccccccccccccc\n" |
| " : ddddddddddddddd);"); |
| verifyFormat( |
| "int aaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaa +\n" |
| " aaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaa;"); |
| verifyFormat( |
| "aaaaaa = aaaaaaaaaaaa ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackArguments = false; |
| verifyFormat( |
| "void f() {\n" |
| " g(aaa,\n" |
| " aaaaaaaaaa == aaaaaaaaaa ? aaaa : aaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaa\n" |
| " : aaaaaaaaaaaaaaa);\n" |
| "}", |
| NoBinPacking); |
| verifyFormat( |
| "void f() {\n" |
| " g(aaa,\n" |
| " aaaaaaaaaa == aaaaaaaaaa ? aaaa : aaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ?: aaaaaaaaaaaaaaa);\n" |
| "}", |
| NoBinPacking); |
| |
| verifyFormat("SomeFunction(aaaaaaaaaaaaaaaaa,\n" |
| " // comment.\n" |
| " ccccccccccccccccccccccccccccccccccccccc\n" |
| " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " : bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);"); |
| |
| // Assignments in conditional expressions. Apparently not uncommon :-(. |
| verifyFormat("return a != b\n" |
| " // comment\n" |
| " ? a = b\n" |
| " : a = b;"); |
| verifyFormat("return a != b\n" |
| " // comment\n" |
| " ? a = a != b\n" |
| " // comment\n" |
| " ? a = b\n" |
| " : a\n" |
| " : a;\n"); |
| verifyFormat("return a != b\n" |
| " // comment\n" |
| " ? a\n" |
| " : a = a != b\n" |
| " // comment\n" |
| " ? a = b\n" |
| " : a;"); |
| |
| // Chained conditionals |
| FormatStyle Style = getLLVMStyleWithColumns(70); |
| Style.AlignOperands = FormatStyle::OAS_Align; |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 222222\n" |
| " : 333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : cccccccccccccc ? 3333333333333333\n" |
| " : 4444444444444444;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? (aaa ? bbb : ccc)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : (aaa ? bbb : ccc);", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccccc)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccccc)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? a = (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : dddddddddddddddddd)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : dddddddddddddddddd)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : dddddddddddddddddd)\n", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? 1111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccccc);", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : ccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : ccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee)\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccccc\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee\n" |
| " : bbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaa\n" |
| " ? (aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee)\n" |
| " : bbbbbbbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb\n" |
| " : cccccccccccccccc ? dddddddddddddddddd\n" |
| " : eeeeeeeeeeeeeeeeee\n" |
| " : bbbbbbbbbbbbbbbbbbbbbbb ? 2222222222222222\n" |
| " : 3333333333333333;", |
| Style); |
| |
| Style.AlignOperands = FormatStyle::OAS_DontAlign; |
| Style.BreakBeforeTernaryOperators = false; |
| // FIXME: Aligning the question marks is weird given DontAlign. |
| // Consider disabling this alignment in this case. Also check whether this |
| // will render the adjustment from https://reviews.llvm.org/D82199 |
| // unnecessary. |
| verifyFormat("int x = aaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa :\n" |
| " bbbb ? cccccccccccccccccc :\n" |
| " ddddd;\n", |
| Style); |
| |
| EXPECT_EQ( |
| "MMMMMMMMMMMMMMMMMMMMMMMMMMM = A ?\n" |
| " /*\n" |
| " */\n" |
| " function() {\n" |
| " try {\n" |
| " return JJJJJJJJJJJJJJ(\n" |
| " pppppppppppppppppppppppppppppppppppppppppppppppppp);\n" |
| " }\n" |
| " } :\n" |
| " function() {};", |
| format( |
| "MMMMMMMMMMMMMMMMMMMMMMMMMMM = A ?\n" |
| " /*\n" |
| " */\n" |
| " function() {\n" |
| " try {\n" |
| " return JJJJJJJJJJJJJJ(\n" |
| " pppppppppppppppppppppppppppppppppppppppppppppppppp);\n" |
| " }\n" |
| " } :\n" |
| " function() {};", |
| getGoogleStyle(FormatStyle::LK_JavaScript))); |
| } |
| |
| TEST_F(FormatTest, BreaksConditionalExpressionsAfterOperator) { |
| FormatStyle Style = getLLVMStyleWithColumns(70); |
| Style.BreakBeforeTernaryOperators = false; |
| verifyFormat( |
| "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaa(aaaaaaaaaa, aaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("aaaa(aaaaaaaa, aaaaaaaaaa,\n" |
| " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa ? aaaa(aaaaaa) :\n" |
| " aaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa);", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaa ?: aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("aaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?:\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| Style); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| Style); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaa :\n" |
| " aaaaaaaaaaaaaaa;", |
| Style); |
| verifyFormat("f(aaaaaaaaaaaaaaaa == // force break\n" |
| " aaaaaaaaa ?\n" |
| " b :\n" |
| " c);", |
| Style); |
| verifyFormat("unsigned Indent =\n" |
| " format(TheLine.First,\n" |
| " IndentForLevel[TheLine.Level] >= 0 ?\n" |
| " IndentForLevel[TheLine.Level] :\n" |
| " TheLine * 2,\n" |
| " TheLine.InPPDirective, PreviousEndOfLineColumn);", |
| Style); |
| verifyFormat("bool aaaaaa = aaaaaaaaaaaaa ? //\n" |
| " aaaaaaaaaaaaaaa :\n" |
| " bbbbbbbbbbbbbbb ? //\n" |
| " ccccccccccccccc :\n" |
| " ddddddddddddddd;", |
| Style); |
| verifyFormat("bool aaaaaa = aaaaaaaaaaaaa ? //\n" |
| " aaaaaaaaaaaaaaa :\n" |
| " (bbbbbbbbbbbbbbb ? //\n" |
| " ccccccccccccccc :\n" |
| " ddddddddddddddd);", |
| Style); |
| verifyFormat("int i = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " /*bbbbbbbbbbbbbbb=*/bbbbbbbbbbbbbbbbbbbbbbbbb :\n" |
| " ccccccccccccccccccccccccccc;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaa :\n" |
| " bbbbbbbbbbbbbbb + cccccccccccccccc;", |
| Style); |
| |
| // Chained conditionals |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 222222 :\n" |
| " 333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " cccccccccccccccc ? 3333333333333333 :\n" |
| " 4444444444444444;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? (aaa ? bbb : ccc) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " (aaa ? bbb : ccc);", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? a = (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " dddddddddddddddddd) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " dddddddddddddddddd) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " a + (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " dddddddddddddddddd)\n", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? 1111111111111111 :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc);", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " ccccccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " ccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? (aaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " ccccccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee) :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat( |
| "return aaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee :\n" |
| " bbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaa ?\n" |
| " (aaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee) :\n" |
| " bbbbbbbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaa ?\n" |
| " aaaaaaaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb :\n" |
| " cccccccccccccccccccc ? dddddddddddddddddd :\n" |
| " eeeeeeeeeeeeeeeeee :\n" |
| " bbbbbbbbbbbbbbbbbbbbb ? 2222222222222222 :\n" |
| " 3333333333333333;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, DeclarationsOfMultipleVariables) { |
| verifyFormat("bool aaaaaaaaaaaaaaaaa = aaaaaa->aaaaaaaaaaaaaaaaa(),\n" |
| " aaaaaaaaaaa = aaaaaa->aaaaaaaaaaa();"); |
| verifyFormat("bool a = true, b = false;"); |
| |
| verifyFormat("bool aaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa),\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbb =\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbbbbbbbbbbb);"); |
| verifyFormat( |
| "bool aaaaaaaaaaaaaaaaaaaaa =\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbb && cccccccccccccccccccccccccccc,\n" |
| " d = e && f;"); |
| verifyFormat("aaaaaaaaa a = aaaaaaaaaaaaaaaaaaaa, b = bbbbbbbbbbbbbbbbbbbb,\n" |
| " c = cccccccccccccccccccc, d = dddddddddddddddddddd;"); |
| verifyFormat("aaaaaaaaa *a = aaaaaaaaaaaaaaaaaaa, *b = bbbbbbbbbbbbbbbbbbb,\n" |
| " *c = ccccccccccccccccccc, *d = ddddddddddddddddddd;"); |
| verifyFormat("aaaaaaaaa ***a = aaaaaaaaaaaaaaaaaaa, ***b = bbbbbbbbbbbbbbb,\n" |
| " ***c = ccccccccccccccccccc, ***d = ddddddddddddddd;"); |
| |
| FormatStyle Style = getGoogleStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| Style.DerivePointerAlignment = false; |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaa,\n" |
| " *b = bbbbbbbbbbbbbbbbbbb;", |
| Style); |
| verifyFormat("aaaaaaaaa *a = aaaaaaaaaaaaaaaaaaa, *b = bbbbbbbbbbbbbbbbbbb,\n" |
| " *b = bbbbbbbbbbbbbbbbbbb, *d = ddddddddddddddddddd;", |
| Style); |
| verifyFormat("vector<int*> a, b;", Style); |
| verifyFormat("for (int *p, *q; p != q; p = p->next) {\n}", Style); |
| verifyFormat("/*comment*/ for (int *p, *q; p != q; p = p->next) {\n}", Style); |
| verifyFormat("if (int *p, *q; p != q) {\n p = p->next;\n}", Style); |
| verifyFormat("/*comment*/ if (int *p, *q; p != q) {\n p = p->next;\n}", |
| Style); |
| verifyFormat("switch (int *p, *q; p != q) {\n default:\n break;\n}", |
| Style); |
| verifyFormat( |
| "/*comment*/ switch (int *p, *q; p != q) {\n default:\n break;\n}", |
| Style); |
| |
| verifyFormat("if ([](int* p, int* q) {}()) {\n}", Style); |
| verifyFormat("for ([](int* p, int* q) {}();;) {\n}", Style); |
| verifyFormat("for (; [](int* p, int* q) {}();) {\n}", Style); |
| verifyFormat("for (;; [](int* p, int* q) {}()) {\n}", Style); |
| verifyFormat("switch ([](int* p, int* q) {}()) {\n default:\n break;\n}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ConditionalExpressionsInBrackets) { |
| verifyFormat("arr[foo ? bar : baz];"); |
| verifyFormat("f()[foo ? bar : baz];"); |
| verifyFormat("(a + b)[foo ? bar : baz];"); |
| verifyFormat("arr[foo ? (4 > 5 ? 4 : 5) : 5 < 5 ? 5 : 7];"); |
| } |
| |
| TEST_F(FormatTest, AlignsStringLiterals) { |
| verifyFormat("loooooooooooooooooooooooooongFunction(\"short literal \"\n" |
| " \"short literal\");"); |
| verifyFormat( |
| "looooooooooooooooooooooooongFunction(\n" |
| " \"short literal\"\n" |
| " \"looooooooooooooooooooooooooooooooooooooooooooooooong literal\");"); |
| verifyFormat("someFunction(\"Always break between multi-line\"\n" |
| " \" string literals\",\n" |
| " and, other, parameters);"); |
| EXPECT_EQ("fun + \"1243\" /* comment */\n" |
| " \"5678\";", |
| format("fun + \"1243\" /* comment */\n" |
| " \"5678\";", |
| getLLVMStyleWithColumns(28))); |
| EXPECT_EQ( |
| "aaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" |
| " \"aaaaaaaaaaaaaaaaaaaaa\"\n" |
| " \"aaaaaaaaaaaaaaaa\";", |
| format("aaaaaa =" |
| "\"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaa\" " |
| "\"aaaaaaaaaaaaaaaa\";")); |
| verifyFormat("a = a + \"a\"\n" |
| " \"a\"\n" |
| " \"a\";"); |
| verifyFormat("f(\"a\", \"b\"\n" |
| " \"c\");"); |
| |
| verifyFormat( |
| "#define LL_FORMAT \"ll\"\n" |
| "printf(\"aaaaa: %d, bbbbbb: %\" LL_FORMAT \"d, cccccccc: %\" LL_FORMAT\n" |
| " \"d, ddddddddd: %\" LL_FORMAT \"d\");"); |
| |
| verifyFormat("#define A(X) \\\n" |
| " \"aaaaa\" #X \"bbbbbb\" \\\n" |
| " \"ccccc\"", |
| getLLVMStyleWithColumns(23)); |
| verifyFormat("#define A \"def\"\n" |
| "f(\"abc\" A \"ghi\"\n" |
| " \"jkl\");"); |
| |
| verifyFormat("f(L\"a\"\n" |
| " L\"b\");"); |
| verifyFormat("#define A(X) \\\n" |
| " L\"aaaaa\" #X L\"bbbbbb\" \\\n" |
| " L\"ccccc\"", |
| getLLVMStyleWithColumns(25)); |
| |
| verifyFormat("f(@\"a\"\n" |
| " @\"b\");"); |
| verifyFormat("NSString s = @\"a\"\n" |
| " @\"b\"\n" |
| " @\"c\";"); |
| verifyFormat("NSString s = @\"a\"\n" |
| " \"b\"\n" |
| " \"c\";"); |
| } |
| |
| TEST_F(FormatTest, ReturnTypeBreakingStyle) { |
| FormatStyle Style = getLLVMStyle(); |
| // No declarations or definitions should be moved to own line. |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; |
| verifyFormat("class A {\n" |
| " int f() { return 1; }\n" |
| " int g();\n" |
| "};\n" |
| "int f() { return 1; }\n" |
| "int g();\n", |
| Style); |
| |
| // All declarations and definitions should have the return type moved to its |
| // own line. |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_All; |
| Style.TypenameMacros = {"LIST"}; |
| verifyFormat("SomeType\n" |
| "funcdecl(LIST(uint64_t));", |
| Style); |
| verifyFormat("class E {\n" |
| " int\n" |
| " f() {\n" |
| " return 1;\n" |
| " }\n" |
| " int\n" |
| " g();\n" |
| "};\n" |
| "int\n" |
| "f() {\n" |
| " return 1;\n" |
| "}\n" |
| "int\n" |
| "g();\n", |
| Style); |
| |
| // Top-level definitions, and no kinds of declarations should have the |
| // return type moved to its own line. |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevelDefinitions; |
| verifyFormat("class B {\n" |
| " int f() { return 1; }\n" |
| " int g();\n" |
| "};\n" |
| "int\n" |
| "f() {\n" |
| " return 1;\n" |
| "}\n" |
| "int g();\n", |
| Style); |
| |
| // Top-level definitions and declarations should have the return type moved |
| // to its own line. |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_TopLevel; |
| verifyFormat("class C {\n" |
| " int f() { return 1; }\n" |
| " int g();\n" |
| "};\n" |
| "int\n" |
| "f() {\n" |
| " return 1;\n" |
| "}\n" |
| "int\n" |
| "g();\n", |
| Style); |
| |
| // All definitions should have the return type moved to its own line, but no |
| // kinds of declarations. |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions; |
| verifyFormat("class D {\n" |
| " int\n" |
| " f() {\n" |
| " return 1;\n" |
| " }\n" |
| " int g();\n" |
| "};\n" |
| "int\n" |
| "f() {\n" |
| " return 1;\n" |
| "}\n" |
| "int g();\n", |
| Style); |
| verifyFormat("const char *\n" |
| "f(void) {\n" // Break here. |
| " return \"\";\n" |
| "}\n" |
| "const char *bar(void);\n", // No break here. |
| Style); |
| verifyFormat("template <class T>\n" |
| "T *\n" |
| "f(T &c) {\n" // Break here. |
| " return NULL;\n" |
| "}\n" |
| "template <class T> T *f(T &c);\n", // No break here. |
| Style); |
| verifyFormat("class C {\n" |
| " int\n" |
| " operator+() {\n" |
| " return 1;\n" |
| " }\n" |
| " int\n" |
| " operator()() {\n" |
| " return 1;\n" |
| " }\n" |
| "};\n", |
| Style); |
| verifyFormat("void\n" |
| "A::operator()() {}\n" |
| "void\n" |
| "A::operator>>() {}\n" |
| "void\n" |
| "A::operator+() {}\n" |
| "void\n" |
| "A::operator*() {}\n" |
| "void\n" |
| "A::operator->() {}\n" |
| "void\n" |
| "A::operator void *() {}\n" |
| "void\n" |
| "A::operator void &() {}\n" |
| "void\n" |
| "A::operator void &&() {}\n" |
| "void\n" |
| "A::operator char *() {}\n" |
| "void\n" |
| "A::operator[]() {}\n" |
| "void\n" |
| "A::operator!() {}\n" |
| "void\n" |
| "A::operator**() {}\n" |
| "void\n" |
| "A::operator<Foo> *() {}\n" |
| "void\n" |
| "A::operator<Foo> **() {}\n" |
| "void\n" |
| "A::operator<Foo> &() {}\n" |
| "void\n" |
| "A::operator void **() {}\n", |
| Style); |
| verifyFormat("constexpr auto\n" |
| "operator()() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator>>() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator+() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator*() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator->() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator++() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator void *() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator void **() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator void *() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator void &() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator void &&() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator char *() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator!() const -> reference {}\n" |
| "constexpr auto\n" |
| "operator[]() const -> reference {}\n", |
| Style); |
| verifyFormat("void *operator new(std::size_t s);", // No break here. |
| Style); |
| verifyFormat("void *\n" |
| "operator new(std::size_t s) {}", |
| Style); |
| verifyFormat("void *\n" |
| "operator delete[](void *ptr) {}", |
| Style); |
| Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; |
| verifyFormat("const char *\n" |
| "f(void)\n" // Break here. |
| "{\n" |
| " return \"\";\n" |
| "}\n" |
| "const char *bar(void);\n", // No break here. |
| Style); |
| verifyFormat("template <class T>\n" |
| "T *\n" // Problem here: no line break |
| "f(T &c)\n" // Break here. |
| "{\n" |
| " return NULL;\n" |
| "}\n" |
| "template <class T> T *f(T &c);\n", // No break here. |
| Style); |
| verifyFormat("int\n" |
| "foo(A<bool> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| verifyFormat("int\n" |
| "foo(A<8> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| verifyFormat("int\n" |
| "foo(A<B<bool>, 8> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| verifyFormat("int\n" |
| "foo(A<B<8>, bool> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| verifyFormat("int\n" |
| "foo(A<B<bool>, bool> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| verifyFormat("int\n" |
| "foo(A<B<8>, 8> a)\n" |
| "{\n" |
| " return a;\n" |
| "}\n", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| verifyFormat("int f(i);\n" // No break here. |
| "int\n" // Break here. |
| "f(i)\n" |
| "{\n" |
| " return i + 1;\n" |
| "}\n" |
| "int\n" // Break here. |
| "f(i)\n" |
| "{\n" |
| " return i + 1;\n" |
| "};", |
| Style); |
| verifyFormat("int f(a, b, c);\n" // No break here. |
| "int\n" // Break here. |
| "f(a, b, c)\n" // Break here. |
| "short a, b;\n" |
| "float c;\n" |
| "{\n" |
| " return a + b < c;\n" |
| "}\n" |
| "int\n" // Break here. |
| "f(a, b, c)\n" // Break here. |
| "short a, b;\n" |
| "float c;\n" |
| "{\n" |
| " return a + b < c;\n" |
| "};", |
| Style); |
| verifyFormat("byte *\n" // Break here. |
| "f(a)\n" // Break here. |
| "byte a[];\n" |
| "{\n" |
| " return a;\n" |
| "}", |
| Style); |
| verifyFormat("bool f(int a, int) override;\n" |
| "Bar g(int a, Bar) final;\n" |
| "Bar h(a, Bar) final;", |
| Style); |
| verifyFormat("int\n" |
| "f(a)", |
| Style); |
| verifyFormat("bool\n" |
| "f(size_t = 0, bool b = false)\n" |
| "{\n" |
| " return !b;\n" |
| "}", |
| Style); |
| |
| // The return breaking style doesn't affect: |
| // * function and object definitions with attribute-like macros |
| verifyFormat("Tttttttttttttttttttttttt ppppppppppppppp\n" |
| " ABSL_GUARDED_BY(mutex) = {};", |
| getGoogleStyleWithColumns(40)); |
| verifyFormat("Tttttttttttttttttttttttt ppppppppppppppp\n" |
| " ABSL_GUARDED_BY(mutex); // comment", |
| getGoogleStyleWithColumns(40)); |
| verifyFormat("Tttttttttttttttttttttttt ppppppppppppppp\n" |
| " ABSL_GUARDED_BY(mutex1)\n" |
| " ABSL_GUARDED_BY(mutex2);", |
| getGoogleStyleWithColumns(40)); |
| verifyFormat("Tttttt f(int a, int b)\n" |
| " ABSL_GUARDED_BY(mutex1)\n" |
| " ABSL_GUARDED_BY(mutex2);", |
| getGoogleStyleWithColumns(40)); |
| // * typedefs |
| verifyFormat("typedef ATTR(X) char x;", getGoogleStyle()); |
| |
| Style = getGNUStyle(); |
| |
| // Test for comments at the end of function declarations. |
| verifyFormat("void\n" |
| "foo (int a, /*abc*/ int b) // def\n" |
| "{\n" |
| "}\n", |
| Style); |
| |
| verifyFormat("void\n" |
| "foo (int a, /* abc */ int b) /* def */\n" |
| "{\n" |
| "}\n", |
| Style); |
| |
| // Definitions that should not break after return type |
| verifyFormat("void foo (int a, int b); // def\n", Style); |
| verifyFormat("void foo (int a, int b); /* def */\n", Style); |
| verifyFormat("void foo (int a, int b);\n", Style); |
| } |
| |
| TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { |
| FormatStyle NoBreak = getLLVMStyle(); |
| NoBreak.AlwaysBreakBeforeMultilineStrings = false; |
| FormatStyle Break = getLLVMStyle(); |
| Break.AlwaysBreakBeforeMultilineStrings = true; |
| verifyFormat("aaaa = \"bbbb\"\n" |
| " \"cccc\";", |
| NoBreak); |
| verifyFormat("aaaa =\n" |
| " \"bbbb\"\n" |
| " \"cccc\";", |
| Break); |
| verifyFormat("aaaa(\"bbbb\"\n" |
| " \"cccc\");", |
| NoBreak); |
| verifyFormat("aaaa(\n" |
| " \"bbbb\"\n" |
| " \"cccc\");", |
| Break); |
| verifyFormat("aaaa(qqq, \"bbbb\"\n" |
| " \"cccc\");", |
| NoBreak); |
| verifyFormat("aaaa(qqq,\n" |
| " \"bbbb\"\n" |
| " \"cccc\");", |
| Break); |
| verifyFormat("aaaa(qqq,\n" |
| " L\"bbbb\"\n" |
| " L\"cccc\");", |
| Break); |
| verifyFormat("aaaaa(aaaaaa, aaaaaaa(\"aaaa\"\n" |
| " \"bbbb\"));", |
| Break); |
| verifyFormat("string s = someFunction(\n" |
| " \"abc\"\n" |
| " \"abc\");", |
| Break); |
| |
| // As we break before unary operators, breaking right after them is bad. |
| verifyFormat("string foo = abc ? \"x\"\n" |
| " \"blah blah blah blah blah blah\"\n" |
| " : \"y\";", |
| Break); |
| |
| // Don't break if there is no column gain. |
| verifyFormat("f(\"aaaa\"\n" |
| " \"bbbb\");", |
| Break); |
| |
| // Treat literals with escaped newlines like multi-line string literals. |
| EXPECT_EQ("x = \"a\\\n" |
| "b\\\n" |
| "c\";", |
| format("x = \"a\\\n" |
| "b\\\n" |
| "c\";", |
| NoBreak)); |
| EXPECT_EQ("xxxx =\n" |
| " \"a\\\n" |
| "b\\\n" |
| "c\";", |
| format("xxxx = \"a\\\n" |
| "b\\\n" |
| "c\";", |
| Break)); |
| |
| EXPECT_EQ("NSString *const kString =\n" |
| " @\"aaaa\"\n" |
| " @\"bbbb\";", |
| format("NSString *const kString = @\"aaaa\"\n" |
| "@\"bbbb\";", |
| Break)); |
| |
| Break.ColumnLimit = 0; |
| verifyFormat("const char *hello = \"hello llvm\";", Break); |
| } |
| |
| TEST_F(FormatTest, AlignsPipes) { |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n" |
| " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n" |
| " << \"ccccccccccccccccccccccccccccccccccccccccccccccccc\";"); |
| verifyFormat( |
| "aaaaaaaa << (aaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); |
| verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaaaaaaaaaaa(aaaaaaaa, aaaaaaaaaaa);"); |
| verifyFormat( |
| "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "auto Diag = diag() << aaaaaaaaaaaaaaaa(aaaaaaaaaaaa, aaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();"); |
| verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaa)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("LOG_IF(aaa == //\n" |
| " bbb)\n" |
| " << a << b;"); |
| |
| // But sometimes, breaking before the first "<<" is desirable. |
| verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa);"); |
| verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("SemaRef.Diag(Loc, diag::note_for_range_begin_end)\n" |
| " << BEF << IsTemplate << Description << E->getType();"); |
| verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " << aaa;"); |
| |
| verifyFormat( |
| "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| |
| // Incomplete string literal. |
| EXPECT_EQ("llvm::errs() << \"\n" |
| " << a;", |
| format("llvm::errs() << \"\n<<a;")); |
| |
| verifyFormat("void f() {\n" |
| " CHECK_EQ(aaaa, (*bbbbbbbbb)->cccccc)\n" |
| " << \"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\";\n" |
| "}"); |
| |
| // Handle 'endl'. |
| verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaa << endl\n" |
| " << bbbbbbbbbbbbbbbbbbbbbb << endl;"); |
| verifyFormat("llvm::errs() << endl << bbbbbbbbbbbbbbbbbbbbbb << endl;"); |
| |
| // Handle '\n'. |
| verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaa << \"\\n\"\n" |
| " << bbbbbbbbbbbbbbbbbbbbbb << \"\\n\";"); |
| verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaa << \'\\n\'\n" |
| " << bbbbbbbbbbbbbbbbbbbbbb << \'\\n\';"); |
| verifyFormat("llvm::errs() << aaaa << \"aaaaaaaaaaaaaaaaaa\\n\"\n" |
| " << bbbb << \"bbbbbbbbbbbbbbbbbb\\n\";"); |
| verifyFormat("llvm::errs() << \"\\n\" << bbbbbbbbbbbbbbbbbbbbbb << \"\\n\";"); |
| } |
| |
| TEST_F(FormatTest, KeepStringLabelValuePairsOnALine) { |
| verifyFormat("return out << \"somepacket = {\\n\"\n" |
| " << \" aaaaaa = \" << pkt.aaaaaa << \"\\n\"\n" |
| " << \" bbbb = \" << pkt.bbbb << \"\\n\"\n" |
| " << \" cccccc = \" << pkt.cccccc << \"\\n\"\n" |
| " << \" ddd = [\" << pkt.ddd << \"]\\n\"\n" |
| " << \"}\";"); |
| |
| verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "llvm::outs() << \"aaaaaaaaaaaaaaaaa = \" << aaaaaaaaaaaaaaaaa\n" |
| " << \"bbbbbbbbbbbbbbbbb = \" << bbbbbbbbbbbbbbbbb\n" |
| " << \"ccccccccccccccccc = \" << ccccccccccccccccc\n" |
| " << \"ddddddddddddddddd = \" << ddddddddddddddddd\n" |
| " << \"eeeeeeeeeeeeeeeee = \" << eeeeeeeeeeeeeeeee;"); |
| verifyFormat("llvm::outs() << aaaaaaaaaaaaaaaaaaaaaaaa << \"=\"\n" |
| " << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); |
| verifyFormat( |
| "void f() {\n" |
| " llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n" |
| "}"); |
| |
| // Breaking before the first "<<" is generally not desirable. |
| verifyFormat( |
| "llvm::errs()\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| getLLVMStyleWithColumns(70)); |
| verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " << \"aaaaaaaaaaaaaaaaaaa: \"\n" |
| " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;", |
| getLLVMStyleWithColumns(70)); |
| |
| verifyFormat("string v = \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa +\n" |
| " \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa +\n" |
| " \"aaaaaaaaaaaaaaaa: \" + aaaaaaaaaaaaaaaa;"); |
| verifyFormat("string v = StrCat(\"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa,\n" |
| " \"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa,\n" |
| " \"aaaaaaaaaaaaaaaa: \", aaaaaaaaaaaaaaaa);"); |
| verifyFormat("string v = \"aaaaaaaaaaaaaaaa: \" +\n" |
| " (aaaa + aaaa);", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("string v = StrCat(\"aaaaaaaaaaaa: \" +\n" |
| " (aaaaaaa + aaaaa));", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat( |
| "string v = StrCat(\"aaaaaaaaaaaaaaaaaaaaaaaaaaa: \",\n" |
| " SomeFunction(aaaaaaaaaaaa, aaaaaaaa.aaaaaaa),\n" |
| " bbbbbbbbbbbbbbbbbbbbbbb);"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsEquals) { |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat( |
| "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat( |
| "if (a) {\n" |
| " f();\n" |
| "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" |
| "}"); |
| |
| verifyFormat("if (int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " 100000000 + 10000000) {\n}"); |
| } |
| |
| TEST_F(FormatTest, WrapsAtFunctionCallsIfNecessary) { |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooongObject\n" |
| " .looooooooooooooooooooooooooooooooooooooongFunction();"); |
| |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooongObject\n" |
| " ->looooooooooooooooooooooooooooooooooooooongFunction();"); |
| |
| verifyFormat( |
| "LooooooooooooooooooooooooooooooooongObject->shortFunction(Parameter1,\n" |
| " Parameter2);"); |
| |
| verifyFormat( |
| "ShortObject->shortFunction(\n" |
| " LooooooooooooooooooooooooooooooooooooooooooooooongParameter1,\n" |
| " LooooooooooooooooooooooooooooooooooooooooooooooongParameter2);"); |
| |
| verifyFormat("loooooooooooooongFunction(\n" |
| " LoooooooooooooongObject->looooooooooooooooongFunction());"); |
| |
| verifyFormat( |
| "function(LoooooooooooooooooooooooooooooooooooongObject\n" |
| " ->loooooooooooooooooooooooooooooooooooooooongFunction());"); |
| |
| verifyFormat("EXPECT_CALL(SomeObject, SomeFunction(Parameter))\n" |
| " .WillRepeatedly(Return(SomeValue));"); |
| verifyFormat("void f() {\n" |
| " EXPECT_CALL(SomeObject, SomeFunction(Parameter))\n" |
| " .Times(2)\n" |
| " .WillRepeatedly(Return(SomeValue));\n" |
| "}"); |
| verifyFormat("SomeMap[std::pair(aaaaaaaaaaaa, bbbbbbbbbbbbbbb)].insert(\n" |
| " ccccccccccccccccccccccc);"); |
| verifyFormat("aaaaa(aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaa(aaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("void f() {\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa)->aaaaaaaaa());\n" |
| "}"); |
| verifyFormat("aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaa(aa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()) {\n" |
| "}"); |
| |
| // Here, it is not necessary to wrap at "." or "->". |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaa) ||\n" |
| " aaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}"); |
| verifyFormat( |
| "aaaaaaaaaaa->aaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaa->aaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa));\n"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa().aaaaaaaaaaaaaaaaa());"); |
| verifyFormat("a->aaaaaa()->aaaaaaaaaaa(aaaaaaaa()->aaaaaa()->aaaaa() *\n" |
| " aaaaaaaaa()->aaaaaa()->aaaaa());"); |
| verifyFormat("a->aaaaaa()->aaaaaaaaaaa(aaaaaaaa()->aaaaaa()->aaaaa() ||\n" |
| " aaaaaaaaa()->aaaaaa()->aaaaa());"); |
| |
| verifyFormat("aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .a();"); |
| |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackParameters = false; |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| NoBinPacking); |
| |
| // If there is a subsequent call, change to hanging indentation. |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa))\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa));"); |
| verifyFormat("aaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("aaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa());"); |
| } |
| |
| TEST_F(FormatTest, WrapsTemplateDeclarations) { |
| verifyFormat("template <typename T>\n" |
| "virtual void loooooooooooongFunction(int Param1, int Param2);"); |
| verifyFormat("template <typename T>\n" |
| "// T should be one of {A, B}.\n" |
| "virtual void loooooooooooongFunction(int Param1, int Param2);"); |
| verifyFormat( |
| "template <typename T>\n" |
| "using comment_to_xml_conversion = comment_to_xml_conversion<T, int>;"); |
| verifyFormat("template <typename T>\n" |
| "void f(int Paaaaaaaaaaaaaaaaaaaaaaaaaaaaaaram1,\n" |
| " int Paaaaaaaaaaaaaaaaaaaaaaaaaaaaaaram2);"); |
| verifyFormat( |
| "template <typename T>\n" |
| "void looooooooooooooooooooongFunction(int Paaaaaaaaaaaaaaaaaaaaram1,\n" |
| " int Paaaaaaaaaaaaaaaaaaaaram2);"); |
| verifyFormat( |
| "template <typename T>\n" |
| "aaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("template <typename T>\n" |
| "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat( |
| "template <typename T1, typename T2 = char, typename T3 = char,\n" |
| " typename T4 = char>\n" |
| "void f();"); |
| verifyFormat("template <typename aaaaaaaaaaa, typename bbbbbbbbbbbbb,\n" |
| " template <typename> class cccccccccccccccccccccc,\n" |
| " typename ddddddddddddd>\n" |
| "class C {};"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("void f() {\n" |
| " a<aaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaa>(\n" |
| " a(aaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa));\n" |
| "}"); |
| |
| verifyFormat("template <typename T> class C {};"); |
| verifyFormat("template <typename T> void f();"); |
| verifyFormat("template <typename T> void f() {}"); |
| verifyFormat( |
| "aaaaaaaaaaaaa<aaaaaaaaaa, aaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> *aaaa =\n" |
| " new aaaaaaaaaaaaa<aaaaaaaaaa, aaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>(\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbb);", |
| getLLVMStyleWithColumns(72)); |
| EXPECT_EQ("static_cast<A< //\n" |
| " B> *>(\n" |
| "\n" |
| ");", |
| format("static_cast<A<//\n" |
| " B>*>(\n" |
| "\n" |
| " );")); |
| verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " const typename aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaa);"); |
| |
| FormatStyle AlwaysBreak = getLLVMStyle(); |
| AlwaysBreak.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; |
| verifyFormat("template <typename T>\nclass C {};", AlwaysBreak); |
| verifyFormat("template <typename T>\nvoid f();", AlwaysBreak); |
| verifyFormat("template <typename T>\nvoid f() {}", AlwaysBreak); |
| verifyFormat("void aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbb>(\n" |
| " ccccccccccccccccccccccccccccccccccccccccccccccc);"); |
| verifyFormat("template <template <typename> class Fooooooo,\n" |
| " template <typename> class Baaaaaaar>\n" |
| "struct C {};", |
| AlwaysBreak); |
| verifyFormat("template <typename T> // T can be A, B or C.\n" |
| "struct C {};", |
| AlwaysBreak); |
| verifyFormat("template <enum E> class A {\n" |
| "public:\n" |
| " E *f();\n" |
| "};"); |
| |
| FormatStyle NeverBreak = getLLVMStyle(); |
| NeverBreak.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_No; |
| verifyFormat("template <typename T> class C {};", NeverBreak); |
| verifyFormat("template <typename T> void f();", NeverBreak); |
| verifyFormat("template <typename T> void f() {}", NeverBreak); |
| verifyFormat("template <typename T>\nvoid foo(aaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "bbbbbbbbbbbbbbbbbbbb) {}", |
| NeverBreak); |
| verifyFormat("void aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbb>(\n" |
| " ccccccccccccccccccccccccccccccccccccccccccccccc);", |
| NeverBreak); |
| verifyFormat("template <template <typename> class Fooooooo,\n" |
| " template <typename> class Baaaaaaar>\n" |
| "struct C {};", |
| NeverBreak); |
| verifyFormat("template <typename T> // T can be A, B or C.\n" |
| "struct C {};", |
| NeverBreak); |
| verifyFormat("template <enum E> class A {\n" |
| "public:\n" |
| " E *f();\n" |
| "};", |
| NeverBreak); |
| NeverBreak.PenaltyBreakTemplateDeclaration = 100; |
| verifyFormat("template <typename T> void\nfoo(aaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "bbbbbbbbbbbbbbbbbbbb) {}", |
| NeverBreak); |
| } |
| |
| TEST_F(FormatTest, WrapsTemplateDeclarationsWithComments) { |
| FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); |
| Style.ColumnLimit = 60; |
| EXPECT_EQ("// Baseline - no comments.\n" |
| "template <\n" |
| " typename aaaaaaaaaaaaaaaaaaaaaa<bbbbbbbbbbbb>::value>\n" |
| "void f() {}", |
| format("// Baseline - no comments.\n" |
| "template <\n" |
| " typename aaaaaaaaaaaaaaaaaaaaaa<bbbbbbbbbbbb>::value>\n" |
| "void f() {}", |
| Style)); |
| |
| EXPECT_EQ("template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> // trailing\n" |
| "void f() {}", |
| format("template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> // trailing\n" |
| "void f() {}", |
| Style)); |
| |
| EXPECT_EQ( |
| "template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> /* line */\n" |
| "void f() {}", |
| format("template <typename aaaaaaaaaa<bbbbbbbbbbbb>::value> /* line */\n" |
| "void f() {}", |
| Style)); |
| |
| EXPECT_EQ( |
| "template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> // trailing\n" |
| " // multiline\n" |
| "void f() {}", |
| format("template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> // trailing\n" |
| " // multiline\n" |
| "void f() {}", |
| Style)); |
| |
| EXPECT_EQ( |
| "template <typename aaaaaaaaaa<\n" |
| " bbbbbbbbbbbb>::value> // trailing loooong\n" |
| "void f() {}", |
| format( |
| "template <\n" |
| " typename aaaaaaaaaa<bbbbbbbbbbbb>::value> // trailing loooong\n" |
| "void f() {}", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, WrapsTemplateParameters) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat( |
| "template <typename... a> struct q {};\n" |
| "extern q<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" |
| " y;", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat( |
| "template <typename... a> struct r {};\n" |
| "extern r<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" |
| " y;", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat("template <typename... a> struct s {};\n" |
| "extern s<\n" |
| " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " |
| "aaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " |
| "aaaaaaaaaaaaaaaaaaaaaa>\n" |
| " y;", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat("template <typename... a> struct t {};\n" |
| "extern t<\n" |
| " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " |
| "aaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, " |
| "aaaaaaaaaaaaaaaaaaaaaa>\n" |
| " y;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) { |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa());"); |
| |
| // FIXME: Should we have the extra indent after the second break? |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb::\n" |
| " cccccccccccccccccccccccccccccccccccccccccccccc());"); |
| |
| // Breaking at nested name specifiers is generally not desirable. |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaa(aaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaa);", |
| getLLVMStyleWithColumns(74)); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsTemplateParameters) { |
| verifyFormat("A<int> a;"); |
| verifyFormat("A<A<A<int>>> a;"); |
| verifyFormat("A<A<A<int, 2>, 3>, 4> a;"); |
| verifyFormat("bool x = a < 1 || 2 > a;"); |
| verifyFormat("bool x = 5 < f<int>();"); |
| verifyFormat("bool x = f<int>() > 5;"); |
| verifyFormat("bool x = 5 < a<int>::x;"); |
| verifyFormat("bool x = a < 4 ? a > 2 : false;"); |
| verifyFormat("bool x = f() ? a < 2 : a > 2;"); |
| |
| verifyGoogleFormat("A<A<int>> a;"); |
| verifyGoogleFormat("A<A<A<int>>> a;"); |
| verifyGoogleFormat("A<A<A<A<int>>>> a;"); |
| verifyGoogleFormat("A<A<int> > a;"); |
| verifyGoogleFormat("A<A<A<int> > > a;"); |
| verifyGoogleFormat("A<A<A<A<int> > > > a;"); |
| verifyGoogleFormat("A<::A<int>> a;"); |
| verifyGoogleFormat("A<::A> a;"); |
| verifyGoogleFormat("A< ::A> a;"); |
| verifyGoogleFormat("A< ::A<int> > a;"); |
| EXPECT_EQ("A<A<A<A>>> a;", format("A<A<A<A> >> a;", getGoogleStyle())); |
| EXPECT_EQ("A<A<A<A>>> a;", format("A<A<A<A>> > a;", getGoogleStyle())); |
| EXPECT_EQ("A<::A<int>> a;", format("A< ::A<int>> a;", getGoogleStyle())); |
| EXPECT_EQ("A<::A<int>> a;", format("A<::A<int> > a;", getGoogleStyle())); |
| EXPECT_EQ("auto x = [] { A<A<A<A>>> a; };", |
| format("auto x=[]{A<A<A<A> >> a;};", getGoogleStyle())); |
| |
| verifyFormat("A<A<int>> a;", getChromiumStyle(FormatStyle::LK_Cpp)); |
| |
| // template closer followed by a token that starts with > or = |
| verifyFormat("bool b = a<1> > 1;"); |
| verifyFormat("bool b = a<1> >= 1;"); |
| verifyFormat("int i = a<1> >> 1;"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.SpaceBeforeAssignmentOperators = false; |
| verifyFormat("bool b= a<1> == 1;", Style); |
| verifyFormat("a<int> = 1;", Style); |
| verifyFormat("a<int> >>= 1;", Style); |
| |
| verifyFormat("test < a | b >> c;"); |
| verifyFormat("test<test<a | b>> c;"); |
| verifyFormat("test >> a >> b;"); |
| verifyFormat("test << a >> b;"); |
| |
| verifyFormat("f<int>();"); |
| verifyFormat("template <typename T> void f() {}"); |
| verifyFormat("struct A<std::enable_if<sizeof(T2) < sizeof(int32)>::type>;"); |
| verifyFormat("struct A<std::enable_if<sizeof(T2) ? sizeof(int32) : " |
| "sizeof(char)>::type>;"); |
| verifyFormat("template <class T> struct S<std::is_arithmetic<T>{}> {};"); |
| verifyFormat("f(a.operator()<A>());"); |
| verifyFormat("f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " .template operator()<A>());", |
| getLLVMStyleWithColumns(35)); |
| verifyFormat("bool_constant<a && noexcept(f())>"); |
| verifyFormat("bool_constant<a || noexcept(f())>"); |
| |
| // Not template parameters. |
| verifyFormat("return a < b && c > d;"); |
| verifyFormat("void f() {\n" |
| " while (a < b && c > d) {\n" |
| " }\n" |
| "}"); |
| verifyFormat("template <typename... Types>\n" |
| "typename enable_if<0 < sizeof...(Types)>::type Foo() {}"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa >> aaaaa);", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("static_assert(is_convertible<A &&, B>::value, \"AAA\");"); |
| verifyFormat("Constructor(A... a) : a_(X<A>{std::forward<A>(a)}...) {}"); |
| verifyFormat("< < < < < < < < < < < < < < < < < < < < < < < < < < < < < <"); |
| verifyFormat("some_templated_type<decltype([](int i) { return i; })>"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsShiftOperators) { |
| verifyFormat("if (i < x >> 1)"); |
| verifyFormat("while (i < x >> 1)"); |
| verifyFormat("for (unsigned i = 0; i < i; ++i, v = v >> 1)"); |
| verifyFormat("for (unsigned i = 0; i < x >> 1; ++i, v = v >> 1)"); |
| verifyFormat( |
| "for (std::vector<int>::iterator i = 0; i < x >> 1; ++i, v = v >> 1)"); |
| verifyFormat("Foo.call<Bar<Function>>()"); |
| verifyFormat("if (Foo.call<Bar<Function>>() == 0)"); |
| verifyFormat("for (std::vector<std::pair<int>>::iterator i = 0; i < x >> 1; " |
| "++i, v = v >> 1)"); |
| verifyFormat("if (w<u<v<x>>, 1>::t)"); |
| } |
| |
| TEST_F(FormatTest, BitshiftOperatorWidth) { |
| EXPECT_EQ("int a = 1 << 2; /* foo\n" |
| " bar */", |
| format("int a=1<<2; /* foo\n" |
| " bar */")); |
| |
| EXPECT_EQ("int b = 256 >> 1; /* foo\n" |
| " bar */", |
| format("int b =256>>1 ; /* foo\n" |
| " bar */")); |
| } |
| |
| TEST_F(FormatTest, UnderstandsBinaryOperators) { |
| verifyFormat("COMPARE(a, ==, b);"); |
| verifyFormat("auto s = sizeof...(Ts) - 1;"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsPointersToMembers) { |
| verifyFormat("int A::*x;"); |
| verifyFormat("int (S::*func)(void *);"); |
| verifyFormat("void f() { int (S::*func)(void *); }"); |
| verifyFormat("typedef bool *(Class::*Member)() const;"); |
| verifyFormat("void f() {\n" |
| " (a->*f)();\n" |
| " a->*x;\n" |
| " (a.*f)();\n" |
| " ((*a).*f)();\n" |
| " a.*x;\n" |
| "}"); |
| verifyFormat("void f() {\n" |
| " (a->*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n" |
| " aaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);\n" |
| "}"); |
| verifyFormat( |
| "(aaaaaaaaaa->*bbbbbbb)(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("typedef bool* (Class::*Member)() const;", Style); |
| } |
| |
| TEST_F(FormatTest, UnderstandsUnaryOperators) { |
| verifyFormat("int a = -2;"); |
| verifyFormat("f(-1, -2, -3);"); |
| verifyFormat("a[-1] = 5;"); |
| verifyFormat("int a = 5 + -2;"); |
| verifyFormat("if (i == -1) {\n}"); |
| verifyFormat("if (i != -1) {\n}"); |
| verifyFormat("if (i > -1) {\n}"); |
| verifyFormat("if (i < -1) {\n}"); |
| verifyFormat("++(a->f());"); |
| verifyFormat("--(a->f());"); |
| verifyFormat("(a->f())++;"); |
| verifyFormat("a[42]++;"); |
| verifyFormat("if (!(a->f())) {\n}"); |
| verifyFormat("if (!+i) {\n}"); |
| verifyFormat("~&a;"); |
| verifyFormat("for (x = 0; -10 < x; --x) {\n}"); |
| verifyFormat("sizeof -x"); |
| verifyFormat("sizeof +x"); |
| verifyFormat("sizeof *x"); |
| verifyFormat("sizeof &x"); |
| verifyFormat("delete +x;"); |
| verifyFormat("co_await +x;"); |
| verifyFormat("case *x:"); |
| verifyFormat("case &x:"); |
| |
| verifyFormat("a-- > b;"); |
| verifyFormat("b ? -a : c;"); |
| verifyFormat("n * sizeof char16;"); |
| verifyFormat("n * alignof char16;", getGoogleStyle()); |
| verifyFormat("sizeof(char);"); |
| verifyFormat("alignof(char);", getGoogleStyle()); |
| |
| verifyFormat("return -1;"); |
| verifyFormat("throw -1;"); |
| verifyFormat("switch (a) {\n" |
| "case -1:\n" |
| " break;\n" |
| "}"); |
| verifyFormat("#define X -1"); |
| verifyFormat("#define X -kConstant"); |
| |
| verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = {-5, +3};"); |
| verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = {+5, -3};"); |
| |
| verifyFormat("int a = /* confusing comment */ -1;"); |
| // FIXME: The space after 'i' is wrong, but hopefully, this is a rare case. |
| verifyFormat("int a = i /* confusing comment */++;"); |
| |
| verifyFormat("co_yield -1;"); |
| verifyFormat("co_return -1;"); |
| |
| // Check that * is not treated as a binary operator when we set |
| // PointerAlignment as PAS_Left after a keyword and not a declaration. |
| FormatStyle PASLeftStyle = getLLVMStyle(); |
| PASLeftStyle.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("co_return *a;", PASLeftStyle); |
| verifyFormat("co_await *a;", PASLeftStyle); |
| verifyFormat("co_yield *a", PASLeftStyle); |
| verifyFormat("return *a;", PASLeftStyle); |
| } |
| |
| TEST_F(FormatTest, DoesNotIndentRelativeToUnaryOperators) { |
| verifyFormat("if (!aaaaaaaaaa( // break\n" |
| " aaaaa)) {\n" |
| "}"); |
| verifyFormat("aaaaaaaaaa(!aaaaaaaaaa( // break\n" |
| " aaaaa));"); |
| verifyFormat("*aaa = aaaaaaa( // break\n" |
| " bbbbbb);"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsOverloadedOperators) { |
| verifyFormat("bool operator<();"); |
| verifyFormat("bool operator>();"); |
| verifyFormat("bool operator=();"); |
| verifyFormat("bool operator==();"); |
| verifyFormat("bool operator!=();"); |
| verifyFormat("int operator+();"); |
| verifyFormat("int operator++();"); |
| verifyFormat("int operator++(int) volatile noexcept;"); |
| verifyFormat("bool operator,();"); |
| verifyFormat("bool operator();"); |
| verifyFormat("bool operator()();"); |
| verifyFormat("bool operator[]();"); |
| verifyFormat("operator bool();"); |
| verifyFormat("operator int();"); |
| verifyFormat("operator void *();"); |
| verifyFormat("operator SomeType<int>();"); |
| verifyFormat("operator SomeType<int, int>();"); |
| verifyFormat("operator SomeType<SomeType<int>>();"); |
| verifyFormat("operator< <>();"); |
| verifyFormat("operator<< <>();"); |
| verifyFormat("< <>"); |
| |
| verifyFormat("void *operator new(std::size_t size);"); |
| verifyFormat("void *operator new[](std::size_t size);"); |
| verifyFormat("void operator delete(void *ptr);"); |
| verifyFormat("void operator delete[](void *ptr);"); |
| verifyFormat("template <typename AAAAAAA, typename BBBBBBB>\n" |
| "AAAAAAA operator/(const AAAAAAA &a, BBBBBBB &b);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaa operator,(\n" |
| " aaaaaaaaaaaaaaaaaaaaa &aaaaaaaaaaaaaaaaaaaaaaaaaa) const;"); |
| |
| verifyFormat( |
| "ostream &operator<<(ostream &OutputStream,\n" |
| " SomeReallyLongType WithSomeReallyLongValue);"); |
| verifyFormat("bool operator<(const aaaaaaaaaaaaaaaaaaaaa &left,\n" |
| " const aaaaaaaaaaaaaaaaaaaaa &right) {\n" |
| " return left.group < right.group;\n" |
| "}"); |
| verifyFormat("SomeType &operator=(const SomeType &S);"); |
| verifyFormat("f.template operator()<int>();"); |
| |
| verifyGoogleFormat("operator void*();"); |
| verifyGoogleFormat("operator SomeType<SomeType<int>>();"); |
| verifyGoogleFormat("operator ::A();"); |
| |
| verifyFormat("using A::operator+;"); |
| verifyFormat("inline A operator^(const A &lhs, const A &rhs) {}\n" |
| "int i;"); |
| |
| // Calling an operator as a member function. |
| verifyFormat("void f() { a.operator*(); }"); |
| verifyFormat("void f() { a.operator*(b & b); }"); |
| verifyFormat("void f() { a->operator&(a * b); }"); |
| verifyFormat("void f() { NS::a.operator+(*b * *b); }"); |
| // TODO: Calling an operator as a non-member function is hard to distinguish. |
| // https://llvm.org/PR50629 |
| // verifyFormat("void f() { operator*(a & a); }"); |
| // verifyFormat("void f() { operator&(a, b * b); }"); |
| |
| verifyFormat("::operator delete(foo);"); |
| verifyFormat("::operator new(n * sizeof(foo));"); |
| verifyFormat("foo() { ::operator delete(foo); }"); |
| verifyFormat("foo() { ::operator new(n * sizeof(foo)); }"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsFunctionRefQualification) { |
| verifyFormat("void A::b() && {}"); |
| verifyFormat("void A::b() &&noexcept {}"); |
| verifyFormat("Deleted &operator=(const Deleted &) & = default;"); |
| verifyFormat("Deleted &operator=(const Deleted &) && = delete;"); |
| verifyFormat("Deleted &operator=(const Deleted &) &noexcept = default;"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) && = delete;"); |
| verifyFormat("Deleted &operator=(const Deleted &) &;"); |
| verifyFormat("Deleted &operator=(const Deleted &) &&;"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) &;"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) &&;"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) && {}"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) && final {}"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) && override {}"); |
| verifyFormat("SomeType MemberFunction(const Deleted &) &&noexcept {}"); |
| verifyFormat("void Fn(T const &) const &;"); |
| verifyFormat("void Fn(T const volatile &&) const volatile &&;"); |
| verifyFormat("void Fn(T const volatile &&) const volatile &&noexcept;"); |
| verifyFormat("template <typename T>\n" |
| "void F(T) && = delete;", |
| getGoogleStyle()); |
| verifyFormat("template <typename T> void operator=(T) &;"); |
| verifyFormat("template <typename T> void operator=(T) const &;"); |
| verifyFormat("template <typename T> void operator=(T) &noexcept;"); |
| verifyFormat("template <typename T> void operator=(T) & = default;"); |
| verifyFormat("template <typename T> void operator=(T) &&;"); |
| verifyFormat("template <typename T> void operator=(T) && = delete;"); |
| verifyFormat("template <typename T> void operator=(T) & {}"); |
| verifyFormat("template <typename T> void operator=(T) && {}"); |
| |
| FormatStyle AlignLeft = getLLVMStyle(); |
| AlignLeft.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("void A::b() && {}", AlignLeft); |
| verifyFormat("void A::b() && noexcept {}", AlignLeft); |
| verifyFormat("Deleted& operator=(const Deleted&) & = default;", AlignLeft); |
| verifyFormat("Deleted& operator=(const Deleted&) & noexcept = default;", |
| AlignLeft); |
| verifyFormat("SomeType MemberFunction(const Deleted&) & = delete;", |
| AlignLeft); |
| verifyFormat("Deleted& operator=(const Deleted&) &;", AlignLeft); |
| verifyFormat("SomeType MemberFunction(const Deleted&) &;", AlignLeft); |
| verifyFormat("auto Function(T t) & -> void {}", AlignLeft); |
| verifyFormat("auto Function(T... t) & -> void {}", AlignLeft); |
| verifyFormat("auto Function(T) & -> void {}", AlignLeft); |
| verifyFormat("auto Function(T) & -> void;", AlignLeft); |
| verifyFormat("void Fn(T const&) const&;", AlignLeft); |
| verifyFormat("void Fn(T const volatile&&) const volatile&&;", AlignLeft); |
| verifyFormat("void Fn(T const volatile&&) const volatile&& noexcept;", |
| AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) &;", AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) const&;", AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) & noexcept;", |
| AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) & = default;", |
| AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) &&;", AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) && = delete;", |
| AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) & {}", AlignLeft); |
| verifyFormat("template <typename T> void operator=(T) && {}", AlignLeft); |
| |
| FormatStyle AlignMiddle = getLLVMStyle(); |
| AlignMiddle.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("void A::b() && {}", AlignMiddle); |
| verifyFormat("void A::b() && noexcept {}", AlignMiddle); |
| verifyFormat("Deleted & operator=(const Deleted &) & = default;", |
| AlignMiddle); |
| verifyFormat("Deleted & operator=(const Deleted &) & noexcept = default;", |
| AlignMiddle); |
| verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;", |
| AlignMiddle); |
| verifyFormat("Deleted & operator=(const Deleted &) &;", AlignMiddle); |
| verifyFormat("SomeType MemberFunction(const Deleted &) &;", AlignMiddle); |
| verifyFormat("auto Function(T t) & -> void {}", AlignMiddle); |
| verifyFormat("auto Function(T... t) & -> void {}", AlignMiddle); |
| verifyFormat("auto Function(T) & -> void {}", AlignMiddle); |
| verifyFormat("auto Function(T) & -> void;", AlignMiddle); |
| verifyFormat("void Fn(T const &) const &;", AlignMiddle); |
| verifyFormat("void Fn(T const volatile &&) const volatile &&;", AlignMiddle); |
| verifyFormat("void Fn(T const volatile &&) const volatile && noexcept;", |
| AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) &;", AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) const &;", AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) & noexcept;", |
| AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) & = default;", |
| AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) &&;", AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) && = delete;", |
| AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) & {}", AlignMiddle); |
| verifyFormat("template <typename T> void operator=(T) && {}", AlignMiddle); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInCStyleCastParentheses = true; |
| verifyFormat("Deleted &operator=(const Deleted &) & = default;", Spaces); |
| verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;", Spaces); |
| verifyFormat("Deleted &operator=(const Deleted &) &;", Spaces); |
| verifyFormat("SomeType MemberFunction(const Deleted &) &;", Spaces); |
| |
| Spaces.SpacesInCStyleCastParentheses = false; |
| Spaces.SpacesInParentheses = true; |
| verifyFormat("Deleted &operator=( const Deleted & ) & = default;", Spaces); |
| verifyFormat("SomeType MemberFunction( const Deleted & ) & = delete;", |
| Spaces); |
| verifyFormat("Deleted &operator=( const Deleted & ) &;", Spaces); |
| verifyFormat("SomeType MemberFunction( const Deleted & ) &;", Spaces); |
| |
| FormatStyle BreakTemplate = getLLVMStyle(); |
| BreakTemplate.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int &foo(const std::string &str) &noexcept {}\n" |
| "};", |
| BreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int &foo(const std::string &str) &&noexcept {}\n" |
| "};", |
| BreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int &foo(const std::string &str) const &noexcept {}\n" |
| "};", |
| BreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int &foo(const std::string &str) const &noexcept {}\n" |
| "};", |
| BreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " auto foo(const std::string &str) &&noexcept -> int & {}\n" |
| "};", |
| BreakTemplate); |
| |
| FormatStyle AlignLeftBreakTemplate = getLLVMStyle(); |
| AlignLeftBreakTemplate.AlwaysBreakTemplateDeclarations = |
| FormatStyle::BTDS_Yes; |
| AlignLeftBreakTemplate.PointerAlignment = FormatStyle::PAS_Left; |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int& foo(const std::string& str) & noexcept {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int& foo(const std::string& str) && noexcept {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int& foo(const std::string& str) const& noexcept {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " int& foo(const std::string& str) const&& noexcept {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " auto foo(const std::string& str) && noexcept -> int& {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| // The `&` in `Type&` should not be confused with a trailing `&` of |
| // DEPRECATED(reason) member function. |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " DEPRECATED(reason)\n" |
| " Type &foo(arguments) {}\n" |
| "};", |
| BreakTemplate); |
| |
| verifyFormat("struct f {\n" |
| " template <class T>\n" |
| " DEPRECATED(reason)\n" |
| " Type& foo(arguments) {}\n" |
| "};", |
| AlignLeftBreakTemplate); |
| |
| verifyFormat("void (*foopt)(int) = &func;"); |
| |
| FormatStyle DerivePointerAlignment = getLLVMStyle(); |
| DerivePointerAlignment.DerivePointerAlignment = true; |
| // There's always a space between the function and its trailing qualifiers. |
| // This isn't evidence for PAS_Right (or for PAS_Left). |
| std::string Prefix = "void a() &;\n" |
| "void b() &;\n"; |
| verifyFormat(Prefix + "int* x;", DerivePointerAlignment); |
| verifyFormat(Prefix + "int *x;", DerivePointerAlignment); |
| // Same if the function is an overloaded operator, and with &&. |
| Prefix = "void operator()() &&;\n" |
| "void operator()() &&;\n"; |
| verifyFormat(Prefix + "int* x;", DerivePointerAlignment); |
| verifyFormat(Prefix + "int *x;", DerivePointerAlignment); |
| // However a space between cv-qualifiers and ref-qualifiers *is* evidence. |
| Prefix = "void a() const &;\n" |
| "void b() const &;\n"; |
| EXPECT_EQ(Prefix + "int *x;", |
| format(Prefix + "int* x;", DerivePointerAlignment)); |
| } |
| |
| TEST_F(FormatTest, UnderstandsNewAndDelete) { |
| verifyFormat("void f() {\n" |
| " A *a = new A;\n" |
| " A *a = new (placement) A;\n" |
| " delete a;\n" |
| " delete (A *)a;\n" |
| "}"); |
| verifyFormat("new (aaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaa))\n" |
| " typename aaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("auto aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " new (aaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaa))\n" |
| " typename aaaaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("delete[] h->p;"); |
| verifyFormat("delete[] (void *)p;"); |
| |
| verifyFormat("void operator delete(void *foo) ATTRIB;"); |
| verifyFormat("void operator new(void *foo) ATTRIB;"); |
| verifyFormat("void operator delete[](void *foo) ATTRIB;"); |
| verifyFormat("void operator delete(void *ptr) noexcept;"); |
| |
| EXPECT_EQ("void new(link p);\n" |
| "void delete(link p);\n", |
| format("void new (link p);\n" |
| "void delete (link p);\n")); |
| } |
| |
| TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { |
| verifyFormat("int *f(int *a) {}"); |
| verifyFormat("int main(int argc, char **argv) {}"); |
| verifyFormat("Test::Test(int b) : a(b * b) {}"); |
| verifyIndependentOfContext("f(a, *a);"); |
| verifyFormat("void g() { f(*a); }"); |
| verifyIndependentOfContext("int a = b * 10;"); |
| verifyIndependentOfContext("int a = 10 * b;"); |
| verifyIndependentOfContext("int a = b * c;"); |
| verifyIndependentOfContext("int a += b * c;"); |
| verifyIndependentOfContext("int a -= b * c;"); |
| verifyIndependentOfContext("int a *= b * c;"); |
| verifyIndependentOfContext("int a /= b * c;"); |
| verifyIndependentOfContext("int a = *b;"); |
| verifyIndependentOfContext("int a = *b * c;"); |
| verifyIndependentOfContext("int a = b * *c;"); |
| verifyIndependentOfContext("int a = b * (10);"); |
| verifyIndependentOfContext("S << b * (10);"); |
| verifyIndependentOfContext("return 10 * b;"); |
| verifyIndependentOfContext("return *b * *c;"); |
| verifyIndependentOfContext("return a & ~b;"); |
| verifyIndependentOfContext("f(b ? *c : *d);"); |
| verifyIndependentOfContext("int a = b ? *c : *d;"); |
| verifyIndependentOfContext("*b = a;"); |
| verifyIndependentOfContext("a * ~b;"); |
| verifyIndependentOfContext("a * !b;"); |
| verifyIndependentOfContext("a * +b;"); |
| verifyIndependentOfContext("a * -b;"); |
| verifyIndependentOfContext("a * ++b;"); |
| verifyIndependentOfContext("a * --b;"); |
| verifyIndependentOfContext("a[4] * b;"); |
| verifyIndependentOfContext("a[a * a] = 1;"); |
| verifyIndependentOfContext("f() * b;"); |
| verifyIndependentOfContext("a * [self dostuff];"); |
| verifyIndependentOfContext("int x = a * (a + b);"); |
| verifyIndependentOfContext("(a *)(a + b);"); |
| verifyIndependentOfContext("*(int *)(p & ~3UL) = 0;"); |
| verifyIndependentOfContext("int *pa = (int *)&a;"); |
| verifyIndependentOfContext("return sizeof(int **);"); |
| verifyIndependentOfContext("return sizeof(int ******);"); |
| verifyIndependentOfContext("return (int **&)a;"); |
| verifyIndependentOfContext("f((*PointerToArray)[10]);"); |
| verifyFormat("void f(Type (*parameter)[10]) {}"); |
| verifyFormat("void f(Type (¶meter)[10]) {}"); |
| verifyGoogleFormat("return sizeof(int**);"); |
| verifyIndependentOfContext("Type **A = static_cast<Type **>(P);"); |
| verifyGoogleFormat("Type** A = static_cast<Type**>(P);"); |
| verifyFormat("auto a = [](int **&, int ***) {};"); |
| verifyFormat("auto PointerBinding = [](const char *S) {};"); |
| verifyFormat("typedef typeof(int(int, int)) *MyFunc;"); |
| verifyFormat("[](const decltype(*a) &value) {}"); |
| verifyFormat("[](const typeof(*a) &value) {}"); |
| verifyFormat("[](const _Atomic(a *) &value) {}"); |
| verifyFormat("[](const __underlying_type(a) &value) {}"); |
| verifyFormat("decltype(a * b) F();"); |
| verifyFormat("typeof(a * b) F();"); |
| verifyFormat("#define MACRO() [](A *a) { return 1; }"); |
| verifyFormat("Constructor() : member([](A *a, B *b) {}) {}"); |
| verifyIndependentOfContext("typedef void (*f)(int *a);"); |
| verifyIndependentOfContext("int i{a * b};"); |
| verifyIndependentOfContext("aaa && aaa->f();"); |
| verifyIndependentOfContext("int x = ~*p;"); |
| verifyFormat("Constructor() : a(a), area(width * height) {}"); |
| verifyFormat("Constructor() : a(a), area(a, width * height) {}"); |
| verifyGoogleFormat("MACRO Constructor(const int& i) : a(a), b(b) {}"); |
| verifyFormat("void f() { f(a, c * d); }"); |
| verifyFormat("void f() { f(new a(), c * d); }"); |
| verifyFormat("void f(const MyOverride &override);"); |
| verifyFormat("void f(const MyFinal &final);"); |
| verifyIndependentOfContext("bool a = f() && override.f();"); |
| verifyIndependentOfContext("bool a = f() && final.f();"); |
| |
| verifyIndependentOfContext("InvalidRegions[*R] = 0;"); |
| |
| verifyIndependentOfContext("A<int *> a;"); |
| verifyIndependentOfContext("A<int **> a;"); |
| verifyIndependentOfContext("A<int *, int *> a;"); |
| verifyIndependentOfContext("A<int *[]> a;"); |
| verifyIndependentOfContext( |
| "const char *const p = reinterpret_cast<const char *const>(q);"); |
| verifyIndependentOfContext("A<int **, int **> a;"); |
| verifyIndependentOfContext("void f(int *a = d * e, int *b = c * d);"); |
| verifyFormat("for (char **a = b; *a; ++a) {\n}"); |
| verifyFormat("for (; a && b;) {\n}"); |
| verifyFormat("bool foo = true && [] { return false; }();"); |
| |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyGoogleFormat("int const* a = &b;"); |
| verifyGoogleFormat("**outparam = 1;"); |
| verifyGoogleFormat("*outparam = a * b;"); |
| verifyGoogleFormat("int main(int argc, char** argv) {}"); |
| verifyGoogleFormat("A<int*> a;"); |
| verifyGoogleFormat("A<int**> a;"); |
| verifyGoogleFormat("A<int*, int*> a;"); |
| verifyGoogleFormat("A<int**, int**> a;"); |
| verifyGoogleFormat("f(b ? *c : *d);"); |
| verifyGoogleFormat("int a = b ? *c : *d;"); |
| verifyGoogleFormat("Type* t = **x;"); |
| verifyGoogleFormat("Type* t = *++*x;"); |
| verifyGoogleFormat("*++*x;"); |
| verifyGoogleFormat("Type* t = const_cast<T*>(&*x);"); |
| verifyGoogleFormat("Type* t = x++ * y;"); |
| verifyGoogleFormat( |
| "const char* const p = reinterpret_cast<const char* const>(q);"); |
| verifyGoogleFormat("void f(int i = 0, SomeType** temps = NULL);"); |
| verifyGoogleFormat("void f(Bar* a = nullptr, Bar* b);"); |
| verifyGoogleFormat("template <typename T>\n" |
| "void f(int i = 0, SomeType** temps = NULL);"); |
| |
| FormatStyle Left = getLLVMStyle(); |
| Left.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("x = *a(x) = *a(y);", Left); |
| verifyFormat("for (;; *a = b) {\n}", Left); |
| verifyFormat("return *this += 1;", Left); |
| verifyFormat("throw *x;", Left); |
| verifyFormat("delete *x;", Left); |
| verifyFormat("typedef typeof(int(int, int))* MyFuncPtr;", Left); |
| verifyFormat("[](const decltype(*a)* ptr) {}", Left); |
| verifyFormat("[](const typeof(*a)* ptr) {}", Left); |
| verifyFormat("[](const _Atomic(a*)* ptr) {}", Left); |
| verifyFormat("[](const __underlying_type(a)* ptr) {}", Left); |
| verifyFormat("typedef typeof /*comment*/ (int(int, int))* MyFuncPtr;", Left); |
| verifyFormat("auto x(A&&, B&&, C&&) -> D;", Left); |
| verifyFormat("auto x = [](A&&, B&&, C&&) -> D {};", Left); |
| verifyFormat("template <class T> X(T&&, T&&, T&&) -> X<T>;", Left); |
| |
| verifyIndependentOfContext("a = *(x + y);"); |
| verifyIndependentOfContext("a = &(x + y);"); |
| verifyIndependentOfContext("*(x + y).call();"); |
| verifyIndependentOfContext("&(x + y)->call();"); |
| verifyFormat("void f() { &(*I).first; }"); |
| |
| verifyIndependentOfContext("f(b * /* confusing comment */ ++c);"); |
| verifyFormat("f(* /* confusing comment */ foo);"); |
| verifyFormat("void (* /*deleter*/)(const Slice &key, void *value)"); |
| verifyFormat("void foo(int * // this is the first paramters\n" |
| " ,\n" |
| " int second);"); |
| verifyFormat("double term = a * // first\n" |
| " b;"); |
| verifyFormat( |
| "int *MyValues = {\n" |
| " *A, // Operator detection might be confused by the '{'\n" |
| " *BB // Operator detection might be confused by previous comment\n" |
| "};"); |
| |
| verifyIndependentOfContext("if (int *a = &b)"); |
| verifyIndependentOfContext("if (int &a = *b)"); |
| verifyIndependentOfContext("if (a & b[i])"); |
| verifyIndependentOfContext("if constexpr (a & b[i])"); |
| verifyIndependentOfContext("if CONSTEXPR (a & b[i])"); |
| verifyIndependentOfContext("if (a * (b * c))"); |
| verifyIndependentOfContext("if constexpr (a * (b * c))"); |
| verifyIndependentOfContext("if CONSTEXPR (a * (b * c))"); |
| verifyIndependentOfContext("if (a::b::c::d & b[i])"); |
| verifyIndependentOfContext("if (*b[i])"); |
| verifyIndependentOfContext("if (int *a = (&b))"); |
| verifyIndependentOfContext("while (int *a = &b)"); |
| verifyIndependentOfContext("while (a * (b * c))"); |
| verifyIndependentOfContext("size = sizeof *a;"); |
| verifyIndependentOfContext("if (a && (b = c))"); |
| verifyFormat("void f() {\n" |
| " for (const int &v : Values) {\n" |
| " }\n" |
| "}"); |
| verifyFormat("for (int i = a * a; i < 10; ++i) {\n}"); |
| verifyFormat("for (int i = 0; i < a * a; ++i) {\n}"); |
| verifyGoogleFormat("for (int i = 0; i * 2 < z; i *= 2) {\n}"); |
| |
| verifyFormat("#define A (!a * b)"); |
| verifyFormat("#define MACRO \\\n" |
| " int *i = a * b; \\\n" |
| " void f(a *b);", |
| getLLVMStyleWithColumns(19)); |
| |
| verifyIndependentOfContext("A = new SomeType *[Length];"); |
| verifyIndependentOfContext("A = new SomeType *[Length]();"); |
| verifyIndependentOfContext("T **t = new T *;"); |
| verifyIndependentOfContext("T **t = new T *();"); |
| verifyGoogleFormat("A = new SomeType*[Length]();"); |
| verifyGoogleFormat("A = new SomeType*[Length];"); |
| verifyGoogleFormat("T** t = new T*;"); |
| verifyGoogleFormat("T** t = new T*();"); |
| |
| verifyFormat("STATIC_ASSERT((a & b) == 0);"); |
| verifyFormat("STATIC_ASSERT(0 == (a & b));"); |
| verifyFormat("template <bool a, bool b> " |
| "typename t::if<x && y>::type f() {}"); |
| verifyFormat("template <int *y> f() {}"); |
| verifyFormat("vector<int *> v;"); |
| verifyFormat("vector<int *const> v;"); |
| verifyFormat("vector<int *const **const *> v;"); |
| verifyFormat("vector<int *volatile> v;"); |
| verifyFormat("vector<a *_Nonnull> v;"); |
| verifyFormat("vector<a *_Nullable> v;"); |
| verifyFormat("vector<a *_Null_unspecified> v;"); |
| verifyFormat("vector<a *__ptr32> v;"); |
| verifyFormat("vector<a *__ptr64> v;"); |
| verifyFormat("vector<a *__capability> v;"); |
| FormatStyle TypeMacros = getLLVMStyle(); |
| TypeMacros.TypenameMacros = {"LIST"}; |
| verifyFormat("vector<LIST(uint64_t)> v;", TypeMacros); |
| verifyFormat("vector<LIST(uint64_t) *> v;", TypeMacros); |
| verifyFormat("vector<LIST(uint64_t) **> v;", TypeMacros); |
| verifyFormat("vector<LIST(uint64_t) *attr> v;", TypeMacros); |
| verifyFormat("vector<A(uint64_t) * attr> v;", TypeMacros); // multiplication |
| |
| FormatStyle CustomQualifier = getLLVMStyle(); |
| // Add identifiers that should not be parsed as a qualifier by default. |
| CustomQualifier.AttributeMacros.push_back("__my_qualifier"); |
| CustomQualifier.AttributeMacros.push_back("_My_qualifier"); |
| CustomQualifier.AttributeMacros.push_back("my_other_qualifier"); |
| verifyFormat("vector<a * __my_qualifier> parse_as_multiply;"); |
| verifyFormat("vector<a *__my_qualifier> v;", CustomQualifier); |
| verifyFormat("vector<a * _My_qualifier> parse_as_multiply;"); |
| verifyFormat("vector<a *_My_qualifier> v;", CustomQualifier); |
| verifyFormat("vector<a * my_other_qualifier> parse_as_multiply;"); |
| verifyFormat("vector<a *my_other_qualifier> v;", CustomQualifier); |
| verifyFormat("vector<a * _NotAQualifier> v;"); |
| verifyFormat("vector<a * __not_a_qualifier> v;"); |
| verifyFormat("vector<a * b> v;"); |
| verifyFormat("foo<b && false>();"); |
| verifyFormat("foo<b & 1>();"); |
| verifyFormat("foo<b & (1)>();"); |
| verifyFormat("foo<b & (~0)>();"); |
| verifyFormat("foo<b & (true)>();"); |
| verifyFormat("foo<b & ((1))>();"); |
| verifyFormat("foo<b & (/*comment*/ 1)>();"); |
| verifyFormat("decltype(*::std::declval<const T &>()) void F();"); |
| verifyFormat("typeof(*::std::declval<const T &>()) void F();"); |
| verifyFormat("_Atomic(*::std::declval<const T &>()) void F();"); |
| verifyFormat("__underlying_type(*::std::declval<const T &>()) void F();"); |
| verifyFormat( |
| "template <class T, class = typename std::enable_if<\n" |
| " std::is_integral<T>::value &&\n" |
| " (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n" |
| "void F();", |
| getLLVMStyleWithColumns(70)); |
| verifyFormat("template <class T,\n" |
| " class = typename std::enable_if<\n" |
| " std::is_integral<T>::value &&\n" |
| " (sizeof(T) > 1 || sizeof(T) < 8)>::type,\n" |
| " class U>\n" |
| "void F();", |
| getLLVMStyleWithColumns(70)); |
| verifyFormat( |
| "template <class T,\n" |
| " class = typename ::std::enable_if<\n" |
| " ::std::is_array<T>{} && ::std::is_array<T>{}>::type>\n" |
| "void F();", |
| getGoogleStyleWithColumns(68)); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("struct {\n" |
| "}* ptr;", |
| Style); |
| verifyFormat("union {\n" |
| "}* ptr;", |
| Style); |
| verifyFormat("class {\n" |
| "}* ptr;", |
| Style); |
| // Don't confuse a multiplication after a brace-initialized expression with |
| // a class pointer. |
| verifyFormat("int i = int{42} * 34;", Style); |
| verifyFormat("struct {\n" |
| "}&& ptr = {};", |
| Style); |
| verifyFormat("union {\n" |
| "}&& ptr = {};", |
| Style); |
| verifyFormat("class {\n" |
| "}&& ptr = {};", |
| Style); |
| verifyFormat("bool b = 3 == int{3} && true;"); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("struct {\n" |
| "} * ptr;", |
| Style); |
| verifyFormat("union {\n" |
| "} * ptr;", |
| Style); |
| verifyFormat("class {\n" |
| "} * ptr;", |
| Style); |
| verifyFormat("struct {\n" |
| "} && ptr = {};", |
| Style); |
| verifyFormat("union {\n" |
| "} && ptr = {};", |
| Style); |
| verifyFormat("class {\n" |
| "} && ptr = {};", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("struct {\n" |
| "} *ptr;", |
| Style); |
| verifyFormat("union {\n" |
| "} *ptr;", |
| Style); |
| verifyFormat("class {\n" |
| "} *ptr;", |
| Style); |
| verifyFormat("struct {\n" |
| "} &&ptr = {};", |
| Style); |
| verifyFormat("union {\n" |
| "} &&ptr = {};", |
| Style); |
| verifyFormat("class {\n" |
| "} &&ptr = {};", |
| Style); |
| |
| verifyIndependentOfContext("MACRO(int *i);"); |
| verifyIndependentOfContext("MACRO(auto *a);"); |
| verifyIndependentOfContext("MACRO(const A *a);"); |
| verifyIndependentOfContext("MACRO(_Atomic(A) *a);"); |
| verifyIndependentOfContext("MACRO(decltype(A) *a);"); |
| verifyIndependentOfContext("MACRO(typeof(A) *a);"); |
| verifyIndependentOfContext("MACRO(__underlying_type(A) *a);"); |
| verifyIndependentOfContext("MACRO(A *const a);"); |
| verifyIndependentOfContext("MACRO(A *restrict a);"); |
| verifyIndependentOfContext("MACRO(A *__restrict__ a);"); |
| verifyIndependentOfContext("MACRO(A *__restrict a);"); |
| verifyIndependentOfContext("MACRO(A *volatile a);"); |
| verifyIndependentOfContext("MACRO(A *__volatile a);"); |
| verifyIndependentOfContext("MACRO(A *__volatile__ a);"); |
| verifyIndependentOfContext("MACRO(A *_Nonnull a);"); |
| verifyIndependentOfContext("MACRO(A *_Nullable a);"); |
| verifyIndependentOfContext("MACRO(A *_Null_unspecified a);"); |
| verifyIndependentOfContext("MACRO(A *__attribute__((foo)) a);"); |
| verifyIndependentOfContext("MACRO(A *__attribute((foo)) a);"); |
| verifyIndependentOfContext("MACRO(A *[[clang::attr]] a);"); |
| verifyIndependentOfContext("MACRO(A *[[clang::attr(\"foo\")]] a);"); |
| verifyIndependentOfContext("MACRO(A *__ptr32 a);"); |
| verifyIndependentOfContext("MACRO(A *__ptr64 a);"); |
| verifyIndependentOfContext("MACRO(A *__capability);"); |
| verifyIndependentOfContext("MACRO(A &__capability);"); |
| verifyFormat("MACRO(A *__my_qualifier);"); // type declaration |
| verifyFormat("void f() { MACRO(A * __my_qualifier); }"); // multiplication |
| // If we add __my_qualifier to AttributeMacros it should always be parsed as |
| // a type declaration: |
| verifyFormat("MACRO(A *__my_qualifier);", CustomQualifier); |
| verifyFormat("void f() { MACRO(A *__my_qualifier); }", CustomQualifier); |
| // Also check that TypenameMacros prevents parsing it as multiplication: |
| verifyIndependentOfContext("MACRO(LIST(uint64_t) * a);"); // multiplication |
| verifyIndependentOfContext("MACRO(LIST(uint64_t) *a);", TypeMacros); // type |
| |
| verifyIndependentOfContext("MACRO('0' <= c && c <= '9');"); |
| verifyFormat("void f() { f(float{1}, a * a); }"); |
| verifyFormat("void f() { f(float(1), a * a); }"); |
| |
| verifyFormat("f((void (*)(int))g);"); |
| verifyFormat("f((void (&)(int))g);"); |
| verifyFormat("f((void (^)(int))g);"); |
| |
| // FIXME: Is there a way to make this work? |
| // verifyIndependentOfContext("MACRO(A *a);"); |
| verifyFormat("MACRO(A &B);"); |
| verifyFormat("MACRO(A *B);"); |
| verifyFormat("void f() { MACRO(A * B); }"); |
| verifyFormat("void f() { MACRO(A & B); }"); |
| |
| // This lambda was mis-formatted after D88956 (treating it as a binop): |
| verifyFormat("auto x = [](const decltype(x) &ptr) {};"); |
| verifyFormat("auto x = [](const decltype(x) *ptr) {};"); |
| verifyFormat("#define lambda [](const decltype(x) &ptr) {}"); |
| verifyFormat("#define lambda [](const decltype(x) *ptr) {}"); |
| |
| verifyFormat("DatumHandle const *operator->() const { return input_; }"); |
| verifyFormat("return options != nullptr && operator==(*options);"); |
| |
| EXPECT_EQ("#define OP(x) \\\n" |
| " ostream &operator<<(ostream &s, const A &a) { \\\n" |
| " return s << a.DebugString(); \\\n" |
| " }", |
| format("#define OP(x) \\\n" |
| " ostream &operator<<(ostream &s, const A &a) { \\\n" |
| " return s << a.DebugString(); \\\n" |
| " }", |
| getLLVMStyleWithColumns(50))); |
| |
| // FIXME: We cannot handle this case yet; we might be able to figure out that |
| // foo<x> d > v; doesn't make sense. |
| verifyFormat("foo<a<b && c> d> v;"); |
| |
| FormatStyle PointerMiddle = getLLVMStyle(); |
| PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("delete *x;", PointerMiddle); |
| verifyFormat("int * x;", PointerMiddle); |
| verifyFormat("int *[] x;", PointerMiddle); |
| verifyFormat("template <int * y> f() {}", PointerMiddle); |
| verifyFormat("int * f(int * a) {}", PointerMiddle); |
| verifyFormat("int main(int argc, char ** argv) {}", PointerMiddle); |
| verifyFormat("Test::Test(int b) : a(b * b) {}", PointerMiddle); |
| verifyFormat("A<int *> a;", PointerMiddle); |
| verifyFormat("A<int **> a;", PointerMiddle); |
| verifyFormat("A<int *, int *> a;", PointerMiddle); |
| verifyFormat("A<int *[]> a;", PointerMiddle); |
| verifyFormat("A = new SomeType *[Length]();", PointerMiddle); |
| verifyFormat("A = new SomeType *[Length];", PointerMiddle); |
| verifyFormat("T ** t = new T *;", PointerMiddle); |
| |
| // Member function reference qualifiers aren't binary operators. |
| verifyFormat("string // break\n" |
| "operator()() & {}"); |
| verifyFormat("string // break\n" |
| "operator()() && {}"); |
| verifyGoogleFormat("template <typename T>\n" |
| "auto x() & -> int {}"); |
| |
| // Should be binary operators when used as an argument expression (overloaded |
| // operator invoked as a member function). |
| verifyFormat("void f() { a.operator()(a * a); }"); |
| verifyFormat("void f() { a->operator()(a & a); }"); |
| verifyFormat("void f() { a.operator()(*a & *a); }"); |
| verifyFormat("void f() { a->operator()(*a * *a); }"); |
| |
| verifyFormat("int operator()(T (&&)[N]) { return 1; }"); |
| verifyFormat("int operator()(T (&)[N]) { return 0; }"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsAttributes) { |
| verifyFormat("SomeType s __attribute__((unused)) (InitValue);"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa __attribute__((unused))\n" |
| "aaaaaaaaaaaaaaaaaaaaaaa(int i);"); |
| verifyFormat("__attribute__((nodebug)) ::qualified_type f();"); |
| FormatStyle AfterType = getLLVMStyle(); |
| AfterType.AlwaysBreakAfterReturnType = FormatStyle::RTBS_All; |
| verifyFormat("__attribute__((nodebug)) void\n" |
| "foo() {}\n", |
| AfterType); |
| verifyFormat("__unused void\n" |
| "foo() {}", |
| AfterType); |
| |
| FormatStyle CustomAttrs = getLLVMStyle(); |
| CustomAttrs.AttributeMacros.push_back("__unused"); |
| CustomAttrs.AttributeMacros.push_back("__attr1"); |
| CustomAttrs.AttributeMacros.push_back("__attr2"); |
| CustomAttrs.AttributeMacros.push_back("no_underscore_attr"); |
| verifyFormat("vector<SomeType *__attribute((foo))> v;"); |
| verifyFormat("vector<SomeType *__attribute__((foo))> v;"); |
| verifyFormat("vector<SomeType * __not_attribute__((foo))> v;"); |
| // Check that it is parsed as a multiplication without AttributeMacros and |
| // as a pointer qualifier when we add __attr1/__attr2 to AttributeMacros. |
| verifyFormat("vector<SomeType * __attr1> v;"); |
| verifyFormat("vector<SomeType __attr1 *> v;"); |
| verifyFormat("vector<SomeType __attr1 *const> v;"); |
| verifyFormat("vector<SomeType __attr1 * __attr2> v;"); |
| verifyFormat("vector<SomeType *__attr1> v;", CustomAttrs); |
| verifyFormat("vector<SomeType *__attr2> v;", CustomAttrs); |
| verifyFormat("vector<SomeType *no_underscore_attr> v;", CustomAttrs); |
| verifyFormat("vector<SomeType __attr1 *> v;", CustomAttrs); |
| verifyFormat("vector<SomeType __attr1 *const> v;", CustomAttrs); |
| verifyFormat("vector<SomeType __attr1 *__attr2> v;", CustomAttrs); |
| verifyFormat("vector<SomeType __attr1 *no_underscore_attr> v;", CustomAttrs); |
| |
| // Check that these are not parsed as function declarations: |
| CustomAttrs.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| CustomAttrs.BreakBeforeBraces = FormatStyle::BS_Allman; |
| verifyFormat("SomeType s(InitValue);", CustomAttrs); |
| verifyFormat("SomeType s{InitValue};", CustomAttrs); |
| verifyFormat("SomeType *__unused s(InitValue);", CustomAttrs); |
| verifyFormat("SomeType *__unused s{InitValue};", CustomAttrs); |
| verifyFormat("SomeType s __unused(InitValue);", CustomAttrs); |
| verifyFormat("SomeType s __unused{InitValue};", CustomAttrs); |
| verifyFormat("SomeType *__capability s(InitValue);", CustomAttrs); |
| verifyFormat("SomeType *__capability s{InitValue};", CustomAttrs); |
| } |
| |
| TEST_F(FormatTest, UnderstandsPointerQualifiersInCast) { |
| // Check that qualifiers on pointers don't break parsing of casts. |
| verifyFormat("x = (foo *const)*v;"); |
| verifyFormat("x = (foo *volatile)*v;"); |
| verifyFormat("x = (foo *restrict)*v;"); |
| verifyFormat("x = (foo *__attribute__((foo)))*v;"); |
| verifyFormat("x = (foo *_Nonnull)*v;"); |
| verifyFormat("x = (foo *_Nullable)*v;"); |
| verifyFormat("x = (foo *_Null_unspecified)*v;"); |
| verifyFormat("x = (foo *_Nonnull)*v;"); |
| verifyFormat("x = (foo *[[clang::attr]])*v;"); |
| verifyFormat("x = (foo *[[clang::attr(\"foo\")]])*v;"); |
| verifyFormat("x = (foo *__ptr32)*v;"); |
| verifyFormat("x = (foo *__ptr64)*v;"); |
| verifyFormat("x = (foo *__capability)*v;"); |
| |
| // Check that we handle multiple trailing qualifiers and skip them all to |
| // determine that the expression is a cast to a pointer type. |
| FormatStyle LongPointerRight = getLLVMStyleWithColumns(999); |
| FormatStyle LongPointerLeft = getLLVMStyleWithColumns(999); |
| LongPointerLeft.PointerAlignment = FormatStyle::PAS_Left; |
| StringRef AllQualifiers = |
| "const volatile restrict __attribute__((foo)) _Nonnull _Null_unspecified " |
| "_Nonnull [[clang::attr]] __ptr32 __ptr64 __capability"; |
| verifyFormat(("x = (foo *" + AllQualifiers + ")*v;").str(), LongPointerRight); |
| verifyFormat(("x = (foo* " + AllQualifiers + ")*v;").str(), LongPointerLeft); |
| |
| // Also check that address-of is not parsed as a binary bitwise-and: |
| verifyFormat("x = (foo *const)&v;"); |
| verifyFormat(("x = (foo *" + AllQualifiers + ")&v;").str(), LongPointerRight); |
| verifyFormat(("x = (foo* " + AllQualifiers + ")&v;").str(), LongPointerLeft); |
| |
| // Check custom qualifiers: |
| FormatStyle CustomQualifier = getLLVMStyleWithColumns(999); |
| CustomQualifier.AttributeMacros.push_back("__my_qualifier"); |
| verifyFormat("x = (foo * __my_qualifier) * v;"); // not parsed as qualifier. |
| verifyFormat("x = (foo *__my_qualifier)*v;", CustomQualifier); |
| verifyFormat(("x = (foo *" + AllQualifiers + " __my_qualifier)*v;").str(), |
| CustomQualifier); |
| verifyFormat(("x = (foo *" + AllQualifiers + " __my_qualifier)&v;").str(), |
| CustomQualifier); |
| |
| // Check that unknown identifiers result in binary operator parsing: |
| verifyFormat("x = (foo * __unknown_qualifier) * v;"); |
| verifyFormat("x = (foo * __unknown_qualifier) & v;"); |
| } |
| |
| TEST_F(FormatTest, UnderstandsSquareAttributes) { |
| verifyFormat("SomeType s [[unused]] (InitValue);"); |
| verifyFormat("SomeType s [[gnu::unused]] (InitValue);"); |
| verifyFormat("SomeType s [[using gnu: unused]] (InitValue);"); |
| verifyFormat("[[gsl::suppress(\"clang-tidy-check-name\")]] void f() {}"); |
| verifyFormat("void f() [[deprecated(\"so sorry\")]];"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [[unused]] aaaaaaaaaaaaaaaaaaaaaaa(int i);"); |
| verifyFormat("[[nodiscard]] bool f() { return false; }"); |
| verifyFormat("class [[nodiscard]] f {\npublic:\n f() {}\n}"); |
| verifyFormat("class [[deprecated(\"so sorry\")]] f {\npublic:\n f() {}\n}"); |
| verifyFormat("class [[gnu::unused]] f {\npublic:\n f() {}\n}"); |
| verifyFormat("[[nodiscard]] ::qualified_type f();"); |
| |
| // Make sure we do not mistake attributes for array subscripts. |
| verifyFormat("int a() {}\n" |
| "[[unused]] int b() {}\n"); |
| verifyFormat("NSArray *arr;\n" |
| "arr[[Foo() bar]];"); |
| |
| // On the other hand, we still need to correctly find array subscripts. |
| verifyFormat("int a = std::vector<int>{1, 2, 3}[0];"); |
| |
| // Make sure that we do not mistake Objective-C method inside array literals |
| // as attributes, even if those method names are also keywords. |
| verifyFormat("@[ [foo bar] ];"); |
| verifyFormat("@[ [NSArray class] ];"); |
| verifyFormat("@[ [foo enum] ];"); |
| |
| verifyFormat("template <typename T> [[nodiscard]] int a() { return 1; }"); |
| |
| // Make sure we do not parse attributes as lambda introducers. |
| FormatStyle MultiLineFunctions = getLLVMStyle(); |
| MultiLineFunctions.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| verifyFormat("[[unused]] int b() {\n" |
| " return 42;\n" |
| "}\n", |
| MultiLineFunctions); |
| } |
| |
| TEST_F(FormatTest, AttributeClass) { |
| FormatStyle Style = getChromiumStyle(FormatStyle::LK_Cpp); |
| verifyFormat("class S {\n" |
| " S(S&&) = default;\n" |
| "};", |
| Style); |
| verifyFormat("class [[nodiscard]] S {\n" |
| " S(S&&) = default;\n" |
| "};", |
| Style); |
| verifyFormat("class __attribute((maybeunused)) S {\n" |
| " S(S&&) = default;\n" |
| "};", |
| Style); |
| verifyFormat("struct S {\n" |
| " S(S&&) = default;\n" |
| "};", |
| Style); |
| verifyFormat("struct [[nodiscard]] S {\n" |
| " S(S&&) = default;\n" |
| "};", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AttributesAfterMacro) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("MACRO;\n" |
| "__attribute__((maybe_unused)) int foo() {\n" |
| " //...\n" |
| "}"); |
| |
| verifyFormat("MACRO;\n" |
| "[[nodiscard]] int foo() {\n" |
| " //...\n" |
| "}"); |
| |
| EXPECT_EQ("MACRO\n\n" |
| "__attribute__((maybe_unused)) int foo() {\n" |
| " //...\n" |
| "}", |
| format("MACRO\n\n" |
| "__attribute__((maybe_unused)) int foo() {\n" |
| " //...\n" |
| "}")); |
| |
| EXPECT_EQ("MACRO\n\n" |
| "[[nodiscard]] int foo() {\n" |
| " //...\n" |
| "}", |
| format("MACRO\n\n" |
| "[[nodiscard]] int foo() {\n" |
| " //...\n" |
| "}")); |
| } |
| |
| TEST_F(FormatTest, AttributePenaltyBreaking) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("void ABCDEFGH::ABCDEFGHIJKLMN(\n" |
| " [[maybe_unused]] const shared_ptr<ALongTypeName> &C d) {}", |
| Style); |
| verifyFormat("void ABCDEFGH::ABCDEFGHIJK(\n" |
| " [[maybe_unused]] const shared_ptr<ALongTypeName> &C d) {}", |
| Style); |
| verifyFormat("void ABCDEFGH::ABCDEFGH([[maybe_unused]] const " |
| "shared_ptr<ALongTypeName> &C d) {\n}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, UnderstandsEllipsis) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("int printf(const char *fmt, ...);"); |
| verifyFormat("template <class... Ts> void Foo(Ts... ts) { Foo(ts...); }"); |
| verifyFormat("template <class... Ts> void Foo(Ts *...ts) {}"); |
| |
| verifyFormat("template <int *...PP> a;", Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("template <class... Ts> void Foo(Ts*... ts) {}", Style); |
| |
| verifyFormat("template <int*... PP> a;", Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("template <int *... PP> a;", Style); |
| } |
| |
| TEST_F(FormatTest, AdaptivelyFormatsPointersAndReferences) { |
| EXPECT_EQ("int *a;\n" |
| "int *a;\n" |
| "int *a;", |
| format("int *a;\n" |
| "int* a;\n" |
| "int *a;", |
| getGoogleStyle())); |
| EXPECT_EQ("int* a;\n" |
| "int* a;\n" |
| "int* a;", |
| format("int* a;\n" |
| "int* a;\n" |
| "int *a;", |
| getGoogleStyle())); |
| EXPECT_EQ("int *a;\n" |
| "int *a;\n" |
| "int *a;", |
| format("int *a;\n" |
| "int * a;\n" |
| "int * a;", |
| getGoogleStyle())); |
| EXPECT_EQ("auto x = [] {\n" |
| " int *a;\n" |
| " int *a;\n" |
| " int *a;\n" |
| "};", |
| format("auto x=[]{int *a;\n" |
| "int * a;\n" |
| "int * a;};", |
| getGoogleStyle())); |
| } |
| |
| TEST_F(FormatTest, UnderstandsRvalueReferences) { |
| verifyFormat("int f(int &&a) {}"); |
| verifyFormat("int f(int a, char &&b) {}"); |
| verifyFormat("void f() { int &&a = b; }"); |
| verifyGoogleFormat("int f(int a, char&& b) {}"); |
| verifyGoogleFormat("void f() { int&& a = b; }"); |
| |
| verifyIndependentOfContext("A<int &&> a;"); |
| verifyIndependentOfContext("A<int &&, int &&> a;"); |
| verifyGoogleFormat("A<int&&> a;"); |
| verifyGoogleFormat("A<int&&, int&&> a;"); |
| |
| // Not rvalue references: |
| verifyFormat("template <bool B, bool C> class A {\n" |
| " static_assert(B && C, \"Something is wrong\");\n" |
| "};"); |
| verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))"); |
| verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))"); |
| verifyFormat("#define A(a, b) (a && b)"); |
| } |
| |
| TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) { |
| verifyFormat("void f() {\n" |
| " x[aaaaaaaaa -\n" |
| " b] = 23;\n" |
| "}", |
| getLLVMStyleWithColumns(15)); |
| } |
| |
| TEST_F(FormatTest, FormatsCasts) { |
| verifyFormat("Type *A = static_cast<Type *>(P);"); |
| verifyFormat("static_cast<Type *>(P);"); |
| verifyFormat("static_cast<Type &>(Fun)(Args);"); |
| verifyFormat("static_cast<Type &>(*Fun)(Args);"); |
| verifyFormat("if (static_cast<int>(A) + B >= 0)\n ;"); |
| // Check that static_cast<...>(...) does not require the next token to be on |
| // the same line. |
| verifyFormat("some_loooong_output << something_something__ << " |
| "static_cast<const void *>(R)\n" |
| " << something;"); |
| verifyFormat("a = static_cast<Type &>(*Fun)(Args);"); |
| verifyFormat("const_cast<Type &>(*Fun)(Args);"); |
| verifyFormat("dynamic_cast<Type &>(*Fun)(Args);"); |
| verifyFormat("reinterpret_cast<Type &>(*Fun)(Args);"); |
| verifyFormat("Type *A = (Type *)P;"); |
| verifyFormat("Type *A = (vector<Type *, int *>)P;"); |
| verifyFormat("int a = (int)(2.0f);"); |
| verifyFormat("int a = (int)2.0f;"); |
| verifyFormat("x[(int32)y];"); |
| verifyFormat("x = (int32)y;"); |
| verifyFormat("#define AA(X) sizeof(((X *)NULL)->a)"); |
| verifyFormat("int a = (int)*b;"); |
| verifyFormat("int a = (int)2.0f;"); |
| verifyFormat("int a = (int)~0;"); |
| verifyFormat("int a = (int)++a;"); |
| verifyFormat("int a = (int)sizeof(int);"); |
| verifyFormat("int a = (int)+2;"); |
| verifyFormat("my_int a = (my_int)2.0f;"); |
| verifyFormat("my_int a = (my_int)sizeof(int);"); |
| verifyFormat("return (my_int)aaa;"); |
| verifyFormat("#define x ((int)-1)"); |
| verifyFormat("#define LENGTH(x, y) (x) - (y) + 1"); |
| verifyFormat("#define p(q) ((int *)&q)"); |
| verifyFormat("fn(a)(b) + 1;"); |
| |
| verifyFormat("void f() { my_int a = (my_int)*b; }"); |
| verifyFormat("void f() { return P ? (my_int)*P : (my_int)0; }"); |
| verifyFormat("my_int a = (my_int)~0;"); |
| verifyFormat("my_int a = (my_int)++a;"); |
| verifyFormat("my_int a = (my_int)-2;"); |
| verifyFormat("my_int a = (my_int)1;"); |
| verifyFormat("my_int a = (my_int *)1;"); |
| verifyFormat("my_int a = (const my_int)-1;"); |
| verifyFormat("my_int a = (const my_int *)-1;"); |
| verifyFormat("my_int a = (my_int)(my_int)-1;"); |
| verifyFormat("my_int a = (ns::my_int)-2;"); |
| verifyFormat("case (my_int)ONE:"); |
| verifyFormat("auto x = (X)this;"); |
| // Casts in Obj-C style calls used to not be recognized as such. |
| verifyFormat("int a = [(type*)[((type*)val) arg] arg];", getGoogleStyle()); |
| |
| // FIXME: single value wrapped with paren will be treated as cast. |
| verifyFormat("void f(int i = (kValue)*kMask) {}"); |
| |
| verifyFormat("{ (void)F; }"); |
| |
| // Don't break after a cast's |
| verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" |
| " (aaaaaaaaaaaaaaaaaaaaaaaaaa *)(aaaaaaaaaaaaaaaaaaaaaa +\n" |
| " bbbbbbbbbbbbbbbbbbbbbb);"); |
| |
| verifyFormat("#define CONF_BOOL(x) (bool *)(void *)(x)"); |
| verifyFormat("#define CONF_BOOL(x) (bool *)(x)"); |
| verifyFormat("#define CONF_BOOL(x) (bool)(x)"); |
| verifyFormat("bool *y = (bool *)(void *)(x);"); |
| verifyFormat("#define CONF_BOOL(x) (bool *)(void *)(int)(x)"); |
| verifyFormat("bool *y = (bool *)(void *)(int)(x);"); |
| verifyFormat("#define CONF_BOOL(x) (bool *)(void *)(int)foo(x)"); |
| verifyFormat("bool *y = (bool *)(void *)(int)foo(x);"); |
| |
| // These are not casts. |
| verifyFormat("void f(int *) {}"); |
| verifyFormat("f(foo)->b;"); |
| verifyFormat("f(foo).b;"); |
| verifyFormat("f(foo)(b);"); |
| verifyFormat("f(foo)[b];"); |
| verifyFormat("[](foo) { return 4; }(bar);"); |
| verifyFormat("(*funptr)(foo)[4];"); |
| verifyFormat("funptrs[4](foo)[4];"); |
| verifyFormat("void f(int *);"); |
| verifyFormat("void f(int *) = 0;"); |
| verifyFormat("void f(SmallVector<int>) {}"); |
| verifyFormat("void f(SmallVector<int>);"); |
| verifyFormat("void f(SmallVector<int>) = 0;"); |
| verifyFormat("void f(int i = (kA * kB) & kMask) {}"); |
| verifyFormat("int a = sizeof(int) * b;"); |
| verifyFormat("int a = alignof(int) * b;", getGoogleStyle()); |
| verifyFormat("template <> void f<int>(int i) SOME_ANNOTATION;"); |
| verifyFormat("f(\"%\" SOME_MACRO(ll) \"d\");"); |
| verifyFormat("aaaaa &operator=(const aaaaa &) LLVM_DELETED_FUNCTION;"); |
| |
| // These are not casts, but at some point were confused with casts. |
| verifyFormat("virtual void foo(int *) override;"); |
| verifyFormat("virtual void foo(char &) const;"); |
| verifyFormat("virtual void foo(int *a, char *) const;"); |
| verifyFormat("int a = sizeof(int *) + b;"); |
| verifyFormat("int a = alignof(int *) + b;", getGoogleStyle()); |
| verifyFormat("bool b = f(g<int>) && c;"); |
| verifyFormat("typedef void (*f)(int i) func;"); |
| verifyFormat("void operator++(int) noexcept;"); |
| verifyFormat("void operator++(int &) noexcept;"); |
| verifyFormat("void operator delete(void *, std::size_t, const std::nothrow_t " |
| "&) noexcept;"); |
| verifyFormat( |
| "void operator delete(std::size_t, const std::nothrow_t &) noexcept;"); |
| verifyFormat("void operator delete(const std::nothrow_t &) noexcept;"); |
| verifyFormat("void operator delete(std::nothrow_t &) noexcept;"); |
| verifyFormat("void operator delete(nothrow_t &) noexcept;"); |
| verifyFormat("void operator delete(foo &) noexcept;"); |
| verifyFormat("void operator delete(foo) noexcept;"); |
| verifyFormat("void operator delete(int) noexcept;"); |
| verifyFormat("void operator delete(int &) noexcept;"); |
| verifyFormat("void operator delete(int &) volatile noexcept;"); |
| verifyFormat("void operator delete(int &) const"); |
| verifyFormat("void operator delete(int &) = default"); |
| verifyFormat("void operator delete(int &) = delete"); |
| verifyFormat("void operator delete(int &) [[noreturn]]"); |
| verifyFormat("void operator delete(int &) throw();"); |
| verifyFormat("void operator delete(int &) throw(int);"); |
| verifyFormat("auto operator delete(int &) -> int;"); |
| verifyFormat("auto operator delete(int &) override"); |
| verifyFormat("auto operator delete(int &) final"); |
| |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *foo = (aaaaaaaaaaaaaaaaa *)\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); |
| // FIXME: The indentation here is not ideal. |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (*cccccccccccccccc)\n" |
| " [dddddddddddddddddddddddddddddddddddddddddddddddddddddddd];"); |
| } |
| |
| TEST_F(FormatTest, FormatsFunctionTypes) { |
| verifyFormat("A<bool()> a;"); |
| verifyFormat("A<SomeType()> a;"); |
| verifyFormat("A<void (*)(int, std::string)> a;"); |
| verifyFormat("A<void *(int)>;"); |
| verifyFormat("void *(*a)(int *, SomeType *);"); |
| verifyFormat("int (*func)(void *);"); |
| verifyFormat("void f() { int (*func)(void *); }"); |
| verifyFormat("template <class CallbackClass>\n" |
| "using MyCallback = void (CallbackClass::*)(SomeObject *Data);"); |
| |
| verifyGoogleFormat("A<void*(int*, SomeType*)>;"); |
| verifyGoogleFormat("void* (*a)(int);"); |
| verifyGoogleFormat( |
| "template <class CallbackClass>\n" |
| "using MyCallback = void (CallbackClass::*)(SomeObject* Data);"); |
| |
| // Other constructs can look somewhat like function types: |
| verifyFormat("A<sizeof(*x)> a;"); |
| verifyFormat("#define DEREF_AND_CALL_F(x) f(*x)"); |
| verifyFormat("some_var = function(*some_pointer_var)[0];"); |
| verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }"); |
| verifyFormat("int x = f(&h)();"); |
| verifyFormat("returnsFunction(¶m1, ¶m2)(param);"); |
| verifyFormat("std::function<\n" |
| " LooooooooooongTemplatedType<\n" |
| " SomeType>*(\n" |
| " LooooooooooooooooongType type)>\n" |
| " function;", |
| getGoogleStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, FormatsPointersToArrayTypes) { |
| verifyFormat("A (*foo_)[6];"); |
| verifyFormat("vector<int> (*foo_)[6];"); |
| } |
| |
| TEST_F(FormatTest, BreaksLongVariableDeclarations) { |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " LoooooooooooooooooooooooooooooooooooooooongVariable;"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n" |
| " LoooooooooooooooooooooooooooooooooooooooongVariable;"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " *LoooooooooooooooooooooooooooooooooooooooongVariable;"); |
| |
| // Different ways of ()-initializiation. |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " LoooooooooooooooooooooooooooooooooooooooongVariable(1);"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " LoooooooooooooooooooooooooooooooooooooooongVariable(a);"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " LoooooooooooooooooooooooooooooooooooooooongVariable({});"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " LoooooooooooooooooooooooooooooooooooooongVariable([A a]);"); |
| |
| // Lambdas should not confuse the variable declaration heuristic. |
| verifyFormat("LooooooooooooooooongType\n" |
| " variable(nullptr, [](A *a) {});", |
| getLLVMStyleWithColumns(40)); |
| } |
| |
| TEST_F(FormatTest, BreaksLongDeclarations) { |
| verifyFormat("typedef LoooooooooooooooooooooooooooooooooooooooongType\n" |
| " AnotherNameForTheLongType;"); |
| verifyFormat("typedef LongTemplateType<aaaaaaaaaaaaaaaaaaa()>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| "LoooooooooooooooooooooooooooooooongFunctionDeclaration();"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType *\n" |
| "LoooooooooooooooooooooooooooooooongFunctionDeclaration();"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType MACRO\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType const\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("typeof(LoooooooooooooooooooooooooooooooooooooooooongName)\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("_Atomic(LooooooooooooooooooooooooooooooooooooooooongName)\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("__underlying_type(LooooooooooooooooooooooooooooooongName)\n" |
| "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| "LooooooooooooooooooooooooooongFunctionDeclaration(T... t);"); |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| "LooooooooooooooooooooooooooongFunctionDeclaration(T /*t*/) {}"); |
| FormatStyle Indented = getLLVMStyle(); |
| Indented.IndentWrappedFunctionNames = true; |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| " LoooooooooooooooooooooooooooooooongFunctionDeclaration();", |
| Indented); |
| verifyFormat( |
| "LoooooooooooooooooooooooooooooooooooooooongReturnType\n" |
| " LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}", |
| Indented); |
| verifyFormat( |
| "LoooooooooooooooooooooooooooooooooooooooongReturnType const\n" |
| " LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}", |
| Indented); |
| verifyFormat( |
| "decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n" |
| " LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}", |
| Indented); |
| |
| // FIXME: Without the comment, this breaks after "(". |
| verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType // break\n" |
| " (*LoooooooooooooooooooooooooooongFunctionTypeVarialbe)();", |
| getGoogleStyle()); |
| |
| verifyFormat("int *someFunction(int LoooooooooooooooooooongParam1,\n" |
| " int LoooooooooooooooooooongParam2) {}"); |
| verifyFormat( |
| "TypeSpecDecl *TypeSpecDecl::Create(ASTContext &C, DeclContext *DC,\n" |
| " SourceLocation L, IdentifierIn *II,\n" |
| " Type *T) {}"); |
| verifyFormat("ReallyLongReturnType<TemplateParam1, TemplateParam2>\n" |
| "ReallyReaaallyLongFunctionName(\n" |
| " const std::string &SomeParameter,\n" |
| " const SomeType<string, SomeOtherTemplateParameter>\n" |
| " &ReallyReallyLongParameterName,\n" |
| " const SomeType<string, SomeOtherTemplateParameter>\n" |
| " &AnotherLongParameterName) {}"); |
| verifyFormat("template <typename A>\n" |
| "SomeLoooooooooooooooooooooongType<\n" |
| " typename some_namespace::SomeOtherType<A>::Type>\n" |
| "Function() {}"); |
| |
| verifyGoogleFormat( |
| "aaaaaaaaaaaaaaaa::aaaaaaaaaaaaaaaa<aaaaaaaaaaaaa, aaaaaaaaaaaa>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa;"); |
| verifyGoogleFormat( |
| "TypeSpecDecl* TypeSpecDecl::Create(ASTContext& C, DeclContext* DC,\n" |
| " SourceLocation L) {}"); |
| verifyGoogleFormat( |
| "some_namespace::LongReturnType\n" |
| "long_namespace::SomeVeryLongClass::SomeVeryLongFunction(\n" |
| " int first_long_parameter, int second_parameter) {}"); |
| |
| verifyGoogleFormat("template <typename T>\n" |
| "aaaaaaaa::aaaaa::aaaaaa<T, aaaaaaaaaaaaaaaaaaaaaaaaa>\n" |
| "aaaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaa() {}"); |
| verifyGoogleFormat("A<A<A>> aaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("typedef size_t (*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n" |
| " const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " *aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa);"); |
| verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| |
| verifyFormat("template <typename T> // Templates on own line.\n" |
| "static int // Some comment.\n" |
| "MyFunction(int a);", |
| getLLVMStyle()); |
| } |
| |
| TEST_F(FormatTest, FormatsAccessModifiers) { |
| FormatStyle Style = getLLVMStyle(); |
| EXPECT_EQ(Style.EmptyLineBeforeAccessModifier, |
| FormatStyle::ELBAMS_LogicalBlock); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo { /* comment */\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo { /* comment */\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo { /* comment */\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo { /* comment */\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo { /* comment */\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Leave; |
| EXPECT_EQ("struct foo {\n" |
| "\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| EXPECT_EQ("struct foo { /* comment */\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo { /* comment */\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| verifyFormat("struct foo { /* comment */\n" |
| "private:\n" |
| " int i;\n" |
| " // comment\n" |
| "private:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| EXPECT_EQ("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| verifyFormat("struct foo {\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| "private:\n" |
| " int i;\n" |
| "#ifdef FOO\n" |
| "private:\n" |
| "#endif\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| FormatStyle NoEmptyLines = getLLVMStyle(); |
| NoEmptyLines.MaxEmptyLinesToKeep = 0; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "public:\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| NoEmptyLines); |
| |
| NoEmptyLines.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "private:\n" |
| " int i;\n" |
| "public:\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| NoEmptyLines); |
| |
| NoEmptyLines.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "public:\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| NoEmptyLines); |
| } |
| |
| TEST_F(FormatTest, FormatsAfterAccessModifiers) { |
| |
| FormatStyle Style = getLLVMStyle(); |
| EXPECT_EQ(Style.EmptyLineAfterAccessModifier, FormatStyle::ELAAMS_Never); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| // Check if lines are removed. |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| // Check if lines are added. |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| // Leave tests rely on the code layout, test::messUp can not be used. |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave; |
| Style.MaxEmptyLinesToKeep = 0u; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style); |
| |
| // Check if MaxEmptyLinesToKeep is respected. |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n\n\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n\n\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| |
| Style.MaxEmptyLinesToKeep = 1u; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| // Check if no lines are kept. |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| // Check if MaxEmptyLinesToKeep is respected. |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n\n\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n\n\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| |
| Style.MaxEmptyLinesToKeep = 10u; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n\n\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n\n\n" |
| " int j;\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| " void f() {}\n" |
| "\n" |
| "private:\n" |
| "\n\n\n" |
| " int i;\n" |
| "\n" |
| "protected:\n" |
| "\n\n\n" |
| " int j;\n" |
| "};\n", |
| Style)); |
| |
| // Test with comments. |
| Style = getLLVMStyle(); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| " int i;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| "\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| "\n" |
| " int i;\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| " // comment\n" |
| " void f() {}\n" |
| "\n" |
| "private: /* comment */\n" |
| "\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| |
| // Test with preprocessor defines. |
| Style = getLLVMStyle(); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| Style); |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| "#ifdef FOO\n" |
| "#endif\n" |
| " void f() {}\n" |
| "};\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsAfterAndBeforeAccessModifiersInteraction) { |
| // Combined tests of EmptyLineAfterAccessModifier and |
| // EmptyLineBeforeAccessModifier. |
| FormatStyle Style = getLLVMStyle(); |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| Style.MaxEmptyLinesToKeep = 10u; |
| // Both remove all new lines. |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| // Leave tests rely on the code layout, test::messUp can not be used. |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Leave; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave; |
| Style.MaxEmptyLinesToKeep = 10u; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); |
| Style.MaxEmptyLinesToKeep = 3u; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); |
| Style.MaxEmptyLinesToKeep = 1u; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); // Based on new lines in original document and not |
| // on the setting. |
| |
| Style.MaxEmptyLinesToKeep = 10u; |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave; |
| // Newlines are kept if they are greater than zero, |
| // test::messUp removes all new lines which changes the logic |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Leave; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| // test::messUp removes all new lines which changes the logic |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Leave; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); // test::messUp removes all new lines which changes |
| // the logic. |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Always; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; |
| EXPECT_EQ("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| format("struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style)); // test::messUp removes all new lines which changes |
| // the logic. |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_Never; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Always; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Leave; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock; |
| Style.EmptyLineAfterAccessModifier = FormatStyle::ELAAMS_Never; |
| verifyFormat("struct foo {\n" |
| "private:\n" |
| "protected:\n" |
| "};\n", |
| "struct foo {\n" |
| "private:\n" |
| "\n\n\n" |
| "protected:\n" |
| "};\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsArrays) { |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa]\n" |
| " [bbbbbbbbbbbbbbbbbbbbbbbbb] = c;"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaa(aaaaaaaaaaaa)]\n" |
| " [bbbbbbbbbbb(bbbbbbbbbbbb)] = c;"); |
| verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaa &&\n" |
| " aaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaa][aaaaaaaaaaaaa]) {\n}"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [a][bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = cccccccc;"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n" |
| " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;"); |
| verifyFormat( |
| "llvm::outs() << \"aaaaaaaaaaaa: \"\n" |
| " << (*aaaaaaaiaaaaaaa)[aaaaaaaaaaaaaaaaaaaaaaaaa]\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaa][a]\n" |
| " .aaaaaaaaaaaaaaaaaaaaaa();"); |
| |
| verifyGoogleFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<int>\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaa];"); |
| verifyFormat( |
| "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n" |
| " .aaaaaaa[0]\n" |
| " .aaaaaaaaaaaaaaaaaaaaaa();"); |
| verifyFormat("a[::b::c];"); |
| |
| verifyNoCrash("a[,Y?)]", getLLVMStyleWithColumns(10)); |
| |
| FormatStyle NoColumnLimit = getLLVMStyleWithColumns(0); |
| verifyFormat("aaaaa[bbbbbb].cccccc()", NoColumnLimit); |
| } |
| |
| TEST_F(FormatTest, LineStartsWithSpecialCharacter) { |
| verifyFormat("(a)->b();"); |
| verifyFormat("--a;"); |
| } |
| |
| TEST_F(FormatTest, HandlesIncludeDirectives) { |
| verifyFormat("#include <string>\n" |
| "#include <a/b/c.h>\n" |
| "#include \"a/b/string\"\n" |
| "#include \"string.h\"\n" |
| "#include \"string.h\"\n" |
| "#include <a-a>\n" |
| "#include < path with space >\n" |
| "#include_next <test.h>" |
| "#include \"abc.h\" // this is included for ABC\n" |
| "#include \"some long include\" // with a comment\n" |
| "#include \"some very long include path\"\n" |
| "#include <some/very/long/include/path>\n", |
| getLLVMStyleWithColumns(35)); |
| EXPECT_EQ("#include \"a.h\"", format("#include \"a.h\"")); |
| EXPECT_EQ("#include <a>", format("#include<a>")); |
| |
| verifyFormat("#import <string>"); |
| verifyFormat("#import <a/b/c.h>"); |
| verifyFormat("#import \"a/b/string\""); |
| verifyFormat("#import \"string.h\""); |
| verifyFormat("#import \"string.h\""); |
| verifyFormat("#if __has_include(<strstream>)\n" |
| "#include <strstream>\n" |
| "#endif"); |
| |
| verifyFormat("#define MY_IMPORT <a/b>"); |
| |
| verifyFormat("#if __has_include(<a/b>)"); |
| verifyFormat("#if __has_include_next(<a/b>)"); |
| verifyFormat("#define F __has_include(<a/b>)"); |
| verifyFormat("#define F __has_include_next(<a/b>)"); |
| |
| // Protocol buffer definition or missing "#". |
| verifyFormat("import \"aaaaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa\";", |
| getLLVMStyleWithColumns(30)); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.AlwaysBreakBeforeMultilineStrings = true; |
| Style.ColumnLimit = 0; |
| verifyFormat("#import \"abc.h\"", Style); |
| |
| // But 'import' might also be a regular C++ namespace. |
| verifyFormat("import::SomeFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Error recovery tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, IncompleteParameterLists) { |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackParameters = false; |
| verifyFormat("void aaaaaaaaaaaaaaaaaa(int level,\n" |
| " double *min_x,\n" |
| " double *max_x,\n" |
| " double *min_y,\n" |
| " double *max_y,\n" |
| " double *min_z,\n" |
| " double *max_z, ) {}", |
| NoBinPacking); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeTrailingStuff) { |
| verifyFormat("void f() { return; }\n42"); |
| verifyFormat("void f() {\n" |
| " if (0)\n" |
| " return;\n" |
| "}\n" |
| "42"); |
| verifyFormat("void f() { return }\n42"); |
| verifyFormat("void f() {\n" |
| " if (0)\n" |
| " return\n" |
| "}\n" |
| "42"); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeMissingSemicolon) { |
| EXPECT_EQ("void f() { return }", format("void f ( ) { return }")); |
| EXPECT_EQ("void f() {\n" |
| " if (a)\n" |
| " return\n" |
| "}", |
| format("void f ( ) { if ( a ) return }")); |
| EXPECT_EQ("namespace N {\n" |
| "void f()\n" |
| "}", |
| format("namespace N { void f() }")); |
| EXPECT_EQ("namespace N {\n" |
| "void f() {}\n" |
| "void g()\n" |
| "} // namespace N", |
| format("namespace N { void f( ) { } void g( ) }")); |
| } |
| |
| TEST_F(FormatTest, IndentationWithinColumnLimitNotPossible) { |
| verifyFormat("int aaaaaaaa =\n" |
| " // Overlylongcomment\n" |
| " b;", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("function(\n" |
| " ShortArgument,\n" |
| " LoooooooooooongArgument);\n", |
| getLLVMStyleWithColumns(20)); |
| } |
| |
| TEST_F(FormatTest, IncorrectAccessSpecifier) { |
| verifyFormat("public:"); |
| verifyFormat("class A {\n" |
| "public\n" |
| " void f() {}\n" |
| "};"); |
| verifyFormat("public\n" |
| "int qwerty;"); |
| verifyFormat("public\n" |
| "B {}"); |
| verifyFormat("public\n" |
| "{}"); |
| verifyFormat("public\n" |
| "B { int x; }"); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { |
| verifyFormat("{"); |
| verifyFormat("#})"); |
| verifyNoCrash("(/**/[:!] ?[)."); |
| } |
| |
| TEST_F(FormatTest, IncorrectUnbalancedBracesInMacrosWithUnicode) { |
| // Found by oss-fuzz: |
| // https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8212 |
| FormatStyle Style = getGoogleStyle(FormatStyle::LK_Cpp); |
| Style.ColumnLimit = 60; |
| verifyNoCrash( |
| "\x23\x47\xff\x20\x28\xff\x3c\xff\x3f\xff\x20\x2f\x7b\x7a\xff\x20" |
| "\xff\xff\xff\xca\xb5\xff\xff\xff\xff\x3a\x7b\x7d\xff\x20\xff\x20" |
| "\xff\x74\xff\x20\x7d\x7d\xff\x7b\x3a\xff\x20\x71\xff\x20\xff\x0a", |
| Style); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeDoNoWhile) { |
| verifyFormat("do {\n}"); |
| verifyFormat("do {\n}\n" |
| "f();"); |
| verifyFormat("do {\n}\n" |
| "wheeee(fun);"); |
| verifyFormat("do {\n" |
| " f();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeMissingParens) { |
| verifyFormat("if {\n foo;\n foo();\n}"); |
| verifyFormat("switch {\n foo;\n foo();\n}"); |
| verifyIncompleteFormat("for {\n foo;\n foo();\n}"); |
| verifyIncompleteFormat("ERROR: for target;"); |
| verifyFormat("while {\n foo;\n foo();\n}"); |
| verifyFormat("do {\n foo;\n foo();\n} while;"); |
| } |
| |
| TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) { |
| verifyIncompleteFormat("namespace {\n" |
| "class Foo { Foo (\n" |
| "};\n" |
| "} // namespace"); |
| } |
| |
| TEST_F(FormatTest, IncorrectCodeErrorDetection) { |
| EXPECT_EQ("{\n {}\n", format("{\n{\n}\n")); |
| EXPECT_EQ("{\n {}\n", format("{\n {\n}\n")); |
| EXPECT_EQ("{\n {}\n", format("{\n {\n }\n")); |
| EXPECT_EQ("{\n {}\n}\n}\n", format("{\n {\n }\n }\n}\n")); |
| |
| EXPECT_EQ("{\n" |
| " {\n" |
| " breakme(\n" |
| " qwe);\n" |
| " }\n", |
| format("{\n" |
| " {\n" |
| " breakme(qwe);\n" |
| "}\n", |
| getLLVMStyleWithColumns(10))); |
| } |
| |
| TEST_F(FormatTest, LayoutCallsInsideBraceInitializers) { |
| verifyFormat("int x = {\n" |
| " avariable,\n" |
| " b(alongervariable)};", |
| getLLVMStyleWithColumns(25)); |
| } |
| |
| TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) { |
| verifyFormat("return (a)(b){1, 2, 3};"); |
| } |
| |
| TEST_F(FormatTest, LayoutCxx11BraceInitializers) { |
| verifyFormat("vector<int> x{1, 2, 3, 4};"); |
| verifyFormat("vector<int> x{\n" |
| " 1,\n" |
| " 2,\n" |
| " 3,\n" |
| " 4,\n" |
| "};"); |
| verifyFormat("vector<T> x{{}, {}, {}, {}};"); |
| verifyFormat("f({1, 2});"); |
| verifyFormat("auto v = Foo{-1};"); |
| verifyFormat("f({1, 2}, {{2, 3}, {4, 5}}, c, {d});"); |
| verifyFormat("Class::Class : member{1, 2, 3} {}"); |
| verifyFormat("new vector<int>{1, 2, 3};"); |
| verifyFormat("new int[3]{1, 2, 3};"); |
| verifyFormat("new int{1};"); |
| verifyFormat("return {arg1, arg2};"); |
| verifyFormat("return {arg1, SomeType{parameter}};"); |
| verifyFormat("int count = set<int>{f(), g(), h()}.size();"); |
| verifyFormat("new T{arg1, arg2};"); |
| verifyFormat("f(MyMap[{composite, key}]);"); |
| verifyFormat("class Class {\n" |
| " T member = {arg1, arg2};\n" |
| "};"); |
| verifyFormat("vector<int> foo = {::SomeGlobalFunction()};"); |
| verifyFormat("const struct A a = {.a = 1, .b = 2};"); |
| verifyFormat("const struct A a = {[0] = 1, [1] = 2};"); |
| verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");"); |
| verifyFormat("int a = std::is_integral<int>{} + 0;"); |
| |
| verifyFormat("int foo(int i) { return fo1{}(i); }"); |
| verifyFormat("int foo(int i) { return fo1{}(i); }"); |
| verifyFormat("auto i = decltype(x){};"); |
| verifyFormat("auto i = typeof(x){};"); |
| verifyFormat("auto i = _Atomic(x){};"); |
| verifyFormat("std::vector<int> v = {1, 0 /* comment */};"); |
| verifyFormat("Node n{1, Node{1000}, //\n" |
| " 2};"); |
| verifyFormat("Aaaa aaaaaaa{\n" |
| " {\n" |
| " aaaa,\n" |
| " },\n" |
| "};"); |
| verifyFormat("class C : public D {\n" |
| " SomeClass SC{2};\n" |
| "};"); |
| verifyFormat("class C : public A {\n" |
| " class D : public B {\n" |
| " void f() { int i{2}; }\n" |
| " };\n" |
| "};"); |
| verifyFormat("#define A {a, a},"); |
| // Don't confuse braced list initializers with compound statements. |
| verifyFormat( |
| "class A {\n" |
| " A() : a{} {}\n" |
| " A(int b) : b(b) {}\n" |
| " A(int a, int b) : a(a), bs{{bs...}} { f(); }\n" |
| " int a, b;\n" |
| " explicit Expr(const Scalar<Result> &x) : u{Constant<Result>{x}} {}\n" |
| " explicit Expr(Scalar<Result> &&x) : u{Constant<Result>{std::move(x)}} " |
| "{}\n" |
| "};"); |
| |
| // Avoid breaking between equal sign and opening brace |
| FormatStyle AvoidBreakingFirstArgument = getLLVMStyle(); |
| AvoidBreakingFirstArgument.PenaltyBreakBeforeFirstCallParameter = 200; |
| verifyFormat("const std::unordered_map<std::string, int> MyHashTable =\n" |
| " {{\"aaaaaaaaaaaaaaaaaaaaa\", 0},\n" |
| " {\"bbbbbbbbbbbbbbbbbbbbb\", 1},\n" |
| " {\"ccccccccccccccccccccc\", 2}};", |
| AvoidBreakingFirstArgument); |
| |
| // Binpacking only if there is no trailing comma |
| verifyFormat("const Aaaaaa aaaaa = {aaaaaaaaaa, bbbbbbbbbb,\n" |
| " cccccccccc, dddddddddd};", |
| getLLVMStyleWithColumns(50)); |
| verifyFormat("const Aaaaaa aaaaa = {\n" |
| " aaaaaaaaaaa,\n" |
| " bbbbbbbbbbb,\n" |
| " ccccccccccc,\n" |
| " ddddddddddd,\n" |
| "};", |
| getLLVMStyleWithColumns(50)); |
| |
| // Cases where distinguising braced lists and blocks is hard. |
| verifyFormat("vector<int> v{12} GUARDED_BY(mutex);"); |
| verifyFormat("void f() {\n" |
| " return; // comment\n" |
| "}\n" |
| "SomeType t;"); |
| verifyFormat("void f() {\n" |
| " if (a) {\n" |
| " f();\n" |
| " }\n" |
| "}\n" |
| "SomeType t;"); |
| |
| // In combination with BinPackArguments = false. |
| FormatStyle NoBinPacking = getLLVMStyle(); |
| NoBinPacking.BinPackArguments = false; |
| verifyFormat("const Aaaaaa aaaaa = {aaaaa,\n" |
| " bbbbb,\n" |
| " ccccc,\n" |
| " ddddd,\n" |
| " eeeee,\n" |
| " ffffff,\n" |
| " ggggg,\n" |
| " hhhhhh,\n" |
| " iiiiii,\n" |
| " jjjjjj,\n" |
| " kkkkkk};", |
| NoBinPacking); |
| verifyFormat("const Aaaaaa aaaaa = {\n" |
| " aaaaa,\n" |
| " bbbbb,\n" |
| " ccccc,\n" |
| " ddddd,\n" |
| " eeeee,\n" |
| " ffffff,\n" |
| " ggggg,\n" |
| " hhhhhh,\n" |
| " iiiiii,\n" |
| " jjjjjj,\n" |
| " kkkkkk,\n" |
| "};", |
| NoBinPacking); |
| verifyFormat( |
| "const Aaaaaa aaaaa = {\n" |
| " aaaaa, bbbbb, ccccc, ddddd, eeeee, ffffff, ggggg, hhhhhh,\n" |
| " iiiiii, jjjjjj, kkkkkk, aaaaa, bbbbb, ccccc, ddddd, eeeee,\n" |
| " ffffff, ggggg, hhhhhh, iiiiii, jjjjjj, kkkkkk,\n" |
| "};", |
| NoBinPacking); |
| |
| NoBinPacking.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| EXPECT_EQ("static uint8 CddDp83848Reg[] = {\n" |
| " CDDDP83848_BMCR_REGISTER,\n" |
| " CDDDP83848_BMSR_REGISTER,\n" |
| " CDDDP83848_RBR_REGISTER};", |
| format("static uint8 CddDp83848Reg[] = {CDDDP83848_BMCR_REGISTER,\n" |
| " CDDDP83848_BMSR_REGISTER,\n" |
| " CDDDP83848_RBR_REGISTER};", |
| NoBinPacking)); |
| |
| // FIXME: The alignment of these trailing comments might be bad. Then again, |
| // this might be utterly useless in real code. |
| verifyFormat("Constructor::Constructor()\n" |
| " : some_value{ //\n" |
| " aaaaaaa, //\n" |
| " bbbbbbb} {}"); |
| |
| // In braced lists, the first comment is always assumed to belong to the |
| // first element. Thus, it can be moved to the next or previous line as |
| // appropriate. |
| EXPECT_EQ("function({// First element:\n" |
| " 1,\n" |
| " // Second element:\n" |
| " 2});", |
| format("function({\n" |
| " // First element:\n" |
| " 1,\n" |
| " // Second element:\n" |
| " 2});")); |
| EXPECT_EQ("std::vector<int> MyNumbers{\n" |
| " // First element:\n" |
| " 1,\n" |
| " // Second element:\n" |
| " 2};", |
| format("std::vector<int> MyNumbers{// First element:\n" |
| " 1,\n" |
| " // Second element:\n" |
| " 2};", |
| getLLVMStyleWithColumns(30))); |
| // A trailing comma should still lead to an enforced line break and no |
| // binpacking. |
| EXPECT_EQ("vector<int> SomeVector = {\n" |
| " // aaa\n" |
| " 1,\n" |
| " 2,\n" |
| "};", |
| format("vector<int> SomeVector = { // aaa\n" |
| " 1, 2, };")); |
| |
| // C++11 brace initializer list l-braces should not be treated any differently |
| // when breaking before lambda bodies is enabled |
| FormatStyle BreakBeforeLambdaBody = getLLVMStyle(); |
| BreakBeforeLambdaBody.BreakBeforeBraces = FormatStyle::BS_Custom; |
| BreakBeforeLambdaBody.BraceWrapping.BeforeLambdaBody = true; |
| BreakBeforeLambdaBody.AlwaysBreakBeforeMultilineStrings = true; |
| verifyFormat( |
| "std::runtime_error{\n" |
| " \"Long string which will force a break onto the next line...\"};", |
| BreakBeforeLambdaBody); |
| |
| FormatStyle ExtraSpaces = getLLVMStyle(); |
| ExtraSpaces.Cpp11BracedListStyle = false; |
| ExtraSpaces.ColumnLimit = 75; |
| verifyFormat("vector<int> x{ 1, 2, 3, 4 };", ExtraSpaces); |
| verifyFormat("vector<T> x{ {}, {}, {}, {} };", ExtraSpaces); |
| verifyFormat("f({ 1, 2 });", ExtraSpaces); |
| verifyFormat("auto v = Foo{ 1 };", ExtraSpaces); |
| verifyFormat("f({ 1, 2 }, { { 2, 3 }, { 4, 5 } }, c, { d });", ExtraSpaces); |
| verifyFormat("Class::Class : member{ 1, 2, 3 } {}", ExtraSpaces); |
| verifyFormat("new vector<int>{ 1, 2, 3 };", ExtraSpaces); |
| verifyFormat("new int[3]{ 1, 2, 3 };", ExtraSpaces); |
| verifyFormat("return { arg1, arg2 };", ExtraSpaces); |
| verifyFormat("return { arg1, SomeType{ parameter } };", ExtraSpaces); |
| verifyFormat("int count = set<int>{ f(), g(), h() }.size();", ExtraSpaces); |
| verifyFormat("new T{ arg1, arg2 };", ExtraSpaces); |
| verifyFormat("f(MyMap[{ composite, key }]);", ExtraSpaces); |
| verifyFormat("class Class {\n" |
| " T member = { arg1, arg2 };\n" |
| "};", |
| ExtraSpaces); |
| verifyFormat( |
| "foo = aaaaaaaaaaa ? vector<int>{ aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaa, aaaaa }\n" |
| " : vector<int>{ bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" |
| " bbbbbbbbbbbbbbbbbbbb, bbbbb };", |
| ExtraSpaces); |
| verifyFormat("DoSomethingWithVector({} /* No data */);", ExtraSpaces); |
| verifyFormat("DoSomethingWithVector({ {} /* No data */ }, { { 1, 2 } });", |
| ExtraSpaces); |
| verifyFormat( |
| "someFunction(OtherParam,\n" |
| " BracedList{ // comment 1 (Forcing interesting break)\n" |
| " param1, param2,\n" |
| " // comment 2\n" |
| " param3, param4 });", |
| ExtraSpaces); |
| verifyFormat( |
| "std::this_thread::sleep_for(\n" |
| " std::chrono::nanoseconds{ std::chrono::seconds{ 1 } } / 5);", |
| ExtraSpaces); |
| verifyFormat("std::vector<MyValues> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa{\n" |
| " aaaaaaa,\n" |
| " aaaaaaaaaa,\n" |
| " aaaaa,\n" |
| " aaaaaaaaaaaaaaa,\n" |
| " aaa,\n" |
| " aaaaaaaaaa,\n" |
| " a,\n" |
| " aaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaa,\n" |
| " a};"); |
| verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces); |
| verifyFormat("const struct A a = { .a = 1, .b = 2 };", ExtraSpaces); |
| verifyFormat("const struct A a = { [0] = 1, [1] = 2 };", ExtraSpaces); |
| |
| // Avoid breaking between initializer/equal sign and opening brace |
| ExtraSpaces.PenaltyBreakBeforeFirstCallParameter = 200; |
| verifyFormat("const std::unordered_map<std::string, int> MyHashTable = {\n" |
| " { \"aaaaaaaaaaaaaaaaaaaaa\", 0 },\n" |
| " { \"bbbbbbbbbbbbbbbbbbbbb\", 1 },\n" |
| " { \"ccccccccccccccccccccc\", 2 }\n" |
| "};", |
| ExtraSpaces); |
| verifyFormat("const std::unordered_map<std::string, int> MyHashTable{\n" |
| " { \"aaaaaaaaaaaaaaaaaaaaa\", 0 },\n" |
| " { \"bbbbbbbbbbbbbbbbbbbbb\", 1 },\n" |
| " { \"ccccccccccccccccccccc\", 2 }\n" |
| "};", |
| ExtraSpaces); |
| |
| FormatStyle SpaceBeforeBrace = getLLVMStyle(); |
| SpaceBeforeBrace.SpaceBeforeCpp11BracedList = true; |
| verifyFormat("vector<int> x {1, 2, 3, 4};", SpaceBeforeBrace); |
| verifyFormat("f({}, {{}, {}}, MyMap[{k, v}]);", SpaceBeforeBrace); |
| |
| FormatStyle SpaceBetweenBraces = getLLVMStyle(); |
| SpaceBetweenBraces.SpacesInAngles = FormatStyle::SIAS_Always; |
| SpaceBetweenBraces.SpacesInParentheses = true; |
| SpaceBetweenBraces.SpacesInSquareBrackets = true; |
| verifyFormat("vector< int > x{ 1, 2, 3, 4 };", SpaceBetweenBraces); |
| verifyFormat("f( {}, { {}, {} }, MyMap[ { k, v } ] );", SpaceBetweenBraces); |
| verifyFormat("vector< int > x{ // comment 1\n" |
| " 1, 2, 3, 4 };", |
| SpaceBetweenBraces); |
| SpaceBetweenBraces.ColumnLimit = 20; |
| EXPECT_EQ("vector< int > x{\n" |
| " 1, 2, 3, 4 };", |
| format("vector<int>x{1,2,3,4};", SpaceBetweenBraces)); |
| SpaceBetweenBraces.ColumnLimit = 24; |
| EXPECT_EQ("vector< int > x{ 1, 2,\n" |
| " 3, 4 };", |
| format("vector<int>x{1,2,3,4};", SpaceBetweenBraces)); |
| EXPECT_EQ("vector< int > x{\n" |
| " 1,\n" |
| " 2,\n" |
| " 3,\n" |
| " 4,\n" |
| "};", |
| format("vector<int>x{1,2,3,4,};", SpaceBetweenBraces)); |
| verifyFormat("vector< int > x{};", SpaceBetweenBraces); |
| SpaceBetweenBraces.SpaceInEmptyParentheses = true; |
| verifyFormat("vector< int > x{ };", SpaceBetweenBraces); |
| } |
| |
| TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { |
| verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777};"); |
| verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777, //\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, //\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777};"); |
| verifyFormat( |
| "vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, // comment\n" |
| " 7777777, 1, 22, 333, 4444, 55555, 666666,\n" |
| " 7777777, 1, 22, 333, 4444, 55555, 666666,\n" |
| " 7777777, 1, 22, 333, 4444, 55555, 666666,\n" |
| " 7777777};"); |
| verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" |
| " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" |
| " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); |
| verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" |
| " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" |
| " // Separating comment.\n" |
| " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); |
| verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n" |
| " // Leading comment\n" |
| " X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n" |
| " X86::R8, X86::R9, X86::R10, X86::R11, 0};"); |
| verifyFormat("vector<int> x = {1, 1, 1, 1,\n" |
| " 1, 1, 1, 1};", |
| getLLVMStyleWithColumns(39)); |
| verifyFormat("vector<int> x = {1, 1, 1, 1,\n" |
| " 1, 1, 1, 1};", |
| getLLVMStyleWithColumns(38)); |
| verifyFormat("vector<int> aaaaaaaaaaaaaaaaaaaaaa = {\n" |
| " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};", |
| getLLVMStyleWithColumns(43)); |
| verifyFormat( |
| "static unsigned SomeValues[10][3] = {\n" |
| " {1, 4, 0}, {4, 9, 0}, {4, 5, 9}, {8, 5, 4}, {1, 8, 4},\n" |
| " {10, 1, 6}, {11, 0, 9}, {2, 11, 9}, {5, 2, 9}, {11, 2, 7}};"); |
| verifyFormat("static auto fields = new vector<string>{\n" |
| " \"aaaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaa\",\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n" |
| "};"); |
| verifyFormat("vector<int> x = {1, 2, 3, 4, aaaaaaaaaaaaaaaaa, 6};"); |
| verifyFormat("vector<int> x = {1, aaaaaaaaaaaaaaaaaaaaaa,\n" |
| " 2, bbbbbbbbbbbbbbbbbbbbbb,\n" |
| " 3, cccccccccccccccccccccc};", |
| getLLVMStyleWithColumns(60)); |
| |
| // Trailing commas. |
| verifyFormat("vector<int> x = {\n" |
| " 1, 1, 1, 1, 1, 1, 1, 1,\n" |
| "};", |
| getLLVMStyleWithColumns(39)); |
| verifyFormat("vector<int> x = {\n" |
| " 1, 1, 1, 1, 1, 1, 1, 1, //\n" |
| "};", |
| getLLVMStyleWithColumns(39)); |
| verifyFormat("vector<int> x = {1, 1, 1, 1,\n" |
| " 1, 1, 1, 1,\n" |
| " /**/ /**/};", |
| getLLVMStyleWithColumns(39)); |
| |
| // Trailing comment in the first line. |
| verifyFormat("vector<int> iiiiiiiiiiiiiii = { //\n" |
| " 1111111111, 2222222222, 33333333333, 4444444444, //\n" |
| " 111111111, 222222222, 3333333333, 444444444, //\n" |
| " 11111111, 22222222, 333333333, 44444444};"); |
| // Trailing comment in the last line. |
| verifyFormat("int aaaaa[] = {\n" |
| " 1, 2, 3, // comment\n" |
| " 4, 5, 6 // comment\n" |
| "};"); |
| |
| // With nested lists, we should either format one item per line or all nested |
| // lists one on line. |
| // FIXME: For some nested lists, we can do better. |
| verifyFormat("return {{aaaaaaaaaaaaaaaaaaaaa},\n" |
| " {aaaaaaaaaaaaaaaaaaa},\n" |
| " {aaaaaaaaaaaaaaaaaaaaa},\n" |
| " {aaaaaaaaaaaaaaaaa}};", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat( |
| "SomeStruct my_struct_array = {\n" |
| " {aaaaaa, aaaaaaaa, aaaaaaaaaa, aaaaaaaaa, aaaaaaaaa, aaaaaaaaaa,\n" |
| " aaaaaaaaaaaaa, aaaaaaa, aaa},\n" |
| " {aaa, aaa},\n" |
| " {aaa, aaa},\n" |
| " {aaaa, aaaa, aaaa, aaaa, aaaa, aaaa, aaaa, aaa},\n" |
| " {aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaaaaaaaa, a, aaaaaaaaaa, aaaaaaaaa, aaa}};"); |
| |
| // No column layout should be used here. |
| verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n" |
| " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};"); |
| |
| verifyNoCrash("a<,"); |
| |
| // No braced initializer here. |
| verifyFormat("void f() {\n" |
| " struct Dummy {};\n" |
| " f(v);\n" |
| "}"); |
| |
| // Long lists should be formatted in columns even if they are nested. |
| verifyFormat( |
| "vector<int> x = function({1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777,\n" |
| " 1, 22, 333, 4444, 55555, 666666, 7777777});"); |
| |
| // Allow "single-column" layout even if that violates the column limit. There |
| // isn't going to be a better way. |
| verifyFormat("std::vector<int> a = {\n" |
| " aaaaaaaa,\n" |
| " aaaaaaaa,\n" |
| " aaaaaaaa,\n" |
| " aaaaaaaa,\n" |
| " aaaaaaaaaa,\n" |
| " aaaaaaaa,\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaa};", |
| getLLVMStyleWithColumns(30)); |
| verifyFormat("vector<int> aaaa = {\n" |
| " aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaa.aaaaaaa,\n" |
| " aaaaaa.aaaaaaa,\n" |
| " aaaaaa.aaaaaaa,\n" |
| " aaaaaa.aaaaaaa,\n" |
| "};"); |
| |
| // Don't create hanging lists. |
| verifyFormat("someFunction(Param, {List1, List2,\n" |
| " List3});", |
| getLLVMStyleWithColumns(35)); |
| verifyFormat("someFunction(Param, Param,\n" |
| " {List1, List2,\n" |
| " List3});", |
| getLLVMStyleWithColumns(35)); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaa, {},\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa);"); |
| } |
| |
| TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { |
| FormatStyle DoNotMerge = getLLVMStyle(); |
| DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| |
| verifyFormat("void f() { return 42; }"); |
| verifyFormat("void f() {\n" |
| " return 42;\n" |
| "}", |
| DoNotMerge); |
| verifyFormat("void f() {\n" |
| " // Comment\n" |
| "}"); |
| verifyFormat("{\n" |
| "#error {\n" |
| " int a;\n" |
| "}"); |
| verifyFormat("{\n" |
| " int a;\n" |
| "#error {\n" |
| "}"); |
| verifyFormat("void f() {} // comment"); |
| verifyFormat("void f() { int a; } // comment"); |
| verifyFormat("void f() {\n" |
| "} // comment", |
| DoNotMerge); |
| verifyFormat("void f() {\n" |
| " int a;\n" |
| "} // comment", |
| DoNotMerge); |
| verifyFormat("void f() {\n" |
| "} // comment", |
| getLLVMStyleWithColumns(15)); |
| |
| verifyFormat("void f() { return 42; }", getLLVMStyleWithColumns(23)); |
| verifyFormat("void f() {\n return 42;\n}", getLLVMStyleWithColumns(22)); |
| |
| verifyFormat("void f() {}", getLLVMStyleWithColumns(11)); |
| verifyFormat("void f() {\n}", getLLVMStyleWithColumns(10)); |
| verifyFormat("class C {\n" |
| " C()\n" |
| " : iiiiiiii(nullptr),\n" |
| " kkkkkkk(nullptr),\n" |
| " mmmmmmm(nullptr),\n" |
| " nnnnnnn(nullptr) {}\n" |
| "};", |
| getGoogleStyle()); |
| |
| FormatStyle NoColumnLimit = getLLVMStyleWithColumns(0); |
| EXPECT_EQ("A() : b(0) {}", format("A():b(0){}", NoColumnLimit)); |
| EXPECT_EQ("class C {\n" |
| " A() : b(0) {}\n" |
| "};", |
| format("class C{A():b(0){}};", NoColumnLimit)); |
| EXPECT_EQ("A()\n" |
| " : b(0) {\n" |
| "}", |
| format("A()\n:b(0)\n{\n}", NoColumnLimit)); |
| |
| FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit; |
| DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine = |
| FormatStyle::SFS_None; |
| EXPECT_EQ("A()\n" |
| " : b(0) {\n" |
| "}", |
| format("A():b(0){}", DoNotMergeNoColumnLimit)); |
| EXPECT_EQ("A()\n" |
| " : b(0) {\n" |
| "}", |
| format("A()\n:b(0)\n{\n}", DoNotMergeNoColumnLimit)); |
| |
| verifyFormat("#define A \\\n" |
| " void f() { \\\n" |
| " int i; \\\n" |
| " }", |
| getLLVMStyleWithColumns(20)); |
| verifyFormat("#define A \\\n" |
| " void f() { int i; }", |
| getLLVMStyleWithColumns(21)); |
| verifyFormat("#define A \\\n" |
| " void f() { \\\n" |
| " int i; \\\n" |
| " } \\\n" |
| " int j;", |
| getLLVMStyleWithColumns(22)); |
| verifyFormat("#define A \\\n" |
| " void f() { int i; } \\\n" |
| " int j;", |
| getLLVMStyleWithColumns(23)); |
| } |
| |
| TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) { |
| FormatStyle MergeEmptyOnly = getLLVMStyle(); |
| MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeEmptyOnly); |
| verifyFormat("class C {\n" |
| " int f() {\n" |
| " return 42;\n" |
| " }\n" |
| "};", |
| MergeEmptyOnly); |
| verifyFormat("int f() {}", MergeEmptyOnly); |
| verifyFormat("int f() {\n" |
| " return 42;\n" |
| "}", |
| MergeEmptyOnly); |
| |
| // Also verify behavior when BraceWrapping.AfterFunction = true |
| MergeEmptyOnly.BreakBeforeBraces = FormatStyle::BS_Custom; |
| MergeEmptyOnly.BraceWrapping.AfterFunction = true; |
| verifyFormat("int f() {}", MergeEmptyOnly); |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeEmptyOnly); |
| } |
| |
| TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) { |
| FormatStyle MergeInlineOnly = getLLVMStyle(); |
| MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; |
| verifyFormat("class C {\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f() {\n" |
| " return 42;\n" |
| "}", |
| MergeInlineOnly); |
| |
| // SFS_Inline implies SFS_Empty |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f() {}", MergeInlineOnly); |
| // https://llvm.org/PR54147 |
| verifyFormat("auto lambda = []() {\n" |
| " // comment\n" |
| " f();\n" |
| " g();\n" |
| "};", |
| MergeInlineOnly); |
| |
| verifyFormat("class C {\n" |
| "#ifdef A\n" |
| " int f() { return 42; }\n" |
| "#endif\n" |
| "};", |
| MergeInlineOnly); |
| |
| verifyFormat("struct S {\n" |
| "// comment\n" |
| "#ifdef FOO\n" |
| " int foo() { bar(); }\n" |
| "#endif\n" |
| "};", |
| MergeInlineOnly); |
| |
| // Also verify behavior when BraceWrapping.AfterFunction = true |
| MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom; |
| MergeInlineOnly.BraceWrapping.AfterFunction = true; |
| verifyFormat("class C {\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f()\n" |
| "{\n" |
| " return 42;\n" |
| "}", |
| MergeInlineOnly); |
| |
| // SFS_Inline implies SFS_Empty |
| verifyFormat("int f() {}", MergeInlineOnly); |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeInlineOnly); |
| |
| MergeInlineOnly.BraceWrapping.AfterClass = true; |
| MergeInlineOnly.BraceWrapping.AfterStruct = true; |
| verifyFormat("class C\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("struct C\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f()\n" |
| "{\n" |
| " return 42;\n" |
| "}", |
| MergeInlineOnly); |
| verifyFormat("int f() {}", MergeInlineOnly); |
| verifyFormat("class C\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("struct C\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("struct C\n" |
| "// comment\n" |
| "/* comment */\n" |
| "// comment\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("/* comment */ struct C\n" |
| "{\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| } |
| |
| TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) { |
| FormatStyle MergeInlineOnly = getLLVMStyle(); |
| MergeInlineOnly.AllowShortFunctionsOnASingleLine = |
| FormatStyle::SFS_InlineOnly; |
| verifyFormat("class C {\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f() {\n" |
| " return 42;\n" |
| "}", |
| MergeInlineOnly); |
| |
| // SFS_InlineOnly does not imply SFS_Empty |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f() {\n" |
| "}", |
| MergeInlineOnly); |
| |
| // Also verify behavior when BraceWrapping.AfterFunction = true |
| MergeInlineOnly.BreakBeforeBraces = FormatStyle::BS_Custom; |
| MergeInlineOnly.BraceWrapping.AfterFunction = true; |
| verifyFormat("class C {\n" |
| " int f() { return 42; }\n" |
| "};", |
| MergeInlineOnly); |
| verifyFormat("int f()\n" |
| "{\n" |
| " return 42;\n" |
| "}", |
| MergeInlineOnly); |
| |
| // SFS_InlineOnly does not imply SFS_Empty |
| verifyFormat("int f()\n" |
| "{\n" |
| "}", |
| MergeInlineOnly); |
| verifyFormat("class C {\n" |
| " int f() {}\n" |
| "};", |
| MergeInlineOnly); |
| } |
| |
| TEST_F(FormatTest, SplitEmptyFunction) { |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| Style.BraceWrapping.SplitEmptyFunction = false; |
| |
| verifyFormat("int f()\n" |
| "{}", |
| Style); |
| verifyFormat("int f()\n" |
| "{\n" |
| " return 42;\n" |
| "}", |
| Style); |
| verifyFormat("int f()\n" |
| "{\n" |
| " // some comment\n" |
| "}", |
| Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty; |
| verifyFormat("int f() {}", Style); |
| verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" |
| "{}", |
| Style); |
| verifyFormat("int f()\n" |
| "{\n" |
| " return 0;\n" |
| "}", |
| Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; |
| verifyFormat("class Foo {\n" |
| " int f() {}\n" |
| "};\n", |
| Style); |
| verifyFormat("class Foo {\n" |
| " int f() { return 0; }\n" |
| "};\n", |
| Style); |
| verifyFormat("class Foo {\n" |
| " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" |
| " {}\n" |
| "};\n", |
| Style); |
| verifyFormat("class Foo {\n" |
| " int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" |
| " {\n" |
| " return 0;\n" |
| " }\n" |
| "};\n", |
| Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| verifyFormat("int f() {}", Style); |
| verifyFormat("int f() { return 0; }", Style); |
| verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" |
| "{}", |
| Style); |
| verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n" |
| "{\n" |
| " return 0;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) { |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterFunction = true; |
| Style.BraceWrapping.SplitEmptyFunction = true; |
| Style.BraceWrapping.SplitEmptyRecord = false; |
| |
| verifyFormat("class C {};", Style); |
| verifyFormat("struct C {};", Style); |
| verifyFormat("void f(int aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbbbbbbbbbbbbb)\n" |
| "{\n" |
| "}", |
| Style); |
| verifyFormat("class C {\n" |
| " C()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaaaaaa(),\n" |
| " bbbbbbbbbbbbbbbbbbb()\n" |
| " {\n" |
| " }\n" |
| " void\n" |
| " m(int aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " int bbbbbbbbbbbbbbbbbbbbbbbb)\n" |
| " {\n" |
| " }\n" |
| "};", |
| Style); |
| } |
| |
| TEST_F(FormatTest, KeepShortFunctionAfterPPElse) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| verifyFormat("#ifdef A\n" |
| "int f() {}\n" |
| "#else\n" |
| "int g() {}\n" |
| "#endif", |
| Style); |
| } |
| |
| TEST_F(FormatTest, SplitEmptyClass) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterClass = true; |
| Style.BraceWrapping.SplitEmptyRecord = false; |
| |
| verifyFormat("class Foo\n" |
| "{};", |
| Style); |
| verifyFormat("/* something */ class Foo\n" |
| "{};", |
| Style); |
| verifyFormat("template <typename X> class Foo\n" |
| "{};", |
| Style); |
| verifyFormat("class Foo\n" |
| "{\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef class Foo\n" |
| "{\n" |
| "} Foo_t;", |
| Style); |
| |
| Style.BraceWrapping.SplitEmptyRecord = true; |
| Style.BraceWrapping.AfterStruct = true; |
| verifyFormat("class rep\n" |
| "{\n" |
| "};", |
| Style); |
| verifyFormat("struct rep\n" |
| "{\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> class rep\n" |
| "{\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> struct rep\n" |
| "{\n" |
| "};", |
| Style); |
| verifyFormat("class rep\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("struct rep\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> class rep\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> struct rep\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> class rep // Foo\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> struct rep // Bar\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| |
| verifyFormat("template <typename T> class rep<T>\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| |
| verifyFormat("template <typename T> class rep<std::complex<T>>\n" |
| "{\n" |
| " int x;\n" |
| "};", |
| Style); |
| verifyFormat("template <typename T> class rep<std::complex<T>>\n" |
| "{\n" |
| "};", |
| Style); |
| |
| verifyFormat("#include \"stdint.h\"\n" |
| "namespace rep {}", |
| Style); |
| verifyFormat("#include <stdint.h>\n" |
| "namespace rep {}", |
| Style); |
| verifyFormat("#include <stdint.h>\n" |
| "namespace rep {}", |
| "#include <stdint.h>\n" |
| "namespace rep {\n" |
| "\n" |
| "\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, SplitEmptyStruct) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterStruct = true; |
| Style.BraceWrapping.SplitEmptyRecord = false; |
| |
| verifyFormat("struct Foo\n" |
| "{};", |
| Style); |
| verifyFormat("/* something */ struct Foo\n" |
| "{};", |
| Style); |
| verifyFormat("template <typename X> struct Foo\n" |
| "{};", |
| Style); |
| verifyFormat("struct Foo\n" |
| "{\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef struct Foo\n" |
| "{\n" |
| "} Foo_t;", |
| Style); |
| // typedef struct Bar {} Bar_t; |
| } |
| |
| TEST_F(FormatTest, SplitEmptyUnion) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterUnion = true; |
| Style.BraceWrapping.SplitEmptyRecord = false; |
| |
| verifyFormat("union Foo\n" |
| "{};", |
| Style); |
| verifyFormat("/* something */ union Foo\n" |
| "{};", |
| Style); |
| verifyFormat("union Foo\n" |
| "{\n" |
| " A,\n" |
| "};", |
| Style); |
| verifyFormat("typedef union Foo\n" |
| "{\n" |
| "} Foo_t;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, SplitEmptyNamespace) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterNamespace = true; |
| Style.BraceWrapping.SplitEmptyNamespace = false; |
| |
| verifyFormat("namespace Foo\n" |
| "{};", |
| Style); |
| verifyFormat("/* something */ namespace Foo\n" |
| "{};", |
| Style); |
| verifyFormat("inline namespace Foo\n" |
| "{};", |
| Style); |
| verifyFormat("/* something */ inline namespace Foo\n" |
| "{};", |
| Style); |
| verifyFormat("export namespace Foo\n" |
| "{};", |
| Style); |
| verifyFormat("namespace Foo\n" |
| "{\n" |
| "void Bar();\n" |
| "};", |
| Style); |
| } |
| |
| TEST_F(FormatTest, NeverMergeShortRecords) { |
| FormatStyle Style = getLLVMStyle(); |
| |
| verifyFormat("class Foo {\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef class Foo {\n" |
| " Foo();\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("struct Foo {\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef struct Foo {\n" |
| " Foo();\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("union Foo {\n" |
| " A,\n" |
| "};", |
| Style); |
| verifyFormat("typedef union Foo {\n" |
| " A,\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("namespace Foo {\n" |
| "void Bar();\n" |
| "};", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterClass = true; |
| Style.BraceWrapping.AfterStruct = true; |
| Style.BraceWrapping.AfterUnion = true; |
| Style.BraceWrapping.AfterNamespace = true; |
| verifyFormat("class Foo\n" |
| "{\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef class Foo\n" |
| "{\n" |
| " Foo();\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("struct Foo\n" |
| "{\n" |
| " Foo();\n" |
| "};", |
| Style); |
| verifyFormat("typedef struct Foo\n" |
| "{\n" |
| " Foo();\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("union Foo\n" |
| "{\n" |
| " A,\n" |
| "};", |
| Style); |
| verifyFormat("typedef union Foo\n" |
| "{\n" |
| " A,\n" |
| "} Foo_t;", |
| Style); |
| verifyFormat("namespace Foo\n" |
| "{\n" |
| "void Bar();\n" |
| "};", |
| Style); |
| } |
| |
| TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { |
| // Elaborate type variable declarations. |
| verifyFormat("struct foo a = {bar};\nint n;"); |
| verifyFormat("class foo a = {bar};\nint n;"); |
| verifyFormat("union foo a = {bar};\nint n;"); |
| |
| // Elaborate types inside function definitions. |
| verifyFormat("struct foo f() {}\nint n;"); |
| verifyFormat("class foo f() {}\nint n;"); |
| verifyFormat("union foo f() {}\nint n;"); |
| |
| // Templates. |
| verifyFormat("template <class X> void f() {}\nint n;"); |
| verifyFormat("template <struct X> void f() {}\nint n;"); |
| verifyFormat("template <union X> void f() {}\nint n;"); |
| |
| // Actual definitions... |
| verifyFormat("struct {\n} n;"); |
| verifyFormat( |
| "template <template <class T, class Y>, class Z> class X {\n} n;"); |
| verifyFormat("union Z {\n int n;\n} x;"); |
| verifyFormat("class MACRO Z {\n} n;"); |
| verifyFormat("class MACRO(X) Z {\n} n;"); |
| verifyFormat("class __attribute__(X) Z {\n} n;"); |
| verifyFormat("class __declspec(X) Z {\n} n;"); |
| verifyFormat("class A##B##C {\n} n;"); |
| verifyFormat("class alignas(16) Z {\n} n;"); |
| verifyFormat("class MACRO(X) alignas(16) Z {\n} n;"); |
| verifyFormat("class MACROA MACRO(X) Z {\n} n;"); |
| |
| // Redefinition from nested context: |
| verifyFormat("class A::B::C {\n} n;"); |
| |
| // Template definitions. |
| verifyFormat( |
| "template <typename F>\n" |
| "Matcher(const Matcher<F> &Other,\n" |
| " typename enable_if_c<is_base_of<F, T>::value &&\n" |
| " !is_same<F, T>::value>::type * = 0)\n" |
| " : Implementation(new ImplicitCastMatcher<F>(Other)) {}"); |
| |
| // FIXME: This is still incorrectly handled at the formatter side. |
| verifyFormat("template <> struct X < 15, i<3 && 42 < 50 && 33 < 28> {};"); |
| verifyFormat("int i = SomeFunction(a<b, a> b);"); |
| |
| // FIXME: |
| // This now gets parsed incorrectly as class definition. |
| // verifyFormat("class A<int> f() {\n}\nint n;"); |
| |
| // Elaborate types where incorrectly parsing the structural element would |
| // break the indent. |
| verifyFormat("if (true)\n" |
| " class X x;\n" |
| "else\n" |
| " f();\n"); |
| |
| // This is simply incomplete. Formatting is not important, but must not crash. |
| verifyFormat("class A:"); |
| } |
| |
| TEST_F(FormatTest, DoNotInterfereWithErrorAndWarning) { |
| EXPECT_EQ("#error Leave all white!!!!! space* alone!\n", |
| format("#error Leave all white!!!!! space* alone!\n")); |
| EXPECT_EQ( |
| "#warning Leave all white!!!!! space* alone!\n", |
| format("#warning Leave all white!!!!! space* alone!\n")); |
| EXPECT_EQ("#error 1", format(" # error 1")); |
| EXPECT_EQ("#warning 1", format(" # warning 1")); |
| } |
| |
| TEST_F(FormatTest, FormatHashIfExpressions) { |
| verifyFormat("#if AAAA && BBBB"); |
| verifyFormat("#if (AAAA && BBBB)"); |
| verifyFormat("#elif (AAAA && BBBB)"); |
| // FIXME: Come up with a better indentation for #elif. |
| verifyFormat( |
| "#if !defined(AAAAAAA) && (defined CCCCCC || defined DDDDDD) && \\\n" |
| " defined(BBBBBBBB)\n" |
| "#elif !defined(AAAAAA) && (defined CCCCC || defined DDDDDD) && \\\n" |
| " defined(BBBBBBBB)\n" |
| "#endif", |
| getLLVMStyleWithColumns(65)); |
| } |
| |
| TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) { |
| FormatStyle AllowsMergedIf = getGoogleStyle(); |
| AllowsMergedIf.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| verifyFormat("void f() { f(); }\n#error E", AllowsMergedIf); |
| verifyFormat("if (true) return 42;\n#error E", AllowsMergedIf); |
| verifyFormat("if (true)\n#error E\n return 42;", AllowsMergedIf); |
| EXPECT_EQ("if (true) return 42;", |
| format("if (true)\nreturn 42;", AllowsMergedIf)); |
| FormatStyle ShortMergedIf = AllowsMergedIf; |
| ShortMergedIf.ColumnLimit = 25; |
| verifyFormat("#define A \\\n" |
| " if (true) return 42;", |
| ShortMergedIf); |
| verifyFormat("#define A \\\n" |
| " f(); \\\n" |
| " if (true)\n" |
| "#define B", |
| ShortMergedIf); |
| verifyFormat("#define A \\\n" |
| " f(); \\\n" |
| " if (true)\n" |
| "g();", |
| ShortMergedIf); |
| verifyFormat("{\n" |
| "#ifdef A\n" |
| " // Comment\n" |
| " if (true) continue;\n" |
| "#endif\n" |
| " // Comment\n" |
| " if (true) continue;\n" |
| "}", |
| ShortMergedIf); |
| ShortMergedIf.ColumnLimit = 33; |
| verifyFormat("#define A \\\n" |
| " if constexpr (true) return 42;", |
| ShortMergedIf); |
| verifyFormat("#define A \\\n" |
| " if CONSTEXPR (true) return 42;", |
| ShortMergedIf); |
| ShortMergedIf.ColumnLimit = 29; |
| verifyFormat("#define A \\\n" |
| " if (aaaaaaaaaa) return 1; \\\n" |
| " return 2;", |
| ShortMergedIf); |
| ShortMergedIf.ColumnLimit = 28; |
| verifyFormat("#define A \\\n" |
| " if (aaaaaaaaaa) \\\n" |
| " return 1; \\\n" |
| " return 2;", |
| ShortMergedIf); |
| verifyFormat("#define A \\\n" |
| " if constexpr (aaaaaaa) \\\n" |
| " return 1; \\\n" |
| " return 2;", |
| ShortMergedIf); |
| verifyFormat("#define A \\\n" |
| " if CONSTEXPR (aaaaaaa) \\\n" |
| " return 1; \\\n" |
| " return 2;", |
| ShortMergedIf); |
| |
| verifyFormat("//\n" |
| "#define a \\\n" |
| " if \\\n" |
| " 0", |
| getChromiumStyle(FormatStyle::LK_Cpp)); |
| } |
| |
| TEST_F(FormatTest, FormatStarDependingOnContext) { |
| verifyFormat("void f(int *a);"); |
| verifyFormat("void f() { f(fint * b); }"); |
| verifyFormat("class A {\n void f(int *a);\n};"); |
| verifyFormat("class A {\n int *a;\n};"); |
| verifyFormat("namespace a {\n" |
| "namespace b {\n" |
| "class A {\n" |
| " void f() {}\n" |
| " int *a;\n" |
| "};\n" |
| "} // namespace b\n" |
| "} // namespace a"); |
| } |
| |
| TEST_F(FormatTest, SpecialTokensAtEndOfLine) { |
| verifyFormat("while"); |
| verifyFormat("operator"); |
| } |
| |
| TEST_F(FormatTest, SkipsDeeplyNestedLines) { |
| // This code would be painfully slow to format if we didn't skip it. |
| std::string Code("A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" // 20x |
| "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" |
| "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" |
| "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" |
| "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" |
| "A(1, 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" // 10x |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" |
| ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1);\n"); |
| // Deeply nested part is untouched, rest is formatted. |
| EXPECT_EQ(std::string("int i;\n") + Code + "int j;\n", |
| format(std::string("int i;\n") + Code + "int j;\n", |
| getLLVMStyle(), SC_ExpectIncomplete)); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Objective-C tests. |
| //===----------------------------------------------------------------------===// |
| |
| TEST_F(FormatTest, FormatForObjectiveCMethodDecls) { |
| verifyFormat("- (void)sendAction:(SEL)aSelector to:(BOOL)anObject;"); |
| EXPECT_EQ("- (NSUInteger)indexOfObject:(id)anObject;", |
| format("-(NSUInteger)indexOfObject:(id)anObject;")); |
| EXPECT_EQ("- (NSInteger)Mthod1;", format("-(NSInteger)Mthod1;")); |
| EXPECT_EQ("+ (id)Mthod2;", format("+(id)Mthod2;")); |
| EXPECT_EQ("- (NSInteger)Method3:(id)anObject;", |
| format("-(NSInteger)Method3:(id)anObject;")); |
| EXPECT_EQ("- (NSInteger)Method4:(id)anObject;", |
| format("-(NSInteger)Method4:(id)anObject;")); |
| EXPECT_EQ("- (NSInteger)Method5:(id)anObject:(id)AnotherObject;", |
| format("-(NSInteger)Method5:(id)anObject:(id)AnotherObject;")); |
| EXPECT_EQ("- (id)Method6:(id)A:(id)B:(id)C:(id)D;", |
| format("- (id)Method6:(id)A:(id)B:(id)C:(id)D;")); |
| EXPECT_EQ("- (void)sendAction:(SEL)aSelector to:(id)anObject " |
| "forAllCells:(BOOL)flag;", |
| format("- (void)sendAction:(SEL)aSelector to:(id)anObject " |
| "forAllCells:(BOOL)flag;")); |
| |
| // Very long objectiveC method declaration. |
| verifyFormat("- (void)aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n" |
| " (SoooooooooooooooooooooomeType *)bbbbbbbbbb;"); |
| verifyFormat("- (NSUInteger)indexOfObject:(id)anObject\n" |
| " inRange:(NSRange)range\n" |
| " outRange:(NSRange)out_range\n" |
| " outRange1:(NSRange)out_range1\n" |
| " outRange2:(NSRange)out_range2\n" |
| " outRange3:(NSRange)out_range3\n" |
| " outRange4:(NSRange)out_range4\n" |
| " outRange5:(NSRange)out_range5\n" |
| " outRange6:(NSRange)out_range6\n" |
| " outRange7:(NSRange)out_range7\n" |
| " outRange8:(NSRange)out_range8\n" |
| " outRange9:(NSRange)out_range9;"); |
| |
| // When the function name has to be wrapped. |
| FormatStyle Style = getLLVMStyle(); |
| // ObjC ignores IndentWrappedFunctionNames when wrapping methods |
| // and always indents instead. |
| Style.IndentWrappedFunctionNames = false; |
| verifyFormat("- (SomeLooooooooooooooooooooongType *)\n" |
| " veryLooooooooooongName:(NSString)aaaaaaaaaaaaaa\n" |
| " anotherName:(NSString)bbbbbbbbbbbbbb {\n" |
| "}", |
| Style); |
| Style.IndentWrappedFunctionNames = true; |
| verifyFormat("- (SomeLooooooooooooooooooooongType *)\n" |
| " veryLooooooooooongName:(NSString)cccccccccccccc\n" |
| " anotherName:(NSString)dddddddddddddd {\n" |
| "}", |
| Style); |
| |
| verifyFormat("- (int)sum:(vector<int>)numbers;"); |
| verifyGoogleFormat("- (void)setDelegate:(id<Protocol>)delegate;"); |
| // FIXME: In LLVM style, there should be a space in front of a '<' for ObjC |
| // protocol lists (but not for template classes): |
| // verifyFormat("- (void)setDelegate:(id <Protocol>)delegate;"); |
| |
| verifyFormat("- (int (*)())foo:(int (*)())f;"); |
| verifyGoogleFormat("- (int (*)())foo:(int (*)())foo;"); |
| |
| // If there's no return type (very rare in practice!), LLVM and Google style |
| // agree. |
| verifyFormat("- foo;"); |
| verifyFormat("- foo:(int)f;"); |
| verifyGoogleFormat("- foo:(int)foo;"); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiterals) { |
| EXPECT_EQ("\"some text \"\n" |
| "\"other\";", |
| format("\"some text other\";", getLLVMStyleWithColumns(12))); |
| EXPECT_EQ("\"some text \"\n" |
| "\"other\";", |
| format("\\\n\"some text other\";", getLLVMStyleWithColumns(12))); |
| EXPECT_EQ( |
| "#define A \\\n" |
| " \"some \" \\\n" |
| " \"text \" \\\n" |
| " \"other\";", |
| format("#define A \"some text other\";", getLLVMStyleWithColumns(12))); |
| EXPECT_EQ( |
| "#define A \\\n" |
| " \"so \" \\\n" |
| " \"text \" \\\n" |
| " \"other\";", |
| format("#define A \"so text other\";", getLLVMStyleWithColumns(12))); |
| |
| EXPECT_EQ("\"some text\"", |
| format("\"some text\"", getLLVMStyleWithColumns(1))); |
| EXPECT_EQ("\"some text\"", |
| format("\"some text\"", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("\"some \"\n" |
| "\"text\"", |
| format("\"some text\"", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("\"some \"\n" |
| "\"text\"", |
| format("\"some text\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"some\"\n" |
| "\" tex\"\n" |
| "\"t\"", |
| format("\"some text\"", getLLVMStyleWithColumns(6))); |
| EXPECT_EQ("\"some\"\n" |
| "\" tex\"\n" |
| "\" and\"", |
| format("\"some tex and\"", getLLVMStyleWithColumns(6))); |
| EXPECT_EQ("\"some\"\n" |
| "\"/tex\"\n" |
| "\"/and\"", |
| format("\"some/tex/and\"", getLLVMStyleWithColumns(6))); |
| |
| EXPECT_EQ("variable =\n" |
| " \"long string \"\n" |
| " \"literal\";", |
| format("variable = \"long string literal\";", |
| getLLVMStyleWithColumns(20))); |
| |
| EXPECT_EQ("variable = f(\n" |
| " \"long string \"\n" |
| " \"literal\",\n" |
| " short,\n" |
| " loooooooooooooooooooong);", |
| format("variable = f(\"long string literal\", short, " |
| "loooooooooooooooooooong);", |
| getLLVMStyleWithColumns(20))); |
| |
| EXPECT_EQ( |
| "f(g(\"long string \"\n" |
| " \"literal\"),\n" |
| " b);", |
| format("f(g(\"long string literal\"), b);", getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("f(g(\"long string \"\n" |
| " \"literal\",\n" |
| " a),\n" |
| " b);", |
| format("f(g(\"long string literal\", a), b);", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ( |
| "f(\"one two\".split(\n" |
| " variable));", |
| format("f(\"one two\".split(variable));", getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("f(\"one two three four five six \"\n" |
| " \"seven\".split(\n" |
| " really_looooong_variable));", |
| format("f(\"one two three four five six seven\"." |
| "split(really_looooong_variable));", |
| getLLVMStyleWithColumns(33))); |
| |
| EXPECT_EQ("f(\"some \"\n" |
| " \"text\",\n" |
| " other);", |
| format("f(\"some text\", other);", getLLVMStyleWithColumns(10))); |
| |
| // Only break as a last resort. |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaaaaaaaaaaaaaaaaaa,\n" |
| " aaaaaa(\"aaa aaaaa aaa aaa aaaaa aaa aaaaa aaa aaa aaaaaa\"));"); |
| |
| EXPECT_EQ("\"splitmea\"\n" |
| "\"trandomp\"\n" |
| "\"oint\"", |
| format("\"splitmeatrandompoint\"", getLLVMStyleWithColumns(10))); |
| |
| EXPECT_EQ("\"split/\"\n" |
| "\"pathat/\"\n" |
| "\"slashes\"", |
| format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); |
| |
| EXPECT_EQ("\"split/\"\n" |
| "\"pathat/\"\n" |
| "\"slashes\"", |
| format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("\"split at \"\n" |
| "\"spaces/at/\"\n" |
| "\"slashes.at.any$\"\n" |
| "\"non-alphanumeric%\"\n" |
| "\"1111111111characte\"\n" |
| "\"rs\"", |
| format("\"split at " |
| "spaces/at/" |
| "slashes.at." |
| "any$non-" |
| "alphanumeric%" |
| "1111111111characte" |
| "rs\"", |
| getLLVMStyleWithColumns(20))); |
| |
| // Verify that splitting the strings understands |
| // Style::AlwaysBreakBeforeMultilineStrings. |
| EXPECT_EQ("aaaaaaaaaaaa(\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa \"\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa\");", |
| format("aaaaaaaaaaaa(\"aaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaaa\");", |
| getGoogleStyle())); |
| EXPECT_EQ("return \"aaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaa\";", |
| format("return \"aaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaaa\";", |
| getGoogleStyle())); |
| EXPECT_EQ("llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";", |
| format("llvm::outs() << " |
| "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa" |
| "aaaaaaaaaaaaaaaaaaa\";")); |
| EXPECT_EQ("ffff(\n" |
| " {\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" |
| " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"});", |
| format("ffff({\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa " |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"});", |
| getGoogleStyle())); |
| |
| FormatStyle Style = getLLVMStyleWithColumns(12); |
| Style.BreakStringLiterals = false; |
| EXPECT_EQ("\"some text other\";", format("\"some text other\";", Style)); |
| |
| FormatStyle AlignLeft = getLLVMStyleWithColumns(12); |
| AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| EXPECT_EQ("#define A \\\n" |
| " \"some \" \\\n" |
| " \"text \" \\\n" |
| " \"other\";", |
| format("#define A \"some text other\";", AlignLeft)); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralsAtColumnLimit) { |
| EXPECT_EQ("C a = \"some more \"\n" |
| " \"text\";", |
| format("C a = \"some more text\";", getLLVMStyleWithColumns(18))); |
| } |
| |
| TEST_F(FormatTest, FullyRemoveEmptyLines) { |
| FormatStyle NoEmptyLines = getLLVMStyleWithColumns(80); |
| NoEmptyLines.MaxEmptyLinesToKeep = 0; |
| EXPECT_EQ("int i = a(b());", |
| format("int i=a(\n\n b(\n\n\n )\n\n);", NoEmptyLines)); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralsWithTabs) { |
| EXPECT_EQ( |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" |
| "(\n" |
| " \"x\t\");", |
| format("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" |
| "aaaaaaa(" |
| "\"x\t\");")); |
| } |
| |
| TEST_F(FormatTest, BreaksWideAndNSStringLiterals) { |
| EXPECT_EQ( |
| "u8\"utf8 string \"\n" |
| "u8\"literal\";", |
| format("u8\"utf8 string literal\";", getGoogleStyleWithColumns(16))); |
| EXPECT_EQ( |
| "u\"utf16 string \"\n" |
| "u\"literal\";", |
| format("u\"utf16 string literal\";", getGoogleStyleWithColumns(16))); |
| EXPECT_EQ( |
| "U\"utf32 string \"\n" |
| "U\"literal\";", |
| format("U\"utf32 string literal\";", getGoogleStyleWithColumns(16))); |
| EXPECT_EQ("L\"wide string \"\n" |
| "L\"literal\";", |
| format("L\"wide string literal\";", getGoogleStyleWithColumns(16))); |
| EXPECT_EQ("@\"NSString \"\n" |
| "@\"literal\";", |
| format("@\"NSString literal\";", getGoogleStyleWithColumns(19))); |
| verifyFormat(R"(NSString *s = @"那那那那";)", getLLVMStyleWithColumns(26)); |
| |
| // This input makes clang-format try to split the incomplete unicode escape |
| // sequence, which used to lead to a crasher. |
| verifyNoCrash( |
| "aaaaaaaaaaaaaaaaaaaa = L\"\\udff\"'; // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
| getLLVMStyleWithColumns(60)); |
| } |
| |
| TEST_F(FormatTest, DoesNotBreakRawStringLiterals) { |
| FormatStyle Style = getGoogleStyleWithColumns(15); |
| EXPECT_EQ("R\"x(raw literal)x\";", format("R\"x(raw literal)x\";", Style)); |
| EXPECT_EQ("uR\"x(raw literal)x\";", format("uR\"x(raw literal)x\";", Style)); |
| EXPECT_EQ("LR\"x(raw literal)x\";", format("LR\"x(raw literal)x\";", Style)); |
| EXPECT_EQ("UR\"x(raw literal)x\";", format("UR\"x(raw literal)x\";", Style)); |
| EXPECT_EQ("u8R\"x(raw literal)x\";", |
| format("u8R\"x(raw literal)x\";", Style)); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { |
| FormatStyle Style = getLLVMStyleWithColumns(20); |
| EXPECT_EQ( |
| "_T(\"aaaaaaaaaaaaaa\")\n" |
| "_T(\"aaaaaaaaaaaaaa\")\n" |
| "_T(\"aaaaaaaaaaaa\")", |
| format(" _T(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")", Style)); |
| EXPECT_EQ("f(x,\n" |
| " _T(\"aaaaaaaaaaaa\")\n" |
| " _T(\"aaa\"),\n" |
| " z);", |
| format("f(x, _T(\"aaaaaaaaaaaaaaa\"), z);", Style)); |
| |
| // FIXME: Handle embedded spaces in one iteration. |
| // EXPECT_EQ("_T(\"aaaaaaaaaaaaa\")\n" |
| // "_T(\"aaaaaaaaaaaaa\")\n" |
| // "_T(\"aaaaaaaaaaaaa\")\n" |
| // "_T(\"a\")", |
| // format(" _T ( \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" )", |
| // getLLVMStyleWithColumns(20))); |
| EXPECT_EQ( |
| "_T ( \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" )", |
| format(" _T ( \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\" )", Style)); |
| EXPECT_EQ("f(\n" |
| "#if !TEST\n" |
| " _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" |
| "#endif\n" |
| ");", |
| format("f(\n" |
| "#if !TEST\n" |
| "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n" |
| "#endif\n" |
| ");")); |
| EXPECT_EQ("f(\n" |
| "\n" |
| " _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));", |
| format("f(\n" |
| "\n" |
| "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));")); |
| // Regression test for accessing tokens past the end of a vector in the |
| // TokenLexer. |
| verifyNoCrash(R"(_T( |
| " |
| ) |
| )"); |
| } |
| |
| TEST_F(FormatTest, BreaksStringLiteralOperands) { |
| // In a function call with two operands, the second can be broken with no line |
| // break before it. |
| EXPECT_EQ( |
| "func(a, \"long long \"\n" |
| " \"long long\");", |
| format("func(a, \"long long long long\");", getLLVMStyleWithColumns(24))); |
| // In a function call with three operands, the second must be broken with a |
| // line break before it. |
| EXPECT_EQ("func(a,\n" |
| " \"long long long \"\n" |
| " \"long\",\n" |
| " c);", |
| format("func(a, \"long long long long\", c);", |
| getLLVMStyleWithColumns(24))); |
| // In a function call with three operands, the third must be broken with a |
| // line break before it. |
| EXPECT_EQ("func(a, b,\n" |
| " \"long long long \"\n" |
| " \"long\");", |
| format("func(a, b, \"long long long long\");", |
| getLLVMStyleWithColumns(24))); |
| // In a function call with three operands, both the second and the third must |
| // be broken with a line break before them. |
| EXPECT_EQ("func(a,\n" |
| " \"long long long \"\n" |
| " \"long\",\n" |
| " \"long long long \"\n" |
| " \"long\");", |
| format("func(a, \"long long long long\", \"long long long long\");", |
| getLLVMStyleWithColumns(24))); |
| // In a chain of << with two operands, the second can be broken with no line |
| // break before it. |
| EXPECT_EQ("a << \"line line \"\n" |
| " \"line\";", |
| format("a << \"line line line\";", getLLVMStyleWithColumns(20))); |
| // In a chain of << with three operands, the second can be broken with no line |
| // break before it. |
| EXPECT_EQ( |
| "abcde << \"line \"\n" |
| " \"line line\"\n" |
| " << c;", |
| format("abcde << \"line line line\" << c;", getLLVMStyleWithColumns(20))); |
| // In a chain of << with three operands, the third must be broken with a line |
| // break before it. |
| EXPECT_EQ( |
| "a << b\n" |
| " << \"line line \"\n" |
| " \"line\";", |
| format("a << b << \"line line line\";", getLLVMStyleWithColumns(20))); |
| // In a chain of << with three operands, the second can be broken with no line |
| // break before it and the third must be broken with a line break before it. |
| EXPECT_EQ("abcd << \"line line \"\n" |
| " \"line\"\n" |
| " << \"line line \"\n" |
| " \"line\";", |
| format("abcd << \"line line line\" << \"line line line\";", |
| getLLVMStyleWithColumns(20))); |
| // In a chain of binary operators with two operands, the second can be broken |
| // with no line break before it. |
| EXPECT_EQ( |
| "abcd + \"line line \"\n" |
| " \"line line\";", |
| format("abcd + \"line line line line\";", getLLVMStyleWithColumns(20))); |
| // In a chain of binary operators with three operands, the second must be |
| // broken with a line break before it. |
| EXPECT_EQ("abcd +\n" |
| " \"line line \"\n" |
| " \"line line\" +\n" |
| " e;", |
| format("abcd + \"line line line line\" + e;", |
| getLLVMStyleWithColumns(20))); |
| // In a function call with two operands, with AlignAfterOpenBracket enabled, |
| // the first must be broken with a line break before it. |
| FormatStyle Style = getLLVMStyleWithColumns(25); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| EXPECT_EQ("someFunction(\n" |
| " \"long long long \"\n" |
| " \"long\",\n" |
| " a);", |
| format("someFunction(\"long long long long\", a);", Style)); |
| } |
| |
| TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { |
| EXPECT_EQ( |
| "aaaaaaaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";", |
| format("aaaaaaaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";")); |
| } |
| |
| TEST_F(FormatTest, CountsCharactersInMultilineRawStringLiterals) { |
| EXPECT_EQ("f(g(R\"x(raw literal)x\", a), b);", |
| format("f(g(R\"x(raw literal)x\", a), b);", getGoogleStyle())); |
| EXPECT_EQ("fffffffffff(g(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\",\n" |
| " a),\n" |
| " b);", |
| format("fffffffffff(g(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\", a), b);", |
| getGoogleStyleWithColumns(20))); |
| EXPECT_EQ("fffffffffff(\n" |
| " g(R\"x(qqq\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\",\n" |
| " a),\n" |
| " b);", |
| format("fffffffffff(g(R\"x(qqq\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\", a), b);", |
| getGoogleStyleWithColumns(20))); |
| |
| EXPECT_EQ("fffffffffff(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\");", |
| format("fffffffffff(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\");", |
| getGoogleStyleWithColumns(20))); |
| EXPECT_EQ("fffffffffff(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\" + bbbbbb);", |
| format("fffffffffff(R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\" + bbbbbb);", |
| getGoogleStyleWithColumns(20))); |
| EXPECT_EQ("fffffffffff(\n" |
| " R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\" +\n" |
| " bbbbbb);", |
| format("fffffffffff(\n" |
| " R\"x(\n" |
| "multiline raw string literal xxxxxxxxxxxxxx\n" |
| ")x\" + bbbbbb);", |
| getGoogleStyleWithColumns(20))); |
| EXPECT_EQ("fffffffffff(R\"(single line raw string)\" + bbbbbb);", |
| format("fffffffffff(\n" |
| " R\"(single line raw string)\" + bbbbbb);")); |
| } |
| |
| TEST_F(FormatTest, SkipsUnknownStringLiterals) { |
| verifyFormat("string a = \"unterminated;"); |
| EXPECT_EQ("function(\"unterminated,\n" |
| " OtherParameter);", |
| format("function( \"unterminated,\n" |
| " OtherParameter);")); |
| } |
| |
| TEST_F(FormatTest, DoesNotTryToParseUDLiteralsInPreCpp11Code) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.Standard = FormatStyle::LS_Cpp03; |
| EXPECT_EQ("#define x(_a) printf(\"foo\" _a);", |
| format("#define x(_a) printf(\"foo\"_a);", Style)); |
| } |
| |
| TEST_F(FormatTest, CppLexVersion) { |
| FormatStyle Style = getLLVMStyle(); |
| // Formatting of x * y differs if x is a type. |
| verifyFormat("void foo() { MACRO(a * b); }", Style); |
| verifyFormat("void foo() { MACRO(int *b); }", Style); |
| |
| // LLVM style uses latest lexer. |
| verifyFormat("void foo() { MACRO(char8_t *b); }", Style); |
| Style.Standard = FormatStyle::LS_Cpp17; |
| // But in c++17, char8_t isn't a keyword. |
| verifyFormat("void foo() { MACRO(char8_t * b); }", Style); |
| } |
| |
| TEST_F(FormatTest, UnderstandsCpp1y) { verifyFormat("int bi{1'000'000};"); } |
| |
| TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) { |
| EXPECT_EQ("someFunction(\"aaabbbcccd\"\n" |
| " \"ddeeefff\");", |
| format("someFunction(\"aaabbbcccdddeeefff\");", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("someFunction1234567890(\n" |
| " \"aaabbbcccdddeeefff\");", |
| format("someFunction1234567890(\"aaabbbcccdddeeefff\");", |
| getLLVMStyleWithColumns(26))); |
| EXPECT_EQ("someFunction1234567890(\n" |
| " \"aaabbbcccdddeeeff\"\n" |
| " \"f\");", |
| format("someFunction1234567890(\"aaabbbcccdddeeefff\");", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("someFunction1234567890(\n" |
| " \"aaabbbcccdddeeeff\"\n" |
| " \"f\");", |
| format("someFunction1234567890(\"aaabbbcccdddeeefff\");", |
| getLLVMStyleWithColumns(24))); |
| EXPECT_EQ("someFunction(\n" |
| " \"aaabbbcc ddde \"\n" |
| " \"efff\");", |
| format("someFunction(\"aaabbbcc ddde efff\");", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("someFunction(\"aaabbbccc \"\n" |
| " \"ddeeefff\");", |
| format("someFunction(\"aaabbbccc ddeeefff\");", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("someFunction1234567890(\n" |
| " \"aaabb \"\n" |
| " \"cccdddeeefff\");", |
| format("someFunction1234567890(\"aaabb cccdddeeefff\");", |
| getLLVMStyleWithColumns(25))); |
| EXPECT_EQ("#define A \\\n" |
| " string s = \\\n" |
| " \"123456789\" \\\n" |
| " \"0\"; \\\n" |
| " int i;", |
| format("#define A string s = \"1234567890\"; int i;", |
| getLLVMStyleWithColumns(20))); |
| EXPECT_EQ("someFunction(\n" |
| " \"aaabbbcc \"\n" |
| " \"dddeeefff\");", |
| format("someFunction(\"aaabbbcc dddeeefff\");", |
| getLLVMStyleWithColumns(25))); |
| } |
| |
| TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) { |
| EXPECT_EQ("\"\\a\"", format("\"\\a\"", getLLVMStyleWithColumns(3))); |
| EXPECT_EQ("\"\\\"", format("\"\\\"", getLLVMStyleWithColumns(2))); |
| EXPECT_EQ("\"test\"\n" |
| "\"\\n\"", |
| format("\"test\\n\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"tes\\\\\"\n" |
| "\"n\"", |
| format("\"tes\\\\n\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"\\\\\\\\\"\n" |
| "\"\\n\"", |
| format("\"\\\\\\\\\\n\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"\\uff01\"", format("\"\\uff01\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"\\uff01\"\n" |
| "\"test\"", |
| format("\"\\uff01test\"", getLLVMStyleWithColumns(8))); |
| EXPECT_EQ("\"\\Uff01ff02\"", |
| format("\"\\Uff01ff02\"", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("\"\\x000000000001\"\n" |
| "\"next\"", |
| format("\"\\x000000000001next\"", getLLVMStyleWithColumns(16))); |
| EXPECT_EQ("\"\\x000000000001next\"", |
| format("\"\\x000000000001next\"", getLLVMStyleWithColumns(15))); |
| EXPECT_EQ("\"\\x000000000001\"", |
| format("\"\\x000000000001\"", getLLVMStyleWithColumns(7))); |
| EXPECT_EQ("\"test\"\n" |
| "\"\\000000\"\n" |
| "\"000001\"", |
| format("\"test\\000000000001\"", getLLVMStyleWithColumns(9))); |
| EXPECT_EQ("\"test\\000\"\n" |
| "\"00000000\"\n" |
| "\"1\"", |
| format("\"test\\000000000001\"", getLLVMStyleWithColumns(10))); |
| } |
| |
| TEST_F(FormatTest, DoNotCreateUnreasonableUnwrappedLines) { |
| verifyFormat("void f() {\n" |
| " return g() {}\n" |
| " void h() {}"); |
| verifyFormat("int a[] = {void forgot_closing_brace(){f();\n" |
| "g();\n" |
| "}"); |
| } |
| |
| TEST_F(FormatTest, DoNotPrematurelyEndUnwrappedLineForReturnStatements) { |
| verifyFormat( |
| "void f() { return C{param1, param2}.SomeCall(param1, param2); }"); |
| } |
| |
| TEST_F(FormatTest, FormatsClosingBracesInEmptyNestedBlocks) { |
| verifyFormat("class X {\n" |
| " void f() {\n" |
| " }\n" |
| "};", |
| getLLVMStyleWithColumns(12)); |
| } |
| |
| TEST_F(FormatTest, ConfigurableIndentWidth) { |
| FormatStyle EightIndent = getLLVMStyleWithColumns(18); |
| EightIndent.IndentWidth = 8; |
| EightIndent.ContinuationIndentWidth = 8; |
| verifyFormat("void f() {\n" |
| " someFunction();\n" |
| " if (true) {\n" |
| " f();\n" |
| " }\n" |
| "}", |
| EightIndent); |
| verifyFormat("class X {\n" |
| " void f() {\n" |
| " }\n" |
| "};", |
| EightIndent); |
| verifyFormat("int x[] = {\n" |
| " call(),\n" |
| " call()};", |
| EightIndent); |
| } |
| |
| TEST_F(FormatTest, ConfigurableFunctionDeclarationIndentAfterType) { |
| verifyFormat("double\n" |
| "f();", |
| getLLVMStyleWithColumns(8)); |
| } |
| |
| TEST_F(FormatTest, ConfigurableUseOfTab) { |
| FormatStyle Tab = getLLVMStyleWithColumns(42); |
| Tab.IndentWidth = 8; |
| Tab.UseTab = FormatStyle::UT_Always; |
| Tab.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb)\t\t// w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| EXPECT_EQ("if (aaa && bbb) // w\n" |
| "\t;", |
| format("if(aaa&&bbb)// w\n" |
| ";", |
| Tab)); |
| |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("#define A \\\n" |
| "\tvoid f() { \\\n" |
| "\t\tsomeFunction( \\\n" |
| "\t\t parameter1, \\\n" |
| "\t\t parameter2); \\\n" |
| "\t}", |
| Tab); |
| verifyFormat("int a;\t // x\n" |
| "int bbbbbbbb; // x\n", |
| Tab); |
| |
| FormatStyle TabAlignment = Tab; |
| TabAlignment.AlignConsecutiveDeclarations.Enabled = true; |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("unsigned long long big;\n" |
| "char*\t\t ptr;", |
| TabAlignment); |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("unsigned long long big;\n" |
| "char *\t\t ptr;", |
| TabAlignment); |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("unsigned long long big;\n" |
| "char\t\t *ptr;", |
| TabAlignment); |
| |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 8; |
| verifyFormat("class TabWidth4Indent8 {\n" |
| "\t\tvoid f() {\n" |
| "\t\t\t\tsomeFunction(parameter1,\n" |
| "\t\t\t\t\t\t\t parameter2);\n" |
| "\t\t}\n" |
| "};", |
| Tab); |
| |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth4Indent4 {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t\t\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth8Indent4 {\n" |
| " void f() {\n" |
| "\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| " }\n" |
| "};", |
| Tab); |
| |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 8; |
| EXPECT_EQ("/*\n" |
| "\t a\t\tcomment\n" |
| "\t in multiple lines\n" |
| " */", |
| format(" /*\t \t \n" |
| " \t \t a\t\tcomment\t \t\n" |
| " \t \t in multiple lines\t\n" |
| " \t */", |
| Tab)); |
| |
| TabAlignment.UseTab = FormatStyle::UT_ForIndentation; |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("void f() {\n" |
| "\tunsigned long long big;\n" |
| "\tchar* ptr;\n" |
| "}", |
| TabAlignment); |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("void f() {\n" |
| "\tunsigned long long big;\n" |
| "\tchar * ptr;\n" |
| "}", |
| TabAlignment); |
| TabAlignment.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("void f() {\n" |
| "\tunsigned long long big;\n" |
| "\tchar *ptr;\n" |
| "}", |
| TabAlignment); |
| |
| Tab.UseTab = FormatStyle::UT_ForIndentation; |
| verifyFormat("{\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "};", |
| Tab); |
| verifyFormat("enum AA {\n" |
| "\ta1, // Force multiple lines\n" |
| "\ta2,\n" |
| "\ta3\n" |
| "};", |
| Tab); |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb) // w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("{\n" |
| "\tQ(\n" |
| "\t {\n" |
| "\t\t int a;\n" |
| "\t\t someFunction(aaaaaaaa,\n" |
| "\t\t bbbbbbb);\n" |
| "\t },\n" |
| "\t p);\n" |
| "}", |
| Tab); |
| EXPECT_EQ("{\n" |
| "\t/* aaaa\n" |
| "\t bbbb */\n" |
| "}", |
| format("{\n" |
| "/* aaaa\n" |
| " bbbb */\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t// bbbbbbbbbbbbb\n" |
| "}", |
| format("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| |
| verifyFormat("void f() {\n" |
| "\treturn true ? aaaaaaaaaaaaaaaaaa\n" |
| "\t : bbbbbbbbbbbbbbbbbb\n" |
| "}", |
| Tab); |
| FormatStyle TabNoBreak = Tab; |
| TabNoBreak.BreakBeforeTernaryOperators = false; |
| verifyFormat("void f() {\n" |
| "\treturn true ? aaaaaaaaaaaaaaaaaa :\n" |
| "\t bbbbbbbbbbbbbbbbbb\n" |
| "}", |
| TabNoBreak); |
| verifyFormat("void f() {\n" |
| "\treturn true ?\n" |
| "\t aaaaaaaaaaaaaaaaaaaa :\n" |
| "\t bbbbbbbbbbbbbbbbbbbb\n" |
| "}", |
| TabNoBreak); |
| |
| Tab.UseTab = FormatStyle::UT_Never; |
| EXPECT_EQ("/*\n" |
| " a\t\tcomment\n" |
| " in multiple lines\n" |
| " */", |
| format(" /*\t \t \n" |
| " \t \t a\t\tcomment\t \t\n" |
| " \t \t in multiple lines\t\n" |
| " \t */", |
| Tab)); |
| EXPECT_EQ("/* some\n" |
| " comment */", |
| format(" \t \t /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("int a; /* some\n" |
| " comment */", |
| format(" \t \t int a; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| |
| EXPECT_EQ("int a; /* some\n" |
| "comment */", |
| format(" \t \t int\ta; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("f(\"\t\t\"); /* some\n" |
| " comment */", |
| format(" \t \t f(\"\t\t\"); /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("{\n" |
| " /*\n" |
| " * Comment\n" |
| " */\n" |
| " int i;\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t * Comment\n" |
| "\t */\n" |
| "\t int i;\n" |
| "}", |
| Tab)); |
| |
| Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation; |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 8; |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb) // w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| EXPECT_EQ("if (aaa && bbb) // w\n" |
| "\t;", |
| format("if(aaa&&bbb)// w\n" |
| ";", |
| Tab)); |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("#define A \\\n" |
| "\tvoid f() { \\\n" |
| "\t\tsomeFunction( \\\n" |
| "\t\t parameter1, \\\n" |
| "\t\t parameter2); \\\n" |
| "\t}", |
| Tab); |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 8; |
| verifyFormat("class TabWidth4Indent8 {\n" |
| "\t\tvoid f() {\n" |
| "\t\t\t\tsomeFunction(parameter1,\n" |
| "\t\t\t\t\t\t\t parameter2);\n" |
| "\t\t}\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth4Indent4 {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t\t\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth8Indent4 {\n" |
| " void f() {\n" |
| "\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| " }\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 8; |
| EXPECT_EQ("/*\n" |
| "\t a\t\tcomment\n" |
| "\t in multiple lines\n" |
| " */", |
| format(" /*\t \t \n" |
| " \t \t a\t\tcomment\t \t\n" |
| " \t \t in multiple lines\t\n" |
| " \t */", |
| Tab)); |
| verifyFormat("{\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "};", |
| Tab); |
| verifyFormat("enum AA {\n" |
| "\ta1, // Force multiple lines\n" |
| "\ta2,\n" |
| "\ta3\n" |
| "};", |
| Tab); |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb) // w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("{\n" |
| "\tQ(\n" |
| "\t {\n" |
| "\t\t int a;\n" |
| "\t\t someFunction(aaaaaaaa,\n" |
| "\t\t\t\t bbbbbbb);\n" |
| "\t },\n" |
| "\t p);\n" |
| "}", |
| Tab); |
| EXPECT_EQ("{\n" |
| "\t/* aaaa\n" |
| "\t bbbb */\n" |
| "}", |
| format("{\n" |
| "/* aaaa\n" |
| " bbbb */\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t// bbbbbbbbbbbbb\n" |
| "}", |
| format("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("/* some\n" |
| " comment */", |
| format(" \t \t /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("int a; /* some\n" |
| " comment */", |
| format(" \t \t int a; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("int a; /* some\n" |
| "comment */", |
| format(" \t \t int\ta; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("f(\"\t\t\"); /* some\n" |
| " comment */", |
| format(" \t \t f(\"\t\t\"); /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t * Comment\n" |
| "\t */\n" |
| "\tint i;\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t * Comment\n" |
| "\t */\n" |
| "\t int i;\n" |
| "}", |
| Tab)); |
| Tab.TabWidth = 2; |
| Tab.IndentWidth = 2; |
| EXPECT_EQ("{\n" |
| "\t/* aaaa\n" |
| "\t\t bbbb */\n" |
| "}", |
| format("{\n" |
| "/* aaaa\n" |
| "\t bbbb */\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t\taaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t\tbbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "*/\n" |
| "}", |
| Tab)); |
| Tab.AlignConsecutiveAssignments.Enabled = true; |
| Tab.AlignConsecutiveDeclarations.Enabled = true; |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 4; |
| verifyFormat("class Assign {\n" |
| "\tvoid f() {\n" |
| "\t\tint x = 123;\n" |
| "\t\tint random = 4;\n" |
| "\t\tstd::string alphabet =\n" |
| "\t\t\t\"abcdefghijklmnopqrstuvwxyz\";\n" |
| "\t}\n" |
| "};", |
| Tab); |
| |
| Tab.UseTab = FormatStyle::UT_AlignWithSpaces; |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 8; |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb) // w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| EXPECT_EQ("if (aaa && bbb) // w\n" |
| "\t;", |
| format("if(aaa&&bbb)// w\n" |
| ";", |
| Tab)); |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("#define A \\\n" |
| "\tvoid f() { \\\n" |
| "\t\tsomeFunction( \\\n" |
| "\t\t parameter1, \\\n" |
| "\t\t parameter2); \\\n" |
| "\t}", |
| Tab); |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 8; |
| verifyFormat("class TabWidth4Indent8 {\n" |
| "\t\tvoid f() {\n" |
| "\t\t\t\tsomeFunction(parameter1,\n" |
| "\t\t\t\t parameter2);\n" |
| "\t\t}\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth4Indent4 {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 4; |
| verifyFormat("class TabWidth8Indent4 {\n" |
| " void f() {\n" |
| "\tsomeFunction(parameter1,\n" |
| "\t parameter2);\n" |
| " }\n" |
| "};", |
| Tab); |
| Tab.TabWidth = 8; |
| Tab.IndentWidth = 8; |
| EXPECT_EQ("/*\n" |
| " a\t\tcomment\n" |
| " in multiple lines\n" |
| " */", |
| format(" /*\t \t \n" |
| " \t \t a\t\tcomment\t \t\n" |
| " \t \t in multiple lines\t\n" |
| " \t */", |
| Tab)); |
| verifyFormat("{\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" |
| "};", |
| Tab); |
| verifyFormat("enum AA {\n" |
| "\ta1, // Force multiple lines\n" |
| "\ta2,\n" |
| "\ta3\n" |
| "};", |
| Tab); |
| EXPECT_EQ("if (aaaaaaaa && // q\n" |
| " bb) // w\n" |
| "\t;", |
| format("if (aaaaaaaa &&// q\n" |
| "bb)// w\n" |
| ";", |
| Tab)); |
| verifyFormat("class X {\n" |
| "\tvoid f() {\n" |
| "\t\tsomeFunction(parameter1,\n" |
| "\t\t parameter2);\n" |
| "\t}\n" |
| "};", |
| Tab); |
| verifyFormat("{\n" |
| "\tQ(\n" |
| "\t {\n" |
| "\t\t int a;\n" |
| "\t\t someFunction(aaaaaaaa,\n" |
| "\t\t bbbbbbb);\n" |
| "\t },\n" |
| "\t p);\n" |
| "}", |
| Tab); |
| EXPECT_EQ("{\n" |
| "\t/* aaaa\n" |
| "\t bbbb */\n" |
| "}", |
| format("{\n" |
| "/* aaaa\n" |
| " bbbb */\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t// bbbbbbbbbbbbb\n" |
| "}", |
| format("{\n" |
| "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| " asdf\n" |
| "\t*/\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("/* some\n" |
| " comment */", |
| format(" \t \t /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("int a; /* some\n" |
| " comment */", |
| format(" \t \t int a; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("int a; /* some\n" |
| "comment */", |
| format(" \t \t int\ta; /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("f(\"\t\t\"); /* some\n" |
| " comment */", |
| format(" \t \t f(\"\t\t\"); /* some\n" |
| " \t \t comment */", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t * Comment\n" |
| "\t */\n" |
| "\tint i;\n" |
| "}", |
| format("{\n" |
| "\t/*\n" |
| "\t * Comment\n" |
| "\t */\n" |
| "\t int i;\n" |
| "}", |
| Tab)); |
| Tab.TabWidth = 2; |
| Tab.IndentWidth = 2; |
| EXPECT_EQ("{\n" |
| "\t/* aaaa\n" |
| "\t bbbb */\n" |
| "}", |
| format("{\n" |
| "/* aaaa\n" |
| " bbbb */\n" |
| "}", |
| Tab)); |
| EXPECT_EQ("{\n" |
| "\t/*\n" |
| "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n" |
| "\t bbbbbbbbbbbbb\n" |
| "\t*/\n" |
| "}", |
| format("{\n" |
| "/*\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" |
| "*/\n" |
| "}", |
| Tab)); |
| Tab.AlignConsecutiveAssignments.Enabled = true; |
| Tab.AlignConsecutiveDeclarations.Enabled = true; |
| Tab.TabWidth = 4; |
| Tab.IndentWidth = 4; |
| verifyFormat("class Assign {\n" |
| "\tvoid f() {\n" |
| "\t\tint x = 123;\n" |
| "\t\tint random = 4;\n" |
| "\t\tstd::string alphabet =\n" |
| "\t\t\t\"abcdefghijklmnopqrstuvwxyz\";\n" |
| "\t}\n" |
| "};", |
| Tab); |
| Tab.AlignOperands = FormatStyle::OAS_Align; |
| verifyFormat("int aaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb +\n" |
| " cccccccccccccccccccc;", |
| Tab); |
| // no alignment |
| verifyFormat("int aaaaaaaaaa =\n" |
| "\tbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", |
| Tab); |
| verifyFormat("return aaaaaaaaaaaaaaaa ? 111111111111111\n" |
| " : bbbbbbbbbbbbbb ? 222222222222222\n" |
| " : 333333333333333;", |
| Tab); |
| Tab.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| Tab.AlignOperands = FormatStyle::OAS_AlignAfterOperator; |
| verifyFormat("int aaaaaaaaaa = bbbbbbbbbbbbbbbbbbbb\n" |
| " + cccccccccccccccccccc;", |
| Tab); |
| } |
| |
| TEST_F(FormatTest, ZeroTabWidth) { |
| FormatStyle Tab = getLLVMStyleWithColumns(42); |
| Tab.IndentWidth = 8; |
| Tab.UseTab = FormatStyle::UT_Never; |
| Tab.TabWidth = 0; |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| Tab.UseTab = FormatStyle::UT_ForIndentation; |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation; |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| Tab.UseTab = FormatStyle::UT_AlignWithSpaces; |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| EXPECT_EQ("void a(){\n" |
| " // line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| Tab.UseTab = FormatStyle::UT_Always; |
| EXPECT_EQ("void a(){\n" |
| "// line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| |
| EXPECT_EQ("void a(){\n" |
| "// line starts with '\t'\n" |
| "};", |
| format("void a(){\n" |
| "\t\t// line starts with '\t'\n" |
| "};", |
| Tab)); |
| } |
| |
| TEST_F(FormatTest, CalculatesOriginalColumn) { |
| EXPECT_EQ("\"qqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "q\"; /* some\n" |
| " comment */", |
| format(" \"qqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "q\"; /* some\n" |
| " comment */", |
| getLLVMStyle())); |
| EXPECT_EQ("// qqqqqqqqqqqqqqqqqqqqqqqqqq\n" |
| "/* some\n" |
| " comment */", |
| format("// qqqqqqqqqqqqqqqqqqqqqqqqqq\n" |
| " /* some\n" |
| " comment */", |
| getLLVMStyle())); |
| EXPECT_EQ("// qqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "qqq\n" |
| "/* some\n" |
| " comment */", |
| format("// qqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "qqq\n" |
| " /* some\n" |
| " comment */", |
| getLLVMStyle())); |
| EXPECT_EQ("inttt qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "wwww; /* some\n" |
| " comment */", |
| format(" inttt qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\\\n" |
| "wwww; /* some\n" |
| " comment */", |
| getLLVMStyle())); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpaceBeforeParens) { |
| FormatStyle NoSpace = getLLVMStyle(); |
| NoSpace.SpaceBeforeParens = FormatStyle::SBPO_Never; |
| |
| verifyFormat("while(true)\n" |
| " continue;", |
| NoSpace); |
| verifyFormat("for(;;)\n" |
| " continue;", |
| NoSpace); |
| verifyFormat("if(true)\n" |
| " f();\n" |
| "else if(true)\n" |
| " f();", |
| NoSpace); |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while(something());", |
| NoSpace); |
| verifyFormat("switch(x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| NoSpace); |
| verifyFormat("auto i = std::make_unique<int>(5);", NoSpace); |
| verifyFormat("size_t x = sizeof(x);", NoSpace); |
| verifyFormat("auto f(int x) -> decltype(x);", NoSpace); |
| verifyFormat("auto f(int x) -> typeof(x);", NoSpace); |
| verifyFormat("auto f(int x) -> _Atomic(x);", NoSpace); |
| verifyFormat("auto f(int x) -> __underlying_type(x);", NoSpace); |
| verifyFormat("int f(T x) noexcept(x.create());", NoSpace); |
| verifyFormat("alignas(128) char a[128];", NoSpace); |
| verifyFormat("size_t x = alignof(MyType);", NoSpace); |
| verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", NoSpace); |
| verifyFormat("int f() throw(Deprecated);", NoSpace); |
| verifyFormat("typedef void (*cb)(int);", NoSpace); |
| verifyFormat("T A::operator()();", NoSpace); |
| verifyFormat("X A::operator++(T);", NoSpace); |
| verifyFormat("auto lambda = []() { return 0; };", NoSpace); |
| |
| FormatStyle Space = getLLVMStyle(); |
| Space.SpaceBeforeParens = FormatStyle::SBPO_Always; |
| |
| verifyFormat("int f ();", Space); |
| verifyFormat("void f (int a, T b) {\n" |
| " while (true)\n" |
| " continue;\n" |
| "}", |
| Space); |
| verifyFormat("if (true)\n" |
| " f ();\n" |
| "else if (true)\n" |
| " f ();", |
| Space); |
| verifyFormat("do {\n" |
| " do_something ();\n" |
| "} while (something ());", |
| Space); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| Space); |
| verifyFormat("A::A () : a (1) {}", Space); |
| verifyFormat("void f () __attribute__ ((asdf));", Space); |
| verifyFormat("*(&a + 1);\n" |
| "&((&a)[1]);\n" |
| "a[(b + c) * d];\n" |
| "(((a + 1) * 2) + 3) * 4;", |
| Space); |
| verifyFormat("#define A(x) x", Space); |
| verifyFormat("#define A (x) x", Space); |
| verifyFormat("#if defined(x)\n" |
| "#endif", |
| Space); |
| verifyFormat("auto i = std::make_unique<int> (5);", Space); |
| verifyFormat("size_t x = sizeof (x);", Space); |
| verifyFormat("auto f (int x) -> decltype (x);", Space); |
| verifyFormat("auto f (int x) -> typeof (x);", Space); |
| verifyFormat("auto f (int x) -> _Atomic (x);", Space); |
| verifyFormat("auto f (int x) -> __underlying_type (x);", Space); |
| verifyFormat("int f (T x) noexcept (x.create ());", Space); |
| verifyFormat("alignas (128) char a[128];", Space); |
| verifyFormat("size_t x = alignof (MyType);", Space); |
| verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", Space); |
| verifyFormat("int f () throw (Deprecated);", Space); |
| verifyFormat("typedef void (*cb) (int);", Space); |
| // FIXME these tests regressed behaviour. |
| // verifyFormat("T A::operator() ();", Space); |
| // verifyFormat("X A::operator++ (T);", Space); |
| verifyFormat("auto lambda = [] () { return 0; };", Space); |
| verifyFormat("int x = int (y);", Space); |
| verifyFormat("#define F(...) __VA_OPT__ (__VA_ARGS__)", Space); |
| verifyFormat("__builtin_LINE ()", Space); |
| verifyFormat("__builtin_UNKNOWN ()", Space); |
| |
| FormatStyle SomeSpace = getLLVMStyle(); |
| SomeSpace.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses; |
| |
| verifyFormat("[]() -> float {}", SomeSpace); |
| verifyFormat("[] (auto foo) {}", SomeSpace); |
| verifyFormat("[foo]() -> int {}", SomeSpace); |
| verifyFormat("int f();", SomeSpace); |
| verifyFormat("void f (int a, T b) {\n" |
| " while (true)\n" |
| " continue;\n" |
| "}", |
| SomeSpace); |
| verifyFormat("if (true)\n" |
| " f();\n" |
| "else if (true)\n" |
| " f();", |
| SomeSpace); |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while (something());", |
| SomeSpace); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| SomeSpace); |
| verifyFormat("A::A() : a (1) {}", SomeSpace); |
| verifyFormat("void f() __attribute__ ((asdf));", SomeSpace); |
| verifyFormat("*(&a + 1);\n" |
| "&((&a)[1]);\n" |
| "a[(b + c) * d];\n" |
| "(((a + 1) * 2) + 3) * 4;", |
| SomeSpace); |
| verifyFormat("#define A(x) x", SomeSpace); |
| verifyFormat("#define A (x) x", SomeSpace); |
| verifyFormat("#if defined(x)\n" |
| "#endif", |
| SomeSpace); |
| verifyFormat("auto i = std::make_unique<int> (5);", SomeSpace); |
| verifyFormat("size_t x = sizeof (x);", SomeSpace); |
| verifyFormat("auto f (int x) -> decltype (x);", SomeSpace); |
| verifyFormat("auto f (int x) -> typeof (x);", SomeSpace); |
| verifyFormat("auto f (int x) -> _Atomic (x);", SomeSpace); |
| verifyFormat("auto f (int x) -> __underlying_type (x);", SomeSpace); |
| verifyFormat("int f (T x) noexcept (x.create());", SomeSpace); |
| verifyFormat("alignas (128) char a[128];", SomeSpace); |
| verifyFormat("size_t x = alignof (MyType);", SomeSpace); |
| verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", |
| SomeSpace); |
| verifyFormat("int f() throw (Deprecated);", SomeSpace); |
| verifyFormat("typedef void (*cb) (int);", SomeSpace); |
| verifyFormat("T A::operator()();", SomeSpace); |
| // FIXME these tests regressed behaviour. |
| // verifyFormat("X A::operator++ (T);", SomeSpace); |
| verifyFormat("int x = int (y);", SomeSpace); |
| verifyFormat("auto lambda = []() { return 0; };", SomeSpace); |
| |
| FormatStyle SpaceControlStatements = getLLVMStyle(); |
| SpaceControlStatements.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceControlStatements.SpaceBeforeParensOptions.AfterControlStatements = true; |
| |
| verifyFormat("while (true)\n" |
| " continue;", |
| SpaceControlStatements); |
| verifyFormat("if (true)\n" |
| " f();\n" |
| "else if (true)\n" |
| " f();", |
| SpaceControlStatements); |
| verifyFormat("for (;;) {\n" |
| " do_something();\n" |
| "}", |
| SpaceControlStatements); |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while (something());", |
| SpaceControlStatements); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| SpaceControlStatements); |
| |
| FormatStyle SpaceFuncDecl = getLLVMStyle(); |
| SpaceFuncDecl.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceFuncDecl.SpaceBeforeParensOptions.AfterFunctionDeclarationName = true; |
| |
| verifyFormat("int f ();", SpaceFuncDecl); |
| verifyFormat("void f(int a, T b) {}", SpaceFuncDecl); |
| verifyFormat("A::A() : a(1) {}", SpaceFuncDecl); |
| verifyFormat("void f () __attribute__((asdf));", SpaceFuncDecl); |
| verifyFormat("#define A(x) x", SpaceFuncDecl); |
| verifyFormat("#define A (x) x", SpaceFuncDecl); |
| verifyFormat("#if defined(x)\n" |
| "#endif", |
| SpaceFuncDecl); |
| verifyFormat("auto i = std::make_unique<int>(5);", SpaceFuncDecl); |
| verifyFormat("size_t x = sizeof(x);", SpaceFuncDecl); |
| verifyFormat("auto f (int x) -> decltype(x);", SpaceFuncDecl); |
| verifyFormat("auto f (int x) -> typeof(x);", SpaceFuncDecl); |
| verifyFormat("auto f (int x) -> _Atomic(x);", SpaceFuncDecl); |
| verifyFormat("auto f (int x) -> __underlying_type(x);", SpaceFuncDecl); |
| verifyFormat("int f (T x) noexcept(x.create());", SpaceFuncDecl); |
| verifyFormat("alignas(128) char a[128];", SpaceFuncDecl); |
| verifyFormat("size_t x = alignof(MyType);", SpaceFuncDecl); |
| verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", |
| SpaceFuncDecl); |
| verifyFormat("int f () throw(Deprecated);", SpaceFuncDecl); |
| verifyFormat("typedef void (*cb)(int);", SpaceFuncDecl); |
| // FIXME these tests regressed behaviour. |
| // verifyFormat("T A::operator() ();", SpaceFuncDecl); |
| // verifyFormat("X A::operator++ (T);", SpaceFuncDecl); |
| verifyFormat("T A::operator()() {}", SpaceFuncDecl); |
| verifyFormat("auto lambda = []() { return 0; };", SpaceFuncDecl); |
| verifyFormat("int x = int(y);", SpaceFuncDecl); |
| verifyFormat("M(std::size_t R, std::size_t C) : C(C), data(R) {}", |
| SpaceFuncDecl); |
| |
| FormatStyle SpaceFuncDef = getLLVMStyle(); |
| SpaceFuncDef.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceFuncDef.SpaceBeforeParensOptions.AfterFunctionDefinitionName = true; |
| |
| verifyFormat("int f();", SpaceFuncDef); |
| verifyFormat("void f (int a, T b) {}", SpaceFuncDef); |
| verifyFormat("A::A() : a(1) {}", SpaceFuncDef); |
| verifyFormat("void f() __attribute__((asdf));", SpaceFuncDef); |
| verifyFormat("#define A(x) x", SpaceFuncDef); |
| verifyFormat("#define A (x) x", SpaceFuncDef); |
| verifyFormat("#if defined(x)\n" |
| "#endif", |
| SpaceFuncDef); |
| verifyFormat("auto i = std::make_unique<int>(5);", SpaceFuncDef); |
| verifyFormat("size_t x = sizeof(x);", SpaceFuncDef); |
| verifyFormat("auto f(int x) -> decltype(x);", SpaceFuncDef); |
| verifyFormat("auto f(int x) -> typeof(x);", SpaceFuncDef); |
| verifyFormat("auto f(int x) -> _Atomic(x);", SpaceFuncDef); |
| verifyFormat("auto f(int x) -> __underlying_type(x);", SpaceFuncDef); |
| verifyFormat("int f(T x) noexcept(x.create());", SpaceFuncDef); |
| verifyFormat("alignas(128) char a[128];", SpaceFuncDef); |
| verifyFormat("size_t x = alignof(MyType);", SpaceFuncDef); |
| verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", |
| SpaceFuncDef); |
| verifyFormat("int f() throw(Deprecated);", SpaceFuncDef); |
| verifyFormat("typedef void (*cb)(int);", SpaceFuncDef); |
| verifyFormat("T A::operator()();", SpaceFuncDef); |
| verifyFormat("X A::operator++(T);", SpaceFuncDef); |
| // verifyFormat("T A::operator() () {}", SpaceFuncDef); |
| verifyFormat("auto lambda = [] () { return 0; };", SpaceFuncDef); |
| verifyFormat("int x = int(y);", SpaceFuncDef); |
| verifyFormat("M(std::size_t R, std::size_t C) : C(C), data(R) {}", |
| SpaceFuncDef); |
| |
| FormatStyle SpaceIfMacros = getLLVMStyle(); |
| SpaceIfMacros.IfMacros.clear(); |
| SpaceIfMacros.IfMacros.push_back("MYIF"); |
| SpaceIfMacros.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceIfMacros.SpaceBeforeParensOptions.AfterIfMacros = true; |
| verifyFormat("MYIF (a)\n return;", SpaceIfMacros); |
| verifyFormat("MYIF (a)\n return;\nelse MYIF (b)\n return;", SpaceIfMacros); |
| verifyFormat("MYIF (a)\n return;\nelse\n return;", SpaceIfMacros); |
| |
| FormatStyle SpaceForeachMacros = getLLVMStyle(); |
| EXPECT_EQ(SpaceForeachMacros.AllowShortBlocksOnASingleLine, |
| FormatStyle::SBS_Never); |
| EXPECT_EQ(SpaceForeachMacros.AllowShortLoopsOnASingleLine, false); |
| SpaceForeachMacros.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceForeachMacros.SpaceBeforeParensOptions.AfterForeachMacros = true; |
| verifyFormat("for (;;) {\n" |
| "}", |
| SpaceForeachMacros); |
| verifyFormat("foreach (Item *item, itemlist) {\n" |
| "}", |
| SpaceForeachMacros); |
| verifyFormat("Q_FOREACH (Item *item, itemlist) {\n" |
| "}", |
| SpaceForeachMacros); |
| verifyFormat("BOOST_FOREACH (Item *item, itemlist) {\n" |
| "}", |
| SpaceForeachMacros); |
| verifyFormat("UNKNOWN_FOREACH(Item *item, itemlist) {}", SpaceForeachMacros); |
| |
| FormatStyle SomeSpace2 = getLLVMStyle(); |
| SomeSpace2.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SomeSpace2.SpaceBeforeParensOptions.BeforeNonEmptyParentheses = true; |
| verifyFormat("[]() -> float {}", SomeSpace2); |
| verifyFormat("[] (auto foo) {}", SomeSpace2); |
| verifyFormat("[foo]() -> int {}", SomeSpace2); |
| verifyFormat("int f();", SomeSpace2); |
| verifyFormat("void f (int a, T b) {\n" |
| " while (true)\n" |
| " continue;\n" |
| "}", |
| SomeSpace2); |
| verifyFormat("if (true)\n" |
| " f();\n" |
| "else if (true)\n" |
| " f();", |
| SomeSpace2); |
| verifyFormat("do {\n" |
| " do_something();\n" |
| "} while (something());", |
| SomeSpace2); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| SomeSpace2); |
| verifyFormat("A::A() : a (1) {}", SomeSpace2); |
| verifyFormat("void f() __attribute__ ((asdf));", SomeSpace2); |
| verifyFormat("*(&a + 1);\n" |
| "&((&a)[1]);\n" |
| "a[(b + c) * d];\n" |
| "(((a + 1) * 2) + 3) * 4;", |
| SomeSpace2); |
| verifyFormat("#define A(x) x", SomeSpace2); |
| verifyFormat("#define A (x) x", SomeSpace2); |
| verifyFormat("#if defined(x)\n" |
| "#endif", |
| SomeSpace2); |
| verifyFormat("auto i = std::make_unique<int> (5);", SomeSpace2); |
| verifyFormat("size_t x = sizeof (x);", SomeSpace2); |
| verifyFormat("auto f (int x) -> decltype (x);", SomeSpace2); |
| verifyFormat("auto f (int x) -> typeof (x);", SomeSpace2); |
| verifyFormat("auto f (int x) -> _Atomic (x);", SomeSpace2); |
| verifyFormat("auto f (int x) -> __underlying_type (x);", SomeSpace2); |
| verifyFormat("int f (T x) noexcept (x.create());", SomeSpace2); |
| verifyFormat("alignas (128) char a[128];", SomeSpace2); |
| verifyFormat("size_t x = alignof (MyType);", SomeSpace2); |
| verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", |
| SomeSpace2); |
| verifyFormat("int f() throw (Deprecated);", SomeSpace2); |
| verifyFormat("typedef void (*cb) (int);", SomeSpace2); |
| verifyFormat("T A::operator()();", SomeSpace2); |
| // verifyFormat("X A::operator++ (T);", SomeSpace2); |
| verifyFormat("int x = int (y);", SomeSpace2); |
| verifyFormat("auto lambda = []() { return 0; };", SomeSpace2); |
| |
| FormatStyle SpaceAfterOverloadedOperator = getLLVMStyle(); |
| SpaceAfterOverloadedOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| SpaceAfterOverloadedOperator.SpaceBeforeParensOptions |
| .AfterOverloadedOperator = true; |
| |
| verifyFormat("auto operator++ () -> int;", SpaceAfterOverloadedOperator); |
| verifyFormat("X A::operator++ ();", SpaceAfterOverloadedOperator); |
| verifyFormat("some_object.operator++ ();", SpaceAfterOverloadedOperator); |
| verifyFormat("auto func() -> int;", SpaceAfterOverloadedOperator); |
| |
| SpaceAfterOverloadedOperator.SpaceBeforeParensOptions |
| .AfterOverloadedOperator = false; |
| |
| verifyFormat("auto operator++() -> int;", SpaceAfterOverloadedOperator); |
| verifyFormat("X A::operator++();", SpaceAfterOverloadedOperator); |
| verifyFormat("some_object.operator++();", SpaceAfterOverloadedOperator); |
| verifyFormat("auto func() -> int;", SpaceAfterOverloadedOperator); |
| |
| auto SpaceAfterRequires = getLLVMStyle(); |
| SpaceAfterRequires.SpaceBeforeParens = FormatStyle::SBPO_Custom; |
| EXPECT_FALSE( |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause); |
| EXPECT_FALSE( |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression); |
| verifyFormat("void f(auto x)\n" |
| " requires requires(int i) { x + i; }\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("void f(auto x)\n" |
| " requires(requires(int i) { x + i; })\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("if (requires(int i) { x + i; })\n" |
| " return;", |
| SpaceAfterRequires); |
| verifyFormat("bool b = requires(int i) { x + i; };", SpaceAfterRequires); |
| verifyFormat("template <typename T>\n" |
| " requires(Foo<T>)\n" |
| "class Bar;", |
| SpaceAfterRequires); |
| |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; |
| verifyFormat("void f(auto x)\n" |
| " requires requires(int i) { x + i; }\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("void f(auto x)\n" |
| " requires (requires(int i) { x + i; })\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("if (requires(int i) { x + i; })\n" |
| " return;", |
| SpaceAfterRequires); |
| verifyFormat("bool b = requires(int i) { x + i; };", SpaceAfterRequires); |
| verifyFormat("template <typename T>\n" |
| " requires (Foo<T>)\n" |
| "class Bar;", |
| SpaceAfterRequires); |
| |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = false; |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInExpression = true; |
| verifyFormat("void f(auto x)\n" |
| " requires requires (int i) { x + i; }\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("void f(auto x)\n" |
| " requires(requires (int i) { x + i; })\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("if (requires (int i) { x + i; })\n" |
| " return;", |
| SpaceAfterRequires); |
| verifyFormat("bool b = requires (int i) { x + i; };", SpaceAfterRequires); |
| verifyFormat("template <typename T>\n" |
| " requires(Foo<T>)\n" |
| "class Bar;", |
| SpaceAfterRequires); |
| |
| SpaceAfterRequires.SpaceBeforeParensOptions.AfterRequiresInClause = true; |
| verifyFormat("void f(auto x)\n" |
| " requires requires (int i) { x + i; }\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("void f(auto x)\n" |
| " requires (requires (int i) { x + i; })\n" |
| "{}", |
| SpaceAfterRequires); |
| verifyFormat("if (requires (int i) { x + i; })\n" |
| " return;", |
| SpaceAfterRequires); |
| verifyFormat("bool b = requires (int i) { x + i; };", SpaceAfterRequires); |
| verifyFormat("template <typename T>\n" |
| " requires (Foo<T>)\n" |
| "class Bar;", |
| SpaceAfterRequires); |
| } |
| |
| TEST_F(FormatTest, SpaceAfterLogicalNot) { |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpaceAfterLogicalNot = true; |
| |
| verifyFormat("bool x = ! y", Spaces); |
| verifyFormat("if (! isFailure())", Spaces); |
| verifyFormat("if (! (a && b))", Spaces); |
| verifyFormat("\"Error!\"", Spaces); |
| verifyFormat("! ! x", Spaces); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpacesInParentheses) { |
| FormatStyle Spaces = getLLVMStyle(); |
| |
| Spaces.SpacesInParentheses = true; |
| verifyFormat("do_something( ::globalVar );", Spaces); |
| verifyFormat("call( x, y, z );", Spaces); |
| verifyFormat("call();", Spaces); |
| verifyFormat("std::function<void( int, int )> callback;", Spaces); |
| verifyFormat("void inFunction() { std::function<void( int, int )> fct; }", |
| Spaces); |
| verifyFormat("while ( (bool)1 )\n" |
| " continue;", |
| Spaces); |
| verifyFormat("for ( ;; )\n" |
| " continue;", |
| Spaces); |
| verifyFormat("if ( true )\n" |
| " f();\n" |
| "else if ( true )\n" |
| " f();", |
| Spaces); |
| verifyFormat("do {\n" |
| " do_something( (int)i );\n" |
| "} while ( something() );", |
| Spaces); |
| verifyFormat("switch ( x ) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| Spaces); |
| |
| Spaces.SpacesInParentheses = false; |
| Spaces.SpacesInCStyleCastParentheses = true; |
| verifyFormat("Type *A = ( Type * )P;", Spaces); |
| verifyFormat("Type *A = ( vector<Type *, int *> )P;", Spaces); |
| verifyFormat("x = ( int32 )y;", Spaces); |
| verifyFormat("int a = ( int )(2.0f);", Spaces); |
| verifyFormat("#define AA(X) sizeof((( X * )NULL)->a)", Spaces); |
| verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces); |
| verifyFormat("#define x (( int )-1)", Spaces); |
| |
| // Run the first set of tests again with: |
| Spaces.SpacesInParentheses = false; |
| Spaces.SpaceInEmptyParentheses = true; |
| Spaces.SpacesInCStyleCastParentheses = true; |
| verifyFormat("call(x, y, z);", Spaces); |
| verifyFormat("call( );", Spaces); |
| verifyFormat("std::function<void(int, int)> callback;", Spaces); |
| verifyFormat("while (( bool )1)\n" |
| " continue;", |
| Spaces); |
| verifyFormat("for (;;)\n" |
| " continue;", |
| Spaces); |
| verifyFormat("if (true)\n" |
| " f( );\n" |
| "else if (true)\n" |
| " f( );", |
| Spaces); |
| verifyFormat("do {\n" |
| " do_something(( int )i);\n" |
| "} while (something( ));", |
| Spaces); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| Spaces); |
| |
| // Run the first set of tests again with: |
| Spaces.SpaceAfterCStyleCast = true; |
| verifyFormat("call(x, y, z);", Spaces); |
| verifyFormat("call( );", Spaces); |
| verifyFormat("std::function<void(int, int)> callback;", Spaces); |
| verifyFormat("while (( bool ) 1)\n" |
| " continue;", |
| Spaces); |
| verifyFormat("for (;;)\n" |
| " continue;", |
| Spaces); |
| verifyFormat("if (true)\n" |
| " f( );\n" |
| "else if (true)\n" |
| " f( );", |
| Spaces); |
| verifyFormat("do {\n" |
| " do_something(( int ) i);\n" |
| "} while (something( ));", |
| Spaces); |
| verifyFormat("switch (x) {\n" |
| "default:\n" |
| " break;\n" |
| "}", |
| Spaces); |
| verifyFormat("#define CONF_BOOL(x) ( bool * ) ( void * ) (x)", Spaces); |
| verifyFormat("#define CONF_BOOL(x) ( bool * ) (x)", Spaces); |
| verifyFormat("#define CONF_BOOL(x) ( bool ) (x)", Spaces); |
| verifyFormat("bool *y = ( bool * ) ( void * ) (x);", Spaces); |
| verifyFormat("bool *y = ( bool * ) (x);", Spaces); |
| |
| // Run subset of tests again with: |
| Spaces.SpacesInCStyleCastParentheses = false; |
| Spaces.SpaceAfterCStyleCast = true; |
| verifyFormat("while ((bool) 1)\n" |
| " continue;", |
| Spaces); |
| verifyFormat("do {\n" |
| " do_something((int) i);\n" |
| "} while (something( ));", |
| Spaces); |
| |
| verifyFormat("size_t idx = (size_t) (ptr - ((char *) file));", Spaces); |
| verifyFormat("size_t idx = (size_t) a;", Spaces); |
| verifyFormat("size_t idx = (size_t) (a - 1);", Spaces); |
| verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (*foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces); |
| verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (x)", Spaces); |
| verifyFormat("#define CONF_BOOL(x) (bool *) (void *) (int) (x)", Spaces); |
| verifyFormat("bool *y = (bool *) (void *) (x);", Spaces); |
| verifyFormat("bool *y = (bool *) (void *) (int) (x);", Spaces); |
| verifyFormat("bool *y = (bool *) (void *) (int) foo(x);", Spaces); |
| Spaces.ColumnLimit = 80; |
| Spaces.IndentWidth = 4; |
| Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| verifyFormat("void foo( ) {\n" |
| " size_t foo = (*(function))(\n" |
| " Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, " |
| "BarrrrrrrrrrrrLong,\n" |
| " FoooooooooLooooong);\n" |
| "}", |
| Spaces); |
| Spaces.SpaceAfterCStyleCast = false; |
| verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces); |
| verifyFormat("size_t idx = (size_t)a;", Spaces); |
| verifyFormat("size_t idx = (size_t)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (*foo)(a - 1);", Spaces); |
| verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces); |
| |
| verifyFormat("void foo( ) {\n" |
| " size_t foo = (*(function))(\n" |
| " Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, " |
| "BarrrrrrrrrrrrLong,\n" |
| " FoooooooooLooooong);\n" |
| "}", |
| Spaces); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpacesInSquareBrackets) { |
| verifyFormat("int a[5];"); |
| verifyFormat("a[3] += 42;"); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInSquareBrackets = true; |
| // Not lambdas. |
| verifyFormat("int a[ 5 ];", Spaces); |
| verifyFormat("a[ 3 ] += 42;", Spaces); |
| verifyFormat("constexpr char hello[]{\"hello\"};", Spaces); |
| verifyFormat("double &operator[](int i) { return 0; }\n" |
| "int i;", |
| Spaces); |
| verifyFormat("std::unique_ptr<int[]> foo() {}", Spaces); |
| verifyFormat("int i = a[ a ][ a ]->f();", Spaces); |
| verifyFormat("int i = (*b)[ a ]->f();", Spaces); |
| // Lambdas. |
| verifyFormat("int c = []() -> int { return 2; }();\n", Spaces); |
| verifyFormat("return [ i, args... ] {};", Spaces); |
| verifyFormat("int foo = [ &bar ]() {};", Spaces); |
| verifyFormat("int foo = [ = ]() {};", Spaces); |
| verifyFormat("int foo = [ & ]() {};", Spaces); |
| verifyFormat("int foo = [ =, &bar ]() {};", Spaces); |
| verifyFormat("int foo = [ &bar, = ]() {};", Spaces); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpaceBeforeBrackets) { |
| FormatStyle NoSpaceStyle = getLLVMStyle(); |
| verifyFormat("int a[5];", NoSpaceStyle); |
| verifyFormat("a[3] += 42;", NoSpaceStyle); |
| |
| verifyFormat("int a[1];", NoSpaceStyle); |
| verifyFormat("int 1 [a];", NoSpaceStyle); |
| verifyFormat("int a[1][2];", NoSpaceStyle); |
| verifyFormat("a[7] = 5;", NoSpaceStyle); |
| verifyFormat("int a = (f())[23];", NoSpaceStyle); |
| verifyFormat("f([] {})", NoSpaceStyle); |
| |
| FormatStyle Space = getLLVMStyle(); |
| Space.SpaceBeforeSquareBrackets = true; |
| verifyFormat("int c = []() -> int { return 2; }();\n", Space); |
| verifyFormat("return [i, args...] {};", Space); |
| |
| verifyFormat("int a [5];", Space); |
| verifyFormat("a [3] += 42;", Space); |
| verifyFormat("constexpr char hello []{\"hello\"};", Space); |
| verifyFormat("double &operator[](int i) { return 0; }\n" |
| "int i;", |
| Space); |
| verifyFormat("std::unique_ptr<int []> foo() {}", Space); |
| verifyFormat("int i = a [a][a]->f();", Space); |
| verifyFormat("int i = (*b) [a]->f();", Space); |
| |
| verifyFormat("int a [1];", Space); |
| verifyFormat("int 1 [a];", Space); |
| verifyFormat("int a [1][2];", Space); |
| verifyFormat("a [7] = 5;", Space); |
| verifyFormat("int a = (f()) [23];", Space); |
| verifyFormat("f([] {})", Space); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpaceBeforeAssignmentOperators) { |
| verifyFormat("int a = 5;"); |
| verifyFormat("a += 42;"); |
| verifyFormat("a or_eq 8;"); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpaceBeforeAssignmentOperators = false; |
| verifyFormat("int a= 5;", Spaces); |
| verifyFormat("a+= 42;", Spaces); |
| verifyFormat("a or_eq 8;", Spaces); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpaceBeforeColon) { |
| verifyFormat("class Foo : public Bar {};"); |
| verifyFormat("Foo::Foo() : foo(1) {}"); |
| verifyFormat("for (auto a : b) {\n}"); |
| verifyFormat("int x = a ? b : c;"); |
| verifyFormat("{\n" |
| "label0:\n" |
| " int x = 0;\n" |
| "}"); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| "default:\n" |
| "}"); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1: {\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default: {\n" |
| " break;\n" |
| "}\n" |
| "}"); |
| |
| FormatStyle CtorInitializerStyle = getLLVMStyleWithColumns(30); |
| CtorInitializerStyle.SpaceBeforeCtorInitializerColon = false; |
| verifyFormat("class Foo : public Bar {};", CtorInitializerStyle); |
| verifyFormat("Foo::Foo(): foo(1) {}", CtorInitializerStyle); |
| verifyFormat("for (auto a : b) {\n}", CtorInitializerStyle); |
| verifyFormat("int x = a ? b : c;", CtorInitializerStyle); |
| verifyFormat("{\n" |
| "label1:\n" |
| " int x = 0;\n" |
| "}", |
| CtorInitializerStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| "default:\n" |
| "}", |
| CtorInitializerStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1: {\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default: {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| CtorInitializerStyle); |
| CtorInitializerStyle.BreakConstructorInitializers = |
| FormatStyle::BCIS_AfterColon; |
| verifyFormat("Fooooooooooo::Fooooooooooo():\n" |
| " aaaaaaaaaaaaaaaa(1),\n" |
| " bbbbbbbbbbbbbbbb(2) {}", |
| CtorInitializerStyle); |
| CtorInitializerStyle.BreakConstructorInitializers = |
| FormatStyle::BCIS_BeforeComma; |
| verifyFormat("Fooooooooooo::Fooooooooooo()\n" |
| " : aaaaaaaaaaaaaaaa(1)\n" |
| " , bbbbbbbbbbbbbbbb(2) {}", |
| CtorInitializerStyle); |
| CtorInitializerStyle.BreakConstructorInitializers = |
| FormatStyle::BCIS_BeforeColon; |
| verifyFormat("Fooooooooooo::Fooooooooooo()\n" |
| " : aaaaaaaaaaaaaaaa(1),\n" |
| " bbbbbbbbbbbbbbbb(2) {}", |
| CtorInitializerStyle); |
| CtorInitializerStyle.ConstructorInitializerIndentWidth = 0; |
| verifyFormat("Fooooooooooo::Fooooooooooo()\n" |
| ": aaaaaaaaaaaaaaaa(1),\n" |
| " bbbbbbbbbbbbbbbb(2) {}", |
| CtorInitializerStyle); |
| |
| FormatStyle InheritanceStyle = getLLVMStyleWithColumns(30); |
| InheritanceStyle.SpaceBeforeInheritanceColon = false; |
| verifyFormat("class Foo: public Bar {};", InheritanceStyle); |
| verifyFormat("Foo::Foo() : foo(1) {}", InheritanceStyle); |
| verifyFormat("for (auto a : b) {\n}", InheritanceStyle); |
| verifyFormat("int x = a ? b : c;", InheritanceStyle); |
| verifyFormat("{\n" |
| "label2:\n" |
| " int x = 0;\n" |
| "}", |
| InheritanceStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| "default:\n" |
| "}", |
| InheritanceStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1: {\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default: {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| InheritanceStyle); |
| InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_AfterComma; |
| verifyFormat("class Foooooooooooooooooooooo\n" |
| " : public aaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbb {\n" |
| "}", |
| InheritanceStyle); |
| InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_AfterColon; |
| verifyFormat("class Foooooooooooooooooooooo:\n" |
| " public aaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbb {\n" |
| "}", |
| InheritanceStyle); |
| InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma; |
| verifyFormat("class Foooooooooooooooooooooo\n" |
| " : public aaaaaaaaaaaaaaaaaa\n" |
| " , public bbbbbbbbbbbbbbbbbb {\n" |
| "}", |
| InheritanceStyle); |
| InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; |
| verifyFormat("class Foooooooooooooooooooooo\n" |
| " : public aaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbb {\n" |
| "}", |
| InheritanceStyle); |
| InheritanceStyle.ConstructorInitializerIndentWidth = 0; |
| verifyFormat("class Foooooooooooooooooooooo\n" |
| ": public aaaaaaaaaaaaaaaaaa,\n" |
| " public bbbbbbbbbbbbbbbbbb {}", |
| InheritanceStyle); |
| |
| FormatStyle ForLoopStyle = getLLVMStyle(); |
| ForLoopStyle.SpaceBeforeRangeBasedForLoopColon = false; |
| verifyFormat("class Foo : public Bar {};", ForLoopStyle); |
| verifyFormat("Foo::Foo() : foo(1) {}", ForLoopStyle); |
| verifyFormat("for (auto a: b) {\n}", ForLoopStyle); |
| verifyFormat("int x = a ? b : c;", ForLoopStyle); |
| verifyFormat("{\n" |
| "label2:\n" |
| " int x = 0;\n" |
| "}", |
| ForLoopStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| "default:\n" |
| "}", |
| ForLoopStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1: {\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default: {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| ForLoopStyle); |
| |
| FormatStyle CaseStyle = getLLVMStyle(); |
| CaseStyle.SpaceBeforeCaseColon = true; |
| verifyFormat("class Foo : public Bar {};", CaseStyle); |
| verifyFormat("Foo::Foo() : foo(1) {}", CaseStyle); |
| verifyFormat("for (auto a : b) {\n}", CaseStyle); |
| verifyFormat("int x = a ? b : c;", CaseStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1 :\n" |
| "default :\n" |
| "}", |
| CaseStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1 : {\n" |
| " break;\n" |
| "}\n" |
| "case 2 : {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default : {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| CaseStyle); |
| |
| FormatStyle NoSpaceStyle = getLLVMStyle(); |
| EXPECT_EQ(NoSpaceStyle.SpaceBeforeCaseColon, false); |
| NoSpaceStyle.SpaceBeforeCtorInitializerColon = false; |
| NoSpaceStyle.SpaceBeforeInheritanceColon = false; |
| NoSpaceStyle.SpaceBeforeRangeBasedForLoopColon = false; |
| verifyFormat("class Foo: public Bar {};", NoSpaceStyle); |
| verifyFormat("Foo::Foo(): foo(1) {}", NoSpaceStyle); |
| verifyFormat("for (auto a: b) {\n}", NoSpaceStyle); |
| verifyFormat("int x = a ? b : c;", NoSpaceStyle); |
| verifyFormat("{\n" |
| "label3:\n" |
| " int x = 0;\n" |
| "}", |
| NoSpaceStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1:\n" |
| "default:\n" |
| "}", |
| NoSpaceStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1: {\n" |
| " break;\n" |
| "}\n" |
| "case 2: {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default: {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| NoSpaceStyle); |
| |
| FormatStyle InvertedSpaceStyle = getLLVMStyle(); |
| InvertedSpaceStyle.SpaceBeforeCaseColon = true; |
| InvertedSpaceStyle.SpaceBeforeCtorInitializerColon = false; |
| InvertedSpaceStyle.SpaceBeforeInheritanceColon = false; |
| InvertedSpaceStyle.SpaceBeforeRangeBasedForLoopColon = false; |
| verifyFormat("class Foo: public Bar {};", InvertedSpaceStyle); |
| verifyFormat("Foo::Foo(): foo(1) {}", InvertedSpaceStyle); |
| verifyFormat("for (auto a: b) {\n}", InvertedSpaceStyle); |
| verifyFormat("int x = a ? b : c;", InvertedSpaceStyle); |
| verifyFormat("{\n" |
| "label3:\n" |
| " int x = 0;\n" |
| "}", |
| InvertedSpaceStyle); |
| verifyFormat("switch (x) {\n" |
| "case 1 :\n" |
| "case 2 : {\n" |
| " break;\n" |
| "}\n" |
| "default :\n" |
| " break;\n" |
| "}", |
| InvertedSpaceStyle); |
| verifyFormat("switch (allBraces) {\n" |
| "case 1 : {\n" |
| " break;\n" |
| "}\n" |
| "case 2 : {\n" |
| " [[fallthrough]];\n" |
| "}\n" |
| "default : {\n" |
| " break;\n" |
| "}\n" |
| "}", |
| InvertedSpaceStyle); |
| } |
| |
| TEST_F(FormatTest, ConfigurableSpaceAroundPointerQualifiers) { |
| FormatStyle Style = getLLVMStyle(); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; |
| verifyFormat("void* const* x = NULL;", Style); |
| |
| #define verifyQualifierSpaces(Code, Pointers, Qualifiers) \ |
| do { \ |
| Style.PointerAlignment = FormatStyle::Pointers; \ |
| Style.SpaceAroundPointerQualifiers = FormatStyle::Qualifiers; \ |
| verifyFormat(Code, Style); \ |
| } while (false) |
| |
| verifyQualifierSpaces("void* const* x = NULL;", PAS_Left, SAPQ_Default); |
| verifyQualifierSpaces("void *const *x = NULL;", PAS_Right, SAPQ_Default); |
| verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Default); |
| |
| verifyQualifierSpaces("void* const* x = NULL;", PAS_Left, SAPQ_Before); |
| verifyQualifierSpaces("void * const *x = NULL;", PAS_Right, SAPQ_Before); |
| verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Before); |
| |
| verifyQualifierSpaces("void* const * x = NULL;", PAS_Left, SAPQ_After); |
| verifyQualifierSpaces("void *const *x = NULL;", PAS_Right, SAPQ_After); |
| verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_After); |
| |
| verifyQualifierSpaces("void* const * x = NULL;", PAS_Left, SAPQ_Both); |
| verifyQualifierSpaces("void * const *x = NULL;", PAS_Right, SAPQ_Both); |
| verifyQualifierSpaces("void * const * x = NULL;", PAS_Middle, SAPQ_Both); |
| |
| verifyQualifierSpaces("Foo::operator void const*();", PAS_Left, SAPQ_Default); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, |
| SAPQ_Default); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, |
| SAPQ_Default); |
| |
| verifyQualifierSpaces("Foo::operator void const*();", PAS_Left, SAPQ_Before); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, |
| SAPQ_Before); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, |
| SAPQ_Before); |
| |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Left, SAPQ_After); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, SAPQ_After); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, |
| SAPQ_After); |
| |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Left, SAPQ_Both); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Right, SAPQ_Both); |
| verifyQualifierSpaces("Foo::operator void const *();", PAS_Middle, SAPQ_Both); |
| |
| #undef verifyQualifierSpaces |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.AttributeMacros.push_back("qualified"); |
| Spaces.PointerAlignment = FormatStyle::PAS_Right; |
| Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Default; |
| verifyFormat("SomeType *volatile *a = NULL;", Spaces); |
| verifyFormat("SomeType *__attribute__((attr)) *a = NULL;", Spaces); |
| verifyFormat("std::vector<SomeType *const *> x;", Spaces); |
| verifyFormat("std::vector<SomeType *qualified *> x;", Spaces); |
| verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); |
| Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Before; |
| verifyFormat("SomeType * volatile *a = NULL;", Spaces); |
| verifyFormat("SomeType * __attribute__((attr)) *a = NULL;", Spaces); |
| verifyFormat("std::vector<SomeType * const *> x;", Spaces); |
| verifyFormat("std::vector<SomeType * qualified *> x;", Spaces); |
| verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); |
| |
| // Check that SAPQ_Before doesn't result in extra spaces for PAS_Left. |
| Spaces.PointerAlignment = FormatStyle::PAS_Left; |
| Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Before; |
| verifyFormat("SomeType* volatile* a = NULL;", Spaces); |
| verifyFormat("SomeType* __attribute__((attr))* a = NULL;", Spaces); |
| verifyFormat("std::vector<SomeType* const*> x;", Spaces); |
| verifyFormat("std::vector<SomeType* qualified*> x;", Spaces); |
| verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); |
| // However, setting it to SAPQ_After should add spaces after __attribute, etc. |
| Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_After; |
| verifyFormat("SomeType* volatile * a = NULL;", Spaces); |
| verifyFormat("SomeType* __attribute__((attr)) * a = NULL;", Spaces); |
| verifyFormat("std::vector<SomeType* const *> x;", Spaces); |
| verifyFormat("std::vector<SomeType* qualified *> x;", Spaces); |
| verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); |
| |
| // PAS_Middle should not have any noticeable changes even for SAPQ_Both |
| Spaces.PointerAlignment = FormatStyle::PAS_Middle; |
| Spaces.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_After; |
| verifyFormat("SomeType * volatile * a = NULL;", Spaces); |
| verifyFormat("SomeType * __attribute__((attr)) * a = NULL;", Spaces); |
| verifyFormat("std::vector<SomeType * const *> x;", Spaces); |
| verifyFormat("std::vector<SomeType * qualified *> x;", Spaces); |
| verifyFormat("std::vector<SomeVar * NotAQualifier> x;", Spaces); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| |
| verifyFormat("#define a 3\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style); |
| |
| verifyFormat("#define f(x) (x * x)\n" |
| "#define fff(x, y, z) (x * y + z)\n" |
| "#define ffff(x, y) (x - y)", |
| Style); |
| |
| verifyFormat("#define foo(x, y) (x + y)\n" |
| "#define bar (5, 6)(2 + 2)", |
| Style); |
| |
| verifyFormat("#define a 3\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)\n" |
| "#define f(x) (x * x)\n" |
| "#define fff(x, y, z) (x * y + z)\n" |
| "#define ffff(x, y) (x - y)", |
| Style); |
| |
| Style.AlignConsecutiveMacros.Enabled = true; |
| verifyFormat("#define a 3\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style); |
| |
| verifyFormat("#define true 1\n" |
| "#define false 0", |
| Style); |
| |
| verifyFormat("#define f(x) (x * x)\n" |
| "#define fff(x, y, z) (x * y + z)\n" |
| "#define ffff(x, y) (x - y)", |
| Style); |
| |
| verifyFormat("#define foo(x, y) (x + y)\n" |
| "#define bar (5, 6)(2 + 2)", |
| Style); |
| |
| verifyFormat("#define a 3\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)\n" |
| "#define f(x) (x * x)\n" |
| "#define fff(x, y, z) (x * y + z)\n" |
| "#define ffff(x, y) (x - y)", |
| Style); |
| |
| verifyFormat("#define a 5\n" |
| "#define foo(x, y) (x + y)\n" |
| "#define CCC (6)\n" |
| "auto lambda = []() {\n" |
| " auto ii = 0;\n" |
| " float j = 0;\n" |
| " return 0;\n" |
| "};\n" |
| "int i = 0;\n" |
| "float i2 = 0;\n" |
| "auto v = type{\n" |
| " i = 1, //\n" |
| " (i = 2), //\n" |
| " i = 3 //\n" |
| "};", |
| Style); |
| |
| Style.AlignConsecutiveMacros.Enabled = false; |
| Style.ColumnLimit = 20; |
| |
| verifyFormat("#define a \\\n" |
| " \"aabbbbbbbbbbbb\"\n" |
| "#define D \\\n" |
| " \"aabbbbbbbbbbbb\" \\\n" |
| " \"ccddeeeeeeeee\"\n" |
| "#define B \\\n" |
| " \"QQQQQQQQQQQQQ\" \\\n" |
| " \"FFFFFFFFFFFFF\" \\\n" |
| " \"LLLLLLLL\"\n", |
| Style); |
| |
| Style.AlignConsecutiveMacros.Enabled = true; |
| verifyFormat("#define a \\\n" |
| " \"aabbbbbbbbbbbb\"\n" |
| "#define D \\\n" |
| " \"aabbbbbbbbbbbb\" \\\n" |
| " \"ccddeeeeeeeee\"\n" |
| "#define B \\\n" |
| " \"QQQQQQQQQQQQQ\" \\\n" |
| " \"FFFFFFFFFFFFF\" \\\n" |
| " \"LLLLLLLL\"\n", |
| Style); |
| |
| // Test across comments |
| Style.MaxEmptyLinesToKeep = 10; |
| Style.ReflowComments = false; |
| Style.AlignConsecutiveMacros.AcrossComments = true; |
| EXPECT_EQ("#define a 3\n" |
| "// line comment\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "// line comment\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "/* block comment */\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "/* block comment */\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "// empty lines still break.\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "// empty lines still break.\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| // Test across empty lines |
| Style.AlignConsecutiveMacros.AcrossComments = false; |
| Style.AlignConsecutiveMacros.AcrossEmptyLines = true; |
| EXPECT_EQ("#define a 3\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "// comments should break alignment\n" |
| "//\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "// comments should break alignment\n" |
| "//\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| // Test across empty lines and comments |
| Style.AlignConsecutiveMacros.AcrossComments = true; |
| verifyFormat("#define a 3\n" |
| "\n" |
| "// line comment\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style); |
| |
| EXPECT_EQ("#define a 3\n" |
| "\n" |
| "\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "\n" |
| "\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| |
| EXPECT_EQ("#define a 3\n" |
| "\n" |
| "\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| format("#define a 3\n" |
| "\n" |
| "\n" |
| "/* multi-line *\n" |
| " * block comment */\n" |
| "\n" |
| "\n" |
| "#define bbbb 4\n" |
| "#define ccc (5)", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLines) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveMacros.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true; |
| |
| Alignment.MaxEmptyLinesToKeep = 10; |
| /* Test alignment across empty lines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "int oneTwoThree= 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment)); |
| |
| /* Test across comments */ |
| EXPECT_EQ("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| /* Test across comments and newlines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveDeclarationsAcrossEmptyLinesAndComments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveDeclarations.Enabled = true; |
| Alignment.AlignConsecutiveDeclarations.AcrossEmptyLines = true; |
| Alignment.AlignConsecutiveDeclarations.AcrossComments = true; |
| |
| Alignment.MaxEmptyLinesToKeep = 10; |
| /* Test alignment across empty lines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "float const oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "float const oneTwoThree = 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "float const one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "float const one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| Alignment)); |
| |
| /* Test across comments */ |
| EXPECT_EQ("float const a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("float const a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("float const a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("float const a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| /* Test across comments and newlines */ |
| EXPECT_EQ("float const a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("float const a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("float const a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("float const a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveBitFieldsAcrossEmptyLinesAndComments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveBitFields.Enabled = true; |
| Alignment.AlignConsecutiveBitFields.AcrossEmptyLines = true; |
| Alignment.AlignConsecutiveBitFields.AcrossComments = true; |
| |
| Alignment.MaxEmptyLinesToKeep = 10; |
| /* Test alignment across empty lines */ |
| EXPECT_EQ("int a : 5;\n" |
| "\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| EXPECT_EQ("int a : 5;\n" |
| "int one : 1;\n" |
| "\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "int one : 1;\n" |
| "\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| |
| /* Test across comments */ |
| EXPECT_EQ("int a : 5;\n" |
| "/* block comment */\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "/* block comment */\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| EXPECT_EQ("int a : 5;\n" |
| "int one : 1;\n" |
| "// line comment\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "int one : 1;\n" |
| "// line comment\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| |
| /* Test across comments and newlines */ |
| EXPECT_EQ("int a : 5;\n" |
| "/* block comment */\n" |
| "\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "/* block comment */\n" |
| "\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| EXPECT_EQ("int a : 5;\n" |
| "int one : 1;\n" |
| "\n" |
| "// line comment\n" |
| "\n" |
| "int longbitfield : 6;", |
| format("int a : 5;\n" |
| "int one : 1;\n" |
| "\n" |
| "// line comment \n" |
| "\n" |
| "int longbitfield : 6;", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossComments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveMacros.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.AcrossComments = true; |
| |
| Alignment.MaxEmptyLinesToKeep = 10; |
| /* Test alignment across empty lines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "int oneTwoThree= 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| Alignment)); |
| |
| /* Test across comments */ |
| EXPECT_EQ("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "/*\n" |
| " * multi-line block comment\n" |
| " */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "/*\n" |
| " * multi-line block comment\n" |
| " */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "//\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "//\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| /* Test across comments and newlines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveAssignmentsAcrossEmptyLinesAndComments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveMacros.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true; |
| Alignment.AlignConsecutiveAssignments.AcrossComments = true; |
| verifyFormat("int a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| verifyFormat("int a = method();\n" |
| "int oneTwoThree = 133;", |
| Alignment); |
| verifyFormat("a &= 5;\n" |
| "bcd *= 5;\n" |
| "ghtyf += 5;\n" |
| "dvfvdb -= 5;\n" |
| "a /= 5;\n" |
| "vdsvsv %= 5;\n" |
| "sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv |= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("int i = 1, j = 10;\n" |
| "something = 2000;", |
| Alignment); |
| verifyFormat("something = 2000;\n" |
| "int i = 1, j = 10;\n", |
| Alignment); |
| verifyFormat("something = 2000;\n" |
| "another = 911;\n" |
| "int i = 1, j = 10;\n" |
| "oneMore = 1;\n" |
| "i = 2;", |
| Alignment); |
| verifyFormat("int a = 5;\n" |
| "int one = 1;\n" |
| "method();\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment); |
| verifyFormat("int oneTwoThree = 123;\n" |
| "int oneTwo = 12;\n" |
| "method();\n", |
| Alignment); |
| verifyFormat("int oneTwoThree = 123; // comment\n" |
| "int oneTwo = 12; // comment", |
| Alignment); |
| |
| // Bug 25167 |
| /* Uncomment when fixed |
| verifyFormat("#if A\n" |
| "#else\n" |
| "int aaaaaaaa = 12;\n" |
| "#endif\n" |
| "#if B\n" |
| "#else\n" |
| "int a = 12;\n" |
| "#endif\n", |
| Alignment); |
| verifyFormat("enum foo {\n" |
| "#if A\n" |
| "#else\n" |
| " aaaaaaaa = 12;\n" |
| "#endif\n" |
| "#if B\n" |
| "#else\n" |
| " a = 12;\n" |
| "#endif\n" |
| "};\n", |
| Alignment); |
| */ |
| |
| Alignment.MaxEmptyLinesToKeep = 10; |
| /* Test alignment across empty lines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "int oneTwoThree= 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment)); |
| |
| /* Test across comments */ |
| EXPECT_EQ("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| /* Test across comments and newlines */ |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "//\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "//\n" |
| "// multi-line line comment\n" |
| "//\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "/*\n" |
| " * multi-line block comment\n" |
| " */\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "/*\n" |
| " * multi-line block comment\n" |
| " */\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "\n" |
| "\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "/* block comment */\n" |
| "\n" |
| "\n" |
| "\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "\n" |
| "\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "// line comment\n" |
| "\n" |
| "\n" |
| "\n" |
| "int oneTwoThree=123;", |
| Alignment)); |
| |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " int b = 23; \\\n" |
| " int ccc = 234; \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " int b = 23; \\\n" |
| " int ccc = 234; \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right; |
| verifyFormat("#define A " |
| " \\\n" |
| " int aaaa = 12; " |
| " \\\n" |
| " int b = 23; " |
| " \\\n" |
| " int ccc = 234; " |
| " \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int " |
| "k = 4, int l = 5,\n" |
| " int m = 6) {\n" |
| " int j = 10;\n" |
| " otherThing = 1;\n" |
| "}", |
| Alignment); |
| verifyFormat("void SomeFunction(int parameter = 0) {\n" |
| " int i = 1;\n" |
| " int j = 2;\n" |
| " int big = 10000;\n" |
| "}", |
| Alignment); |
| verifyFormat("class C {\n" |
| "public:\n" |
| " int i = 1;\n" |
| " virtual void f() = 0;\n" |
| "};", |
| Alignment); |
| verifyFormat("int i = 1;\n" |
| "if (SomeType t = getSomething()) {\n" |
| "}\n" |
| "int j = 2;\n" |
| "int big = 10000;", |
| Alignment); |
| verifyFormat("int j = 7;\n" |
| "for (int k = 0; k < N; ++k) {\n" |
| "}\n" |
| "int j = 2;\n" |
| "int big = 10000;\n" |
| "}", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat("int i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable\n" |
| " = someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat("int i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable =\n" |
| " someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| |
| verifyFormat("auto lambda = []() {\n" |
| " auto i = 0;\n" |
| " return 0;\n" |
| "};\n" |
| "int i = 0;\n" |
| "auto v = type{\n" |
| " i = 1, //\n" |
| " (i = 2), //\n" |
| " i = 3 //\n" |
| "};", |
| Alignment); |
| |
| verifyFormat( |
| "int i = 1;\n" |
| "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" |
| " loooooooooooooooooooooongParameterB);\n" |
| "int j = 2;", |
| Alignment); |
| |
| verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n" |
| " typename B = very_long_type_name_1,\n" |
| " typename T_2 = very_long_type_name_2>\n" |
| "auto foo() {}\n", |
| Alignment); |
| verifyFormat("int a, b = 1;\n" |
| "int c = 2;\n" |
| "int dd = 3;\n", |
| Alignment); |
| verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" |
| "float b[1][] = {{3.f}};\n", |
| Alignment); |
| verifyFormat("for (int i = 0; i < 1; i++)\n" |
| " int x = 1;\n", |
| Alignment); |
| verifyFormat("for (i = 0; i < 1; i++)\n" |
| " x = 1;\n" |
| "y = 1;\n", |
| Alignment); |
| |
| Alignment.ReflowComments = true; |
| Alignment.ColumnLimit = 50; |
| EXPECT_EQ("int x = 0;\n" |
| "int yy = 1; /// specificlennospace\n" |
| "int zzz = 2;\n", |
| format("int x = 0;\n" |
| "int yy = 1; ///specificlennospace\n" |
| "int zzz = 2;\n", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignCompoundAssignments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.AlignConsecutiveAssignments.AlignCompound = true; |
| Alignment.AlignConsecutiveAssignments.PadOperators = false; |
| verifyFormat("sfdbddfbdfbb = 5;\n" |
| "dvsdsv = 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv |= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv <<= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| // Test that `<=` is not treated as a compound assignment. |
| verifyFormat("aa &= 5;\n" |
| "b <= 10;\n" |
| "c = 15;", |
| Alignment); |
| Alignment.AlignConsecutiveAssignments.PadOperators = true; |
| verifyFormat("sfdbddfbdfbb = 5;\n" |
| "dvsdsv = 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv |= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv <<= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true; |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = false; |
| Alignment.AlignConsecutiveAssignments.AcrossComments = true; |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| Alignment.AlignConsecutiveAssignments.AcrossEmptyLines = true; |
| EXPECT_EQ("a += 5;\n" |
| "one >>= 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| format("a += 5;\n" |
| "one >>= 1;\n" |
| "\n" |
| "oneTwoThree = 123;\n", |
| Alignment)); |
| EXPECT_EQ("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree <<= 123;\n", |
| format("a += 5;\n" |
| "one = 1;\n" |
| "//\n" |
| "oneTwoThree <<= 123;\n", |
| Alignment)); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveAssignments) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveMacros.Enabled = true; |
| verifyFormat("int a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| verifyFormat("int a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| verifyFormat("int a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| verifyFormat("int a = method();\n" |
| "int oneTwoThree = 133;", |
| Alignment); |
| verifyFormat("aa <= 5;\n" |
| "a &= 5;\n" |
| "bcd *= 5;\n" |
| "ghtyf += 5;\n" |
| "dvfvdb -= 5;\n" |
| "a /= 5;\n" |
| "vdsvsv %= 5;\n" |
| "sfdbddfbdfbb ^= 5;\n" |
| "dvsdsv |= 5;\n" |
| "int dsvvdvsdvvv = 123;", |
| Alignment); |
| verifyFormat("int i = 1, j = 10;\n" |
| "something = 2000;", |
| Alignment); |
| verifyFormat("something = 2000;\n" |
| "int i = 1, j = 10;\n", |
| Alignment); |
| verifyFormat("something = 2000;\n" |
| "another = 911;\n" |
| "int i = 1, j = 10;\n" |
| "oneMore = 1;\n" |
| "i = 2;", |
| Alignment); |
| verifyFormat("int a = 5;\n" |
| "int one = 1;\n" |
| "method();\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment); |
| verifyFormat("int oneTwoThree = 123;\n" |
| "int oneTwo = 12;\n" |
| "method();\n", |
| Alignment); |
| verifyFormat("int oneTwoThree = 123; // comment\n" |
| "int oneTwo = 12; // comment", |
| Alignment); |
| verifyFormat("int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator=() {", |
| Alignment); |
| verifyFormat("int f() = delete;\n" |
| "int &operator() = delete;\n" |
| "int &operator=() {", |
| Alignment); |
| verifyFormat("int f() = default; // comment\n" |
| "int &operator() = default; // comment\n" |
| "int &operator=() {", |
| Alignment); |
| verifyFormat("int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator==() {", |
| Alignment); |
| verifyFormat("int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator<=() {", |
| Alignment); |
| verifyFormat("int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator!=() {", |
| Alignment); |
| verifyFormat("int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator=();", |
| Alignment); |
| verifyFormat("int f() = delete;\n" |
| "int &operator() = delete;\n" |
| "int &operator=();", |
| Alignment); |
| verifyFormat("/* long long padding */ int f() = default;\n" |
| "int &operator() = default;\n" |
| "int &operator/**/ =();", |
| Alignment); |
| // https://llvm.org/PR33697 |
| FormatStyle AlignmentWithPenalty = getLLVMStyle(); |
| AlignmentWithPenalty.AlignConsecutiveAssignments.Enabled = true; |
| AlignmentWithPenalty.PenaltyReturnTypeOnItsOwnLine = 5000; |
| verifyFormat("class SSSSSSSSSSSSSSSSSSSSSSSSSSSS {\n" |
| " void f() = delete;\n" |
| " SSSSSSSSSSSSSSSSSSSSSSSSSSSS &operator=(\n" |
| " const SSSSSSSSSSSSSSSSSSSSSSSSSSSS &other) = delete;\n" |
| "};\n", |
| AlignmentWithPenalty); |
| |
| // Bug 25167 |
| /* Uncomment when fixed |
| verifyFormat("#if A\n" |
| "#else\n" |
| "int aaaaaaaa = 12;\n" |
| "#endif\n" |
| "#if B\n" |
| "#else\n" |
| "int a = 12;\n" |
| "#endif\n", |
| Alignment); |
| verifyFormat("enum foo {\n" |
| "#if A\n" |
| "#else\n" |
| " aaaaaaaa = 12;\n" |
| "#endif\n" |
| "#if B\n" |
| "#else\n" |
| " a = 12;\n" |
| "#endif\n" |
| "};\n", |
| Alignment); |
| */ |
| |
| EXPECT_EQ("int a = 5;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "\n" |
| "int oneTwoThree= 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| Alignment)); |
| EXPECT_EQ("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| format("int a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "int oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment)); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " int b = 23; \\\n" |
| " int ccc = 234; \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " int b = 23; \\\n" |
| " int ccc = 234; \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right; |
| verifyFormat("#define A " |
| " \\\n" |
| " int aaaa = 12; " |
| " \\\n" |
| " int b = 23; " |
| " \\\n" |
| " int ccc = 234; " |
| " \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int " |
| "k = 4, int l = 5,\n" |
| " int m = 6) {\n" |
| " int j = 10;\n" |
| " otherThing = 1;\n" |
| "}", |
| Alignment); |
| verifyFormat("void SomeFunction(int parameter = 0) {\n" |
| " int i = 1;\n" |
| " int j = 2;\n" |
| " int big = 10000;\n" |
| "}", |
| Alignment); |
| verifyFormat("class C {\n" |
| "public:\n" |
| " int i = 1;\n" |
| " virtual void f() = 0;\n" |
| "};", |
| Alignment); |
| verifyFormat("int i = 1;\n" |
| "if (SomeType t = getSomething()) {\n" |
| "}\n" |
| "int j = 2;\n" |
| "int big = 10000;", |
| Alignment); |
| verifyFormat("int j = 7;\n" |
| "for (int k = 0; k < N; ++k) {\n" |
| "}\n" |
| "int j = 2;\n" |
| "int big = 10000;\n" |
| "}", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat("int i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable\n" |
| " = someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat("int i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable =\n" |
| " someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| |
| verifyFormat("auto lambda = []() {\n" |
| " auto i = 0;\n" |
| " return 0;\n" |
| "};\n" |
| "int i = 0;\n" |
| "auto v = type{\n" |
| " i = 1, //\n" |
| " (i = 2), //\n" |
| " i = 3 //\n" |
| "};", |
| Alignment); |
| |
| verifyFormat( |
| "int i = 1;\n" |
| "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" |
| " loooooooooooooooooooooongParameterB);\n" |
| "int j = 2;", |
| Alignment); |
| |
| verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n" |
| " typename B = very_long_type_name_1,\n" |
| " typename T_2 = very_long_type_name_2>\n" |
| "auto foo() {}\n", |
| Alignment); |
| verifyFormat("int a, b = 1;\n" |
| "int c = 2;\n" |
| "int dd = 3;\n", |
| Alignment); |
| verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" |
| "float b[1][] = {{3.f}};\n", |
| Alignment); |
| verifyFormat("for (int i = 0; i < 1; i++)\n" |
| " int x = 1;\n", |
| Alignment); |
| verifyFormat("for (i = 0; i < 1; i++)\n" |
| " x = 1;\n" |
| "y = 1;\n", |
| Alignment); |
| |
| EXPECT_EQ(Alignment.ReflowComments, true); |
| Alignment.ColumnLimit = 50; |
| EXPECT_EQ("int x = 0;\n" |
| "int yy = 1; /// specificlennospace\n" |
| "int zzz = 2;\n", |
| format("int x = 0;\n" |
| "int yy = 1; ///specificlennospace\n" |
| "int zzz = 2;\n", |
| Alignment)); |
| |
| verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n" |
| "auto b = [] {\n" |
| " f();\n" |
| " return;\n" |
| "};", |
| Alignment); |
| verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n" |
| "auto b = g([] {\n" |
| " f();\n" |
| " return;\n" |
| "});", |
| Alignment); |
| verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n" |
| "auto b = g(param, [] {\n" |
| " f();\n" |
| " return;\n" |
| "});", |
| Alignment); |
| verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n" |
| "auto b = [] {\n" |
| " if (condition) {\n" |
| " return;\n" |
| " }\n" |
| "};", |
| Alignment); |
| |
| verifyFormat("auto b = f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| " ccc ? aaaaa : bbbbb,\n" |
| " dddddddddddddddddddddddddd);", |
| Alignment); |
| // FIXME: https://llvm.org/PR53497 |
| // verifyFormat("auto aaaaaaaaaaaa = f();\n" |
| // "auto b = f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" |
| // " ccc ? aaaaa : bbbbb,\n" |
| // " dddddddddddddddddddddddddd);", |
| // Alignment); |
| |
| // Confirm proper handling of AlignConsecutiveAssignments with |
| // BinPackArguments. |
| // See https://llvm.org/PR55360 |
| Alignment = getLLVMStyleWithColumns(50); |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.BinPackArguments = false; |
| verifyFormat("int a_long_name = 1;\n" |
| "auto b = B({a_long_name, a_long_name},\n" |
| " {a_longer_name_for_wrap,\n" |
| " a_longer_name_for_wrap});", |
| Alignment); |
| verifyFormat("int a_long_name = 1;\n" |
| "auto b = B{{a_long_name, a_long_name},\n" |
| " {a_longer_name_for_wrap,\n" |
| " a_longer_name_for_wrap}};", |
| Alignment); |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveBitFields) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveBitFields.Enabled = true; |
| verifyFormat("int const a : 5;\n" |
| "int oneTwoThree : 23;", |
| Alignment); |
| |
| // Initializers are allowed starting with c++2a |
| verifyFormat("int const a : 5 = 1;\n" |
| "int oneTwoThree : 23 = 0;", |
| Alignment); |
| |
| Alignment.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("int const a : 5;\n" |
| "int oneTwoThree : 23;", |
| Alignment); |
| |
| verifyFormat("int const a : 5; // comment\n" |
| "int oneTwoThree : 23; // comment", |
| Alignment); |
| |
| verifyFormat("int const a : 5 = 1;\n" |
| "int oneTwoThree : 23 = 0;", |
| Alignment); |
| |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| verifyFormat("int const a : 5 = 1;\n" |
| "int oneTwoThree : 23 = 0;", |
| Alignment); |
| verifyFormat("int const a : 5 = {1};\n" |
| "int oneTwoThree : 23 = 0;", |
| Alignment); |
| |
| Alignment.BitFieldColonSpacing = FormatStyle::BFCS_None; |
| verifyFormat("int const a :5;\n" |
| "int oneTwoThree:23;", |
| Alignment); |
| |
| Alignment.BitFieldColonSpacing = FormatStyle::BFCS_Before; |
| verifyFormat("int const a :5;\n" |
| "int oneTwoThree :23;", |
| Alignment); |
| |
| Alignment.BitFieldColonSpacing = FormatStyle::BFCS_After; |
| verifyFormat("int const a : 5;\n" |
| "int oneTwoThree: 23;", |
| Alignment); |
| |
| // Known limitations: ':' is only recognized as a bitfield colon when |
| // followed by a number. |
| /* |
| verifyFormat("int oneTwoThree : SOME_CONSTANT;\n" |
| "int a : 5;", |
| Alignment); |
| */ |
| } |
| |
| TEST_F(FormatTest, AlignConsecutiveDeclarations) { |
| FormatStyle Alignment = getLLVMStyle(); |
| Alignment.AlignConsecutiveMacros.Enabled = true; |
| Alignment.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("float const a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| verifyFormat("int a = 5;\n" |
| "float const oneTwoThree = 123;", |
| Alignment); |
| |
| Alignment.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("float const a = 5;\n" |
| "int oneTwoThree = 123;", |
| Alignment); |
| verifyFormat("int a = method();\n" |
| "float const oneTwoThree = 133;", |
| Alignment); |
| verifyFormat("int i = 1, j = 10;\n" |
| "something = 2000;", |
| Alignment); |
| verifyFormat("something = 2000;\n" |
| "int i = 1, j = 10;\n", |
| Alignment); |
| verifyFormat("float something = 2000;\n" |
| "double another = 911;\n" |
| "int i = 1, j = 10;\n" |
| "const int *oneMore = 1;\n" |
| "unsigned i = 2;", |
| Alignment); |
| verifyFormat("float a = 5;\n" |
| "int one = 1;\n" |
| "method();\n" |
| "const double oneTwoThree = 123;\n" |
| "const unsigned int oneTwo = 12;", |
| Alignment); |
| verifyFormat("int oneTwoThree{0}; // comment\n" |
| "unsigned oneTwo; // comment", |
| Alignment); |
| verifyFormat("unsigned int *a;\n" |
| "int *b;\n" |
| "unsigned int Const *c;\n" |
| "unsigned int const *d;\n" |
| "unsigned int Const &e;\n" |
| "unsigned int const &f;", |
| Alignment); |
| 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;", |
| Alignment); |
| EXPECT_EQ("float const a = 5;\n" |
| "\n" |
| "int oneTwoThree = 123;", |
| format("float const a = 5;\n" |
| "\n" |
| "int oneTwoThree= 123;", |
| Alignment)); |
| EXPECT_EQ("float a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "unsigned oneTwoThree = 123;", |
| format("float a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "unsigned oneTwoThree = 123;", |
| Alignment)); |
| EXPECT_EQ("float a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "unsigned oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| format("float a = 5;\n" |
| "int one = 1;\n" |
| "\n" |
| "unsigned oneTwoThree = 123;\n" |
| "int oneTwo = 12;", |
| Alignment)); |
| // Function prototype alignment |
| verifyFormat("int a();\n" |
| "double b();", |
| Alignment); |
| verifyFormat("int a(int x);\n" |
| "double b();", |
| Alignment); |
| unsigned OldColumnLimit = Alignment.ColumnLimit; |
| // We need to set ColumnLimit to zero, in order to stress nested alignments, |
| // otherwise the function parameters will be re-flowed onto a single line. |
| Alignment.ColumnLimit = 0; |
| EXPECT_EQ("int a(int x,\n" |
| " float y);\n" |
| "double b(int x,\n" |
| " double y);", |
| format("int a(int x,\n" |
| " float y);\n" |
| "double b(int x,\n" |
| " double y);", |
| Alignment)); |
| // This ensures that function parameters of function declarations are |
| // correctly indented when their owning functions are indented. |
| // The failure case here is for 'double y' to not be indented enough. |
| EXPECT_EQ("double a(int x);\n" |
| "int b(int y,\n" |
| " double z);", |
| format("double a(int x);\n" |
| "int b(int y,\n" |
| " double z);", |
| Alignment)); |
| // Set ColumnLimit low so that we induce wrapping immediately after |
| // the function name and opening paren. |
| Alignment.ColumnLimit = 13; |
| verifyFormat("int function(\n" |
| " int x,\n" |
| " bool y);", |
| Alignment); |
| Alignment.ColumnLimit = OldColumnLimit; |
| // Ensure function pointers don't screw up recursive alignment |
| verifyFormat("int a(int x, void (*fp)(int y));\n" |
| "double b();", |
| Alignment); |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| // Ensure recursive alignment is broken by function braces, so that the |
| // "a = 1" does not align with subsequent assignments inside the function |
| // body. |
| verifyFormat("int func(int a = 1) {\n" |
| " int b = 2;\n" |
| " int cc = 3;\n" |
| "}", |
| Alignment); |
| verifyFormat("float something = 2000;\n" |
| "double another = 911;\n" |
| "int i = 1, j = 10;\n" |
| "const int *oneMore = 1;\n" |
| "unsigned i = 2;", |
| Alignment); |
| verifyFormat("int oneTwoThree = {0}; // comment\n" |
| "unsigned oneTwo = 0; // comment", |
| Alignment); |
| // Make sure that scope is correctly tracked, in the absence of braces |
| verifyFormat("for (int i = 0; i < n; i++)\n" |
| " j = i;\n" |
| "double x = 1;\n", |
| Alignment); |
| verifyFormat("if (int i = 0)\n" |
| " j = i;\n" |
| "double x = 1;\n", |
| Alignment); |
| // Ensure operator[] and operator() are comprehended |
| verifyFormat("struct test {\n" |
| " long long int foo();\n" |
| " int operator[](int a);\n" |
| " double bar();\n" |
| "};\n", |
| Alignment); |
| verifyFormat("struct test {\n" |
| " long long int foo();\n" |
| " int operator()(int a);\n" |
| " double bar();\n" |
| "};\n", |
| Alignment); |
| // http://llvm.org/PR52914 |
| verifyFormat("char *a[] = {\"a\", // comment\n" |
| " \"bb\"};\n" |
| "int bbbbbbb = 0;", |
| Alignment); |
| |
| // PAS_Right |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int *j = 2;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int *j=2;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| Alignment)); |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int **j = 2, ***k;\n" |
| " int &k = i;\n" |
| " int &&l = i + j;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int **j=2,***k;\n" |
| "int &k=i;\n" |
| "int &&l=i+j;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| Alignment)); |
| // variables are aligned at their name, pointers are at the right most |
| // position |
| verifyFormat("int *a;\n" |
| "int **b;\n" |
| "int ***c;\n" |
| "int foobar;\n", |
| Alignment); |
| |
| // PAS_Left |
| FormatStyle AlignmentLeft = Alignment; |
| AlignmentLeft.PointerAlignment = FormatStyle::PAS_Left; |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int* j = 2;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int *j=2;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| AlignmentLeft)); |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int** j = 2;\n" |
| " int& k = i;\n" |
| " int&& l = i + j;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int **j=2;\n" |
| "int &k=i;\n" |
| "int &&l=i+j;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| AlignmentLeft)); |
| // variables are aligned at their name, pointers are at the left most position |
| verifyFormat("int* a;\n" |
| "int** b;\n" |
| "int*** c;\n" |
| "int foobar;\n", |
| AlignmentLeft); |
| |
| // PAS_Middle |
| FormatStyle AlignmentMiddle = Alignment; |
| AlignmentMiddle.PointerAlignment = FormatStyle::PAS_Middle; |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int * j = 2;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int *j=2;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| AlignmentMiddle)); |
| EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int ** j = 2, ***k;\n" |
| " int & k = i;\n" |
| " int && l = i + j;\n" |
| " int big = 10000;\n" |
| "\n" |
| " unsigned oneTwoThree = 123;\n" |
| " int oneTwo = 12;\n" |
| " method();\n" |
| " float k = 2;\n" |
| " int ll = 10000;\n" |
| "}", |
| format("void SomeFunction(int parameter= 0) {\n" |
| " int const i= 1;\n" |
| " int **j=2,***k;\n" |
| "int &k=i;\n" |
| "int &&l=i+j;\n" |
| " int big = 10000;\n" |
| "\n" |
| "unsigned oneTwoThree =123;\n" |
| "int oneTwo = 12;\n" |
| " method();\n" |
| "float k= 2;\n" |
| "int ll=10000;\n" |
| "}", |
| AlignmentMiddle)); |
| // variables are aligned at their name, pointers are in the middle |
| verifyFormat("int * a;\n" |
| "int * b;\n" |
| "int *** c;\n" |
| "int foobar;\n", |
| AlignmentMiddle); |
| |
| Alignment.AlignConsecutiveAssignments.Enabled = false; |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " float b = 23; \\\n" |
| " const int ccc = 234; \\\n" |
| " unsigned dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " float b = 23; \\\n" |
| " const int ccc = 234; \\\n" |
| " unsigned dddddddddd = 2345;", |
| Alignment); |
| Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right; |
| Alignment.ColumnLimit = 30; |
| verifyFormat("#define A \\\n" |
| " int aaaa = 12; \\\n" |
| " float b = 23; \\\n" |
| " const int ccc = 234; \\\n" |
| " int dddddddddd = 2345;", |
| Alignment); |
| Alignment.ColumnLimit = 80; |
| verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int " |
| "k = 4, int l = 5,\n" |
| " int m = 6) {\n" |
| " const int j = 10;\n" |
| " otherThing = 1;\n" |
| "}", |
| Alignment); |
| verifyFormat("void SomeFunction(int parameter = 0) {\n" |
| " int const i = 1;\n" |
| " int *j = 2;\n" |
| " int big = 10000;\n" |
| "}", |
| Alignment); |
| verifyFormat("class C {\n" |
| "public:\n" |
| " int i = 1;\n" |
| " virtual void f() = 0;\n" |
| "};", |
| Alignment); |
| verifyFormat("float i = 1;\n" |
| "if (SomeType t = getSomething()) {\n" |
| "}\n" |
| "const unsigned j = 2;\n" |
| "int big = 10000;", |
| Alignment); |
| verifyFormat("float j = 7;\n" |
| "for (int k = 0; k < N; ++k) {\n" |
| "}\n" |
| "unsigned j = 2;\n" |
| "int big = 10000;\n" |
| "}", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat("float i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable\n" |
| " = someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None; |
| verifyFormat("int i = 1;\n" |
| "LooooooooooongType loooooooooooooooooooooongVariable =\n" |
| " someLooooooooooooooooongFunction();\n" |
| "int j = 2;", |
| Alignment); |
| |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| verifyFormat("auto lambda = []() {\n" |
| " auto ii = 0;\n" |
| " float j = 0;\n" |
| " return 0;\n" |
| "};\n" |
| "int i = 0;\n" |
| "float i2 = 0;\n" |
| "auto v = type{\n" |
| " i = 1, //\n" |
| " (i = 2), //\n" |
| " i = 3 //\n" |
| "};", |
| Alignment); |
| Alignment.AlignConsecutiveAssignments.Enabled = false; |
| |
| verifyFormat( |
| "int i = 1;\n" |
| "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" |
| " loooooooooooooooooooooongParameterB);\n" |
| "int j = 2;", |
| Alignment); |
| |
| // Test interactions with ColumnLimit and AlignConsecutiveAssignments: |
| // We expect declarations and assignments to align, as long as it doesn't |
| // exceed the column limit, starting a new alignment sequence whenever it |
| // happens. |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| Alignment.ColumnLimit = 30; |
| verifyFormat("float ii = 1;\n" |
| "unsigned j = 2;\n" |
| "int someVerylongVariable = 1;\n" |
| "AnotherLongType ll = 123456;\n" |
| "VeryVeryLongType k = 2;\n" |
| "int myvar = 1;", |
| Alignment); |
| Alignment.ColumnLimit = 80; |
| Alignment.AlignConsecutiveAssignments.Enabled = false; |
| |
| verifyFormat( |
| "template <typename LongTemplate, typename VeryLongTemplateTypeName,\n" |
| " typename LongType, typename B>\n" |
| "auto foo() {}\n", |
| Alignment); |
| verifyFormat("float a, b = 1;\n" |
| "int c = 2;\n" |
| "int dd = 3;\n", |
| Alignment); |
| verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" |
| "float b[1][] = {{3.f}};\n", |
| Alignment); |
| Alignment.AlignConsecutiveAssignments.Enabled = true; |
| verifyFormat("float a, b = 1;\n" |
| "int c = 2;\n" |
| "int dd = 3;\n", |
| Alignment); |
| verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" |
| "float b[1][] = {{3.f}};\n", |
| Alignment); |
| Alignment.AlignConsecutiveAssignments.Enabled = false; |
| |
| Alignment.ColumnLimit = 30; |
| Alignment.BinPackParameters = false; |
| verifyFormat("void foo(float a,\n" |
| " float b,\n" |
| " int c,\n" |
| " uint32_t *d) {\n" |
| " int *e = 0;\n" |
| " float f = 0;\n" |
| " double g = 0;\n" |
| "}\n" |
| "void bar(ino_t a,\n" |
| " int b,\n" |
| " uint32_t *c,\n" |
| " bool d) {}\n", |
| Alignment); |
| Alignment.BinPackParameters = true; |
| Alignment.ColumnLimit = 80; |
| |
| // Bug 33507 |
| Alignment.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat( |
| "auto found = range::find_if(vsProducts, [&](auto * aProduct) {\n" |
| " static const Version verVs2017;\n" |
| " return true;\n" |
| "});\n", |
| Alignment); |
| Alignment.PointerAlignment = FormatStyle::PAS_Right; |
| |
| // See llvm.org/PR35641 |
| Alignment.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("int func() { //\n" |
| " int b;\n" |
| " unsigned c;\n" |
| "}", |
| Alignment); |
| |
| // See PR37175 |
| FormatStyle Style = getMozillaStyle(); |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| EXPECT_EQ("DECOR1 /**/ int8_t /**/ DECOR2 /**/\n" |
| "foo(int a);", |
| format("DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style)); |
| |
| Alignment.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("unsigned int* a;\n" |
| "int* b;\n" |
| "unsigned int Const* c;\n" |
| "unsigned int const* d;\n" |
| "unsigned int Const& e;\n" |
| "unsigned int const& f;", |
| Alignment); |
| 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;", |
| Alignment); |
| |
| Alignment.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("unsigned int * a;\n" |
| "int * b;\n" |
| "unsigned int Const * c;\n" |
| "unsigned int const * d;\n" |
| "unsigned int Const & e;\n" |
| "unsigned int const & f;", |
| Alignment); |
| 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;", |
| Alignment); |
| |
| // See PR46529 |
| FormatStyle BracedAlign = getLLVMStyle(); |
| BracedAlign.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("const auto result{[]() {\n" |
| " const auto something = 1;\n" |
| " return 2;\n" |
| "}};", |
| BracedAlign); |
| verifyFormat("int foo{[]() {\n" |
| " int bar{0};\n" |
| " return 0;\n" |
| "}()};", |
| BracedAlign); |
| BracedAlign.Cpp11BracedListStyle = false; |
| verifyFormat("const auto result{ []() {\n" |
| " const auto something = 1;\n" |
| " return 2;\n" |
| "} };", |
| BracedAlign); |
| verifyFormat("int foo{ []() {\n" |
| " int bar{ 0 };\n" |
| " return 0;\n" |
| "}() };", |
| BracedAlign); |
| } |
| |
| TEST_F(FormatTest, AlignWithLineBreaks) { |
| auto Style = getLLVMStyleWithColumns(120); |
| |
| EXPECT_EQ(Style.AlignConsecutiveAssignments, |
| FormatStyle::AlignConsecutiveStyle( |
| {/*Enabled=*/false, /*AcrossEmptyLines=*/false, |
| /*AcrossComments=*/false, /*AlignCompound=*/false, |
| /*PadOperators=*/true})); |
| EXPECT_EQ(Style.AlignConsecutiveDeclarations, |
| FormatStyle::AlignConsecutiveStyle({})); |
| verifyFormat("void foo() {\n" |
| " int myVar = 5;\n" |
| " double x = 3.14;\n" |
| " auto str = \"Hello \"\n" |
| " \"World\";\n" |
| " auto s = \"Hello \"\n" |
| " \"Again\";\n" |
| "}", |
| Style); |
| |
| // clang-format off |
| verifyFormat("void foo() {\n" |
| " const int capacityBefore = Entries.capacity();\n" |
| " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| "}", |
| Style); |
| // clang-format on |
| |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| verifyFormat("void foo() {\n" |
| " int myVar = 5;\n" |
| " double x = 3.14;\n" |
| " auto str = \"Hello \"\n" |
| " \"World\";\n" |
| " auto s = \"Hello \"\n" |
| " \"Again\";\n" |
| "}", |
| Style); |
| |
| // clang-format off |
| verifyFormat("void foo() {\n" |
| " const int capacityBefore = Entries.capacity();\n" |
| " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| "}", |
| Style); |
| // clang-format on |
| |
| Style.AlignConsecutiveAssignments.Enabled = false; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("void foo() {\n" |
| " int myVar = 5;\n" |
| " double x = 3.14;\n" |
| " auto str = \"Hello \"\n" |
| " \"World\";\n" |
| " auto s = \"Hello \"\n" |
| " \"Again\";\n" |
| "}", |
| Style); |
| |
| // clang-format off |
| verifyFormat("void foo() {\n" |
| " const int capacityBefore = Entries.capacity();\n" |
| " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| "}", |
| Style); |
| // clang-format on |
| |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| |
| verifyFormat("void foo() {\n" |
| " int myVar = 5;\n" |
| " double x = 3.14;\n" |
| " auto str = \"Hello \"\n" |
| " \"World\";\n" |
| " auto s = \"Hello \"\n" |
| " \"Again\";\n" |
| "}", |
| Style); |
| |
| // clang-format off |
| verifyFormat("void foo() {\n" |
| " const int capacityBefore = Entries.capacity();\n" |
| " const auto newEntry = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| " const X newEntry2 = Entries.emplaceHint(std::piecewise_construct, std::forward_as_tuple(uniqueId),\n" |
| " std::forward_as_tuple(id, uniqueId, name, threadCreation));\n" |
| "}", |
| Style); |
| // clang-format on |
| |
| Style = getLLVMStyleWithColumns(20); |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.IndentWidth = 4; |
| |
| verifyFormat("void foo() {\n" |
| " int i1 = 1;\n" |
| " int j = 0;\n" |
| " int k = bar(\n" |
| " argument1,\n" |
| " argument2);\n" |
| "}", |
| Style); |
| |
| verifyFormat("unsigned i = 0;\n" |
| "int a[] = {\n" |
| " 1234567890,\n" |
| " -1234567890};", |
| Style); |
| |
| Style.ColumnLimit = 120; |
| |
| // clang-format off |
| verifyFormat("void SomeFunc() {\n" |
| " newWatcher.maxAgeUsec = ToLegacyTimestamp(GetMaxAge(FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec),\n" |
| " seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| " newWatcher.maxAge = ToLegacyTimestamp(GetMaxAge(FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec),\n" |
| " seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| " newWatcher.max = ToLegacyTimestamp(GetMaxAge(FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec),\n" |
| " seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| "}", |
| Style); |
| // clang-format on |
| |
| Style.BinPackArguments = false; |
| |
| // clang-format off |
| verifyFormat("void SomeFunc() {\n" |
| " newWatcher.maxAgeUsec = ToLegacyTimestamp(GetMaxAge(\n" |
| " FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec), seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| " newWatcher.maxAge = ToLegacyTimestamp(GetMaxAge(\n" |
| " FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec), seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| " newWatcher.max = ToLegacyTimestamp(GetMaxAge(\n" |
| " FromLegacyTimestamp<milliseconds>(monitorFrequencyUsec), seconds(std::uint64_t(maxSampleAge)), maxKeepSamples));\n" |
| "}", |
| Style); |
| // clang-format on |
| } |
| |
| TEST_F(FormatTest, AlignWithInitializerPeriods) { |
| auto Style = getLLVMStyleWithColumns(60); |
| |
| verifyFormat("void foo1(void) {\n" |
| " BYTE p[1] = 1;\n" |
| " A B = {.one_foooooooooooooooo = 2,\n" |
| " .two_fooooooooooooo = 3,\n" |
| " .three_fooooooooooooo = 4};\n" |
| " BYTE payload = 2;\n" |
| "}", |
| Style); |
| |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = false; |
| verifyFormat("void foo2(void) {\n" |
| " BYTE p[1] = 1;\n" |
| " A B = {.one_foooooooooooooooo = 2,\n" |
| " .two_fooooooooooooo = 3,\n" |
| " .three_fooooooooooooo = 4};\n" |
| " BYTE payload = 2;\n" |
| "}", |
| Style); |
| |
| Style.AlignConsecutiveAssignments.Enabled = false; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("void foo3(void) {\n" |
| " BYTE p[1] = 1;\n" |
| " A B = {.one_foooooooooooooooo = 2,\n" |
| " .two_fooooooooooooo = 3,\n" |
| " .three_fooooooooooooo = 4};\n" |
| " BYTE payload = 2;\n" |
| "}", |
| Style); |
| |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("void foo4(void) {\n" |
| " BYTE p[1] = 1;\n" |
| " A B = {.one_foooooooooooooooo = 2,\n" |
| " .two_fooooooooooooo = 3,\n" |
| " .three_fooooooooooooo = 4};\n" |
| " BYTE payload = 2;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, LinuxBraceBreaking) { |
| FormatStyle LinuxBraceStyle = getLLVMStyle(); |
| LinuxBraceStyle.BreakBeforeBraces = FormatStyle::BS_Linux; |
| verifyFormat("namespace a\n" |
| "{\n" |
| "class A\n" |
| "{\n" |
| " void f()\n" |
| " {\n" |
| " if (true) {\n" |
| " a();\n" |
| " b();\n" |
| " } else {\n" |
| " a();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "};\n" |
| "struct B {\n" |
| " int x;\n" |
| "};\n" |
| "} // namespace a\n", |
| LinuxBraceStyle); |
| verifyFormat("enum X {\n" |
| " Y = 0,\n" |
| "}\n", |
| LinuxBraceStyle); |
| verifyFormat("struct S {\n" |
| " int Type;\n" |
| " union {\n" |
| " int x;\n" |
| " double y;\n" |
| " } Value;\n" |
| " class C\n" |
| " {\n" |
| " MyFavoriteType Value;\n" |
| " } Class;\n" |
| "}\n", |
| LinuxBraceStyle); |
| } |
| |
| TEST_F(FormatTest, MozillaBraceBreaking) { |
| FormatStyle MozillaBraceStyle = getLLVMStyle(); |
| MozillaBraceStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; |
| MozillaBraceStyle.FixNamespaceComments = false; |
| verifyFormat("namespace a {\n" |
| "class A\n" |
| "{\n" |
| " void f()\n" |
| " {\n" |
| " if (true) {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "};\n" |
| "enum E\n" |
| "{\n" |
| " A,\n" |
| " // foo\n" |
| " B,\n" |
| " C\n" |
| "};\n" |
| "struct B\n" |
| "{\n" |
| " int x;\n" |
| "};\n" |
| "}\n", |
| MozillaBraceStyle); |
| verifyFormat("struct S\n" |
| "{\n" |
| " int Type;\n" |
| " union\n" |
| " {\n" |
| " int x;\n" |
| " double y;\n" |
| " } Value;\n" |
| " class C\n" |
| " {\n" |
| " MyFavoriteType Value;\n" |
| " } Class;\n" |
| "}\n", |
| MozillaBraceStyle); |
| } |
| |
| TEST_F(FormatTest, StroustrupBraceBreaking) { |
| FormatStyle StroustrupBraceStyle = getLLVMStyle(); |
| StroustrupBraceStyle.BreakBeforeBraces = FormatStyle::BS_Stroustrup; |
| verifyFormat("namespace a {\n" |
| "class A {\n" |
| " void f()\n" |
| " {\n" |
| " if (true) {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "};\n" |
| "struct B {\n" |
| " int x;\n" |
| "};\n" |
| "} // namespace a\n", |
| StroustrupBraceStyle); |
| |
| verifyFormat("void foo()\n" |
| "{\n" |
| " if (a) {\n" |
| " a();\n" |
| " }\n" |
| " else {\n" |
| " b();\n" |
| " }\n" |
| "}\n", |
| StroustrupBraceStyle); |
| |
| verifyFormat("#ifdef _DEBUG\n" |
| "int foo(int i = 0)\n" |
| "#else\n" |
| "int foo(int i = 5)\n" |
| "#endif\n" |
| "{\n" |
| " return i;\n" |
| "}", |
| StroustrupBraceStyle); |
| |
| verifyFormat("void foo() {}\n" |
| "void bar()\n" |
| "#ifdef _DEBUG\n" |
| "{\n" |
| " foo();\n" |
| "}\n" |
| "#else\n" |
| "{\n" |
| "}\n" |
| "#endif", |
| StroustrupBraceStyle); |
| |
| verifyFormat("void foobar() { int i = 5; }\n" |
| "#ifdef _DEBUG\n" |
| "void bar() {}\n" |
| "#else\n" |
| "void bar() { foobar(); }\n" |
| "#endif", |
| StroustrupBraceStyle); |
| } |
| |
| TEST_F(FormatTest, AllmanBraceBreaking) { |
| FormatStyle AllmanBraceStyle = getLLVMStyle(); |
| AllmanBraceStyle.BreakBeforeBraces = FormatStyle::BS_Allman; |
| |
| EXPECT_EQ("namespace a\n" |
| "{\n" |
| "void f();\n" |
| "void g();\n" |
| "} // namespace a\n", |
| format("namespace a\n" |
| "{\n" |
| "void f();\n" |
| "void g();\n" |
| "}\n", |
| AllmanBraceStyle)); |
| |
| verifyFormat("namespace a\n" |
| "{\n" |
| "class A\n" |
| "{\n" |
| " void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "};\n" |
| "struct B\n" |
| "{\n" |
| " int x;\n" |
| "};\n" |
| "union C\n" |
| "{\n" |
| "};\n" |
| "} // namespace a", |
| AllmanBraceStyle); |
| |
| verifyFormat("void f()\n" |
| "{\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " else if (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " c();\n" |
| " }\n" |
| "}\n", |
| AllmanBraceStyle); |
| |
| verifyFormat("void f()\n" |
| "{\n" |
| " for (int i = 0; i < 10; ++i)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " while (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " do\n" |
| " {\n" |
| " c();\n" |
| " } while (false)\n" |
| "}\n", |
| AllmanBraceStyle); |
| |
| verifyFormat("void f(int a)\n" |
| "{\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " break;\n" |
| " case 1:\n" |
| " {\n" |
| " break;\n" |
| " }\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " break;\n" |
| " }\n" |
| "}\n", |
| AllmanBraceStyle); |
| |
| verifyFormat("enum X\n" |
| "{\n" |
| " Y = 0,\n" |
| "}\n", |
| AllmanBraceStyle); |
| verifyFormat("enum X\n" |
| "{\n" |
| " Y = 0\n" |
| "}\n", |
| AllmanBraceStyle); |
| |
| verifyFormat("@interface BSApplicationController ()\n" |
| "{\n" |
| "@private\n" |
| " id _extraIvar;\n" |
| "}\n" |
| "@end\n", |
| AllmanBraceStyle); |
| |
| verifyFormat("#ifdef _DEBUG\n" |
| "int foo(int i = 0)\n" |
| "#else\n" |
| "int foo(int i = 5)\n" |
| "#endif\n" |
| "{\n" |
| " return i;\n" |
| "}", |
| AllmanBraceStyle); |
| |
| verifyFormat("void foo() {}\n" |
| "void bar()\n" |
| "#ifdef _DEBUG\n" |
| "{\n" |
| " foo();\n" |
| "}\n" |
| "#else\n" |
| "{\n" |
| "}\n" |
| "#endif", |
| AllmanBraceStyle); |
| |
| verifyFormat("void foobar() { int i = 5; }\n" |
| "#ifdef _DEBUG\n" |
| "void bar() {}\n" |
| "#else\n" |
| "void bar() { foobar(); }\n" |
| "#endif", |
| AllmanBraceStyle); |
| |
| EXPECT_EQ(AllmanBraceStyle.AllowShortLambdasOnASingleLine, |
| FormatStyle::SLS_All); |
| |
| verifyFormat("[](int i) { return i + 2; };\n" |
| "[](int i, int j)\n" |
| "{\n" |
| " auto x = i + j;\n" |
| " auto y = i * j;\n" |
| " return x ^ y;\n" |
| "};\n" |
| "void foo()\n" |
| "{\n" |
| " auto shortLambda = [](int i) { return i + 2; };\n" |
| " auto longLambda = [](int i, int j)\n" |
| " {\n" |
| " auto x = i + j;\n" |
| " auto y = i * j;\n" |
| " return x ^ y;\n" |
| " };\n" |
| "}", |
| AllmanBraceStyle); |
| |
| AllmanBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; |
| |
| verifyFormat("[](int i)\n" |
| "{\n" |
| " return i + 2;\n" |
| "};\n" |
| "[](int i, int j)\n" |
| "{\n" |
| " auto x = i + j;\n" |
| " auto y = i * j;\n" |
| " return x ^ y;\n" |
| "};\n" |
| "void foo()\n" |
| "{\n" |
| " auto shortLambda = [](int i)\n" |
| " {\n" |
| " return i + 2;\n" |
| " };\n" |
| " auto longLambda = [](int i, int j)\n" |
| " {\n" |
| " auto x = i + j;\n" |
| " auto y = i * j;\n" |
| " return x ^ y;\n" |
| " };\n" |
| "}", |
| AllmanBraceStyle); |
| |
| // Reset |
| AllmanBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All; |
| |
| // This shouldn't affect ObjC blocks.. |
| verifyFormat("[self doSomeThingWithACompletionHandler:^{\n" |
| " // ...\n" |
| " int i;\n" |
| "}];", |
| AllmanBraceStyle); |
| verifyFormat("void (^block)(void) = ^{\n" |
| " // ...\n" |
| " int i;\n" |
| "};", |
| AllmanBraceStyle); |
| // .. or dict literals. |
| verifyFormat("void f()\n" |
| "{\n" |
| " // ...\n" |
| " [object someMethod:@{@\"a\" : @\"b\"}];\n" |
| "}", |
| AllmanBraceStyle); |
| verifyFormat("void f()\n" |
| "{\n" |
| " // ...\n" |
| " [object someMethod:@{a : @\"b\"}];\n" |
| "}", |
| AllmanBraceStyle); |
| verifyFormat("int f()\n" |
| "{ // comment\n" |
| " return 42;\n" |
| "}", |
| AllmanBraceStyle); |
| |
| AllmanBraceStyle.ColumnLimit = 19; |
| verifyFormat("void f() { int i; }", AllmanBraceStyle); |
| AllmanBraceStyle.ColumnLimit = 18; |
| verifyFormat("void f()\n" |
| "{\n" |
| " int i;\n" |
| "}", |
| AllmanBraceStyle); |
| AllmanBraceStyle.ColumnLimit = 80; |
| |
| FormatStyle BreakBeforeBraceShortIfs = AllmanBraceStyle; |
| BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_WithoutElse; |
| BreakBeforeBraceShortIfs.AllowShortLoopsOnASingleLine = true; |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if constexpr (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if CONSTEXPR (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if (b) return;\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if constexpr (b) return;\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " if CONSTEXPR (b) return;\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| "{\n" |
| " while (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| "}\n", |
| BreakBeforeBraceShortIfs); |
| } |
| |
| TEST_F(FormatTest, WhitesmithsBraceBreaking) { |
| FormatStyle WhitesmithsBraceStyle = getLLVMStyleWithColumns(0); |
| WhitesmithsBraceStyle.BreakBeforeBraces = FormatStyle::BS_Whitesmiths; |
| |
| // Make a few changes to the style for testing purposes |
| WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine = |
| FormatStyle::SFS_Empty; |
| WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; |
| |
| // FIXME: this test case can't decide whether there should be a blank line |
| // after the ~D() line or not. It adds one if one doesn't exist in the test |
| // and it removes the line if one exists. |
| /* |
| verifyFormat("class A;\n" |
| "namespace B\n" |
| " {\n" |
| "class C;\n" |
| "// Comment\n" |
| "class D\n" |
| " {\n" |
| "public:\n" |
| " D();\n" |
| " ~D() {}\n" |
| "private:\n" |
| " enum E\n" |
| " {\n" |
| " F\n" |
| " }\n" |
| " };\n" |
| " } // namespace B\n", |
| WhitesmithsBraceStyle); |
| */ |
| |
| WhitesmithsBraceStyle.NamespaceIndentation = FormatStyle::NI_None; |
| verifyFormat("namespace a\n" |
| " {\n" |
| "class A\n" |
| " {\n" |
| " void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g()\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " };\n" |
| "struct B\n" |
| " {\n" |
| " int x;\n" |
| " };\n" |
| " } // namespace a", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("namespace a\n" |
| " {\n" |
| "namespace b\n" |
| " {\n" |
| "class A\n" |
| " {\n" |
| " void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g()\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " };\n" |
| "struct B\n" |
| " {\n" |
| " int x;\n" |
| " };\n" |
| " } // namespace b\n" |
| " } // namespace a", |
| WhitesmithsBraceStyle); |
| |
| WhitesmithsBraceStyle.NamespaceIndentation = FormatStyle::NI_Inner; |
| verifyFormat("namespace a\n" |
| " {\n" |
| "namespace b\n" |
| " {\n" |
| " class A\n" |
| " {\n" |
| " void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g()\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " };\n" |
| " struct B\n" |
| " {\n" |
| " int x;\n" |
| " };\n" |
| " } // namespace b\n" |
| " } // namespace a", |
| WhitesmithsBraceStyle); |
| |
| WhitesmithsBraceStyle.NamespaceIndentation = FormatStyle::NI_All; |
| verifyFormat("namespace a\n" |
| " {\n" |
| " namespace b\n" |
| " {\n" |
| " class A\n" |
| " {\n" |
| " void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g()\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " };\n" |
| " struct B\n" |
| " {\n" |
| " int x;\n" |
| " };\n" |
| " } // namespace b\n" |
| " } // namespace a", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void f()\n" |
| " {\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " else if (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " c();\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void f()\n" |
| " {\n" |
| " for (int i = 0; i < 10; ++i)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " while (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " do\n" |
| " {\n" |
| " c();\n" |
| " } while (false)\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| WhitesmithsBraceStyle.IndentCaseLabels = true; |
| verifyFormat("void switchTest1(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void switchTest2(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " break;\n" |
| " case 1:\n" |
| " {\n" |
| " break;\n" |
| " }\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void switchTest3(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " {\n" |
| " foo(x);\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " {\n" |
| " foo(1);\n" |
| " }\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| WhitesmithsBraceStyle.IndentCaseLabels = false; |
| |
| verifyFormat("void switchTest4(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void switchTest5(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " break;\n" |
| " case 1:\n" |
| " {\n" |
| " foo();\n" |
| " break;\n" |
| " }\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void switchTest6(int a)\n" |
| " {\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " {\n" |
| " foo(x);\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " {\n" |
| " foo(1);\n" |
| " }\n" |
| " break;\n" |
| " }\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("enum X\n" |
| " {\n" |
| " Y = 0, // testing\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("enum X\n" |
| " {\n" |
| " Y = 0\n" |
| " }\n", |
| WhitesmithsBraceStyle); |
| verifyFormat("enum X\n" |
| " {\n" |
| " Y = 0,\n" |
| " Z = 1\n" |
| " };\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("@interface BSApplicationController ()\n" |
| " {\n" |
| "@private\n" |
| " id _extraIvar;\n" |
| " }\n" |
| "@end\n", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("#ifdef _DEBUG\n" |
| "int foo(int i = 0)\n" |
| "#else\n" |
| "int foo(int i = 5)\n" |
| "#endif\n" |
| " {\n" |
| " return i;\n" |
| " }", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void foo() {}\n" |
| "void bar()\n" |
| "#ifdef _DEBUG\n" |
| " {\n" |
| " foo();\n" |
| " }\n" |
| "#else\n" |
| " {\n" |
| " }\n" |
| "#endif", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("void foobar()\n" |
| " {\n" |
| " int i = 5;\n" |
| " }\n" |
| "#ifdef _DEBUG\n" |
| "void bar()\n" |
| " {\n" |
| " }\n" |
| "#else\n" |
| "void bar()\n" |
| " {\n" |
| " foobar();\n" |
| " }\n" |
| "#endif", |
| WhitesmithsBraceStyle); |
| |
| // This shouldn't affect ObjC blocks.. |
| verifyFormat("[self doSomeThingWithACompletionHandler:^{\n" |
| " // ...\n" |
| " int i;\n" |
| "}];", |
| WhitesmithsBraceStyle); |
| verifyFormat("void (^block)(void) = ^{\n" |
| " // ...\n" |
| " int i;\n" |
| "};", |
| WhitesmithsBraceStyle); |
| // .. or dict literals. |
| verifyFormat("void f()\n" |
| " {\n" |
| " [object someMethod:@{@\"a\" : @\"b\"}];\n" |
| " }", |
| WhitesmithsBraceStyle); |
| |
| verifyFormat("int f()\n" |
| " { // comment\n" |
| " return 42;\n" |
| " }", |
| WhitesmithsBraceStyle); |
| |
| FormatStyle BreakBeforeBraceShortIfs = WhitesmithsBraceStyle; |
| BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = |
| FormatStyle::SIS_OnlyFirstIf; |
| BreakBeforeBraceShortIfs.AllowShortLoopsOnASingleLine = true; |
| verifyFormat("void f(bool b)\n" |
| " {\n" |
| " if (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " }\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| " {\n" |
| " if (b) return;\n" |
| " }\n", |
| BreakBeforeBraceShortIfs); |
| verifyFormat("void f(bool b)\n" |
| " {\n" |
| " while (b)\n" |
| " {\n" |
| " return;\n" |
| " }\n" |
| " }\n", |
| BreakBeforeBraceShortIfs); |
| } |
| |
| TEST_F(FormatTest, GNUBraceBreaking) { |
| FormatStyle GNUBraceStyle = getLLVMStyle(); |
| GNUBraceStyle.BreakBeforeBraces = FormatStyle::BS_GNU; |
| verifyFormat("namespace a\n" |
| "{\n" |
| "class A\n" |
| "{\n" |
| " void f()\n" |
| " {\n" |
| " int a;\n" |
| " {\n" |
| " int b;\n" |
| " }\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "}\n" |
| "} // namespace a", |
| GNUBraceStyle); |
| |
| verifyFormat("void f()\n" |
| "{\n" |
| " if (true)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " else if (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " c();\n" |
| " }\n" |
| "}\n", |
| GNUBraceStyle); |
| |
| verifyFormat("void f()\n" |
| "{\n" |
| " for (int i = 0; i < 10; ++i)\n" |
| " {\n" |
| " a();\n" |
| " }\n" |
| " while (false)\n" |
| " {\n" |
| " b();\n" |
| " }\n" |
| " do\n" |
| " {\n" |
| " c();\n" |
| " }\n" |
| " while (false);\n" |
| "}\n", |
| GNUBraceStyle); |
| |
| verifyFormat("void f(int a)\n" |
| "{\n" |
| " switch (a)\n" |
| " {\n" |
| " case 0:\n" |
| " break;\n" |
| " case 1:\n" |
| " {\n" |
| " break;\n" |
| " }\n" |
| " case 2:\n" |
| " {\n" |
| " }\n" |
| " break;\n" |
| " default:\n" |
| " break;\n" |
| " }\n" |
| "}\n", |
| GNUBraceStyle); |
| |
| verifyFormat("enum X\n" |
| "{\n" |
| " Y = 0,\n" |
| "}\n", |
| GNUBraceStyle); |
| |
| verifyFormat("@interface BSApplicationController ()\n" |
| "{\n" |
| "@private\n" |
| " id _extraIvar;\n" |
| "}\n" |
| "@end\n", |
| GNUBraceStyle); |
| |
| verifyFormat("#ifdef _DEBUG\n" |
| "int foo(int i = 0)\n" |
| "#else\n" |
| "int foo(int i = 5)\n" |
| "#endif\n" |
| "{\n" |
| " return i;\n" |
| "}", |
| GNUBraceStyle); |
| |
| verifyFormat("void foo() {}\n" |
| "void bar()\n" |
| "#ifdef _DEBUG\n" |
| "{\n" |
| " foo();\n" |
| "}\n" |
| "#else\n" |
| "{\n" |
| "}\n" |
| "#endif", |
| GNUBraceStyle); |
| |
| verifyFormat("void foobar() { int i = 5; }\n" |
| "#ifdef _DEBUG\n" |
| "void bar() {}\n" |
| "#else\n" |
| "void bar() { foobar(); }\n" |
| "#endif", |
| GNUBraceStyle); |
| } |
| |
| TEST_F(FormatTest, WebKitBraceBreaking) { |
| FormatStyle WebKitBraceStyle = getLLVMStyle(); |
| WebKitBraceStyle.BreakBeforeBraces = FormatStyle::BS_WebKit; |
| WebKitBraceStyle.FixNamespaceComments = false; |
| verifyFormat("namespace a {\n" |
| "class A {\n" |
| " void f()\n" |
| " {\n" |
| " if (true) {\n" |
| " a();\n" |
| " b();\n" |
| " }\n" |
| " }\n" |
| " void g() { return; }\n" |
| "};\n" |
| "enum E {\n" |
| " A,\n" |
| " // foo\n" |
| " B,\n" |
| " C\n" |
| "};\n" |
| "struct B {\n" |
| " int x;\n" |
| "};\n" |
| "}\n", |
| WebKitBraceStyle); |
| verifyFormat("struct S {\n" |
| " int Type;\n" |
| " union {\n" |
| " int x;\n" |
| " double y;\n" |
| " } Value;\n" |
| " class C {\n" |
| " MyFavoriteType Value;\n" |
| " } Class;\n" |
| "};\n", |
| WebKitBraceStyle); |
| } |
| |
| TEST_F(FormatTest, CatchExceptionReferenceBinding) { |
| verifyFormat("void f() {\n" |
| " try {\n" |
| " } catch (const Exception &e) {\n" |
| " }\n" |
| "}\n", |
| getLLVMStyle()); |
| } |
| |
| TEST_F(FormatTest, CatchAlignArrayOfStructuresRightAlignment) { |
| auto Style = getLLVMStyle(); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Right; |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"}, // first line\n" |
| " {-1, 93463, \"world\"}, // second line\n" |
| " { 7, 5, \"!!\"} // third line\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[4] = {\n" |
| " { 56, 23, 21, \"oh\"}, // first line\n" |
| " { -1, 93463, 22, \"my\"}, // second line\n" |
| " { 7, 5, 1, \"goodness\"} // third line\n" |
| " {234, 5, 1, \"gracious\"} // fourth line\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[3] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[3] = {\n" |
| " {int{56}, 23, \"hello\"},\n" |
| " {int{-1}, 93463, \"world\"},\n" |
| " { int{7}, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"},\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"},\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("demo = std::array<struct test, 3>{\n" |
| " test{56, 23, \"hello\"},\n" |
| " test{-1, 93463, \"world\"},\n" |
| " test{ 7, 5, \"!!\"},\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| "#if X\n" |
| " {-1, 93463, \"world\"},\n" |
| "#endif\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat( |
| "test demo[] = {\n" |
| " { 7, 23,\n" |
| " \"hello world i am a very long line that really, in any\"\n" |
| " \"just world, ought to be split over multiple lines\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {56, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("return GradForUnaryCwise(g, {\n" |
| " {{\"sign\"}, \"Sign\", " |
| " {\"x\", \"dy\"}},\n" |
| " { {\"dx\"}, \"Mul\", {\"dy\"" |
| ", \"sign\"}},\n" |
| "});\n", |
| Style); |
| |
| Style.ColumnLimit = 0; |
| EXPECT_EQ( |
| "test demo[] = {\n" |
| " {56, 23, \"hello world i am a very long line that really, " |
| "in any just world, ought to be split over multiple lines\"},\n" |
| " {-1, 93463, " |
| " \"world\"},\n" |
| " { 7, 5, " |
| " \"!!\"},\n" |
| "};", |
| format("test demo[] = {{56, 23, \"hello world i am a very long line " |
| "that really, in any just world, ought to be split over multiple " |
| "lines\"},{-1, 93463, \"world\"},{7, 5, \"!!\"},};", |
| Style)); |
| |
| Style.ColumnLimit = 80; |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, /* a comment */ \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\" /* comment here */},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, /* a comment */ 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n", |
| Style); |
| |
| Style.ColumnLimit = 20; |
| EXPECT_EQ( |
| "demo = std::array<\n" |
| " struct test, 3>{\n" |
| " test{\n" |
| " 56, 23,\n" |
| " \"hello \"\n" |
| " \"world i \"\n" |
| " \"am a very \"\n" |
| " \"long line \"\n" |
| " \"that \"\n" |
| " \"really, \"\n" |
| " \"in any \"\n" |
| " \"just \"\n" |
| " \"world, \"\n" |
| " \"ought to \"\n" |
| " \"be split \"\n" |
| " \"over \"\n" |
| " \"multiple \"\n" |
| " \"lines\"},\n" |
| " test{-1, 93463,\n" |
| " \"world\"},\n" |
| " test{ 7, 5,\n" |
| " \"!!\" },\n" |
| "};", |
| format("demo = std::array<struct test, 3>{test{56, 23, \"hello world " |
| "i am a very long line that really, in any just world, ought " |
| "to be split over multiple lines\"},test{-1, 93463, \"world\"}," |
| "test{7, 5, \"!!\"},};", |
| Style)); |
| // This caused a core dump by enabling Alignment in the LLVMStyle globally |
| Style = getLLVMStyleWithColumns(50); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Right; |
| verifyFormat("static A x = {\n" |
| " {{init1, init2, init3, init4},\n" |
| " {init1, init2, init3, init4}}\n" |
| "};", |
| Style); |
| // TODO: Fix the indentations below when this option is fully functional. |
| verifyFormat("int a[][] = {\n" |
| " {\n" |
| " {0, 2}, //\n" |
| " {1, 2} //\n" |
| " }\n" |
| "};", |
| Style); |
| Style.ColumnLimit = 100; |
| EXPECT_EQ( |
| "test demo[] = {\n" |
| " {56, 23,\n" |
| " \"hello world i am a very long line that really, in any just world" |
| ", ought to be split over \"\n" |
| " \"multiple lines\" },\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"},\n" |
| "};", |
| format("test demo[] = {{56, 23, \"hello world i am a very long line " |
| "that really, in any just world, ought to be split over multiple " |
| "lines\"},{-1, 93463, \"world\"},{7, 5, \"!!\"},};", |
| Style)); |
| |
| Style = getLLVMStyleWithColumns(50); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Right; |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n" |
| "static A x = {\n" |
| " {{init1, init2, init3, init4},\n" |
| " {init1, init2, init3, init4}}\n" |
| "};", |
| Style); |
| Style.ColumnLimit = 100; |
| Style.AlignConsecutiveAssignments.AcrossComments = true; |
| Style.AlignConsecutiveDeclarations.AcrossComments = true; |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " { 7, 5, \"!!\"}\n" |
| "};\n" |
| "struct test demo[4] = {\n" |
| " { 56, 23, 21, \"oh\"}, // first line\n" |
| " { -1, 93463, 22, \"my\"}, // second line\n" |
| " { 7, 5, 1, \"goodness\"} // third line\n" |
| " {234, 5, 1, \"gracious\"} // fourth line\n" |
| "};\n", |
| Style); |
| EXPECT_EQ( |
| "test demo[] = {\n" |
| " {56,\n" |
| " \"hello world i am a very long line that really, in any just world" |
| ", ought to be split over \"\n" |
| " \"multiple lines\", 23},\n" |
| " {-1, \"world\", 93463},\n" |
| " { 7, \"!!\", 5},\n" |
| "};", |
| format("test demo[] = {{56, \"hello world i am a very long line " |
| "that really, in any just world, ought to be split over multiple " |
| "lines\", 23},{-1, \"world\", 93463},{7, \"!!\", 5},};", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, CatchAlignArrayOfStructuresLeftAlignment) { |
| auto Style = getLLVMStyle(); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Left; |
| /* FIXME: This case gets misformatted. |
| verifyFormat("auto foo = Items{\n" |
| " Section{0, bar(), },\n" |
| " Section{1, boo() }\n" |
| "};\n", |
| Style); |
| */ |
| verifyFormat("auto foo = Items{\n" |
| " Section{\n" |
| " 0, bar(),\n" |
| " }\n" |
| "};\n", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"}, // first line\n" |
| " {-1, 93463, \"world\"}, // second line\n" |
| " {7, 5, \"!!\" } // third line\n" |
| "};\n", |
| Style); |
| verifyFormat("struct test demo[4] = {\n" |
| " {56, 23, 21, \"oh\" }, // first line\n" |
| " {-1, 93463, 22, \"my\" }, // second line\n" |
| " {7, 5, 1, \"goodness\"} // third line\n" |
| " {234, 5, 1, \"gracious\"} // fourth line\n" |
| "};\n", |
| Style); |
| verifyFormat("struct test demo[3] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("struct test demo[3] = {\n" |
| " {int{56}, 23, \"hello\"},\n" |
| " {int{-1}, 93463, \"world\"},\n" |
| " {int{7}, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" },\n" |
| "};\n", |
| Style); |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" },\n" |
| "};\n", |
| Style); |
| verifyFormat("demo = std::array<struct test, 3>{\n" |
| " test{56, 23, \"hello\"},\n" |
| " test{-1, 93463, \"world\"},\n" |
| " test{7, 5, \"!!\" },\n" |
| "};\n", |
| Style); |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\"},\n" |
| "#if X\n" |
| " {-1, 93463, \"world\"},\n" |
| "#endif\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| verifyFormat( |
| "test demo[] = {\n" |
| " {7, 23,\n" |
| " \"hello world i am a very long line that really, in any\"\n" |
| " \"just world, ought to be split over multiple lines\"},\n" |
| " {-1, 93463, \"world\" },\n" |
| " {56, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("return GradForUnaryCwise(g, {\n" |
| " {{\"sign\"}, \"Sign\", {\"x\", " |
| "\"dy\"} },\n" |
| " {{\"dx\"}, \"Mul\", " |
| "{\"dy\", \"sign\"}},\n" |
| "});\n", |
| Style); |
| |
| Style.ColumnLimit = 0; |
| EXPECT_EQ( |
| "test demo[] = {\n" |
| " {56, 23, \"hello world i am a very long line that really, in any " |
| "just world, ought to be split over multiple lines\"},\n" |
| " {-1, 93463, \"world\" " |
| " },\n" |
| " {7, 5, \"!!\" " |
| " },\n" |
| "};", |
| format("test demo[] = {{56, 23, \"hello world i am a very long line " |
| "that really, in any just world, ought to be split over multiple " |
| "lines\"},{-1, 93463, \"world\"},{7, 5, \"!!\"},};", |
| Style)); |
| |
| Style.ColumnLimit = 80; |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, /* a comment */ \"hello\"},\n" |
| " {-1, 93463, \"world\" },\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, 23, \"hello\" },\n" |
| " {-1, 93463, \"world\" /* comment here */},\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| |
| verifyFormat("test demo[] = {\n" |
| " {56, /* a comment */ 23, \"hello\"},\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" }\n" |
| "};\n", |
| Style); |
| |
| Style.ColumnLimit = 20; |
| EXPECT_EQ( |
| "demo = std::array<\n" |
| " struct test, 3>{\n" |
| " test{\n" |
| " 56, 23,\n" |
| " \"hello \"\n" |
| " \"world i \"\n" |
| " \"am a very \"\n" |
| " \"long line \"\n" |
| " \"that \"\n" |
| " \"really, \"\n" |
| " \"in any \"\n" |
| " \"just \"\n" |
| " \"world, \"\n" |
| " \"ought to \"\n" |
| " \"be split \"\n" |
| " \"over \"\n" |
| " \"multiple \"\n" |
| " \"lines\"},\n" |
| " test{-1, 93463,\n" |
| " \"world\"},\n" |
| " test{7, 5,\n" |
| " \"!!\" },\n" |
| "};", |
| format("demo = std::array<struct test, 3>{test{56, 23, \"hello world " |
| "i am a very long line that really, in any just world, ought " |
| "to be split over multiple lines\"},test{-1, 93463, \"world\"}," |
| "test{7, 5, \"!!\"},};", |
| Style)); |
| |
| // This caused a core dump by enabling Alignment in the LLVMStyle globally |
| Style = getLLVMStyleWithColumns(50); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Left; |
| verifyFormat("static A x = {\n" |
| " {{init1, init2, init3, init4},\n" |
| " {init1, init2, init3, init4}}\n" |
| "};", |
| Style); |
| Style.ColumnLimit = 100; |
| EXPECT_EQ( |
| "test demo[] = {\n" |
| " {56, 23,\n" |
| " \"hello world i am a very long line that really, in any just world" |
| ", ought to be split over \"\n" |
| " \"multiple lines\" },\n" |
| " {-1, 93463, \"world\"},\n" |
| " {7, 5, \"!!\" },\n" |
| "};", |
| format("test demo[] = {{56, 23, \"hello world i am a very long line " |
| "that really, in any just world, ought to be split over multiple " |
| "lines\"},{-1, 93463, \"world\"},{7, 5, \"!!\"},};", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, UnderstandsPragmas) { |
| verifyFormat("#pragma omp reduction(| : var)"); |
| verifyFormat("#pragma omp reduction(+ : var)"); |
| |
| EXPECT_EQ("#pragma mark Any non-hyphenated or hyphenated string " |
| "(including parentheses).", |
| format("#pragma mark Any non-hyphenated or hyphenated string " |
| "(including parentheses).")); |
| } |
| |
| TEST_F(FormatTest, UnderstandPragmaOption) { |
| verifyFormat("#pragma option -C -A"); |
| |
| EXPECT_EQ("#pragma option -C -A", format("#pragma option -C -A")); |
| } |
| |
| TEST_F(FormatTest, UnderstandPragmaRegion) { |
| auto Style = getLLVMStyleWithColumns(0); |
| verifyFormat("#pragma region TEST(FOO : BAR)", Style); |
| |
| EXPECT_EQ("#pragma region TEST(FOO : BAR)", |
| format("#pragma region TEST(FOO : BAR)", Style)); |
| } |
| |
| TEST_F(FormatTest, OptimizeBreakPenaltyVsExcess) { |
| FormatStyle Style = getLLVMStyleWithColumns(20); |
| |
| // See PR41213 |
| EXPECT_EQ("/*\n" |
| " *\t9012345\n" |
| " * /8901\n" |
| " */", |
| format("/*\n" |
| " *\t9012345 /8901\n" |
| " */", |
| Style)); |
| EXPECT_EQ("/*\n" |
| " *345678\n" |
| " *\t/8901\n" |
| " */", |
| format("/*\n" |
| " *345678\t/8901\n" |
| " */", |
| Style)); |
| |
| verifyFormat("int a; // the\n" |
| " // comment", |
| Style); |
| EXPECT_EQ("int a; /* first line\n" |
| " * second\n" |
| " * line third\n" |
| " * line\n" |
| " */", |
| format("int a; /* first line\n" |
| " * second\n" |
| " * line third\n" |
| " * line\n" |
| " */", |
| Style)); |
| EXPECT_EQ("int a; // first line\n" |
| " // second\n" |
| " // line third\n" |
| " // line", |
| format("int a; // first line\n" |
| " // second line\n" |
| " // third line", |
| Style)); |
| |
| Style.PenaltyExcessCharacter = 90; |
| verifyFormat("int a; // the comment", Style); |
| EXPECT_EQ("int a; // the comment\n" |
| " // aaa", |
| format("int a; // the comment aaa", Style)); |
| EXPECT_EQ("int a; /* first line\n" |
| " * second line\n" |
| " * third line\n" |
| " */", |
| format("int a; /* first line\n" |
| " * second line\n" |
| " * third line\n" |
| " */", |
| Style)); |
| EXPECT_EQ("int a; // first line\n" |
| " // second line\n" |
| " // third line", |
| format("int a; // first line\n" |
| " // second line\n" |
| " // third line", |
| Style)); |
| // FIXME: Investigate why this is not getting the same layout as the test |
| // above. |
| EXPECT_EQ("int a; /* first line\n" |
| " * second line\n" |
| " * third line\n" |
| " */", |
| format("int a; /* first line second line third line" |
| "\n*/", |
| Style)); |
| |
| EXPECT_EQ("// foo bar baz bazfoo\n" |
| "// foo bar foo bar\n", |
| format("// foo bar baz bazfoo\n" |
| "// foo bar foo bar\n", |
| Style)); |
| EXPECT_EQ("// foo bar baz bazfoo\n" |
| "// foo bar foo bar\n", |
| format("// foo bar baz bazfoo\n" |
| "// foo bar foo bar\n", |
| Style)); |
| |
| // FIXME: Optimally, we'd keep bazfoo on the first line and reflow bar to the |
| // next one. |
| EXPECT_EQ("// foo bar baz bazfoo\n" |
| "// bar foo bar\n", |
| format("// foo bar baz bazfoo bar\n" |
| "// foo bar\n", |
| Style)); |
| |
| EXPECT_EQ("// foo bar baz bazfoo\n" |
| "// foo bar baz bazfoo\n" |
| "// bar foo bar\n", |
| format("// foo bar baz bazfoo\n" |
| "// foo bar baz bazfoo bar\n" |
| "// foo bar\n", |
| Style)); |
| |
| EXPECT_EQ("// foo bar baz bazfoo\n" |
| "// foo bar baz bazfoo\n" |
| "// bar foo bar\n", |
| format("// foo bar baz bazfoo\n" |
| "// foo bar baz bazfoo bar\n" |
| "// foo bar\n", |
| Style)); |
| |
| // Make sure we do not keep protruding characters if strict mode reflow is |
| // cheaper than keeping protruding characters. |
| Style.ColumnLimit = 21; |
| EXPECT_EQ( |
| "// foo foo foo foo\n" |
| "// foo foo foo foo\n" |
| "// foo foo foo foo\n", |
| format("// foo foo foo foo foo foo foo foo foo foo foo foo\n", Style)); |
| |
| EXPECT_EQ("int a = /* long block\n" |
| " comment */\n" |
| " 42;", |
| format("int a = /* long block comment */ 42;", Style)); |
| } |
| |
| TEST_F(FormatTest, BreakPenaltyAfterLParen) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = 8; |
| Style.PenaltyExcessCharacter = 15; |
| verifyFormat("int foo(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| Style.PenaltyBreakOpenParenthesis = 200; |
| EXPECT_EQ("int foo(int aaaaaaaaaaaaaaaaaaaaaaaa);", |
| format("int foo(\n" |
| " int aaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, BreakPenaltyAfterCastLParen) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = 5; |
| Style.PenaltyExcessCharacter = 150; |
| verifyFormat("foo((\n" |
| " int)aaaaaaaaaaaaaaaaaaaaaaaa);", |
| |
| Style); |
| Style.PenaltyBreakOpenParenthesis = 100000; |
| EXPECT_EQ("foo((int)\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaa);", |
| format("foo((\n" |
| "int)aaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, BreakPenaltyAfterForLoopLParen) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = 4; |
| Style.PenaltyExcessCharacter = 100; |
| verifyFormat("for (\n" |
| " int iiiiiiiiiiiiiiiii =\n" |
| " 0;\n" |
| " iiiiiiiiiiiiiiiii <\n" |
| " 2;\n" |
| " iiiiiiiiiiiiiiiii++) {\n" |
| "}", |
| |
| Style); |
| Style.PenaltyBreakOpenParenthesis = 1250; |
| EXPECT_EQ("for (int iiiiiiiiiiiiiiiii =\n" |
| " 0;\n" |
| " iiiiiiiiiiiiiiiii <\n" |
| " 2;\n" |
| " iiiiiiiiiiiiiiiii++) {\n" |
| "}", |
| format("for (\n" |
| " int iiiiiiiiiiiiiiiii =\n" |
| " 0;\n" |
| " iiiiiiiiiiiiiiiii <\n" |
| " 2;\n" |
| " iiiiiiiiiiiiiiiii++) {\n" |
| "}", |
| Style)); |
| } |
| |
| #define EXPECT_ALL_STYLES_EQUAL(Styles) \ |
| for (size_t i = 1; i < Styles.size(); ++i) \ |
| EXPECT_EQ(Styles[0], Styles[i]) \ |
| << "Style #" << i << " of " << Styles.size() << " differs from Style #0" |
| |
| TEST_F(FormatTest, GetsPredefinedStyleByName) { |
| SmallVector<FormatStyle, 3> Styles; |
| Styles.resize(3); |
| |
| Styles[0] = getLLVMStyle(); |
| EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getGoogleStyle(); |
| EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript); |
| EXPECT_TRUE( |
| getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1])); |
| EXPECT_TRUE( |
| getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp); |
| EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getMozillaStyle(); |
| EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getWebKitStyle(); |
| EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles[0] = getGNUStyle(); |
| EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1])); |
| EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2])); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0])); |
| } |
| |
| TEST_F(FormatTest, GetsCorrectBasedOnStyle) { |
| SmallVector<FormatStyle, 8> Styles; |
| Styles.resize(2); |
| |
| Styles[0] = getGoogleStyle(); |
| Styles[1] = getLLVMStyle(); |
| EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value()); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| |
| Styles.resize(5); |
| Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript); |
| Styles[1] = getLLVMStyle(); |
| Styles[1].Language = FormatStyle::LK_JavaScript; |
| EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value()); |
| |
| Styles[2] = getLLVMStyle(); |
| Styles[2].Language = FormatStyle::LK_JavaScript; |
| EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n" |
| "BasedOnStyle: Google", |
| &Styles[2]) |
| .value()); |
| |
| Styles[3] = getLLVMStyle(); |
| Styles[3].Language = FormatStyle::LK_JavaScript; |
| EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n" |
| "Language: JavaScript", |
| &Styles[3]) |
| .value()); |
| |
| Styles[4] = getLLVMStyle(); |
| Styles[4].Language = FormatStyle::LK_JavaScript; |
| EXPECT_EQ(0, parseConfiguration("---\n" |
| "BasedOnStyle: LLVM\n" |
| "IndentWidth: 123\n" |
| "---\n" |
| "BasedOnStyle: Google\n" |
| "Language: JavaScript", |
| &Styles[4]) |
| .value()); |
| EXPECT_ALL_STYLES_EQUAL(Styles); |
| } |
| |
| #define CHECK_PARSE_BOOL_FIELD(FIELD, CONFIG_NAME) \ |
| Style.FIELD = false; \ |
| EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": true", &Style).value()); \ |
| EXPECT_TRUE(Style.FIELD); \ |
| EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": false", &Style).value()); \ |
| EXPECT_FALSE(Style.FIELD); |
| |
| #define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD) |
| |
| #define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME) \ |
| Style.STRUCT.FIELD = false; \ |
| EXPECT_EQ(0, \ |
| parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": true", &Style) \ |
| .value()); \ |
| EXPECT_TRUE(Style.STRUCT.FIELD); \ |
| EXPECT_EQ(0, \ |
| parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": false", &Style) \ |
| .value()); \ |
| EXPECT_FALSE(Style.STRUCT.FIELD); |
| |
| #define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD) \ |
| CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD) |
| |
| #define CHECK_PARSE(TEXT, FIELD, VALUE) \ |
| EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!"; \ |
| EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \ |
| EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!" |
| |
| TEST_F(FormatTest, ParsesConfigurationBools) { |
| FormatStyle Style = {}; |
| Style.Language = FormatStyle::LK_Cpp; |
| CHECK_PARSE_BOOL(AlignTrailingComments); |
| CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine); |
| CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); |
| CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); |
| CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine); |
| CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); |
| CHECK_PARSE_BOOL(BinPackArguments); |
| CHECK_PARSE_BOOL(BinPackParameters); |
| CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations); |
| CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); |
| CHECK_PARSE_BOOL(BreakStringLiterals); |
| CHECK_PARSE_BOOL(CompactNamespaces); |
| CHECK_PARSE_BOOL(DeriveLineEnding); |
| CHECK_PARSE_BOOL(DerivePointerAlignment); |
| CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); |
| CHECK_PARSE_BOOL(DisableFormat); |
| CHECK_PARSE_BOOL(IndentAccessModifiers); |
| CHECK_PARSE_BOOL(IndentCaseLabels); |
| CHECK_PARSE_BOOL(IndentCaseBlocks); |
| CHECK_PARSE_BOOL(IndentGotoLabels); |
| CHECK_PARSE_BOOL_FIELD(IndentRequiresClause, "IndentRequires"); |
| CHECK_PARSE_BOOL(IndentRequiresClause); |
| CHECK_PARSE_BOOL(IndentWrappedFunctionNames); |
| CHECK_PARSE_BOOL(InsertBraces); |
| CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks); |
| CHECK_PARSE_BOOL(ObjCSpaceAfterProperty); |
| CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); |
| CHECK_PARSE_BOOL(Cpp11BracedListStyle); |
| CHECK_PARSE_BOOL(ReflowComments); |
| CHECK_PARSE_BOOL(RemoveBracesLLVM); |
| CHECK_PARSE_BOOL(SortUsingDeclarations); |
| CHECK_PARSE_BOOL(SpacesInParentheses); |
| CHECK_PARSE_BOOL(SpacesInSquareBrackets); |
| CHECK_PARSE_BOOL(SpacesInConditionalStatement); |
| CHECK_PARSE_BOOL(SpaceInEmptyBlock); |
| CHECK_PARSE_BOOL(SpaceInEmptyParentheses); |
| CHECK_PARSE_BOOL(SpacesInContainerLiterals); |
| CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses); |
| CHECK_PARSE_BOOL(SpaceAfterCStyleCast); |
| CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword); |
| CHECK_PARSE_BOOL(SpaceAfterLogicalNot); |
| CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators); |
| CHECK_PARSE_BOOL(SpaceBeforeCaseColon); |
| CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList); |
| CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon); |
| CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon); |
| CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon); |
| CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets); |
| CHECK_PARSE_BOOL(UseCRLF); |
| |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord); |
| CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, |
| AfterFunctionDeclarationName); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, |
| AfterFunctionDefinitionName); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator); |
| CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses); |
| } |
| |
| #undef CHECK_PARSE_BOOL |
| |
| TEST_F(FormatTest, ParsesConfiguration) { |
| FormatStyle Style = {}; |
| Style.Language = FormatStyle::LK_Cpp; |
| CHECK_PARSE("AccessModifierOffset: -1234", AccessModifierOffset, -1234); |
| CHECK_PARSE("ConstructorInitializerIndentWidth: 1234", |
| ConstructorInitializerIndentWidth, 1234u); |
| CHECK_PARSE("ObjCBlockIndentWidth: 1234", ObjCBlockIndentWidth, 1234u); |
| CHECK_PARSE("ColumnLimit: 1234", ColumnLimit, 1234u); |
| CHECK_PARSE("MaxEmptyLinesToKeep: 1234", MaxEmptyLinesToKeep, 1234u); |
| CHECK_PARSE("PenaltyBreakAssignment: 1234", PenaltyBreakAssignment, 1234u); |
| CHECK_PARSE("PenaltyBreakBeforeFirstCallParameter: 1234", |
| PenaltyBreakBeforeFirstCallParameter, 1234u); |
| CHECK_PARSE("PenaltyBreakTemplateDeclaration: 1234", |
| PenaltyBreakTemplateDeclaration, 1234u); |
| CHECK_PARSE("PenaltyBreakOpenParenthesis: 1234", PenaltyBreakOpenParenthesis, |
| 1234u); |
| CHECK_PARSE("PenaltyExcessCharacter: 1234", PenaltyExcessCharacter, 1234u); |
| CHECK_PARSE("PenaltyReturnTypeOnItsOwnLine: 1234", |
| PenaltyReturnTypeOnItsOwnLine, 1234u); |
| CHECK_PARSE("SpacesBeforeTrailingComments: 1234", |
| SpacesBeforeTrailingComments, 1234u); |
| CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u); |
| CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u); |
| CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$"); |
| |
| Style.QualifierAlignment = FormatStyle::QAS_Right; |
| CHECK_PARSE("QualifierAlignment: Leave", QualifierAlignment, |
| FormatStyle::QAS_Leave); |
| CHECK_PARSE("QualifierAlignment: Right", QualifierAlignment, |
| FormatStyle::QAS_Right); |
| CHECK_PARSE("QualifierAlignment: Left", QualifierAlignment, |
| FormatStyle::QAS_Left); |
| CHECK_PARSE("QualifierAlignment: Custom", QualifierAlignment, |
| FormatStyle::QAS_Custom); |
| |
| Style.QualifierOrder.clear(); |
| CHECK_PARSE("QualifierOrder: [ const, volatile, type ]", QualifierOrder, |
| std::vector<std::string>({"const", "volatile", "type"})); |
| Style.QualifierOrder.clear(); |
| CHECK_PARSE("QualifierOrder: [const, type]", QualifierOrder, |
| std::vector<std::string>({"const", "type"})); |
| Style.QualifierOrder.clear(); |
| CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder, |
| std::vector<std::string>({"volatile", "type"})); |
| |
| #define CHECK_ALIGN_CONSECUTIVE(FIELD) \ |
| do { \ |
| Style.FIELD.Enabled = true; \ |
| CHECK_PARSE(#FIELD ": None", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/false, /*AcrossEmptyLines=*/false, \ |
| /*AcrossComments=*/false, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| CHECK_PARSE(#FIELD ": Consecutive", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ |
| /*AcrossComments=*/false, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| CHECK_PARSE(#FIELD ": AcrossEmptyLines", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ |
| /*AcrossComments=*/false, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| CHECK_PARSE(#FIELD ": AcrossEmptyLinesAndComments", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \ |
| /*AcrossComments=*/true, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| /* For backwards compability, false / true should still parse */ \ |
| CHECK_PARSE(#FIELD ": false", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/false, /*AcrossEmptyLines=*/false, \ |
| /*AcrossComments=*/false, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| CHECK_PARSE(#FIELD ": true", FIELD, \ |
| FormatStyle::AlignConsecutiveStyle( \ |
| {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \ |
| /*AcrossComments=*/false, /*AlignCompound=*/false, \ |
| /*PadOperators=*/true})); \ |
| \ |
| CHECK_PARSE_NESTED_BOOL(FIELD, Enabled); \ |
| CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines); \ |
| CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \ |
| CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound); \ |
| CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators); \ |
| } while (false) |
| |
| CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments); |
| CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields); |
| CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros); |
| CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations); |
| |
| #undef CHECK_ALIGN_CONSECUTIVE |
| |
| Style.PointerAlignment = FormatStyle::PAS_Middle; |
| CHECK_PARSE("PointerAlignment: Left", PointerAlignment, |
| FormatStyle::PAS_Left); |
| CHECK_PARSE("PointerAlignment: Right", PointerAlignment, |
| FormatStyle::PAS_Right); |
| CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, |
| FormatStyle::PAS_Middle); |
| Style.ReferenceAlignment = FormatStyle::RAS_Middle; |
| CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment, |
| FormatStyle::RAS_Pointer); |
| CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment, |
| FormatStyle::RAS_Left); |
| CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment, |
| FormatStyle::RAS_Right); |
| CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment, |
| FormatStyle::RAS_Middle); |
| // For backward compatibility: |
| CHECK_PARSE("PointerBindsToType: Left", PointerAlignment, |
| FormatStyle::PAS_Left); |
| CHECK_PARSE("PointerBindsToType: Right", PointerAlignment, |
| FormatStyle::PAS_Right); |
| CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment, |
| FormatStyle::PAS_Middle); |
| |
| Style.Standard = FormatStyle::LS_Auto; |
| CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03); |
| CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11); |
| CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14); |
| CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17); |
| CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20); |
| CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto); |
| CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest); |
| // Legacy aliases: |
| CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03); |
| CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest); |
| CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03); |
| CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment", |
| BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment); |
| CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators, |
| FormatStyle::BOS_None); |
| CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators, |
| FormatStyle::BOS_All); |
| // For backward compatibility: |
| CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators, |
| FormatStyle::BOS_None); |
| CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators, |
| FormatStyle::BOS_All); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; |
| CHECK_PARSE("BreakConstructorInitializers: BeforeComma", |
| BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); |
| CHECK_PARSE("BreakConstructorInitializers: AfterColon", |
| BreakConstructorInitializers, FormatStyle::BCIS_AfterColon); |
| CHECK_PARSE("BreakConstructorInitializers: BeforeColon", |
| BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon); |
| // For backward compatibility: |
| CHECK_PARSE("BreakConstructorInitializersBeforeComma: true", |
| BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); |
| |
| Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon; |
| CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList, |
| FormatStyle::BILS_AfterComma); |
| CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList, |
| FormatStyle::BILS_BeforeComma); |
| CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList, |
| FormatStyle::BILS_AfterColon); |
| CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList, |
| FormatStyle::BILS_BeforeColon); |
| // For backward compatibility: |
| CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList, |
| FormatStyle::BILS_BeforeComma); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack; |
| CHECK_PARSE("PackConstructorInitializers: Never", PackConstructorInitializers, |
| FormatStyle::PCIS_Never); |
| CHECK_PARSE("PackConstructorInitializers: BinPack", |
| PackConstructorInitializers, FormatStyle::PCIS_BinPack); |
| CHECK_PARSE("PackConstructorInitializers: CurrentLine", |
| PackConstructorInitializers, FormatStyle::PCIS_CurrentLine); |
| CHECK_PARSE("PackConstructorInitializers: NextLine", |
| PackConstructorInitializers, FormatStyle::PCIS_NextLine); |
| // For backward compatibility: |
| CHECK_PARSE("BasedOnStyle: Google\n" |
| "ConstructorInitializerAllOnOneLineOrOnePerLine: true\n" |
| "AllowAllConstructorInitializersOnNextLine: false", |
| PackConstructorInitializers, FormatStyle::PCIS_CurrentLine); |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| CHECK_PARSE("BasedOnStyle: Google\n" |
| "ConstructorInitializerAllOnOneLineOrOnePerLine: false", |
| PackConstructorInitializers, FormatStyle::PCIS_BinPack); |
| CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n" |
| "AllowAllConstructorInitializersOnNextLine: true", |
| PackConstructorInitializers, FormatStyle::PCIS_NextLine); |
| Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack; |
| CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n" |
| "AllowAllConstructorInitializersOnNextLine: false", |
| PackConstructorInitializers, FormatStyle::PCIS_CurrentLine); |
| |
| Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock; |
| CHECK_PARSE("EmptyLineBeforeAccessModifier: Never", |
| EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Never); |
| CHECK_PARSE("EmptyLineBeforeAccessModifier: Leave", |
| EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Leave); |
| CHECK_PARSE("EmptyLineBeforeAccessModifier: LogicalBlock", |
| EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_LogicalBlock); |
| CHECK_PARSE("EmptyLineBeforeAccessModifier: Always", |
| EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Always); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, |
| FormatStyle::BAS_Align); |
| CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, |
| FormatStyle::BAS_DontAlign); |
| CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket, |
| FormatStyle::BAS_AlwaysBreak); |
| CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket, |
| FormatStyle::BAS_BlockIndent); |
| // For backward compatibility: |
| CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, |
| FormatStyle::BAS_DontAlign); |
| CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, |
| FormatStyle::BAS_Align); |
| |
| Style.AlignEscapedNewlines = FormatStyle::ENAS_Left; |
| CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines, |
| FormatStyle::ENAS_DontAlign); |
| CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines, |
| FormatStyle::ENAS_Left); |
| CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines, |
| FormatStyle::ENAS_Right); |
| // For backward compatibility: |
| CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines, |
| FormatStyle::ENAS_Left); |
| CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines, |
| FormatStyle::ENAS_Right); |
| |
| Style.AlignOperands = FormatStyle::OAS_Align; |
| CHECK_PARSE("AlignOperands: DontAlign", AlignOperands, |
| FormatStyle::OAS_DontAlign); |
| CHECK_PARSE("AlignOperands: Align", AlignOperands, FormatStyle::OAS_Align); |
| CHECK_PARSE("AlignOperands: AlignAfterOperator", AlignOperands, |
| FormatStyle::OAS_AlignAfterOperator); |
| // For backward compatibility: |
| CHECK_PARSE("AlignOperands: false", AlignOperands, |
| FormatStyle::OAS_DontAlign); |
| CHECK_PARSE("AlignOperands: true", AlignOperands, FormatStyle::OAS_Align); |
| |
| Style.UseTab = FormatStyle::UT_ForIndentation; |
| CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never); |
| CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation); |
| CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always); |
| CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab, |
| FormatStyle::UT_ForContinuationAndIndentation); |
| CHECK_PARSE("UseTab: AlignWithSpaces", UseTab, |
| FormatStyle::UT_AlignWithSpaces); |
| // For backward compatibility: |
| CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never); |
| CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always); |
| |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; |
| CHECK_PARSE("AllowShortBlocksOnASingleLine: Never", |
| AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); |
| CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty", |
| AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty); |
| CHECK_PARSE("AllowShortBlocksOnASingleLine: Always", |
| AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always); |
| // For backward compatibility: |
| CHECK_PARSE("AllowShortBlocksOnASingleLine: false", |
| AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never); |
| CHECK_PARSE("AllowShortBlocksOnASingleLine: true", |
| AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: None", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline); |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty); |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: All", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All); |
| // For backward compatibility: |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: false", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); |
| CHECK_PARSE("AllowShortFunctionsOnASingleLine: true", |
| AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All); |
| |
| Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both; |
| CHECK_PARSE("SpaceAroundPointerQualifiers: Default", |
| SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default); |
| CHECK_PARSE("SpaceAroundPointerQualifiers: Before", |
| SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before); |
| CHECK_PARSE("SpaceAroundPointerQualifiers: After", |
| SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After); |
| CHECK_PARSE("SpaceAroundPointerQualifiers: Both", |
| SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both); |
| |
| Style.SpaceBeforeParens = FormatStyle::SBPO_Always; |
| CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens, |
| FormatStyle::SBPO_Never); |
| CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens, |
| FormatStyle::SBPO_Always); |
| CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens, |
| FormatStyle::SBPO_ControlStatements); |
| CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros", |
| SpaceBeforeParens, |
| FormatStyle::SBPO_ControlStatementsExceptControlMacros); |
| CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens, |
| FormatStyle::SBPO_NonEmptyParentheses); |
| CHECK_PARSE("SpaceBeforeParens: Custom", SpaceBeforeParens, |
| FormatStyle::SBPO_Custom); |
| // For backward compatibility: |
| CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens, |
| FormatStyle::SBPO_Never); |
| CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens, |
| FormatStyle::SBPO_ControlStatements); |
| CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros", |
| SpaceBeforeParens, |
| FormatStyle::SBPO_ControlStatementsExceptControlMacros); |
| |
| Style.ColumnLimit = 123; |
| FormatStyle BaseStyle = getLLVMStyle(); |
| CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit); |
| CHECK_PARSE("BasedOnStyle: LLVM\nColumnLimit: 1234", ColumnLimit, 1234u); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; |
| CHECK_PARSE("BreakBeforeBraces: Attach", BreakBeforeBraces, |
| FormatStyle::BS_Attach); |
| CHECK_PARSE("BreakBeforeBraces: Linux", BreakBeforeBraces, |
| FormatStyle::BS_Linux); |
| CHECK_PARSE("BreakBeforeBraces: Mozilla", BreakBeforeBraces, |
| FormatStyle::BS_Mozilla); |
| CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces, |
| FormatStyle::BS_Stroustrup); |
| CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces, |
| FormatStyle::BS_Allman); |
| CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces, |
| FormatStyle::BS_Whitesmiths); |
| CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); |
| CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces, |
| FormatStyle::BS_WebKit); |
| CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces, |
| FormatStyle::BS_Custom); |
| |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never; |
| CHECK_PARSE("BraceWrapping:\n" |
| " AfterControlStatement: MultiLine", |
| BraceWrapping.AfterControlStatement, |
| FormatStyle::BWACS_MultiLine); |
| CHECK_PARSE("BraceWrapping:\n" |
| " AfterControlStatement: Always", |
| BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always); |
| CHECK_PARSE("BraceWrapping:\n" |
| " AfterControlStatement: Never", |
| BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never); |
| // For backward compatibility: |
| CHECK_PARSE("BraceWrapping:\n" |
| " AfterControlStatement: true", |
| BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always); |
| CHECK_PARSE("BraceWrapping:\n" |
| " AfterControlStatement: false", |
| BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never); |
| |
| Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_All; |
| CHECK_PARSE("AlwaysBreakAfterReturnType: None", AlwaysBreakAfterReturnType, |
| FormatStyle::RTBS_None); |
| CHECK_PARSE("AlwaysBreakAfterReturnType: All", AlwaysBreakAfterReturnType, |
| FormatStyle::RTBS_All); |
| CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel", |
| AlwaysBreakAfterReturnType, FormatStyle::RTBS_TopLevel); |
| CHECK_PARSE("AlwaysBreakAfterReturnType: AllDefinitions", |
| AlwaysBreakAfterReturnType, FormatStyle::RTBS_AllDefinitions); |
| CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevelDefinitions", |
| AlwaysBreakAfterReturnType, |
| FormatStyle::RTBS_TopLevelDefinitions); |
| |
| Style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes; |
| CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", |
| AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_No); |
| CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine", |
| AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_MultiLine); |
| CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", |
| AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_Yes); |
| CHECK_PARSE("AlwaysBreakTemplateDeclarations: false", |
| AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_MultiLine); |
| CHECK_PARSE("AlwaysBreakTemplateDeclarations: true", |
| AlwaysBreakTemplateDeclarations, FormatStyle::BTDS_Yes); |
| |
| Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; |
| CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None", |
| AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None); |
| CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All", |
| AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All); |
| CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel", |
| AlwaysBreakAfterDefinitionReturnType, |
| FormatStyle::DRTBS_TopLevel); |
| |
| Style.NamespaceIndentation = FormatStyle::NI_All; |
| CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation, |
| FormatStyle::NI_None); |
| CHECK_PARSE("NamespaceIndentation: Inner", NamespaceIndentation, |
| FormatStyle::NI_Inner); |
| CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation, |
| FormatStyle::NI_All); |
| |
| Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_OnlyFirstIf; |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never", |
| AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse", |
| AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_WithoutElse); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: OnlyFirstIf", |
| AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_OnlyFirstIf); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: AllIfsAndElse", |
| AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_AllIfsAndElse); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always", |
| AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_OnlyFirstIf); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false", |
| AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never); |
| CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true", |
| AllowShortIfStatementsOnASingleLine, |
| FormatStyle::SIS_WithoutElse); |
| |
| Style.IndentExternBlock = FormatStyle::IEBS_NoIndent; |
| CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, |
| FormatStyle::IEBS_AfterExternBlock); |
| CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, |
| FormatStyle::IEBS_Indent); |
| CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, |
| FormatStyle::IEBS_NoIndent); |
| CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, |
| FormatStyle::IEBS_Indent); |
| CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, |
| FormatStyle::IEBS_NoIndent); |
| |
| Style.BitFieldColonSpacing = FormatStyle::BFCS_None; |
| CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing, |
| FormatStyle::BFCS_Both); |
| CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing, |
| FormatStyle::BFCS_None); |
| CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing, |
| FormatStyle::BFCS_Before); |
| CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing, |
| FormatStyle::BFCS_After); |
| |
| Style.SortJavaStaticImport = FormatStyle::SJSIO_Before; |
| CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport, |
| FormatStyle::SJSIO_After); |
| CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport, |
| FormatStyle::SJSIO_Before); |
| |
| // FIXME: This is required because parsing a configuration simply overwrites |
| // the first N elements of the list instead of resetting it. |
| Style.ForEachMacros.clear(); |
| std::vector<std::string> BoostForeach; |
| BoostForeach.push_back("BOOST_FOREACH"); |
| CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach); |
| std::vector<std::string> BoostAndQForeach; |
| BoostAndQForeach.push_back("BOOST_FOREACH"); |
| BoostAndQForeach.push_back("Q_FOREACH"); |
| CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros, |
| BoostAndQForeach); |
| |
| Style.IfMacros.clear(); |
| std::vector<std::string> CustomIfs; |
| CustomIfs.push_back("MYIF"); |
| CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs); |
| |
| Style.AttributeMacros.clear(); |
| CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros, |
| std::vector<std::string>{"__capability"}); |
| CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros, |
| std::vector<std::string>({"attr1", "attr2"})); |
| |
| Style.StatementAttributeLikeMacros.clear(); |
| CHECK_PARSE("StatementAttributeLikeMacros: [emit,Q_EMIT]", |
| StatementAttributeLikeMacros, |
| std::vector<std::string>({"emit", "Q_EMIT"})); |
| |
| Style.StatementMacros.clear(); |
| CHECK_PARSE("StatementMacros: [QUNUSED]", StatementMacros, |
| std::vector<std::string>{"QUNUSED"}); |
| CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros, |
| std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"})); |
| |
| Style.NamespaceMacros.clear(); |
| CHECK_PARSE("NamespaceMacros: [TESTSUITE]", NamespaceMacros, |
| std::vector<std::string>{"TESTSUITE"}); |
| CHECK_PARSE("NamespaceMacros: [TESTSUITE, SUITE]", NamespaceMacros, |
| std::vector<std::string>({"TESTSUITE", "SUITE"})); |
| |
| Style.WhitespaceSensitiveMacros.clear(); |
| CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]", |
| WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"}); |
| CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]", |
| WhitespaceSensitiveMacros, |
| std::vector<std::string>({"STRINGIZE", "ASSERT"})); |
| Style.WhitespaceSensitiveMacros.clear(); |
| CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']", |
| WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"}); |
| CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']", |
| WhitespaceSensitiveMacros, |
| std::vector<std::string>({"STRINGIZE", "ASSERT"})); |
| |
| Style.IncludeStyle.IncludeCategories.clear(); |
| std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = { |
| {"abc/.*", 2, 0, false}, {".*", 1, 0, true}}; |
| CHECK_PARSE("IncludeCategories:\n" |
| " - Regex: abc/.*\n" |
| " Priority: 2\n" |
| " - Regex: .*\n" |
| " Priority: 1\n" |
| " CaseSensitive: true\n", |
| IncludeStyle.IncludeCategories, ExpectedCategories); |
| CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeStyle.IncludeIsMainRegex, |
| "abc$"); |
| CHECK_PARSE("IncludeIsMainSourceRegex: 'abc$'", |
| IncludeStyle.IncludeIsMainSourceRegex, "abc$"); |
| |
| Style.SortIncludes = FormatStyle::SI_Never; |
| CHECK_PARSE("SortIncludes: true", SortIncludes, |
| FormatStyle::SI_CaseSensitive); |
| CHECK_PARSE("SortIncludes: false", SortIncludes, FormatStyle::SI_Never); |
| CHECK_PARSE("SortIncludes: CaseInsensitive", SortIncludes, |
| FormatStyle::SI_CaseInsensitive); |
| CHECK_PARSE("SortIncludes: CaseSensitive", SortIncludes, |
| FormatStyle::SI_CaseSensitive); |
| CHECK_PARSE("SortIncludes: Never", SortIncludes, FormatStyle::SI_Never); |
| |
| Style.RawStringFormats.clear(); |
| std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = { |
| { |
| FormatStyle::LK_TextProto, |
| {"pb", "proto"}, |
| {"PARSE_TEXT_PROTO"}, |
| /*CanonicalDelimiter=*/"", |
| "llvm", |
| }, |
| { |
| FormatStyle::LK_Cpp, |
| {"cc", "cpp"}, |
| {"C_CODEBLOCK", "CPPEVAL"}, |
| /*CanonicalDelimiter=*/"cc", |
| /*BasedOnStyle=*/"", |
| }, |
| }; |
| |
| CHECK_PARSE("RawStringFormats:\n" |
| " - Language: TextProto\n" |
| " Delimiters:\n" |
| " - 'pb'\n" |
| " - 'proto'\n" |
| " EnclosingFunctions:\n" |
| " - 'PARSE_TEXT_PROTO'\n" |
| " BasedOnStyle: llvm\n" |
| " - Language: Cpp\n" |
| " Delimiters:\n" |
| " - 'cc'\n" |
| " - 'cpp'\n" |
| " EnclosingFunctions:\n" |
| " - 'C_CODEBLOCK'\n" |
| " - 'CPPEVAL'\n" |
| " CanonicalDelimiter: 'cc'", |
| RawStringFormats, ExpectedRawStringFormats); |
| |
| CHECK_PARSE("SpacesInLineCommentPrefix:\n" |
| " Minimum: 0\n" |
| " Maximum: 0", |
| SpacesInLineCommentPrefix.Minimum, 0u); |
| EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u); |
| Style.SpacesInLineCommentPrefix.Minimum = 1; |
| CHECK_PARSE("SpacesInLineCommentPrefix:\n" |
| " Minimum: 2", |
| SpacesInLineCommentPrefix.Minimum, 0u); |
| CHECK_PARSE("SpacesInLineCommentPrefix:\n" |
| " Maximum: -1", |
| SpacesInLineCommentPrefix.Maximum, -1u); |
| CHECK_PARSE("SpacesInLineCommentPrefix:\n" |
| " Minimum: 2", |
| SpacesInLineCommentPrefix.Minimum, 2u); |
| CHECK_PARSE("SpacesInLineCommentPrefix:\n" |
| " Maximum: 1", |
| SpacesInLineCommentPrefix.Maximum, 1u); |
| EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u); |
| |
| Style.SpacesInAngles = FormatStyle::SIAS_Always; |
| CHECK_PARSE("SpacesInAngles: Never", SpacesInAngles, FormatStyle::SIAS_Never); |
| CHECK_PARSE("SpacesInAngles: Always", SpacesInAngles, |
| FormatStyle::SIAS_Always); |
| CHECK_PARSE("SpacesInAngles: Leave", SpacesInAngles, FormatStyle::SIAS_Leave); |
| // For backward compatibility: |
| CHECK_PARSE("SpacesInAngles: false", SpacesInAngles, FormatStyle::SIAS_Never); |
| CHECK_PARSE("SpacesInAngles: true", SpacesInAngles, FormatStyle::SIAS_Always); |
| |
| CHECK_PARSE("RequiresClausePosition: WithPreceding", RequiresClausePosition, |
| FormatStyle::RCPS_WithPreceding); |
| CHECK_PARSE("RequiresClausePosition: WithFollowing", RequiresClausePosition, |
| FormatStyle::RCPS_WithFollowing); |
| CHECK_PARSE("RequiresClausePosition: SingleLine", RequiresClausePosition, |
| FormatStyle::RCPS_SingleLine); |
| CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition, |
| FormatStyle::RCPS_OwnLine); |
| |
| CHECK_PARSE("BreakBeforeConceptDeclarations: Never", |
| BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never); |
| CHECK_PARSE("BreakBeforeConceptDeclarations: Always", |
| BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always); |
| CHECK_PARSE("BreakBeforeConceptDeclarations: Allowed", |
| BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed); |
| // For backward compatibility: |
| CHECK_PARSE("BreakBeforeConceptDeclarations: true", |
| BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always); |
| CHECK_PARSE("BreakBeforeConceptDeclarations: false", |
| BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed); |
| } |
| |
| TEST_F(FormatTest, ParsesConfigurationWithLanguages) { |
| FormatStyle Style = {}; |
| Style.Language = FormatStyle::LK_Cpp; |
| CHECK_PARSE("Language: Cpp\n" |
| "IndentWidth: 12", |
| IndentWidth, 12u); |
| EXPECT_EQ(parseConfiguration("Language: JavaScript\n" |
| "IndentWidth: 34", |
| &Style), |
| ParseError::Unsuitable); |
| FormatStyle BinPackedTCS = {}; |
| BinPackedTCS.Language = FormatStyle::LK_JavaScript; |
| EXPECT_EQ(parseConfiguration("BinPackArguments: true\n" |
| "InsertTrailingCommas: Wrapped", |
| &BinPackedTCS), |
| ParseError::BinPackTrailingCommaConflict); |
| EXPECT_EQ(12u, Style.IndentWidth); |
| CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u); |
| EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language); |
| |
| Style.Language = FormatStyle::LK_JavaScript; |
| CHECK_PARSE("Language: JavaScript\n" |
| "IndentWidth: 12", |
| IndentWidth, 12u); |
| CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u); |
| EXPECT_EQ(parseConfiguration("Language: Cpp\n" |
| "IndentWidth: 34", |
| &Style), |
| ParseError::Unsuitable); |
| EXPECT_EQ(23u, Style.IndentWidth); |
| CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u); |
| EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language); |
| |
| CHECK_PARSE("BasedOnStyle: LLVM\n" |
| "IndentWidth: 67", |
| IndentWidth, 67u); |
| |
| CHECK_PARSE("---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 12\n" |
| "---\n" |
| "Language: Cpp\n" |
| "IndentWidth: 34\n" |
| "...\n", |
| IndentWidth, 12u); |
| |
| Style.Language = FormatStyle::LK_Cpp; |
| CHECK_PARSE("---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 12\n" |
| "---\n" |
| "Language: Cpp\n" |
| "IndentWidth: 34\n" |
| "...\n", |
| IndentWidth, 34u); |
| CHECK_PARSE("---\n" |
| "IndentWidth: 78\n" |
| "---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 56\n" |
| "...\n", |
| IndentWidth, 78u); |
| |
| Style.ColumnLimit = 123; |
| Style.IndentWidth = 234; |
| Style.BreakBeforeBraces = FormatStyle::BS_Linux; |
| Style.TabWidth = 345; |
| EXPECT_FALSE(parseConfiguration("---\n" |
| "IndentWidth: 456\n" |
| "BreakBeforeBraces: Allman\n" |
| "---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 111\n" |
| "TabWidth: 111\n" |
| "---\n" |
| "Language: Cpp\n" |
| "BreakBeforeBraces: Stroustrup\n" |
| "TabWidth: 789\n" |
| "...\n", |
| &Style)); |
| EXPECT_EQ(123u, Style.ColumnLimit); |
| EXPECT_EQ(456u, Style.IndentWidth); |
| EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces); |
| EXPECT_EQ(789u, Style.TabWidth); |
| |
| EXPECT_EQ(parseConfiguration("---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 56\n" |
| "---\n" |
| "IndentWidth: 78\n" |
| "...\n", |
| &Style), |
| ParseError::Error); |
| EXPECT_EQ(parseConfiguration("---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 56\n" |
| "---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 78\n" |
| "...\n", |
| &Style), |
| ParseError::Error); |
| |
| EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language); |
| } |
| |
| TEST_F(FormatTest, UsesLanguageForBasedOnStyle) { |
| FormatStyle Style = {}; |
| Style.Language = FormatStyle::LK_JavaScript; |
| Style.BreakBeforeTernaryOperators = true; |
| EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value()); |
| EXPECT_FALSE(Style.BreakBeforeTernaryOperators); |
| |
| Style.BreakBeforeTernaryOperators = true; |
| EXPECT_EQ(0, parseConfiguration("---\n" |
| "BasedOnStyle: Google\n" |
| "---\n" |
| "Language: JavaScript\n" |
| "IndentWidth: 76\n" |
| "...\n", |
| &Style) |
| .value()); |
| EXPECT_FALSE(Style.BreakBeforeTernaryOperators); |
| EXPECT_EQ(76u, Style.IndentWidth); |
| EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language); |
| } |
| |
| TEST_F(FormatTest, ConfigurationRoundTripTest) { |
| FormatStyle Style = getLLVMStyle(); |
| std::string YAML = configurationAsText(Style); |
| FormatStyle ParsedStyle = {}; |
| ParsedStyle.Language = FormatStyle::LK_Cpp; |
| EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value()); |
| EXPECT_EQ(Style, ParsedStyle); |
| } |
| |
| TEST_F(FormatTest, WorksFor8bitEncodings) { |
| EXPECT_EQ("\"\xce\xe4\xed\xe0\xe6\xe4\xfb \xe2 \"\n" |
| "\"\xf1\xf2\xf3\xe4\xb8\xed\xf3\xfe \"\n" |
| "\"\xe7\xe8\xec\xed\xfe\xfe \"\n" |
| "\"\xef\xee\xf0\xf3...\"", |
| format("\"\xce\xe4\xed\xe0\xe6\xe4\xfb \xe2 " |
| "\xf1\xf2\xf3\xe4\xb8\xed\xf3\xfe \xe7\xe8\xec\xed\xfe\xfe " |
| "\xef\xee\xf0\xf3...\"", |
| getLLVMStyleWithColumns(12))); |
| } |
| |
| TEST_F(FormatTest, HandlesUTF8BOM) { |
| EXPECT_EQ("\xef\xbb\xbf", format("\xef\xbb\xbf")); |
| EXPECT_EQ("\xef\xbb\xbf#include <iostream>", |
| format("\xef\xbb\xbf#include <iostream>")); |
| EXPECT_EQ("\xef\xbb\xbf\n#include <iostream>", |
| format("\xef\xbb\xbf\n#include <iostream>")); |
| } |
| |
| // FIXME: Encode Cyrillic and CJK characters below to appease MS compilers. |
| #if !defined(_MSC_VER) |
| |
| TEST_F(FormatTest, CountsUTF8CharactersProperly) { |
| verifyFormat("\"Однажды в студёную зимнюю пору...\"", |
| getLLVMStyleWithColumns(35)); |
| verifyFormat("\"一 二 三 四 五 六 七 八 九 十\"", |
| getLLVMStyleWithColumns(31)); |
| verifyFormat("// Однажды в студёную зимнюю пору...", |
| getLLVMStyleWithColumns(36)); |
| verifyFormat("// 一 二 三 四 五 六 七 八 九 十", getLLVMStyleWithColumns(32)); |
| verifyFormat("/* Однажды в студёную зимнюю пору... */", |
| getLLVMStyleWithColumns(39)); |
| verifyFormat("/* 一 二 三 四 五 六 七 八 九 十 */", |
| getLLVMStyleWithColumns(35)); |
| } |
| |
| TEST_F(FormatTest, SplitsUTF8Strings) { |
| // Non-printable characters' width is currently considered to be the length in |
| // bytes in UTF8. The characters can be displayed in very different manner |
| // (zero-width, single width with a substitution glyph, expanded to their code |
| // (e.g. "<8d>"), so there's no single correct way to handle them. |
| EXPECT_EQ("\"aaaaÄ\"\n" |
| "\"\xc2\x8d\";", |
| format("\"aaaaÄ\xc2\x8d\";", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("\"aaaaaaaÄ\"\n" |
| "\"\xc2\x8d\";", |
| format("\"aaaaaaaÄ\xc2\x8d\";", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("\"Однажды, в \"\n" |
| "\"студёную \"\n" |
| "\"зимнюю \"\n" |
| "\"пору,\"", |
| format("\"Однажды, в студёную зимнюю пору,\"", |
| getLLVMStyleWithColumns(13))); |
| EXPECT_EQ( |
| "\"一 二 三 \"\n" |
| "\"四 五六 \"\n" |
| "\"七 八 九 \"\n" |
| "\"十\"", |
| format("\"一 二 三 四 五六 七 八 九 十\"", getLLVMStyleWithColumns(11))); |
| EXPECT_EQ("\"一\t\"\n" |
| "\"二 \t\"\n" |
| "\"三 四 \"\n" |
| "\"五\t\"\n" |
| "\"六 \t\"\n" |
| "\"七 \"\n" |
| "\"八九十\tqq\"", |
| format("\"一\t二 \t三 四 五\t六 \t七 八九十\tqq\"", |
| getLLVMStyleWithColumns(11))); |
| |
| // UTF8 character in an escape sequence. |
| EXPECT_EQ("\"aaaaaa\"\n" |
| "\"\\\xC2\x8D\"", |
| format("\"aaaaaa\\\xC2\x8D\"", getLLVMStyleWithColumns(10))); |
| } |
| |
| TEST_F(FormatTest, HandlesDoubleWidthCharsInMultiLineStrings) { |
| EXPECT_EQ("const char *sssss =\n" |
| " \"一二三四五六七八\\\n" |
| " 九 十\";", |
| format("const char *sssss = \"一二三四五六七八\\\n" |
| " 九 十\";", |
| getLLVMStyleWithColumns(30))); |
| } |
| |
| TEST_F(FormatTest, SplitsUTF8LineComments) { |
| EXPECT_EQ("// aaaaÄ\xc2\x8d", |
| format("// aaaaÄ\xc2\x8d", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("// Я из лесу\n" |
| "// вышел; был\n" |
| "// сильный\n" |
| "// мороз.", |
| format("// Я из лесу вышел; был сильный мороз.", |
| getLLVMStyleWithColumns(13))); |
| EXPECT_EQ("// 一二三\n" |
| "// 四五六七\n" |
| "// 八 九\n" |
| "// 十", |
| format("// 一二三 四五六七 八 九 十", getLLVMStyleWithColumns(9))); |
| } |
| |
| TEST_F(FormatTest, SplitsUTF8BlockComments) { |
| EXPECT_EQ("/* Гляжу,\n" |
| " * поднимается\n" |
| " * медленно в\n" |
| " * гору\n" |
| " * Лошадка,\n" |
| " * везущая\n" |
| " * хворосту\n" |
| " * воз. */", |
| format("/* Гляжу, поднимается медленно в гору\n" |
| " * Лошадка, везущая хворосту воз. */", |
| getLLVMStyleWithColumns(13))); |
| EXPECT_EQ( |
| "/* 一二三\n" |
| " * 四五六七\n" |
| " * 八 九\n" |
| " * 十 */", |
| format("/* 一二三 四五六七 八 九 十 */", getLLVMStyleWithColumns(9))); |
| EXPECT_EQ("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯\n" |
| " * 𝕓𝕪𝕥𝕖\n" |
| " * 𝖀𝕿𝕱-𝟠 */", |
| format("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯 𝕓𝕪𝕥𝕖 𝖀𝕿𝕱-𝟠 */", getLLVMStyleWithColumns(12))); |
| } |
| |
| #endif // _MSC_VER |
| |
| TEST_F(FormatTest, ConstructorInitializerIndentWidth) { |
| FormatStyle Style = getLLVMStyle(); |
| |
| Style.ConstructorInitializerIndentWidth = 4; |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| Style); |
| |
| Style.ConstructorInitializerIndentWidth = 2; |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| Style); |
| |
| Style.ConstructorInitializerIndentWidth = 0; |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| ": aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n" |
| " aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}", |
| Style); |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; |
| verifyFormat( |
| "SomeLongTemplateVariableName<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>", |
| Style); |
| verifyFormat("bool smaller = 1 < " |
| "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" |
| " " |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", |
| Style); |
| |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon; |
| verifyFormat("SomeClass::Constructor() :\n" |
| "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa),\n" |
| "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa) {}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; |
| Style.ConstructorInitializerIndentWidth = 4; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| " , b(b)\n" |
| " , c(c) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a) {}", |
| Style); |
| |
| Style.ColumnLimit = 0; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor() noexcept\n" |
| " : a(a) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| " , b(b)\n" |
| " , c(c) {}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a) {\n" |
| " foo();\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| " , b(b)\n" |
| " , c(c) {\n}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a) {\n}", |
| Style); |
| |
| Style.ColumnLimit = 80; |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; |
| Style.ConstructorInitializerIndentWidth = 2; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| " , b(b)\n" |
| " , c(c) {}", |
| Style); |
| |
| Style.ConstructorInitializerIndentWidth = 0; |
| verifyFormat("SomeClass::Constructor()\n" |
| ": a(a)\n" |
| ", b(b)\n" |
| ", c(c) {}", |
| Style); |
| |
| Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine; |
| Style.ConstructorInitializerIndentWidth = 4; |
| verifyFormat("SomeClass::Constructor() : aaaaaaaa(aaaaaaaa) {}", Style); |
| verifyFormat( |
| "SomeClass::Constructor() : aaaaa(aaaaa), aaaaa(aaaaa), aaaaa(aaaaa)\n", |
| Style); |
| verifyFormat( |
| "SomeClass::Constructor()\n" |
| " : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa) {}", |
| Style); |
| Style.ConstructorInitializerIndentWidth = 4; |
| Style.ColumnLimit = 60; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : aaaaaaaa(aaaaaaaa)\n" |
| " , aaaaaaaa(aaaaaaaa)\n" |
| " , aaaaaaaa(aaaaaaaa) {}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ConstructorInitializersWithPreprocessorDirective) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; |
| Style.ConstructorInitializerIndentWidth = 4; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a{a}\n" |
| " , b{b} {}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a{a}\n" |
| "#if CONDITION\n" |
| " , b{b}\n" |
| "#endif\n" |
| "{\n}", |
| Style); |
| Style.ConstructorInitializerIndentWidth = 2; |
| verifyFormat("SomeClass::Constructor()\n" |
| "#if CONDITION\n" |
| " : a{a}\n" |
| "#endif\n" |
| " , b{b}\n" |
| " , c{c} {\n}", |
| Style); |
| Style.ConstructorInitializerIndentWidth = 0; |
| verifyFormat("SomeClass::Constructor()\n" |
| ": a{a}\n" |
| "#ifdef CONDITION\n" |
| ", b{b}\n" |
| "#else\n" |
| ", c{c}\n" |
| "#endif\n" |
| ", d{d} {\n}", |
| Style); |
| Style.ConstructorInitializerIndentWidth = 4; |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a{a}\n" |
| "#if WINDOWS\n" |
| "#if DEBUG\n" |
| " , b{0}\n" |
| "#else\n" |
| " , b{1}\n" |
| "#endif\n" |
| "#else\n" |
| "#if DEBUG\n" |
| " , b{2}\n" |
| "#else\n" |
| " , b{3}\n" |
| "#endif\n" |
| "#endif\n" |
| "{\n}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a{a}\n" |
| "#if WINDOWS\n" |
| " , b{0}\n" |
| "#if DEBUG\n" |
| " , c{0}\n" |
| "#else\n" |
| " , c{1}\n" |
| "#endif\n" |
| "#else\n" |
| "#if DEBUG\n" |
| " , c{2}\n" |
| "#else\n" |
| " , c{3}\n" |
| "#endif\n" |
| " , b{1}\n" |
| "#endif\n" |
| "{\n}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, Destructors) { |
| verifyFormat("void F(int &i) { i.~int(); }"); |
| verifyFormat("void F(int &i) { i->~int(); }"); |
| } |
| |
| TEST_F(FormatTest, FormatsWithWebKitStyle) { |
| FormatStyle Style = getWebKitStyle(); |
| |
| // Don't indent in outer namespaces. |
| verifyFormat("namespace outer {\n" |
| "int i;\n" |
| "namespace inner {\n" |
| " int i;\n" |
| "} // namespace inner\n" |
| "} // namespace outer\n" |
| "namespace other_outer {\n" |
| "int i;\n" |
| "}", |
| Style); |
| |
| // Don't indent case labels. |
| verifyFormat("switch (variable) {\n" |
| "case 1:\n" |
| "case 2:\n" |
| " doSomething();\n" |
| " break;\n" |
| "default:\n" |
| " ++variable;\n" |
| "}", |
| Style); |
| |
| // Wrap before binary operators. |
| EXPECT_EQ("void f()\n" |
| "{\n" |
| " if (aaaaaaaaaaaaaaaa\n" |
| " && bbbbbbbbbbbbbbbbbbbbbbbb\n" |
| " && (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" |
| " return;\n" |
| "}", |
| format("void f() {\n" |
| "if (aaaaaaaaaaaaaaaa\n" |
| "&& bbbbbbbbbbbbbbbbbbbbbbbb\n" |
| "&& (cccccccccccccccccccccccccc || dddddddddddddddddddd))\n" |
| "return;\n" |
| "}", |
| Style)); |
| |
| // Allow functions on a single line. |
| verifyFormat("void f() { return; }", Style); |
| |
| // Allow empty blocks on a single line and insert a space in empty blocks. |
| EXPECT_EQ("void f() { }", format("void f() {}", Style)); |
| EXPECT_EQ("while (true) { }", format("while (true) {}", Style)); |
| // However, don't merge non-empty short loops. |
| EXPECT_EQ("while (true) {\n" |
| " continue;\n" |
| "}", |
| format("while (true) { continue; }", Style)); |
| |
| // Constructor initializers are formatted one per line with the "," on the |
| // new line. |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" |
| " , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n" |
| " aaaaaaaaaaaaaa)\n" |
| " , aaaaaaaaaaaaaaaaaaaaaaa()\n" |
| "{\n" |
| "}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| "{\n" |
| "}", |
| Style); |
| EXPECT_EQ("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| "{\n" |
| "}", |
| format("SomeClass::Constructor():a(a){}", Style)); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| " , b(b)\n" |
| " , c(c)\n" |
| "{\n" |
| "}", |
| Style); |
| verifyFormat("SomeClass::Constructor()\n" |
| " : a(a)\n" |
| "{\n" |
| " foo();\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| // Access specifiers should be aligned left. |
| verifyFormat("class C {\n" |
| "public:\n" |
| " int i;\n" |
| "};", |
| Style); |
| |
| // Do not align comments. |
| verifyFormat("int a; // Do not\n" |
| "double b; // align comments.", |
| Style); |
| |
| // Do not align operands. |
| EXPECT_EQ("ASSERT(aaaa\n" |
| " || bbbb);", |
| format("ASSERT ( aaaa\n||bbbb);", Style)); |
| |
| // Accept input's line breaks. |
| EXPECT_EQ("if (aaaaaaaaaaaaaaa\n" |
| " || bbbbbbbbbbbbbbb) {\n" |
| " i++;\n" |
| "}", |
| format("if (aaaaaaaaaaaaaaa\n" |
| "|| bbbbbbbbbbbbbbb) { i++; }", |
| Style)); |
| EXPECT_EQ("if (aaaaaaaaaaaaaaa || bbbbbbbbbbbbbbb) {\n" |
| " i++;\n" |
| "}", |
| format("if (aaaaaaaaaaaaaaa || bbbbbbbbbbbbbbb) { i++; }", Style)); |
| |
| // Don't automatically break all macro definitions (llvm.org/PR17842). |
| verifyFormat("#define aNumber 10", Style); |
| // However, generally keep the line breaks that the user authored. |
| EXPECT_EQ("#define aNumber \\\n" |
| " 10", |
| format("#define aNumber \\\n" |
| " 10", |
| Style)); |
| |
| // Keep empty and one-element array literals on a single line. |
| EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[]\n" |
| " copyItems:YES];", |
| format("NSArray*a=[[NSArray alloc] initWithArray:@[]\n" |
| "copyItems:YES];", |
| Style)); |
| EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\" ]\n" |
| " copyItems:YES];", |
| format("NSArray*a=[[NSArray alloc]initWithArray:@[ @\"a\" ]\n" |
| " copyItems:YES];", |
| Style)); |
| // FIXME: This does not seem right, there should be more indentation before |
| // the array literal's entries. Nested blocks have the same problem. |
| EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[\n" |
| " @\"a\",\n" |
| " @\"a\"\n" |
| "]\n" |
| " copyItems:YES];", |
| format("NSArray* a = [[NSArray alloc] initWithArray:@[\n" |
| " @\"a\",\n" |
| " @\"a\"\n" |
| " ]\n" |
| " copyItems:YES];", |
| Style)); |
| EXPECT_EQ( |
| "NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n" |
| " copyItems:YES];", |
| format("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n" |
| " copyItems:YES];", |
| Style)); |
| |
| verifyFormat("[self.a b:c c:d];", Style); |
| EXPECT_EQ("[self.a b:c\n" |
| " c:d];", |
| format("[self.a b:c\n" |
| "c:d];", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, FormatsLambdas) { |
| verifyFormat("int c = [b]() mutable { return [&b] { return b++; }(); }();\n"); |
| verifyFormat( |
| "int c = [b]() mutable noexcept { return [&b] { return b++; }(); }();\n"); |
| verifyFormat("int c = [&] { [=] { return b++; }(); }();\n"); |
| verifyFormat("int c = [&, &a, a] { [=, c, &d] { return b++; }(); }();\n"); |
| verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n"); |
| verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n"); |
| verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n"); |
| verifyFormat("auto c = [a = [b = 42] {}] {};\n"); |
| verifyFormat("auto c = [a = &i + 10, b = [] {}] {};\n"); |
| verifyFormat("int x = f(*+[] {});"); |
| verifyFormat("void f() {\n" |
| " other(x.begin(), x.end(), [&](int, int) { return 1; });\n" |
| "}\n"); |
| verifyFormat("void f() {\n" |
| " other(x.begin(), //\n" |
| " x.end(), //\n" |
| " [&](int, int) { return 1; });\n" |
| "}\n"); |
| verifyFormat("void f() {\n" |
| " other.other.other.other.other(\n" |
| " x.begin(), x.end(),\n" |
| " [something, rather](int, int, int, int, int, int, int) { " |
| "return 1; });\n" |
| "}\n"); |
| verifyFormat( |
| "void f() {\n" |
| " other.other.other.other.other(\n" |
| " x.begin(), x.end(),\n" |
| " [something, rather](int, int, int, int, int, int, int) {\n" |
| " //\n" |
| " });\n" |
| "}\n"); |
| verifyFormat("SomeFunction([]() { // A cool function...\n" |
| " return 43;\n" |
| "});"); |
| EXPECT_EQ("SomeFunction([]() {\n" |
| "#define A a\n" |
| " return 43;\n" |
| "});", |
| format("SomeFunction([](){\n" |
| "#define A a\n" |
| "return 43;\n" |
| "});")); |
| verifyFormat("void f() {\n" |
| " SomeFunction([](decltype(x), A *a) {});\n" |
| " SomeFunction([](typeof(x), A *a) {});\n" |
| " SomeFunction([](_Atomic(x), A *a) {});\n" |
| " SomeFunction([](__underlying_type(x), A *a) {});\n" |
| "}"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " [](const aaaaaaaaaa &a) { return a; });"); |
| verifyFormat("string abc = SomeFunction(aaaaaaaaaaaaa, aaaaa, []() {\n" |
| " SomeOtherFunctioooooooooooooooooooooooooon();\n" |
| "});"); |
| verifyFormat("Constructor()\n" |
| " : Field([] { // comment\n" |
| " int i;\n" |
| " }) {}"); |
| verifyFormat("auto my_lambda = [](const string &some_parameter) {\n" |
| " return some_parameter.size();\n" |
| "};"); |
| verifyFormat("std::function<std::string(const std::string &)> my_lambda =\n" |
| " [](const string &s) { return s; };"); |
| verifyFormat("int i = aaaaaa ? 1 //\n" |
| " : [] {\n" |
| " return 2; //\n" |
| " }();"); |
| verifyFormat("llvm::errs() << \"number of twos is \"\n" |
| " << std::count_if(v.begin(), v.end(), [](int x) {\n" |
| " return x == 2; // force break\n" |
| " });"); |
| verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " [=](int iiiiiiiiiiii) {\n" |
| " return aaaaaaaaaaaaaaaaaaaaaaa !=\n" |
| " aaaaaaaaaaaaaaaaaaaaaaa;\n" |
| " });", |
| getLLVMStyleWithColumns(60)); |
| |
| verifyFormat("SomeFunction({[&] {\n" |
| " // comment\n" |
| " },\n" |
| " [&] {\n" |
| " // comment\n" |
| " }});"); |
| verifyFormat("SomeFunction({[&] {\n" |
| " // comment\n" |
| "}});"); |
| verifyFormat( |
| "virtual aaaaaaaaaaaaaaaa(\n" |
| " std::function<bool()> bbbbbbbbbbbb = [&]() { return true; },\n" |
| " aaaaa aaaaaaaaa);"); |
| |
| // Lambdas with return types. |
| verifyFormat("int c = []() -> int { return 2; }();\n"); |
| verifyFormat("int c = []() -> int * { return 2; }();\n"); |
| verifyFormat("int c = []() -> vector<int> { return {2}; }();\n"); |
| verifyFormat("Foo([]() -> std::vector<int> { return {2}; }());"); |
| verifyFormat("foo([]() noexcept -> int {});"); |
| verifyGoogleFormat("auto a = [&b, c](D* d) -> D* {};"); |
| verifyGoogleFormat("auto a = [&b, c](D* d) -> pair<D*, D*> {};"); |
| verifyGoogleFormat("auto a = [&b, c](D* d) -> D& {};"); |
| verifyGoogleFormat("auto a = [&b, c](D* d) -> const D* {};"); |
| verifyFormat("[a, a]() -> a<1> {};"); |
| verifyFormat("[]() -> foo<5 + 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 - 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 / 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 * 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 % 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 << 2> { return {}; };"); |
| verifyFormat("[]() -> foo<!5> { return {}; };"); |
| verifyFormat("[]() -> foo<~5> { return {}; };"); |
| verifyFormat("[]() -> foo<5 | 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 || 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 & 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 && 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 == 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 != 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 >= 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 <= 2> { return {}; };"); |
| verifyFormat("[]() -> foo<5 < 2> { return {}; };"); |
| verifyFormat("[]() -> foo<2 ? 1 : 0> { return {}; };"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 + 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 - 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 / 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 * 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 % 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 << 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<!5> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<~5> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 | 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 || 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 & 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 && 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 == 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 != 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 >= 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 <= 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<5 < 2> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("namespace bar {\n" |
| "// broken:\n" |
| "auto foo{[]() -> foo<2 ? 1 : 0> { return {}; }};\n" |
| "} // namespace bar"); |
| verifyFormat("[]() -> a<1> {};"); |
| verifyFormat("[]() -> a<1> { ; };"); |
| verifyFormat("[]() -> a<1> { ; }();"); |
| verifyFormat("[a, a]() -> a<true> {};"); |
| verifyFormat("[]() -> a<true> {};"); |
| verifyFormat("[]() -> a<true> { ; };"); |
| verifyFormat("[]() -> a<true> { ; }();"); |
| verifyFormat("[a, a]() -> a<false> {};"); |
| verifyFormat("[]() -> a<false> {};"); |
| verifyFormat("[]() -> a<false> { ; };"); |
| verifyFormat("[]() -> a<false> { ; }();"); |
| verifyFormat("auto foo{[]() -> foo<false> { ; }};"); |
| verifyFormat("namespace bar {\n" |
| "auto foo{[]() -> foo<false> { ; }};\n" |
| "} // namespace bar"); |
| verifyFormat("auto aaaaaaaa = [](int i, // break for some reason\n" |
| " int j) -> int {\n" |
| " return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n" |
| "};"); |
| verifyFormat( |
| "aaaaaaaaaaaaaaaaaaaaaa(\n" |
| " [](aaaaaaaaaaaaaaaaaaaaaaaaaaa &aaa) -> aaaaaaaaaaaaaaaa {\n" |
| " return aaaaaaaaaaaaaaaaa;\n" |
| " });", |
| getLLVMStyleWithColumns(70)); |
| verifyFormat("[]() //\n" |
| " -> int {\n" |
| " return 1; //\n" |
| "};"); |
| verifyFormat("[]() -> Void<T...> {};"); |
| verifyFormat("[a, b]() -> Tuple<T...> { return {}; };"); |
| verifyFormat("SomeFunction({[]() -> int[] { return {}; }});"); |
| verifyFormat("SomeFunction({[]() -> int *[] { return {}; }});"); |
| verifyFormat("SomeFunction({[]() -> int (*)[] { return {}; }});"); |
| verifyFormat("SomeFunction({[]() -> ns::type<int (*)[]> { return {}; }});"); |
| verifyFormat("return int{[x = x]() { return x; }()};"); |
| |
| // Lambdas with explicit template argument lists. |
| verifyFormat( |
| "auto L = []<template <typename> class T, class U>(T<U> &&a) {};\n"); |
| verifyFormat("auto L = []<class T>(T) {\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("auto L = []<class... T>(T...) {\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("auto L = []<typename... T>(T...) {\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("auto L = []<template <typename...> class T>(T...) {\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| "};\n"); |
| verifyFormat("auto L = []</*comment*/ class... T>(T...) {\n" |
| " {\n" |
| " f();\n" |
| " g();\n" |
| " }\n" |
| "};\n"); |
| |
| // Multiple lambdas in the same parentheses change indentation rules. These |
| // lambdas are forced to start on new lines. |
| verifyFormat("SomeFunction(\n" |
| " []() {\n" |
| " //\n" |
| " },\n" |
| " []() {\n" |
| " //\n" |
| " });"); |
| |
| // A lambda passed as arg0 is always pushed to the next line. |
| verifyFormat("SomeFunction(\n" |
| " [this] {\n" |
| " //\n" |
| " },\n" |
| " 1);\n"); |
| |
| // A multi-line lambda passed as arg1 forces arg0 to be pushed out, just like |
| // the arg0 case above. |
| auto Style = getGoogleStyle(); |
| Style.BinPackArguments = false; |
| verifyFormat("SomeFunction(\n" |
| " a,\n" |
| " [this] {\n" |
| " //\n" |
| " },\n" |
| " b);\n", |
| Style); |
| verifyFormat("SomeFunction(\n" |
| " a,\n" |
| " [this] {\n" |
| " //\n" |
| " },\n" |
| " b);\n"); |
| |
| // A lambda with a very long line forces arg0 to be pushed out irrespective of |
| // the BinPackArguments value (as long as the code is wide enough). |
| verifyFormat( |
| "something->SomeFunction(\n" |
| " a,\n" |
| " [this] {\n" |
| " " |
| "D0000000000000000000000000000000000000000000000000000000000001();\n" |
| " },\n" |
| " b);\n"); |
| |
| // A multi-line lambda is pulled up as long as the introducer fits on the |
| // previous line and there are no further args. |
| verifyFormat("function(1, [this, that] {\n" |
| " //\n" |
| "});\n"); |
| verifyFormat("function([this, that] {\n" |
| " //\n" |
| "});\n"); |
| // FIXME: this format is not ideal and we should consider forcing the first |
| // arg onto its own line. |
| verifyFormat("function(a, b, c, //\n" |
| " d, [this, that] {\n" |
| " //\n" |
| " });\n"); |
| |
| // Multiple lambdas are treated correctly even when there is a short arg0. |
| verifyFormat("SomeFunction(\n" |
| " 1,\n" |
| " [this] {\n" |
| " //\n" |
| " },\n" |
| " [this] {\n" |
| " //\n" |
| " },\n" |
| " 1);\n"); |
| |
| // More complex introducers. |
| verifyFormat("return [i, args...] {};"); |
| |
| // Not lambdas. |
| verifyFormat("constexpr char hello[]{\"hello\"};"); |
| verifyFormat("double &operator[](int i) { return 0; }\n" |
| "int i;"); |
| verifyFormat("std::unique_ptr<int[]> foo() {}"); |
| verifyFormat("int i = a[a][a]->f();"); |
| verifyFormat("int i = (*b)[a]->f();"); |
| |
| // Other corner cases. |
| verifyFormat("void f() {\n" |
| " bar([]() {} // Did not respect SpacesBeforeTrailingComments\n" |
| " );\n" |
| "}"); |
| verifyFormat("auto k = *[](int *j) { return j; }(&i);"); |
| |
| // Lambdas created through weird macros. |
| verifyFormat("void f() {\n" |
| " MACRO((const AA &a) { return 1; });\n" |
| " MACRO((AA &a) { return 1; });\n" |
| "}"); |
| |
| verifyFormat("if (blah_blah(whatever, whatever, [] {\n" |
| " doo_dah();\n" |
| " doo_dah();\n" |
| " })) {\n" |
| "}"); |
| verifyFormat("if constexpr (blah_blah(whatever, whatever, [] {\n" |
| " doo_dah();\n" |
| " doo_dah();\n" |
| " })) {\n" |
| "}"); |
| verifyFormat("if CONSTEXPR (blah_blah(whatever, whatever, [] {\n" |
| " doo_dah();\n" |
| " doo_dah();\n" |
| " })) {\n" |
| "}"); |
| verifyFormat("auto lambda = []() {\n" |
| " int a = 2\n" |
| "#if A\n" |
| " + 2\n" |
| "#endif\n" |
| " ;\n" |
| "};"); |
| |
| // Lambdas with complex multiline introducers. |
| verifyFormat( |
| "aaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]()\n" |
| " -> ::std::unordered_set<\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n" |
| " //\n" |
| " });"); |
| |
| FormatStyle DoNotMerge = getLLVMStyle(); |
| DoNotMerge.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; |
| verifyFormat("auto c = []() {\n" |
| " return b;\n" |
| "};", |
| "auto c = []() { return b; };", DoNotMerge); |
| verifyFormat("auto c = []() {\n" |
| "};", |
| " auto c = []() {};", DoNotMerge); |
| |
| FormatStyle MergeEmptyOnly = getLLVMStyle(); |
| MergeEmptyOnly.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty; |
| verifyFormat("auto c = []() {\n" |
| " return b;\n" |
| "};", |
| "auto c = []() {\n" |
| " return b;\n" |
| " };", |
| MergeEmptyOnly); |
| verifyFormat("auto c = []() {};", |
| "auto c = []() {\n" |
| "};", |
| MergeEmptyOnly); |
| |
| FormatStyle MergeInline = getLLVMStyle(); |
| MergeInline.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Inline; |
| verifyFormat("auto c = []() {\n" |
| " return b;\n" |
| "};", |
| "auto c = []() { return b; };", MergeInline); |
| verifyFormat("function([]() { return b; })", "function([]() { return b; })", |
| MergeInline); |
| verifyFormat("function([]() { return b; }, a)", |
| "function([]() { return b; }, a)", MergeInline); |
| verifyFormat("function(a, []() { return b; })", |
| "function(a, []() { return b; })", MergeInline); |
| |
| // Check option "BraceWrapping.BeforeLambdaBody" and different state of |
| // AllowShortLambdasOnASingleLine |
| FormatStyle LLVMWithBeforeLambdaBody = getLLVMStyle(); |
| LLVMWithBeforeLambdaBody.BreakBeforeBraces = FormatStyle::BS_Custom; |
| LLVMWithBeforeLambdaBody.BraceWrapping.BeforeLambdaBody = true; |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_None; |
| verifyFormat("FctWithOneNestedLambdaInline_SLS_None(\n" |
| " []()\n" |
| " {\n" |
| " return 17;\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdaEmpty_SLS_None(\n" |
| " []()\n" |
| " {\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto fct_SLS_None = []()\n" |
| "{\n" |
| " return 17;\n" |
| "};", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_None(\n" |
| " []()\n" |
| " {\n" |
| " return Call(\n" |
| " []()\n" |
| " {\n" |
| " return 17;\n" |
| " });\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("void Fct() {\n" |
| " return {[]()\n" |
| " {\n" |
| " return 17;\n" |
| " }};\n" |
| "}", |
| LLVMWithBeforeLambdaBody); |
| |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_Empty; |
| verifyFormat("FctWithOneNestedLambdaInline_SLS_Empty(\n" |
| " []()\n" |
| " {\n" |
| " return 17;\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdaEmpty_SLS_Empty([]() {});", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdaEmptyInsideAVeryVeryVeryVeryVeryVeryVeryL" |
| "ongFunctionName_SLS_Empty(\n" |
| " []() {});", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithMultipleParams_SLS_Empty(A, B,\n" |
| " []()\n" |
| " {\n" |
| " return 17;\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto fct_SLS_Empty = []()\n" |
| "{\n" |
| " return 17;\n" |
| "};", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_Empty(\n" |
| " []()\n" |
| " {\n" |
| " return Call([]() {});\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_Empty(A,\n" |
| " []()\n" |
| " {\n" |
| " return Call([]() {});\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_Empty(\n" |
| " []()\n" |
| " {\n" |
| " return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n" |
| " AndShouldNotBeConsiderAsInline,\n" |
| " LambdaBodyMustBeBreak);\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_Inline; |
| verifyFormat("FctWithOneNestedLambdaInline_SLS_Inline([]() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdaEmpty_SLS_Inline([]() {});", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto fct_SLS_Inline = []()\n" |
| "{\n" |
| " return 17;\n" |
| "};", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_Inline([]() { return Call([]() { return " |
| "17; }); });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_Inline(\n" |
| " []()\n" |
| " {\n" |
| " return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n" |
| " AndShouldNotBeConsiderAsInline,\n" |
| " LambdaBodyMustBeBreak);\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithMultipleParams_SLS_Inline(" |
| "VeryLongParameterThatShouldAskToBeOnMultiLine,\n" |
| " []() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithMultipleParams_SLS_Inline(FirstParam, []() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_All; |
| verifyFormat("FctWithOneNestedLambdaInline_SLS_All([]() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdaEmpty_SLS_All([]() {});", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto fct_SLS_All = []() { return 17; };", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneParam_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " // A cool function...\n" |
| " return 43;\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithMultipleParams_SLS_All(" |
| "VeryLongParameterThatShouldAskToBeOnMultiLine,\n" |
| " []() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithMultipleParams_SLS_All(A, []() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithMultipleParams_SLS_All(A, B, []() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n" |
| " AndShouldNotBeConsiderAsInline,\n" |
| " LambdaBodyMustBeBreak);\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "auto fct_SLS_All = []()\n" |
| "{\n" |
| " return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n" |
| " AndShouldNotBeConsiderAsInline,\n" |
| " LambdaBodyMustBeBreak);\n" |
| "};", |
| LLVMWithBeforeLambdaBody); |
| LLVMWithBeforeLambdaBody.BinPackParameters = false; |
| verifyFormat("FctAllOnSameLine_SLS_All([]() { return S; }, Fst, Second);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_All([]() { return SomeValueNotSoLong; },\n" |
| " FirstParam,\n" |
| " SecondParam,\n" |
| " ThirdParam,\n" |
| " FourthParam);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithLongLineInLambda_SLS_All(\n" |
| " []() { return " |
| "SomeValueVeryVeryVeryVeryVeryVeryVeryVeryVeryLong; },\n" |
| " FirstParam,\n" |
| " SecondParam,\n" |
| " ThirdParam,\n" |
| " FourthParam);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_All(FirstParam,\n" |
| " SecondParam,\n" |
| " ThirdParam,\n" |
| " FourthParam,\n" |
| " []() { return SomeValueNotSoLong; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithLongLineInLambda_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " return " |
| "HereAVeryLongLineThatWillBeFormattedOnMultipleLineAndShouldNotB" |
| "eConsiderAsInline;\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "FctWithLongLineInLambda_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " return HereAVeryLongLine(ThatWillBeFormatted, OnMultipleLine,\n" |
| " AndShouldNotBeConsiderAsInline,\n" |
| " LambdaBodyMustBeBreak);\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithTwoParams_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " // A cool function...\n" |
| " return 43;\n" |
| " },\n" |
| " 87);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithTwoParams_SLS_All([]() { return 43; }, 87);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("FctWithOneNestedLambdas_SLS_All([]() { return 17; });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "TwoNestedLambdas_SLS_All([]() { return Call([]() { return 17; }); });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_All([]() { return Call([]() { return 17; " |
| "}); }, x);", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " // A cool function...\n" |
| " return Call([]() { return 17; });\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("TwoNestedLambdas_SLS_All(\n" |
| " []()\n" |
| " {\n" |
| " return Call(\n" |
| " []()\n" |
| " {\n" |
| " // A cool function...\n" |
| " return 17;\n" |
| " });\n" |
| " });", |
| LLVMWithBeforeLambdaBody); |
| |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_None; |
| |
| verifyFormat("auto select = [this]() -> const Library::Object *\n" |
| "{\n" |
| " return MyAssignment::SelectFromList(this);\n" |
| "};\n", |
| LLVMWithBeforeLambdaBody); |
| |
| verifyFormat("auto select = [this]() -> const Library::Object &\n" |
| "{\n" |
| " return MyAssignment::SelectFromList(this);\n" |
| "};\n", |
| LLVMWithBeforeLambdaBody); |
| |
| verifyFormat("auto select = [this]() -> std::unique_ptr<Object>\n" |
| "{\n" |
| " return MyAssignment::SelectFromList(this);\n" |
| "};\n", |
| LLVMWithBeforeLambdaBody); |
| |
| verifyFormat("namespace test {\n" |
| "class Test {\n" |
| "public:\n" |
| " Test() = default;\n" |
| "};\n" |
| "} // namespace test", |
| LLVMWithBeforeLambdaBody); |
| |
| // Lambdas with different indentation styles. |
| Style = getLLVMStyleWithColumns(100); |
| EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then(\n" |
| " [this, &someVariable, someObject = " |
| "std::mv(s)](std::vector<int> evaluated) mutable {\n" |
| " return someObject.startAsyncAction().then(\n" |
| " [this, &someVariable](AsyncActionResult result) " |
| "mutable { result.processMore(); });\n" |
| " });\n" |
| "}\n", |
| format("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then([this, &someVariable, someObject = " |
| "std::mv(s)](std::vector<int> evaluated) mutable {\n" |
| " return someObject.startAsyncAction().then([this, " |
| "&someVariable](AsyncActionResult result) mutable {\n" |
| " result.processMore();\n" |
| " });\n" |
| " });\n" |
| "}\n", |
| Style)); |
| Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope; |
| verifyFormat("test() {\n" |
| " ([]() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " }).foo();\n" |
| "}", |
| Style); |
| verifyFormat("test() {\n" |
| " []() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " }\n" |
| "}", |
| Style); |
| verifyFormat("std::sort(v.begin(), v.end(),\n" |
| " [](const auto &someLongArgumentName, const auto " |
| "&someOtherLongArgumentName) {\n" |
| " return someLongArgumentName.someMemberVariable < " |
| "someOtherLongArgumentName.someMemberVariable;\n" |
| "});", |
| Style); |
| verifyFormat("test() {\n" |
| " (\n" |
| " []() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " },\n" |
| " foo, bar)\n" |
| " .foo();\n" |
| "}", |
| Style); |
| verifyFormat("test() {\n" |
| " ([]() -> {\n" |
| " int b = 32;\n" |
| " return 3;\n" |
| " })\n" |
| " .foo()\n" |
| " .bar();\n" |
| "}", |
| Style); |
| EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then(\n" |
| " [this, &someVariable, someObject = " |
| "std::mv(s)](std::vector<int> evaluated) mutable {\n" |
| " return someObject.startAsyncAction().then(\n" |
| " [this, &someVariable](AsyncActionResult result) mutable { " |
| "result.processMore(); });\n" |
| " });\n" |
| "}\n", |
| format("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then([this, &someVariable, someObject = " |
| "std::mv(s)](std::vector<int> evaluated) mutable {\n" |
| " return someObject.startAsyncAction().then([this, " |
| "&someVariable](AsyncActionResult result) mutable {\n" |
| " result.processMore();\n" |
| " });\n" |
| " });\n" |
| "}\n", |
| Style)); |
| EXPECT_EQ("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then([this, &someVariable] {\n" |
| " return someObject.startAsyncAction().then(\n" |
| " [this, &someVariable](AsyncActionResult result) mutable { " |
| "result.processMore(); });\n" |
| " });\n" |
| "}\n", |
| format("SomeResult doSomething(SomeObject promise) {\n" |
| " return promise.then([this, &someVariable] {\n" |
| " return someObject.startAsyncAction().then([this, " |
| "&someVariable](AsyncActionResult result) mutable {\n" |
| " result.processMore();\n" |
| " });\n" |
| " });\n" |
| "}\n", |
| Style)); |
| Style = getGoogleStyle(); |
| Style.LambdaBodyIndentation = FormatStyle::LBI_OuterScope; |
| EXPECT_EQ("#define A \\\n" |
| " [] { \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); \\\n" |
| " }", |
| format("#define A [] { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx( \\\n" |
| "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx); }", |
| Style)); |
| // TODO: The current formatting has a minor issue that's not worth fixing |
| // right now whereby the closing brace is indented relative to the signature |
| // instead of being aligned. This only happens with macros. |
| } |
| |
| TEST_F(FormatTest, LambdaWithLineComments) { |
| FormatStyle LLVMWithBeforeLambdaBody = getLLVMStyle(); |
| LLVMWithBeforeLambdaBody.BreakBeforeBraces = FormatStyle::BS_Custom; |
| LLVMWithBeforeLambdaBody.BraceWrapping.BeforeLambdaBody = true; |
| LLVMWithBeforeLambdaBody.AllowShortLambdasOnASingleLine = |
| FormatStyle::ShortLambdaStyle::SLS_All; |
| |
| verifyFormat("auto k = []() { return; }", LLVMWithBeforeLambdaBody); |
| verifyFormat("auto k = []() // comment\n" |
| "{ return; }", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto k = []() /* comment */ { return; }", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto k = []() /* comment */ /* comment */ { return; }", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("auto k = []() // X\n" |
| "{ return; }", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat( |
| "auto k = []() // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" |
| "{ return; }", |
| LLVMWithBeforeLambdaBody); |
| |
| LLVMWithBeforeLambdaBody.ColumnLimit = 0; |
| |
| verifyFormat("foo([]()\n" |
| " {\n" |
| " bar(); //\n" |
| " return 1; // comment\n" |
| " }());", |
| "foo([]() {\n" |
| " bar(); //\n" |
| " return 1; // comment\n" |
| "}());", |
| LLVMWithBeforeLambdaBody); |
| verifyFormat("foo(\n" |
| " 1, MACRO {\n" |
| " baz();\n" |
| " bar(); // comment\n" |
| " },\n" |
| " []() {});", |
| "foo(\n" |
| " 1, MACRO { baz(); bar(); // comment\n" |
| " }, []() {}\n" |
| ");", |
| LLVMWithBeforeLambdaBody); |
| } |
| |
| TEST_F(FormatTest, EmptyLinesInLambdas) { |
| verifyFormat("auto lambda = []() {\n" |
| " x(); //\n" |
| "};", |
| "auto lambda = []() {\n" |
| "\n" |
| " x(); //\n" |
| "\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, FormatsBlocks) { |
| FormatStyle ShortBlocks = getLLVMStyle(); |
| ShortBlocks.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; |
| verifyFormat("int (^Block)(int, int);", ShortBlocks); |
| verifyFormat("int (^Block1)(int, int) = ^(int i, int j)", ShortBlocks); |
| verifyFormat("void (^block)(int) = ^(id test) { int i; };", ShortBlocks); |
| verifyFormat("void (^block)(int) = ^(int test) { int i; };", ShortBlocks); |
| verifyFormat("void (^block)(int) = ^id(int test) { int i; };", ShortBlocks); |
| verifyFormat("void (^block)(int) = ^int(int test) { int i; };", ShortBlocks); |
| |
| verifyFormat("foo(^{ bar(); });", ShortBlocks); |
| verifyFormat("foo(a, ^{ bar(); });", ShortBlocks); |
| verifyFormat("{ void (^block)(Object *x); }", ShortBlocks); |
| |
| verifyFormat("[operation setCompletionBlock:^{\n" |
| " [self onOperationDone];\n" |
| "}];"); |
| verifyFormat("int i = {[operation setCompletionBlock:^{\n" |
| " [self onOperationDone];\n" |
| "}]};"); |
| verifyFormat("[operation setCompletionBlock:^(int *i) {\n" |
| " f();\n" |
| "}];"); |
| verifyFormat("int a = [operation block:^int(int *i) {\n" |
| " return 1;\n" |
| "}];"); |
| verifyFormat("[myObject doSomethingWith:arg1\n" |
| " aaa:^int(int *a) {\n" |
| " return 1;\n" |
| " }\n" |
| " bbb:f(a * bbbbbbbb)];"); |
| |
| verifyFormat("[operation setCompletionBlock:^{\n" |
| " [self.delegate newDataAvailable];\n" |
| "}];", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("dispatch_async(_fileIOQueue, ^{\n" |
| " NSString *path = [self sessionFilePath];\n" |
| " if (path) {\n" |
| " // ...\n" |
| " }\n" |
| "});"); |
| verifyFormat("[[SessionService sharedService]\n" |
| " loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" |
| " if (window) {\n" |
| " [self windowDidLoad:window];\n" |
| " } else {\n" |
| " [self errorLoadingWindow];\n" |
| " }\n" |
| " }];"); |
| verifyFormat("void (^largeBlock)(void) = ^{\n" |
| " // ...\n" |
| "};\n", |
| getLLVMStyleWithColumns(40)); |
| verifyFormat("[[SessionService sharedService]\n" |
| " loadWindowWithCompletionBlock: //\n" |
| " ^(SessionWindow *window) {\n" |
| " if (window) {\n" |
| " [self windowDidLoad:window];\n" |
| " } else {\n" |
| " [self errorLoadingWindow];\n" |
| " }\n" |
| " }];", |
| getLLVMStyleWithColumns(60)); |
| verifyFormat("[myObject doSomethingWith:arg1\n" |
| " firstBlock:^(Foo *a) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }\n" |
| " secondBlock:^(Bar *b) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }\n" |
| " thirdBlock:^Foo(Bar *b) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }];"); |
| verifyFormat("[myObject doSomethingWith:arg1\n" |
| " firstBlock:-1\n" |
| " secondBlock:^(Bar *b) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }];"); |
| |
| verifyFormat("f(^{\n" |
| " @autoreleasepool {\n" |
| " if (a) {\n" |
| " g();\n" |
| " }\n" |
| " }\n" |
| "});"); |
| verifyFormat("Block b = ^int *(A *a, B *b) {}"); |
| verifyFormat("BOOL (^aaa)(void) = ^BOOL {\n" |
| "};"); |
| |
| FormatStyle FourIndent = getLLVMStyle(); |
| FourIndent.ObjCBlockIndentWidth = 4; |
| verifyFormat("[operation setCompletionBlock:^{\n" |
| " [self onOperationDone];\n" |
| "}];", |
| FourIndent); |
| } |
| |
| TEST_F(FormatTest, FormatsBlocksWithZeroColumnWidth) { |
| FormatStyle ZeroColumn = getLLVMStyleWithColumns(0); |
| |
| verifyFormat("[[SessionService sharedService] " |
| "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" |
| " if (window) {\n" |
| " [self windowDidLoad:window];\n" |
| " } else {\n" |
| " [self errorLoadingWindow];\n" |
| " }\n" |
| "}];", |
| ZeroColumn); |
| EXPECT_EQ("[[SessionService sharedService]\n" |
| " loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" |
| " if (window) {\n" |
| " [self windowDidLoad:window];\n" |
| " } else {\n" |
| " [self errorLoadingWindow];\n" |
| " }\n" |
| " }];", |
| format("[[SessionService sharedService]\n" |
| "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n" |
| " if (window) {\n" |
| " [self windowDidLoad:window];\n" |
| " } else {\n" |
| " [self errorLoadingWindow];\n" |
| " }\n" |
| "}];", |
| ZeroColumn)); |
| verifyFormat("[myObject doSomethingWith:arg1\n" |
| " firstBlock:^(Foo *a) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }\n" |
| " secondBlock:^(Bar *b) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }\n" |
| " thirdBlock:^Foo(Bar *b) {\n" |
| " // ...\n" |
| " int i;\n" |
| " }];", |
| ZeroColumn); |
| verifyFormat("f(^{\n" |
| " @autoreleasepool {\n" |
| " if (a) {\n" |
| " g();\n" |
| " }\n" |
| " }\n" |
| "});", |
| ZeroColumn); |
| verifyFormat("void (^largeBlock)(void) = ^{\n" |
| " // ...\n" |
| "};", |
| ZeroColumn); |
| |
| ZeroColumn.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always; |
| EXPECT_EQ("void (^largeBlock)(void) = ^{ int i; };", |
| format("void (^largeBlock)(void) = ^{ int i; };", ZeroColumn)); |
| ZeroColumn.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; |
| EXPECT_EQ("void (^largeBlock)(void) = ^{\n" |
| " int i;\n" |
| "};", |
| format("void (^largeBlock)(void) = ^{ int i; };", ZeroColumn)); |
| } |
| |
| TEST_F(FormatTest, SupportsCRLF) { |
| EXPECT_EQ("int a;\r\n" |
| "int b;\r\n" |
| "int c;\r\n", |
| format("int a;\r\n" |
| " int b;\r\n" |
| " int c;\r\n", |
| getLLVMStyle())); |
| EXPECT_EQ("int a;\r\n" |
| "int b;\r\n" |
| "int c;\r\n", |
| format("int a;\r\n" |
| " int b;\n" |
| " int c;\r\n", |
| getLLVMStyle())); |
| EXPECT_EQ("int a;\n" |
| "int b;\n" |
| "int c;\n", |
| format("int a;\r\n" |
| " int b;\n" |
| " int c;\n", |
| getLLVMStyle())); |
| EXPECT_EQ("\"aaaaaaa \"\r\n" |
| "\"bbbbbbb\";\r\n", |
| format("\"aaaaaaa bbbbbbb\";\r\n", getLLVMStyleWithColumns(10))); |
| EXPECT_EQ("#define A \\\r\n" |
| " b; \\\r\n" |
| " c; \\\r\n" |
| " d;\r\n", |
| format("#define A \\\r\n" |
| " b; \\\r\n" |
| " c; d; \r\n", |
| getGoogleStyle())); |
| |
| EXPECT_EQ("/*\r\n" |
| "multi line block comments\r\n" |
| "should not introduce\r\n" |
| "an extra carriage return\r\n" |
| "*/\r\n", |
| format("/*\r\n" |
| "multi line block comments\r\n" |
| "should not introduce\r\n" |
| "an extra carriage return\r\n" |
| "*/\r\n")); |
| EXPECT_EQ("/*\r\n" |
| "\r\n" |
| "*/", |
| format("/*\r\n" |
| " \r\r\r\n" |
| "*/")); |
| |
| FormatStyle style = getLLVMStyle(); |
| |
| style.DeriveLineEnding = true; |
| style.UseCRLF = false; |
| EXPECT_EQ("union FooBarBazQux {\n" |
| " int foo;\n" |
| " int bar;\n" |
| " int baz;\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| "};", |
| style)); |
| style.UseCRLF = true; |
| EXPECT_EQ("union FooBarBazQux {\r\n" |
| " int foo;\r\n" |
| " int bar;\r\n" |
| " int baz;\r\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| "};", |
| style)); |
| |
| style.DeriveLineEnding = false; |
| style.UseCRLF = false; |
| EXPECT_EQ("union FooBarBazQux {\n" |
| " int foo;\n" |
| " int bar;\n" |
| " int baz;\n" |
| " int qux;\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| " int qux;\r\n" |
| "};", |
| style)); |
| style.UseCRLF = true; |
| EXPECT_EQ("union FooBarBazQux {\r\n" |
| " int foo;\r\n" |
| " int bar;\r\n" |
| " int baz;\r\n" |
| " int qux;\r\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| " int qux;\n" |
| "};", |
| style)); |
| |
| style.DeriveLineEnding = true; |
| style.UseCRLF = false; |
| EXPECT_EQ("union FooBarBazQux {\r\n" |
| " int foo;\r\n" |
| " int bar;\r\n" |
| " int baz;\r\n" |
| " int qux;\r\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| " int qux;\r\n" |
| "};", |
| style)); |
| style.UseCRLF = true; |
| EXPECT_EQ("union FooBarBazQux {\n" |
| " int foo;\n" |
| " int bar;\n" |
| " int baz;\n" |
| " int qux;\n" |
| "};", |
| format("union FooBarBazQux {\r\n" |
| " int foo;\n" |
| " int bar;\r\n" |
| " int baz;\n" |
| " int qux;\n" |
| "};", |
| style)); |
| } |
| |
| TEST_F(FormatTest, MunchSemicolonAfterBlocks) { |
| verifyFormat("MY_CLASS(C) {\n" |
| " int i;\n" |
| " int j;\n" |
| "};"); |
| } |
| |
| TEST_F(FormatTest, ConfigurableContinuationIndentWidth) { |
| FormatStyle TwoIndent = getLLVMStyleWithColumns(15); |
| TwoIndent.ContinuationIndentWidth = 2; |
| |
| EXPECT_EQ("int i =\n" |
| " longFunction(\n" |
| " arg);", |
| format("int i = longFunction(arg);", TwoIndent)); |
| |
| FormatStyle SixIndent = getLLVMStyleWithColumns(20); |
| SixIndent.ContinuationIndentWidth = 6; |
| |
| EXPECT_EQ("int i =\n" |
| " longFunction(\n" |
| " arg);", |
| format("int i = longFunction(arg);", SixIndent)); |
| } |
| |
| TEST_F(FormatTest, WrappedClosingParenthesisIndent) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("int Foo::getter(\n" |
| " //\n" |
| ") const {\n" |
| " return foo;\n" |
| "}", |
| Style); |
| verifyFormat("void Foo::setter(\n" |
| " //\n" |
| ") {\n" |
| " foo = 1;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, SpacesInAngles) { |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Always; |
| |
| verifyFormat("vector< ::std::string > x1;", Spaces); |
| verifyFormat("Foo< int, Bar > x2;", Spaces); |
| verifyFormat("Foo< ::int, ::Bar > x3;", Spaces); |
| |
| verifyFormat("static_cast< int >(arg);", Spaces); |
| verifyFormat("template < typename T0, typename T1 > void f() {}", Spaces); |
| verifyFormat("f< int, float >();", Spaces); |
| verifyFormat("template <> g() {}", Spaces); |
| verifyFormat("template < std::vector< int > > f() {}", Spaces); |
| verifyFormat("std::function< void(int, int) > fct;", Spaces); |
| verifyFormat("void inFunction() { std::function< void(int, int) > fct; }", |
| Spaces); |
| |
| Spaces.Standard = FormatStyle::LS_Cpp03; |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Always; |
| verifyFormat("A< A< int > >();", Spaces); |
| |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Never; |
| verifyFormat("A<A<int> >();", Spaces); |
| |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Leave; |
| verifyFormat("vector< ::std::string> x4;", "vector<::std::string> x4;", |
| Spaces); |
| verifyFormat("vector< ::std::string > x4;", "vector<::std::string > x4;", |
| Spaces); |
| |
| verifyFormat("A<A<int> >();", Spaces); |
| verifyFormat("A<A<int> >();", "A<A<int>>();", Spaces); |
| verifyFormat("A< A< int > >();", Spaces); |
| |
| Spaces.Standard = FormatStyle::LS_Cpp11; |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Always; |
| verifyFormat("A< A< int > >();", Spaces); |
| |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Never; |
| verifyFormat("vector<::std::string> x4;", Spaces); |
| verifyFormat("vector<int> x5;", Spaces); |
| verifyFormat("Foo<int, Bar> x6;", Spaces); |
| verifyFormat("Foo<::int, ::Bar> x7;", Spaces); |
| |
| verifyFormat("A<A<int>>();", Spaces); |
| |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Leave; |
| verifyFormat("vector<::std::string> x4;", Spaces); |
| verifyFormat("vector< ::std::string > x4;", Spaces); |
| verifyFormat("vector<int> x5;", Spaces); |
| verifyFormat("vector< int > x5;", Spaces); |
| verifyFormat("Foo<int, Bar> x6;", Spaces); |
| verifyFormat("Foo< int, Bar > x6;", Spaces); |
| verifyFormat("Foo<::int, ::Bar> x7;", Spaces); |
| verifyFormat("Foo< ::int, ::Bar > x7;", Spaces); |
| |
| verifyFormat("A<A<int>>();", Spaces); |
| verifyFormat("A< A< int > >();", Spaces); |
| verifyFormat("A<A<int > >();", Spaces); |
| verifyFormat("A< A< int>>();", Spaces); |
| |
| Spaces.SpacesInAngles = FormatStyle::SIAS_Always; |
| verifyFormat("// clang-format off\n" |
| "foo<<<1, 1>>>();\n" |
| "// clang-format on\n", |
| Spaces); |
| verifyFormat("// clang-format off\n" |
| "foo< < <1, 1> > >();\n" |
| "// clang-format on\n", |
| Spaces); |
| } |
| |
| TEST_F(FormatTest, SpaceAfterTemplateKeyword) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.SpaceAfterTemplateKeyword = false; |
| verifyFormat("template<int> void foo();", Style); |
| } |
| |
| TEST_F(FormatTest, TripleAngleBrackets) { |
| verifyFormat("f<<<1, 1>>>();"); |
| verifyFormat("f<<<1, 1, 1, s>>>();"); |
| verifyFormat("f<<<a, b, c, d>>>();"); |
| EXPECT_EQ("f<<<1, 1>>>();", format("f <<< 1, 1 >>> ();")); |
| verifyFormat("f<param><<<1, 1>>>();"); |
| verifyFormat("f<1><<<1, 1>>>();"); |
| EXPECT_EQ("f<param><<<1, 1>>>();", format("f< param > <<< 1, 1 >>> ();")); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" |
| "aaaaaaaaaaa<<<\n 1, 1>>>();"); |
| verifyFormat("aaaaaaaaaaaaaaa<aaaaaaaaa, aaaaaaaaaa, aaaaaaaaaaaaaa>\n" |
| " <<<aaaaaaaaa, aaaaaaaaaa, aaaaaaaaaaaaaaaaaa>>>();"); |
| } |
| |
| TEST_F(FormatTest, MergeLessLessAtEnd) { |
| verifyFormat("<<"); |
| EXPECT_EQ("< < <", format("\\\n<<<")); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" |
| "aaallvm::outs() <<"); |
| verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" |
| "aaaallvm::outs()\n <<"); |
| } |
| |
| TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) { |
| std::string code = "#if A\n" |
| "#if B\n" |
| "a.\n" |
| "#endif\n" |
| " a = 1;\n" |
| "#else\n" |
| "#endif\n" |
| "#if C\n" |
| "#else\n" |
| "#endif\n"; |
| EXPECT_EQ(code, format(code)); |
| } |
| |
| TEST_F(FormatTest, HandleConflictMarkers) { |
| // Git/SVN conflict markers. |
| EXPECT_EQ("int a;\n" |
| "void f() {\n" |
| " callme(some(parameter1,\n" |
| "<<<<<<< text by the vcs\n" |
| " parameter2),\n" |
| "||||||| text by the vcs\n" |
| " parameter2),\n" |
| " parameter3,\n" |
| "======= text by the vcs\n" |
| " parameter2, parameter3),\n" |
| ">>>>>>> text by the vcs\n" |
| " otherparameter);\n", |
| format("int a;\n" |
| "void f() {\n" |
| " callme(some(parameter1,\n" |
| "<<<<<<< text by the vcs\n" |
| " parameter2),\n" |
| "||||||| text by the vcs\n" |
| " parameter2),\n" |
| " parameter3,\n" |
| "======= text by the vcs\n" |
| " parameter2,\n" |
| " parameter3),\n" |
| ">>>>>>> text by the vcs\n" |
| " otherparameter);\n")); |
| |
| // Perforce markers. |
| EXPECT_EQ("void f() {\n" |
| " function(\n" |
| ">>>> text by the vcs\n" |
| " parameter,\n" |
| "==== text by the vcs\n" |
| " parameter,\n" |
| "==== text by the vcs\n" |
| " parameter,\n" |
| "<<<< text by the vcs\n" |
| " parameter);\n", |
| format("void f() {\n" |
| " function(\n" |
| ">>>> text by the vcs\n" |
| " parameter,\n" |
| "==== text by the vcs\n" |
| " parameter,\n" |
| "==== text by the vcs\n" |
| " parameter,\n" |
| "<<<< text by the vcs\n" |
| " parameter);\n")); |
| |
| EXPECT_EQ("<<<<<<<\n" |
| "|||||||\n" |
| "=======\n" |
| ">>>>>>>", |
| format("<<<<<<<\n" |
| "|||||||\n" |
| "=======\n" |
| ">>>>>>>")); |
| |
| EXPECT_EQ("<<<<<<<\n" |
| "|||||||\n" |
| "int i;\n" |
| "=======\n" |
| ">>>>>>>", |
| format("<<<<<<<\n" |
| "|||||||\n" |
| "int i;\n" |
| "=======\n" |
| ">>>>>>>")); |
| |
| // FIXME: Handle parsing of macros around conflict markers correctly: |
| EXPECT_EQ("#define Macro \\\n" |
| "<<<<<<<\n" |
| "Something \\\n" |
| "|||||||\n" |
| "Else \\\n" |
| "=======\n" |
| "Other \\\n" |
| ">>>>>>>\n" |
| " End int i;\n", |
| format("#define Macro \\\n" |
| "<<<<<<<\n" |
| " Something \\\n" |
| "|||||||\n" |
| " Else \\\n" |
| "=======\n" |
| " Other \\\n" |
| ">>>>>>>\n" |
| " End\n" |
| "int i;\n")); |
| |
| verifyFormat(R"(==== |
| #ifdef A |
| a |
| #else |
| b |
| #endif |
| )"); |
| } |
| |
| TEST_F(FormatTest, DisableRegions) { |
| EXPECT_EQ("int i;\n" |
| "// clang-format off\n" |
| " int j;\n" |
| "// clang-format on\n" |
| "int k;", |
| format(" int i;\n" |
| " // clang-format off\n" |
| " int j;\n" |
| " // clang-format on\n" |
| " int k;")); |
| EXPECT_EQ("int i;\n" |
| "/* clang-format off */\n" |
| " int j;\n" |
| "/* clang-format on */\n" |
| "int k;", |
| format(" int i;\n" |
| " /* clang-format off */\n" |
| " int j;\n" |
| " /* clang-format on */\n" |
| " int k;")); |
| |
| // Don't reflow comments within disabled regions. |
| EXPECT_EQ("// clang-format off\n" |
| "// long long long long long long line\n" |
| "/* clang-format on */\n" |
| "/* long long long\n" |
| " * long long long\n" |
| " * line */\n" |
| "int i;\n" |
| "/* clang-format off */\n" |
| "/* long long long long long long line */\n", |
| format("// clang-format off\n" |
| "// long long long long long long line\n" |
| "/* clang-format on */\n" |
| "/* long long long long long long line */\n" |
| "int i;\n" |
| "/* clang-format off */\n" |
| "/* long long long long long long line */\n", |
| getLLVMStyleWithColumns(20))); |
| } |
| |
| TEST_F(FormatTest, DoNotCrashOnInvalidInput) { |
| format("? ) ="); |
| verifyNoCrash("#define a\\\n /**/}"); |
| } |
| |
| TEST_F(FormatTest, FormatsTableGenCode) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.Language = FormatStyle::LK_TableGen; |
| verifyFormat("include \"a.td\"\ninclude \"b.td\"", Style); |
| } |
| |
| TEST_F(FormatTest, ArrayOfTemplates) { |
| EXPECT_EQ("auto a = new unique_ptr<int>[10];", |
| format("auto a = new unique_ptr<int > [ 10];")); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInSquareBrackets = true; |
| EXPECT_EQ("auto a = new unique_ptr<int>[ 10 ];", |
| format("auto a = new unique_ptr<int > [10];", Spaces)); |
| } |
| |
| TEST_F(FormatTest, ArrayAsTemplateType) { |
| EXPECT_EQ("auto a = unique_ptr<Foo<Bar>[10]>;", |
| format("auto a = unique_ptr < Foo < Bar>[ 10]> ;")); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInSquareBrackets = true; |
| EXPECT_EQ("auto a = unique_ptr<Foo<Bar>[ 10 ]>;", |
| format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces)); |
| } |
| |
| TEST_F(FormatTest, NoSpaceAfterSuper) { verifyFormat("__super::FooBar();"); } |
| |
| TEST(FormatStyle, GetStyleWithEmptyFileName) { |
| llvm::vfs::InMemoryFileSystem FS; |
| auto Style1 = getStyle("file", "", "Google", "", &FS); |
| ASSERT_TRUE((bool)Style1); |
| ASSERT_EQ(*Style1, getGoogleStyle()); |
| } |
| |
| TEST(FormatStyle, GetStyleOfFile) { |
| llvm::vfs::InMemoryFileSystem FS; |
| // Test 1: format file in the same directory. |
| ASSERT_TRUE( |
| FS.addFile("/a/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM"))); |
| ASSERT_TRUE( |
| FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS); |
| ASSERT_TRUE((bool)Style1); |
| ASSERT_EQ(*Style1, getLLVMStyle()); |
| |
| // Test 2.1: fallback to default. |
| ASSERT_TRUE( |
| FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS); |
| ASSERT_TRUE((bool)Style2); |
| ASSERT_EQ(*Style2, getMozillaStyle()); |
| |
| // Test 2.2: no format on 'none' fallback style. |
| Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS); |
| ASSERT_TRUE((bool)Style2); |
| ASSERT_EQ(*Style2, getNoStyle()); |
| |
| // Test 2.3: format if config is found with no based style while fallback is |
| // 'none'. |
| ASSERT_TRUE(FS.addFile("/b/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2"))); |
| Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS); |
| ASSERT_TRUE((bool)Style2); |
| ASSERT_EQ(*Style2, getLLVMStyle()); |
| |
| // Test 2.4: format if yaml with no based style, while fallback is 'none'. |
| Style2 = getStyle("{}", "a.h", "none", "", &FS); |
| ASSERT_TRUE((bool)Style2); |
| ASSERT_EQ(*Style2, getLLVMStyle()); |
| |
| // Test 3: format file in parent directory. |
| ASSERT_TRUE( |
| FS.addFile("/c/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google"))); |
| ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0, |
| llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS); |
| ASSERT_TRUE((bool)Style3); |
| ASSERT_EQ(*Style3, getGoogleStyle()); |
| |
| // Test 4: error on invalid fallback style |
| auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS); |
| ASSERT_FALSE((bool)Style4); |
| llvm::consumeError(Style4.takeError()); |
| |
| // Test 5: error on invalid yaml on command line |
| auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS); |
| ASSERT_FALSE((bool)Style5); |
| llvm::consumeError(Style5.takeError()); |
| |
| // Test 6: error on invalid style |
| auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS); |
| ASSERT_FALSE((bool)Style6); |
| llvm::consumeError(Style6.takeError()); |
| |
| // Test 7: found config file, error on parsing it |
| ASSERT_TRUE( |
| FS.addFile("/d/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n" |
| "InvalidKey: InvalidValue"))); |
| ASSERT_TRUE( |
| FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style7a = getStyle("file", "/d/.clang-format", "LLVM", "", &FS); |
| ASSERT_FALSE((bool)Style7a); |
| llvm::consumeError(Style7a.takeError()); |
| |
| auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", &FS, true); |
| ASSERT_TRUE((bool)Style7b); |
| |
| // Test 8: inferred per-language defaults apply. |
| auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS); |
| ASSERT_TRUE((bool)StyleTd); |
| ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen)); |
| |
| // Test 9.1.1: overwriting a file style, when no parent file exists with no |
| // fallback style. |
| ASSERT_TRUE(FS.addFile( |
| "/e/sub/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n" |
| "ColumnLimit: 20"))); |
| ASSERT_TRUE(FS.addFile("/e/sub/code.cpp", 0, |
| llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [] { |
| auto Style = getNoStyle(); |
| Style.ColumnLimit = 20; |
| return Style; |
| }()); |
| |
| // Test 9.1.2: propagate more than one level with no parent file. |
| ASSERT_TRUE(FS.addFile("/e/sub/sub/code.cpp", 0, |
| llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| ASSERT_TRUE(FS.addFile("/e/sub/sub/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer( |
| "BasedOnStyle: InheritParentConfig\n" |
| "WhitespaceSensitiveMacros: ['FOO', 'BAR']"))); |
| std::vector<std::string> NonDefaultWhiteSpaceMacros{"FOO", "BAR"}; |
| |
| ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros); |
| Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [&NonDefaultWhiteSpaceMacros] { |
| auto Style = getNoStyle(); |
| Style.ColumnLimit = 20; |
| Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros; |
| return Style; |
| }()); |
| |
| // Test 9.2: with LLVM fallback style |
| Style9 = getStyle("file", "/e/sub/code.cpp", "LLVM", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [] { |
| auto Style = getLLVMStyle(); |
| Style.ColumnLimit = 20; |
| return Style; |
| }()); |
| |
| // Test 9.3: with a parent file |
| ASSERT_TRUE( |
| FS.addFile("/e/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google\n" |
| "UseTab: Always"))); |
| Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [] { |
| auto Style = getGoogleStyle(); |
| Style.ColumnLimit = 20; |
| Style.UseTab = FormatStyle::UT_Always; |
| return Style; |
| }()); |
| |
| // Test 9.4: propagate more than one level with a parent file. |
| const auto SubSubStyle = [&NonDefaultWhiteSpaceMacros] { |
| auto Style = getGoogleStyle(); |
| Style.ColumnLimit = 20; |
| Style.UseTab = FormatStyle::UT_Always; |
| Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros; |
| return Style; |
| }(); |
| |
| ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros); |
| Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, SubSubStyle); |
| |
| // Test 9.5: use InheritParentConfig as style name |
| Style9 = |
| getStyle("inheritparentconfig", "/e/sub/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, SubSubStyle); |
| |
| // Test 9.6: use command line style with inheritance |
| Style9 = getStyle("{BasedOnStyle: InheritParentConfig}", "/e/sub/code.cpp", |
| "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, SubSubStyle); |
| |
| // Test 9.7: use command line style with inheritance and own config |
| Style9 = getStyle("{BasedOnStyle: InheritParentConfig, " |
| "WhitespaceSensitiveMacros: ['FOO', 'BAR']}", |
| "/e/sub/code.cpp", "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, SubSubStyle); |
| |
| // Test 9.8: use inheritance from a file without BasedOnStyle |
| ASSERT_TRUE(FS.addFile("/e/withoutbase/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("ColumnLimit: 123"))); |
| ASSERT_TRUE( |
| FS.addFile("/e/withoutbase/sub/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer( |
| "BasedOnStyle: InheritParentConfig\nIndentWidth: 7"))); |
| // Make sure we do not use the fallback style |
| Style9 = getStyle("file", "/e/withoutbase/code.cpp", "google", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [] { |
| auto Style = getLLVMStyle(); |
| Style.ColumnLimit = 123; |
| return Style; |
| }()); |
| |
| Style9 = getStyle("file", "/e/withoutbase/sub/code.cpp", "google", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, [] { |
| auto Style = getLLVMStyle(); |
| Style.ColumnLimit = 123; |
| Style.IndentWidth = 7; |
| return Style; |
| }()); |
| |
| // Test 9.9: use inheritance from a specific config file. |
| Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp", |
| "none", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style9)); |
| ASSERT_EQ(*Style9, SubSubStyle); |
| } |
| |
| TEST(FormatStyle, GetStyleOfSpecificFile) { |
| llvm::vfs::InMemoryFileSystem FS; |
| // Specify absolute path to a format file in a parent directory. |
| ASSERT_TRUE( |
| FS.addFile("/e/.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM"))); |
| ASSERT_TRUE( |
| FS.addFile("/e/explicit.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google"))); |
| ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0, |
| llvm::MemoryBuffer::getMemBuffer("int i;"))); |
| auto Style = getStyle("file:/e/explicit.clang-format", |
| "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style)); |
| ASSERT_EQ(*Style, getGoogleStyle()); |
| |
| // Specify relative path to a format file. |
| ASSERT_TRUE( |
| FS.addFile("../../e/explicit.clang-format", 0, |
| llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google"))); |
| Style = getStyle("file:../../e/explicit.clang-format", |
| "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS); |
| ASSERT_TRUE(static_cast<bool>(Style)); |
| ASSERT_EQ(*Style, getGoogleStyle()); |
| |
| // Specify path to a format file that does not exist. |
| Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp", |
| "LLVM", "", &FS); |
| ASSERT_FALSE(static_cast<bool>(Style)); |
| llvm::consumeError(Style.takeError()); |
| |
| // Specify path to a file on the filesystem. |
| SmallString<128> FormatFilePath; |
| std::error_code ECF = llvm::sys::fs::createTemporaryFile( |
| "FormatFileTest", "tpl", FormatFilePath); |
| EXPECT_FALSE((bool)ECF); |
| llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF); |
| EXPECT_FALSE((bool)ECF); |
| FormatFileTest << "BasedOnStyle: Google\n"; |
| FormatFileTest.close(); |
| |
| SmallString<128> TestFilePath; |
| std::error_code ECT = |
| llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath); |
| EXPECT_FALSE((bool)ECT); |
| llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT); |
| CodeFileTest << "int i;\n"; |
| CodeFileTest.close(); |
| |
| std::string format_file_arg = std::string("file:") + FormatFilePath.c_str(); |
| Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr); |
| |
| llvm::sys::fs::remove(FormatFilePath.c_str()); |
| llvm::sys::fs::remove(TestFilePath.c_str()); |
| ASSERT_TRUE(static_cast<bool>(Style)); |
| ASSERT_EQ(*Style, getGoogleStyle()); |
| } |
| |
| TEST_F(ReplacementTest, FormatCodeAfterReplacements) { |
| // Column limit is 20. |
| std::string Code = "Type *a =\n" |
| " new Type();\n" |
| "g(iiiii, 0, jjjjj,\n" |
| " 0, kkkkk, 0, mm);\n" |
| "int bad = format ;"; |
| std::string Expected = "auto a = new Type();\n" |
| "g(iiiii, nullptr,\n" |
| " jjjjj, nullptr,\n" |
| " kkkkk, nullptr,\n" |
| " mm);\n" |
| "int bad = format ;"; |
| FileID ID = Context.createInMemoryFile("format.cpp", Code); |
| tooling::Replacements Replaces = toReplacements( |
| {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 6, |
| "auto "), |
| tooling::Replacement(Context.Sources, Context.getLocation(ID, 3, 10), 1, |
| "nullptr"), |
| tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 3), 1, |
| "nullptr"), |
| tooling::Replacement(Context.Sources, Context.getLocation(ID, 4, 13), 1, |
| "nullptr")}); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.ColumnLimit = 20; // Set column limit to 20 to increase readibility. |
| auto FormattedReplaces = formatReplacements(Code, Replaces, Style); |
| EXPECT_TRUE(static_cast<bool>(FormattedReplaces)) |
| << llvm::toString(FormattedReplaces.takeError()) << "\n"; |
| auto Result = applyAllReplacements(Code, *FormattedReplaces); |
| EXPECT_TRUE(static_cast<bool>(Result)); |
| EXPECT_EQ(Expected, *Result); |
| } |
| |
| TEST_F(ReplacementTest, SortIncludesAfterReplacement) { |
| std::string Code = "#include \"a.h\"\n" |
| "#include \"c.h\"\n" |
| "\n" |
| "int main() {\n" |
| " return 0;\n" |
| "}"; |
| std::string Expected = "#include \"a.h\"\n" |
| "#include \"b.h\"\n" |
| "#include \"c.h\"\n" |
| "\n" |
| "int main() {\n" |
| " return 0;\n" |
| "}"; |
| FileID ID = Context.createInMemoryFile("fix.cpp", Code); |
| tooling::Replacements Replaces = toReplacements( |
| {tooling::Replacement(Context.Sources, Context.getLocation(ID, 1, 1), 0, |
| "#include \"b.h\"\n")}); |
| |
| FormatStyle Style = getLLVMStyle(); |
| Style.SortIncludes = FormatStyle::SI_CaseSensitive; |
| auto FormattedReplaces = formatReplacements(Code, Replaces, Style); |
| EXPECT_TRUE(static_cast<bool>(FormattedReplaces)) |
| << llvm::toString(FormattedReplaces.takeError()) << "\n"; |
| auto Result = applyAllReplacements(Code, *FormattedReplaces); |
| EXPECT_TRUE(static_cast<bool>(Result)); |
| EXPECT_EQ(Expected, *Result); |
| } |
| |
| TEST_F(FormatTest, FormatSortsUsingDeclarations) { |
| EXPECT_EQ("using std::cin;\n" |
| "using std::cout;", |
| format("using std::cout;\n" |
| "using std::cin;", |
| getGoogleStyle())); |
| } |
| |
| TEST_F(FormatTest, UTF8CharacterLiteralCpp03) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.Standard = FormatStyle::LS_Cpp03; |
| // cpp03 recognize this string as identifier u8 and literal character 'a' |
| EXPECT_EQ("auto c = u8 'a';", format("auto c = u8'a';", Style)); |
| } |
| |
| TEST_F(FormatTest, UTF8CharacterLiteralCpp11) { |
| // u8'a' is a C++17 feature, utf8 literal character, LS_Cpp11 covers |
| // all modes, including C++11, C++14 and C++17 |
| EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';")); |
| } |
| |
| TEST_F(FormatTest, DoNotFormatLikelyXml) { |
| EXPECT_EQ("<!-- ;> -->", format("<!-- ;> -->", getGoogleStyle())); |
| EXPECT_EQ(" <!-- >; -->", format(" <!-- >; -->", getGoogleStyle())); |
| } |
| |
| TEST_F(FormatTest, StructuredBindings) { |
| // Structured bindings is a C++17 feature. |
| // all modes, including C++11, C++14 and C++17 |
| verifyFormat("auto [a, b] = f();"); |
| EXPECT_EQ("auto [a, b] = f();", format("auto[a, b] = f();")); |
| EXPECT_EQ("const auto [a, b] = f();", format("const auto[a, b] = f();")); |
| EXPECT_EQ("auto const [a, b] = f();", format("auto const[a, b] = f();")); |
| EXPECT_EQ("auto const volatile [a, b] = f();", |
| format("auto const volatile[a, b] = f();")); |
| EXPECT_EQ("auto [a, b, c] = f();", format("auto [ a , b,c ] = f();")); |
| EXPECT_EQ("auto &[a, b, c] = f();", |
| format("auto &[ a , b,c ] = f();")); |
| EXPECT_EQ("auto &&[a, b, c] = f();", |
| format("auto &&[ a , b,c ] = f();")); |
| EXPECT_EQ("auto const &[a, b] = f();", format("auto const&[a, b] = f();")); |
| EXPECT_EQ("auto const volatile &&[a, b] = f();", |
| format("auto const volatile &&[a, b] = f();")); |
| EXPECT_EQ("auto const &&[a, b] = f();", |
| format("auto const && [a, b] = f();")); |
| EXPECT_EQ("const auto &[a, b] = f();", |
| format("const auto & [a, b] = f();")); |
| EXPECT_EQ("const auto volatile &&[a, b] = f();", |
| format("const auto volatile &&[a, b] = f();")); |
| EXPECT_EQ("volatile const auto &&[a, b] = f();", |
| format("volatile const auto &&[a, b] = f();")); |
| EXPECT_EQ("const auto &&[a, b] = f();", |
| format("const auto && [a, b] = f();")); |
| |
| // Make sure we don't mistake structured bindings for lambdas. |
| FormatStyle PointerMiddle = getLLVMStyle(); |
| PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("auto [a1, b]{A * i};", getGoogleStyle()); |
| verifyFormat("auto [a2, b]{A * i};", getLLVMStyle()); |
| verifyFormat("auto [a3, b]{A * i};", PointerMiddle); |
| verifyFormat("auto const [a1, b]{A * i};", getGoogleStyle()); |
| verifyFormat("auto const [a2, b]{A * i};", getLLVMStyle()); |
| verifyFormat("auto const [a3, b]{A * i};", PointerMiddle); |
| verifyFormat("auto const& [a1, b]{A * i};", getGoogleStyle()); |
| verifyFormat("auto const &[a2, b]{A * i};", getLLVMStyle()); |
| verifyFormat("auto const & [a3, b]{A * i};", PointerMiddle); |
| verifyFormat("auto const&& [a1, b]{A * i};", getGoogleStyle()); |
| verifyFormat("auto const &&[a2, b]{A * i};", getLLVMStyle()); |
| verifyFormat("auto const && [a3, b]{A * i};", PointerMiddle); |
| |
| EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n}", |
| format("for (const auto && [a, b] : some_range) {\n}")); |
| EXPECT_EQ("for (const auto &[a, b] : some_range) {\n}", |
| format("for (const auto & [a, b] : some_range) {\n}")); |
| EXPECT_EQ("for (const auto [a, b] : some_range) {\n}", |
| format("for (const auto[a, b] : some_range) {\n}")); |
| EXPECT_EQ("auto [x, y](expr);", format("auto[x,y] (expr);")); |
| EXPECT_EQ("auto &[x, y](expr);", format("auto & [x,y] (expr);")); |
| EXPECT_EQ("auto &&[x, y](expr);", format("auto && [x,y] (expr);")); |
| EXPECT_EQ("auto const &[x, y](expr);", |
| format("auto const & [x,y] (expr);")); |
| EXPECT_EQ("auto const &&[x, y](expr);", |
| format("auto const && [x,y] (expr);")); |
| EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};")); |
| EXPECT_EQ("auto const &[x, y]{expr};", |
| format("auto const & [x,y] {expr};")); |
| EXPECT_EQ("auto const &&[x, y]{expr};", |
| format("auto const && [x,y] {expr};")); |
| |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.SpacesInSquareBrackets = true; |
| verifyFormat("auto [ a, b ] = f();", Spaces); |
| verifyFormat("auto &&[ a, b ] = f();", Spaces); |
| verifyFormat("auto &[ a, b ] = f();", Spaces); |
| verifyFormat("auto const &&[ a, b ] = f();", Spaces); |
| verifyFormat("auto const &[ a, b ] = f();", Spaces); |
| } |
| |
| TEST_F(FormatTest, FileAndCode) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.cc", "")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.m", "")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.mm", "")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "@interface Foo\n@end\n")); |
| EXPECT_EQ( |
| FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "#define TRY(x, y) @try { x; } @finally { y; }")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "#define AVAIL(x) @available(x, *))")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.h", "@class Foo;")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo", "")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo", "@interface Foo\n@end\n")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int DoStuff(CGRect rect);\n")); |
| EXPECT_EQ( |
| FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", |
| "#define MY_POINT_MAKE(x, y) CGPointMake((x), (y));\n")); |
| EXPECT_EQ( |
| FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "#define FOO(...) auto bar = [] __VA_ARGS__;")); |
| // Only one of the two preprocessor regions has ObjC-like code. |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "#if A\n" |
| "#define B() C\n" |
| "#else\n" |
| "#define B() [NSString a:@\"\"]\n" |
| "#endif\n")); |
| } |
| |
| TEST_F(FormatTest, GuessLanguageWithCpp11AttributeSpecifiers) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "[[noreturn]];")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "array[[calculator getIndex]];")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[noreturn, deprecated(\"so sorry\")]];")); |
| EXPECT_EQ( |
| FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[noreturn, deprecated(\"gone, sorry\")]];")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "[[noreturn foo] bar];")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[clang::fallthrough]];")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "[[clang:fallthrough] foo];")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[gsl::suppress(\"type\")]];")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[using clang: fallthrough]];")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "[[abusing clang:fallthrough] bar];")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "[[using gsl: suppress(\"type\")]];")); |
| EXPECT_EQ( |
| FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "for (auto &&[endpoint, stream] : streams_)")); |
| EXPECT_EQ( |
| FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", |
| "[[clang::callable_when(\"unconsumed\", \"unknown\")]]")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "[[foo::bar, ...]]")); |
| } |
| |
| TEST_F(FormatTest, GuessLanguageWithCaret) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "FOO(^);")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "FOO(^, Bar);")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int(^)(char, float);")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int(^foo)(char, float);")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int(^foo[10])(char, float);")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int(^foo[kNumEntries])(char, float);")); |
| EXPECT_EQ( |
| FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "int(^foo[(kNumEntries + 10)])(char, float);")); |
| } |
| |
| TEST_F(FormatTest, GuessLanguageWithPragmas) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "__pragma(warning(disable:))")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "#pragma(warning(disable:))")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "_Pragma(warning(disable:))")); |
| } |
| |
| TEST_F(FormatTest, FormatsInlineAsmSymbolicNames) { |
| // ASM symbolic names are identifiers that must be surrounded by [] without |
| // space in between: |
| // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands |
| |
| // Example from https://bugs.llvm.org/show_bug.cgi?id=45108. |
| verifyFormat(R"(// |
| asm volatile("mrs %x[result], FPCR" : [result] "=r"(result)); |
| )"); |
| |
| // A list of several ASM symbolic names. |
| verifyFormat(R"(asm("mov %[e], %[d]" : [d] "=rm"(d), [e] "rm"(*e));)"); |
| |
| // ASM symbolic names in inline ASM with inputs and outputs. |
| verifyFormat(R"(// |
| asm("cmoveq %1, %2, %[result]" |
| : [result] "=r"(result) |
| : "r"(test), "r"(new), "[result]"(old)); |
| )"); |
| |
| // ASM symbolic names in inline ASM with no outputs. |
| verifyFormat(R"(asm("mov %[e], %[d]" : : [d] "=rm"(d), [e] "rm"(*e));)"); |
| } |
| |
| TEST_F(FormatTest, GuessedLanguageWithInlineAsmClobbers) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " asm (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d)\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " _asm (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d)\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " __asm (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d)\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " __asm__ (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d)\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " asm (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d),\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "void f() {\n" |
| " asm volatile (\"mov %[e], %[d]\"\n" |
| " : [d] \"=rm\" (d)\n" |
| " [e] \"rm\" (*e));\n" |
| "}")); |
| } |
| |
| TEST_F(FormatTest, GuessLanguageWithChildLines) { |
| EXPECT_EQ(FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "#define FOO ({ std::string s; })")); |
| EXPECT_EQ(FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "#define FOO ({ NSString *s; })")); |
| EXPECT_EQ( |
| FormatStyle::LK_Cpp, |
| guessLanguage("foo.h", "#define FOO ({ foo(); ({ std::string s; }) })")); |
| EXPECT_EQ( |
| FormatStyle::LK_ObjC, |
| guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })")); |
| } |
| |
| TEST_F(FormatTest, TypenameMacros) { |
| std::vector<std::string> TypenameMacros = {"STACK_OF", "LIST", "TAILQ_ENTRY"}; |
| |
| // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=30353 |
| FormatStyle Google = getGoogleStyleWithColumns(0); |
| Google.TypenameMacros = TypenameMacros; |
| verifyFormat("struct foo {\n" |
| " int bar;\n" |
| " TAILQ_ENTRY(a) bleh;\n" |
| "};", |
| Google); |
| |
| FormatStyle Macros = getLLVMStyle(); |
| Macros.TypenameMacros = TypenameMacros; |
| |
| verifyFormat("STACK_OF(int) a;", Macros); |
| verifyFormat("STACK_OF(int) *a;", Macros); |
| verifyFormat("STACK_OF(int const *) *a;", Macros); |
| verifyFormat("STACK_OF(int *const) *a;", Macros); |
| verifyFormat("STACK_OF(int, string) a;", Macros); |
| verifyFormat("STACK_OF(LIST(int)) a;", Macros); |
| verifyFormat("STACK_OF(LIST(int)) a, b;", Macros); |
| verifyFormat("for (LIST(int) *a = NULL; a;) {\n}", Macros); |
| verifyFormat("STACK_OF(int) f(LIST(int) *arg);", Macros); |
| verifyFormat("vector<LIST(uint64_t) *attr> x;", Macros); |
| verifyFormat("vector<LIST(uint64_t) *const> f(LIST(uint64_t) *arg);", Macros); |
| |
| Macros.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("STACK_OF(int)* a;", Macros); |
| verifyFormat("STACK_OF(int*)* a;", Macros); |
| verifyFormat("x = (STACK_OF(uint64_t))*a;", Macros); |
| verifyFormat("x = (STACK_OF(uint64_t))&a;", Macros); |
| verifyFormat("vector<STACK_OF(uint64_t)* attr> x;", Macros); |
| } |
| |
| TEST_F(FormatTest, AtomicQualifier) { |
| // Check that we treate _Atomic as a type and not a function call |
| FormatStyle Google = getGoogleStyleWithColumns(0); |
| verifyFormat("struct foo {\n" |
| " int a1;\n" |
| " _Atomic(a) a2;\n" |
| " _Atomic(_Atomic(int) *const) a3;\n" |
| "};", |
| Google); |
| verifyFormat("_Atomic(uint64_t) a;"); |
| verifyFormat("_Atomic(uint64_t) *a;"); |
| verifyFormat("_Atomic(uint64_t const *) *a;"); |
| verifyFormat("_Atomic(uint64_t *const) *a;"); |
| verifyFormat("_Atomic(const uint64_t *) *a;"); |
| verifyFormat("_Atomic(uint64_t) a;"); |
| verifyFormat("_Atomic(_Atomic(uint64_t)) a;"); |
| verifyFormat("_Atomic(_Atomic(uint64_t)) a, b;"); |
| verifyFormat("for (_Atomic(uint64_t) *a = NULL; a;) {\n}"); |
| verifyFormat("_Atomic(uint64_t) f(_Atomic(uint64_t) *arg);"); |
| |
| verifyFormat("_Atomic(uint64_t) *s(InitValue);"); |
| verifyFormat("_Atomic(uint64_t) *s{InitValue};"); |
| FormatStyle Style = getLLVMStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("_Atomic(uint64_t)* s(InitValue);", Style); |
| verifyFormat("_Atomic(uint64_t)* s{InitValue};", Style); |
| verifyFormat("_Atomic(int)* a;", Style); |
| verifyFormat("_Atomic(int*)* a;", Style); |
| verifyFormat("vector<_Atomic(uint64_t)* attr> x;", Style); |
| |
| Style.SpacesInCStyleCastParentheses = true; |
| Style.SpacesInParentheses = false; |
| verifyFormat("x = ( _Atomic(uint64_t) )*a;", Style); |
| Style.SpacesInCStyleCastParentheses = false; |
| Style.SpacesInParentheses = true; |
| verifyFormat("x = (_Atomic( uint64_t ))*a;", Style); |
| verifyFormat("x = (_Atomic( uint64_t ))&a;", Style); |
| } |
| |
| TEST_F(FormatTest, AmbersandInLamda) { |
| // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899 |
| FormatStyle AlignStyle = getLLVMStyle(); |
| AlignStyle.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("auto lambda = [&a = a]() { a = 2; };", AlignStyle); |
| AlignStyle.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("auto lambda = [&a = a]() { a = 2; };", AlignStyle); |
| } |
| |
| TEST_F(FormatTest, SpacesInConditionalStatement) { |
| FormatStyle Spaces = getLLVMStyle(); |
| Spaces.IfMacros.clear(); |
| Spaces.IfMacros.push_back("MYIF"); |
| Spaces.SpacesInConditionalStatement = true; |
| verifyFormat("for ( int i = 0; i; i++ )\n continue;", Spaces); |
| verifyFormat("if ( !a )\n return;", Spaces); |
| verifyFormat("if ( a )\n return;", Spaces); |
| verifyFormat("if constexpr ( a )\n return;", Spaces); |
| verifyFormat("MYIF ( a )\n return;", Spaces); |
| verifyFormat("MYIF ( a )\n return;\nelse MYIF ( b )\n return;", Spaces); |
| verifyFormat("MYIF ( a )\n return;\nelse\n return;", Spaces); |
| verifyFormat("switch ( a )\ncase 1:\n return;", Spaces); |
| verifyFormat("while ( a )\n return;", Spaces); |
| verifyFormat("while ( (a && b) )\n return;", Spaces); |
| verifyFormat("do {\n} while ( 1 != 0 );", Spaces); |
| verifyFormat("try {\n} catch ( const std::exception & ) {\n}", Spaces); |
| // Check that space on the left of "::" is inserted as expected at beginning |
| // of condition. |
| verifyFormat("while ( ::func() )\n return;", Spaces); |
| |
| // Check impact of ControlStatementsExceptControlMacros is honored. |
| Spaces.SpaceBeforeParens = |
| FormatStyle::SBPO_ControlStatementsExceptControlMacros; |
| verifyFormat("MYIF( a )\n return;", Spaces); |
| verifyFormat("MYIF( a )\n return;\nelse MYIF( b )\n return;", Spaces); |
| verifyFormat("MYIF( a )\n return;\nelse\n return;", Spaces); |
| } |
| |
| TEST_F(FormatTest, AlternativeOperators) { |
| // Test case for ensuring alternate operators are not |
| // combined with their right most neighbour. |
| verifyFormat("int a and b;"); |
| verifyFormat("int a and_eq b;"); |
| verifyFormat("int a bitand b;"); |
| verifyFormat("int a bitor b;"); |
| verifyFormat("int a compl b;"); |
| verifyFormat("int a not b;"); |
| verifyFormat("int a not_eq b;"); |
| verifyFormat("int a or b;"); |
| verifyFormat("int a xor b;"); |
| verifyFormat("int a xor_eq b;"); |
| verifyFormat("return this not_eq bitand other;"); |
| verifyFormat("bool operator not_eq(const X bitand other)"); |
| |
| verifyFormat("int a and 5;"); |
| verifyFormat("int a and_eq 5;"); |
| verifyFormat("int a bitand 5;"); |
| verifyFormat("int a bitor 5;"); |
| verifyFormat("int a compl 5;"); |
| verifyFormat("int a not 5;"); |
| verifyFormat("int a not_eq 5;"); |
| verifyFormat("int a or 5;"); |
| verifyFormat("int a xor 5;"); |
| verifyFormat("int a xor_eq 5;"); |
| |
| verifyFormat("int a compl(5);"); |
| verifyFormat("int a not(5);"); |
| |
| /* FIXME handle alternate tokens |
| * https://en.cppreference.com/w/cpp/language/operator_alternative |
| // alternative tokens |
| verifyFormat("compl foo();"); // ~foo(); |
| verifyFormat("foo() <%%>;"); // foo(); |
| verifyFormat("void foo() <%%>;"); // void foo(){} |
| verifyFormat("int a <:1:>;"); // int a[1];[ |
| verifyFormat("%:define ABC abc"); // #define ABC abc |
| verifyFormat("%:%:"); // ## |
| */ |
| } |
| |
| TEST_F(FormatTest, STLWhileNotDefineChed) { |
| verifyFormat("#if defined(while)\n" |
| "#define while EMIT WARNING C4005\n" |
| "#endif // while"); |
| } |
| |
| TEST_F(FormatTest, OperatorSpacing) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.PointerAlignment = FormatStyle::PAS_Right; |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("Foo::operator void *();", Style); |
| verifyFormat("Foo::operator void **();", Style); |
| verifyFormat("Foo::operator void *&();", Style); |
| verifyFormat("Foo::operator void *&&();", Style); |
| verifyFormat("Foo::operator void const *();", Style); |
| verifyFormat("Foo::operator void const **();", Style); |
| verifyFormat("Foo::operator void const *&();", Style); |
| verifyFormat("Foo::operator void const *&&();", Style); |
| verifyFormat("Foo::operator()(void *);", Style); |
| verifyFormat("Foo::operator*(void *);", Style); |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("Foo::operator**();", Style); |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("Foo::operator<int> *();", Style); |
| verifyFormat("Foo::operator<Foo> *();", Style); |
| verifyFormat("Foo::operator<int> **();", Style); |
| verifyFormat("Foo::operator<Foo> **();", Style); |
| verifyFormat("Foo::operator<int> &();", Style); |
| verifyFormat("Foo::operator<Foo> &();", Style); |
| verifyFormat("Foo::operator<int> &&();", Style); |
| verifyFormat("Foo::operator<Foo> &&();", Style); |
| verifyFormat("Foo::operator<int> *&();", Style); |
| verifyFormat("Foo::operator<Foo> *&();", Style); |
| verifyFormat("Foo::operator<int> *&&();", Style); |
| verifyFormat("Foo::operator<Foo> *&&();", Style); |
| verifyFormat("operator*(int (*)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("Foo::operator void &();", Style); |
| verifyFormat("Foo::operator void const &();", Style); |
| verifyFormat("Foo::operator()(void &);", Style); |
| verifyFormat("Foo::operator&(void &);", Style); |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("operator&(int (&)(), class Foo);", Style); |
| verifyFormat("operator&&(int (&)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("Foo::operator**();", Style); |
| verifyFormat("Foo::operator void &&();", Style); |
| verifyFormat("Foo::operator void const &&();", Style); |
| verifyFormat("Foo::operator()(void &&);", Style); |
| verifyFormat("Foo::operator&&(void &&);", Style); |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("operator&&(int (&&)(), class Foo);", Style); |
| verifyFormat("operator const nsTArrayRight<E> &()", Style); |
| verifyFormat("[[nodiscard]] operator const nsTArrayRight<E, Allocator> &()", |
| Style); |
| verifyFormat("operator void **()", Style); |
| verifyFormat("operator const FooRight<Object> &()", Style); |
| verifyFormat("operator const FooRight<Object> *()", Style); |
| verifyFormat("operator const FooRight<Object> **()", Style); |
| verifyFormat("operator const FooRight<Object> *&()", Style); |
| verifyFormat("operator const FooRight<Object> *&&()", Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Left; |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("Foo::operator**();", Style); |
| verifyFormat("Foo::operator void*();", Style); |
| verifyFormat("Foo::operator void**();", Style); |
| verifyFormat("Foo::operator void*&();", Style); |
| verifyFormat("Foo::operator void*&&();", Style); |
| verifyFormat("Foo::operator void const*();", Style); |
| verifyFormat("Foo::operator void const**();", Style); |
| verifyFormat("Foo::operator void const*&();", Style); |
| verifyFormat("Foo::operator void const*&&();", Style); |
| verifyFormat("Foo::operator/*comment*/ void*();", Style); |
| verifyFormat("Foo::operator/*a*/ const /*b*/ void*();", Style); |
| verifyFormat("Foo::operator/*a*/ volatile /*b*/ void*();", Style); |
| verifyFormat("Foo::operator()(void*);", Style); |
| verifyFormat("Foo::operator*(void*);", Style); |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("Foo::operator<int>*();", Style); |
| verifyFormat("Foo::operator<Foo>*();", Style); |
| verifyFormat("Foo::operator<int>**();", Style); |
| verifyFormat("Foo::operator<Foo>**();", Style); |
| verifyFormat("Foo::operator<Foo>*&();", Style); |
| verifyFormat("Foo::operator<int>&();", Style); |
| verifyFormat("Foo::operator<Foo>&();", Style); |
| verifyFormat("Foo::operator<int>&&();", Style); |
| verifyFormat("Foo::operator<Foo>&&();", Style); |
| verifyFormat("Foo::operator<int>*&();", Style); |
| verifyFormat("Foo::operator<Foo>*&();", Style); |
| verifyFormat("operator*(int (*)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("Foo::operator void&();", Style); |
| verifyFormat("Foo::operator void const&();", Style); |
| verifyFormat("Foo::operator/*comment*/ void&();", Style); |
| verifyFormat("Foo::operator/*a*/ const /*b*/ void&();", Style); |
| verifyFormat("Foo::operator/*a*/ volatile /*b*/ void&();", Style); |
| verifyFormat("Foo::operator()(void&);", Style); |
| verifyFormat("Foo::operator&(void&);", Style); |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("operator&(int (&)(), class Foo);", Style); |
| verifyFormat("operator&(int (&&)(), class Foo);", Style); |
| verifyFormat("operator&&(int (&&)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("Foo::operator void&&();", Style); |
| verifyFormat("Foo::operator void const&&();", Style); |
| verifyFormat("Foo::operator/*comment*/ void&&();", Style); |
| verifyFormat("Foo::operator/*a*/ const /*b*/ void&&();", Style); |
| verifyFormat("Foo::operator/*a*/ volatile /*b*/ void&&();", Style); |
| verifyFormat("Foo::operator()(void&&);", Style); |
| verifyFormat("Foo::operator&&(void&&);", Style); |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("operator&&(int (&&)(), class Foo);", Style); |
| verifyFormat("operator const nsTArrayLeft<E>&()", Style); |
| verifyFormat("[[nodiscard]] operator const nsTArrayLeft<E, Allocator>&()", |
| Style); |
| verifyFormat("operator void**()", Style); |
| verifyFormat("operator const FooLeft<Object>&()", Style); |
| verifyFormat("operator const FooLeft<Object>*()", Style); |
| verifyFormat("operator const FooLeft<Object>**()", Style); |
| verifyFormat("operator const FooLeft<Object>*&()", Style); |
| verifyFormat("operator const FooLeft<Object>*&&()", Style); |
| |
| // PR45107 |
| verifyFormat("operator Vector<String>&();", Style); |
| verifyFormat("operator const Vector<String>&();", Style); |
| verifyFormat("operator foo::Bar*();", Style); |
| verifyFormat("operator const Foo<X>::Bar<Y>*();", Style); |
| verifyFormat("operator/*a*/ const /*b*/ Foo /*c*/<X> /*d*/ ::Bar<Y>*();", |
| Style); |
| |
| Style.PointerAlignment = FormatStyle::PAS_Middle; |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("Foo::operator void *();", Style); |
| verifyFormat("Foo::operator()(void *);", Style); |
| verifyFormat("Foo::operator*(void *);", Style); |
| verifyFormat("Foo::operator*();", Style); |
| verifyFormat("operator*(int (*)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("Foo::operator void &();", Style); |
| verifyFormat("Foo::operator void const &();", Style); |
| verifyFormat("Foo::operator()(void &);", Style); |
| verifyFormat("Foo::operator&(void &);", Style); |
| verifyFormat("Foo::operator&();", Style); |
| verifyFormat("operator&(int (&)(), class Foo);", Style); |
| |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("Foo::operator void &&();", Style); |
| verifyFormat("Foo::operator void const &&();", Style); |
| verifyFormat("Foo::operator()(void &&);", Style); |
| verifyFormat("Foo::operator&&(void &&);", Style); |
| verifyFormat("Foo::operator&&();", Style); |
| verifyFormat("operator&&(int (&&)(), class Foo);", Style); |
| } |
| |
| TEST_F(FormatTest, OperatorPassedAsAFunctionPtr) { |
| FormatStyle Style = getLLVMStyle(); |
| // PR46157 |
| verifyFormat("foo(operator+, -42);", Style); |
| verifyFormat("foo(operator++, -42);", Style); |
| verifyFormat("foo(operator--, -42);", Style); |
| verifyFormat("foo(-42, operator--);", Style); |
| verifyFormat("foo(-42, operator, );", Style); |
| verifyFormat("foo(operator, , -42);", Style); |
| } |
| |
| TEST_F(FormatTest, WhitespaceSensitiveMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.WhitespaceSensitiveMacros.push_back("FOO"); |
| |
| // Don't use the helpers here, since 'mess up' will change the whitespace |
| // and these are all whitespace sensitive by definition |
| EXPECT_EQ("FOO(String-ized&Messy+But(: :Still)=Intentional);", |
| format("FOO(String-ized&Messy+But(: :Still)=Intentional);", Style)); |
| EXPECT_EQ( |
| "FOO(String-ized&Messy+But\\(: :Still)=Intentional);", |
| format("FOO(String-ized&Messy+But\\(: :Still)=Intentional);", Style)); |
| EXPECT_EQ("FOO(String-ized&Messy+But,: :Still=Intentional);", |
| format("FOO(String-ized&Messy+But,: :Still=Intentional);", Style)); |
| EXPECT_EQ("FOO(String-ized&Messy+But,: :\n" |
| " Still=Intentional);", |
| format("FOO(String-ized&Messy+But,: :\n" |
| " Still=Intentional);", |
| Style)); |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| EXPECT_EQ("FOO(String-ized=&Messy+But,: :\n" |
| " Still=Intentional);", |
| format("FOO(String-ized=&Messy+But,: :\n" |
| " Still=Intentional);", |
| Style)); |
| |
| Style.ColumnLimit = 21; |
| EXPECT_EQ("FOO(String-ized&Messy+But: :Still=Intentional);", |
| format("FOO(String-ized&Messy+But: :Still=Intentional);", Style)); |
| } |
| |
| TEST_F(FormatTest, VeryLongNamespaceCommentSplit) { |
| // These tests are not in NamespaceEndCommentsFixerTest because that doesn't |
| // test its interaction with line wrapping |
| FormatStyle Style = getLLVMStyleWithColumns(80); |
| verifyFormat("namespace {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace", |
| Style); |
| |
| verifyFormat("namespace AAA {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace AAA", |
| Style); |
| |
| EXPECT_EQ("namespace Averyveryveryverylongnamespace {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace Averyveryveryverylongnamespace", |
| format("namespace Averyveryveryverylongnamespace {\n" |
| "int i;\n" |
| "int j;\n" |
| "}", |
| Style)); |
| |
| EXPECT_EQ( |
| "namespace " |
| "would::it::save::you::a::lot::of::time::if_::i::just::gave::up::and_::\n" |
| " went::mad::now {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace\n" |
| " // " |
| "would::it::save::you::a::lot::of::time::if_::i::just::gave::up::and_::" |
| "went::mad::now", |
| format("namespace " |
| "would::it::save::you::a::lot::of::time::if_::i::" |
| "just::gave::up::and_::went::mad::now {\n" |
| "int i;\n" |
| "int j;\n" |
| "}", |
| Style)); |
| |
| // This used to duplicate the comment again and again on subsequent runs |
| EXPECT_EQ( |
| "namespace " |
| "would::it::save::you::a::lot::of::time::if_::i::just::gave::up::and_::\n" |
| " went::mad::now {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace\n" |
| " // " |
| "would::it::save::you::a::lot::of::time::if_::i::just::gave::up::and_::" |
| "went::mad::now", |
| format("namespace " |
| "would::it::save::you::a::lot::of::time::if_::i::" |
| "just::gave::up::and_::went::mad::now {\n" |
| "int i;\n" |
| "int j;\n" |
| "} // namespace\n" |
| " // " |
| "would::it::save::you::a::lot::of::time::if_::i::just::gave::up::" |
| "and_::went::mad::now", |
| Style)); |
| } |
| |
| TEST_F(FormatTest, LikelyUnlikely) { |
| FormatStyle Style = getLLVMStyle(); |
| |
| verifyFormat("if (argc > 5) [[unlikely]] {\n" |
| " return 29;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (argc > 5) [[likely]] {\n" |
| " return 29;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (argc > 5) [[unlikely]] {\n" |
| " return 29;\n" |
| "} else [[likely]] {\n" |
| " return 42;\n" |
| "}\n", |
| Style); |
| |
| verifyFormat("if (argc > 5) [[unlikely]] {\n" |
| " return 29;\n" |
| "} else if (argc > 10) [[likely]] {\n" |
| " return 99;\n" |
| "} else {\n" |
| " return 42;\n" |
| "}\n", |
| Style); |
| |
| verifyFormat("if (argc > 5) [[gnu::unused]] {\n" |
| " return 29;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (argc > 5) [[unlikely]]\n" |
| " return 29;\n", |
| Style); |
| verifyFormat("if (argc > 5) [[likely]]\n" |
| " return 29;\n", |
| Style); |
| |
| verifyFormat("while (limit > 0) [[unlikely]] {\n" |
| " --limit;\n" |
| "}", |
| Style); |
| verifyFormat("for (auto &limit : limits) [[likely]] {\n" |
| " --limit;\n" |
| "}", |
| Style); |
| |
| verifyFormat("for (auto &limit : limits) [[unlikely]]\n" |
| " --limit;", |
| Style); |
| verifyFormat("while (limit > 0) [[likely]]\n" |
| " --limit;", |
| Style); |
| |
| Style.AttributeMacros.push_back("UNLIKELY"); |
| Style.AttributeMacros.push_back("LIKELY"); |
| verifyFormat("if (argc > 5) UNLIKELY\n" |
| " return 29;\n", |
| Style); |
| |
| verifyFormat("if (argc > 5) UNLIKELY {\n" |
| " return 29;\n" |
| "}", |
| Style); |
| verifyFormat("if (argc > 5) UNLIKELY {\n" |
| " return 29;\n" |
| "} else [[likely]] {\n" |
| " return 42;\n" |
| "}\n", |
| Style); |
| verifyFormat("if (argc > 5) UNLIKELY {\n" |
| " return 29;\n" |
| "} else LIKELY {\n" |
| " return 42;\n" |
| "}\n", |
| Style); |
| verifyFormat("if (argc > 5) [[unlikely]] {\n" |
| " return 29;\n" |
| "} else LIKELY {\n" |
| " return 42;\n" |
| "}\n", |
| Style); |
| |
| verifyFormat("for (auto &limit : limits) UNLIKELY {\n" |
| " --limit;\n" |
| "}", |
| Style); |
| verifyFormat("while (limit > 0) LIKELY {\n" |
| " --limit;\n" |
| "}", |
| Style); |
| |
| verifyFormat("while (limit > 0) UNLIKELY\n" |
| " --limit;", |
| Style); |
| verifyFormat("for (auto &limit : limits) LIKELY\n" |
| " --limit;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, PenaltyIndentedWhitespace) { |
| verifyFormat("Constructor()\n" |
| " : aaaaaa(aaaaaa), aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaa(aaaaaaaaaaaaaaaaaa, " |
| "aaaaaaaaaaaaaaaaaat))"); |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaa), " |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaa)"); |
| |
| FormatStyle StyleWithWhitespacePenalty = getLLVMStyle(); |
| StyleWithWhitespacePenalty.PenaltyIndentedWhitespace = 5; |
| verifyFormat("Constructor()\n" |
| " : aaaaaa(aaaaaa),\n" |
| " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" |
| " aaaa(aaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaat))", |
| StyleWithWhitespacePenalty); |
| verifyFormat("Constructor()\n" |
| " : aaaaaaaaaaaaa(aaaaaa), " |
| "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaa)", |
| StyleWithWhitespacePenalty); |
| } |
| |
| TEST_F(FormatTest, LLVMDefaultStyle) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("extern \"C\" {\n" |
| "int foo();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, GNUDefaultStyle) { |
| FormatStyle Style = getGNUStyle(); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| " int foo ();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, MozillaDefaultStyle) { |
| FormatStyle Style = getMozillaStyle(); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| " int foo();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, GoogleDefaultStyle) { |
| FormatStyle Style = getGoogleStyle(); |
| verifyFormat("extern \"C\" {\n" |
| "int foo();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, ChromiumDefaultStyle) { |
| FormatStyle Style = getChromiumStyle(FormatStyle::LanguageKind::LK_Cpp); |
| verifyFormat("extern \"C\" {\n" |
| "int foo();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, MicrosoftDefaultStyle) { |
| FormatStyle Style = getMicrosoftStyle(FormatStyle::LanguageKind::LK_Cpp); |
| verifyFormat("extern \"C\"\n" |
| "{\n" |
| " int foo();\n" |
| "}", |
| Style); |
| } |
| TEST_F(FormatTest, WebKitDefaultStyle) { |
| FormatStyle Style = getWebKitStyle(); |
| verifyFormat("extern \"C\" {\n" |
| "int foo();\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, Concepts) { |
| EXPECT_EQ(getLLVMStyle().BreakBeforeConceptDeclarations, |
| FormatStyle::BBCDS_Always); |
| verifyFormat("template <typename T>\n" |
| "concept True = true;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = ((false || foo()) && C2<T>) ||\n" |
| " (std::trait<T>::value && Baz) || sizeof(T) >= 6;", |
| getLLVMStyleWithColumns(60)); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = true && requires(T t) { t.bar(); } && " |
| "sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = true && requires(T t) {\n" |
| " t.bar();\n" |
| " t.baz();\n" |
| " } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = true && requires(T t) { // Comment\n" |
| " t.bar();\n" |
| " t.baz();\n" |
| " } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = false || requires(T t) { t.bar(); } && " |
| "sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = !!false || requires(T t) { t.bar(); } " |
| "&& sizeof(T) <= 8;"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept DelayedCheck = static_cast<bool>(0) ||\n" |
| " requires(T t) { t.bar(); } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = bool(0) || requires(T t) { t.bar(); } " |
| "&& sizeof(T) <= 8;"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept DelayedCheck = (bool)(0) ||\n" |
| " requires(T t) { t.bar(); } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept DelayedCheck = (bool)0 || requires(T t) { t.bar(); } " |
| "&& sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Size = sizeof(T) >= 5 && requires(T t) { t.bar(); } && " |
| "sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Size = 2 < 5 && 2 <= 5 && 8 >= 5 && 8 > 5 &&\n" |
| " requires(T t) {\n" |
| " t.bar();\n" |
| " t.baz();\n" |
| " } && sizeof(T) <= 8 && !(4 < 3);", |
| getLLVMStyleWithColumns(60)); |
| |
| verifyFormat("template <typename T>\n" |
| "concept TrueOrNot = IsAlwaysTrue || IsNeverTrue;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = foo();"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = foo(T());"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = foo(T{});"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Size = V<sizeof(T)>::Value > 5;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept True = S<T>::Value;"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept C = []() { return true; }() && requires(T t) { t.bar(); } &&\n" |
| " sizeof(T) <= 8;"); |
| |
| // FIXME: This is misformatted because the fake l paren starts at bool, not at |
| // the lambda l square. |
| verifyFormat("template <typename T>\n" |
| "concept C = [] -> bool { return true; }() && requires(T t) { " |
| "t.bar(); } &&\n" |
| " sizeof(T) <= 8;"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept C = decltype([]() { return std::true_type{}; }())::value &&\n" |
| " requires(T t) { t.bar(); } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = decltype([]() { return std::true_type{}; " |
| "}())::value && requires(T t) { t.bar(); } && sizeof(T) <= 8;", |
| getLLVMStyleWithColumns(120)); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = decltype([]() -> std::true_type { return {}; " |
| "}())::value &&\n" |
| " requires(T t) { t.bar(); } && sizeof(T) <= 8;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = true;\n" |
| "Foo Bar;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Hashable = requires(T a) {\n" |
| " { std::hash<T>{}(a) } -> " |
| "std::convertible_to<std::size_t>;\n" |
| " };"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept EqualityComparable = requires(T a, T b) {\n" |
| " { a == b } -> std::same_as<bool>;\n" |
| " };"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept EqualityComparable = requires(T a, T b) {\n" |
| " { a == b } -> std::same_as<bool>;\n" |
| " { a != b } -> std::same_as<bool>;\n" |
| " };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept WeakEqualityComparable = requires(T a, T b) {\n" |
| " { a == b };\n" |
| " { a != b };\n" |
| " };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept HasSizeT = requires { typename T::size_t; };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Semiregular =\n" |
| " DefaultConstructible<T> && CopyConstructible<T> && " |
| "CopyAssignable<T> &&\n" |
| " requires(T a, std::size_t n) {\n" |
| " requires Same<T *, decltype(&a)>;\n" |
| " { a.~T() } noexcept;\n" |
| " requires Same<T *, decltype(new T)>;\n" |
| " requires Same<T *, decltype(new T[n])>;\n" |
| " { delete new T; };\n" |
| " { delete new T[n]; };\n" |
| " };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Semiregular =\n" |
| " requires(T a, std::size_t n) {\n" |
| " requires Same<T *, decltype(&a)>;\n" |
| " { a.~T() } noexcept;\n" |
| " requires Same<T *, decltype(new T)>;\n" |
| " requires Same<T *, decltype(new T[n])>;\n" |
| " { delete new T; };\n" |
| " { delete new T[n]; };\n" |
| " { new T } -> std::same_as<T *>;\n" |
| " } && DefaultConstructible<T> && CopyConstructible<T> && " |
| "CopyAssignable<T>;"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept Semiregular =\n" |
| " DefaultConstructible<T> && requires(T a, std::size_t n) {\n" |
| " requires Same<T *, decltype(&a)>;\n" |
| " { a.~T() } noexcept;\n" |
| " requires Same<T *, decltype(new T)>;\n" |
| " requires Same<T *, decltype(new " |
| "T[n])>;\n" |
| " { delete new T; };\n" |
| " { delete new T[n]; };\n" |
| " } && CopyConstructible<T> && " |
| "CopyAssignable<T>;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Two = requires(T t) {\n" |
| " { t.foo() } -> std::same_as<Bar>;\n" |
| " } && requires(T &&t) {\n" |
| " { t.foo() } -> std::same_as<Bar &&>;\n" |
| " };"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept C = requires(T x) {\n" |
| " { *x } -> std::convertible_to<typename T::inner>;\n" |
| " { x + 1 } noexcept -> std::same_as<int>;\n" |
| " { x * 1 } -> std::convertible_to<T>;\n" |
| " };"); |
| |
| verifyFormat( |
| "template <typename T, typename U = T>\n" |
| "concept Swappable = requires(T &&t, U &&u) {\n" |
| " swap(std::forward<T>(t), std::forward<U>(u));\n" |
| " swap(std::forward<U>(u), std::forward<T>(t));\n" |
| " };"); |
| |
| verifyFormat("template <typename T, typename U>\n" |
| "concept Common = requires(T &&t, U &&u) {\n" |
| " typename CommonType<T, U>;\n" |
| " { CommonType<T, U>(std::forward<T>(t)) };\n" |
| " };"); |
| |
| verifyFormat("template <typename T, typename U>\n" |
| "concept Common = requires(T &&t, U &&u) {\n" |
| " typename CommonType<T, U>;\n" |
| " { CommonType<T, U>{std::forward<T>(t)} };\n" |
| " };"); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept C = requires(T t) {\n" |
| " requires Bar<T> && Foo<T>;\n" |
| " requires((trait<T> && Baz) || (T2<T> && Foo<T>));\n" |
| " };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept HasFoo = requires(T t) {\n" |
| " { t.foo() };\n" |
| " t.foo();\n" |
| " };\n" |
| "template <typename T>\n" |
| "concept HasBar = requires(T t) {\n" |
| " { t.bar() };\n" |
| " t.bar();\n" |
| " };"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Large = sizeof(T) > 10;"); |
| |
| verifyFormat("template <typename T, typename U>\n" |
| "concept FooableWith = requires(T t, U u) {\n" |
| " typename T::foo_type;\n" |
| " { t.foo(u) } -> typename T::foo_type;\n" |
| " t++;\n" |
| " };\n" |
| "void doFoo(FooableWith<int> auto t) { t.foo(3); }"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Context = is_specialization_of_v<context, T>;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Node = std::is_object_v<T>;"); |
| |
| verifyFormat("template <class T>\n" |
| "concept integral = __is_integral(T);"); |
| |
| verifyFormat("template <class T>\n" |
| "concept is2D = __array_extent(T, 1) == 2;"); |
| |
| verifyFormat("template <class T>\n" |
| "concept isRhs = __is_rvalue_expr(std::declval<T>() + 2)"); |
| |
| verifyFormat("template <class T, class T2>\n" |
| "concept Same = __is_same_as<T, T2>;"); |
| |
| verifyFormat( |
| "template <class _InIt, class _OutIt>\n" |
| "concept _Can_reread_dest =\n" |
| " std::forward_iterator<_OutIt> &&\n" |
| " std::same_as<std::iter_value_t<_InIt>, std::iter_value_t<_OutIt>>;"); |
| |
| auto Style = getLLVMStyle(); |
| Style.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Allowed; |
| |
| verifyFormat( |
| "template <typename T>\n" |
| "concept C = requires(T t) {\n" |
| " requires Bar<T> && Foo<T>;\n" |
| " requires((trait<T> && Baz) || (T2<T> && Foo<T>));\n" |
| " };", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "concept HasFoo = requires(T t) {\n" |
| " { t.foo() };\n" |
| " t.foo();\n" |
| " };\n" |
| "template <typename T>\n" |
| "concept HasBar = requires(T t) {\n" |
| " { t.bar() };\n" |
| " t.bar();\n" |
| " };", |
| Style); |
| |
| verifyFormat("template <typename T> concept True = true;", Style); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = decltype([]() -> std::true_type { return {}; " |
| "}())::value &&\n" |
| " requires(T t) { t.bar(); } && sizeof(T) <= 8;", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "concept Semiregular =\n" |
| " DefaultConstructible<T> && CopyConstructible<T> && " |
| "CopyAssignable<T> &&\n" |
| " requires(T a, std::size_t n) {\n" |
| " requires Same<T *, decltype(&a)>;\n" |
| " { a.~T() } noexcept;\n" |
| " requires Same<T *, decltype(new T)>;\n" |
| " requires Same<T *, decltype(new T[n])>;\n" |
| " { delete new T; };\n" |
| " { delete new T[n]; };\n" |
| " };", |
| Style); |
| |
| Style.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Never; |
| |
| verifyFormat("template <typename T> concept C =\n" |
| " requires(T t) {\n" |
| " requires Bar<T> && Foo<T>;\n" |
| " requires((trait<T> && Baz) || (T2<T> && Foo<T>));\n" |
| " };", |
| Style); |
| |
| verifyFormat("template <typename T> concept HasFoo = requires(T t) {\n" |
| " { t.foo() };\n" |
| " t.foo();\n" |
| " };\n" |
| "template <typename T> concept HasBar = requires(T t) {\n" |
| " { t.bar() };\n" |
| " t.bar();\n" |
| " };", |
| Style); |
| |
| verifyFormat("template <typename T> concept True = true;", Style); |
| |
| verifyFormat( |
| "template <typename T> concept C = decltype([]() -> std::true_type {\n" |
| " return {};\n" |
| " }())::value &&\n" |
| " requires(T t) { t.bar(); } && " |
| "sizeof(T) <= 8;", |
| Style); |
| |
| verifyFormat("template <typename T> concept Semiregular =\n" |
| " DefaultConstructible<T> && CopyConstructible<T> && " |
| "CopyAssignable<T> &&\n" |
| " requires(T a, std::size_t n) {\n" |
| " requires Same<T *, decltype(&a)>;\n" |
| " { a.~T() } noexcept;\n" |
| " requires Same<T *, decltype(new T)>;\n" |
| " requires Same<T *, decltype(new T[n])>;\n" |
| " { delete new T; };\n" |
| " { delete new T[n]; };\n" |
| " };", |
| Style); |
| |
| // The following tests are invalid C++, we just want to make sure we don't |
| // assert. |
| verifyFormat("template <typename T>\n" |
| "concept C = requires C2<T>;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = 5 + 4;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C =\n" |
| "class X;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = [] && true;"); |
| |
| verifyFormat("template <typename T>\n" |
| "concept C = [] && requires(T t) { typename T::size_type; };"); |
| } |
| |
| TEST_F(FormatTest, RequiresClausesPositions) { |
| auto Style = getLLVMStyle(); |
| EXPECT_EQ(Style.RequiresClausePosition, FormatStyle::RCPS_OwnLine); |
| EXPECT_EQ(Style.IndentRequiresClause, true); |
| |
| verifyFormat("template <typename T>\n" |
| " requires(Foo<T> && std::trait<T>)\n" |
| "struct Bar;", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| " requires(Foo<T> && std::trait<T>)\n" |
| "class Bar {\n" |
| "public:\n" |
| " Bar(T t);\n" |
| " bool baz();\n" |
| "};", |
| Style); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| " requires requires(T &&t) {\n" |
| " typename T::I;\n" |
| " requires(F<typename T::I> && std::trait<typename T::I>);\n" |
| " }\n" |
| "Bar(T) -> Bar<typename T::I>;", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| " requires(Foo<T> && std::trait<T>)\n" |
| "constexpr T MyGlobal;", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| " requires Foo<T> && requires(T t) {\n" |
| " { t.baz() } -> std::same_as<bool>;\n" |
| " requires std::same_as<T::Factor, int>;\n" |
| " }\n" |
| "inline int bar(T t) {\n" |
| " return t.baz() ? T::Factor : 5;\n" |
| "}", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "inline int bar(T t)\n" |
| " requires Foo<T> && requires(T t) {\n" |
| " { t.baz() } -> std::same_as<bool>;\n" |
| " requires std::same_as<T::Factor, int>;\n" |
| " }\n" |
| "{\n" |
| " return t.baz() ? T::Factor : 5;\n" |
| "}", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| " requires F<T>\n" |
| "int bar(T t) {\n" |
| " return 5;\n" |
| "}", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "int bar(T t)\n" |
| " requires F<T>\n" |
| "{\n" |
| " return 5;\n" |
| "}", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "int bar(T t)\n" |
| " requires F<T>;", |
| Style); |
| |
| Style.IndentRequiresClause = false; |
| verifyFormat("template <typename T>\n" |
| "requires F<T>\n" |
| "int bar(T t) {\n" |
| " return 5;\n" |
| "}", |
| Style); |
| |
| verifyFormat("template <typename T>\n" |
| "int bar(T t)\n" |
| "requires F<T>\n" |
| "{\n" |
| " return 5;\n" |
| "}", |
| Style); |
| |
| Style.RequiresClausePosition = FormatStyle::RCPS_SingleLine; |
| verifyFormat("template <typename T> requires Foo<T> struct Bar {};\n" |
| "template <typename T> requires Foo<T> void bar() {}\n" |
| "template <typename T> void bar() requires Foo<T> {}\n" |
| "template <typename T> void bar() requires Foo<T>;\n" |
| "template <typename T> requires Foo<T> Bar(T) -> Bar<T>;", |
| Style); |
| |
| auto ColumnStyle = Style; |
| ColumnStyle.ColumnLimit = 40; |
| verifyFormat("template <typename AAAAAAA>\n" |
| "requires Foo<T> struct Bar {};\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<T> void bar() {}\n" |
| "template <typename AAAAAAA>\n" |
| "void bar() requires Foo<T> {}\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<T> Baz(T) -> Baz<T>;", |
| ColumnStyle); |
| |
| verifyFormat("template <typename T>\n" |
| "requires Foo<AAAAAAA> struct Bar {};\n" |
| "template <typename T>\n" |
| "requires Foo<AAAAAAA> void bar() {}\n" |
| "template <typename T>\n" |
| "void bar() requires Foo<AAAAAAA> {}\n" |
| "template <typename T>\n" |
| "requires Foo<AAAAAAA> Bar(T) -> Bar<T>;", |
| ColumnStyle); |
| |
| verifyFormat("template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "struct Bar {};\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "void bar() {}\n" |
| "template <typename AAAAAAA>\n" |
| "void bar()\n" |
| " requires Foo<AAAAAAAAAAAAAAAA> {}\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAA> Bar(T) -> Bar<T>;\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "Bar(T) -> Bar<T>;", |
| ColumnStyle); |
| |
| Style.RequiresClausePosition = FormatStyle::RCPS_WithFollowing; |
| ColumnStyle.RequiresClausePosition = FormatStyle::RCPS_WithFollowing; |
| |
| verifyFormat("template <typename T>\n" |
| "requires Foo<T> struct Bar {};\n" |
| "template <typename T>\n" |
| "requires Foo<T> void bar() {}\n" |
| "template <typename T>\n" |
| "void bar()\n" |
| "requires Foo<T> {}\n" |
| "template <typename T>\n" |
| "void bar()\n" |
| "requires Foo<T>;\n" |
| "template <typename T>\n" |
| "requires Foo<T> Bar(T) -> Bar<T>;", |
| Style); |
| |
| verifyFormat("template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "struct Bar {};\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "void bar() {}\n" |
| "template <typename AAAAAAA>\n" |
| "void bar()\n" |
| "requires Foo<AAAAAAAAAAAAAAAA> {}\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAA> Bar(T) -> Bar<T>;\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "Bar(T) -> Bar<T>;", |
| ColumnStyle); |
| |
| Style.IndentRequiresClause = true; |
| ColumnStyle.IndentRequiresClause = true; |
| |
| verifyFormat("template <typename T>\n" |
| " requires Foo<T> struct Bar {};\n" |
| "template <typename T>\n" |
| " requires Foo<T> void bar() {}\n" |
| "template <typename T>\n" |
| "void bar()\n" |
| " requires Foo<T> {}\n" |
| "template <typename T>\n" |
| " requires Foo<T> Bar(T) -> Bar<T>;", |
| Style); |
| |
| verifyFormat("template <typename AAAAAAA>\n" |
| " requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "struct Bar {};\n" |
| "template <typename AAAAAAA>\n" |
| " requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "void bar() {}\n" |
| "template <typename AAAAAAA>\n" |
| "void bar()\n" |
| " requires Foo<AAAAAAAAAAAAAAAA> {}\n" |
| "template <typename AAAAAAA>\n" |
| " requires Foo<AAAAAA> Bar(T) -> Bar<T>;\n" |
| "template <typename AAAAAAA>\n" |
| " requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "Bar(T) -> Bar<T>;", |
| ColumnStyle); |
| |
| Style.RequiresClausePosition = FormatStyle::RCPS_WithPreceding; |
| ColumnStyle.RequiresClausePosition = FormatStyle::RCPS_WithPreceding; |
| |
| verifyFormat("template <typename T> requires Foo<T>\n" |
| "struct Bar {};\n" |
| "template <typename T> requires Foo<T>\n" |
| "void bar() {}\n" |
| "template <typename T>\n" |
| "void bar() requires Foo<T>\n" |
| "{}\n" |
| "template <typename T> void bar() requires Foo<T>;\n" |
| "template <typename T> requires Foo<T>\n" |
| "Bar(T) -> Bar<T>;", |
| Style); |
| |
| verifyFormat("template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "struct Bar {};\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "void bar() {}\n" |
| "template <typename AAAAAAA>\n" |
| "void bar()\n" |
| " requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "{}\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAA>\n" |
| "Bar(T) -> Bar<T>;\n" |
| "template <typename AAAAAAA>\n" |
| "requires Foo<AAAAAAAAAAAAAAAA>\n" |
| "Bar(T) -> Bar<T>;", |
| ColumnStyle); |
| } |
| |
| TEST_F(FormatTest, RequiresClauses) { |
| verifyFormat("struct [[nodiscard]] zero_t {\n" |
| " template <class T>\n" |
| " requires requires { number_zero_v<T>; }\n" |
| " [[nodiscard]] constexpr operator T() const {\n" |
| " return number_zero_v<T>;\n" |
| " }\n" |
| "};"); |
| |
| auto Style = getLLVMStyle(); |
| |
| verifyFormat( |
| "template <typename T>\n" |
| " requires is_default_constructible_v<hash<T>> and\n" |
| " is_copy_constructible_v<hash<T>> and\n" |
| " is_move_constructible_v<hash<T>> and\n" |
| " is_copy_assignable_v<hash<T>> and " |
| "is_move_assignable_v<hash<T>> and\n" |
| " is_destructible_v<hash<T>> and is_swappable_v<hash<T>> and\n" |
| " is_callable_v<hash<T>(T)> and\n" |
| " is_same_v<size_t, decltype(hash<T>(declval<T>()))> and\n" |
| " is_same_v<size_t, decltype(hash<T>(declval<T &>()))> and\n" |
| " is_same_v<size_t, decltype(hash<T>(declval<const T &>()))>\n" |
| "struct S {};", |
| Style); |
| |
| Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; |
| verifyFormat( |
| "template <typename T>\n" |
| " requires is_default_constructible_v<hash<T>>\n" |
| " and is_copy_constructible_v<hash<T>>\n" |
| " and is_move_constructible_v<hash<T>>\n" |
| " and is_copy_assignable_v<hash<T>> and " |
| "is_move_assignable_v<hash<T>>\n" |
| " and is_destructible_v<hash<T>> and is_swappable_v<hash<T>>\n" |
| " and is_callable_v<hash<T>(T)>\n" |
| " and is_same_v<size_t, decltype(hash<T>(declval<T>()))>\n" |
| " and is_same_v<size_t, decltype(hash<T>(declval<T &>()))>\n" |
| " and is_same_v<size_t, decltype(hash<T>(declval<const T " |
| "&>()))>\n" |
| "struct S {};", |
| Style); |
| |
| Style = getLLVMStyle(); |
| Style.ConstructorInitializerIndentWidth = 4; |
| Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; |
| Style.PackConstructorInitializers = FormatStyle::PCIS_Never; |
| verifyFormat("constexpr Foo(Foo const &other)\n" |
| " requires std::is_copy_constructible<T>\n" |
| " : value{other.value} {\n" |
| " do_magic();\n" |
| " do_more_magic();\n" |
| "}", |
| Style); |
| |
| // Not a clause, but we once hit an assert. |
| verifyFormat("#if 0\n" |
| "#else\n" |
| "foo();\n" |
| "#endif\n" |
| "bar(requires);"); |
| } |
| |
| TEST_F(FormatTest, StatementAttributeLikeMacros) { |
| FormatStyle Style = getLLVMStyle(); |
| StringRef Source = "void Foo::slot() {\n" |
| " unsigned char MyChar = 'x';\n" |
| " emit signal(MyChar);\n" |
| " Q_EMIT signal(MyChar);\n" |
| "}"; |
| |
| EXPECT_EQ(Source, format(Source, Style)); |
| |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| EXPECT_EQ("void Foo::slot() {\n" |
| " unsigned char MyChar = 'x';\n" |
| " emit signal(MyChar);\n" |
| " Q_EMIT signal(MyChar);\n" |
| "}", |
| format(Source, Style)); |
| |
| Style.StatementAttributeLikeMacros.push_back("emit"); |
| EXPECT_EQ(Source, format(Source, Style)); |
| |
| Style.StatementAttributeLikeMacros = {}; |
| EXPECT_EQ("void Foo::slot() {\n" |
| " unsigned char MyChar = 'x';\n" |
| " emit signal(MyChar);\n" |
| " Q_EMIT signal(MyChar);\n" |
| "}", |
| format(Source, Style)); |
| } |
| |
| TEST_F(FormatTest, IndentAccessModifiers) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.IndentAccessModifiers = true; |
| // Members are *two* levels below the record; |
| // Style.IndentWidth == 2, thus yielding a 4 spaces wide indentation. |
| verifyFormat("class C {\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| verifyFormat("union C {\n" |
| " int i;\n" |
| " unsigned u;\n" |
| "};\n", |
| Style); |
| // Access modifiers should be indented one level below the record. |
| verifyFormat("class C {\n" |
| " public:\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| verifyFormat("struct S {\n" |
| " private:\n" |
| " class C {\n" |
| " int j;\n" |
| "\n" |
| " public:\n" |
| " C();\n" |
| " };\n" |
| "\n" |
| " public:\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| // Enumerations are not records and should be unaffected. |
| Style.AllowShortEnumsOnASingleLine = false; |
| verifyFormat("enum class E {\n" |
| " A,\n" |
| " B\n" |
| "};\n", |
| Style); |
| // Test with a different indentation width; |
| // also proves that the result is Style.AccessModifierOffset agnostic. |
| Style.IndentWidth = 3; |
| verifyFormat("class C {\n" |
| " public:\n" |
| " int i;\n" |
| "};\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, LimitlessStringsAndComments) { |
| auto Style = getLLVMStyleWithColumns(0); |
| constexpr StringRef Code = |
| "/**\n" |
| " * This is a multiline comment with quite some long lines, at least for " |
| "the LLVM Style.\n" |
| " * We will redo this with strings and line comments. Just to check if " |
| "everything is working.\n" |
| " */\n" |
| "bool foo() {\n" |
| " /* Single line multi line comment. */\n" |
| " const std::string String = \"This is a multiline string with quite " |
| "some long lines, at least for the LLVM Style.\"\n" |
| " \"We already did it with multi line " |
| "comments, and we will do it with line comments. Just to check if " |
| "everything is working.\";\n" |
| " // This is a line comment (block) with quite some long lines, at " |
| "least for the LLVM Style.\n" |
| " // We already did this with multi line comments and strings. Just to " |
| "check if everything is working.\n" |
| " const std::string SmallString = \"Hello World\";\n" |
| " // Small line comment\n" |
| " return String.size() > SmallString.size();\n" |
| "}"; |
| EXPECT_EQ(Code, format(Code, Style)); |
| } |
| |
| TEST_F(FormatTest, FormatDecayCopy) { |
| // error cases from unit tests |
| verifyFormat("foo(auto())"); |
| verifyFormat("foo(auto{})"); |
| verifyFormat("foo(auto({}))"); |
| verifyFormat("foo(auto{{}})"); |
| |
| verifyFormat("foo(auto(1))"); |
| verifyFormat("foo(auto{1})"); |
| verifyFormat("foo(new auto(1))"); |
| verifyFormat("foo(new auto{1})"); |
| verifyFormat("decltype(auto(1)) x;"); |
| verifyFormat("decltype(auto{1}) x;"); |
| verifyFormat("auto(x);"); |
| verifyFormat("auto{x};"); |
| verifyFormat("new auto{x};"); |
| verifyFormat("auto{x} = y;"); |
| verifyFormat("auto(x) = y;"); // actually a declaration, but this is clearly |
| // the user's own fault |
| verifyFormat("integral auto(x) = y;"); // actually a declaration, but this is |
| // clearly the user's own fault |
| verifyFormat("auto(*p)() = f;"); // actually a declaration; TODO FIXME |
| } |
| |
| TEST_F(FormatTest, Cpp20ModulesSupport) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; |
| Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; |
| |
| verifyFormat("export import foo;", Style); |
| verifyFormat("export import foo:bar;", Style); |
| verifyFormat("export import foo.bar;", Style); |
| verifyFormat("export import foo.bar:baz;", Style); |
| verifyFormat("export import :bar;", Style); |
| verifyFormat("export module foo:bar;", Style); |
| verifyFormat("export module foo;", Style); |
| verifyFormat("export module foo.bar;", Style); |
| verifyFormat("export module foo.bar:baz;", Style); |
| verifyFormat("export import <string_view>;", Style); |
| |
| verifyFormat("export type_name var;", Style); |
| verifyFormat("template <class T> export using A = B<T>;", Style); |
| verifyFormat("export using A = B;", Style); |
| verifyFormat("export int func() {\n" |
| " foo();\n" |
| "}", |
| Style); |
| verifyFormat("export struct {\n" |
| " int foo;\n" |
| "};", |
| Style); |
| verifyFormat("export {\n" |
| " int foo;\n" |
| "};", |
| Style); |
| verifyFormat("export export char const *hello() { return \"hello\"; }"); |
| |
| verifyFormat("import bar;", Style); |
| verifyFormat("import foo.bar;", Style); |
| verifyFormat("import foo:bar;", Style); |
| verifyFormat("import :bar;", Style); |
| verifyFormat("import <ctime>;", Style); |
| verifyFormat("import \"header\";", Style); |
| |
| verifyFormat("module foo;", Style); |
| verifyFormat("module foo:bar;", Style); |
| verifyFormat("module foo.bar;", Style); |
| verifyFormat("module;", Style); |
| |
| verifyFormat("export namespace hi {\n" |
| "const char *sayhi();\n" |
| "}", |
| Style); |
| |
| verifyFormat("module :private;", Style); |
| verifyFormat("import <foo/bar.h>;", Style); |
| verifyFormat("import foo...bar;", Style); |
| verifyFormat("import ..........;", Style); |
| verifyFormat("module foo:private;", Style); |
| verifyFormat("import a", Style); |
| verifyFormat("module a", Style); |
| verifyFormat("export import a", Style); |
| verifyFormat("export module a", Style); |
| |
| verifyFormat("import", Style); |
| verifyFormat("module", Style); |
| verifyFormat("export", Style); |
| } |
| |
| TEST_F(FormatTest, CoroutineForCoawait) { |
| FormatStyle Style = getLLVMStyle(); |
| verifyFormat("for co_await (auto x : range())\n ;"); |
| verifyFormat("for (auto i : arr) {\n" |
| "}", |
| Style); |
| verifyFormat("for co_await (auto i : arr) {\n" |
| "}", |
| Style); |
| verifyFormat("for co_await (auto i : foo(T{})) {\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, CoroutineCoAwait) { |
| verifyFormat("int x = co_await foo();"); |
| verifyFormat("int x = (co_await foo());"); |
| verifyFormat("co_await (42);"); |
| verifyFormat("void operator co_await(int);"); |
| verifyFormat("void operator co_await(a);"); |
| verifyFormat("co_await a;"); |
| verifyFormat("co_await missing_await_resume{};"); |
| verifyFormat("co_await a; // comment"); |
| verifyFormat("void test0() { co_await a; }"); |
| verifyFormat("co_await co_await co_await foo();"); |
| verifyFormat("co_await foo().bar();"); |
| verifyFormat("co_await [this]() -> Task { co_return x; }"); |
| verifyFormat("co_await [this](int a, int b) -> Task { co_return co_await " |
| "foo(); }(x, y);"); |
| |
| FormatStyle Style = getLLVMStyleWithColumns(40); |
| verifyFormat("co_await [this](int a, int b) -> Task {\n" |
| " co_return co_await foo();\n" |
| "}(x, y);", |
| Style); |
| verifyFormat("co_await;"); |
| } |
| |
| TEST_F(FormatTest, CoroutineCoYield) { |
| verifyFormat("int x = co_yield foo();"); |
| verifyFormat("int x = (co_yield foo());"); |
| verifyFormat("co_yield (42);"); |
| verifyFormat("co_yield {42};"); |
| verifyFormat("co_yield 42;"); |
| verifyFormat("co_yield n++;"); |
| verifyFormat("co_yield ++n;"); |
| verifyFormat("co_yield;"); |
| } |
| |
| TEST_F(FormatTest, CoroutineCoReturn) { |
| verifyFormat("co_return (42);"); |
| verifyFormat("co_return;"); |
| verifyFormat("co_return {};"); |
| verifyFormat("co_return x;"); |
| verifyFormat("co_return co_await foo();"); |
| verifyFormat("co_return co_yield foo();"); |
| } |
| |
| TEST_F(FormatTest, EmptyShortBlock) { |
| auto Style = getLLVMStyle(); |
| Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; |
| |
| verifyFormat("try {\n" |
| " doA();\n" |
| "} catch (Exception &e) {\n" |
| " e.printStackTrace();\n" |
| "}\n", |
| Style); |
| |
| verifyFormat("try {\n" |
| " doA();\n" |
| "} catch (Exception &e) {}\n", |
| Style); |
| } |
| |
| TEST_F(FormatTest, ShortTemplatedArgumentLists) { |
| auto Style = getLLVMStyle(); |
| |
| verifyFormat("template <> struct S : Template<int (*)[]> {};\n", Style); |
| verifyFormat("template <> struct S : Template<int (*)[10]> {};\n", Style); |
| verifyFormat("struct Y : X<[] { return 0; }> {};", Style); |
| verifyFormat("struct Y<[] { return 0; }> {};", Style); |
| |
| verifyFormat("struct Z : X<decltype([] { return 0; }){}> {};", Style); |
| verifyFormat("template <int N> struct Foo<char[N]> {};", 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) { // 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); |
| |
| 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); |
| } |
| |
| TEST_F(FormatTest, RemoveBraces) { |
| FormatStyle Style = getLLVMStyle(); |
| Style.RemoveBracesLLVM = true; |
| |
| // The following test cases are fully-braced versions of the examples at |
| // "llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single- |
| // statement-bodies-of-if-else-loop-statements". |
| |
| // Omit the braces since the body is simple and clearly associated with the |
| // `if`. |
| verifyFormat("if (isa<FunctionDecl>(D))\n" |
| " handleFunctionDecl(D);\n" |
| "else if (isa<VarDecl>(D))\n" |
| " handleVarDecl(D);", |
| "if (isa<FunctionDecl>(D)) {\n" |
| " handleFunctionDecl(D);\n" |
| "} else if (isa<VarDecl>(D)) {\n" |
| " handleVarDecl(D);\n" |
| "}", |
| Style); |
| |
| // Here we document the condition itself and not the body. |
| verifyFormat("if (isa<VarDecl>(D)) {\n" |
| " // It is necessary that we explain the situation with this\n" |
| " // surprisingly long comment, so it would be unclear\n" |
| " // without the braces whether the following statement is in\n" |
| " // the scope of the `if`.\n" |
| " // Because the condition is documented, we can't really\n" |
| " // hoist this comment that applies to the body above the\n" |
| " // `if`.\n" |
| " handleOtherDecl(D);\n" |
| "}", |
| Style); |
| |
| // Use braces on the outer `if` to avoid a potential dangling `else` |
| // situation. |
| verifyFormat("if (isa<VarDecl>(D)) {\n" |
| " if (shouldProcessAttr(A))\n" |
| " handleAttr(A);\n" |
| "}", |
| "if (isa<VarDecl>(D)) {\n" |
| " if (shouldProcessAttr(A)) {\n" |
| " handleAttr(A);\n" |
| " }\n" |
| "}", |
| Style); |
| |
| // Use braces for the `if` block to keep it uniform with the `else` block. |
| verifyFormat("if (isa<FunctionDecl>(D)) {\n" |
| " handleFunctionDecl(D);\n" |
| "} else {\n" |
| " // In this `else` case, it is necessary that we explain the\n" |
| " // situation with this surprisingly long comment, so it\n" |
| " // would be unclear without the braces whether the\n" |
| " // following statement is in the scope of the `if`.\n" |
| " handleOtherDecl(D);\n" |
| "}", |
| Style); |
| |
| // This should also omit braces. The `for` loop contains only a single |
| // statement, so it shouldn't have braces. The `if` also only contains a |
| // single simple statement (the `for` loop), so it also should omit braces. |
| verifyFormat("if (isa<FunctionDecl>(D))\n" |
| " for (auto *A : D.attrs())\n" |
| " handleAttr(A);", |
| "if (isa<FunctionDecl>(D)) {\n" |
| " for (auto *A : D.attrs()) {\n" |
| " handleAttr(A);\n" |
| " }\n" |
| "}", |
| Style); |
| |
| // Use braces for a `do-while` loop and its enclosing statement. |
| verifyFormat("if (Tok->is(tok::l_brace)) {\n" |
| " do {\n" |
| " Tok = Tok->Next;\n" |
| " } while (Tok);\n" |
| "}", |
| Style); |
| |
| // Use braces for the outer `if` since the nested `for` is braced. |
| verifyFormat("if (isa<FunctionDecl>(D)) {\n" |
| " for (auto *A : D.attrs()) {\n" |
| " // In this `for` loop body, it is necessary that we\n" |
| " // explain the situation with this surprisingly long\n" |
| " // comment, forcing braces on the `for` block.\n" |
| " handleAttr(A);\n" |
| " }\n" |
| "}", |
| Style); |
| |
| // Use braces on the outer block because there are more than two levels of |
| // nesting. |
| verifyFormat("if (isa<FunctionDecl>(D)) {\n" |
| " for (auto *A : D.attrs())\n" |
| " for (ssize_t i : llvm::seq<ssize_t>(count))\n" |
| " handleAttrOnDecl(D, A, i);\n" |
| "}", |
| "if (isa<FunctionDecl>(D)) {\n" |
| " for (auto *A : D.attrs()) {\n" |
| " for (ssize_t i : llvm::seq<ssize_t>(count)) {\n" |
| " handleAttrOnDecl(D, A, i);\n" |
| " }\n" |
| " }\n" |
| "}", |
| Style); |
| |
| // Use braces on the outer block because of a nested `if`; otherwise the |
| // compiler would warn: `add explicit braces to avoid dangling else` |
| verifyFormat("if (auto *D = dyn_cast<FunctionDecl>(D)) {\n" |
| " if (shouldProcess(D))\n" |
| " handleVarDecl(D);\n" |
| " else\n" |
| " markAsIgnored(D);\n" |
| "}", |
| "if (auto *D = dyn_cast<FunctionDecl>(D)) {\n" |
| " if (shouldProcess(D)) {\n" |
| " handleVarDecl(D);\n" |
| " } else {\n" |
| " markAsIgnored(D);\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("// clang-format off\n" |
| "// comment\n" |
| "while (i > 0) { --i; }\n" |
| "// clang-format on\n" |
| "while (j < 0)\n" |
| " ++j;", |
| "// clang-format off\n" |
| "// comment\n" |
| "while (i > 0) { --i; }\n" |
| "// clang-format on\n" |
| "while (j < 0) { ++j; }", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b; // comment\n" |
| "else if (c)\n" |
| " d; /* comment */\n" |
| "else\n" |
| " e;", |
| "if (a) {\n" |
| " b; // comment\n" |
| "} else if (c) {\n" |
| " d; /* comment */\n" |
| "} else {\n" |
| " e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| " c;\n" |
| "} else if (d) {\n" |
| " e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| "#undef NDEBUG\n" |
| " b;\n" |
| "} else {\n" |
| " c;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " // comment\n" |
| "} else if (b) {\n" |
| " c;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else {\n" |
| " { c; }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b) // comment\n" |
| " c;\n" |
| "} else if (d) {\n" |
| " e;\n" |
| "}", |
| "if (a) {\n" |
| " if (b) { // comment\n" |
| " c;\n" |
| " }\n" |
| "} else if (d) {\n" |
| " e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b) {\n" |
| " c;\n" |
| " // comment\n" |
| " } else if (d) {\n" |
| " e;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b)\n" |
| " c;\n" |
| "}", |
| "if (a) {\n" |
| " if (b) {\n" |
| " c;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " if (b)\n" |
| " c;\n" |
| " else\n" |
| " d;\n" |
| "else\n" |
| " e;", |
| "if (a) {\n" |
| " if (b) {\n" |
| " c;\n" |
| " } else {\n" |
| " d;\n" |
| " }\n" |
| "} else {\n" |
| " e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " // comment\n" |
| " if (b)\n" |
| " c;\n" |
| " else if (d)\n" |
| " e;\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| "if (a) {\n" |
| " // comment\n" |
| " if (b) {\n" |
| " c;\n" |
| " } else if (d) {\n" |
| " e;\n" |
| " }\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b;\n" |
| "else if (c)\n" |
| " d;\n" |
| "else\n" |
| " e;", |
| "if (a) {\n" |
| " b;\n" |
| "} else {\n" |
| " if (c) {\n" |
| " d;\n" |
| " } else {\n" |
| " e;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b)\n" |
| " c;\n" |
| " else if (d)\n" |
| " e;\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| "if (a) {\n" |
| " if (b)\n" |
| " c;\n" |
| " else {\n" |
| " if (d)\n" |
| " e;\n" |
| " }\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (isa<VarDecl>(D)) {\n" |
| " for (auto *A : D.attrs())\n" |
| " if (shouldProcessAttr(A))\n" |
| " handleAttr(A);\n" |
| "}", |
| "if (isa<VarDecl>(D)) {\n" |
| " for (auto *A : D.attrs()) {\n" |
| " if (shouldProcessAttr(A)) {\n" |
| " handleAttr(A);\n" |
| " }\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("do {\n" |
| " ++I;\n" |
| "} while (hasMore() && Filter(*I));", |
| "do { ++I; } while (hasMore() && Filter(*I));", Style); |
| |
| verifyFormat("if (a)\n" |
| " if (b)\n" |
| " c;\n" |
| " else {\n" |
| " if (d)\n" |
| " e;\n" |
| " }\n" |
| "else\n" |
| " f;", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " if (b)\n" |
| " c;\n" |
| " else {\n" |
| " if (d)\n" |
| " e;\n" |
| " else if (f)\n" |
| " g;\n" |
| " }\n" |
| "else\n" |
| " h;", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " d;\n" |
| " e;\n" |
| "}", |
| "if (a) {\n" |
| " b;\n" |
| "} else {\n" |
| " if (c) {\n" |
| " d;\n" |
| " e;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| " c;\n" |
| "} else if (d) {\n" |
| " e;\n" |
| " f;\n" |
| "}", |
| "if (a) {\n" |
| " b;\n" |
| " c;\n" |
| "} else {\n" |
| " if (d) {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " d;\n" |
| "} else {\n" |
| " e;\n" |
| " f;\n" |
| "}", |
| "if (a) {\n" |
| " b;\n" |
| "} else {\n" |
| " if (c) {\n" |
| " d;\n" |
| " } else {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " d;\n" |
| "} else if (e) {\n" |
| " f;\n" |
| " g;\n" |
| "}", |
| "if (a) {\n" |
| " b;\n" |
| "} else {\n" |
| " if (c) {\n" |
| " d;\n" |
| " } else if (e) {\n" |
| " f;\n" |
| " g;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b)\n" |
| " c;\n" |
| " else if (d) {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| "if (a) {\n" |
| " if (b)\n" |
| " c;\n" |
| " else {\n" |
| " if (d) {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| " }\n" |
| "} else {\n" |
| " g;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " if (b)\n" |
| " c;\n" |
| " else {\n" |
| " if (d) {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| " }\n" |
| "else\n" |
| " g;", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| " c;\n" |
| "} else { // comment\n" |
| " if (d) {\n" |
| " e;\n" |
| " f;\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b;\n" |
| "else if (c)\n" |
| " while (d)\n" |
| " e;\n" |
| "// comment", |
| "if (a)\n" |
| "{\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " while (d) {\n" |
| " e;\n" |
| " }\n" |
| "}\n" |
| "// comment", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " d;\n" |
| "} else {\n" |
| " e;\n" |
| " g;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b;\n" |
| "} else if (c) {\n" |
| " d;\n" |
| "} else {\n" |
| " e;\n" |
| "} // comment", |
| Style); |
| |
| verifyFormat("int abs = [](int i) {\n" |
| " if (i >= 0)\n" |
| " return i;\n" |
| " return -i;\n" |
| "};", |
| "int abs = [](int i) {\n" |
| " if (i >= 0) {\n" |
| " return i;\n" |
| " }\n" |
| " return -i;\n" |
| "};", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " foo();\n" |
| "else\n" |
| " bar();", |
| "if (a)\n" |
| "{\n" |
| " foo();\n" |
| "}\n" |
| "else\n" |
| "{\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " foo();\n" |
| "// comment\n" |
| "else\n" |
| " bar();", |
| "if (a) {\n" |
| " foo();\n" |
| "}\n" |
| "// comment\n" |
| "else {\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " if (b)\n" |
| " c = 1; // comment\n" |
| "}", |
| "if (a) {\n" |
| " if (b) {\n" |
| " c = 1; // comment\n" |
| " }\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| "Label:\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| "Label:\n" |
| " f();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " f();\n" |
| "Label:\n" |
| "}", |
| Style); |
| |
| verifyFormat("if consteval {\n" |
| " f();\n" |
| "} else {\n" |
| " g();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if not consteval {\n" |
| " f();\n" |
| "} else if (a) {\n" |
| " g();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if !consteval {\n" |
| " g();\n" |
| "}", |
| Style); |
| |
| Style.ColumnLimit = 65; |
| verifyFormat("if (condition) {\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "} else {\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "}", |
| Style); |
| |
| Style.ColumnLimit = 20; |
| |
| verifyFormat("int i;\n" |
| "#define FOO(a, b) \\\n" |
| " while (a) { \\\n" |
| " b; \\\n" |
| " }", |
| Style); |
| |
| verifyFormat("int ab = [](int i) {\n" |
| " if (i > 0) {\n" |
| " i = 12345678 -\n" |
| " i;\n" |
| " }\n" |
| " return i;\n" |
| "};", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b = c + // 1 -\n" |
| " d;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) {\n" |
| " b = c >= 0 ? d\n" |
| " : e;\n" |
| "}", |
| "if (a) {\n" |
| " b = c >= 0 ? d : e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b = c > 0 ? d : e;", |
| "if (a) {\n" |
| " b = c > 0 ? d : e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (-b >=\n" |
| " c) { // Keep.\n" |
| " foo();\n" |
| "} else {\n" |
| " bar();\n" |
| "}", |
| "if (-b >= c) { // Keep.\n" |
| " foo();\n" |
| "} else {\n" |
| " bar();\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a) /* Remove. */\n" |
| " f();\n" |
| "else\n" |
| " g();", |
| "if (a) <% /* Remove. */\n" |
| " f();\n" |
| "%> else <%\n" |
| " g();\n" |
| "%>", |
| Style); |
| |
| verifyFormat("while (\n" |
| " !i--) <% // Keep.\n" |
| " foo();\n" |
| "%>", |
| "while (!i--) <% // Keep.\n" |
| " foo();\n" |
| "%>", |
| Style); |
| |
| verifyFormat("for (int &i : chars)\n" |
| " ++i;", |
| "for (int &i :\n" |
| " chars) {\n" |
| " ++i;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b;\n" |
| "else if (c) {\n" |
| " d;\n" |
| " e;\n" |
| "} else\n" |
| " f = g(foo, bar,\n" |
| " baz);", |
| "if (a)\n" |
| " b;\n" |
| "else {\n" |
| " if (c) {\n" |
| " d;\n" |
| " e;\n" |
| " } else\n" |
| " f = g(foo, bar, baz);\n" |
| "}", |
| Style); |
| |
| Style.ColumnLimit = 0; |
| verifyFormat("if (a)\n" |
| " b234567890223456789032345678904234567890 = " |
| "c234567890223456789032345678904234567890;", |
| "if (a) {\n" |
| " b234567890223456789032345678904234567890 = " |
| "c234567890223456789032345678904234567890;\n" |
| "}", |
| Style); |
| |
| Style.BreakBeforeBraces = FormatStyle::BS_Custom; |
| Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always; |
| Style.BraceWrapping.BeforeElse = true; |
| |
| Style.ColumnLimit = 65; |
| |
| verifyFormat("if (condition)\n" |
| "{\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "}\n" |
| "else\n" |
| "{\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "}", |
| "if (condition) {\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "} else {\n" |
| " ff(Indices,\n" |
| " [&](unsigned LHSI, unsigned RHSI) { return true; });\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| "{ //\n" |
| " foo();\n" |
| "}", |
| "if (a) { //\n" |
| " foo();\n" |
| "}", |
| Style); |
| |
| Style.ColumnLimit = 20; |
| |
| verifyFormat("int ab = [](int i) {\n" |
| " if (i > 0)\n" |
| " {\n" |
| " i = 12345678 -\n" |
| " i;\n" |
| " }\n" |
| " return i;\n" |
| "};", |
| "int ab = [](int i) {\n" |
| " if (i > 0) {\n" |
| " i = 12345678 -\n" |
| " i;\n" |
| " }\n" |
| " return i;\n" |
| "};", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| "{\n" |
| " b = c + // 1 -\n" |
| " d;\n" |
| "}", |
| "if (a) {\n" |
| " b = c + // 1 -\n" |
| " d;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| "{\n" |
| " b = c >= 0 ? d\n" |
| " : e;\n" |
| "}", |
| "if (a) {\n" |
| " b = c >= 0 ? d : e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (a)\n" |
| " b = c > 0 ? d : e;", |
| "if (a)\n" |
| "{\n" |
| " b = c > 0 ? d : e;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (foo + bar <=\n" |
| " baz)\n" |
| "{\n" |
| " func(arg1, arg2);\n" |
| "}", |
| "if (foo + bar <= baz) {\n" |
| " func(arg1, arg2);\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (foo + bar < baz)\n" |
| " func(arg1, arg2);\n" |
| "else\n" |
| " func();", |
| "if (foo + bar < baz)\n" |
| "<%\n" |
| " func(arg1, arg2);\n" |
| "%>\n" |
| "else\n" |
| "<%\n" |
| " func();\n" |
| "%>", |
| Style); |
| |
| verifyFormat("while (i--)\n" |
| "<% // Keep.\n" |
| " foo();\n" |
| "%>", |
| "while (i--) <% // Keep.\n" |
| " foo();\n" |
| "%>", |
| Style); |
| |
| verifyFormat("for (int &i : chars)\n" |
| " ++i;", |
| "for (int &i : chars)\n" |
| "{\n" |
| " ++i;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AlignAfterOpenBracketBlockIndent) { |
| auto Style = getLLVMStyle(); |
| |
| StringRef Short = "functionCall(paramA, paramB, paramC);\n" |
| "void functionDecl(int a, int b, int c);"; |
| |
| StringRef Medium = "functionCall(paramA, paramB, paramC, paramD, paramE, " |
| "paramF, paramG, paramH, paramI);\n" |
| "void functionDecl(int argumentA, int argumentB, int " |
| "argumentC, int argumentD, int argumentE);"; |
| |
| verifyFormat(Short, Style); |
| |
| StringRef NoBreak = "functionCall(paramA, paramB, paramC, paramD, paramE, " |
| "paramF, paramG, paramH,\n" |
| " paramI);\n" |
| "void functionDecl(int argumentA, int argumentB, int " |
| "argumentC, int argumentD,\n" |
| " int argumentE);"; |
| |
| verifyFormat(NoBreak, Medium, Style); |
| verifyFormat(NoBreak, |
| "functionCall(\n" |
| " paramA,\n" |
| " paramB,\n" |
| " paramC,\n" |
| " paramD,\n" |
| " paramE,\n" |
| " paramF,\n" |
| " paramG,\n" |
| " paramH,\n" |
| " paramI\n" |
| ");\n" |
| "void functionDecl(\n" |
| " int argumentA,\n" |
| " int argumentB,\n" |
| " int argumentC,\n" |
| " int argumentD,\n" |
| " int argumentE\n" |
| ");", |
| Style); |
| |
| verifyFormat("outerFunctionCall(nestedFunctionCall(argument1),\n" |
| " nestedLongFunctionCall(argument1, " |
| "argument2, argument3,\n" |
| " argument4, " |
| "argument5));", |
| Style); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; |
| |
| verifyFormat(Short, Style); |
| verifyFormat( |
| "functionCall(\n" |
| " paramA, paramB, paramC, paramD, paramE, paramF, paramG, paramH, " |
| "paramI\n" |
| ");\n" |
| "void functionDecl(\n" |
| " int argumentA, int argumentB, int argumentC, int argumentD, int " |
| "argumentE\n" |
| ");", |
| Medium, Style); |
| |
| Style.AllowAllArgumentsOnNextLine = false; |
| Style.AllowAllParametersOfDeclarationOnNextLine = false; |
| |
| verifyFormat(Short, Style); |
| verifyFormat( |
| "functionCall(\n" |
| " paramA, paramB, paramC, paramD, paramE, paramF, paramG, paramH, " |
| "paramI\n" |
| ");\n" |
| "void functionDecl(\n" |
| " int argumentA, int argumentB, int argumentC, int argumentD, int " |
| "argumentE\n" |
| ");", |
| Medium, Style); |
| |
| Style.BinPackArguments = false; |
| Style.BinPackParameters = false; |
| |
| verifyFormat(Short, Style); |
| |
| verifyFormat("functionCall(\n" |
| " paramA,\n" |
| " paramB,\n" |
| " paramC,\n" |
| " paramD,\n" |
| " paramE,\n" |
| " paramF,\n" |
| " paramG,\n" |
| " paramH,\n" |
| " paramI\n" |
| ");\n" |
| "void functionDecl(\n" |
| " int argumentA,\n" |
| " int argumentB,\n" |
| " int argumentC,\n" |
| " int argumentD,\n" |
| " int argumentE\n" |
| ");", |
| Medium, Style); |
| |
| verifyFormat("outerFunctionCall(\n" |
| " nestedFunctionCall(argument1),\n" |
| " nestedLongFunctionCall(\n" |
| " argument1,\n" |
| " argument2,\n" |
| " argument3,\n" |
| " argument4,\n" |
| " argument5\n" |
| " )\n" |
| ");", |
| Style); |
| |
| verifyFormat("int a = (int)b;", Style); |
| verifyFormat("int a = (int)b;", |
| "int a = (\n" |
| " int\n" |
| ") b;", |
| Style); |
| |
| verifyFormat("return (true);", Style); |
| verifyFormat("return (true);", |
| "return (\n" |
| " true\n" |
| ");", |
| Style); |
| |
| verifyFormat("void foo();", Style); |
| verifyFormat("void foo();", |
| "void foo(\n" |
| ");", |
| Style); |
| |
| verifyFormat("void foo() {}", Style); |
| verifyFormat("void foo() {}", |
| "void foo(\n" |
| ") {\n" |
| "}", |
| Style); |
| |
| verifyFormat("auto string = std::string();", Style); |
| verifyFormat("auto string = std::string();", |
| "auto string = std::string(\n" |
| ");", |
| Style); |
| |
| verifyFormat("void (*functionPointer)() = nullptr;", Style); |
| verifyFormat("void (*functionPointer)() = nullptr;", |
| "void (\n" |
| " *functionPointer\n" |
| ")\n" |
| "(\n" |
| ") = nullptr;", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentIfStatement) { |
| auto Style = getLLVMStyle(); |
| |
| verifyFormat("if (foo()) {\n" |
| " return;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (quitelongarg !=\n" |
| " (alsolongarg - 1)) { // ABC is a very longgggggggggggg " |
| "comment\n" |
| " return;\n" |
| "}", |
| Style); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; |
| |
| verifyFormat("if (foo()) {\n" |
| " return;\n" |
| "}", |
| Style); |
| |
| verifyFormat("if (quitelongarg !=\n" |
| " (alsolongarg - 1)) { // ABC is a very longgggggggggggg " |
| "comment\n" |
| " return;\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AlignAfterOpenBracketBlockIndentForStatement) { |
| auto Style = getLLVMStyle(); |
| |
| verifyFormat("for (int i = 0; i < 5; ++i) {\n" |
| " doSomething();\n" |
| "}", |
| Style); |
| |
| verifyFormat("for (int myReallyLongCountVariable = 0; " |
| "myReallyLongCountVariable < count;\n" |
| " myReallyLongCountVariable++) {\n" |
| " doSomething();\n" |
| "}", |
| Style); |
| |
| Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; |
| |
| verifyFormat("for (int i = 0; i < 5; ++i) {\n" |
| " doSomething();\n" |
| "}", |
| Style); |
| |
| verifyFormat("for (int myReallyLongCountVariable = 0; " |
| "myReallyLongCountVariable < count;\n" |
| " myReallyLongCountVariable++) {\n" |
| " doSomething();\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, UnderstandsDigraphs) { |
| verifyFormat("int arr<:5:> = {};"); |
| verifyFormat("int arr[5] = <%%>;"); |
| verifyFormat("int arr<:::qualified_variable:> = {};"); |
| verifyFormat("int arr[::qualified_variable] = <%%>;"); |
| verifyFormat("%:include <header>"); |
| verifyFormat("%:define A x##y"); |
| verifyFormat("#define A x%:%:y"); |
| } |
| |
| TEST_F(FormatTest, AlignArrayOfStructuresLeftAlignmentNonSquare) { |
| auto Style = getLLVMStyle(); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Left; |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| |
| // The AlignArray code is incorrect for non square Arrays and can cause |
| // crashes, these tests assert that the array is not changed but will |
| // also act as regression tests for when it is properly fixed |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3, 4, 5},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3, 4, 5},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8, 9, 10, 11, 12}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8, 9, 10, 11, 12}\n" |
| "};", |
| Style); |
| |
| verifyFormat("S{\n" |
| " {},\n" |
| " {},\n" |
| " {a, b}\n" |
| "};", |
| Style); |
| verifyFormat("S{\n" |
| " {},\n" |
| " {},\n" |
| " {a, b},\n" |
| "};", |
| Style); |
| verifyFormat("void foo() {\n" |
| " auto thing = test{\n" |
| " {\n" |
| " {13}, {something}, // A\n" |
| " }\n" |
| " };\n" |
| "}", |
| "void foo() {\n" |
| " auto thing = test{\n" |
| " {\n" |
| " {13},\n" |
| " {something}, // A\n" |
| " }\n" |
| " };\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, AlignArrayOfStructuresRightAlignmentNonSquare) { |
| auto Style = getLLVMStyle(); |
| Style.AlignArrayOfStructures = FormatStyle::AIAS_Right; |
| Style.AlignConsecutiveAssignments.Enabled = true; |
| Style.AlignConsecutiveDeclarations.Enabled = true; |
| |
| // The AlignArray code is incorrect for non square Arrays and can cause |
| // crashes, these tests assert that the array is not changed but will |
| // also act as regression tests for when it is properly fixed |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3, 4, 5},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3, 4, 5},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8, 9, 10, 11, 12}\n" |
| "};", |
| Style); |
| verifyFormat("struct test demo[] = {\n" |
| " {1, 2, 3},\n" |
| " {3, 4, 5},\n" |
| " {6, 7, 8, 9, 10, 11, 12}\n" |
| "};", |
| Style); |
| |
| verifyFormat("S{\n" |
| " {},\n" |
| " {},\n" |
| " {a, b}\n" |
| "};", |
| Style); |
| verifyFormat("S{\n" |
| " {},\n" |
| " {},\n" |
| " {a, b},\n" |
| "};", |
| Style); |
| verifyFormat("void foo() {\n" |
| " auto thing = test{\n" |
| " {\n" |
| " {13}, {something}, // A\n" |
| " }\n" |
| " };\n" |
| "}", |
| "void foo() {\n" |
| " auto thing = test{\n" |
| " {\n" |
| " {13},\n" |
| " {something}, // A\n" |
| " }\n" |
| " };\n" |
| "}", |
| Style); |
| } |
| |
| TEST_F(FormatTest, FormatsVariableTemplates) { |
| verifyFormat("inline bool var = is_integral_v<int> && is_signed_v<int>;"); |
| verifyFormat("template <typename T> " |
| "inline bool var = is_integral_v<T> && is_signed_v<T>;"); |
| } |
| |
| } // namespace |
| } // namespace format |
| } // namespace clang |