timwoj created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This diff adds a new option SpacesAroundConditions that inserts spaces inside the braces for conditional statements. It's used by the Zeek project (https://github.com/zeek/zeek) as described in their style guide (https://github.com/zeek/zeek-docs/blob/master/devel/style_guide.rst#conditional-expressions) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D68346 Files: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -12177,6 +12177,7 @@ CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon); CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon); CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon); + CHECK_PARSE_BOOL(SpacesAroundConditions); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel); CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); @@ -14373,6 +14374,16 @@ verifyFormat("auto lambda = [&a = a]() { a = 2; };", AlignStyle); } +TEST_F(FormatTest, SpacesAroundConditions) { + FormatStyle Spaces = getLLVMStyle(); + Spaces.SpacesAroundConditions = true; + verifyFormat("if ( !a )\n return;", Spaces); + verifyFormat("if ( a )\n return;", Spaces); + verifyFormat("while ( a )\n return;", Spaces); + verifyFormat("while ( (a && b) )\n return;", Spaces); + verifyFormat("do {\n} while ( 1 != 0 );", Spaces); +} + } // end namespace } // end namespace format } // end namespace clang Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2505,6 +2505,18 @@ return Right.is(tok::hash); if (Left.is(tok::l_paren) && Right.is(tok::r_paren)) return Style.SpaceInEmptyParentheses; + if (Style.SpacesAroundConditions) { + const auto is_cond_kw = [&](const FormatToken *t) { + return t->isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while, + tok::kw_switch, tok::kw_constexpr, TT_ForEachMacro); + }; + if (Left.is(tok::l_paren) && Left.Previous && is_cond_kw(Left.Previous)) + return true; + if (Right.is(tok::r_paren) && Right.MatchingParen && + Right.MatchingParen->Previous && + is_cond_kw(Right.MatchingParen->Previous)) + return true; + } if (Left.is(tok::l_paren) || Right.is(tok::r_paren)) return (Right.is(TT_CastRParen) || (Left.MatchingParen && Left.MatchingParen->is(TT_CastRParen))) @@ -2903,7 +2915,8 @@ // The identifier might actually be a macro name such as ALWAYS_INLINE. If // this turns out to be too lenient, add analysis of the identifier itself. return Right.WhitespaceRange.getBegin() != Right.WhitespaceRange.getEnd(); - if (Right.is(tok::coloncolon) && !Left.isOneOf(tok::l_brace, tok::comment)) + if (Right.is(tok::coloncolon) && + !Left.isOneOf(tok::l_brace, tok::comment, tok::l_paren)) return (Left.is(TT_TemplateOpener) && Style.Standard < FormatStyle::LS_Cpp11) || !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square, Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -517,6 +517,7 @@ Style.SpacesInCStyleCastParentheses); IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses); IO.mapOptional("SpacesInSquareBrackets", Style.SpacesInSquareBrackets); + IO.mapOptional("SpacesAroundConditions", Style.SpacesAroundConditions); IO.mapOptional("Standard", Style.Standard); IO.mapOptional("StatementMacros", Style.StatementMacros); IO.mapOptional("TabWidth", Style.TabWidth); @@ -775,6 +776,7 @@ LLVMStyle.SpaceBeforeAssignmentOperators = true; LLVMStyle.SpaceBeforeCpp11BracedList = false; LLVMStyle.SpacesInAngles = false; + LLVMStyle.SpacesAroundConditions = false; LLVMStyle.PenaltyBreakAssignment = prec::Assignment; LLVMStyle.PenaltyBreakComment = 300; Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1945,6 +1945,10 @@ /// \endcode bool SpacesInSquareBrackets; + /// \brief If ``true``, spaces will be inserted around if/for/while (and + /// similar) conditions. + bool SpacesAroundConditions; + /// Supported language standards. enum LanguageStandard { /// Use C++03-compatible syntax. @@ -2081,6 +2085,7 @@ SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses && SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && + SpacesAroundConditions == R.SpacesAroundConditions && Standard == R.Standard && TabWidth == R.TabWidth && StatementMacros == R.StatementMacros && UseTab == R.UseTab && TypenameMacros == R.TypenameMacros; Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2287,6 +2287,9 @@ int a[ 5 ]; vs. int a[5]; std::unique_ptr<int[]> foo() {} // Won't be affected +**SpacesAroundConditions** (``bool``) + If ``true``, spaces will be inserted around if/for/while (and similar) conditions. + **Standard** (``LanguageStandard``) Format compatible with this standard, e.g. use ``A<A<int> >`` instead of ``A<A<int>>`` for ``LS_Cpp03``.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits