Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Format/ContinuationIndenter.cpp
Show First 20 Lines • Show All 278 Lines • ▼ Show 20 Lines | bool ContinuationIndenter::canBreak(const LineState &State) { | ||||
const FormatToken &Previous = *Current.Previous; | const FormatToken &Previous = *Current.Previous; | ||||
assert(&Previous == Current.Previous); | assert(&Previous == Current.Previous); | ||||
if (!Current.CanBreakBefore && !(State.Stack.back().BreakBeforeClosingBrace && | if (!Current.CanBreakBefore && !(State.Stack.back().BreakBeforeClosingBrace && | ||||
Current.closesBlockOrBlockTypeList(Style))) | Current.closesBlockOrBlockTypeList(Style))) | ||||
return false; | return false; | ||||
// The opening "{" of a braced list has to be on the same line as the first | // The opening "{" of a braced list has to be on the same line as the first | ||||
// element if it is nested in another braced init list or function call. | // element if it is nested in another braced init list or function call. | ||||
if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && | if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && | ||||
Previous.isNot(TT_DictLiteral) && Previous.BlockKind == BK_BracedInit && | Previous.isNot(TT_DictLiteral) && Previous.is(BK_BracedInit) && | ||||
Previous.Previous && | Previous.Previous && | ||||
Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) | Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) | ||||
return false; | return false; | ||||
// This prevents breaks like: | // This prevents breaks like: | ||||
// ... | // ... | ||||
// SomeParameter, OtherParameter).DoSomething( | // SomeParameter, OtherParameter).DoSomething( | ||||
// ... | // ... | ||||
// As they hide "DoSomething" and are generally bad for readability. | // As they hide "DoSomething" and are generally bad for readability. | ||||
▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | if (((Current.is(TT_FunctionDeclarationName) && | ||||
Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None)) || | Style.AlwaysBreakAfterReturnType != FormatStyle::RTBS_None)) || | ||||
(Current.is(tok::kw_operator) && !Previous.is(tok::coloncolon))) && | (Current.is(tok::kw_operator) && !Previous.is(tok::coloncolon))) && | ||||
!Previous.is(tok::kw_template) && State.Stack.back().BreakBeforeParameter) | !Previous.is(tok::kw_template) && State.Stack.back().BreakBeforeParameter) | ||||
return true; | return true; | ||||
// The following could be precomputed as they do not depend on the state. | // The following could be precomputed as they do not depend on the state. | ||||
// However, as they should take effect only if the UnwrappedLine does not fit | // However, as they should take effect only if the UnwrappedLine does not fit | ||||
// into the ColumnLimit, they are checked here in the ContinuationIndenter. | // into the ColumnLimit, they are checked here in the ContinuationIndenter. | ||||
if (Style.ColumnLimit != 0 && Previous.BlockKind == BK_Block && | if (Style.ColumnLimit != 0 && Previous.is(BK_Block) && | ||||
Previous.is(tok::l_brace) && !Current.isOneOf(tok::r_brace, tok::comment)) | Previous.is(tok::l_brace) && !Current.isOneOf(tok::r_brace, tok::comment)) | ||||
return true; | return true; | ||||
if (Current.is(tok::lessless) && | if (Current.is(tok::lessless) && | ||||
((Previous.is(tok::identifier) && Previous.TokenText == "endl") || | ((Previous.is(tok::identifier) && Previous.TokenText == "endl") || | ||||
(Previous.Tok.isLiteral() && (Previous.TokenText.endswith("\\n\"") || | (Previous.Tok.isLiteral() && (Previous.TokenText.endswith("\\n\"") || | ||||
Previous.TokenText == "\'\\n\'")))) | Previous.TokenText == "\'\\n\'")))) | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | else | ||||
State.Stack.back().ColonPos = FirstColonPos; | State.Stack.back().ColonPos = FirstColonPos; | ||||
} | } | ||||
// In "AlwaysBreak" mode, enforce wrapping directly after the parenthesis by | // In "AlwaysBreak" mode, enforce wrapping directly after the parenthesis by | ||||
// disallowing any further line breaks if there is no line break after the | // disallowing any further line breaks if there is no line break after the | ||||
// opening parenthesis. Don't break if it doesn't conserve columns. | // opening parenthesis. Don't break if it doesn't conserve columns. | ||||
if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak && | if (Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak && | ||||
(Previous.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) || | (Previous.isOneOf(tok::l_paren, TT_TemplateOpener, tok::l_square) || | ||||
(Previous.is(tok::l_brace) && Previous.BlockKind != BK_Block && | (Previous.is(tok::l_brace) && Previous.isNot(BK_Block) && | ||||
Style.Cpp11BracedListStyle)) && | Style.Cpp11BracedListStyle)) && | ||||
State.Column > getNewLineColumn(State) && | State.Column > getNewLineColumn(State) && | ||||
(!Previous.Previous || !Previous.Previous->isOneOf( | (!Previous.Previous || !Previous.Previous->isOneOf( | ||||
tok::kw_for, tok::kw_while, tok::kw_switch)) && | tok::kw_for, tok::kw_while, tok::kw_switch)) && | ||||
// Don't do this for simple (no expressions) one-argument function calls | // Don't do this for simple (no expressions) one-argument function calls | ||||
// as that feels like needlessly wasting whitespace, e.g.: | // as that feels like needlessly wasting whitespace, e.g.: | ||||
// | // | ||||
// caaaaaaaaaaaall( | // caaaaaaaaaaaall( | ||||
// caaaaaaaaaaaall( | // caaaaaaaaaaaall( | ||||
// caaaaaaaaaaaall( | // caaaaaaaaaaaall( | ||||
// caaaaaaaaaaaaaaaaaaaaaaall(aaaaaaaaaaaaaa, aaaaaaaaa)))); | // caaaaaaaaaaaaaaaaaaaaaaall(aaaaaaaaaaaaaa, aaaaaaaaa)))); | ||||
Current.FakeLParens.size() > 0 && | Current.FakeLParens.size() > 0 && | ||||
Current.FakeLParens.back() > prec::Unknown) | Current.FakeLParens.back() > prec::Unknown) | ||||
State.Stack.back().NoLineBreak = true; | State.Stack.back().NoLineBreak = true; | ||||
if (Previous.is(TT_TemplateString) && Previous.opensScope()) | if (Previous.is(TT_TemplateString) && Previous.opensScope()) | ||||
State.Stack.back().NoLineBreak = true; | State.Stack.back().NoLineBreak = true; | ||||
if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign && | if (Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign && | ||||
!State.Stack.back().IsCSharpGenericTypeConstraint && | !State.Stack.back().IsCSharpGenericTypeConstraint && | ||||
Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) && | Previous.opensScope() && Previous.isNot(TT_ObjCMethodExpr) && | ||||
(Current.isNot(TT_LineComment) || Previous.BlockKind == BK_BracedInit)) { | (Current.isNot(TT_LineComment) || Previous.is(BK_BracedInit))) { | ||||
State.Stack.back().Indent = State.Column + Spaces; | State.Stack.back().Indent = State.Column + Spaces; | ||||
MyDeveloperDay: I think this is better in that its now easier perhaps to see when the block kind gets checked… | |||||
Yes I think I agree with you; adding is and isNot would be an improvement. I will still leave getBlockKind if someone wants to switch on it. riccibruno: Yes I think I agree with you; adding `is` and `isNot` would be an improvement. I will still… | |||||
State.Stack.back().IsAligned = true; | State.Stack.back().IsAligned = true; | ||||
} | } | ||||
if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style)) | if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style)) | ||||
State.Stack.back().NoLineBreak = true; | State.Stack.back().NoLineBreak = true; | ||||
if (startsSegmentOfBuilderTypeCall(Current) && | if (startsSegmentOfBuilderTypeCall(Current) && | ||||
State.Column > getNewLineColumn(State)) | State.Column > getNewLineColumn(State)) | ||||
State.Stack.back().ContainsUnwrappedBuilder = true; | State.Stack.back().ContainsUnwrappedBuilder = true; | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | if (Style.Language == FormatStyle::LK_Java && | ||||
return std::max(State.Stack.back().LastSpace, | return std::max(State.Stack.back().LastSpace, | ||||
State.Stack.back().Indent + Style.ContinuationIndentWidth); | State.Stack.back().Indent + Style.ContinuationIndentWidth); | ||||
if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths && | if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths && | ||||
State.Line->First->is(tok::kw_enum)) | State.Line->First->is(tok::kw_enum)) | ||||
return (Style.IndentWidth * State.Line->First->IndentLevel) + | return (Style.IndentWidth * State.Line->First->IndentLevel) + | ||||
Style.IndentWidth; | Style.IndentWidth; | ||||
if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block) | if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) | ||||
return Current.NestingLevel == 0 ? State.FirstIndent | return Current.NestingLevel == 0 ? State.FirstIndent | ||||
: State.Stack.back().Indent; | : State.Stack.back().Indent; | ||||
if ((Current.isOneOf(tok::r_brace, tok::r_square) || | if ((Current.isOneOf(tok::r_brace, tok::r_square) || | ||||
(Current.is(tok::greater) && | (Current.is(tok::greater) && | ||||
(Style.Language == FormatStyle::LK_Proto || | (Style.Language == FormatStyle::LK_Proto || | ||||
Style.Language == FormatStyle::LK_TextProto))) && | Style.Language == FormatStyle::LK_TextProto))) && | ||||
State.Stack.size() > 1) { | State.Stack.size() > 1) { | ||||
if (Current.closesBlockOrBlockTypeList(Style)) | if (Current.closesBlockOrBlockTypeList(Style)) | ||||
return State.Stack[State.Stack.size() - 2].NestedBlockIndent; | return State.Stack[State.Stack.size() - 2].NestedBlockIndent; | ||||
if (Current.MatchingParen && | if (Current.MatchingParen && Current.MatchingParen->is(BK_BracedInit)) | ||||
Current.MatchingParen->BlockKind == BK_BracedInit) | |||||
return State.Stack[State.Stack.size() - 2].LastSpace; | return State.Stack[State.Stack.size() - 2].LastSpace; | ||||
return State.FirstIndent; | return State.FirstIndent; | ||||
} | } | ||||
// Indent a closing parenthesis at the previous level if followed by a semi, | // Indent a closing parenthesis at the previous level if followed by a semi, | ||||
// const, or opening brace. This allows indentations such as: | // const, or opening brace. This allows indentations such as: | ||||
// foo( | // foo( | ||||
// a, | // a, | ||||
// ); | // ); | ||||
▲ Show 20 Lines • Show All 417 Lines • ▼ Show 20 Lines | void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, | ||||
if (!Current.opensScope()) | if (!Current.opensScope()) | ||||
return; | return; | ||||
// Don't allow '<' or '(' in C# generic type constraints to start new scopes. | // Don't allow '<' or '(' in C# generic type constraints to start new scopes. | ||||
if (Current.isOneOf(tok::less, tok::l_paren) && | if (Current.isOneOf(tok::less, tok::l_paren) && | ||||
State.Stack.back().IsCSharpGenericTypeConstraint) | State.Stack.back().IsCSharpGenericTypeConstraint) | ||||
return; | return; | ||||
if (Current.MatchingParen && Current.BlockKind == BK_Block) { | if (Current.MatchingParen && Current.is(BK_Block)) { | ||||
moveStateToNewBlock(State); | moveStateToNewBlock(State); | ||||
return; | return; | ||||
} | } | ||||
unsigned NewIndent; | unsigned NewIndent; | ||||
unsigned LastSpace = State.Stack.back().LastSpace; | unsigned LastSpace = State.Stack.back().LastSpace; | ||||
bool AvoidBinPacking; | bool AvoidBinPacking; | ||||
bool BreakBeforeParameter = false; | bool BreakBeforeParameter = false; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | bool BinPackDeclaration = | ||||
(State.Line->Type == LT_ObjCDecl && ObjCBinPackProtocolList); | (State.Line->Type == LT_ObjCDecl && ObjCBinPackProtocolList); | ||||
AvoidBinPacking = | AvoidBinPacking = | ||||
(State.Stack.back().IsCSharpGenericTypeConstraint) || | (State.Stack.back().IsCSharpGenericTypeConstraint) || | ||||
(Style.Language == FormatStyle::LK_JavaScript && EndsInComma) || | (Style.Language == FormatStyle::LK_JavaScript && EndsInComma) || | ||||
(State.Line->MustBeDeclaration && !BinPackDeclaration) || | (State.Line->MustBeDeclaration && !BinPackDeclaration) || | ||||
(!State.Line->MustBeDeclaration && !Style.BinPackArguments) || | (!State.Line->MustBeDeclaration && !Style.BinPackArguments) || | ||||
(Style.ExperimentalAutoDetectBinPacking && | (Style.ExperimentalAutoDetectBinPacking && | ||||
(Current.PackingKind == PPK_OnePerLine || | (Current.getPackingKind() == PPK_OnePerLine || | ||||
MyDeveloperDayUnsubmitted Current.is(PPK_OnePerLine) MyDeveloperDay: Current.is(PPK_OnePerLine) | |||||
(!BinPackInconclusiveFunctions && | (!BinPackInconclusiveFunctions && | ||||
Current.PackingKind == PPK_Inconclusive))); | Current.getPackingKind() == PPK_Inconclusive))); | ||||
MyDeveloperDayUnsubmitted Current.is(PPK_Inconclusive) MyDeveloperDay: Current.is(PPK_Inconclusive) | |||||
if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen && | if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen && | ||||
Style.ObjCBreakBeforeNestedBlockParam) { | Style.ObjCBreakBeforeNestedBlockParam) { | ||||
if (Style.ColumnLimit) { | if (Style.ColumnLimit) { | ||||
// If this '[' opens an ObjC call, determine whether all parameters fit | // If this '[' opens an ObjC call, determine whether all parameters fit | ||||
// into one line and put one per line if they don't. | // into one line and put one per line if they don't. | ||||
if (getLengthToMatchingParen(Current, State.Stack) + State.Column > | if (getLengthToMatchingParen(Current, State.Stack) + State.Column > | ||||
getColumnLimit(State)) | getColumnLimit(State)) | ||||
▲ Show 20 Lines • Show All 865 Lines • Show Last 20 Lines |
I think this is better in that its now easier perhaps to see when the block kind gets checked:
I wonder if it would read even better as if we added is(BraceBlockKind) isNot(BraceBlockKind)
e.g.
Previous.is(BK_BraceInit)