Add option to put short loops on a single line.

This enables things like:

for (int &v : vec) v *= 2;

Enabled for Google style.

llvm-svn: 182000
This commit is contained in:
Daniel Jasper 2013-05-16 12:12:21 +00:00
parent 41942fb37a
commit 3a685df7e0
3 changed files with 55 additions and 13 deletions

View File

@ -86,6 +86,9 @@ struct FormatStyle {
/// \brief If true, "if (a) return;" can be put on a single line. /// \brief If true, "if (a) return;" can be put on a single line.
bool AllowShortIfStatementsOnASingleLine; bool AllowShortIfStatementsOnASingleLine;
/// \brief If true, "while (true) continue;" can be put on a single line.
bool AllowShortLoopsOnASingleLine;
/// \brief Add a space in front of an Objective-C protocol list, i.e. use /// \brief Add a space in front of an Objective-C protocol list, i.e. use
/// Foo <Protocol> instead of Foo<Protocol>. /// Foo <Protocol> instead of Foo<Protocol>.
bool ObjCSpaceBeforeProtocolList; bool ObjCSpaceBeforeProtocolList;

View File

@ -78,6 +78,8 @@ template <> struct MappingTraits<clang::format::FormatStyle> {
Style.AllowAllParametersOfDeclarationOnNextLine); Style.AllowAllParametersOfDeclarationOnNextLine);
IO.mapOptional("AllowShortIfStatementsOnASingleLine", IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine); Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
Style.AllowShortLoopsOnASingleLine);
IO.mapOptional("BinPackParameters", Style.BinPackParameters); IO.mapOptional("BinPackParameters", Style.BinPackParameters);
IO.mapOptional("ColumnLimit", Style.ColumnLimit); IO.mapOptional("ColumnLimit", Style.ColumnLimit);
IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
@ -111,6 +113,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.AlignEscapedNewlinesLeft = false; LLVMStyle.AlignEscapedNewlinesLeft = false;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.BinPackParameters = true; LLVMStyle.BinPackParameters = true;
LLVMStyle.ColumnLimit = 80; LLVMStyle.ColumnLimit = 80;
LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
@ -135,6 +138,7 @@ FormatStyle getGoogleStyle() {
GoogleStyle.AlignEscapedNewlinesLeft = true; GoogleStyle.AlignEscapedNewlinesLeft = true;
GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true; GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true;
GoogleStyle.AllowShortIfStatementsOnASingleLine = true; GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
GoogleStyle.AllowShortLoopsOnASingleLine= true;
GoogleStyle.BinPackParameters = true; GoogleStyle.BinPackParameters = true;
GoogleStyle.ColumnLimit = 80; GoogleStyle.ColumnLimit = 80;
GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
@ -157,6 +161,7 @@ FormatStyle getChromiumStyle() {
FormatStyle ChromiumStyle = getGoogleStyle(); FormatStyle ChromiumStyle = getGoogleStyle();
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = false; ChromiumStyle.BinPackParameters = false;
ChromiumStyle.Standard = FormatStyle::LS_Cpp03; ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
ChromiumStyle.DerivePointerBinding = false; ChromiumStyle.DerivePointerBinding = false;
@ -1352,8 +1357,12 @@ private:
if (I->Last->is(tok::l_brace)) { if (I->Last->is(tok::l_brace)) {
tryMergeSimpleBlock(I, E, Limit); tryMergeSimpleBlock(I, E, Limit);
} else if (I->First.is(tok::kw_if)) { } else if (Style.AllowShortIfStatementsOnASingleLine &&
tryMergeSimpleIf(I, E, Limit); I->First.is(tok::kw_if)) {
tryMergeSimpleControlStatement(I, E, Limit);
} else if (Style.AllowShortLoopsOnASingleLine &&
I->First.isOneOf(tok::kw_for, tok::kw_while)) {
tryMergeSimpleControlStatement(I, E, Limit);
} else if (I->InPPDirective && (I->First.FormatTok.HasUnescapedNewline || } else if (I->InPPDirective && (I->First.FormatTok.HasUnescapedNewline ||
I->First.FormatTok.IsFirst)) { I->First.FormatTok.IsFirst)) {
tryMergeSimplePPDirective(I, E, Limit); tryMergeSimplePPDirective(I, E, Limit);
@ -1376,13 +1385,11 @@ private:
join(Line, *(++I)); join(Line, *(++I));
} }
void tryMergeSimpleIf(std::vector<AnnotatedLine>::iterator &I, void tryMergeSimpleControlStatement(std::vector<AnnotatedLine>::iterator &I,
std::vector<AnnotatedLine>::iterator E, std::vector<AnnotatedLine>::iterator E,
unsigned Limit) { unsigned Limit) {
if (Limit == 0) if (Limit == 0)
return; return;
if (!Style.AllowShortIfStatementsOnASingleLine)
return;
if ((I + 1)->InPPDirective != I->InPPDirective || if ((I + 1)->InPPDirective != I->InPPDirective ||
((I + 1)->InPPDirective && ((I + 1)->InPPDirective &&
(I + 1)->First.FormatTok.HasUnescapedNewline)) (I + 1)->First.FormatTok.HasUnescapedNewline))
@ -1392,10 +1399,13 @@ private:
return; return;
if (1 + (I + 1)->Last->TotalLength > Limit) if (1 + (I + 1)->Last->TotalLength > Limit)
return; return;
if ((I + 1)->First.is(tok::kw_if) || (I + 1)->First.Type == TT_LineComment) if ((I + 1)->First.isOneOf(tok::semi, tok::kw_if, tok::kw_for,
tok::kw_while) ||
(I + 1)->First.Type == TT_LineComment)
return; return;
// Only inline simple if's (no nested if or else). // Only inline simple if's (no nested if or else).
if (I + 2 != E && (I + 2)->First.is(tok::kw_else)) if (I + 2 != E && Line.First.is(tok::kw_if) &&
(I + 2)->First.is(tok::kw_else))
return; return;
join(Line, *(++I)); join(Line, *(++I));
} }

View File

@ -214,20 +214,26 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();"); verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();");
verifyFormat("if (a)\n if (b) {\n f();\n }\ng();"); verifyFormat("if (a)\n if (b) {\n f();\n }\ng();");
FormatStyle AllowsMergedIf = getGoogleStyle(); FormatStyle AllowsMergedIf = getLLVMStyle();
AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true; AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
verifyFormat("if (a)\n" verifyFormat("if (a)\n"
" // comment\n" " // comment\n"
" f();", " f();",
AllowsMergedIf); AllowsMergedIf);
verifyFormat("if (a)\n"
" ;",
AllowsMergedIf);
verifyFormat("if (a)\n"
" if (b) return;",
AllowsMergedIf);
verifyFormat("if (a) // Can't merge this\n" verifyFormat("if (a) // Can't merge this\n"
" f();\n", " f();\n",
AllowsMergedIf); AllowsMergedIf);
verifyFormat("if (a) /* still don't merge */\n" verifyFormat("if (a) /* still don't merge */\n"
" f();", " f();",
AllowsMergedIf); AllowsMergedIf);
verifyFormat("if (a) { // Never merge this\n" verifyFormat("if (a) { // Never merge this\n"
" f();\n" " f();\n"
"}", "}",
AllowsMergedIf); AllowsMergedIf);
@ -237,7 +243,7 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
AllowsMergedIf); AllowsMergedIf);
EXPECT_EQ("if (a) return;", format("if(a)\nreturn;", 7, 1, AllowsMergedIf)); EXPECT_EQ("if (a) return;", format("if(a)\nreturn;", 7, 1, AllowsMergedIf));
EXPECT_EQ("if (a) return; // comment", EXPECT_EQ("if (a) return; // comment",
format("if(a)\nreturn; // comment", 20, 1, AllowsMergedIf)); format("if(a)\nreturn; // comment", 20, 1, AllowsMergedIf));
AllowsMergedIf.ColumnLimit = 14; AllowsMergedIf.ColumnLimit = 14;
@ -250,6 +256,29 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
verifyFormat("if (a)\n return;", AllowsMergedIf); 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, ParseIfElse) { TEST_F(FormatTest, ParseIfElse) {
verifyFormat("if (true)\n" verifyFormat("if (true)\n"
" if (true)\n" " if (true)\n"