summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format/ContinuationIndenter.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2014-06-03 12:02:45 +0000
committerDaniel Jasper <djasper@google.com>2014-06-03 12:02:45 +0000
commit114a2bc9d25de52a1beacd18aff3a07929c64910 (patch)
tree60e4dad973d46a8daba7302d9a1b82575598e543 /clang/lib/Format/ContinuationIndenter.cpp
parentbe6d91f1ba7472469dfe865df3d9eb3b0cde0791 (diff)
downloadbcm5719-llvm-114a2bc9d25de52a1beacd18aff3a07929c64910.tar.gz
bcm5719-llvm-114a2bc9d25de52a1beacd18aff3a07929c64910.zip
clang-format: Refactor indentation behavior for multiple nested blocks.
This fixes a few oddities when formatting multiple nested JavaScript blocks, e.g.: Before: promise.then( function success() { doFoo(); doBar(); }, [], function error() { doFoo(); doBaz(); }); promise.then([], function success() { doFoo(); doBar(); }, function error() { doFoo(); doBaz(); }); After: promise.then( function success() { doFoo(); doBar(); }, [], function error() { doFoo(); doBaz(); }); promise.then([], function success() { doFoo(); doBar(); }, function error() { doFoo(); doBaz(); }); llvm-svn: 210097
Diffstat (limited to 'clang/lib/Format/ContinuationIndenter.cpp')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 01467f995d8..5e63d0cb9be 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -112,6 +112,15 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
return false;
if (Current.isMemberAccess() && State.Stack.back().ContainsUnwrappedBuilder)
return false;
+
+ // Don't create a 'hanging' indent if there are multiple blocks in a single
+ // statement.
+ if (Style.Language == FormatStyle::LK_JavaScript &&
+ Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
+ State.Stack[State.Stack.size() - 2].JSFunctionInlined &&
+ State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks)
+ return false;
+
return !State.Stack.back().NoLineBreak;
}
@@ -294,7 +303,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// Treat the condition inside an if as if it was a second function
// parameter, i.e. let nested calls have a continuation indent.
State.Stack.back().LastSpace = State.Column;
- else if (Current.isNot(tok::comment) &&
+ else if (!Current.isOneOf(tok::comment, tok::caret) &&
(Previous.is(tok::comma) ||
(Previous.is(tok::colon) && Previous.Type == TT_ObjCMethodExpr)))
State.Stack.back().LastSpace = State.Column;
@@ -589,8 +598,6 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
Current.LastOperator ? 0 : State.Column + Current.ColumnWidth;
if (Current.Type == TT_ObjCSelectorName)
State.Stack.back().ObjCSelectorNameFound = true;
- if (Current.Type == TT_LambdaLSquare)
- ++State.Stack.back().LambdasFound;
if (Current.Type == TT_CtorInitializerColon) {
// Indent 2 from the column, so:
// SomeClass::SomeClass()
@@ -767,24 +774,24 @@ static void consumeRParens(LineState& State, const FormatToken &Tok) {
// SomeFunction(a, [] {
// f(); // break
// });
-static bool fakeRParenSpecialCase(const FormatToken& Tok) {
+static bool fakeRParenSpecialCase(const LineState &State) {
+ const FormatToken &Tok = *State.NextToken;
if (!Tok.MatchingParen)
return false;
const FormatToken *Left = &Tok;
if (Tok.isOneOf(tok::r_brace, tok::r_square))
Left = Tok.MatchingParen;
- return Left->isOneOf(tok::l_brace, tok::l_square) &&
+ return !State.Stack.back().HasMultipleNestedBlocks &&
+ Left->isOneOf(tok::l_brace, tok::l_square) &&
(Left->BlockKind == BK_Block ||
Left->Type == TT_ArrayInitializerLSquare ||
Left->Type == TT_DictLiteral);
}
void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
- const FormatToken &Current = *State.NextToken;
-
// Don't remove FakeRParens attached to r_braces that surround nested blocks
// as they will have been removed early (see above).
- if (fakeRParenSpecialCase(Current))
+ if (fakeRParenSpecialCase(State))
return;
consumeRParens(State, *State.NextToken);
@@ -806,7 +813,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
bool AvoidBinPacking;
bool BreakBeforeParameter = false;
if (Current.is(tok::l_brace) || Current.Type == TT_ArrayInitializerLSquare) {
- if (fakeRParenSpecialCase(Current))
+ if (fakeRParenSpecialCase(State))
consumeRParens(State, *Current.MatchingParen);
NewIndent = State.Stack.back().LastSpace;
@@ -848,6 +855,7 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
State.Stack.back().LastSpace,
AvoidBinPacking, NoLineBreak));
State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
+ State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
}
void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
@@ -874,10 +882,7 @@ void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
// If we have already found more than one lambda introducers on this level, we
// opt out of this because similarity between the lambdas is more important.
- // FIXME: This should use fakeRParenSpecialCase() and fakeRParenSpecialCase()
- // Needs to include the LambdasFound check. Otherwise the corresponding
- // fake r_parens will never be consumed.
- if (State.Stack.back().LambdasFound <= 1)
+ if (fakeRParenSpecialCase(State))
consumeRParens(State, *State.NextToken->MatchingParen);
// For some reason, ObjC blocks are indented like continuations.
OpenPOWER on IntegriCloud