UnwrappedLineParser.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //===--- UnwrappedLineParser.h - Format C++ code ----------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file contains the declaration of the UnwrappedLineParser,
  11. /// which turns a stream of tokens into UnwrappedLines.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEPARSER_H
  15. #define LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEPARSER_H
  16. #include "FormatToken.h"
  17. #include "clang/Basic/IdentifierTable.h"
  18. #include "clang/Format/Format.h"
  19. #include "llvm/ADT/BitVector.h"
  20. #include "llvm/Support/Regex.h"
  21. #include <stack>
  22. #include <vector>
  23. namespace clang {
  24. namespace format {
  25. struct UnwrappedLineNode;
  26. /// An unwrapped line is a sequence of \c Token, that we would like to
  27. /// put on a single line if there was no column limit.
  28. ///
  29. /// This is used as a main interface between the \c UnwrappedLineParser and the
  30. /// \c UnwrappedLineFormatter. The key property is that changing the formatting
  31. /// within an unwrapped line does not affect any other unwrapped lines.
  32. struct UnwrappedLine {
  33. UnwrappedLine();
  34. /// The \c Tokens comprising this \c UnwrappedLine.
  35. std::vector<UnwrappedLineNode> Tokens;
  36. /// The indent level of the \c UnwrappedLine.
  37. unsigned Level;
  38. /// Whether this \c UnwrappedLine is part of a preprocessor directive.
  39. bool InPPDirective;
  40. bool MustBeDeclaration;
  41. /// If this \c UnwrappedLine closes a block in a sequence of lines,
  42. /// \c MatchingOpeningBlockLineIndex stores the index of the corresponding
  43. /// opening line. Otherwise, \c MatchingOpeningBlockLineIndex must be
  44. /// \c kInvalidIndex.
  45. size_t MatchingOpeningBlockLineIndex = kInvalidIndex;
  46. /// If this \c UnwrappedLine opens a block, stores the index of the
  47. /// line with the corresponding closing brace.
  48. size_t MatchingClosingBlockLineIndex = kInvalidIndex;
  49. static const size_t kInvalidIndex = -1;
  50. unsigned FirstStartColumn = 0;
  51. };
  52. class UnwrappedLineConsumer {
  53. public:
  54. virtual ~UnwrappedLineConsumer() {}
  55. virtual void consumeUnwrappedLine(const UnwrappedLine &Line) = 0;
  56. virtual void finishRun() = 0;
  57. };
  58. class FormatTokenSource;
  59. class UnwrappedLineParser {
  60. public:
  61. UnwrappedLineParser(const FormatStyle &Style,
  62. const AdditionalKeywords &Keywords,
  63. unsigned FirstStartColumn, ArrayRef<FormatToken *> Tokens,
  64. UnwrappedLineConsumer &Callback);
  65. void parse();
  66. private:
  67. enum class IfStmtKind {
  68. NotIf, // Not an if statement.
  69. IfOnly, // An if statement without the else clause.
  70. IfElse, // An if statement followed by else but not else if.
  71. IfElseIf // An if statement followed by else if.
  72. };
  73. void reset();
  74. void parseFile();
  75. bool precededByCommentOrPPDirective() const;
  76. bool mightFitOnOneLine() const;
  77. bool parseLevel(bool HasOpeningBrace, IfStmtKind *IfKind = nullptr);
  78. IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u,
  79. bool MunchSemi = true,
  80. bool UnindentWhitesmithsBraces = false);
  81. void parseChildBlock();
  82. void parsePPDirective();
  83. void parsePPDefine();
  84. void parsePPIf(bool IfDef);
  85. void parsePPElIf();
  86. void parsePPElse();
  87. void parsePPEndIf();
  88. void parsePPUnknown();
  89. void readTokenWithJavaScriptASI();
  90. void parseStructuralElement(IfStmtKind *IfKind = nullptr,
  91. bool IsTopLevel = false);
  92. bool tryToParseBracedList();
  93. bool parseBracedList(bool ContinueOnSemicolons = false, bool IsEnum = false,
  94. tok::TokenKind ClosingBraceKind = tok::r_brace);
  95. void parseParens();
  96. void parseSquare(bool LambdaIntroducer = false);
  97. void keepAncestorBraces();
  98. FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
  99. void parseTryCatch();
  100. void parseForOrWhileLoop();
  101. void parseDoWhile();
  102. void parseLabel(bool LeftAlignLabel = false);
  103. void parseCaseLabel();
  104. void parseSwitch();
  105. void parseNamespace();
  106. void parseModuleImport();
  107. void parseNew();
  108. void parseAccessSpecifier();
  109. bool parseEnum();
  110. bool parseStructLike();
  111. void parseConcept();
  112. void parseRequires();
  113. void parseRequiresExpression(unsigned int OriginalLevel);
  114. void parseConstraintExpression(unsigned int OriginalLevel);
  115. void parseJavaEnumBody();
  116. // Parses a record (aka class) as a top level element. If ParseAsExpr is true,
  117. // parses the record as a child block, i.e. if the class declaration is an
  118. // expression.
  119. void parseRecord(bool ParseAsExpr = false);
  120. void parseObjCLightweightGenerics();
  121. void parseObjCMethod();
  122. void parseObjCProtocolList();
  123. void parseObjCUntilAtEnd();
  124. void parseObjCInterfaceOrImplementation();
  125. bool parseObjCProtocol();
  126. void parseJavaScriptEs6ImportExport();
  127. void parseStatementMacro();
  128. void parseCSharpAttribute();
  129. // Parse a C# generic type constraint: `where T : IComparable<T>`.
  130. // See:
  131. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint
  132. void parseCSharpGenericTypeConstraint();
  133. bool tryToParseLambda();
  134. bool tryToParseChildBlock();
  135. bool tryToParseLambdaIntroducer();
  136. bool tryToParsePropertyAccessor();
  137. void tryToParseJSFunction();
  138. bool tryToParseSimpleAttribute();
  139. // Used by addUnwrappedLine to denote whether to keep or remove a level
  140. // when resetting the line state.
  141. enum class LineLevel { Remove, Keep };
  142. void addUnwrappedLine(LineLevel AdjustLevel = LineLevel::Remove);
  143. bool eof() const;
  144. // LevelDifference is the difference of levels after and before the current
  145. // token. For example:
  146. // - if the token is '{' and opens a block, LevelDifference is 1.
  147. // - if the token is '}' and closes a block, LevelDifference is -1.
  148. void nextToken(int LevelDifference = 0);
  149. void readToken(int LevelDifference = 0);
  150. // Decides which comment tokens should be added to the current line and which
  151. // should be added as comments before the next token.
  152. //
  153. // Comments specifies the sequence of comment tokens to analyze. They get
  154. // either pushed to the current line or added to the comments before the next
  155. // token.
  156. //
  157. // NextTok specifies the next token. A null pointer NextTok is supported, and
  158. // signifies either the absence of a next token, or that the next token
  159. // shouldn't be taken into accunt for the analysis.
  160. void distributeComments(const SmallVectorImpl<FormatToken *> &Comments,
  161. const FormatToken *NextTok);
  162. // Adds the comment preceding the next token to unwrapped lines.
  163. void flushComments(bool NewlineBeforeNext);
  164. void pushToken(FormatToken *Tok);
  165. void calculateBraceTypes(bool ExpectClassBody = false);
  166. // Marks a conditional compilation edge (for example, an '#if', '#ifdef',
  167. // '#else' or merge conflict marker). If 'Unreachable' is true, assumes
  168. // this branch either cannot be taken (for example '#if false'), or should
  169. // not be taken in this round.
  170. void conditionalCompilationCondition(bool Unreachable);
  171. void conditionalCompilationStart(bool Unreachable);
  172. void conditionalCompilationAlternative();
  173. void conditionalCompilationEnd();
  174. bool isOnNewLine(const FormatToken &FormatTok);
  175. // Compute hash of the current preprocessor branch.
  176. // This is used to identify the different branches, and thus track if block
  177. // open and close in the same branch.
  178. size_t computePPHash() const;
  179. // FIXME: We are constantly running into bugs where Line.Level is incorrectly
  180. // subtracted from beyond 0. Introduce a method to subtract from Line.Level
  181. // and use that everywhere in the Parser.
  182. std::unique_ptr<UnwrappedLine> Line;
  183. // Comments are sorted into unwrapped lines by whether they are in the same
  184. // line as the previous token, or not. If not, they belong to the next token.
  185. // Since the next token might already be in a new unwrapped line, we need to
  186. // store the comments belonging to that token.
  187. SmallVector<FormatToken *, 1> CommentsBeforeNextToken;
  188. FormatToken *FormatTok;
  189. bool MustBreakBeforeNextToken;
  190. // The parsed lines. Only added to through \c CurrentLines.
  191. SmallVector<UnwrappedLine, 8> Lines;
  192. // Preprocessor directives are parsed out-of-order from other unwrapped lines.
  193. // Thus, we need to keep a list of preprocessor directives to be reported
  194. // after an unwrapped line that has been started was finished.
  195. SmallVector<UnwrappedLine, 4> PreprocessorDirectives;
  196. // New unwrapped lines are added via CurrentLines.
  197. // Usually points to \c &Lines. While parsing a preprocessor directive when
  198. // there is an unfinished previous unwrapped line, will point to
  199. // \c &PreprocessorDirectives.
  200. SmallVectorImpl<UnwrappedLine> *CurrentLines;
  201. // We store for each line whether it must be a declaration depending on
  202. // whether we are in a compound statement or not.
  203. llvm::BitVector DeclarationScopeStack;
  204. const FormatStyle &Style;
  205. const AdditionalKeywords &Keywords;
  206. llvm::Regex CommentPragmasRegex;
  207. FormatTokenSource *Tokens;
  208. UnwrappedLineConsumer &Callback;
  209. // FIXME: This is a temporary measure until we have reworked the ownership
  210. // of the format tokens. The goal is to have the actual tokens created and
  211. // owned outside of and handed into the UnwrappedLineParser.
  212. ArrayRef<FormatToken *> AllTokens;
  213. // Keeps a stack of the states of nested control statements (true if the
  214. // statement contains more than some predefined number of nested statements).
  215. SmallVector<bool, 8> NestedTooDeep;
  216. // Represents preprocessor branch type, so we can find matching
  217. // #if/#else/#endif directives.
  218. enum PPBranchKind {
  219. PP_Conditional, // Any #if, #ifdef, #ifndef, #elif, block outside #if 0
  220. PP_Unreachable // #if 0 or a conditional preprocessor block inside #if 0
  221. };
  222. struct PPBranch {
  223. PPBranch(PPBranchKind Kind, size_t Line) : Kind(Kind), Line(Line) {}
  224. PPBranchKind Kind;
  225. size_t Line;
  226. };
  227. // Keeps a stack of currently active preprocessor branching directives.
  228. SmallVector<PPBranch, 16> PPStack;
  229. // The \c UnwrappedLineParser re-parses the code for each combination
  230. // of preprocessor branches that can be taken.
  231. // To that end, we take the same branch (#if, #else, or one of the #elif
  232. // branches) for each nesting level of preprocessor branches.
  233. // \c PPBranchLevel stores the current nesting level of preprocessor
  234. // branches during one pass over the code.
  235. int PPBranchLevel;
  236. // Contains the current branch (#if, #else or one of the #elif branches)
  237. // for each nesting level.
  238. SmallVector<int, 8> PPLevelBranchIndex;
  239. // Contains the maximum number of branches at each nesting level.
  240. SmallVector<int, 8> PPLevelBranchCount;
  241. // Contains the number of branches per nesting level we are currently
  242. // in while parsing a preprocessor branch sequence.
  243. // This is used to update PPLevelBranchCount at the end of a branch
  244. // sequence.
  245. std::stack<int> PPChainBranchIndex;
  246. // Include guard search state. Used to fixup preprocessor indent levels
  247. // so that include guards do not participate in indentation.
  248. enum IncludeGuardState {
  249. IG_Inited, // Search started, looking for #ifndef.
  250. IG_IfNdefed, // #ifndef found, IncludeGuardToken points to condition.
  251. IG_Defined, // Matching #define found, checking other requirements.
  252. IG_Found, // All requirements met, need to fix indents.
  253. IG_Rejected, // Search failed or never started.
  254. };
  255. // Current state of include guard search.
  256. IncludeGuardState IncludeGuard;
  257. // Points to the #ifndef condition for a potential include guard. Null unless
  258. // IncludeGuardState == IG_IfNdefed.
  259. FormatToken *IncludeGuardToken;
  260. // Contains the first start column where the source begins. This is zero for
  261. // normal source code and may be nonzero when formatting a code fragment that
  262. // does not start at the beginning of the file.
  263. unsigned FirstStartColumn;
  264. friend class ScopedLineState;
  265. friend class CompoundStatementIndenter;
  266. };
  267. struct UnwrappedLineNode {
  268. UnwrappedLineNode() : Tok(nullptr) {}
  269. UnwrappedLineNode(FormatToken *Tok) : Tok(Tok) {}
  270. FormatToken *Tok;
  271. SmallVector<UnwrappedLine, 0> Children;
  272. };
  273. inline UnwrappedLine::UnwrappedLine()
  274. : Level(0), InPPDirective(false), MustBeDeclaration(false),
  275. MatchingOpeningBlockLineIndex(kInvalidIndex) {}
  276. } // end namespace format
  277. } // end namespace clang
  278. #endif