1 //===--- Format.cpp - Format C++ code -------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief This file implements functions declared in Format.h. This will be 12 /// split into separate files as we go. 13 /// 14 /// This is EXPERIMENTAL code under heavy development. It is not in a state yet, 15 /// where it can be used to format real code. 16 /// 17 //===----------------------------------------------------------------------===// 18 19 #include "clang/Format/Format.h" 20 #include "UnwrappedLineParser.h" 21 #include "clang/Basic/OperatorPrecedence.h" 22 #include "clang/Basic/SourceManager.h" 23 #include "clang/Lex/Lexer.h" 24 #include <string> 25 26 namespace clang { 27 namespace format { 28 29 enum TokenType { 30 TT_Unknown, 31 TT_TemplateOpener, 32 TT_TemplateCloser, 33 TT_BinaryOperator, 34 TT_UnaryOperator, 35 TT_TrailingUnaryOperator, 36 TT_OverloadedOperator, 37 TT_PointerOrReference, 38 TT_ConditionalExpr, 39 TT_CtorInitializerColon, 40 TT_LineComment, 41 TT_BlockComment, 42 TT_DirectorySeparator, 43 TT_PureVirtualSpecifier, 44 TT_ObjCMethodSpecifier 45 }; 46 47 enum LineType { 48 LT_Invalid, 49 LT_Other, 50 LT_PreprocessorDirective, 51 LT_VirtualFunctionDecl, 52 LT_ObjCMethodDecl 53 }; 54 55 // FIXME: Move somewhere sane. 56 struct TokenAnnotation { 57 TokenType Type; 58 59 bool SpaceRequiredBefore; 60 bool CanBreakBefore; 61 bool MustBreakBefore; 62 63 bool ClosesTemplateDeclaration; 64 }; 65 66 static prec::Level getPrecedence(const FormatToken &Tok) { 67 return getBinOpPrecedence(Tok.Tok.getKind(), true, true); 68 } 69 70 using llvm::MutableArrayRef; 71 72 FormatStyle getLLVMStyle() { 73 FormatStyle LLVMStyle; 74 LLVMStyle.ColumnLimit = 80; 75 LLVMStyle.MaxEmptyLinesToKeep = 1; 76 LLVMStyle.PointerAndReferenceBindToType = false; 77 LLVMStyle.AccessModifierOffset = -2; 78 LLVMStyle.SplitTemplateClosingGreater = true; 79 LLVMStyle.IndentCaseLabels = false; 80 LLVMStyle.SpacesBeforeTrailingComments = 1; 81 return LLVMStyle; 82 } 83 84 FormatStyle getGoogleStyle() { 85 FormatStyle GoogleStyle; 86 GoogleStyle.ColumnLimit = 80; 87 GoogleStyle.MaxEmptyLinesToKeep = 1; 88 GoogleStyle.PointerAndReferenceBindToType = true; 89 GoogleStyle.AccessModifierOffset = -1; 90 GoogleStyle.SplitTemplateClosingGreater = false; 91 GoogleStyle.IndentCaseLabels = true; 92 GoogleStyle.SpacesBeforeTrailingComments = 2; 93 return GoogleStyle; 94 } 95 96 struct OptimizationParameters { 97 unsigned PenaltyIndentLevel; 98 unsigned PenaltyLevelDecrease; 99 }; 100 101 class UnwrappedLineFormatter { 102 public: 103 UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr, 104 const UnwrappedLine &Line, 105 unsigned PreviousEndOfLineColumn, 106 LineType CurrentLineType, 107 const std::vector<TokenAnnotation> &Annotations, 108 tooling::Replacements &Replaces, bool StructuralError) 109 : Style(Style), SourceMgr(SourceMgr), Line(Line), 110 PreviousEndOfLineColumn(PreviousEndOfLineColumn), 111 CurrentLineType(CurrentLineType), Annotations(Annotations), 112 Replaces(Replaces), StructuralError(StructuralError) { 113 Parameters.PenaltyIndentLevel = 15; 114 Parameters.PenaltyLevelDecrease = 30; 115 } 116 117 /// \brief Formats an \c UnwrappedLine. 118 /// 119 /// \returns The column after the last token in the last line of the 120 /// \c UnwrappedLine. 121 unsigned format() { 122 // Format first token and initialize indent. 123 unsigned Indent = formatFirstToken(); 124 125 // Initialize state dependent on indent. 126 IndentState State; 127 State.Column = Indent; 128 State.ConsumedTokens = 0; 129 State.Indent.push_back(Indent + 4); 130 State.LastSpace.push_back(Indent); 131 State.FirstLessLess.push_back(0); 132 State.ForLoopVariablePos = 0; 133 State.LineContainsContinuedForLoopSection = false; 134 State.StartOfLineLevel = 1; 135 136 // The first token has already been indented and thus consumed. 137 moveStateToNextToken(State); 138 139 // Check whether the UnwrappedLine can be put onto a single line. If so, 140 // this is bound to be the optimal solution (by definition) and we don't 141 // need to analyze the entire solution space. 142 unsigned Columns = State.Column; 143 bool FitsOnALine = true; 144 for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) { 145 Columns += (Annotations[i].SpaceRequiredBefore ? 1 : 0) + 146 Line.Tokens[i].TokenLength; 147 // A special case for the colon of a constructor initializer as this only 148 // needs to be put on a new line if the line needs to be split. 149 if (Columns > Style.ColumnLimit - (Line.InPPDirective ? 1 : 0) || 150 (Annotations[i].MustBreakBefore && 151 Annotations[i].Type != TT_CtorInitializerColon)) { 152 FitsOnALine = false; 153 break; 154 } 155 } 156 157 // Start iterating at 1 as we have correctly formatted of Token #0 above. 158 for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) { 159 if (FitsOnALine) { 160 addTokenToState(false, false, State); 161 } else { 162 unsigned NoBreak = calcPenalty(State, false, UINT_MAX); 163 unsigned Break = calcPenalty(State, true, NoBreak); 164 addTokenToState(Break < NoBreak, false, State); 165 } 166 } 167 return State.Column; 168 } 169 170 private: 171 /// \brief The current state when indenting a unwrapped line. 172 /// 173 /// As the indenting tries different combinations this is copied by value. 174 struct IndentState { 175 /// \brief The number of used columns in the current line. 176 unsigned Column; 177 178 /// \brief The number of tokens already consumed. 179 unsigned ConsumedTokens; 180 181 /// \brief The parenthesis level of the first token on the current line. 182 unsigned StartOfLineLevel; 183 184 /// \brief The position to which a specific parenthesis level needs to be 185 /// indented. 186 std::vector<unsigned> Indent; 187 188 /// \brief The position of the last space on each level. 189 /// 190 /// Used e.g. to break like: 191 /// functionCall(Parameter, otherCall( 192 /// OtherParameter)); 193 std::vector<unsigned> LastSpace; 194 195 /// \brief The position the first "<<" operator encountered on each level. 196 /// 197 /// Used to align "<<" operators. 0 if no such operator has been encountered 198 /// on a level. 199 std::vector<unsigned> FirstLessLess; 200 201 /// \brief The column of the first variable in a for-loop declaration. 202 /// 203 /// Used to align the second variable if necessary. 204 unsigned ForLoopVariablePos; 205 206 /// \brief \c true if this line contains a continued for-loop section. 207 bool LineContainsContinuedForLoopSection; 208 209 /// \brief Comparison operator to be able to used \c IndentState in \c map. 210 bool operator<(const IndentState &Other) const { 211 if (Other.ConsumedTokens != ConsumedTokens) 212 return Other.ConsumedTokens > ConsumedTokens; 213 if (Other.Column != Column) 214 return Other.Column > Column; 215 if (Other.StartOfLineLevel != StartOfLineLevel) 216 return Other.StartOfLineLevel > StartOfLineLevel; 217 if (Other.Indent.size() != Indent.size()) 218 return Other.Indent.size() > Indent.size(); 219 for (int i = 0, e = Indent.size(); i != e; ++i) { 220 if (Other.Indent[i] != Indent[i]) 221 return Other.Indent[i] > Indent[i]; 222 } 223 if (Other.LastSpace.size() != LastSpace.size()) 224 return Other.LastSpace.size() > LastSpace.size(); 225 for (int i = 0, e = LastSpace.size(); i != e; ++i) { 226 if (Other.LastSpace[i] != LastSpace[i]) 227 return Other.LastSpace[i] > LastSpace[i]; 228 } 229 if (Other.FirstLessLess.size() != FirstLessLess.size()) 230 return Other.FirstLessLess.size() > FirstLessLess.size(); 231 for (int i = 0, e = FirstLessLess.size(); i != e; ++i) { 232 if (Other.FirstLessLess[i] != FirstLessLess[i]) 233 return Other.FirstLessLess[i] > FirstLessLess[i]; 234 } 235 if (Other.ForLoopVariablePos != ForLoopVariablePos) 236 return Other.ForLoopVariablePos < ForLoopVariablePos; 237 if (Other.LineContainsContinuedForLoopSection != 238 LineContainsContinuedForLoopSection) 239 return LineContainsContinuedForLoopSection; 240 return false; 241 } 242 }; 243 244 /// \brief Appends the next token to \p State and updates information 245 /// necessary for indentation. 246 /// 247 /// Puts the token on the current line if \p Newline is \c true and adds a 248 /// line break and necessary indentation otherwise. 249 /// 250 /// If \p DryRun is \c false, also creates and stores the required 251 /// \c Replacement. 252 void addTokenToState(bool Newline, bool DryRun, IndentState &State) { 253 unsigned Index = State.ConsumedTokens; 254 const FormatToken &Current = Line.Tokens[Index]; 255 const FormatToken &Previous = Line.Tokens[Index - 1]; 256 unsigned ParenLevel = State.Indent.size() - 1; 257 258 if (Newline) { 259 unsigned WhitespaceStartColumn = State.Column; 260 if (Previous.Tok.is(tok::l_brace)) { 261 // FIXME: This does not work with nested static initializers. 262 // Implement a better handling for static initializers and similar 263 // constructs. 264 State.Column = Line.Level * 2 + 2; 265 } else if (Current.Tok.is(tok::string_literal) && 266 Previous.Tok.is(tok::string_literal)) { 267 State.Column = State.Column - Previous.TokenLength; 268 } else if (Current.Tok.is(tok::lessless) && 269 State.FirstLessLess[ParenLevel] != 0) { 270 State.Column = State.FirstLessLess[ParenLevel]; 271 } else if (ParenLevel != 0 && 272 (Previous.Tok.is(tok::equal) || Current.Tok.is(tok::arrow) || 273 Current.Tok.is(tok::period))) { 274 // Indent and extra 4 spaces after '=' as it continues an expression. 275 // Don't do that on the top level, as we already indent 4 there. 276 State.Column = State.Indent[ParenLevel] + 4; 277 } else if (Line.Tokens[0].Tok.is(tok::kw_for) && 278 Previous.Tok.is(tok::comma)) { 279 State.Column = State.ForLoopVariablePos; 280 } else if (Annotations[Index - 1].ClosesTemplateDeclaration) { 281 State.Column = State.Indent[ParenLevel] - 4; 282 } else { 283 State.Column = State.Indent[ParenLevel]; 284 } 285 286 State.StartOfLineLevel = ParenLevel + 1; 287 288 if (Line.Tokens[0].Tok.is(tok::kw_for)) 289 State.LineContainsContinuedForLoopSection = 290 Previous.Tok.isNot(tok::semi); 291 292 if (!DryRun) { 293 if (!Line.InPPDirective) 294 replaceWhitespace(Current, 1, State.Column); 295 else 296 replacePPWhitespace(Current, 1, State.Column, WhitespaceStartColumn); 297 } 298 299 State.LastSpace[ParenLevel] = State.Indent[ParenLevel]; 300 if (Current.Tok.is(tok::colon) && CurrentLineType != LT_ObjCMethodDecl && 301 Annotations[Index].Type != TT_ConditionalExpr) 302 State.Indent[ParenLevel] += 2; 303 } else { 304 if (Current.Tok.is(tok::equal) && Line.Tokens[0].Tok.is(tok::kw_for)) 305 State.ForLoopVariablePos = State.Column - Previous.TokenLength; 306 307 unsigned Spaces = Annotations[Index].SpaceRequiredBefore ? 1 : 0; 308 if (Annotations[Index].Type == TT_LineComment) 309 Spaces = Style.SpacesBeforeTrailingComments; 310 311 if (!DryRun) 312 replaceWhitespace(Current, 0, Spaces); 313 314 if (Line.Tokens[0].Tok.isNot(tok::kw_for) && 315 (getPrecedence(Previous) == prec::Assignment || 316 Previous.Tok.is(tok::kw_return))) 317 State.Indent[ParenLevel] = State.Column + Spaces; 318 if (Previous.Tok.is(tok::l_paren) || 319 Annotations[Index - 1].Type == TT_TemplateOpener) 320 State.Indent[ParenLevel] = State.Column; 321 322 // Top-level spaces that are not part of assignments are exempt as that 323 // mostly leads to better results. 324 State.Column += Spaces; 325 if (Spaces > 0 && 326 (ParenLevel != 0 || getPrecedence(Previous) == prec::Assignment)) 327 State.LastSpace[ParenLevel] = State.Column; 328 } 329 moveStateToNextToken(State); 330 } 331 332 /// \brief Mark the next token as consumed in \p State and modify its stacks 333 /// accordingly. 334 void moveStateToNextToken(IndentState &State) { 335 unsigned Index = State.ConsumedTokens; 336 const FormatToken &Current = Line.Tokens[Index]; 337 unsigned ParenLevel = State.Indent.size() - 1; 338 339 if (Current.Tok.is(tok::lessless) && State.FirstLessLess[ParenLevel] == 0) 340 State.FirstLessLess[ParenLevel] = State.Column; 341 342 State.Column += Current.TokenLength; 343 344 // If we encounter an opening (, [, { or <, we add a level to our stacks to 345 // prepare for the following tokens. 346 if (Current.Tok.is(tok::l_paren) || Current.Tok.is(tok::l_square) || 347 Current.Tok.is(tok::l_brace) || 348 Annotations[Index].Type == TT_TemplateOpener) { 349 State.Indent.push_back(4 + State.LastSpace.back()); 350 State.LastSpace.push_back(State.LastSpace.back()); 351 State.FirstLessLess.push_back(0); 352 } 353 354 // If we encounter a closing ), ], } or >, we can remove a level from our 355 // stacks. 356 if (Current.Tok.is(tok::r_paren) || Current.Tok.is(tok::r_square) || 357 (Current.Tok.is(tok::r_brace) && State.ConsumedTokens > 0) || 358 Annotations[Index].Type == TT_TemplateCloser) { 359 State.Indent.pop_back(); 360 State.LastSpace.pop_back(); 361 State.FirstLessLess.pop_back(); 362 } 363 364 ++State.ConsumedTokens; 365 } 366 367 /// \brief Calculate the penalty for splitting after the token at \p Index. 368 unsigned splitPenalty(unsigned Index) { 369 assert(Index < Line.Tokens.size() && 370 "Tried to calculate penalty for splitting after the last token"); 371 const FormatToken &Left = Line.Tokens[Index]; 372 const FormatToken &Right = Line.Tokens[Index + 1]; 373 374 // In for-loops, prefer breaking at ',' and ';'. 375 if (Line.Tokens[0].Tok.is(tok::kw_for) && 376 (Left.Tok.isNot(tok::comma) && Left.Tok.isNot(tok::semi))) 377 return 20; 378 379 if (Left.Tok.is(tok::semi) || Left.Tok.is(tok::comma) || 380 Annotations[Index].ClosesTemplateDeclaration) 381 return 0; 382 if (Left.Tok.is(tok::l_paren)) 383 return 20; 384 385 prec::Level Level = getPrecedence(Left); 386 387 // Breaking after an assignment leads to a bad result as the two sides of 388 // the assignment are visually very close together. 389 if (Level == prec::Assignment) 390 return 50; 391 392 if (Level != prec::Unknown) 393 return Level; 394 395 if (Right.Tok.is(tok::arrow) || Right.Tok.is(tok::period)) 396 return 150; 397 398 return 3; 399 } 400 401 /// \brief Calculate the number of lines needed to format the remaining part 402 /// of the unwrapped line. 403 /// 404 /// Assumes the formatting so far has led to 405 /// the \c IndentState \p State. If \p NewLine is set, a new line will be 406 /// added after the previous token. 407 /// 408 /// \param StopAt is used for optimization. If we can determine that we'll 409 /// definitely need at least \p StopAt additional lines, we already know of a 410 /// better solution. 411 unsigned calcPenalty(IndentState State, bool NewLine, unsigned StopAt) { 412 // We are at the end of the unwrapped line, so we don't need any more lines. 413 if (State.ConsumedTokens >= Line.Tokens.size()) 414 return 0; 415 416 if (!NewLine && Annotations[State.ConsumedTokens].MustBreakBefore) 417 return UINT_MAX; 418 if (NewLine && !Annotations[State.ConsumedTokens].CanBreakBefore) 419 return UINT_MAX; 420 if (!NewLine && Line.Tokens[State.ConsumedTokens - 1].Tok.is(tok::semi) && 421 State.LineContainsContinuedForLoopSection) 422 return UINT_MAX; 423 424 unsigned CurrentPenalty = 0; 425 if (NewLine) { 426 CurrentPenalty += Parameters.PenaltyIndentLevel * State.Indent.size() + 427 splitPenalty(State.ConsumedTokens - 1); 428 } else { 429 if (State.Indent.size() < State.StartOfLineLevel) 430 CurrentPenalty += Parameters.PenaltyLevelDecrease * 431 (State.StartOfLineLevel - State.Indent.size()); 432 } 433 434 addTokenToState(NewLine, true, State); 435 436 // Exceeding column limit is bad. 437 if (State.Column > Style.ColumnLimit - (Line.InPPDirective ? 1 : 0)) 438 return UINT_MAX; 439 440 if (StopAt <= CurrentPenalty) 441 return UINT_MAX; 442 StopAt -= CurrentPenalty; 443 444 StateMap::iterator I = Memory.find(State); 445 if (I != Memory.end()) { 446 // If this state has already been examined, we can safely return the 447 // previous result if we 448 // - have not hit the optimatization (and thus returned UINT_MAX) OR 449 // - are now computing for a smaller or equal StopAt. 450 unsigned SavedResult = I->second.first; 451 unsigned SavedStopAt = I->second.second; 452 if (SavedResult != UINT_MAX) 453 return SavedResult + CurrentPenalty; 454 else if (StopAt <= SavedStopAt) 455 return UINT_MAX; 456 } 457 458 unsigned NoBreak = calcPenalty(State, false, StopAt); 459 unsigned WithBreak = calcPenalty(State, true, std::min(StopAt, NoBreak)); 460 unsigned Result = std::min(NoBreak, WithBreak); 461 462 // We have to store 'Result' without adding 'CurrentPenalty' as the latter 463 // can depend on 'NewLine'. 464 Memory[State] = std::pair<unsigned, unsigned>(Result, StopAt); 465 466 return Result == UINT_MAX ? UINT_MAX : Result + CurrentPenalty; 467 } 468 469 /// \brief Replaces the whitespace in front of \p Tok. Only call once for 470 /// each \c FormatToken. 471 void replaceWhitespace(const FormatToken &Tok, unsigned NewLines, 472 unsigned Spaces) { 473 Replaces.insert(tooling::Replacement( 474 SourceMgr, Tok.WhiteSpaceStart, Tok.WhiteSpaceLength, 475 std::string(NewLines, '\n') + std::string(Spaces, ' '))); 476 } 477 478 /// \brief Like \c replaceWhitespace, but additionally adds right-aligned 479 /// backslashes to escape newlines inside a preprocessor directive. 480 /// 481 /// This function and \c replaceWhitespace have the same behavior if 482 /// \c Newlines == 0. 483 void replacePPWhitespace(const FormatToken &Tok, unsigned NewLines, 484 unsigned Spaces, unsigned WhitespaceStartColumn) { 485 std::string NewLineText; 486 if (NewLines > 0) { 487 unsigned Offset = std::min<int>(Style.ColumnLimit - 1, 488 WhitespaceStartColumn); 489 for (unsigned i = 0; i < NewLines; ++i) { 490 NewLineText += std::string(Style.ColumnLimit - Offset - 1, ' '); 491 NewLineText += "\\\n"; 492 Offset = 0; 493 } 494 } 495 Replaces.insert(tooling::Replacement(SourceMgr, Tok.WhiteSpaceStart, 496 Tok.WhiteSpaceLength, NewLineText + 497 std::string(Spaces, ' '))); 498 } 499 500 /// \brief Add a new line and the required indent before the first Token 501 /// of the \c UnwrappedLine if there was no structural parsing error. 502 /// Returns the indent level of the \c UnwrappedLine. 503 unsigned formatFirstToken() { 504 const FormatToken &Token = Line.Tokens[0]; 505 if (!Token.WhiteSpaceStart.isValid() || StructuralError) 506 return SourceMgr.getSpellingColumnNumber(Token.Tok.getLocation()) - 1; 507 508 unsigned Newlines = std::min(Token.NewlinesBefore, 509 Style.MaxEmptyLinesToKeep + 1); 510 if (Newlines == 0 && !Token.IsFirst) 511 Newlines = 1; 512 unsigned Indent = Line.Level * 2; 513 if ((Token.Tok.is(tok::kw_public) || Token.Tok.is(tok::kw_protected) || 514 Token.Tok.is(tok::kw_private)) && 515 static_cast<int>(Indent) + Style.AccessModifierOffset >= 0) 516 Indent += Style.AccessModifierOffset; 517 if (!Line.InPPDirective || Token.HasUnescapedNewline) 518 replaceWhitespace(Token, Newlines, Indent); 519 else 520 replacePPWhitespace(Token, Newlines, Indent, PreviousEndOfLineColumn); 521 return Indent; 522 } 523 524 FormatStyle Style; 525 SourceManager &SourceMgr; 526 const UnwrappedLine &Line; 527 const unsigned PreviousEndOfLineColumn; 528 const LineType CurrentLineType; 529 const std::vector<TokenAnnotation> &Annotations; 530 tooling::Replacements &Replaces; 531 bool StructuralError; 532 533 // A map from an indent state to a pair (Result, Used-StopAt). 534 typedef std::map<IndentState, std::pair<unsigned, unsigned> > StateMap; 535 StateMap Memory; 536 537 OptimizationParameters Parameters; 538 }; 539 540 /// \brief Determines extra information about the tokens comprising an 541 /// \c UnwrappedLine. 542 class TokenAnnotator { 543 public: 544 TokenAnnotator(const UnwrappedLine &Line, const FormatStyle &Style, 545 SourceManager &SourceMgr, Lexer &Lex) 546 : Line(Line), Style(Style), SourceMgr(SourceMgr), Lex(Lex) { 547 } 548 549 /// \brief A parser that gathers additional information about tokens. 550 /// 551 /// The \c TokenAnnotator tries to matches parenthesis and square brakets and 552 /// store a parenthesis levels. It also tries to resolve matching "<" and ">" 553 /// into template parameter lists. 554 class AnnotatingParser { 555 public: 556 AnnotatingParser(const SmallVector<FormatToken, 16> &Tokens, 557 std::vector<TokenAnnotation> &Annotations) 558 : Tokens(Tokens), Annotations(Annotations), Index(0), 559 KeywordVirtualFound(false) { 560 } 561 562 bool parseAngle() { 563 while (Index < Tokens.size()) { 564 if (Tokens[Index].Tok.is(tok::greater)) { 565 Annotations[Index].Type = TT_TemplateCloser; 566 next(); 567 return true; 568 } 569 if (Tokens[Index].Tok.is(tok::r_paren) || 570 Tokens[Index].Tok.is(tok::r_square) || 571 Tokens[Index].Tok.is(tok::r_brace)) 572 return false; 573 if (Tokens[Index].Tok.is(tok::pipepipe) || 574 Tokens[Index].Tok.is(tok::ampamp) || 575 Tokens[Index].Tok.is(tok::question) || 576 Tokens[Index].Tok.is(tok::colon)) 577 return false; 578 if (!consumeToken()) 579 return false; 580 } 581 return false; 582 } 583 584 bool parseParens() { 585 while (Index < Tokens.size()) { 586 if (Tokens[Index].Tok.is(tok::r_paren)) { 587 next(); 588 return true; 589 } 590 if (Tokens[Index].Tok.is(tok::r_square) || 591 Tokens[Index].Tok.is(tok::r_brace)) 592 return false; 593 if (!consumeToken()) 594 return false; 595 } 596 return false; 597 } 598 599 bool parseSquare() { 600 while (Index < Tokens.size()) { 601 if (Tokens[Index].Tok.is(tok::r_square)) { 602 next(); 603 return true; 604 } 605 if (Tokens[Index].Tok.is(tok::r_paren) || 606 Tokens[Index].Tok.is(tok::r_brace)) 607 return false; 608 if (!consumeToken()) 609 return false; 610 } 611 return false; 612 } 613 614 bool parseConditional() { 615 while (Index < Tokens.size()) { 616 if (Tokens[Index].Tok.is(tok::colon)) { 617 Annotations[Index].Type = TT_ConditionalExpr; 618 next(); 619 return true; 620 } 621 if (!consumeToken()) 622 return false; 623 } 624 return false; 625 } 626 627 bool parseTemplateDeclaration() { 628 if (Index < Tokens.size() && Tokens[Index].Tok.is(tok::less)) { 629 Annotations[Index].Type = TT_TemplateOpener; 630 next(); 631 if (!parseAngle()) 632 return false; 633 Annotations[Index - 1].ClosesTemplateDeclaration = true; 634 parseLine(); 635 return true; 636 } 637 return false; 638 } 639 640 bool consumeToken() { 641 unsigned CurrentIndex = Index; 642 next(); 643 switch (Tokens[CurrentIndex].Tok.getKind()) { 644 case tok::l_paren: 645 if (!parseParens()) 646 return false; 647 if (Index < Tokens.size() && Tokens[Index].Tok.is(tok::colon)) { 648 Annotations[Index].Type = TT_CtorInitializerColon; 649 next(); 650 } 651 break; 652 case tok::l_square: 653 if (!parseSquare()) 654 return false; 655 break; 656 case tok::less: 657 if (parseAngle()) 658 Annotations[CurrentIndex].Type = TT_TemplateOpener; 659 else { 660 Annotations[CurrentIndex].Type = TT_BinaryOperator; 661 Index = CurrentIndex + 1; 662 } 663 break; 664 case tok::r_paren: 665 case tok::r_square: 666 return false; 667 case tok::greater: 668 Annotations[CurrentIndex].Type = TT_BinaryOperator; 669 break; 670 case tok::kw_operator: 671 if (Tokens[Index].Tok.is(tok::l_paren)) { 672 Annotations[Index].Type = TT_OverloadedOperator; 673 next(); 674 if (Index < Tokens.size() && Tokens[Index].Tok.is(tok::r_paren)) { 675 Annotations[Index].Type = TT_OverloadedOperator; 676 next(); 677 } 678 } else { 679 while (Index < Tokens.size() && !Tokens[Index].Tok.is(tok::l_paren)) { 680 Annotations[Index].Type = TT_OverloadedOperator; 681 next(); 682 } 683 } 684 break; 685 case tok::question: 686 parseConditional(); 687 break; 688 case tok::kw_template: 689 parseTemplateDeclaration(); 690 break; 691 default: 692 break; 693 } 694 return true; 695 } 696 697 void parseIncludeDirective() { 698 while (Index < Tokens.size()) { 699 if (Tokens[Index].Tok.is(tok::slash)) 700 Annotations[Index].Type = TT_DirectorySeparator; 701 else if (Tokens[Index].Tok.is(tok::less)) 702 Annotations[Index].Type = TT_TemplateOpener; 703 else if (Tokens[Index].Tok.is(tok::greater)) 704 Annotations[Index].Type = TT_TemplateCloser; 705 next(); 706 } 707 } 708 709 void parsePreprocessorDirective() { 710 next(); 711 if (Index >= Tokens.size()) 712 return; 713 // Hashes in the middle of a line can lead to any strange token 714 // sequence. 715 if (Tokens[Index].Tok.getIdentifierInfo() == NULL) 716 return; 717 switch (Tokens[Index].Tok.getIdentifierInfo()->getPPKeywordID()) { 718 case tok::pp_include: 719 case tok::pp_import: 720 parseIncludeDirective(); 721 break; 722 default: 723 break; 724 } 725 } 726 727 LineType parseLine() { 728 if (Tokens[Index].Tok.is(tok::hash)) { 729 parsePreprocessorDirective(); 730 return LT_PreprocessorDirective; 731 } 732 while (Index < Tokens.size()) { 733 if (Tokens[Index].Tok.is(tok::kw_virtual)) 734 KeywordVirtualFound = true; 735 if (!consumeToken()) 736 return LT_Invalid; 737 } 738 if (KeywordVirtualFound) 739 return LT_VirtualFunctionDecl; 740 return LT_Other; 741 } 742 743 void next() { 744 ++Index; 745 } 746 747 private: 748 const SmallVector<FormatToken, 16> &Tokens; 749 std::vector<TokenAnnotation> &Annotations; 750 unsigned Index; 751 bool KeywordVirtualFound; 752 }; 753 754 bool annotate() { 755 if (Line.Tokens.size() == 0) 756 return true; 757 758 Annotations.clear(); 759 for (int i = 0, e = Line.Tokens.size(); i != e; ++i) { 760 Annotations.push_back(TokenAnnotation()); 761 } 762 763 AnnotatingParser Parser(Line.Tokens, Annotations); 764 CurrentLineType = Parser.parseLine(); 765 if (CurrentLineType == LT_Invalid) 766 return false; 767 768 determineTokenTypes(); 769 770 if (Annotations[0].Type == TT_ObjCMethodSpecifier) 771 CurrentLineType = LT_ObjCMethodDecl; 772 773 for (int i = 1, e = Line.Tokens.size(); i != e; ++i) { 774 TokenAnnotation &Annotation = Annotations[i]; 775 776 Annotation.SpaceRequiredBefore = spaceRequiredBefore(i); 777 778 if (Annotation.Type == TT_CtorInitializerColon || 779 Annotations[i - 1].Type == TT_LineComment || 780 (Line.Tokens[i].Tok.is(tok::string_literal) && 781 Line.Tokens[i - 1].Tok.is(tok::string_literal))) { 782 Annotation.MustBreakBefore = true; 783 } else if (Line.Tokens[i].Tok.is(tok::at) && 784 Line.Tokens[i - 2].Tok.is(tok::at)) { 785 // Don't put two objc's '@' on the same line. This could happen, 786 // as in, @optional @property ... 787 Annotation.MustBreakBefore = true; 788 } 789 790 Annotation.CanBreakBefore = Annotation.MustBreakBefore || 791 canBreakBefore(i); 792 } 793 return true; 794 } 795 796 LineType getLineType() { 797 return CurrentLineType; 798 } 799 800 const std::vector<TokenAnnotation> &getAnnotations() { 801 return Annotations; 802 } 803 804 private: 805 void determineTokenTypes() { 806 bool IsRHS = false; 807 for (int i = 0, e = Line.Tokens.size(); i != e; ++i) { 808 TokenAnnotation &Annotation = Annotations[i]; 809 const FormatToken &Tok = Line.Tokens[i]; 810 811 if (getPrecedence(Tok) == prec::Assignment || 812 Tok.Tok.is(tok::kw_return) || Tok.Tok.is(tok::kw_throw)) 813 IsRHS = true; 814 815 if (Annotation.Type != TT_Unknown) 816 continue; 817 818 if (Tok.Tok.is(tok::star) || Tok.Tok.is(tok::amp)) { 819 Annotation.Type = determineStarAmpUsage(i, IsRHS); 820 } else if (Tok.Tok.is(tok::minus) || Tok.Tok.is(tok::plus)) { 821 Annotation.Type = determinePlusMinusUsage(i); 822 } else if (Tok.Tok.is(tok::minusminus) || Tok.Tok.is(tok::plusplus)) { 823 Annotation.Type = determineIncrementUsage(i); 824 } else if (Tok.Tok.is(tok::exclaim)) { 825 Annotation.Type = TT_UnaryOperator; 826 } else if (isBinaryOperator(Line.Tokens[i])) { 827 Annotation.Type = TT_BinaryOperator; 828 } else if (Tok.Tok.is(tok::comment)) { 829 std::string Data( 830 Lexer::getSpelling(Tok.Tok, SourceMgr, Lex.getLangOpts())); 831 if (StringRef(Data).startswith("//")) 832 Annotation.Type = TT_LineComment; 833 else 834 Annotation.Type = TT_BlockComment; 835 } 836 } 837 } 838 839 bool isBinaryOperator(const FormatToken &Tok) { 840 // Comma is a binary operator, but does not behave as such wrt. formatting. 841 return getPrecedence(Tok) > prec::Comma; 842 } 843 844 TokenType determineStarAmpUsage(unsigned Index, bool IsRHS) { 845 if (Index == 0) 846 return TT_UnaryOperator; 847 if (Index == Annotations.size()) 848 return TT_Unknown; 849 const FormatToken &PrevToken = Line.Tokens[Index - 1]; 850 const FormatToken &NextToken = Line.Tokens[Index + 1]; 851 852 if (PrevToken.Tok.is(tok::l_paren) || PrevToken.Tok.is(tok::l_square) || 853 PrevToken.Tok.is(tok::comma) || PrevToken.Tok.is(tok::kw_return) || 854 PrevToken.Tok.is(tok::colon) || 855 Annotations[Index - 1].Type == TT_BinaryOperator) 856 return TT_UnaryOperator; 857 858 if (PrevToken.Tok.isLiteral() || NextToken.Tok.isLiteral() || 859 NextToken.Tok.is(tok::plus) || NextToken.Tok.is(tok::minus) || 860 NextToken.Tok.is(tok::plusplus) || NextToken.Tok.is(tok::minusminus) || 861 NextToken.Tok.is(tok::tilde) || NextToken.Tok.is(tok::exclaim) || 862 NextToken.Tok.is(tok::kw_alignof) || NextToken.Tok.is(tok::kw_sizeof)) 863 return TT_BinaryOperator; 864 865 if (NextToken.Tok.is(tok::comma) || NextToken.Tok.is(tok::r_paren) || 866 NextToken.Tok.is(tok::greater)) 867 return TT_PointerOrReference; 868 869 // It is very unlikely that we are going to find a pointer or reference type 870 // definition on the RHS of an assignment. 871 if (IsRHS) 872 return TT_BinaryOperator; 873 874 return TT_PointerOrReference; 875 } 876 877 TokenType determinePlusMinusUsage(unsigned Index) { 878 // At the start of the line, +/- specific ObjectiveC method declarations. 879 if (Index == 0) 880 return TT_ObjCMethodSpecifier; 881 882 // Use heuristics to recognize unary operators. 883 const Token &PreviousTok = Line.Tokens[Index - 1].Tok; 884 if (PreviousTok.is(tok::equal) || PreviousTok.is(tok::l_paren) || 885 PreviousTok.is(tok::comma) || PreviousTok.is(tok::l_square) || 886 PreviousTok.is(tok::question) || PreviousTok.is(tok::colon) || 887 PreviousTok.is(tok::kw_return) || PreviousTok.is(tok::kw_case)) 888 return TT_UnaryOperator; 889 890 // There can't be to consecutive binary operators. 891 if (Annotations[Index - 1].Type == TT_BinaryOperator) 892 return TT_UnaryOperator; 893 894 // Fall back to marking the token as binary operator. 895 return TT_BinaryOperator; 896 } 897 898 /// \brief Determine whether ++/-- are pre- or post-increments/-decrements. 899 TokenType determineIncrementUsage(unsigned Index) { 900 if (Index != 0 && Line.Tokens[Index - 1].Tok.is(tok::identifier)) 901 return TT_TrailingUnaryOperator; 902 903 return TT_UnaryOperator; 904 } 905 906 bool spaceRequiredBetween(Token Left, Token Right) { 907 if (Right.is(tok::r_paren) || Right.is(tok::semi) || Right.is(tok::comma)) 908 return false; 909 if (Left.is(tok::kw_template) && Right.is(tok::less)) 910 return true; 911 if (Left.is(tok::arrow) || Right.is(tok::arrow)) 912 return false; 913 if (Left.is(tok::exclaim) || Left.is(tok::tilde)) 914 return false; 915 if (Left.is(tok::at) && Right.is(tok::identifier)) 916 return false; 917 if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less)) 918 return false; 919 if (Right.is(tok::amp) || Right.is(tok::star)) 920 return Left.isLiteral() || 921 (Left.isNot(tok::star) && Left.isNot(tok::amp) && 922 !Style.PointerAndReferenceBindToType); 923 if (Left.is(tok::amp) || Left.is(tok::star)) 924 return Right.isLiteral() || Style.PointerAndReferenceBindToType; 925 if (Right.is(tok::star) && Left.is(tok::l_paren)) 926 return false; 927 if (Left.is(tok::l_square) || Right.is(tok::l_square) || 928 Right.is(tok::r_square)) 929 return false; 930 if (Left.is(tok::coloncolon) || 931 (Right.is(tok::coloncolon) && 932 (Left.is(tok::identifier) || Left.is(tok::greater)))) 933 return false; 934 if (Left.is(tok::period) || Right.is(tok::period)) 935 return false; 936 if (Left.is(tok::colon) || Right.is(tok::colon)) 937 return true; 938 if (Left.is(tok::l_paren)) 939 return false; 940 if (Left.is(tok::hash)) 941 return false; 942 if (Right.is(tok::l_paren)) { 943 return Left.is(tok::kw_if) || Left.is(tok::kw_for) || 944 Left.is(tok::kw_while) || Left.is(tok::kw_switch) || 945 (Left.isNot(tok::identifier) && Left.isNot(tok::kw_sizeof) && 946 Left.isNot(tok::kw_typeof) && Left.isNot(tok::kw_alignof)); 947 } 948 if (Left.is(tok::at) && Right.getObjCKeywordID() != tok::objc_not_keyword) 949 return false; 950 return true; 951 } 952 953 bool spaceRequiredBefore(unsigned i) { 954 TokenAnnotation &Annotation = Annotations[i]; 955 const FormatToken &Current = Line.Tokens[i]; 956 957 if (CurrentLineType == LT_ObjCMethodDecl) { 958 if (Current.Tok.is(tok::identifier) && (i != Line.Tokens.size() - 1) && 959 Line.Tokens[i + 1].Tok.is(tok::colon) && 960 Line.Tokens[i - 1].Tok.is(tok::identifier)) 961 return true; 962 if (Current.Tok.is(tok::colon)) 963 return false; 964 if (Annotations[i - 1].Type == TT_ObjCMethodSpecifier) 965 return true; 966 if (Line.Tokens[i - 1].Tok.is(tok::r_paren) && 967 Current.Tok.is(tok::identifier)) 968 // Don't space between ')' and <id> 969 return false; 970 if (Line.Tokens[i - 1].Tok.is(tok::colon) && Current.Tok.is(tok::l_paren)) 971 // Don't space between ':' and '(' 972 return false; 973 } 974 975 if (Annotation.Type == TT_CtorInitializerColon) 976 return true; 977 if (Annotation.Type == TT_OverloadedOperator) 978 return Current.Tok.is(tok::identifier) || Current.Tok.is(tok::kw_new) || 979 Current.Tok.is(tok::kw_delete); 980 if (Annotations[i - 1].Type == TT_OverloadedOperator) 981 return false; 982 if (Current.Tok.is(tok::colon)) 983 return Line.Tokens[0].Tok.isNot(tok::kw_case) && 984 (i != Line.Tokens.size() - 1); 985 if (Annotations[i - 1].Type == TT_UnaryOperator) 986 return false; 987 if (Annotation.Type == TT_UnaryOperator) 988 return Line.Tokens[i - 1].Tok.isNot(tok::l_paren) && 989 Line.Tokens[i - 1].Tok.isNot(tok::l_square); 990 if (Line.Tokens[i - 1].Tok.is(tok::greater) && 991 Current.Tok.is(tok::greater)) { 992 return Annotation.Type == TT_TemplateCloser && Annotations[i - 1].Type == 993 TT_TemplateCloser && Style.SplitTemplateClosingGreater; 994 } 995 if (Annotation.Type == TT_DirectorySeparator || 996 Annotations[i - 1].Type == TT_DirectorySeparator) 997 return false; 998 if (Annotation.Type == TT_BinaryOperator || 999 Annotations[i - 1].Type == TT_BinaryOperator) 1000 return true; 1001 if (Annotations[i - 1].Type == TT_TemplateCloser && 1002 Current.Tok.is(tok::l_paren)) 1003 return false; 1004 if (Current.Tok.is(tok::less) && Line.Tokens[0].Tok.is(tok::hash)) 1005 return true; 1006 if (Annotation.Type == TT_TrailingUnaryOperator) 1007 return false; 1008 return spaceRequiredBetween(Line.Tokens[i - 1].Tok, Current.Tok); 1009 } 1010 1011 bool canBreakBefore(unsigned i) { 1012 if (CurrentLineType == LT_ObjCMethodDecl) { 1013 if (Line.Tokens[i].Tok.is(tok::identifier) && 1014 (i != Line.Tokens.size() - 1) && 1015 Line.Tokens[i + 1].Tok.is(tok::colon) && 1016 Line.Tokens[i - 1].Tok.is(tok::identifier)) 1017 return true; 1018 if (CurrentLineType == LT_ObjCMethodDecl && 1019 Line.Tokens[i].Tok.is(tok::identifier) && 1020 Line.Tokens[i - 1].Tok.is(tok::l_paren) && 1021 Line.Tokens[i - 2].Tok.is(tok::colon)) 1022 // Don't break this identifier as ':' or identifier 1023 // before it will break. 1024 return false; 1025 if (Line.Tokens[i].Tok.is(tok::colon) && 1026 Line.Tokens[i - 1].Tok.is(tok::identifier) && 1027 Annotations[i - 1].CanBreakBefore) 1028 // Don't break at ':' if identifier before it can beak. 1029 return false; 1030 } 1031 if (Annotations[i - 1].ClosesTemplateDeclaration) 1032 return true; 1033 if (Annotations[i - 1].Type == TT_PointerOrReference || 1034 Annotations[i - 1].Type == TT_TemplateCloser || 1035 Annotations[i].Type == TT_ConditionalExpr) { 1036 return false; 1037 } 1038 const FormatToken &Left = Line.Tokens[i - 1]; 1039 const FormatToken &Right = Line.Tokens[i]; 1040 if (Left.Tok.is(tok::equal) && CurrentLineType == LT_VirtualFunctionDecl) 1041 return false; 1042 1043 if (Right.Tok.is(tok::r_paren) || Right.Tok.is(tok::l_brace) || 1044 Right.Tok.is(tok::comment) || Right.Tok.is(tok::greater)) 1045 return false; 1046 return (isBinaryOperator(Left) && Left.Tok.isNot(tok::lessless)) || 1047 Left.Tok.is(tok::comma) || Right.Tok.is(tok::lessless) || 1048 Right.Tok.is(tok::arrow) || Right.Tok.is(tok::period) || 1049 Right.Tok.is(tok::colon) || Left.Tok.is(tok::semi) || 1050 Left.Tok.is(tok::l_brace) || 1051 (Left.Tok.is(tok::l_paren) && !Right.Tok.is(tok::r_paren)); 1052 } 1053 1054 const UnwrappedLine &Line; 1055 FormatStyle Style; 1056 SourceManager &SourceMgr; 1057 Lexer &Lex; 1058 LineType CurrentLineType; 1059 std::vector<TokenAnnotation> Annotations; 1060 }; 1061 1062 class LexerBasedFormatTokenSource : public FormatTokenSource { 1063 public: 1064 LexerBasedFormatTokenSource(Lexer &Lex, SourceManager &SourceMgr) 1065 : GreaterStashed(false), Lex(Lex), SourceMgr(SourceMgr), 1066 IdentTable(Lex.getLangOpts()) { 1067 Lex.SetKeepWhitespaceMode(true); 1068 } 1069 1070 virtual FormatToken getNextToken() { 1071 if (GreaterStashed) { 1072 FormatTok.NewlinesBefore = 0; 1073 FormatTok.WhiteSpaceStart = 1074 FormatTok.Tok.getLocation().getLocWithOffset(1); 1075 FormatTok.WhiteSpaceLength = 0; 1076 GreaterStashed = false; 1077 return FormatTok; 1078 } 1079 1080 FormatTok = FormatToken(); 1081 Lex.LexFromRawLexer(FormatTok.Tok); 1082 StringRef Text = rawTokenText(FormatTok.Tok); 1083 FormatTok.WhiteSpaceStart = FormatTok.Tok.getLocation(); 1084 if (SourceMgr.getFileOffset(FormatTok.WhiteSpaceStart) == 0) 1085 FormatTok.IsFirst = true; 1086 1087 // Consume and record whitespace until we find a significant token. 1088 while (FormatTok.Tok.is(tok::unknown)) { 1089 FormatTok.NewlinesBefore += Text.count('\n'); 1090 FormatTok.HasUnescapedNewline = Text.count("\\\n") != 1091 FormatTok.NewlinesBefore; 1092 FormatTok.WhiteSpaceLength += FormatTok.Tok.getLength(); 1093 1094 if (FormatTok.Tok.is(tok::eof)) 1095 return FormatTok; 1096 Lex.LexFromRawLexer(FormatTok.Tok); 1097 Text = rawTokenText(FormatTok.Tok); 1098 } 1099 1100 // Now FormatTok is the next non-whitespace token. 1101 FormatTok.TokenLength = Text.size(); 1102 1103 // In case the token starts with escaped newlines, we want to 1104 // take them into account as whitespace - this pattern is quite frequent 1105 // in macro definitions. 1106 // FIXME: What do we want to do with other escaped spaces, and escaped 1107 // spaces or newlines in the middle of tokens? 1108 // FIXME: Add a more explicit test. 1109 unsigned i = 0; 1110 while (i + 1 < Text.size() && Text[i] == '\\' && Text[i + 1] == '\n') { 1111 FormatTok.WhiteSpaceLength += 2; 1112 FormatTok.TokenLength -= 2; 1113 i += 2; 1114 } 1115 1116 if (FormatTok.Tok.is(tok::raw_identifier)) { 1117 IdentifierInfo &Info = IdentTable.get(Text); 1118 FormatTok.Tok.setIdentifierInfo(&Info); 1119 FormatTok.Tok.setKind(Info.getTokenID()); 1120 } 1121 1122 if (FormatTok.Tok.is(tok::greatergreater)) { 1123 FormatTok.Tok.setKind(tok::greater); 1124 GreaterStashed = true; 1125 } 1126 1127 return FormatTok; 1128 } 1129 1130 private: 1131 FormatToken FormatTok; 1132 bool GreaterStashed; 1133 Lexer &Lex; 1134 SourceManager &SourceMgr; 1135 IdentifierTable IdentTable; 1136 1137 /// Returns the text of \c FormatTok. 1138 StringRef rawTokenText(Token &Tok) { 1139 return StringRef(SourceMgr.getCharacterData(Tok.getLocation()), 1140 Tok.getLength()); 1141 } 1142 }; 1143 1144 class Formatter : public UnwrappedLineConsumer { 1145 public: 1146 Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr, 1147 const std::vector<CharSourceRange> &Ranges) 1148 : Style(Style), Lex(Lex), SourceMgr(SourceMgr), Ranges(Ranges), 1149 StructuralError(false) { 1150 } 1151 1152 virtual ~Formatter() { 1153 } 1154 1155 tooling::Replacements format() { 1156 LexerBasedFormatTokenSource Tokens(Lex, SourceMgr); 1157 UnwrappedLineParser Parser(Style, Tokens, *this); 1158 StructuralError = Parser.parse(); 1159 unsigned PreviousEndOfLineColumn = 0; 1160 for (std::vector<UnwrappedLine>::iterator I = UnwrappedLines.begin(), 1161 E = UnwrappedLines.end(); 1162 I != E; ++I) 1163 PreviousEndOfLineColumn = formatUnwrappedLine(*I, 1164 PreviousEndOfLineColumn); 1165 return Replaces; 1166 } 1167 1168 private: 1169 virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) { 1170 UnwrappedLines.push_back(TheLine); 1171 } 1172 1173 unsigned formatUnwrappedLine(const UnwrappedLine &TheLine, 1174 unsigned PreviousEndOfLineColumn) { 1175 if (TheLine.Tokens.empty()) 1176 return 0; // FIXME: Find out how this can ever happen. 1177 1178 CharSourceRange LineRange = CharSourceRange::getTokenRange( 1179 TheLine.Tokens.front().Tok.getLocation(), 1180 TheLine.Tokens.back().Tok.getLocation()); 1181 1182 for (unsigned i = 0, e = Ranges.size(); i != e; ++i) { 1183 if (SourceMgr.isBeforeInTranslationUnit(LineRange.getEnd(), 1184 Ranges[i].getBegin()) || 1185 SourceMgr.isBeforeInTranslationUnit(Ranges[i].getEnd(), 1186 LineRange.getBegin())) 1187 continue; 1188 1189 TokenAnnotator Annotator(TheLine, Style, SourceMgr, Lex); 1190 if (!Annotator.annotate()) 1191 break; 1192 UnwrappedLineFormatter Formatter( 1193 Style, SourceMgr, TheLine, PreviousEndOfLineColumn, 1194 Annotator.getLineType(), Annotator.getAnnotations(), Replaces, 1195 StructuralError); 1196 return Formatter.format(); 1197 } 1198 // If we did not reformat this unwrapped line, the column at the end of the 1199 // last token is unchanged - thus, we can calculate the end of the last 1200 // token, and return the result. 1201 const FormatToken &Token = TheLine.Tokens.back(); 1202 return SourceMgr.getSpellingColumnNumber(Token.Tok.getLocation()) + 1203 Lex.MeasureTokenLength(Token.Tok.getLocation(), SourceMgr, 1204 Lex.getLangOpts()) - 1205 1; 1206 } 1207 1208 FormatStyle Style; 1209 Lexer &Lex; 1210 SourceManager &SourceMgr; 1211 tooling::Replacements Replaces; 1212 std::vector<CharSourceRange> Ranges; 1213 std::vector<UnwrappedLine> UnwrappedLines; 1214 bool StructuralError; 1215 }; 1216 1217 tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex, 1218 SourceManager &SourceMgr, 1219 std::vector<CharSourceRange> Ranges) { 1220 Formatter formatter(Style, Lex, SourceMgr, Ranges); 1221 return formatter.format(); 1222 } 1223 1224 } // namespace format 1225 } // namespace clang 1226