clang API Documentation
00001 //===--- ContinuationIndenter.cpp - Format C++ code -----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief This file implements the continuation indenter. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "BreakableToken.h" 00016 #include "ContinuationIndenter.h" 00017 #include "WhitespaceManager.h" 00018 #include "clang/Basic/OperatorPrecedence.h" 00019 #include "clang/Basic/SourceManager.h" 00020 #include "clang/Format/Format.h" 00021 #include "llvm/Support/Debug.h" 00022 #include <string> 00023 00024 #define DEBUG_TYPE "format-formatter" 00025 00026 namespace clang { 00027 namespace format { 00028 00029 // Returns the length of everything up to the first possible line break after 00030 // the ), ], } or > matching \c Tok. 00031 static unsigned getLengthToMatchingParen(const FormatToken &Tok) { 00032 if (!Tok.MatchingParen) 00033 return 0; 00034 FormatToken *End = Tok.MatchingParen; 00035 while (End->Next && !End->Next->CanBreakBefore) { 00036 End = End->Next; 00037 } 00038 return End->TotalLength - Tok.TotalLength + 1; 00039 } 00040 00041 // Returns \c true if \c Tok is the "." or "->" of a call and starts the next 00042 // segment of a builder type call. 00043 static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok) { 00044 return Tok.isMemberAccess() && Tok.Previous && Tok.Previous->closesScope(); 00045 } 00046 00047 // Returns \c true if \c Current starts a new parameter. 00048 static bool startsNextParameter(const FormatToken &Current, 00049 const FormatStyle &Style) { 00050 const FormatToken &Previous = *Current.Previous; 00051 if (Current.Type == TT_CtorInitializerComma && 00052 Style.BreakConstructorInitializersBeforeComma) 00053 return true; 00054 return Previous.is(tok::comma) && !Current.isTrailingComment() && 00055 (Previous.Type != TT_CtorInitializerComma || 00056 !Style.BreakConstructorInitializersBeforeComma); 00057 } 00058 00059 ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style, 00060 const AdditionalKeywords &Keywords, 00061 SourceManager &SourceMgr, 00062 WhitespaceManager &Whitespaces, 00063 encoding::Encoding Encoding, 00064 bool BinPackInconclusiveFunctions) 00065 : Style(Style), Keywords(Keywords), SourceMgr(SourceMgr), 00066 Whitespaces(Whitespaces), Encoding(Encoding), 00067 BinPackInconclusiveFunctions(BinPackInconclusiveFunctions), 00068 CommentPragmasRegex(Style.CommentPragmas) {} 00069 00070 LineState ContinuationIndenter::getInitialState(unsigned FirstIndent, 00071 const AnnotatedLine *Line, 00072 bool DryRun) { 00073 LineState State; 00074 State.FirstIndent = FirstIndent; 00075 State.Column = FirstIndent; 00076 State.Line = Line; 00077 State.NextToken = Line->First; 00078 State.Stack.push_back(ParenState(FirstIndent, Line->Level, FirstIndent, 00079 /*AvoidBinPacking=*/false, 00080 /*NoLineBreak=*/false)); 00081 State.LineContainsContinuedForLoopSection = false; 00082 State.StartOfStringLiteral = 0; 00083 State.StartOfLineLevel = 0; 00084 State.LowestLevelOnLine = 0; 00085 State.IgnoreStackForComparison = false; 00086 00087 // The first token has already been indented and thus consumed. 00088 moveStateToNextToken(State, DryRun, /*Newline=*/false); 00089 return State; 00090 } 00091 00092 bool ContinuationIndenter::canBreak(const LineState &State) { 00093 const FormatToken &Current = *State.NextToken; 00094 const FormatToken &Previous = *Current.Previous; 00095 assert(&Previous == Current.Previous); 00096 if (!Current.CanBreakBefore && !(State.Stack.back().BreakBeforeClosingBrace && 00097 Current.closesBlockTypeList(Style))) 00098 return false; 00099 // The opening "{" of a braced list has to be on the same line as the first 00100 // element if it is nested in another braced init list or function call. 00101 if (!Current.MustBreakBefore && Previous.is(tok::l_brace) && 00102 Previous.Type != TT_DictLiteral && Previous.BlockKind == BK_BracedInit && 00103 Previous.Previous && 00104 Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma)) 00105 return false; 00106 // This prevents breaks like: 00107 // ... 00108 // SomeParameter, OtherParameter).DoSomething( 00109 // ... 00110 // As they hide "DoSomething" and are generally bad for readability. 00111 if (Previous.opensScope() && Previous.isNot(tok::l_brace) && 00112 State.LowestLevelOnLine < State.StartOfLineLevel && 00113 State.LowestLevelOnLine < Current.NestingLevel) 00114 return false; 00115 if (Current.isMemberAccess() && State.Stack.back().ContainsUnwrappedBuilder) 00116 return false; 00117 00118 // Don't create a 'hanging' indent if there are multiple blocks in a single 00119 // statement. 00120 if (Style.Language == FormatStyle::LK_JavaScript && 00121 Previous.is(tok::l_brace) && State.Stack.size() > 1 && 00122 State.Stack[State.Stack.size() - 2].JSFunctionInlined && 00123 State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks) 00124 return false; 00125 00126 // Don't break after very short return types (e.g. "void") as that is often 00127 // unexpected. 00128 if (Current.Type == TT_FunctionDeclarationName && 00129 !Style.AlwaysBreakAfterDefinitionReturnType && State.Column < 6) 00130 return false; 00131 00132 return !State.Stack.back().NoLineBreak; 00133 } 00134 00135 bool ContinuationIndenter::mustBreak(const LineState &State) { 00136 const FormatToken &Current = *State.NextToken; 00137 const FormatToken &Previous = *Current.Previous; 00138 if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon) 00139 return true; 00140 if (State.Stack.back().BreakBeforeClosingBrace && 00141 Current.closesBlockTypeList(Style)) 00142 return true; 00143 if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) 00144 return true; 00145 if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || 00146 (Style.BreakBeforeTernaryOperators && 00147 (Current.is(tok::question) || (Current.Type == TT_ConditionalExpr && 00148 Previous.isNot(tok::question)))) || 00149 (!Style.BreakBeforeTernaryOperators && 00150 (Previous.is(tok::question) || Previous.Type == TT_ConditionalExpr))) && 00151 State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() && 00152 !Current.isOneOf(tok::r_paren, tok::r_brace)) 00153 return true; 00154 if (Style.AlwaysBreakBeforeMultilineStrings && 00155 State.Column > State.Stack.back().Indent && // Breaking saves columns. 00156 !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at) && 00157 Previous.Type != TT_InlineASMColon && 00158 Previous.Type != TT_ConditionalExpr && nextIsMultilineString(State)) 00159 return true; 00160 if (((Previous.Type == TT_DictLiteral && Previous.is(tok::l_brace)) || 00161 Previous.Type == TT_ArrayInitializerLSquare) && 00162 Style.ColumnLimit > 0 && 00163 getLengthToMatchingParen(Previous) + State.Column > getColumnLimit(State)) 00164 return true; 00165 if (Current.Type == TT_CtorInitializerColon && 00166 ((Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All) || 00167 Style.BreakConstructorInitializersBeforeComma || Style.ColumnLimit != 0)) 00168 return true; 00169 00170 if (State.Column < getNewLineColumn(State)) 00171 return false; 00172 if (!Style.BreakBeforeBinaryOperators) { 00173 // If we need to break somewhere inside the LHS of a binary expression, we 00174 // should also break after the operator. Otherwise, the formatting would 00175 // hide the operator precedence, e.g. in: 00176 // if (aaaaaaaaaaaaaa == 00177 // bbbbbbbbbbbbbb && c) {.. 00178 // For comparisons, we only apply this rule, if the LHS is a binary 00179 // expression itself as otherwise, the line breaks seem superfluous. 00180 // We need special cases for ">>" which we have split into two ">" while 00181 // lexing in order to make template parsing easier. 00182 // 00183 // FIXME: We'll need something similar for styles that break before binary 00184 // operators. 00185 bool IsComparison = (Previous.getPrecedence() == prec::Relational || 00186 Previous.getPrecedence() == prec::Equality) && 00187 Previous.Previous && 00188 Previous.Previous->Type != TT_BinaryOperator; // For >>. 00189 bool LHSIsBinaryExpr = 00190 Previous.Previous && Previous.Previous->EndsBinaryExpression; 00191 if (Previous.Type == TT_BinaryOperator && 00192 (!IsComparison || LHSIsBinaryExpr) && 00193 Current.Type != TT_BinaryOperator && // For >>. 00194 !Current.isTrailingComment() && !Previous.is(tok::lessless) && 00195 Previous.getPrecedence() != prec::Assignment && 00196 State.Stack.back().BreakBeforeParameter) 00197 return true; 00198 } 00199 00200 // Same as above, but for the first "<<" operator. 00201 if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator && 00202 State.Stack.back().BreakBeforeParameter && 00203 State.Stack.back().FirstLessLess == 0) 00204 return true; 00205 00206 if (Current.Type == TT_SelectorName && 00207 State.Stack.back().ObjCSelectorNameFound && 00208 State.Stack.back().BreakBeforeParameter) 00209 return true; 00210 if (Previous.ClosesTemplateDeclaration && Current.NestingLevel == 0 && 00211 !Current.isTrailingComment()) 00212 return true; 00213 00214 // If the return type spans multiple lines, wrap before the function name. 00215 if ((Current.Type == TT_FunctionDeclarationName || 00216 Current.is(tok::kw_operator)) && 00217 State.Stack.back().BreakBeforeParameter) 00218 return true; 00219 00220 if (startsSegmentOfBuilderTypeCall(Current) && 00221 (State.Stack.back().CallContinuation != 0 || 00222 (State.Stack.back().BreakBeforeParameter && 00223 State.Stack.back().ContainsUnwrappedBuilder))) 00224 return true; 00225 00226 // The following could be precomputed as they do not depend on the state. 00227 // However, as they should take effect only if the UnwrappedLine does not fit 00228 // into the ColumnLimit, they are checked here in the ContinuationIndenter. 00229 if (Style.ColumnLimit != 0 && Previous.BlockKind == BK_Block && 00230 Previous.is(tok::l_brace) && !Current.isOneOf(tok::r_brace, tok::comment)) 00231 return true; 00232 00233 return false; 00234 } 00235 00236 unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, 00237 bool DryRun, 00238 unsigned ExtraSpaces) { 00239 const FormatToken &Current = *State.NextToken; 00240 00241 assert(!State.Stack.empty()); 00242 if ((Current.Type == TT_ImplicitStringLiteral && 00243 (Current.Previous->Tok.getIdentifierInfo() == nullptr || 00244 Current.Previous->Tok.getIdentifierInfo()->getPPKeywordID() == 00245 tok::pp_not_keyword))) { 00246 // FIXME: Is this correct? 00247 int WhitespaceLength = SourceMgr.getSpellingColumnNumber( 00248 State.NextToken->WhitespaceRange.getEnd()) - 00249 SourceMgr.getSpellingColumnNumber( 00250 State.NextToken->WhitespaceRange.getBegin()); 00251 State.Column += WhitespaceLength; 00252 moveStateToNextToken(State, DryRun, /*Newline=*/false); 00253 return 0; 00254 } 00255 00256 unsigned Penalty = 0; 00257 if (Newline) 00258 Penalty = addTokenOnNewLine(State, DryRun); 00259 else 00260 addTokenOnCurrentLine(State, DryRun, ExtraSpaces); 00261 00262 return moveStateToNextToken(State, DryRun, Newline) + Penalty; 00263 } 00264 00265 void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, 00266 unsigned ExtraSpaces) { 00267 FormatToken &Current = *State.NextToken; 00268 const FormatToken &Previous = *State.NextToken->Previous; 00269 if (Current.is(tok::equal) && 00270 (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) && 00271 State.Stack.back().VariablePos == 0) { 00272 State.Stack.back().VariablePos = State.Column; 00273 // Move over * and & if they are bound to the variable name. 00274 const FormatToken *Tok = &Previous; 00275 while (Tok && State.Stack.back().VariablePos >= Tok->ColumnWidth) { 00276 State.Stack.back().VariablePos -= Tok->ColumnWidth; 00277 if (Tok->SpacesRequiredBefore != 0) 00278 break; 00279 Tok = Tok->Previous; 00280 } 00281 if (Previous.PartOfMultiVariableDeclStmt) 00282 State.Stack.back().LastSpace = State.Stack.back().VariablePos; 00283 } 00284 00285 unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces; 00286 00287 if (!DryRun) 00288 Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0, 00289 Spaces, State.Column + Spaces); 00290 00291 if (Current.Type == TT_SelectorName && 00292 !State.Stack.back().ObjCSelectorNameFound) { 00293 if (Current.LongestObjCSelectorName == 0) 00294 State.Stack.back().AlignColons = false; 00295 else if (State.Stack.back().Indent + Current.LongestObjCSelectorName > 00296 State.Column + Spaces + Current.ColumnWidth) 00297 State.Stack.back().ColonPos = 00298 State.Stack.back().Indent + Current.LongestObjCSelectorName; 00299 else 00300 State.Stack.back().ColonPos = State.Column + Spaces + Current.ColumnWidth; 00301 } 00302 00303 if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr && 00304 (Current.Type != TT_LineComment || Previous.BlockKind == BK_BracedInit)) 00305 State.Stack.back().Indent = State.Column + Spaces; 00306 if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style)) 00307 State.Stack.back().NoLineBreak = true; 00308 if (startsSegmentOfBuilderTypeCall(Current)) 00309 State.Stack.back().ContainsUnwrappedBuilder = true; 00310 00311 if (Current.isMemberAccess() && Previous.is(tok::r_paren) && 00312 (Previous.MatchingParen && 00313 (Previous.TotalLength - Previous.MatchingParen->TotalLength > 10))) { 00314 // If there is a function call with long parameters, break before trailing 00315 // calls. This prevents things like: 00316 // EXPECT_CALL(SomeLongParameter).Times( 00317 // 2); 00318 // We don't want to do this for short parameters as they can just be 00319 // indexes. 00320 State.Stack.back().NoLineBreak = true; 00321 } 00322 00323 State.Column += Spaces; 00324 if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) && 00325 Previous.Previous && Previous.Previous->isOneOf(tok::kw_if, tok::kw_for)) 00326 // Treat the condition inside an if as if it was a second function 00327 // parameter, i.e. let nested calls have a continuation indent. 00328 State.Stack.back().LastSpace = State.Column; 00329 else if (!Current.isOneOf(tok::comment, tok::caret) && 00330 (Previous.is(tok::comma) || 00331 (Previous.is(tok::colon) && Previous.Type == TT_ObjCMethodExpr))) 00332 State.Stack.back().LastSpace = State.Column; 00333 else if ((Previous.Type == TT_BinaryOperator || 00334 Previous.Type == TT_ConditionalExpr || 00335 Previous.Type == TT_CtorInitializerColon) && 00336 ((Previous.getPrecedence() != prec::Assignment && 00337 (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 || 00338 !Previous.LastOperator)) || 00339 Current.StartsBinaryExpression)) 00340 // Always indent relative to the RHS of the expression unless this is a 00341 // simple assignment without binary expression on the RHS. Also indent 00342 // relative to unary operators and the colons of constructor initializers. 00343 State.Stack.back().LastSpace = State.Column; 00344 else if (Previous.Type == TT_InheritanceColon) { 00345 State.Stack.back().Indent = State.Column; 00346 State.Stack.back().LastSpace = State.Column; 00347 } else if (Previous.opensScope()) { 00348 // If a function has a trailing call, indent all parameters from the 00349 // opening parenthesis. This avoids confusing indents like: 00350 // OuterFunction(InnerFunctionCall( // break 00351 // ParameterToInnerFunction)) // break 00352 // .SecondInnerFunctionCall(); 00353 bool HasTrailingCall = false; 00354 if (Previous.MatchingParen) { 00355 const FormatToken *Next = Previous.MatchingParen->getNextNonComment(); 00356 HasTrailingCall = Next && Next->isMemberAccess(); 00357 } 00358 if (HasTrailingCall && 00359 State.Stack[State.Stack.size() - 2].CallContinuation == 0) 00360 State.Stack.back().LastSpace = State.Column; 00361 } 00362 } 00363 00364 unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, 00365 bool DryRun) { 00366 FormatToken &Current = *State.NextToken; 00367 const FormatToken &Previous = *State.NextToken->Previous; 00368 00369 // Extra penalty that needs to be added because of the way certain line 00370 // breaks are chosen. 00371 unsigned Penalty = 0; 00372 00373 const FormatToken *PreviousNonComment = Current.getPreviousNonComment(); 00374 const FormatToken *NextNonComment = Previous.getNextNonComment(); 00375 if (!NextNonComment) 00376 NextNonComment = &Current; 00377 // The first line break on any NestingLevel causes an extra penalty in order 00378 // prefer similar line breaks. 00379 if (!State.Stack.back().ContainsLineBreak) 00380 Penalty += 15; 00381 State.Stack.back().ContainsLineBreak = true; 00382 00383 Penalty += State.NextToken->SplitPenalty; 00384 00385 // Breaking before the first "<<" is generally not desirable if the LHS is 00386 // short. Also always add the penalty if the LHS is split over mutliple lines 00387 // to avoid unnecessary line breaks that just work around this penalty. 00388 if (NextNonComment->is(tok::lessless) && 00389 State.Stack.back().FirstLessLess == 0 && 00390 (State.Column <= Style.ColumnLimit / 3 || 00391 State.Stack.back().BreakBeforeParameter)) 00392 Penalty += Style.PenaltyBreakFirstLessLess; 00393 00394 State.Column = getNewLineColumn(State); 00395 if (NextNonComment->isMemberAccess()) { 00396 if (State.Stack.back().CallContinuation == 0) 00397 State.Stack.back().CallContinuation = State.Column; 00398 } else if (NextNonComment->Type == TT_SelectorName) { 00399 if (!State.Stack.back().ObjCSelectorNameFound) { 00400 if (NextNonComment->LongestObjCSelectorName == 0) { 00401 State.Stack.back().AlignColons = false; 00402 } else { 00403 State.Stack.back().ColonPos = 00404 State.Stack.back().Indent + NextNonComment->LongestObjCSelectorName; 00405 } 00406 } else if (State.Stack.back().AlignColons && 00407 State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) { 00408 State.Stack.back().ColonPos = State.Column + NextNonComment->ColumnWidth; 00409 } 00410 } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) && 00411 (PreviousNonComment->Type == TT_ObjCMethodExpr || 00412 PreviousNonComment->Type == TT_DictLiteral)) { 00413 // FIXME: This is hacky, find a better way. The problem is that in an ObjC 00414 // method expression, the block should be aligned to the line starting it, 00415 // e.g.: 00416 // [aaaaaaaaaaaaaaa aaaaaaaaa: \\ break for some reason 00417 // ^(int *i) { 00418 // // ... 00419 // }]; 00420 // Thus, we set LastSpace of the next higher NestingLevel, to which we move 00421 // when we consume all of the "}"'s FakeRParens at the "{". 00422 if (State.Stack.size() > 1) 00423 State.Stack[State.Stack.size() - 2].LastSpace = 00424 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 00425 Style.ContinuationIndentWidth; 00426 } 00427 00428 if ((Previous.isOneOf(tok::comma, tok::semi) && 00429 !State.Stack.back().AvoidBinPacking) || 00430 Previous.Type == TT_BinaryOperator) 00431 State.Stack.back().BreakBeforeParameter = false; 00432 if ((Previous.Type == TT_TemplateCloser || 00433 Previous.Type == TT_JavaAnnotation) && 00434 Current.NestingLevel == 0) 00435 State.Stack.back().BreakBeforeParameter = false; 00436 if (NextNonComment->is(tok::question) || 00437 (PreviousNonComment && PreviousNonComment->is(tok::question))) 00438 State.Stack.back().BreakBeforeParameter = true; 00439 00440 if (!DryRun) { 00441 unsigned Newlines = std::max( 00442 1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1)); 00443 Whitespaces.replaceWhitespace(Current, Newlines, 00444 State.Stack.back().IndentLevel, State.Column, 00445 State.Column, State.Line->InPPDirective); 00446 } 00447 00448 if (!Current.isTrailingComment()) 00449 State.Stack.back().LastSpace = State.Column; 00450 State.StartOfLineLevel = Current.NestingLevel; 00451 State.LowestLevelOnLine = Current.NestingLevel; 00452 00453 // Any break on this level means that the parent level has been broken 00454 // and we need to avoid bin packing there. 00455 bool JavaScriptFormat = Style.Language == FormatStyle::LK_JavaScript && 00456 Current.is(tok::r_brace) && 00457 State.Stack.size() > 1 && 00458 State.Stack[State.Stack.size() - 2].JSFunctionInlined; 00459 if (!JavaScriptFormat) { 00460 for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) { 00461 State.Stack[i].BreakBeforeParameter = true; 00462 } 00463 } 00464 00465 if (PreviousNonComment && 00466 !PreviousNonComment->isOneOf(tok::comma, tok::semi) && 00467 (PreviousNonComment->Type != TT_TemplateCloser || 00468 Current.NestingLevel != 0) && 00469 PreviousNonComment->Type != TT_BinaryOperator && 00470 PreviousNonComment->Type != TT_JavaAnnotation && 00471 PreviousNonComment->Type != TT_LeadingJavaAnnotation && 00472 Current.Type != TT_BinaryOperator && !PreviousNonComment->opensScope()) 00473 State.Stack.back().BreakBeforeParameter = true; 00474 00475 // If we break after { or the [ of an array initializer, we should also break 00476 // before the corresponding } or ]. 00477 if (PreviousNonComment && 00478 (PreviousNonComment->is(tok::l_brace) || 00479 PreviousNonComment->Type == TT_ArrayInitializerLSquare)) 00480 State.Stack.back().BreakBeforeClosingBrace = true; 00481 00482 if (State.Stack.back().AvoidBinPacking) { 00483 // If we are breaking after '(', '{', '<', this is not bin packing 00484 // unless AllowAllParametersOfDeclarationOnNextLine is false or this is a 00485 // dict/object literal. 00486 if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) || 00487 Previous.Type == TT_BinaryOperator) || 00488 (!Style.AllowAllParametersOfDeclarationOnNextLine && 00489 State.Line->MustBeDeclaration) || 00490 Previous.Type == TT_DictLiteral) 00491 State.Stack.back().BreakBeforeParameter = true; 00492 } 00493 00494 return Penalty; 00495 } 00496 00497 unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { 00498 if (!State.NextToken || !State.NextToken->Previous) 00499 return 0; 00500 FormatToken &Current = *State.NextToken; 00501 const FormatToken &Previous = *Current.Previous; 00502 // If we are continuing an expression, we want to use the continuation indent. 00503 unsigned ContinuationIndent = 00504 std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 00505 Style.ContinuationIndentWidth; 00506 const FormatToken *PreviousNonComment = Current.getPreviousNonComment(); 00507 const FormatToken *NextNonComment = Previous.getNextNonComment(); 00508 if (!NextNonComment) 00509 NextNonComment = &Current; 00510 00511 // Java specific bits. 00512 if (Style.Language == FormatStyle::LK_Java && 00513 Current.isOneOf(Keywords.kw_implements, Keywords.kw_extends)) 00514 return std::max(State.Stack.back().LastSpace, 00515 State.Stack.back().Indent + Style.ContinuationIndentWidth); 00516 00517 if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block) 00518 return Current.NestingLevel == 0 ? State.FirstIndent 00519 : State.Stack.back().Indent; 00520 if (Current.isOneOf(tok::r_brace, tok::r_square)) { 00521 if (State.Stack.size() > 1 && 00522 State.Stack[State.Stack.size() - 2].JSFunctionInlined) 00523 return State.FirstIndent; 00524 if (Current.closesBlockTypeList(Style) || 00525 (Current.MatchingParen && 00526 Current.MatchingParen->BlockKind == BK_BracedInit)) 00527 return State.Stack[State.Stack.size() - 2].LastSpace; 00528 else 00529 return State.FirstIndent; 00530 } 00531 if (Current.is(tok::identifier) && Current.Next && 00532 Current.Next->Type == TT_DictLiteral) 00533 return State.Stack.back().Indent; 00534 if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0) 00535 return State.StartOfStringLiteral; 00536 if (NextNonComment->is(tok::lessless) && 00537 State.Stack.back().FirstLessLess != 0) 00538 return State.Stack.back().FirstLessLess; 00539 if (NextNonComment->isMemberAccess()) { 00540 if (State.Stack.back().CallContinuation == 0) { 00541 return ContinuationIndent; 00542 } else { 00543 return State.Stack.back().CallContinuation; 00544 } 00545 } 00546 if (State.Stack.back().QuestionColumn != 0 && 00547 ((NextNonComment->is(tok::colon) && 00548 NextNonComment->Type == TT_ConditionalExpr) || 00549 Previous.Type == TT_ConditionalExpr)) 00550 return State.Stack.back().QuestionColumn; 00551 if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) 00552 return State.Stack.back().VariablePos; 00553 if ((PreviousNonComment && 00554 (PreviousNonComment->ClosesTemplateDeclaration || 00555 PreviousNonComment->Type == TT_AttributeParen || 00556 PreviousNonComment->Type == TT_JavaAnnotation || 00557 PreviousNonComment->Type == TT_LeadingJavaAnnotation)) || 00558 (!Style.IndentWrappedFunctionNames && 00559 (NextNonComment->is(tok::kw_operator) || 00560 NextNonComment->Type == TT_FunctionDeclarationName))) 00561 return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent); 00562 if (NextNonComment->Type == TT_SelectorName) { 00563 if (!State.Stack.back().ObjCSelectorNameFound) { 00564 if (NextNonComment->LongestObjCSelectorName == 0) { 00565 return State.Stack.back().Indent; 00566 } else { 00567 return State.Stack.back().Indent + 00568 NextNonComment->LongestObjCSelectorName - 00569 NextNonComment->ColumnWidth; 00570 } 00571 } else if (!State.Stack.back().AlignColons) { 00572 return State.Stack.back().Indent; 00573 } else if (State.Stack.back().ColonPos > NextNonComment->ColumnWidth) { 00574 return State.Stack.back().ColonPos - NextNonComment->ColumnWidth; 00575 } else { 00576 return State.Stack.back().Indent; 00577 } 00578 } 00579 if (NextNonComment->Type == TT_ArraySubscriptLSquare) { 00580 if (State.Stack.back().StartOfArraySubscripts != 0) 00581 return State.Stack.back().StartOfArraySubscripts; 00582 else 00583 return ContinuationIndent; 00584 } 00585 if (NextNonComment->Type == TT_StartOfName || 00586 Previous.isOneOf(tok::coloncolon, tok::equal)) { 00587 return ContinuationIndent; 00588 } 00589 if (PreviousNonComment && PreviousNonComment->is(tok::colon) && 00590 (PreviousNonComment->Type == TT_ObjCMethodExpr || 00591 PreviousNonComment->Type == TT_DictLiteral)) 00592 return ContinuationIndent; 00593 if (NextNonComment->Type == TT_CtorInitializerColon) 00594 return State.FirstIndent + Style.ConstructorInitializerIndentWidth; 00595 if (NextNonComment->Type == TT_CtorInitializerComma) 00596 return State.Stack.back().Indent; 00597 if (Previous.is(tok::r_paren) && !Current.isBinaryOperator() && 00598 !Current.isOneOf(tok::colon, tok::comment)) 00599 return ContinuationIndent; 00600 if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment && 00601 PreviousNonComment->isNot(tok::r_brace)) 00602 // Ensure that we fall back to the continuation indent width instead of 00603 // just flushing continuations left. 00604 return State.Stack.back().Indent + Style.ContinuationIndentWidth; 00605 return State.Stack.back().Indent; 00606 } 00607 00608 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, 00609 bool DryRun, bool Newline) { 00610 assert(State.Stack.size()); 00611 const FormatToken &Current = *State.NextToken; 00612 00613 if (Current.Type == TT_InheritanceColon) 00614 State.Stack.back().AvoidBinPacking = true; 00615 if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator) { 00616 if (State.Stack.back().FirstLessLess == 0) 00617 State.Stack.back().FirstLessLess = State.Column; 00618 else 00619 State.Stack.back().LastOperatorWrapped = Newline; 00620 } 00621 if ((Current.Type == TT_BinaryOperator && Current.isNot(tok::lessless)) || 00622 Current.Type == TT_ConditionalExpr) 00623 State.Stack.back().LastOperatorWrapped = Newline; 00624 if (Current.Type == TT_ArraySubscriptLSquare && 00625 State.Stack.back().StartOfArraySubscripts == 0) 00626 State.Stack.back().StartOfArraySubscripts = State.Column; 00627 if ((Current.is(tok::question) && Style.BreakBeforeTernaryOperators) || 00628 (Current.getPreviousNonComment() && Current.isNot(tok::colon) && 00629 Current.getPreviousNonComment()->is(tok::question) && 00630 !Style.BreakBeforeTernaryOperators)) 00631 State.Stack.back().QuestionColumn = State.Column; 00632 if (!Current.opensScope() && !Current.closesScope()) 00633 State.LowestLevelOnLine = 00634 std::min(State.LowestLevelOnLine, Current.NestingLevel); 00635 if (Current.isMemberAccess()) 00636 State.Stack.back().StartOfFunctionCall = 00637 Current.LastOperator ? 0 : State.Column + Current.ColumnWidth; 00638 if (Current.Type == TT_SelectorName) 00639 State.Stack.back().ObjCSelectorNameFound = true; 00640 if (Current.Type == TT_CtorInitializerColon) { 00641 // Indent 2 from the column, so: 00642 // SomeClass::SomeClass() 00643 // : First(...), ... 00644 // Next(...) 00645 // ^ line up here. 00646 State.Stack.back().Indent = 00647 State.Column + (Style.BreakConstructorInitializersBeforeComma ? 0 : 2); 00648 if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) 00649 State.Stack.back().AvoidBinPacking = true; 00650 State.Stack.back().BreakBeforeParameter = false; 00651 } 00652 00653 // In ObjC method declaration we align on the ":" of parameters, but we need 00654 // to ensure that we indent parameters on subsequent lines by at least our 00655 // continuation indent width. 00656 if (Current.Type == TT_ObjCMethodSpecifier) 00657 State.Stack.back().Indent += Style.ContinuationIndentWidth; 00658 00659 // Insert scopes created by fake parenthesis. 00660 const FormatToken *Previous = Current.getPreviousNonComment(); 00661 00662 // Add special behavior to support a format commonly used for JavaScript 00663 // closures: 00664 // SomeFunction(function() { 00665 // foo(); 00666 // bar(); 00667 // }, a, b, c); 00668 if (Style.Language == FormatStyle::LK_JavaScript) { 00669 if (Current.isNot(tok::comment) && Previous && Previous->is(tok::l_brace) && 00670 State.Stack.size() > 1) { 00671 if (State.Stack[State.Stack.size() - 2].JSFunctionInlined && Newline) { 00672 for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) { 00673 State.Stack[i].NoLineBreak = true; 00674 } 00675 } 00676 State.Stack[State.Stack.size() - 2].JSFunctionInlined = false; 00677 } 00678 if (Current.is(Keywords.kw_function)) 00679 State.Stack.back().JSFunctionInlined = 00680 !Newline && Previous && Previous->Type != TT_DictLiteral && 00681 // If the unnamed function is the only parameter to another function, 00682 // we can likely inline it and come up with a good format. 00683 (Previous->isNot(tok::l_paren) || Previous->ParameterCount > 1); 00684 } 00685 00686 moveStatePastFakeLParens(State, Newline); 00687 moveStatePastScopeOpener(State, Newline); 00688 moveStatePastScopeCloser(State); 00689 moveStatePastFakeRParens(State); 00690 00691 if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) { 00692 State.StartOfStringLiteral = State.Column; 00693 } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) && 00694 !Current.isStringLiteral()) { 00695 State.StartOfStringLiteral = 0; 00696 } 00697 00698 State.Column += Current.ColumnWidth; 00699 State.NextToken = State.NextToken->Next; 00700 unsigned Penalty = breakProtrudingToken(Current, State, DryRun); 00701 if (State.Column > getColumnLimit(State)) { 00702 unsigned ExcessCharacters = State.Column - getColumnLimit(State); 00703 Penalty += Style.PenaltyExcessCharacter * ExcessCharacters; 00704 } 00705 00706 if (Current.Role) 00707 Current.Role->formatFromToken(State, this, DryRun); 00708 // If the previous has a special role, let it consume tokens as appropriate. 00709 // It is necessary to start at the previous token for the only implemented 00710 // role (comma separated list). That way, the decision whether or not to break 00711 // after the "{" is already done and both options are tried and evaluated. 00712 // FIXME: This is ugly, find a better way. 00713 if (Previous && Previous->Role) 00714 Penalty += Previous->Role->formatAfterToken(State, this, DryRun); 00715 00716 return Penalty; 00717 } 00718 00719 void ContinuationIndenter::moveStatePastFakeLParens(LineState &State, 00720 bool Newline) { 00721 const FormatToken &Current = *State.NextToken; 00722 const FormatToken *Previous = Current.getPreviousNonComment(); 00723 00724 // Don't add extra indentation for the first fake parenthesis after 00725 // 'return', assignments or opening <({[. The indentation for these cases 00726 // is special cased. 00727 bool SkipFirstExtraIndent = 00728 (Previous && (Previous->opensScope() || Previous->is(tok::kw_return) || 00729 Previous->getPrecedence() == prec::Assignment || 00730 Previous->Type == TT_ObjCMethodExpr)); 00731 for (SmallVectorImpl<prec::Level>::const_reverse_iterator 00732 I = Current.FakeLParens.rbegin(), 00733 E = Current.FakeLParens.rend(); 00734 I != E; ++I) { 00735 ParenState NewParenState = State.Stack.back(); 00736 NewParenState.ContainsLineBreak = false; 00737 00738 // Indent from 'LastSpace' unless this the fake parentheses encapsulating a 00739 // builder type call after 'return'. If such a call is line-wrapped, we 00740 // commonly just want to indent from the start of the line. 00741 if (!Current.isTrailingComment() && 00742 (!Previous || Previous->isNot(tok::kw_return) || *I > 0)) 00743 NewParenState.Indent = 00744 std::max(std::max(State.Column, NewParenState.Indent), 00745 State.Stack.back().LastSpace); 00746 00747 // Don't allow the RHS of an operator to be split over multiple lines unless 00748 // there is a line-break right after the operator. 00749 // Exclude relational operators, as there, it is always more desirable to 00750 // have the LHS 'left' of the RHS. 00751 if (Previous && Previous->getPrecedence() > prec::Assignment && 00752 (Previous->Type == TT_BinaryOperator || 00753 Previous->Type == TT_ConditionalExpr) && 00754 Previous->getPrecedence() != prec::Relational) { 00755 bool BreakBeforeOperator = Previous->is(tok::lessless) || 00756 (Previous->Type == TT_BinaryOperator && 00757 Style.BreakBeforeBinaryOperators) || 00758 (Previous->Type == TT_ConditionalExpr && 00759 Style.BreakBeforeTernaryOperators); 00760 if ((!Newline && !BreakBeforeOperator) || 00761 (!State.Stack.back().LastOperatorWrapped && BreakBeforeOperator)) 00762 NewParenState.NoLineBreak = true; 00763 } 00764 00765 // Do not indent relative to the fake parentheses inserted for "." or "->". 00766 // This is a special case to make the following to statements consistent: 00767 // OuterFunction(InnerFunctionCall( // break 00768 // ParameterToInnerFunction)); 00769 // OuterFunction(SomeObject.InnerFunctionCall( // break 00770 // ParameterToInnerFunction)); 00771 if (*I > prec::Unknown) 00772 NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column); 00773 NewParenState.StartOfFunctionCall = State.Column; 00774 00775 // Always indent conditional expressions. Never indent expression where 00776 // the 'operator' is ',', ';' or an assignment (i.e. *I <= 00777 // prec::Assignment) as those have different indentation rules. Indent 00778 // other expression, unless the indentation needs to be skipped. 00779 if (*I == prec::Conditional || 00780 (!SkipFirstExtraIndent && *I > prec::Assignment && 00781 !Current.isTrailingComment() && !Style.BreakBeforeBinaryOperators)) 00782 NewParenState.Indent += Style.ContinuationIndentWidth; 00783 if ((Previous && !Previous->opensScope()) || *I > prec::Comma) 00784 NewParenState.BreakBeforeParameter = false; 00785 State.Stack.push_back(NewParenState); 00786 SkipFirstExtraIndent = false; 00787 } 00788 } 00789 00790 // Remove the fake r_parens after 'Tok'. 00791 static void consumeRParens(LineState& State, const FormatToken &Tok) { 00792 for (unsigned i = 0, e = Tok.FakeRParens; i != e; ++i) { 00793 unsigned VariablePos = State.Stack.back().VariablePos; 00794 assert(State.Stack.size() > 1); 00795 if (State.Stack.size() == 1) { 00796 // Do not pop the last element. 00797 break; 00798 } 00799 State.Stack.pop_back(); 00800 State.Stack.back().VariablePos = VariablePos; 00801 } 00802 } 00803 00804 // Returns whether 'Tok' opens or closes a scope requiring special handling 00805 // of the subsequent fake r_parens. 00806 // 00807 // For example, if this is an l_brace starting a nested block, we pretend (wrt. 00808 // to indentation) that we already consumed the corresponding r_brace. Thus, we 00809 // remove all ParenStates caused by fake parentheses that end at the r_brace. 00810 // The net effect of this is that we don't indent relative to the l_brace, if 00811 // the nested block is the last parameter of a function. This formats: 00812 // 00813 // SomeFunction(a, [] { 00814 // f(); // break 00815 // }); 00816 // 00817 // instead of: 00818 // SomeFunction(a, [] { 00819 // f(); // break 00820 // }); 00821 static bool fakeRParenSpecialCase(const LineState &State) { 00822 const FormatToken &Tok = *State.NextToken; 00823 if (!Tok.MatchingParen) 00824 return false; 00825 const FormatToken *Left = &Tok; 00826 if (Tok.isOneOf(tok::r_brace, tok::r_square)) 00827 Left = Tok.MatchingParen; 00828 return !State.Stack.back().HasMultipleNestedBlocks && 00829 Left->isOneOf(tok::l_brace, tok::l_square) && 00830 (Left->BlockKind == BK_Block || 00831 Left->Type == TT_ArrayInitializerLSquare || 00832 Left->Type == TT_DictLiteral); 00833 } 00834 00835 void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) { 00836 // Don't remove FakeRParens attached to r_braces that surround nested blocks 00837 // as they will have been removed early (see above). 00838 if (fakeRParenSpecialCase(State)) 00839 return; 00840 00841 consumeRParens(State, *State.NextToken); 00842 } 00843 00844 void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, 00845 bool Newline) { 00846 const FormatToken &Current = *State.NextToken; 00847 if (!Current.opensScope()) 00848 return; 00849 00850 if (Current.MatchingParen && Current.BlockKind == BK_Block) { 00851 moveStateToNewBlock(State); 00852 return; 00853 } 00854 00855 unsigned NewIndent; 00856 unsigned NewIndentLevel = State.Stack.back().IndentLevel; 00857 bool AvoidBinPacking; 00858 bool BreakBeforeParameter = false; 00859 if (Current.is(tok::l_brace) || Current.Type == TT_ArrayInitializerLSquare) { 00860 if (fakeRParenSpecialCase(State)) 00861 consumeRParens(State, *Current.MatchingParen); 00862 00863 NewIndent = State.Stack.back().LastSpace; 00864 if (Current.opensBlockTypeList(Style)) { 00865 NewIndent += Style.IndentWidth; 00866 NewIndent = std::min(State.Column + 2, NewIndent); 00867 ++NewIndentLevel; 00868 } else { 00869 NewIndent += Style.ContinuationIndentWidth; 00870 NewIndent = std::min(State.Column + 1, NewIndent); 00871 } 00872 const FormatToken *NextNoComment = Current.getNextNonComment(); 00873 AvoidBinPacking = Current.Type == TT_ArrayInitializerLSquare || 00874 Current.Type == TT_DictLiteral || 00875 Style.Language == FormatStyle::LK_Proto || 00876 !Style.BinPackParameters || 00877 (NextNoComment && 00878 NextNoComment->Type == TT_DesignatedInitializerPeriod); 00879 } else { 00880 NewIndent = Style.ContinuationIndentWidth + 00881 std::max(State.Stack.back().LastSpace, 00882 State.Stack.back().StartOfFunctionCall); 00883 AvoidBinPacking = 00884 (State.Line->MustBeDeclaration && !Style.BinPackParameters) || 00885 (!State.Line->MustBeDeclaration && !Style.BinPackArguments) || 00886 (Style.ExperimentalAutoDetectBinPacking && 00887 (Current.PackingKind == PPK_OnePerLine || 00888 (!BinPackInconclusiveFunctions && 00889 Current.PackingKind == PPK_Inconclusive))); 00890 // If this '[' opens an ObjC call, determine whether all parameters fit 00891 // into one line and put one per line if they don't. 00892 if (Current.Type == TT_ObjCMethodExpr && Style.ColumnLimit != 0 && 00893 getLengthToMatchingParen(Current) + State.Column > 00894 getColumnLimit(State)) 00895 BreakBeforeParameter = true; 00896 } 00897 bool NoLineBreak = State.Stack.back().NoLineBreak || 00898 (Current.Type == TT_TemplateOpener && 00899 State.Stack.back().ContainsUnwrappedBuilder); 00900 State.Stack.push_back(ParenState(NewIndent, NewIndentLevel, 00901 State.Stack.back().LastSpace, 00902 AvoidBinPacking, NoLineBreak)); 00903 State.Stack.back().BreakBeforeParameter = BreakBeforeParameter; 00904 State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1; 00905 } 00906 00907 void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) { 00908 const FormatToken &Current = *State.NextToken; 00909 if (!Current.closesScope()) 00910 return; 00911 00912 // If we encounter a closing ), ], } or >, we can remove a level from our 00913 // stacks. 00914 if (State.Stack.size() > 1 && 00915 (Current.isOneOf(tok::r_paren, tok::r_square) || 00916 (Current.is(tok::r_brace) && State.NextToken != State.Line->First) || 00917 State.NextToken->Type == TT_TemplateCloser)) 00918 State.Stack.pop_back(); 00919 00920 if (Current.is(tok::r_square)) { 00921 // If this ends the array subscript expr, reset the corresponding value. 00922 const FormatToken *NextNonComment = Current.getNextNonComment(); 00923 if (NextNonComment && NextNonComment->isNot(tok::l_square)) 00924 State.Stack.back().StartOfArraySubscripts = 0; 00925 } 00926 } 00927 00928 void ContinuationIndenter::moveStateToNewBlock(LineState &State) { 00929 // If we have already found more than one lambda introducers on this level, we 00930 // opt out of this because similarity between the lambdas is more important. 00931 if (fakeRParenSpecialCase(State)) 00932 consumeRParens(State, *State.NextToken->MatchingParen); 00933 00934 // ObjC block sometimes follow special indentation rules. 00935 unsigned NewIndent = State.Stack.back().LastSpace + 00936 (State.NextToken->Type == TT_ObjCBlockLBrace 00937 ? Style.ObjCBlockIndentWidth 00938 : Style.IndentWidth); 00939 State.Stack.push_back(ParenState( 00940 NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1, 00941 State.Stack.back().LastSpace, /*AvoidBinPacking=*/true, 00942 State.Stack.back().NoLineBreak)); 00943 State.Stack.back().BreakBeforeParameter = true; 00944 } 00945 00946 unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current, 00947 LineState &State) { 00948 // Break before further function parameters on all levels. 00949 for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) 00950 State.Stack[i].BreakBeforeParameter = true; 00951 00952 unsigned ColumnsUsed = State.Column; 00953 // We can only affect layout of the first and the last line, so the penalty 00954 // for all other lines is constant, and we ignore it. 00955 State.Column = Current.LastLineColumnWidth; 00956 00957 if (ColumnsUsed > getColumnLimit(State)) 00958 return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit(State)); 00959 return 0; 00960 } 00961 00962 static bool getRawStringLiteralPrefixPostfix(StringRef Text, StringRef &Prefix, 00963 StringRef &Postfix) { 00964 if (Text.startswith(Prefix = "R\"") || Text.startswith(Prefix = "uR\"") || 00965 Text.startswith(Prefix = "UR\"") || Text.startswith(Prefix = "u8R\"") || 00966 Text.startswith(Prefix = "LR\"")) { 00967 size_t ParenPos = Text.find('('); 00968 if (ParenPos != StringRef::npos) { 00969 StringRef Delimiter = 00970 Text.substr(Prefix.size(), ParenPos - Prefix.size()); 00971 Prefix = Text.substr(0, ParenPos + 1); 00972 Postfix = Text.substr(Text.size() - 2 - Delimiter.size()); 00973 return Postfix.front() == ')' && Postfix.back() == '"' && 00974 Postfix.substr(1).startswith(Delimiter); 00975 } 00976 } 00977 return false; 00978 } 00979 00980 unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current, 00981 LineState &State, 00982 bool DryRun) { 00983 // Don't break multi-line tokens other than block comments. Instead, just 00984 // update the state. 00985 if (Current.Type != TT_BlockComment && Current.IsMultiline) 00986 return addMultilineToken(Current, State); 00987 00988 // Don't break implicit string literals. 00989 if (Current.Type == TT_ImplicitStringLiteral) 00990 return 0; 00991 00992 if (!Current.isStringLiteral() && !Current.is(tok::comment)) 00993 return 0; 00994 00995 std::unique_ptr<BreakableToken> Token; 00996 unsigned StartColumn = State.Column - Current.ColumnWidth; 00997 unsigned ColumnLimit = getColumnLimit(State); 00998 00999 if (Current.isStringLiteral()) { 01000 // Don't break string literals inside preprocessor directives (except for 01001 // #define directives, as their contents are stored in separate lines and 01002 // are not affected by this check). 01003 // This way we avoid breaking code with line directives and unknown 01004 // preprocessor directives that contain long string literals. 01005 if (State.Line->Type == LT_PreprocessorDirective) 01006 return 0; 01007 // Exempts unterminated string literals from line breaking. The user will 01008 // likely want to terminate the string before any line breaking is done. 01009 if (Current.IsUnterminatedLiteral) 01010 return 0; 01011 01012 StringRef Text = Current.TokenText; 01013 StringRef Prefix; 01014 StringRef Postfix; 01015 bool IsNSStringLiteral = false; 01016 // FIXME: Handle whitespace between '_T', '(', '"..."', and ')'. 01017 // FIXME: Store Prefix and Suffix (or PrefixLength and SuffixLength to 01018 // reduce the overhead) for each FormatToken, which is a string, so that we 01019 // don't run multiple checks here on the hot path. 01020 if (Text.startswith("\"") && Current.Previous && 01021 Current.Previous->is(tok::at)) { 01022 IsNSStringLiteral = true; 01023 Prefix = "@\""; 01024 } 01025 if ((Text.endswith(Postfix = "\"") && 01026 (IsNSStringLiteral || Text.startswith(Prefix = "\"") || 01027 Text.startswith(Prefix = "u\"") || Text.startswith(Prefix = "U\"") || 01028 Text.startswith(Prefix = "u8\"") || 01029 Text.startswith(Prefix = "L\""))) || 01030 (Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")")) || 01031 getRawStringLiteralPrefixPostfix(Text, Prefix, Postfix)) { 01032 Token.reset(new BreakableStringLiteral( 01033 Current, State.Line->Level, StartColumn, Prefix, Postfix, 01034 State.Line->InPPDirective, Encoding, Style)); 01035 } else { 01036 return 0; 01037 } 01038 } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) { 01039 if (CommentPragmasRegex.match(Current.TokenText.substr(2))) 01040 return 0; 01041 Token.reset(new BreakableBlockComment( 01042 Current, State.Line->Level, StartColumn, Current.OriginalColumn, 01043 !Current.Previous, State.Line->InPPDirective, Encoding, Style)); 01044 } else if (Current.Type == TT_LineComment && 01045 (Current.Previous == nullptr || 01046 Current.Previous->Type != TT_ImplicitStringLiteral)) { 01047 if (CommentPragmasRegex.match(Current.TokenText.substr(2))) 01048 return 0; 01049 Token.reset(new BreakableLineComment(Current, State.Line->Level, 01050 StartColumn, /*InPPDirective=*/false, 01051 Encoding, Style)); 01052 // We don't insert backslashes when breaking line comments. 01053 ColumnLimit = Style.ColumnLimit; 01054 } else { 01055 return 0; 01056 } 01057 if (Current.UnbreakableTailLength >= ColumnLimit) 01058 return 0; 01059 01060 unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength; 01061 bool BreakInserted = false; 01062 unsigned Penalty = 0; 01063 unsigned RemainingTokenColumns = 0; 01064 for (unsigned LineIndex = 0, EndIndex = Token->getLineCount(); 01065 LineIndex != EndIndex; ++LineIndex) { 01066 if (!DryRun) 01067 Token->replaceWhitespaceBefore(LineIndex, Whitespaces); 01068 unsigned TailOffset = 0; 01069 RemainingTokenColumns = 01070 Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos); 01071 while (RemainingTokenColumns > RemainingSpace) { 01072 BreakableToken::Split Split = 01073 Token->getSplit(LineIndex, TailOffset, ColumnLimit); 01074 if (Split.first == StringRef::npos) { 01075 // The last line's penalty is handled in addNextStateToQueue(). 01076 if (LineIndex < EndIndex - 1) 01077 Penalty += Style.PenaltyExcessCharacter * 01078 (RemainingTokenColumns - RemainingSpace); 01079 break; 01080 } 01081 assert(Split.first != 0); 01082 unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit( 01083 LineIndex, TailOffset + Split.first + Split.second, StringRef::npos); 01084 01085 // We can remove extra whitespace instead of breaking the line. 01086 if (RemainingTokenColumns + 1 - Split.second <= RemainingSpace) { 01087 RemainingTokenColumns = 0; 01088 if (!DryRun) 01089 Token->replaceWhitespace(LineIndex, TailOffset, Split, Whitespaces); 01090 break; 01091 } 01092 01093 // When breaking before a tab character, it may be moved by a few columns, 01094 // but will still be expanded to the next tab stop, so we don't save any 01095 // columns. 01096 if (NewRemainingTokenColumns == RemainingTokenColumns) 01097 break; 01098 01099 assert(NewRemainingTokenColumns < RemainingTokenColumns); 01100 if (!DryRun) 01101 Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces); 01102 Penalty += Current.SplitPenalty; 01103 unsigned ColumnsUsed = 01104 Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first); 01105 if (ColumnsUsed > ColumnLimit) { 01106 Penalty += Style.PenaltyExcessCharacter * (ColumnsUsed - ColumnLimit); 01107 } 01108 TailOffset += Split.first + Split.second; 01109 RemainingTokenColumns = NewRemainingTokenColumns; 01110 BreakInserted = true; 01111 } 01112 } 01113 01114 State.Column = RemainingTokenColumns; 01115 01116 if (BreakInserted) { 01117 // If we break the token inside a parameter list, we need to break before 01118 // the next parameter on all levels, so that the next parameter is clearly 01119 // visible. Line comments already introduce a break. 01120 if (Current.Type != TT_LineComment) { 01121 for (unsigned i = 0, e = State.Stack.size(); i != e; ++i) 01122 State.Stack[i].BreakBeforeParameter = true; 01123 } 01124 01125 Penalty += Current.isStringLiteral() ? Style.PenaltyBreakString 01126 : Style.PenaltyBreakComment; 01127 01128 State.Stack.back().LastSpace = StartColumn; 01129 } 01130 return Penalty; 01131 } 01132 01133 unsigned ContinuationIndenter::getColumnLimit(const LineState &State) const { 01134 // In preprocessor directives reserve two chars for trailing " \" 01135 return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0); 01136 } 01137 01138 bool ContinuationIndenter::nextIsMultilineString(const LineState &State) { 01139 const FormatToken &Current = *State.NextToken; 01140 if (!Current.isStringLiteral() || Current.Type == TT_ImplicitStringLiteral) 01141 return false; 01142 // We never consider raw string literals "multiline" for the purpose of 01143 // AlwaysBreakBeforeMultilineStrings implementation as they are special-cased 01144 // (see TokenAnnotator::mustBreakBefore(). 01145 if (Current.TokenText.startswith("R\"")) 01146 return false; 01147 if (Current.IsMultiline) 01148 return true; 01149 if (Current.getNextNonComment() && 01150 Current.getNextNonComment()->isStringLiteral()) 01151 return true; // Implicit concatenation. 01152 if (State.Column + Current.ColumnWidth + Current.UnbreakableTailLength > 01153 Style.ColumnLimit) 01154 return true; // String will be split. 01155 return false; 01156 } 01157 01158 } // namespace format 01159 } // namespace clang