summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-10-12 08:19:25 +0200
committerCristian Adam <cristian.adam@qt.io>2021-09-30 14:15:09 +0200
commit42879d1f355fde391ef46b96a659afeb4ad7814a (patch)
treedf3ed432787da31b8a8f2cecd2c6d9da9ec98f19
parent2bf39fe02b3dc3513f1555ca7967f978054dd124 (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.h13
-rw-r--r--clang/lib/Format/Format.cpp4
-rw-r--r--clang/lib/Format/UnwrappedLineFormatter.cpp9
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp2
-rw-r--r--clang/unittests/Format/FormatTest.cpp16
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) {