diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-10-12 08:19:25 +0200 |
---|---|---|
committer | Cristian Adam <cristian.adam@qt.io> | 2021-09-30 14:15:09 +0200 |
commit | 42879d1f355fde391ef46b96a659afeb4ad7814a (patch) | |
tree | df3ed432787da31b8a8f2cecd2c6d9da9ec98f19 | |
parent | 2bf39fe02b3dc3513f1555ca7967f978054dd124 (diff) |
[clang-format] Introduce the flag which allows not to shrink lines
https://reviews.llvm.org/D53072
Currently there's no way to prevent to lines optimization even
if you have intentionally put <CR> to split the line.
In general case it's fine. So I would prefer to have such option
which you can enable in special cases (for me it's an IDE related use case).
Revert this change if upstream clang-format offers better solution.
Reviewed-by; Marco Bubke <marco.bubke@qt.io>
Cherry picked from commit
clang.git/fa1b9053729ec6a4425a44ec5502dd388928274a.
Change-Id: I92296dd177c811593ebba7d4b5c3c5f472af10a2
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
-rw-r--r-- | clang/include/clang/Format/Format.h | 13 | ||||
-rw-r--r-- | clang/lib/Format/Format.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 2 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 16 |
5 files changed, 40 insertions, 4 deletions
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index c424e79a971c..2574acb369fc 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -22,6 +22,8 @@ #include "llvm/Support/SourceMgr.h" #include <system_error> +#define KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED + namespace llvm { namespace vfs { class FileSystem; @@ -2467,6 +2469,16 @@ struct FormatStyle { bool JavaScriptWrapImports; // clang-format on + /// If true, no line breaks are optimized out (works only with ColumnLimit = 0) + /// \code + /// true: false: + /// int foo(int a, vs. int foo(int a, int b) { + /// int b) { + /// bar(); bar(); + /// } } + /// \endcode + bool KeepLineBreaksForNonEmptyLines; + /// If true, the empty line at the start of blocks is kept. /// \code /// true: false: @@ -3457,6 +3469,7 @@ struct FormatStyle { JavaImportGroups == R.JavaImportGroups && JavaScriptQuotes == R.JavaScriptQuotes && JavaScriptWrapImports == R.JavaScriptWrapImports && + KeepLineBreaksForNonEmptyLines == R.KeepLineBreaksForNonEmptyLines && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && LambdaBodyIndentation == R.LambdaBodyIndentation && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 2b860d2a25f7..4b5d40c0eb12 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -671,6 +671,8 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("JavaImportGroups", Style.JavaImportGroups); IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes); IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); + IO.mapOptional("KeepLineBreaksForNonEmptyLines", + Style.KeepLineBreaksForNonEmptyLines); IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); IO.mapOptional("LambdaBodyIndentation", Style.LambdaBodyIndentation); @@ -1069,6 +1071,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.TabWidth = 8; LLVMStyle.LambdaBodyIndentation = FormatStyle::LBI_Signature; LLVMStyle.MaxEmptyLinesToKeep = 1; + LLVMStyle.KeepLineBreaksForNonEmptyLines = false; LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; LLVMStyle.NamespaceIndentation = FormatStyle::NI_None; LLVMStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Auto; @@ -1167,6 +1170,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$"; GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; GoogleStyle.IndentCaseLabels = true; + GoogleStyle.KeepLineBreaksForNonEmptyLines = false; GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never; GoogleStyle.ObjCSpaceAfterProperty = false; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index cca85c1074de..1046aa5ff5ac 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -781,7 +781,7 @@ public: LineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, const FormatStyle &Style, UnwrappedLineFormatter *BlockFormatter) - : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), + : Indenter(Indenter), Style(Style), Whitespaces(Whitespaces), BlockFormatter(BlockFormatter) {} virtual ~LineFormatter() {} @@ -822,7 +822,8 @@ protected: // assert so that we can simply call this function for all tokens. return true; - if (NewLine) { + if (NewLine || (Previous.Children[0]->First->MustBreakBefore && + Style.KeepLineBreaksForNonEmptyLines)) { const ParenState &P = State.Stack.back(); int AdditionalIndent = @@ -880,10 +881,10 @@ protected: } ContinuationIndenter *Indenter; + const FormatStyle &Style; private: WhitespaceManager *Whitespaces; - const FormatStyle &Style; UnwrappedLineFormatter *BlockFormatter; }; @@ -906,7 +907,7 @@ public: while (State.NextToken) { bool Newline = Indenter->mustBreak(State) || - (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0); + (State.NextToken->NewlinesBefore > 0 && Indenter->canBreak(State)); unsigned Penalty = 0; formatChildren(State, Newline, /*DryRun=*/false, Penalty); Indenter->addTokenToState(State, Newline, /*DryRun=*/false); diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 673986d16af2..f1f0f2e16f3a 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3226,6 +3226,8 @@ void UnwrappedLineParser::nextToken(int LevelDifference) { else readTokenWithJavaScriptASI(); FormatTok->Previous = Previous; + if (FormatTok->NewlinesBefore && Style.KeepLineBreaksForNonEmptyLines) + FormatTok->MustBreakBefore = true; } void UnwrappedLineParser::distributeComments( diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index c575f643b5a1..64fbc436bb5d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -527,6 +527,22 @@ TEST_F(FormatTest, RemovesEmptyLines) { " void funk() {}\n" "};", Style)); + + Style.KeepLineBreaksForNonEmptyLines = true; + Style.ColumnLimit = 0; + EXPECT_EQ("int foo(int a,\n" + " int b)\n" + "{\n" + "}", + format("int foo(int a,\n" + "int b) {}", + Style)); + + EXPECT_EQ("[]() {\n" + " foo(); }", + format("[]() {\n" + "foo(); }", + Style)); } TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) { |