blob: 6cffb3b238ee26bd072ff03976d560fc9f513779 [file] [log] [blame]
//===- unittest/Format/FormatTest.cpp - Formatting unit tests -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/Format/Format.h"
#include "../Tooling/ReplacementTest.h"
#include "FormatTestUtils.h"
#include "clang/Frontend/TextDiagnosticPrinter.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;
namespace clang {
namespace format {
namespace {
FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
class FormatTest : public ::testing::Test {
protected:
enum IncompleteCheck {
IC_ExpectComplete,
IC_ExpectIncomplete,
IC_DoNotCheck
};
std::string format(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(),
IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
DEBUG(llvm::errs() << "---\n");
DEBUG(llvm::errs() << Code << "\n\n");
std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
bool IncompleteFormat = false;
tooling::Replacements Replaces =
reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
if (CheckIncomplete != IC_DoNotCheck) {
bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
}
ReplacementCount = Replaces.size();
auto Result = applyAllReplacements(Code, Replaces);
EXPECT_TRUE(static_cast<bool>(Result));
DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
return *Result;
}
FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
FormatStyle Style = getLLVMStyle();
Style.ColumnLimit = ColumnLimit;
return Style;
}
FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) {
FormatStyle Style = getGoogleStyle();
Style.ColumnLimit = ColumnLimit;
return Style;
}
void verifyFormat(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
}
void verifyIncompleteFormat(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
EXPECT_EQ(Code.str(),
format(test::messUp(Code), Style, IC_ExpectIncomplete));
}
void verifyGoogleFormat(llvm::StringRef Code) {
verifyFormat(Code, getGoogleStyle());
}
void verifyIndependentOfContext(llvm::StringRef text) {
verifyFormat(text);
verifyFormat(llvm::Twine("void f() { " + text + " }").str());
}
/// \brief Verify that clang-format does not crash on the given input.
void verifyNoCrash(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle()) {
format(Code, Style, IC_DoNotCheck);
}
int ReplacementCount;
};
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"));
}
//===----------------------------------------------------------------------===//
// 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("bool a = 2 < ::SomeFunction();");
}
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("extern /**/ \"C\" /**/ {\n"
"\n"
"int i;\n"
"}",
format("extern /**/ \"C\" /**/ {\n"
"\n"
"int i;\n"
"}",
getGoogleStyle()));
// ...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"
"}"));
// FIXME: This is slightly inconsistent.
EXPECT_EQ("namespace {\n"
"int i;\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"));
}
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);");
}
//===----------------------------------------------------------------------===//
// 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();");
FormatStyle AllowsMergedIf = getLLVMStyle();
AllowsMergedIf.AlignEscapedNewlinesLeft = true;
AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
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);
AllowsMergedIf.ColumnLimit = 14;
verifyFormat("if (a) return;", AllowsMergedIf);
verifyFormat("if (aaaaaaaaa)\n"
" return;",
AllowsMergedIf);
AllowsMergedIf.ColumnLimit = 13;
verifyFormat("if (a)\n return;", 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);
}
TEST_F(FormatTest, FormatShortBracedStatements) {
FormatStyle AllowSimpleBracedStatements = getLLVMStyle();
AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true;
AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("for (;;) { f(); }", 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("template <int> struct A2 {\n"
" struct B {};\n"
"};",
AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
verifyFormat("if (true) {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
verifyFormat("if (true) {\n"
" f();\n"
"} else {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
verifyFormat("while (true) {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
verifyFormat("for (;;) {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
}
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("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"
"}\n"
"// or else ..\n"
"else {\n"
" g()\n"
"}");
verifyFormat("if (a) {\n"
"} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n"
"}");
verifyFormat("if (a) {\n"
"} else if (\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n"
"}",
getLLVMStyleWithColumns(62));
}
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) {");
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);
}
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"
"}");
// 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");
}
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"
" // On B:\n"
" case B:\n"
" g();\n"
" break;\n"
" }\n"
"});");
verifyFormat("switch (a) {\n"
"case (b):\n"
" return;\n"
"}");
verifyFormat("switch (a) {\n"
"case some_namespace::\n"
" some_constant:\n"
" return;\n"
"}",
getLLVMStyleWithColumns(34));
}
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, 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"
"#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);
}
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"
"}");
}
//===----------------------------------------------------------------------===//
// Tests for comments.
//===----------------------------------------------------------------------===//
TEST_F(FormatTest, UnderstandsSingleLineComments) {
verifyFormat("//* */");
verifyFormat("// line 1\n"
"// line 2\n"
"void f() {}\n");
verifyFormat("void f() {\n"
" // Doesn't do anything\n"
"}");
verifyFormat("SomeObject\n"
" // Calling someFunction on SomeObject\n"
" .someFunction();");
verifyFormat("auto result = SomeObject\n"
" // Calling someFunction on SomeObject\n"
" .someFunction();");
verifyFormat("void f(int i, // some comment (probably for i)\n"
" int j, // some comment (probably for j)\n"
" int k); // some comment (probably for k)");
verifyFormat("void f(int i,\n"
" // some comment (probably for j)\n"
" int j,\n"
" // some comment (probably for k)\n"
" int k);");
verifyFormat("int i // This is a fancy variable\n"
" = 5; // with nicely aligned comment.");
verifyFormat("// Leading comment.\n"
"int a; // Trailing comment.");
verifyFormat("int a; // Trailing comment\n"
" // on 2\n"
" // or 3 lines.\n"
"int b;");
verifyFormat("int a; // Trailing comment\n"
"\n"
"// Leading comment.\n"
"int b;");
verifyFormat("int a; // Comment.\n"
" // More details.\n"
"int bbbb; // Another comment.");
verifyFormat(
"int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
"int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // comment\n"
"int cccccccccccccccccccccccccccccc; // comment\n"
"int ddd; // looooooooooooooooooooooooong comment\n"
"int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n"
"int bbbbbbbbbbbbbbbbbbbbb; // comment\n"
"int ccccccccccccccccccc; // comment");
verifyFormat("#include \"a\" // comment\n"
"#include \"a/b/c\" // comment");
verifyFormat("#include <a> // comment\n"
"#include <a/b/c> // comment");
EXPECT_EQ("#include \"a\" // comment\n"
"#include \"a/b/c\" // comment",
format("#include \\\n"
" \"a\" // comment\n"
"#include \"a/b/c\" // comment"));
verifyFormat("enum E {\n"
" // comment\n"
" VAL_A, // comment\n"
" VAL_B\n"
"};");
verifyFormat(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment");
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
" // Comment inside a statement.\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
verifyFormat("SomeFunction(a,\n"
" // comment\n"
" b + x);");
verifyFormat("SomeFunction(a, a,\n"
" // comment\n"
" b + x);");
verifyFormat(
"bool aaaaaaaaaaaaa = // comment\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
verifyFormat("int aaaa; // aaaaa\n"
"int aa; // aaaaaaa",
getLLVMStyleWithColumns(20));
EXPECT_EQ("void f() { // This does something ..\n"
"}\n"
"int a; // This is unrelated",
format("void f() { // This does something ..\n"
" }\n"
"int a; // This is unrelated"));
EXPECT_EQ("class C {\n"
" void f() { // This does something ..\n"
" } // awesome..\n"
"\n"
" int a; // This is unrelated\n"
"};",
format("class C{void f() { // This does something ..\n"
" } // awesome..\n"
" \n"
"int a; // This is unrelated\n"
"};"));
EXPECT_EQ("int i; // single line trailing comment",
format("int i;\\\n// single line trailing comment"));
verifyGoogleFormat("int a; // Trailing comment.");
verifyFormat("someFunction(anotherFunction( // Force break.\n"
" parameter));");
verifyGoogleFormat("#endif // HEADER_GUARD");
verifyFormat("const char *test[] = {\n"
" // A\n"
" \"aaaa\",\n"
" // B\n"
" \"aaaaa\"};");
verifyGoogleFormat(
"aaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaa); // 81_cols_with_this_comment");
EXPECT_EQ("D(a, {\n"
" // test\n"
" int a;\n"
"});",
format("D(a, {\n"
"// test\n"
"int a;\n"
"});"));
EXPECT_EQ("lineWith(); // comment\n"
"// at start\n"
"otherLine();",
format("lineWith(); // comment\n"
"// at start\n"
"otherLine();"));
EXPECT_EQ("lineWith(); // comment\n"
"/*\n"
" * at start */\n"
"otherLine();",
format("lineWith(); // comment\n"
"/*\n"
" * at start */\n"
"otherLine();"));
EXPECT_EQ("lineWith(); // comment\n"
" // at start\n"
"otherLine();",
format("lineWith(); // comment\n"
" // at start\n"
"otherLine();"));
EXPECT_EQ("lineWith(); // comment\n"
"// at start\n"
"otherLine(); // comment",
format("lineWith(); // comment\n"
"// at start\n"
"otherLine(); // comment"));
EXPECT_EQ("lineWith();\n"
"// at start\n"
"otherLine(); // comment",
format("lineWith();\n"
" // at start\n"
"otherLine(); // comment"));
EXPECT_EQ("// first\n"
"// at start\n"
"otherLine(); // comment",
format("// first\n"
" // at start\n"
"otherLine(); // comment"));
EXPECT_EQ("f();\n"
"// first\n"
"// at start\n"
"otherLine(); // comment",
format("f();\n"
"// first\n"
" // at start\n"
"otherLine(); // comment"));
verifyFormat("f(); // comment\n"
"// first\n"
"// at start\n"
"otherLine();");
EXPECT_EQ("f(); // comment\n"
"// first\n"
"// at start\n"
"otherLine();",
format("f(); // comment\n"
"// first\n"
" // at start\n"
"otherLine();"));
EXPECT_EQ("f(); // comment\n"
" // first\n"
"// at start\n"
"otherLine();",
format("f(); // comment\n"
" // first\n"
"// at start\n"
"otherLine();"));
EXPECT_EQ("void f() {\n"
" lineWith(); // comment\n"
" // at start\n"
"}",
format("void f() {\n"
" lineWith(); // comment\n"
" // at start\n"
"}"));
EXPECT_EQ("int xy; // a\n"
"int z; // b",
format("int xy; // a\n"
"int z; //b"));
EXPECT_EQ("int xy; // a\n"
"int z; // bb",
format("int xy; // a\n"
"int z; //bb",
getLLVMStyleWithColumns(12)));
verifyFormat("#define A \\\n"
" int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
" int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
getLLVMStyleWithColumns(60));
verifyFormat(
"#define A \\\n"
" int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n"
" int jjjjjjjjjjjjjjjjjjjjjjjj; /* */",
getLLVMStyleWithColumns(61));
verifyFormat("if ( // This is some comment\n"
" x + 3) {\n"
"}");
EXPECT_EQ("if ( // This is some comment\n"
" // spanning two lines\n"
" x + 3) {\n"
"}",
format("if( // This is some comment\n"
" // spanning two lines\n"
" x + 3) {\n"
"}"));
verifyNoCrash("/\\\n/");
verifyNoCrash("/\\\n* */");
// The 0-character somehow makes the lexer return a proper comment.
verifyNoCrash(StringRef("/*\\\0\n/", 6));
}
TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) {
EXPECT_EQ("SomeFunction(a,\n"
" b, // comment\n"
" c);",
format("SomeFunction(a,\n"
" b, // comment\n"
" c);"));
EXPECT_EQ("SomeFunction(a, b,\n"
" // comment\n"
" c);",
format("SomeFunction(a,\n"
" b,\n"
" // comment\n"
" c);"));
EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n"
" c);",
format("SomeFunction(a, b, // comment (unclear relation)\n"
" c);"));
EXPECT_EQ("SomeFunction(a, // comment\n"
" b,\n"
" c); // comment",
format("SomeFunction(a, // comment\n"
" b,\n"
" c); // comment"));
}
TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) {
EXPECT_EQ("// comment", format("// comment "));
EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment",
format("int aaaaaaa, bbbbbbb; // comment ",
getLLVMStyleWithColumns(33)));
EXPECT_EQ("// comment\\\n", format("// comment\\\n \t \v \f "));
EXPECT_EQ("// comment \\\n", format("// comment \\\n \t \v \f "));
}
TEST_F(FormatTest, UnderstandsBlockComments) {
verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);");
verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }");
EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n"
" bbbbbbbbbbbbbbbbbbbbbbbbb);",
format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n"
"/* Trailing comment for aa... */\n"
" bbbbbbbbbbbbbbbbbbbbbbbbb);"));
EXPECT_EQ(
"f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);",
format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n"
"/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);"));
EXPECT_EQ(
"void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
"}",
format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaa ,\n"
" aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"
"}"));
verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
FormatStyle NoBinPacking = getLLVMStyle();
NoBinPacking.BinPackParameters = false;
verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n"
" /* parameter 2 */ aaaaaa,\n"
" /* parameter 3 */ aaaaaa,\n"
" /* parameter 4 */ aaaaaa);",
NoBinPacking);
// Aligning block comments in macros.
verifyGoogleFormat("#define A \\\n"
" int i; /*a*/ \\\n"
" int jjj; /*b*/");
}
TEST_F(FormatTest, AlignsBlockComments) {
EXPECT_EQ("/*\n"
" * Really multi-line\n"
" * comment.\n"
" */\n"
"void f() {}",
format(" /*\n"
" * Really multi-line\n"
" * comment.\n"
" */\n"
" void f() {}"));
EXPECT_EQ("class C {\n"
" /*\n"
" * Another multi-line\n"
" * comment.\n"
" */\n"
" void f() {}\n"
"};",
format("class C {\n"
"/*\n"
" * Another multi-line\n"
" * comment.\n"
" */\n"
"void f() {}\n"
"};"));
EXPECT_EQ("/*\n"
" 1. This is a comment with non-trivial formatting.\n"
" 1.1. We have to indent/outdent all lines equally\n"
" 1.1.1. to keep the formatting.\n"
" */",
format(" /*\n"
" 1. This is a comment with non-trivial formatting.\n"
" 1.1. We have to indent/outdent all lines equally\n"
" 1.1.1. to keep the formatting.\n"
" */"));
EXPECT_EQ("/*\n"
"Don't try to outdent if there's not enough indentation.\n"
"*/",
format(" /*\n"
" Don't try to outdent if there's not enough indentation.\n"
" */"));
EXPECT_EQ("int i; /* Comment with empty...\n"
" *\n"
" * line. */",
format("int i; /* Comment with empty...\n"
" *\n"
" * line. */"));
EXPECT_EQ("int foobar = 0; /* comment */\n"
"int bar = 0; /* multiline\n"
" comment 1 */\n"
"int baz = 0; /* multiline\n"
" comment 2 */\n"
"int bzz = 0; /* multiline\n"
" comment 3 */",
format("int foobar = 0; /* comment */\n"
"int bar = 0; /* multiline\n"
" comment 1 */\n"
"int baz = 0; /* multiline\n"
" comment 2 */\n"
"int bzz = 0; /* multiline\n"
" comment 3 */"));
EXPECT_EQ("int foobar = 0; /* comment */\n"
"int bar = 0; /* multiline\n"
" comment */\n"
"int baz = 0; /* multiline\n"
"comment */",
format("int foobar = 0; /* comment */\n"
"int bar = 0; /* multiline\n"
"comment */\n"
"int baz = 0; /* multiline\n"
"comment */"));
}
TEST_F(FormatTest, CommentReflowingCanBeTurnedOff) {
FormatStyle Style = getLLVMStyleWithColumns(20);
Style.ReflowComments = false;
verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style);
verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style);
}
TEST_F(FormatTest, CorrectlyHandlesLengthOfBlockComments) {
EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */",
format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */"));
EXPECT_EQ(
"void ffffffffffff(\n"
" int aaaaaaaa, int bbbbbbbb,\n"
" int cccccccccccc) { /*\n"
" aaaaaaaaaa\n"
" aaaaaaaaaaaaa\n"
" bbbbbbbbbbbbbb\n"
" bbbbbbbbbb\n"
" */\n"
"}",
format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n"
"{ /*\n"
" aaaaaaaaaa aaaaaaaaaaaaa\n"
" bbbbbbbbbbbbbb bbbbbbbbbb\n"
" */\n"
"}",
getLLVMStyleWithColumns(40)));
}
TEST_F(FormatTest, DontBreakNonTrailingBlockComments) {
EXPECT_EQ("void ffffffffff(\n"
" int aaaaa /* test */);",
format("void ffffffffff(int aaaaa /* test */);",
getLLVMStyleWithColumns(35)));
}
TEST_F(FormatTest, SplitsLongCxxComments) {
EXPECT_EQ("// A comment that\n"
"// doesn't fit on\n"
"// one line",
format("// A comment that doesn't fit on one line",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/// A comment that\n"
"/// doesn't fit on\n"
"/// one line",
format("/// A comment that doesn't fit on one line",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("//! A comment that\n"
"//! doesn't fit on\n"
"//! one line",
format("//! A comment that doesn't fit on one line",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("// a b c d\n"
"// e f g\n"
"// h i j k",
format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10)));
EXPECT_EQ(
"// a b c d\n"
"// e f g\n"
"// h i j k",
format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10)));
EXPECT_EQ("if (true) // A comment that\n"
" // doesn't fit on\n"
" // one line",
format("if (true) // A comment that doesn't fit on one line ",
getLLVMStyleWithColumns(30)));
EXPECT_EQ("// Don't_touch_leading_whitespace",
format("// Don't_touch_leading_whitespace",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("// Add leading\n"
"// whitespace",
format("//Add leading whitespace", getLLVMStyleWithColumns(20)));
EXPECT_EQ("/// Add leading\n"
"/// whitespace",
format("///Add leading whitespace", getLLVMStyleWithColumns(20)));
EXPECT_EQ("//! Add leading\n"
"//! whitespace",
format("//!Add leading whitespace", getLLVMStyleWithColumns(20)));
EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle()));
EXPECT_EQ("// Even if it makes the line exceed the column\n"
"// limit",
format("//Even if it makes the line exceed the column limit",
getLLVMStyleWithColumns(51)));
EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle()));
EXPECT_EQ("// aa bb cc dd",
format("// aa bb cc dd ",
getLLVMStyleWithColumns(15)));
EXPECT_EQ("// A comment before\n"
"// a macro\n"
"// definition\n"
"#define a b",
format("// A comment before a macro definition\n"
"#define a b",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("void ffffff(\n"
" int aaaaaaaaa, // wwww\n"
" int bbbbbbbbbb, // xxxxxxx\n"
" // yyyyyyyyyy\n"
" int c, int d, int e) {}",
format("void ffffff(\n"
" int aaaaaaaaa, // wwww\n"
" int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n"
" int c, int d, int e) {}",
getLLVMStyleWithColumns(40)));
EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
getLLVMStyleWithColumns(20)));
EXPECT_EQ(
"#define XXX // a b c d\n"
" // e f g h",
format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22)));
EXPECT_EQ(
"#define XXX // q w e r\n"
" // t y u i",
format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22)));
}
TEST_F(FormatTest, PreservesHangingIndentInCxxComments) {
EXPECT_EQ("// A comment\n"
"// that doesn't\n"
"// fit on one\n"
"// line",
format("// A comment that doesn't fit on one line",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/// A comment\n"
"/// that doesn't\n"
"/// fit on one\n"
"/// line",
format("/// A comment that doesn't fit on one line",
getLLVMStyleWithColumns(20)));
}
TEST_F(FormatTest, DontSplitLineCommentsWithEscapedNewlines) {
EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
"// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
"// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
"// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n"
"// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
getLLVMStyleWithColumns(50)));
// FIXME: One day we might want to implement adjustment of leading whitespace
// of the consecutive lines in this kind of comment:
EXPECT_EQ("double\n"
" a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
" // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
getLLVMStyleWithColumns(49)));
}
TEST_F(FormatTest, DontSplitLineCommentsWithPragmas) {
FormatStyle Pragmas = getLLVMStyleWithColumns(30);
Pragmas.CommentPragmas = "^ IWYU pragma:";
EXPECT_EQ(
"// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb",
format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas));
EXPECT_EQ(
"/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */",
format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas));
}
TEST_F(FormatTest, PriorityOfCommentBreaking) {
EXPECT_EQ("if (xxx ==\n"
" yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
" zzz)\n"
" q();",
format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n"
" zzz) q();",
getLLVMStyleWithColumns(40)));
EXPECT_EQ("if (xxxxxxxxxx ==\n"
" yyy && // aaaaaa bbbbbbbb cccc\n"
" zzz)\n"
" q();",
format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n"
" zzz) q();",
getLLVMStyleWithColumns(40)));
EXPECT_EQ("if (xxxxxxxxxx &&\n"
" yyy || // aaaaaa bbbbbbbb cccc\n"
" zzz)\n"
" q();",
format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n"
" zzz) q();",
getLLVMStyleWithColumns(40)));
EXPECT_EQ("fffffffff(\n"
" &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
" zzz);",
format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
" zzz);",
getLLVMStyleWithColumns(40)));
}
TEST_F(FormatTest, MultiLineCommentsInDefines) {
EXPECT_EQ("#define A(x) /* \\\n"
" a comment \\\n"
" inside */ \\\n"
" f();",
format("#define A(x) /* \\\n"
" a comment \\\n"
" inside */ \\\n"
" f();",
getLLVMStyleWithColumns(17)));
EXPECT_EQ("#define A( \\\n"
" x) /* \\\n"
" a comment \\\n"
" inside */ \\\n"
" f();",
format("#define A( \\\n"
" x) /* \\\n"
" a comment \\\n"
" inside */ \\\n"
" f();",
getLLVMStyleWithColumns(17)));
}
TEST_F(FormatTest, ParsesCommentsAdjacentToPPDirectives) {
EXPECT_EQ("namespace {}\n// Test\n#define A",
format("namespace {}\n // Test\n#define A"));
EXPECT_EQ("namespace {}\n/* Test */\n#define A",
format("namespace {}\n /* Test */\n#define A"));
EXPECT_EQ("namespace {}\n/* Test */ #define A",
format("namespace {}\n /* Test */ #define A"));
}
TEST_F(FormatTest, SplitsLongLinesInComments) {
EXPECT_EQ("/* This is a long\n"
" * comment that\n"
" * doesn't\n"
" * fit on one line.\n"
" */",
format("/* "
"This is a long "
"comment that "
"doesn't "
"fit on one line. */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ(
"/* a b c d\n"
" * e f g\n"
" * h i j k\n"
" */",
format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10)));
EXPECT_EQ(
"/* a b c d\n"
" * e f g\n"
" * h i j k\n"
" */",
format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10)));
EXPECT_EQ("/*\n"
"This is a long\n"
"comment that doesn't\n"
"fit on one line.\n"
"*/",
format("/*\n"
"This is a long "
"comment that doesn't "
"fit on one line. \n"
"*/",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/*\n"
" * This is a long\n"
" * comment that\n"
" * doesn't fit on\n"
" * one line.\n"
" */",
format("/* \n"
" * This is a long "
" comment that "
" doesn't fit on "
" one line. \n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/*\n"
" * This_is_a_comment_with_words_that_dont_fit_on_one_line\n"
" * so_it_should_be_broken\n"
" * wherever_a_space_occurs\n"
" */",
format("/*\n"
" * This_is_a_comment_with_words_that_dont_fit_on_one_line "
" so_it_should_be_broken "
" wherever_a_space_occurs \n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/*\n"
" * This_comment_can_not_be_broken_into_lines\n"
" */",
format("/*\n"
" * This_comment_can_not_be_broken_into_lines\n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("{\n"
" /*\n"
" This is another\n"
" long comment that\n"
" doesn't fit on one\n"
" line 1234567890\n"
" */\n"
"}",
format("{\n"
"/*\n"
"This is another "
" long comment that "
" doesn't fit on one"
" line 1234567890\n"
"*/\n"
"}",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("{\n"
" /*\n"
" * This i s\n"
" * another comment\n"
" * t hat doesn' t\n"
" * fit on one l i\n"
" * n e\n"
" */\n"
"}",
format("{\n"
"/*\n"
" * This i s"
" another comment"
" t hat doesn' t"
" fit on one l i"
" n e\n"
" */\n"
"}",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/*\n"
" * This is a long\n"
" * comment that\n"
" * doesn't fit on\n"
" * one line\n"
" */",
format(" /*\n"
" * This is a long comment that doesn't fit on one line\n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("{\n"
" if (something) /* This is a\n"
" long\n"
" comment */\n"
" ;\n"
"}",
format("{\n"
" if (something) /* This is a long comment */\n"
" ;\n"
"}",
getLLVMStyleWithColumns(30)));
EXPECT_EQ("/* A comment before\n"
" * a macro\n"
" * definition */\n"
"#define a b",
format("/* A comment before a macro definition */\n"
"#define a b",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/* some comment\n"
" * a comment\n"
"* that we break\n"
" * another comment\n"
"* we have to break\n"
"* a left comment\n"
" */",
format(" /* some comment\n"
" * a comment that we break\n"
" * another comment we have to break\n"
"* a left comment\n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/**\n"
" * multiline block\n"
" * comment\n"
" *\n"
" */",
format("/**\n"
" * multiline block comment\n"
" *\n"
" */",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("/*\n"
"\n"
"\n"
" */\n",
format(" /* \n"
" \n"
" \n"
" */\n"));
EXPECT_EQ("/* a a */",
format("/* a a */", getLLVMStyleWithColumns(15)));
EXPECT_EQ("/* a a bc */",
format("/* a a bc */", getLLVMStyleWithColumns(15)));
EXPECT_EQ("/* aaa aaa\n"
" * aaaaa */",
format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15)));
EXPECT_EQ("/* aaa aaa\n"
" * aaaaa */",
format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15)));
}
TEST_F(FormatTest, SplitsLongLinesInCommentsInPreprocessor) {
EXPECT_EQ("#define X \\\n"
" /* \\\n"
" Test \\\n"
" Macro comment \\\n"
" with a long \\\n"
" line \\\n"
" */ \\\n"
" A + B",
format("#define X \\\n"
" /*\n"
" Test\n"
" Macro comment with a long line\n"
" */ \\\n"
" A + B",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("#define X \\\n"
" /* Macro comment \\\n"
" with a long \\\n"
" line */ \\\n"
" A + B",
format("#define X \\\n"
" /* Macro comment with a long\n"
" line */ \\\n"
" A + B",
getLLVMStyleWithColumns(20)));
EXPECT_EQ("#define X \\\n"
" /* Macro comment \\\n"
" * with a long \\\n"
" * line */ \\\n"
" A + B",
format("#define X \\\n"
" /* Macro comment with a long line */ \\\n"
" A + B",
getLLVMStyleWithColumns(20)));
}
TEST_F(FormatTest, CommentsInStaticInitializers) {
EXPECT_EQ(
"static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n"
" aaaaaaaaaaaaaaaaaaaa /* comment */,\n"
" /* comment */ aaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaa, // comment\n"
" aaaaaaaaaaaaaaaaaaaa};",
format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n"
" aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n"
" /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n"
" aaaaaaaaaaaaaaaaaaaa , // comment\n"
" aaaaaaaaaaaaaaaaaaaa };"));
verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n"
" bbbbbbbbbbb, ccccccccccc};");
verifyFormat("static SomeType type = {aaaaaaaaaaa,\n"
" // comment for bb....\n"
" bbbbbbbbbbb, ccccccccccc};");
verifyGoogleFormat(
"static SomeType type = {aaaaaaaaaaa, // comment for aa...\n"
" bbbbbbbbbbb, ccccccccccc};");
verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n"
" // comment for bb....\n"
" bbbbbbbbbbb, ccccccccccc};");
verifyFormat("S s = {{a, b, c}, // Group #1\n"
" {d, e, f}, // Group #2\n"
" {g, h, i}}; // Group #3");
verifyFormat("S s = {{// Group #1\n"
" a, b, c},\n"
" {// Group #2\n"
" d, e, f},\n"
" {// Group #3\n"
" g, h, i}};");
EXPECT_EQ("S s = {\n"
" // Some comment\n"
" a,\n"
"\n"
" // Comment after empty line\n"
" b}",
format("S s = {\n"
" // Some comment\n"
" a,\n"
" \n"
" // Comment after empty line\n"
" b\n"
"}"));
EXPECT_EQ("S s = {\n"
" /* Some comment */\n"
" a,\n"
"\n"
" /* Comment after empty line */\n"
" b}",
format("S s = {\n"
" /* Some comment */\n"
" a,\n"
" \n"
" /* Comment after empty line */\n"
" b\n"
"}"));
verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n"
" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n"
" 0x00, 0x00, 0x00, 0x00}; // comment\n");
}
TEST_F(FormatTest, IgnoresIf0Contents) {
EXPECT_EQ("#if 0\n"
"}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
"#endif\n"
"void f() {}",
format("#if 0\n"
"}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
"#endif\n"
"void f( ) { }"));
EXPECT_EQ("#if false\n"
"void f( ) { }\n"
"#endif\n"
"void g() {}\n",
format("#if false\n"
"void f( ) { }\n"
"#endif\n"
"void g( ) { }\n"));
EXPECT_EQ("enum E {\n"
" One,\n"
" Two,\n"
"#if 0\n"
"Three,\n"
" Four,\n"
"#endif\n"
" Five\n"
"};",
format("enum E {\n"
" One,Two,\n"
"#if 0\n"
"Three,\n"
" Four,\n"
"#endif\n"
" Five};"));
EXPECT_EQ("enum F {\n"
" One,\n"
"#if 1\n"
" Two,\n"
"#if 0\n"
"Three,\n"
" Four,\n"
"#endif\n"
" Five\n"
"#endif\n"
"};",
format("enum F {\n"
"One,\n"
"#if 1\n"
"Two,\n"
"#if 0\n"
"Three,\n"
" Four,\n"
"#endif\n"
"Five\n"
"#endif\n"
"};"));
EXPECT_EQ("enum G {\n"
" One,\n"
"#if 0\n"
"Two,\n"
"#else\n"
" Three,\n"
"#endif\n"
" Four\n"
"};",
format("enum G {\n"
"One,\n"
"#if 0\n"
"Two,\n"
"#else\n"
"Three,\n"
"#endif\n"
"Four\n"
"};"));
EXPECT_EQ("enum H {\n"
" One,\n"
"#if 0\n"
"#ifdef Q\n"
"Two,\n"
"#else\n"
"Three,\n"
"#endif\n"
"#endif\n"
" Four\n"
"};",
format("enum H {\n"
"One,\n"
"#if 0\n"
"#ifdef Q\n"
"Two,\n"
"#else\n"
"Three,\n"
"#endif\n"
"#endif\n"
"Four\n"
"};"));
EXPECT_EQ("enum I {\n"
" One,\n"
"#if /* test */ 0 || 1\n"
"Two,\n"
"Three,\n"
"#endif\n"
" Four\n"
"};",
format("enum I {\n"
"One,\n"
"#if /* test */ 0 || 1\n"
"Two,\n"
"Three,\n"
"#endif\n"
"Four\n"
"};"));
EXPECT_EQ("enum J {\n"
" One,\n"
"#if 0\n"
"#if 0\n"
"Two,\n"
"#else\n"
"Three,\n"
"#endif\n"
"Four,\n"
"#endif\n"
" Five\n"
"};",
format("enum J {\n"
"One,\n"
"#if 0\n"
"#if 0\n"
"Two,\n"
"#else\n"
"Three,\n"
"#endif\n"
"Four,\n"
"#endif\n"
"Five\n"
"};"));
}
//===----------------------------------------------------------------------===//
// 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"
"};");
verifyGoogleFormat("class A {\n"
" public:\n"
" protected:\n"
" private:\n"
" void f() {}\n"
"};");
verifyFormat("class A {\n"
"public slots:\n"
" void f1() {}\n"
"public Q_SLOTS:\n"
" void f2() {}\n"
"protected slots:\n"
" void f3() {}\n"
"protected Q_SLOTS:\n"
" void f4() {}\n"
"private slots:\n"
" void f5() {}\n"
"private Q_SLOTS:\n"
" void f6() {}\n"
"signals:\n"
" void g1();\n"
"Q_SIGNALS:\n"
" void g2();\n"
"};");
// Don't interpret 'signals' the wrong way.
verifyFormat("signals.set();");
verifyFormat("for (Signals signals : f()) {\n}");
verifyFormat("{\n"
" signals.set(); // This needs indentation.\n"
"}");
verifyFormat("void f() {\n"
"label:\n"
" signals.baz();\n"
"}");
}
TEST_F(FormatTest, SeparatesLogicalBlocks) {
EXPECT_EQ("class A {\n"
"public:\n"
" void f();\n"
"\n"
"private:\n"
" void g() {}\n"
" // test\n"
"protected:\n"
" int h;\n"
"};",
format("class A {\n"
"public:\n"
"void f();\n"
"private:\n"
"void g() {}\n"
"// test\n"
"protected:\n"
"int h;\n"
"};"));
EXPECT_EQ("class A {\n"
"protected:\n"
"public:\n"
" void f();\n"
"};",
format("class A {\n"
"protected:\n"
"\n"
"public:\n"
"\n"
" void f();\n"
"};"));
// Even ensure proper spacing inside macros.
EXPECT_EQ("#define B \\\n"
" class A { \\\n"
" protected: \\\n"
" public: \\\n"
" void f(); \\\n"
" };",
format("#define B \\\n"
" class A { \\\n"
" protected: \\\n"
" \\\n"
" public: \\\n"
" \\\n"
" void f(); \\\n"
" };",
getGoogleStyle()));
// But don't remove empty lines after macros ending in access specifiers.
EXPECT_EQ("#define A private:\n"
"\n"
"int i;",
format("#define A private:\n"
"\n"
"int i;"));
}
TEST_F(FormatTest, FormatsClasses) {
verifyFormat("class A : public B {};");
verifyFormat("class A : public ::B {};");
verifyFormat(
"class AAAAAAAAAAAAAAAAAAAA : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n"
" public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};");
verifyFormat("class AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
" : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n"
" public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC {};");
verifyFormat(
"class A : public B, public C, public D, public E, public F {};");
verifyFormat("class AAAAAAAAAAAA : public B,\n"
" public C,\n"
" public D,\n"
" public E,\n"
" public F,\n"
" public G {};");
verifyFormat("class\n"
" ReallyReallyLongClassName {\n"
" int i;\n"
"};",
getLLVMStyleWithColumns(32));
verifyFormat("struct aaaaaaaaaaaaa : public aaaaaaaaaaaaaaaaaaa< // break\n"
" aaaaaaaaaaaaaaaa> {};");
verifyFormat("struct aaaaaaaaaaaaaaaaaaaa\n"
" : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaaaa> {};");
verifyFormat("template <class R, class C>\n"
"struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n"
" : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};");
verifyFormat("class ::A::B {};");
}
TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) {
verifyFormat("class A {\n} a, b;");
verifyFormat("struct A {\n} a, b;");
verifyFormat("union A {\n} a;");
}
TEST_F(FormatTest, FormatsEnum) {
verifyFormat("enum {\n"
" Zero,\n"
" One = 1,\n"
" Two = One + 1,\n"
" Three = (One + Two),\n"
" Four = (Zero && (One ^ Two)) | (One << Two),\n"
" Five = (One, Two, Three, Four, 5)\n"
"};");
verifyGoogleFormat("enum {\n"
" Zero,\n"
" One = 1,\n"
" Two = One + 1,\n"
" Three = (One + Two),\n"
" Four = (Zero && (One ^ Two)) | (One << Two),\n"
" Five = (One, Two, Three, Four, 5)\n"
"};");
verifyFormat("enum Enum {};");
verifyFormat("enum {};");
verifyFormat("enum X E {} d;");
verifyFormat("enum __attribute__((...)) E {} d;");
verifyFormat("enum __declspec__((...)) E {} d;");
verifyFormat("enum {\n"
" Bar = Foo<int, int>::value\n"
"};",
getLLVMStyleWithColumns(30));
verifyFormat("enum ShortEnum { A, B, C };");
verifyGoogleFormat("enum ShortEnum { A, B, C };");
EXPECT_EQ("enum KeepEmptyLines {\n"
" ONE,\n"
"\n"
" TWO,\n"
"\n"
" THREE\n"
"}",
format("enum KeepEmptyLines {\n"
" ONE,\n"
"\n"
" TWO,\n"
"\n"
"\n"
" THREE\n"
"}"));
verifyFormat("enum E { // comment\n"
" ONE,\n"
" TWO\n"
"};\n"
"int i;");
// Not enums.
verifyFormat("enum X f() {\n"
" a();\n"
" return 42;\n"
"}");
verifyFormat("enum X Type::f() {\n"
" a();\n"
" return 42;\n"
"}");
verifyFormat("enum ::X f() {\n"
" a();\n"
" return 42;\n"
"}");
verifyFormat("enum ns::X f() {\n"
" a();\n"
" return 42;\n"
"}");
}
TEST_F(FormatTest, FormatsEnumsWithErrors) {
verifyFormat("enum Type {\n"
" One = 0; // These semicolons should be commas.\n"
" Two = 1;\n"
"};");
verifyFormat("namespace n {\n"
"enum Type {\n"
" One,\n"
" Two, // missing };\n"
" int i;\n"
"}\n"
"void g() {}");
}
TEST_F(FormatTest, FormatsEnumStruct) {
verifyFormat("enum struct {\n"
" Zero,\n"
" One = 1,\n"
" Two = One + 1,\n"
" Three = (One + Two),\n"
" Four = (Zero && (One ^ Two)) | (One << Two),\n"
" Five = (One, Two, Three, Four, 5)\n"
"};");
verifyFormat("enum struct Enum {};");
verifyFormat("enum struct {};");
verifyFormat("enum struct X E {} d;");
verifyFormat("enum struct __attribute__((...)) E {} d;");
verifyFormat("enum struct __declspec__((...)) E {} d;");
verifyFormat("enum struct X f() {\n a();\n return 42;\n}");
}
TEST_F(FormatTest, FormatsEnumClass) {
verifyFormat("enum class {\n"
" Zero,\n"
" One = 1,\n"
" Two = One + 1,\n"
" Three = (One + Two),\n"
" Four = (Zero && (One ^ Two)) | (One << Two),\n"
" Five = (One, Two, Three, Four, 5)\n"
"};");
verifyFormat("enum class Enum {};");
verifyFormat("enum class {};");
verifyFormat("enum class X E {} d;");
verifyFormat("enum class __attribute__((...)) E {} d;");
verifyFormat("enum class __declspec__((...)) E {} d;");
verifyFormat("enum class X f() {\n a();\n return 42;\n}");
}
TEST_F(FormatTest, FormatsEnumTypes) {
verifyFormat("enum X : int {\n"
" A, // Force multiple lines.\n"
" B\n"
"};");
verifyFormat("enum X : int { A, B };");
verifyFormat("enum X : std::uint32_t { A, B };");
}
TEST_F(FormatTest, FormatsNSEnums) {
verifyGoogleFormat("typedef NS_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_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_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"
"};");
}
TEST_F(FormatTest, FormatsNamespaces) {
verifyFormat("namespace some_namespace {\n"
"class A {};\n"
"void f() { f(); }\n"
"}");
verifyFormat("namespace {\n"
"class A {};\n"
"void f() { f(); }\n"
"}");
verifyFormat("inline namespace X {\n"
"class A {};\n"
"void f() { f(); }\n"
"}");
verifyFormat("using namespace some_namespace;\n"
"class A {};\n"
"void f() { f(); }");
// 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 {};");
verifyFormat("namespace {\n"
"class A {};\n"
"};");
verifyFormat("namespace {\n"
"int SomeVariable = 0; // comment\n"
"} // namespace");
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"));
EXPECT_EQ("namespace A::B {\n"
"class C {};\n"
"}",
format("namespace A::B {\n"
"class C {};\n"
"}"));
FormatStyle Style = getLLVMStyle();
Style.NamespaceIndentation = FormatStyle::NI_All;
EXPECT_EQ("namespace out {\n"
" int i;\n"
" namespace in {\n"
" int i;\n"
" } // namespace\n"
"} // namespace",
format("namespace out {\n"
"int i;\n"
"namespace in {\n"
"int i;\n"
"} // namespace\n"
"} // namespace",
Style));
Style.NamespaceIndentation = FormatStyle::NI_Inner;
EXPECT_EQ("namespace out {\n"
"int i;\n"
"namespace in {\n"
" int i;\n"
"} // namespace\n"
"} // namespace",
format("namespace out {\n"
"int i;\n"
"namespace in {\n"
"int i;\n"
"} // namespace\n"
"} // namespace",
Style));
}
TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); }
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");
// Incomplete try-catch blocks.
verifyIncompleteFormat("try {} catch (");
}
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_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, FormatObjCTryCatch) {
verifyFormat("@try {\n"
" f();\n"
"} @catch (NSException e) {\n"
" @throw;\n"
"} @finally {\n"
" exit(42);\n"
"}");
verifyFormat("DEBUG({\n"
" @try {\n"
" } @finally {\n"
" }\n"
"});\n");
}
TEST_F(FormatTest, FormatObjCAutoreleasepool) {
FormatStyle Style = getLLVMStyle();
verifyFormat("@autoreleasepool {\n"
" f();\n"
"}\n"
"@autoreleasepool {\n"
" f();\n"
"}\n",
Style);
Style.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("@autoreleasepool\n"
"{\n"
" f();\n"
"}\n"
"@autoreleasepool\n"
"{\n"
" f();\n"
"}\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};");
}
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, 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()));
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)"));
}
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"
"}",
format("SOME_MACRO\n"
" namespace {\n"
"void f( );\n"
"}"));
// 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));
}
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"
"};"));
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(>)");
}
TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) {
verifyFormat("#define A \\\n"
" f({ \\\n"
" g(); \\\n"
" });",
getLLVMStyleWithColumns(11));
}
TEST_F(FormatTest, IndentPreprocessorDirectivesAtZero) {
EXPECT_EQ("{\n {\n#define A\n }\n}", format("{{\n#define A\n}}"));
}
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) {
EXPECT_EQ(
"#define A \\\n int i; \\\n int j;",
format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11)));
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>"));
}
TEST_F(FormatTest, DontCrashOnBlockComments) {
EXPECT_EQ(
"int xxxxxxxxx; /* "
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n"
"zzzzzz\n"
"0*/",
format("int xxxxxxxxx; /* "
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n"
"0*/"));
}
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 = true;
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(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 {}");
}
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 && 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("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"
"}");
// 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"
"}");
FormatStyle OnePerLine = getLLVMStyle();
OnePerLine.BinPackParameters = false;
verifyFormat(
"if (aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}",
OnePerLine);
}
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}");