From: Daniel Jasper Date: Thu, 16 May 2013 12:12:21 +0000 (+0000) Subject: Add option to put short loops on a single line. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f11bbb9b0e9b741c84214459526d3e5e137e9165;p=clang Add option to put short loops on a single line. This enables things like: for (int &v : vec) v *= 2; Enabled for Google style. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182000 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 4150ad73ac..021073b6c6 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -86,6 +86,9 @@ struct FormatStyle { /// \brief If true, "if (a) return;" can be put on a single line. 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 /// Foo instead of Foo. bool ObjCSpaceBeforeProtocolList; diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index b64437046f..6631c67f7e 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -78,6 +78,8 @@ template <> struct MappingTraits { Style.AllowAllParametersOfDeclarationOnNextLine); IO.mapOptional("AllowShortIfStatementsOnASingleLine", Style.AllowShortIfStatementsOnASingleLine); + IO.mapOptional("AllowShortLoopsOnASingleLine", + Style.AllowShortLoopsOnASingleLine); IO.mapOptional("BinPackParameters", Style.BinPackParameters); IO.mapOptional("ColumnLimit", Style.ColumnLimit); IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine", @@ -111,6 +113,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.AlignEscapedNewlinesLeft = false; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; + LLVMStyle.AllowShortLoopsOnASingleLine = false; LLVMStyle.BinPackParameters = true; LLVMStyle.ColumnLimit = 80; LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false; @@ -135,6 +138,7 @@ FormatStyle getGoogleStyle() { GoogleStyle.AlignEscapedNewlinesLeft = true; GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true; GoogleStyle.AllowShortIfStatementsOnASingleLine = true; + GoogleStyle.AllowShortLoopsOnASingleLine= true; GoogleStyle.BinPackParameters = true; GoogleStyle.ColumnLimit = 80; GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; @@ -157,6 +161,7 @@ FormatStyle getChromiumStyle() { FormatStyle ChromiumStyle = getGoogleStyle(); ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; + ChromiumStyle.AllowShortLoopsOnASingleLine = false; ChromiumStyle.BinPackParameters = false; ChromiumStyle.Standard = FormatStyle::LS_Cpp03; ChromiumStyle.DerivePointerBinding = false; @@ -1352,8 +1357,12 @@ private: if (I->Last->is(tok::l_brace)) { tryMergeSimpleBlock(I, E, Limit); - } else if (I->First.is(tok::kw_if)) { - tryMergeSimpleIf(I, E, Limit); + } else if (Style.AllowShortIfStatementsOnASingleLine && + 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 || I->First.FormatTok.IsFirst)) { tryMergeSimplePPDirective(I, E, Limit); @@ -1376,13 +1385,11 @@ private: join(Line, *(++I)); } - void tryMergeSimpleIf(std::vector::iterator &I, - std::vector::iterator E, - unsigned Limit) { + void tryMergeSimpleControlStatement(std::vector::iterator &I, + std::vector::iterator E, + unsigned Limit) { if (Limit == 0) return; - if (!Style.AllowShortIfStatementsOnASingleLine) - return; if ((I + 1)->InPPDirective != I->InPPDirective || ((I + 1)->InPPDirective && (I + 1)->First.FormatTok.HasUnescapedNewline)) @@ -1392,10 +1399,13 @@ private: return; if (1 + (I + 1)->Last->TotalLength > Limit) 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; // 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; join(Line, *(++I)); } diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 76ec61385d..26097f35e2 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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 f();\n }\ng();"); - FormatStyle AllowsMergedIf = getGoogleStyle(); + FormatStyle AllowsMergedIf = getLLVMStyle(); AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true; verifyFormat("if (a)\n" " // comment\n" " f();", 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", AllowsMergedIf); verifyFormat("if (a) /* still don't merge */\n" " f();", AllowsMergedIf); - verifyFormat("if (a) { // Never merge this\n" + verifyFormat("if (a) { // Never merge this\n" " f();\n" "}", AllowsMergedIf); @@ -237,7 +243,7 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) { 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)); AllowsMergedIf.ColumnLimit = 14; @@ -250,6 +256,29 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) { 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) { verifyFormat("if (true)\n" " if (true)\n"