UnwrappedLineParser.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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/Support/Regex.h"
  20. #include <list>
  21. #include <stack>
  22. namespace clang {
  23. namespace format {
  24. struct UnwrappedLineNode;
  25. /// An unwrapped line is a sequence of \c Token, that we would like to
  26. /// put on a single line if there was no column limit.
  27. ///
  28. /// This is used as a main interface between the \c UnwrappedLineParser and the
  29. /// \c UnwrappedLineFormatter. The key property is that changing the formatting
  30. /// within an unwrapped line does not affect any other unwrapped lines.
  31. struct UnwrappedLine {
  32. UnwrappedLine();
  33. // FIXME: Don't use std::list here.
  34. /// The \c Tokens comprising this \c UnwrappedLine.
  35. std::list<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. void reset();
  68. void parseFile();
  69. void parseLevel(bool HasOpeningBrace);
  70. void parseBlock(bool MustBeDeclaration, bool AddLevel = true,
  71. bool MunchSemi = true);
  72. void parseChildBlock();
  73. void parsePPDirective();
  74. void parsePPDefine();
  75. void parsePPIf(bool IfDef);
  76. void parsePPElIf();
  77. void parsePPElse();
  78. void parsePPEndIf();
  79. void parsePPUnknown();
  80. void readTokenWithJavaScriptASI();
  81. void parseStructuralElement();
  82. bool tryToParseBracedList();
  83. bool parseBracedList(bool ContinueOnSemicolons = false,
  84. tok::TokenKind ClosingBraceKind = tok::r_brace);
  85. void parseParens();
  86. void parseSquare(bool LambdaIntroducer = false);
  87. void parseIfThenElse();
  88. void parseTryCatch();
  89. void parseForOrWhileLoop();
  90. void parseDoWhile();
  91. void parseLabel(bool LeftAlignLabel = false);
  92. void parseCaseLabel();
  93. void parseSwitch();
  94. void parseNamespace();
  95. void parseNew();
  96. void parseAccessSpecifier();
  97. bool parseEnum();
  98. void parseJavaEnumBody();
  99. // Parses a record (aka class) as a top level element. If ParseAsExpr is true,
  100. // parses the record as a child block, i.e. if the class declaration is an
  101. // expression.
  102. void parseRecord(bool ParseAsExpr = false);
  103. void parseObjCMethod();
  104. void parseObjCProtocolList();
  105. void parseObjCUntilAtEnd();
  106. void parseObjCInterfaceOrImplementation();
  107. bool parseObjCProtocol();
  108. void parseJavaScriptEs6ImportExport();
  109. void parseStatementMacro();
  110. bool tryToParseLambda();
  111. bool tryToParseLambdaIntroducer();
  112. void tryToParseJSFunction();
  113. void addUnwrappedLine();
  114. bool eof() const;
  115. // LevelDifference is the difference of levels after and before the current
  116. // token. For example:
  117. // - if the token is '{' and opens a block, LevelDifference is 1.
  118. // - if the token is '}' and closes a block, LevelDifference is -1.
  119. void nextToken(int LevelDifference = 0);
  120. void readToken(int LevelDifference = 0);
  121. // Decides which comment tokens should be added to the current line and which
  122. // should be added as comments before the next token.
  123. //
  124. // Comments specifies the sequence of comment tokens to analyze. They get
  125. // either pushed to the current line or added to the comments before the next
  126. // token.
  127. //
  128. // NextTok specifies the next token. A null pointer NextTok is supported, and
  129. // signifies either the absence of a next token, or that the next token
  130. // shouldn't be taken into accunt for the analysis.
  131. void distributeComments(const SmallVectorImpl<FormatToken *> &Comments,
  132. const FormatToken *NextTok);
  133. // Adds the comment preceding the next token to unwrapped lines.
  134. void flushComments(bool NewlineBeforeNext);
  135. void pushToken(FormatToken *Tok);
  136. void calculateBraceTypes(bool ExpectClassBody = false);
  137. // Marks a conditional compilation edge (for example, an '#if', '#ifdef',
  138. // '#else' or merge conflict marker). If 'Unreachable' is true, assumes
  139. // this branch either cannot be taken (for example '#if false'), or should
  140. // not be taken in this round.
  141. void conditionalCompilationCondition(bool Unreachable);
  142. void conditionalCompilationStart(bool Unreachable);
  143. void conditionalCompilationAlternative();
  144. void conditionalCompilationEnd();
  145. bool isOnNewLine(const FormatToken &FormatTok);
  146. // Compute hash of the current preprocessor branch.
  147. // This is used to identify the different branches, and thus track if block
  148. // open and close in the same branch.
  149. size_t computePPHash() const;
  150. // FIXME: We are constantly running into bugs where Line.Level is incorrectly
  151. // subtracted from beyond 0. Introduce a method to subtract from Line.Level
  152. // and use that everywhere in the Parser.
  153. std::unique_ptr<UnwrappedLine> Line;
  154. // Comments are sorted into unwrapped lines by whether they are in the same
  155. // line as the previous token, or not. If not, they belong to the next token.
  156. // Since the next token might already be in a new unwrapped line, we need to
  157. // store the comments belonging to that token.
  158. SmallVector<FormatToken *, 1> CommentsBeforeNextToken;
  159. FormatToken *FormatTok;
  160. bool MustBreakBeforeNextToken;
  161. // The parsed lines. Only added to through \c CurrentLines.
  162. SmallVector<UnwrappedLine, 8> Lines;
  163. // Preprocessor directives are parsed out-of-order from other unwrapped lines.
  164. // Thus, we need to keep a list of preprocessor directives to be reported
  165. // after an unwrapped line that has been started was finished.
  166. SmallVector<UnwrappedLine, 4> PreprocessorDirectives;
  167. // New unwrapped lines are added via CurrentLines.
  168. // Usually points to \c &Lines. While parsing a preprocessor directive when
  169. // there is an unfinished previous unwrapped line, will point to
  170. // \c &PreprocessorDirectives.
  171. SmallVectorImpl<UnwrappedLine> *CurrentLines;
  172. // We store for each line whether it must be a declaration depending on
  173. // whether we are in a compound statement or not.
  174. std::vector<bool> DeclarationScopeStack;
  175. const FormatStyle &Style;
  176. const AdditionalKeywords &Keywords;
  177. llvm::Regex CommentPragmasRegex;
  178. FormatTokenSource *Tokens;
  179. UnwrappedLineConsumer &Callback;
  180. // FIXME: This is a temporary measure until we have reworked the ownership
  181. // of the format tokens. The goal is to have the actual tokens created and
  182. // owned outside of and handed into the UnwrappedLineParser.
  183. ArrayRef<FormatToken *> AllTokens;
  184. // Represents preprocessor branch type, so we can find matching
  185. // #if/#else/#endif directives.
  186. enum PPBranchKind {
  187. PP_Conditional, // Any #if, #ifdef, #ifndef, #elif, block outside #if 0
  188. PP_Unreachable // #if 0 or a conditional preprocessor block inside #if 0
  189. };
  190. struct PPBranch {
  191. PPBranch(PPBranchKind Kind, size_t Line) : Kind(Kind), Line(Line) {}
  192. PPBranchKind Kind;
  193. size_t Line;
  194. };
  195. // Keeps a stack of currently active preprocessor branching directives.
  196. SmallVector<PPBranch, 16> PPStack;
  197. // The \c UnwrappedLineParser re-parses the code for each combination
  198. // of preprocessor branches that can be taken.
  199. // To that end, we take the same branch (#if, #else, or one of the #elif
  200. // branches) for each nesting level of preprocessor branches.
  201. // \c PPBranchLevel stores the current nesting level of preprocessor
  202. // branches during one pass over the code.
  203. int PPBranchLevel;
  204. // Contains the current branch (#if, #else or one of the #elif branches)
  205. // for each nesting level.
  206. SmallVector<int, 8> PPLevelBranchIndex;
  207. // Contains the maximum number of branches at each nesting level.
  208. SmallVector<int, 8> PPLevelBranchCount;
  209. // Contains the number of branches per nesting level we are currently
  210. // in while parsing a preprocessor branch sequence.
  211. // This is used to update PPLevelBranchCount at the end of a branch
  212. // sequence.
  213. std::stack<int> PPChainBranchIndex;
  214. // Include guard search state. Used to fixup preprocessor indent levels
  215. // so that include guards do not participate in indentation.
  216. enum IncludeGuardState {
  217. IG_Inited, // Search started, looking for #ifndef.
  218. IG_IfNdefed, // #ifndef found, IncludeGuardToken points to condition.
  219. IG_Defined, // Matching #define found, checking other requirements.
  220. IG_Found, // All requirements met, need to fix indents.
  221. IG_Rejected, // Search failed or never started.
  222. };
  223. // Current state of include guard search.
  224. IncludeGuardState IncludeGuard;
  225. // Points to the #ifndef condition for a potential include guard. Null unless
  226. // IncludeGuardState == IG_IfNdefed.
  227. FormatToken *IncludeGuardToken;
  228. // Contains the first start column where the source begins. This is zero for
  229. // normal source code and may be nonzero when formatting a code fragment that
  230. // does not start at the beginning of the file.
  231. unsigned FirstStartColumn;
  232. friend class ScopedLineState;
  233. friend class CompoundStatementIndenter;
  234. };
  235. struct UnwrappedLineNode {
  236. UnwrappedLineNode() : Tok(nullptr) {}
  237. UnwrappedLineNode(FormatToken *Tok) : Tok(Tok) {}
  238. FormatToken *Tok;
  239. SmallVector<UnwrappedLine, 0> Children;
  240. };
  241. inline UnwrappedLine::UnwrappedLine()
  242. : Level(0), InPPDirective(false), MustBeDeclaration(false),
  243. MatchingOpeningBlockLineIndex(kInvalidIndex) {}
  244. } // end namespace format
  245. } // end namespace clang
  246. #endif