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