From 65e68675f101657b69a404432c2116bc9cc23b22 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Wed, 14 May 2014 09:33:35 +0000 Subject: [PATCH] clang-format: Add option to allow short blocks on a single line. With AllowShortBlocksOnASingleLine, clang-format allows: if (a) { return; } Based on patch by Gonzalo BG, thank you! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208765 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/ClangFormatStyleOptions.rst | 9 +++++-- include/clang/Format/Format.h | 6 +++++ lib/Format/Format.cpp | 39 ++++++++++++++++++++++-------- unittests/Format/FormatTest.cpp | 41 ++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 27d5e7426a..b2157dd832 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -106,6 +106,11 @@ the configuration (without a prefix: ``Auto``). Allow putting all parameters of a function declaration onto the next line even if ``BinPackParameters`` is ``false``. +**AllowShortBlocksOnASingleLine** (``bool``) + Allows contracting simple braced statements to a single line. + + E.g., this allows ``if (a) { return; }`` to be put on a single line. + **AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``) Dependent on the value, ``int f() { return 0; }`` can be put on a single line. @@ -284,7 +289,7 @@ the configuration (without a prefix: ``Auto``). **ObjCSpaceAfterProperty** (``bool``) Add a space after ``@property`` in Objective-C, i.e. use - ``@property (readonly)`` instead of ``@property(readonly)``. + ``\@property (readonly)`` instead of ``\@property(readonly)``. **ObjCSpaceBeforeProtocolList** (``bool``) Add a space in front of an Objective-C protocol list, i.e. use @@ -338,7 +343,7 @@ the configuration (without a prefix: ``Auto``). **SpacesBeforeTrailingComments** (``unsigned``) The number of spaces before trailing line comments (//-comments). - This does not affect trailing block comments (/\*\*/-comments) as those + This does not affect trailing block comments (/**/-comments) as those commonly have different usage patterns and a number of special cases. **SpacesInAngles** (``bool``) diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 09c37d1cf7..4356ff0b03 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -158,6 +158,11 @@ struct FormatStyle { /// the commas with the colon. bool BreakConstructorInitializersBeforeComma; + /// \brief Allows contracting simple braced statements to a single line. + /// + /// E.g., this allows if (a) { return; } to be put on a single line. + bool AllowShortBlocksOnASingleLine; + /// \brief If \c true, if (a) return; can be put on a single /// line. bool AllowShortIfStatementsOnASingleLine; @@ -338,6 +343,7 @@ struct FormatStyle { R.AllowAllParametersOfDeclarationOnNextLine && AllowShortFunctionsOnASingleLine == R.AllowShortFunctionsOnASingleLine && + AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && AllowShortIfStatementsOnASingleLine == R.AllowShortIfStatementsOnASingleLine && AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 60706b1b3b..e0b2961af3 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -151,6 +151,8 @@ template <> struct MappingTraits { IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine", Style.AllowAllParametersOfDeclarationOnNextLine); + IO.mapOptional("AllowShortBlocksOnASingleLine", + Style.AllowShortBlocksOnASingleLine); IO.mapOptional("AllowShortIfStatementsOnASingleLine", Style.AllowShortIfStatementsOnASingleLine); IO.mapOptional("AllowShortLoopsOnASingleLine", @@ -263,6 +265,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.AlignTrailingComments = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; + LLVMStyle.AllowShortBlocksOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortLoopsOnASingleLine = false; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; @@ -609,7 +612,7 @@ private: return 0; if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman || Style.BreakBeforeBraces == FormatStyle::BS_GNU) && - I[1]->First->is(tok::l_brace)) + (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine)) return 0; if (I[1]->InPPDirective != (*I)->InPPDirective || (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline)) @@ -635,16 +638,31 @@ private: tryMergeSimpleBlock(SmallVectorImpl::const_iterator I, SmallVectorImpl::const_iterator E, unsigned Limit) { - // First, check that the current line allows merging. This is the case if - // we're not in a control flow statement and the last token is an opening - // brace. AnnotatedLine &Line = **I; - if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace, - tok::kw_else, tok::kw_try, tok::kw_catch, - tok::kw_for, tok::kw_case, - // This gets rid of all ObjC @ keywords and methods. - tok::at, tok::minus, tok::plus)) + + // Don't merge ObjC @ keywords and methods. + if (Line.First->isOneOf(tok::at, tok::minus, tok::plus)) + return 0; + + // Check that the current line allows merging. This depends on whether we + // are in a control flow statements as well as several style flags. + if (Line.First->isOneOf(tok::kw_else, tok::kw_case)) return 0; + if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try, + tok::kw_catch, tok::kw_for, tok::r_brace)) { + if (!Style.AllowShortBlocksOnASingleLine) + return 0; + if (!Style.AllowShortIfStatementsOnASingleLine && + Line.First->is(tok::kw_if)) + return 0; + if (!Style.AllowShortLoopsOnASingleLine && + Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for)) + return 0; + // FIXME: Consider an option to allow short exception handling clauses on + // a single line. + if (Line.First->isOneOf(tok::kw_try, tok::kw_catch)) + return 0; + } FormatToken *Tok = I[1]->First; if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore && @@ -672,7 +690,8 @@ private: if (I[1]->Last->Type == TT_LineComment) return 0; do { - if (Tok->isOneOf(tok::l_brace, tok::r_brace)) + if (Tok->isOneOf(tok::l_brace, tok::r_brace) && + !Style.AllowShortBlocksOnASingleLine) return 0; Tok = Tok->Next; } while (Tok); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 93a0064e7d..7ac6cb4987 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -355,6 +355,46 @@ TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) { 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); + + AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false; + verifyFormat("if (true) {\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" @@ -7928,6 +7968,7 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); + CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine); CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations); -- 2.40.0