krasimir created this revision.
Herald added subscribers: cfe-commits, klimek.
This patch makes `getLengthToMatchingParen` respect the
`BreakBeforeClosingBrace`
ParenState for matching scope closers. In order to distinguish between paren
states
introduced by real vs. fake parens, I've added the token opening the ParensState
to that struct.
Repository:
rC Clang
https://reviews.llvm.org/D46519
Files:
lib/Format/ContinuationIndenter.cpp
lib/Format/ContinuationIndenter.h
lib/Format/UnwrappedLineFormatter.cpp
unittests/Format/FormatTestProto.cpp
unittests/Format/FormatTestRawStrings.cpp
unittests/Format/FormatTestTextProto.cpp
Index: unittests/Format/FormatTestTextProto.cpp
===================================================================
--- unittests/Format/FormatTestTextProto.cpp
+++ unittests/Format/FormatTestTextProto.cpp
@@ -469,6 +469,7 @@
" ccccccccccccccccccccccc: <\n"
" operator: 1\n"
" operator: 2\n"
+ " operator: 3\n"
" operator { key: value }\n"
" >\n"
" >\n"
Index: unittests/Format/FormatTestRawStrings.cpp
===================================================================
--- unittests/Format/FormatTestRawStrings.cpp
+++ unittests/Format/FormatTestRawStrings.cpp
@@ -822,6 +822,41 @@
)test", Style));
}
+TEST_F(FormatTestRawStrings, KeepsRBraceFolloedByMoreLBracesOnSameLine) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(80);
+
+ expect_eq(
+ R"test(
+int f() {
+ if (1) {
+ TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb(
+ ttttttttt {
+ ppppppppppppp {
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" }
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" }
+ }
+ }
+ )pb");
+ }
+}
+)test",
+ format(
+ R"test(
+int f() {
+ if (1) {
+ TTTTTTTTTTTTTTTTTTTTT s = PARSE_TEXT_PROTO(R"pb(
+ ttttttttt {
+ ppppppppppppp {
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_1: "123_1" }
+ [cccccccccc.pppppppppppppp.TTTTTTTTTTTTTTTTTTTT] { field_2: "123_2" }}}
+ )pb");
+ }
+}
+)test",
+ Style));
+}
+
+
} // end namespace
} // end namespace format
} // end namespace clang
Index: unittests/Format/FormatTestProto.cpp
===================================================================
--- unittests/Format/FormatTestProto.cpp
+++ unittests/Format/FormatTestProto.cpp
@@ -486,6 +486,7 @@
" ccccccccccccccccccccccc: <\n"
" operator: 1\n"
" operator: 2\n"
+ " operator: 3\n"
" operator { key: value }\n"
" >\n"
" >\n"
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -659,8 +659,8 @@
static void printLineState(const LineState &State) {
llvm::dbgs() << "State: ";
for (const ParenState &P : State.Stack) {
- llvm::dbgs() << P.Indent << "|" << P.LastSpace << "|" << P.NestedBlockIndent
- << " ";
+ llvm::dbgs() << (P.Tok ? P.Tok->TokenText : "F") << "|" << P.Indent << "|"
+ << P.LastSpace << "|" << P.NestedBlockIndent << " ";
}
llvm::dbgs() << State.NextToken->TokenText << "\n";
}
Index: lib/Format/ContinuationIndenter.h
===================================================================
--- lib/Format/ContinuationIndenter.h
+++ lib/Format/ContinuationIndenter.h
@@ -200,16 +200,20 @@
};
struct ParenState {
- ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
- bool NoLineBreak)
- : Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent),
- BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking),
- BreakBeforeParameter(false), NoLineBreak(NoLineBreak),
- NoLineBreakInOperand(false), LastOperatorWrapped(true),
- ContainsLineBreak(false), ContainsUnwrappedBuilder(false),
- AlignColons(true), ObjCSelectorNameFound(false),
- HasMultipleNestedBlocks(false), NestedBlockInlined(false),
- IsInsideObjCArrayLiteral(false) {}
+ ParenState(const FormatToken *Tok, unsigned Indent, unsigned LastSpace,
+ bool AvoidBinPacking, bool NoLineBreak)
+ : Tok(Tok), Indent(Indent), LastSpace(LastSpace),
+ NestedBlockIndent(Indent), BreakBeforeClosingBrace(false),
+ AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
+ NoLineBreak(NoLineBreak), NoLineBreakInOperand(false),
+ LastOperatorWrapped(true), ContainsLineBreak(false),
+ ContainsUnwrappedBuilder(false), AlignColons(true),
+ ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false),
+ NestedBlockInlined(false), IsInsideObjCArrayLiteral(false) {}
+
+ /// \brief The token opening this parenthesis level, or nullptr if this level
+ /// is opened by fake parenthesis.
+ const FormatToken *Tok;
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -35,11 +35,24 @@
// Returns the length of everything up to the first possible line break after
// the ), ], } or > matching \c Tok.
-static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
+static unsigned getLengthToMatchingParen(const FormatToken &Tok,
+ const std::vector<ParenState> &Stack) {
if (!Tok.MatchingParen)
return 0;
FormatToken *End = Tok.MatchingParen;
- while (End->Next && !End->Next->CanBreakBefore) {
+ int MatchingStackIndex = Stack.size() - 1;
+ while (MatchingStackIndex >= 0 && Stack[MatchingStackIndex].Tok != &Tok)
+ --MatchingStackIndex;
+ while (End->Next) {
+ if (End->Next->CanBreakBefore || !End->Next->closesScope())
+ break;
+ while (MatchingStackIndex >= 0 &&
+ Stack[MatchingStackIndex].Tok != End->Next->MatchingParen)
+ --MatchingStackIndex;
+ if (MatchingStackIndex >= 0 &&
+ Stack[MatchingStackIndex].Tok == End->Next->MatchingParen &&
+ Stack[MatchingStackIndex].BreakBeforeClosingBrace)
+ break;
End = End->Next;
}
return End->TotalLength - Tok.TotalLength + 1;
@@ -192,7 +205,7 @@
State.Column = 0;
State.Line = Line;
State.NextToken = Line->First;
- State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
+ State.Stack.push_back(ParenState(/*Tok=*/nullptr, FirstIndent, FirstIndent,
/*AvoidBinPacking=*/false,
/*NoLineBreak=*/false));
State.LineContainsContinuedForLoopSection = false;
@@ -299,7 +312,7 @@
Previous.ParameterCount > 1) ||
opensProtoMessageField(Previous, Style)) &&
Style.ColumnLimit > 0 &&
- getLengthToMatchingParen(Previous) + State.Column - 1 >
+ getLengthToMatchingParen(Previous, State.Stack) + State.Column - 1 >
getColumnLimit(State))
return true;
@@ -1122,6 +1135,7 @@
E = Current.FakeLParens.rend();
I != E; ++I) {
ParenState NewParenState = State.Stack.back();
+ NewParenState.Tok = nullptr;
NewParenState.ContainsLineBreak = false;
NewParenState.LastOperatorWrapped = true;
NewParenState.NoLineBreak =
@@ -1265,7 +1279,7 @@
if (Style.ColumnLimit) {
// If this '[' opens an ObjC call, determine whether all parameters fit
// into one line and put one per line if they don't.
- if (getLengthToMatchingParen(Current) + State.Column >
+ if (getLengthToMatchingParen(Current, State.Stack) + State.Column >
getColumnLimit(State))
BreakBeforeParameter = true;
} else {
@@ -1296,7 +1310,7 @@
(Current.is(TT_TemplateOpener) &&
State.Stack.back().ContainsUnwrappedBuilder));
State.Stack.push_back(
- ParenState(NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
+ ParenState(&Current, NewIndent, LastSpace, AvoidBinPacking, NoLineBreak));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
@@ -1334,7 +1348,8 @@
NestedBlockIndent + (State.NextToken->is(TT_ObjCBlockLBrace)
? Style.ObjCBlockIndentWidth
: Style.IndentWidth);
- State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,
+ State.Stack.push_back(ParenState(State.NextToken, NewIndent,
+ State.Stack.back().LastSpace,
/*AvoidBinPacking=*/true,
/*NoLineBreak=*/false));
State.Stack.back().NestedBlockIndent = NestedBlockIndent;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits