Author: Owen Pan Date: 2024-10-17T20:21:42-07:00 New Revision: d989c2410eb883f464c3efa472ed026dc5fd9f88
URL: https://github.com/llvm/llvm-project/commit/d989c2410eb883f464c3efa472ed026dc5fd9f88 DIFF: https://github.com/llvm/llvm-project/commit/d989c2410eb883f464c3efa472ed026dc5fd9f88.diff LOG: [clang-format] Add RemoveEmptyLinesInUnwrappedLines option (#112325) Fixes #111340. Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/ConfigParseTest.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 8add0a53e5be13..f36a5472b7e17d 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -5505,6 +5505,31 @@ the configuration (without a prefix: ``Auto``). } } +.. _RemoveEmptyLinesInUnwrappedLines: + +**RemoveEmptyLinesInUnwrappedLines** (``Boolean``) :versionbadge:`clang-format 20` :ref:`¶ <RemoveEmptyLinesInUnwrappedLines>` + Remove empty lines within unwrapped lines. + + .. code-block:: c++ + + false: true: + + int c vs. int c = a + b; + + = a + b; + + enum : unsigned vs. enum : unsigned { + AA = 0, + { BB + AA = 0, } myEnum; + BB + } myEnum; + + while ( vs. while (true) { + } + true) { + } + .. _RemoveParentheses: **RemoveParentheses** (``RemoveParenthesesStyle``) :versionbadge:`clang-format 17` :ref:`¶ <RemoveParentheses>` diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1da8c82d52e618..a65bd6f382901b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -699,8 +699,10 @@ clang-format - Adds ``BreakBinaryOperations`` option. - Adds ``TemplateNames`` option. - Adds ``AlignFunctionDeclarations`` option to ``AlignConsecutiveDeclarations``. -- Adds ``IndentOnly`` suboption to ``ReflowComments`` to fix the indentation of multi-line comments - without touching their contents, renames ``false`` to ``Never``, and ``true`` to ``Always``. +- Adds ``IndentOnly`` suboption to ``ReflowComments`` to fix the indentation of + multi-line comments without touching their contents, renames ``false`` to + ``Never``, and ``true`` to ``Always``. +- Adds ``RemoveEmptyLinesInUnwrappedLines`` option. libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index a0762b088b68ef..debba1c7822839 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -3938,6 +3938,29 @@ struct FormatStyle { /// \version 14 bool RemoveBracesLLVM; + /// Remove empty lines within unwrapped lines. + /// \code + /// false: true: + /// + /// int c vs. int c = a + b; + /// + /// = a + b; + /// + /// enum : unsigned vs. enum : unsigned { + /// AA = 0, + /// { BB + /// AA = 0, } myEnum; + /// BB + /// } myEnum; + /// + /// while ( vs. while (true) { + /// } + /// true) { + /// } + /// \endcode + /// \version 20 + bool RemoveEmptyLinesInUnwrappedLines; + /// Types of redundant parentheses to remove. enum RemoveParenthesesStyle : int8_t { /// Do not remove parentheses. @@ -5232,6 +5255,8 @@ struct FormatStyle { RawStringFormats == R.RawStringFormats && ReferenceAlignment == R.ReferenceAlignment && RemoveBracesLLVM == R.RemoveBracesLLVM && + RemoveEmptyLinesInUnwrappedLines == + R.RemoveEmptyLinesInUnwrappedLines && RemoveParentheses == R.RemoveParentheses && RemoveSemicolon == R.RemoveSemicolon && RequiresClausePosition == R.RequiresClausePosition && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 148270795c562f..c612960ff37ac8 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1104,6 +1104,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment); IO.mapOptional("ReflowComments", Style.ReflowComments); IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM); + IO.mapOptional("RemoveEmptyLinesInUnwrappedLines", + Style.RemoveEmptyLinesInUnwrappedLines); IO.mapOptional("RemoveParentheses", Style.RemoveParentheses); IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon); IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition); @@ -1582,6 +1584,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer; LLVMStyle.ReflowComments = FormatStyle::RCS_Always; LLVMStyle.RemoveBracesLLVM = false; + LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false; LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave; LLVMStyle.RemoveSemicolon = false; LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index fcefaa7bb298ea..13037b6d00604b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -5509,8 +5509,10 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) { bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right) const { const FormatToken &Left = *Right.Previous; - if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) + if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 && + (!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) { return true; + } if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl && Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen && diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp index 318f08c04759b9..9e8529050ed83d 100644 --- a/clang/unittests/Format/ConfigParseTest.cpp +++ b/clang/unittests/Format/ConfigParseTest.cpp @@ -184,6 +184,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList); CHECK_PARSE_BOOL(Cpp11BracedListStyle); CHECK_PARSE_BOOL(RemoveBracesLLVM); + CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines); CHECK_PARSE_BOOL(RemoveSemicolon); CHECK_PARSE_BOOL(SkipMacroDefinitionBody); CHECK_PARSE_BOOL(SpacesInSquareBrackets); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 43513f18321bc0..8f4c92148adae4 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -28135,6 +28135,83 @@ TEST_F(FormatTest, BreakBinaryOperations) { Style); } +TEST_F(FormatTest, RemovesEmptyLinesInUnwrappedLines) { + auto Style = getLLVMStyle(); + Style.RemoveEmptyLinesInUnwrappedLines = true; + + verifyFormat("int c = a + b;", + "int c\n" + "\n" + " = a + b;", + Style); + + verifyFormat("enum : unsigned { AA = 0, BB } myEnum;", + "enum : unsigned\n" + "\n" + "{\n" + " AA = 0,\n" + " BB\n" + "} myEnum;", + Style); + + verifyFormat("class B : public E {\n" + "private:\n" + "};", + "class B : public E\n" + "\n" + "{\n" + "private:\n" + "};", + Style); + + verifyFormat( + "struct AAAAAAAAAAAAAAA test[3] = {{56, 23, \"hello\"}, {7, 5, \"!!\"}};", + "struct AAAAAAAAAAAAAAA test[3] = {{56,\n" + "\n" + " 23, \"hello\"},\n" + " {7, 5, \"!!\"}};", + Style); + + verifyFormat("int myFunction(int aaaaaaaaaaaaa, int ccccccccccccc, int d);", + "int myFunction(\n" + "\n" + " int aaaaaaaaaaaaa,\n" + "\n" + " int ccccccccccccc, int d);", + Style); + + verifyFormat("switch (e) {\n" + "case 1:\n" + " return e;\n" + "case 2:\n" + " return 2;\n" + "}", + "switch (\n" + "\n" + " e) {\n" + "case 1:\n" + " return e;\n" + "case 2:\n" + " return 2;\n" + "}", + Style); + + verifyFormat("while (true) {\n" + "}", + "while (\n" + "\n" + " true) {\n" + "}", + Style); + + verifyFormat("void loooonFunctionIsVeryLongButNotAsLongAsJavaTypeNames(\n" + " std::map<int, std::string> *outputMap);", + "void loooonFunctionIsVeryLongButNotAsLongAsJavaTypeNames\n" + "\n" + " (std::map<int, std::string> *outputMap);", + Style); +} + } // namespace } // namespace test } // namespace format _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits