Commit 218224bc authored by Ivan Donchevskii's avatar Ivan Donchevskii Committed by Cristian Adam
Browse files

[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: default avatarCristian Adam <cristian.adam@qt.io>
parent 5beadd4b
......@@ -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;
......@@ -2551,6 +2553,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:
......@@ -3920,6 +3932,7 @@ struct FormatStyle {
JavaImportGroups == R.JavaImportGroups &&
JavaScriptQuotes == R.JavaScriptQuotes &&
JavaScriptWrapImports == R.JavaScriptWrapImports &&
KeepLineBreaksForNonEmptyLines == R.KeepLineBreaksForNonEmptyLines &&
KeepEmptyLinesAtTheStartOfBlocks ==
R.KeepEmptyLinesAtTheStartOfBlocks &&
LambdaBodyIndentation == R.LambdaBodyIndentation &&
......
......@@ -814,6 +814,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);
......@@ -1277,6 +1279,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;
......@@ -1380,6 +1383,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;
......
......@@ -919,7 +919,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() {}
......@@ -961,7 +961,8 @@ protected:
return true;
}
if (NewLine) {
if (NewLine || (Previous.Children[0]->First->MustBreakBefore &&
Style.KeepLineBreaksForNonEmptyLines)) {
const ParenState &P = State.Stack.back();
int AdditionalIndent =
......@@ -1020,10 +1021,10 @@ protected:
}
ContinuationIndenter *Indenter;
const FormatStyle &Style;
private:
WhitespaceManager *Whitespaces;
const FormatStyle &Style;
UnwrappedLineFormatter *BlockFormatter;
};
......@@ -1046,7 +1047,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);
......
......@@ -4196,6 +4196,8 @@ void UnwrappedLineParser::nextToken(int LevelDifference) {
if (Keywords.isVerilogEnd(*FormatTok))
FormatTok->Tok.setKind(tok::r_brace);
}
if (FormatTok->NewlinesBefore && Style.KeepLineBreaksForNonEmptyLines)
FormatTok->MustBreakBefore = true;
}
void UnwrappedLineParser::distributeComments(
......
......@@ -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) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment