1 //===--- ContinuationIndenter.h - Format C++ code ---------------*- C++ -*-===// 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 an indenter that manages the indentation of 12 /// continuations. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CLANG_LIB_FORMAT_CONTINUATIONINDENTER_H 17 #define LLVM_CLANG_LIB_FORMAT_CONTINUATIONINDENTER_H 18 19 #include "Encoding.h" 20 #include "FormatToken.h" 21 #include "clang/Format/Format.h" 22 #include "llvm/Support/Regex.h" 23 24 namespace clang { 25 class SourceManager; 26 27 namespace format { 28 29 class AnnotatedLine; 30 struct FormatToken; 31 struct LineState; 32 struct ParenState; 33 class WhitespaceManager; 34 35 class ContinuationIndenter { 36 public: 37 /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in 38 /// column \p FirstIndent. 39 ContinuationIndenter(const FormatStyle &Style, 40 const AdditionalKeywords &Keywords, 41 const SourceManager &SourceMgr, 42 WhitespaceManager &Whitespaces, 43 encoding::Encoding Encoding, 44 bool BinPackInconclusiveFunctions); 45 46 /// \brief Get the initial state, i.e. the state after placing \p Line's 47 /// first token at \p FirstIndent. 48 LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line, 49 bool DryRun); 50 51 // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a 52 // better home. 53 /// \brief Returns \c true, if a line break after \p State is allowed. 54 bool canBreak(const LineState &State); 55 56 /// \brief Returns \c true, if a line break after \p State is mandatory. 57 bool mustBreak(const LineState &State); 58 59 /// \brief Appends the next token to \p State and updates information 60 /// necessary for indentation. 61 /// 62 /// Puts the token on the current line if \p Newline is \c false and adds a 63 /// line break and necessary indentation otherwise. 64 /// 65 /// If \p DryRun is \c false, also creates and stores the required 66 /// \c Replacement. 67 unsigned addTokenToState(LineState &State, bool Newline, bool DryRun, 68 unsigned ExtraSpaces = 0); 69 70 /// \brief Get the column limit for this line. This is the style's column 71 /// limit, potentially reduced for preprocessor definitions. 72 unsigned getColumnLimit(const LineState &State) const; 73 74 private: 75 /// \brief Mark the next token as consumed in \p State and modify its stacks 76 /// accordingly. 77 unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline); 78 79 /// \brief Update 'State' according to the next token's fake left parentheses. 80 void moveStatePastFakeLParens(LineState &State, bool Newline); 81 /// \brief Update 'State' according to the next token's fake r_parens. 82 void moveStatePastFakeRParens(LineState &State); 83 84 /// \brief Update 'State' according to the next token being one of "(<{[". 85 void moveStatePastScopeOpener(LineState &State, bool Newline); 86 /// \brief Update 'State' according to the next token being one of ")>}]". 87 void moveStatePastScopeCloser(LineState &State); 88 /// \brief Update 'State' with the next token opening a nested block. 89 void moveStateToNewBlock(LineState &State); 90 91 /// \brief If the current token sticks out over the end of the line, break 92 /// it if possible. 93 /// 94 /// \returns An extra penalty if a token was broken, otherwise 0. 95 /// 96 /// The returned penalty will cover the cost of the additional line breaks and 97 /// column limit violation in all lines except for the last one. The penalty 98 /// for the column limit violation in the last line (and in single line 99 /// tokens) is handled in \c addNextStateToQueue. 100 unsigned breakProtrudingToken(const FormatToken &Current, LineState &State, 101 bool DryRun); 102 103 /// \brief Appends the next token to \p State and updates information 104 /// necessary for indentation. 105 /// 106 /// Puts the token on the current line. 107 /// 108 /// If \p DryRun is \c false, also creates and stores the required 109 /// \c Replacement. 110 void addTokenOnCurrentLine(LineState &State, bool DryRun, 111 unsigned ExtraSpaces); 112 113 /// \brief Appends the next token to \p State and updates information 114 /// necessary for indentation. 115 /// 116 /// Adds a line break and necessary indentation. 117 /// 118 /// If \p DryRun is \c false, also creates and stores the required 119 /// \c Replacement. 120 unsigned addTokenOnNewLine(LineState &State, bool DryRun); 121 122 /// \brief Calculate the new column for a line wrap before the next token. 123 unsigned getNewLineColumn(const LineState &State); 124 125 /// \brief Adds a multiline token to the \p State. 126 /// 127 /// \returns Extra penalty for the first line of the literal: last line is 128 /// handled in \c addNextStateToQueue, and the penalty for other lines doesn't 129 /// matter, as we don't change them. 130 unsigned addMultilineToken(const FormatToken &Current, LineState &State); 131 132 /// \brief Returns \c true if the next token starts a multiline string 133 /// literal. 134 /// 135 /// This includes implicitly concatenated strings, strings that will be broken 136 /// by clang-format and string literals with escaped newlines. 137 bool nextIsMultilineString(const LineState &State); 138 139 FormatStyle Style; 140 const AdditionalKeywords &Keywords; 141 const SourceManager &SourceMgr; 142 WhitespaceManager &Whitespaces; 143 encoding::Encoding Encoding; 144 bool BinPackInconclusiveFunctions; 145 llvm::Regex CommentPragmasRegex; 146 }; 147 148 struct ParenState { 149 ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking, 150 bool NoLineBreak) 151 : Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent), 152 BreakBeforeClosingBrace(false), AvoidBinPacking(AvoidBinPacking), 153 BreakBeforeParameter(false), NoLineBreak(NoLineBreak), 154 NoLineBreakInOperand(false), LastOperatorWrapped(true), 155 ContainsLineBreak(false), ContainsUnwrappedBuilder(false), 156 AlignColons(true), ObjCSelectorNameFound(false), 157 HasMultipleNestedBlocks(false), NestedBlockInlined(false) {} 158 159 /// \brief The position to which a specific parenthesis level needs to be 160 /// indented. 161 unsigned Indent; 162 163 /// \brief The position of the last space on each level. 164 /// 165 /// Used e.g. to break like: 166 /// functionCall(Parameter, otherCall( 167 /// OtherParameter)); 168 unsigned LastSpace; 169 170 /// \brief If a block relative to this parenthesis level gets wrapped, indent 171 /// it this much. 172 unsigned NestedBlockIndent; 173 174 /// \brief The position the first "<<" operator encountered on each level. 175 /// 176 /// Used to align "<<" operators. 0 if no such operator has been encountered 177 /// on a level. 178 unsigned FirstLessLess = 0; 179 180 /// \brief The column of a \c ? in a conditional expression; 181 unsigned QuestionColumn = 0; 182 183 /// \brief The position of the colon in an ObjC method declaration/call. 184 unsigned ColonPos = 0; 185 186 /// \brief The start of the most recent function in a builder-type call. 187 unsigned StartOfFunctionCall = 0; 188 189 /// \brief Contains the start of array subscript expressions, so that they 190 /// can be aligned. 191 unsigned StartOfArraySubscripts = 0; 192 193 /// \brief If a nested name specifier was broken over multiple lines, this 194 /// contains the start column of the second line. Otherwise 0. 195 unsigned NestedNameSpecifierContinuation = 0; 196 197 /// \brief If a call expression was broken over multiple lines, this 198 /// contains the start column of the second line. Otherwise 0. 199 unsigned CallContinuation = 0; 200 201 /// \brief The column of the first variable name in a variable declaration. 202 /// 203 /// Used to align further variables if necessary. 204 unsigned VariablePos = 0; 205 206 /// \brief Whether a newline needs to be inserted before the block's closing 207 /// brace. 208 /// 209 /// We only want to insert a newline before the closing brace if there also 210 /// was a newline after the beginning left brace. 211 bool BreakBeforeClosingBrace : 1; 212 213 /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple 214 /// lines, in this context. 215 bool AvoidBinPacking : 1; 216 217 /// \brief Break after the next comma (or all the commas in this context if 218 /// \c AvoidBinPacking is \c true). 219 bool BreakBeforeParameter : 1; 220 221 /// \brief Line breaking in this context would break a formatting rule. 222 bool NoLineBreak : 1; 223 224 /// \brief Same as \c NoLineBreak, but is restricted until the end of the 225 /// operand (including the next ","). 226 bool NoLineBreakInOperand : 1; 227 228 /// \brief True if the last binary operator on this level was wrapped to the 229 /// next line. 230 bool LastOperatorWrapped : 1; 231 232 /// \brief \c true if this \c ParenState already contains a line-break. 233 /// 234 /// The first line break in a certain \c ParenState causes extra penalty so 235 /// that clang-format prefers similar breaks, i.e. breaks in the same 236 /// parenthesis. 237 bool ContainsLineBreak : 1; 238 239 /// \brief \c true if this \c ParenState contains multiple segments of a 240 /// builder-type call on one line. 241 bool ContainsUnwrappedBuilder : 1; 242 243 /// \brief \c true if the colons of the curren ObjC method expression should 244 /// be aligned. 245 /// 246 /// Not considered for memoization as it will always have the same value at 247 /// the same token. 248 bool AlignColons : 1; 249 250 /// \brief \c true if at least one selector name was found in the current 251 /// ObjC method expression. 252 /// 253 /// Not considered for memoization as it will always have the same value at 254 /// the same token. 255 bool ObjCSelectorNameFound : 1; 256 257 /// \brief \c true if there are multiple nested blocks inside these parens. 258 /// 259 /// Not considered for memoization as it will always have the same value at 260 /// the same token. 261 bool HasMultipleNestedBlocks : 1; 262 263 // \brief The start of a nested block (e.g. lambda introducer in C++ or 264 // "function" in JavaScript) is not wrapped to a new line. 265 bool NestedBlockInlined : 1; 266 267 bool operator<(const ParenState &Other) const { 268 if (Indent != Other.Indent) 269 return Indent < Other.Indent; 270 if (LastSpace != Other.LastSpace) 271 return LastSpace < Other.LastSpace; 272 if (NestedBlockIndent != Other.NestedBlockIndent) 273 return NestedBlockIndent < Other.NestedBlockIndent; 274 if (FirstLessLess != Other.FirstLessLess) 275 return FirstLessLess < Other.FirstLessLess; 276 if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace) 277 return BreakBeforeClosingBrace; 278 if (QuestionColumn != Other.QuestionColumn) 279 return QuestionColumn < Other.QuestionColumn; 280 if (AvoidBinPacking != Other.AvoidBinPacking) 281 return AvoidBinPacking; 282 if (BreakBeforeParameter != Other.BreakBeforeParameter) 283 return BreakBeforeParameter; 284 if (NoLineBreak != Other.NoLineBreak) 285 return NoLineBreak; 286 if (LastOperatorWrapped != Other.LastOperatorWrapped) 287 return LastOperatorWrapped; 288 if (ColonPos != Other.ColonPos) 289 return ColonPos < Other.ColonPos; 290 if (StartOfFunctionCall != Other.StartOfFunctionCall) 291 return StartOfFunctionCall < Other.StartOfFunctionCall; 292 if (StartOfArraySubscripts != Other.StartOfArraySubscripts) 293 return StartOfArraySubscripts < Other.StartOfArraySubscripts; 294 if (CallContinuation != Other.CallContinuation) 295 return CallContinuation < Other.CallContinuation; 296 if (VariablePos != Other.VariablePos) 297 return VariablePos < Other.VariablePos; 298 if (ContainsLineBreak != Other.ContainsLineBreak) 299 return ContainsLineBreak; 300 if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder) 301 return ContainsUnwrappedBuilder; 302 if (NestedBlockInlined != Other.NestedBlockInlined) 303 return NestedBlockInlined; 304 return false; 305 } 306 }; 307 308 /// \brief The current state when indenting a unwrapped line. 309 /// 310 /// As the indenting tries different combinations this is copied by value. 311 struct LineState { 312 /// \brief The number of used columns in the current line. 313 unsigned Column; 314 315 /// \brief The token that needs to be next formatted. 316 FormatToken *NextToken; 317 318 /// \brief \c true if this line contains a continued for-loop section. 319 bool LineContainsContinuedForLoopSection; 320 321 /// \brief The \c NestingLevel at the start of this line. 322 unsigned StartOfLineLevel; 323 324 /// \brief The lowest \c NestingLevel on the current line. 325 unsigned LowestLevelOnLine; 326 327 /// \brief The start column of the string literal, if we're in a string 328 /// literal sequence, 0 otherwise. 329 unsigned StartOfStringLiteral; 330 331 /// \brief A stack keeping track of properties applying to parenthesis 332 /// levels. 333 std::vector<ParenState> Stack; 334 335 /// \brief Ignore the stack of \c ParenStates for state comparison. 336 /// 337 /// In long and deeply nested unwrapped lines, the current algorithm can 338 /// be insufficient for finding the best formatting with a reasonable amount 339 /// of time and memory. Setting this flag will effectively lead to the 340 /// algorithm not analyzing some combinations. However, these combinations 341 /// rarely contain the optimal solution: In short, accepting a higher 342 /// penalty early would need to lead to different values in the \c 343 /// ParenState stack (in an otherwise identical state) and these different 344 /// values would need to lead to a significant amount of avoided penalty 345 /// later. 346 /// 347 /// FIXME: Come up with a better algorithm instead. 348 bool IgnoreStackForComparison; 349 350 /// \brief The indent of the first token. 351 unsigned FirstIndent; 352 353 /// \brief The line that is being formatted. 354 /// 355 /// Does not need to be considered for memoization because it doesn't change. 356 const AnnotatedLine *Line; 357 358 /// \brief Comparison operator to be able to used \c LineState in \c map. 359 bool operator<(const LineState &Other) const { 360 if (NextToken != Other.NextToken) 361 return NextToken < Other.NextToken; 362 if (Column != Other.Column) 363 return Column < Other.Column; 364 if (LineContainsContinuedForLoopSection != 365 Other.LineContainsContinuedForLoopSection) 366 return LineContainsContinuedForLoopSection; 367 if (StartOfLineLevel != Other.StartOfLineLevel) 368 return StartOfLineLevel < Other.StartOfLineLevel; 369 if (LowestLevelOnLine != Other.LowestLevelOnLine) 370 return LowestLevelOnLine < Other.LowestLevelOnLine; 371 if (StartOfStringLiteral != Other.StartOfStringLiteral) 372 return StartOfStringLiteral < Other.StartOfStringLiteral; 373 if (IgnoreStackForComparison || Other.IgnoreStackForComparison) 374 return false; 375 return Stack < Other.Stack; 376 } 377 }; 378 379 } // end namespace format 380 } // end namespace clang 381 382 #endif 383