diff options
Diffstat (limited to 'lib/Format/ContinuationIndenter.cpp')
-rw-r--r-- | lib/Format/ContinuationIndenter.cpp | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 7ca588a675b5a..c369b94b99878 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -403,7 +403,9 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { // }.bind(...)); // FIXME: We should find a more generic solution to this problem. !(State.Column <= NewLineColumn && - Style.Language == FormatStyle::LK_JavaScript)) + Style.Language == FormatStyle::LK_JavaScript) && + !(Previous.closesScopeAfterBlock() && + State.Column <= NewLineColumn)) return true; // If the template declaration spans multiple lines, force wrap before the @@ -700,7 +702,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // Indent relative to the RHS of the expression unless this is a simple // assignment without binary expression on the RHS. Also indent relative to // unary operators and the colons of constructor initializers. - State.Stack.back().LastSpace = State.Column; + if (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None) + State.Stack.back().LastSpace = State.Column; } else if (Previous.is(TT_InheritanceColon)) { State.Stack.back().Indent = State.Column; State.Stack.back().LastSpace = State.Column; @@ -1132,7 +1135,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, // }, a, b, c); if (Current.isNot(tok::comment) && Previous && Previous->isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) && - !Previous->is(TT_DictLiteral) && State.Stack.size() > 1) { + !Previous->is(TT_DictLiteral) && State.Stack.size() > 1 && + !State.Stack.back().HasMultipleNestedBlocks) { if (State.Stack[State.Stack.size() - 2].NestedBlockInlined && Newline) for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) State.Stack[i].NoLineBreak = true; @@ -1499,10 +1503,25 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( // violate the rectangle rule and visually flows within the surrounding // source. bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n'; - unsigned NextStartColumn = - ContentStartsOnNewline - ? State.Stack.back().NestedBlockIndent + Style.IndentWidth - : FirstStartColumn; + // If this token is the last parameter (checked by looking if it's followed by + // `)`, the base the indent off the line's nested block indent. Otherwise, + // base the indent off the arguments indent, so we can achieve: + // fffffffffff(1, 2, 3, R"pb( + // key1: 1 # + // key2: 2)pb"); + // + // fffffffffff(1, 2, 3, + // R"pb( + // key1: 1 # + // key2: 2 + // )pb", + // 5); + unsigned CurrentIndent = (Current.Next && Current.Next->is(tok::r_paren)) + ? State.Stack.back().NestedBlockIndent + : State.Stack.back().Indent; + unsigned NextStartColumn = ContentStartsOnNewline + ? CurrentIndent + Style.IndentWidth + : FirstStartColumn; // The last start column is the column the raw string suffix starts if it is // put on a newline. @@ -1514,7 +1533,7 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( // indent. unsigned LastStartColumn = Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize - : State.Stack.back().NestedBlockIndent; + : CurrentIndent; std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat( RawStringStyle, RawText, {tooling::Range(0, RawText.size())}, @@ -1524,8 +1543,7 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( auto NewCode = applyAllReplacements(RawText, Fixes.first); tooling::Replacements NoFixes; if (!NewCode) { - State.Column += Current.ColumnWidth; - return 0; + return addMultilineToken(Current, State); } if (!DryRun) { if (NewDelimiter != OldDelimiter) { @@ -1574,6 +1592,13 @@ unsigned ContinuationIndenter::reformatRawStringLiteral( unsigned PrefixExcessCharacters = StartColumn + NewPrefixSize > Style.ColumnLimit ? StartColumn + NewPrefixSize - Style.ColumnLimit : 0; + bool IsMultiline = + ContentStartsOnNewline || (NewCode->find('\n') != std::string::npos); + if (IsMultiline) { + // Break before further function parameters on all levels. + for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) + State.Stack[i].BreakBeforeParameter = true; + } return Fixes.second + PrefixExcessCharacters * Style.PenaltyExcessCharacter; } @@ -1840,7 +1865,8 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, // No break opportunity - update the penalty and continue with the next // logical line. if (LineIndex < EndIndex - 1) - // The last line's penalty is handled in addNextStateToQueue(). + // The last line's penalty is handled in addNextStateToQueue() or when + // calling replaceWhitespaceAfterLastLine below. Penalty += Style.PenaltyExcessCharacter * (ContentStartColumn + RemainingTokenColumns - ColumnLimit); LLVM_DEBUG(llvm::dbgs() << " No break opportunity.\n"); @@ -2095,6 +2121,12 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, Token->getSplitAfterLastLine(TailOffset); if (SplitAfterLastLine.first != StringRef::npos) { LLVM_DEBUG(llvm::dbgs() << "Replacing whitespace after last line.\n"); + + // We add the last line's penalty here, since that line is going to be split + // now. + Penalty += Style.PenaltyExcessCharacter * + (ContentStartColumn + RemainingTokenColumns - ColumnLimit); + if (!DryRun) Token->replaceWhitespaceAfterLastLine(TailOffset, SplitAfterLastLine, Whitespaces); |