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