1*67e74705SXin Li //===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li ///
10*67e74705SXin Li /// \file
11*67e74705SXin Li /// \brief This file contains the implementation of the UnwrappedLineParser,
12*67e74705SXin Li /// which turns a stream of tokens into UnwrappedLines.
13*67e74705SXin Li ///
14*67e74705SXin Li //===----------------------------------------------------------------------===//
15*67e74705SXin Li
16*67e74705SXin Li #include "UnwrappedLineParser.h"
17*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
18*67e74705SXin Li #include "llvm/Support/Debug.h"
19*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
20*67e74705SXin Li
21*67e74705SXin Li #define DEBUG_TYPE "format-parser"
22*67e74705SXin Li
23*67e74705SXin Li namespace clang {
24*67e74705SXin Li namespace format {
25*67e74705SXin Li
26*67e74705SXin Li class FormatTokenSource {
27*67e74705SXin Li public:
~FormatTokenSource()28*67e74705SXin Li virtual ~FormatTokenSource() {}
29*67e74705SXin Li virtual FormatToken *getNextToken() = 0;
30*67e74705SXin Li
31*67e74705SXin Li virtual unsigned getPosition() = 0;
32*67e74705SXin Li virtual FormatToken *setPosition(unsigned Position) = 0;
33*67e74705SXin Li };
34*67e74705SXin Li
35*67e74705SXin Li namespace {
36*67e74705SXin Li
37*67e74705SXin Li class ScopedDeclarationState {
38*67e74705SXin Li public:
ScopedDeclarationState(UnwrappedLine & Line,std::vector<bool> & Stack,bool MustBeDeclaration)39*67e74705SXin Li ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
40*67e74705SXin Li bool MustBeDeclaration)
41*67e74705SXin Li : Line(Line), Stack(Stack) {
42*67e74705SXin Li Line.MustBeDeclaration = MustBeDeclaration;
43*67e74705SXin Li Stack.push_back(MustBeDeclaration);
44*67e74705SXin Li }
~ScopedDeclarationState()45*67e74705SXin Li ~ScopedDeclarationState() {
46*67e74705SXin Li Stack.pop_back();
47*67e74705SXin Li if (!Stack.empty())
48*67e74705SXin Li Line.MustBeDeclaration = Stack.back();
49*67e74705SXin Li else
50*67e74705SXin Li Line.MustBeDeclaration = true;
51*67e74705SXin Li }
52*67e74705SXin Li
53*67e74705SXin Li private:
54*67e74705SXin Li UnwrappedLine &Line;
55*67e74705SXin Li std::vector<bool> &Stack;
56*67e74705SXin Li };
57*67e74705SXin Li
58*67e74705SXin Li class ScopedMacroState : public FormatTokenSource {
59*67e74705SXin Li public:
ScopedMacroState(UnwrappedLine & Line,FormatTokenSource * & TokenSource,FormatToken * & ResetToken)60*67e74705SXin Li ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
61*67e74705SXin Li FormatToken *&ResetToken)
62*67e74705SXin Li : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
63*67e74705SXin Li PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
64*67e74705SXin Li Token(nullptr) {
65*67e74705SXin Li TokenSource = this;
66*67e74705SXin Li Line.Level = 0;
67*67e74705SXin Li Line.InPPDirective = true;
68*67e74705SXin Li }
69*67e74705SXin Li
~ScopedMacroState()70*67e74705SXin Li ~ScopedMacroState() override {
71*67e74705SXin Li TokenSource = PreviousTokenSource;
72*67e74705SXin Li ResetToken = Token;
73*67e74705SXin Li Line.InPPDirective = false;
74*67e74705SXin Li Line.Level = PreviousLineLevel;
75*67e74705SXin Li }
76*67e74705SXin Li
getNextToken()77*67e74705SXin Li FormatToken *getNextToken() override {
78*67e74705SXin Li // The \c UnwrappedLineParser guards against this by never calling
79*67e74705SXin Li // \c getNextToken() after it has encountered the first eof token.
80*67e74705SXin Li assert(!eof());
81*67e74705SXin Li Token = PreviousTokenSource->getNextToken();
82*67e74705SXin Li if (eof())
83*67e74705SXin Li return getFakeEOF();
84*67e74705SXin Li return Token;
85*67e74705SXin Li }
86*67e74705SXin Li
getPosition()87*67e74705SXin Li unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
88*67e74705SXin Li
setPosition(unsigned Position)89*67e74705SXin Li FormatToken *setPosition(unsigned Position) override {
90*67e74705SXin Li Token = PreviousTokenSource->setPosition(Position);
91*67e74705SXin Li return Token;
92*67e74705SXin Li }
93*67e74705SXin Li
94*67e74705SXin Li private:
eof()95*67e74705SXin Li bool eof() { return Token && Token->HasUnescapedNewline; }
96*67e74705SXin Li
getFakeEOF()97*67e74705SXin Li FormatToken *getFakeEOF() {
98*67e74705SXin Li static bool EOFInitialized = false;
99*67e74705SXin Li static FormatToken FormatTok;
100*67e74705SXin Li if (!EOFInitialized) {
101*67e74705SXin Li FormatTok.Tok.startToken();
102*67e74705SXin Li FormatTok.Tok.setKind(tok::eof);
103*67e74705SXin Li EOFInitialized = true;
104*67e74705SXin Li }
105*67e74705SXin Li return &FormatTok;
106*67e74705SXin Li }
107*67e74705SXin Li
108*67e74705SXin Li UnwrappedLine &Line;
109*67e74705SXin Li FormatTokenSource *&TokenSource;
110*67e74705SXin Li FormatToken *&ResetToken;
111*67e74705SXin Li unsigned PreviousLineLevel;
112*67e74705SXin Li FormatTokenSource *PreviousTokenSource;
113*67e74705SXin Li
114*67e74705SXin Li FormatToken *Token;
115*67e74705SXin Li };
116*67e74705SXin Li
117*67e74705SXin Li } // end anonymous namespace
118*67e74705SXin Li
119*67e74705SXin Li class ScopedLineState {
120*67e74705SXin Li public:
ScopedLineState(UnwrappedLineParser & Parser,bool SwitchToPreprocessorLines=false)121*67e74705SXin Li ScopedLineState(UnwrappedLineParser &Parser,
122*67e74705SXin Li bool SwitchToPreprocessorLines = false)
123*67e74705SXin Li : Parser(Parser), OriginalLines(Parser.CurrentLines) {
124*67e74705SXin Li if (SwitchToPreprocessorLines)
125*67e74705SXin Li Parser.CurrentLines = &Parser.PreprocessorDirectives;
126*67e74705SXin Li else if (!Parser.Line->Tokens.empty())
127*67e74705SXin Li Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
128*67e74705SXin Li PreBlockLine = std::move(Parser.Line);
129*67e74705SXin Li Parser.Line = llvm::make_unique<UnwrappedLine>();
130*67e74705SXin Li Parser.Line->Level = PreBlockLine->Level;
131*67e74705SXin Li Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
132*67e74705SXin Li }
133*67e74705SXin Li
~ScopedLineState()134*67e74705SXin Li ~ScopedLineState() {
135*67e74705SXin Li if (!Parser.Line->Tokens.empty()) {
136*67e74705SXin Li Parser.addUnwrappedLine();
137*67e74705SXin Li }
138*67e74705SXin Li assert(Parser.Line->Tokens.empty());
139*67e74705SXin Li Parser.Line = std::move(PreBlockLine);
140*67e74705SXin Li if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
141*67e74705SXin Li Parser.MustBreakBeforeNextToken = true;
142*67e74705SXin Li Parser.CurrentLines = OriginalLines;
143*67e74705SXin Li }
144*67e74705SXin Li
145*67e74705SXin Li private:
146*67e74705SXin Li UnwrappedLineParser &Parser;
147*67e74705SXin Li
148*67e74705SXin Li std::unique_ptr<UnwrappedLine> PreBlockLine;
149*67e74705SXin Li SmallVectorImpl<UnwrappedLine> *OriginalLines;
150*67e74705SXin Li };
151*67e74705SXin Li
152*67e74705SXin Li class CompoundStatementIndenter {
153*67e74705SXin Li public:
CompoundStatementIndenter(UnwrappedLineParser * Parser,const FormatStyle & Style,unsigned & LineLevel)154*67e74705SXin Li CompoundStatementIndenter(UnwrappedLineParser *Parser,
155*67e74705SXin Li const FormatStyle &Style, unsigned &LineLevel)
156*67e74705SXin Li : LineLevel(LineLevel), OldLineLevel(LineLevel) {
157*67e74705SXin Li if (Style.BraceWrapping.AfterControlStatement)
158*67e74705SXin Li Parser->addUnwrappedLine();
159*67e74705SXin Li if (Style.BraceWrapping.IndentBraces)
160*67e74705SXin Li ++LineLevel;
161*67e74705SXin Li }
~CompoundStatementIndenter()162*67e74705SXin Li ~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
163*67e74705SXin Li
164*67e74705SXin Li private:
165*67e74705SXin Li unsigned &LineLevel;
166*67e74705SXin Li unsigned OldLineLevel;
167*67e74705SXin Li };
168*67e74705SXin Li
169*67e74705SXin Li namespace {
170*67e74705SXin Li
171*67e74705SXin Li class IndexedTokenSource : public FormatTokenSource {
172*67e74705SXin Li public:
IndexedTokenSource(ArrayRef<FormatToken * > Tokens)173*67e74705SXin Li IndexedTokenSource(ArrayRef<FormatToken *> Tokens)
174*67e74705SXin Li : Tokens(Tokens), Position(-1) {}
175*67e74705SXin Li
getNextToken()176*67e74705SXin Li FormatToken *getNextToken() override {
177*67e74705SXin Li ++Position;
178*67e74705SXin Li return Tokens[Position];
179*67e74705SXin Li }
180*67e74705SXin Li
getPosition()181*67e74705SXin Li unsigned getPosition() override {
182*67e74705SXin Li assert(Position >= 0);
183*67e74705SXin Li return Position;
184*67e74705SXin Li }
185*67e74705SXin Li
setPosition(unsigned P)186*67e74705SXin Li FormatToken *setPosition(unsigned P) override {
187*67e74705SXin Li Position = P;
188*67e74705SXin Li return Tokens[Position];
189*67e74705SXin Li }
190*67e74705SXin Li
reset()191*67e74705SXin Li void reset() { Position = -1; }
192*67e74705SXin Li
193*67e74705SXin Li private:
194*67e74705SXin Li ArrayRef<FormatToken *> Tokens;
195*67e74705SXin Li int Position;
196*67e74705SXin Li };
197*67e74705SXin Li
198*67e74705SXin Li } // end anonymous namespace
199*67e74705SXin Li
UnwrappedLineParser(const FormatStyle & Style,const AdditionalKeywords & Keywords,ArrayRef<FormatToken * > Tokens,UnwrappedLineConsumer & Callback)200*67e74705SXin Li UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
201*67e74705SXin Li const AdditionalKeywords &Keywords,
202*67e74705SXin Li ArrayRef<FormatToken *> Tokens,
203*67e74705SXin Li UnwrappedLineConsumer &Callback)
204*67e74705SXin Li : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
205*67e74705SXin Li CurrentLines(&Lines), Style(Style), Keywords(Keywords), Tokens(nullptr),
206*67e74705SXin Li Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {}
207*67e74705SXin Li
reset()208*67e74705SXin Li void UnwrappedLineParser::reset() {
209*67e74705SXin Li PPBranchLevel = -1;
210*67e74705SXin Li Line.reset(new UnwrappedLine);
211*67e74705SXin Li CommentsBeforeNextToken.clear();
212*67e74705SXin Li FormatTok = nullptr;
213*67e74705SXin Li MustBreakBeforeNextToken = false;
214*67e74705SXin Li PreprocessorDirectives.clear();
215*67e74705SXin Li CurrentLines = &Lines;
216*67e74705SXin Li DeclarationScopeStack.clear();
217*67e74705SXin Li PPStack.clear();
218*67e74705SXin Li }
219*67e74705SXin Li
parse()220*67e74705SXin Li void UnwrappedLineParser::parse() {
221*67e74705SXin Li IndexedTokenSource TokenSource(AllTokens);
222*67e74705SXin Li do {
223*67e74705SXin Li DEBUG(llvm::dbgs() << "----\n");
224*67e74705SXin Li reset();
225*67e74705SXin Li Tokens = &TokenSource;
226*67e74705SXin Li TokenSource.reset();
227*67e74705SXin Li
228*67e74705SXin Li readToken();
229*67e74705SXin Li parseFile();
230*67e74705SXin Li // Create line with eof token.
231*67e74705SXin Li pushToken(FormatTok);
232*67e74705SXin Li addUnwrappedLine();
233*67e74705SXin Li
234*67e74705SXin Li for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(),
235*67e74705SXin Li E = Lines.end();
236*67e74705SXin Li I != E; ++I) {
237*67e74705SXin Li Callback.consumeUnwrappedLine(*I);
238*67e74705SXin Li }
239*67e74705SXin Li Callback.finishRun();
240*67e74705SXin Li Lines.clear();
241*67e74705SXin Li while (!PPLevelBranchIndex.empty() &&
242*67e74705SXin Li PPLevelBranchIndex.back() + 1 >= PPLevelBranchCount.back()) {
243*67e74705SXin Li PPLevelBranchIndex.resize(PPLevelBranchIndex.size() - 1);
244*67e74705SXin Li PPLevelBranchCount.resize(PPLevelBranchCount.size() - 1);
245*67e74705SXin Li }
246*67e74705SXin Li if (!PPLevelBranchIndex.empty()) {
247*67e74705SXin Li ++PPLevelBranchIndex.back();
248*67e74705SXin Li assert(PPLevelBranchIndex.size() == PPLevelBranchCount.size());
249*67e74705SXin Li assert(PPLevelBranchIndex.back() <= PPLevelBranchCount.back());
250*67e74705SXin Li }
251*67e74705SXin Li } while (!PPLevelBranchIndex.empty());
252*67e74705SXin Li }
253*67e74705SXin Li
parseFile()254*67e74705SXin Li void UnwrappedLineParser::parseFile() {
255*67e74705SXin Li // The top-level context in a file always has declarations, except for pre-
256*67e74705SXin Li // processor directives and JavaScript files.
257*67e74705SXin Li bool MustBeDeclaration =
258*67e74705SXin Li !Line->InPPDirective && Style.Language != FormatStyle::LK_JavaScript;
259*67e74705SXin Li ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
260*67e74705SXin Li MustBeDeclaration);
261*67e74705SXin Li parseLevel(/*HasOpeningBrace=*/false);
262*67e74705SXin Li // Make sure to format the remaining tokens.
263*67e74705SXin Li flushComments(true);
264*67e74705SXin Li addUnwrappedLine();
265*67e74705SXin Li }
266*67e74705SXin Li
parseLevel(bool HasOpeningBrace)267*67e74705SXin Li void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
268*67e74705SXin Li bool SwitchLabelEncountered = false;
269*67e74705SXin Li do {
270*67e74705SXin Li tok::TokenKind kind = FormatTok->Tok.getKind();
271*67e74705SXin Li if (FormatTok->Type == TT_MacroBlockBegin) {
272*67e74705SXin Li kind = tok::l_brace;
273*67e74705SXin Li } else if (FormatTok->Type == TT_MacroBlockEnd) {
274*67e74705SXin Li kind = tok::r_brace;
275*67e74705SXin Li }
276*67e74705SXin Li
277*67e74705SXin Li switch (kind) {
278*67e74705SXin Li case tok::comment:
279*67e74705SXin Li nextToken();
280*67e74705SXin Li addUnwrappedLine();
281*67e74705SXin Li break;
282*67e74705SXin Li case tok::l_brace:
283*67e74705SXin Li // FIXME: Add parameter whether this can happen - if this happens, we must
284*67e74705SXin Li // be in a non-declaration context.
285*67e74705SXin Li if (!FormatTok->is(TT_MacroBlockBegin) && tryToParseBracedList())
286*67e74705SXin Li continue;
287*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
288*67e74705SXin Li addUnwrappedLine();
289*67e74705SXin Li break;
290*67e74705SXin Li case tok::r_brace:
291*67e74705SXin Li if (HasOpeningBrace)
292*67e74705SXin Li return;
293*67e74705SXin Li nextToken();
294*67e74705SXin Li addUnwrappedLine();
295*67e74705SXin Li break;
296*67e74705SXin Li case tok::kw_default:
297*67e74705SXin Li case tok::kw_case:
298*67e74705SXin Li if (!SwitchLabelEncountered &&
299*67e74705SXin Li (Style.IndentCaseLabels || (Line->InPPDirective && Line->Level == 1)))
300*67e74705SXin Li ++Line->Level;
301*67e74705SXin Li SwitchLabelEncountered = true;
302*67e74705SXin Li parseStructuralElement();
303*67e74705SXin Li break;
304*67e74705SXin Li default:
305*67e74705SXin Li parseStructuralElement();
306*67e74705SXin Li break;
307*67e74705SXin Li }
308*67e74705SXin Li } while (!eof());
309*67e74705SXin Li }
310*67e74705SXin Li
calculateBraceTypes(bool ExpectClassBody)311*67e74705SXin Li void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
312*67e74705SXin Li // We'll parse forward through the tokens until we hit
313*67e74705SXin Li // a closing brace or eof - note that getNextToken() will
314*67e74705SXin Li // parse macros, so this will magically work inside macro
315*67e74705SXin Li // definitions, too.
316*67e74705SXin Li unsigned StoredPosition = Tokens->getPosition();
317*67e74705SXin Li FormatToken *Tok = FormatTok;
318*67e74705SXin Li const FormatToken *PrevTok = getPreviousToken();
319*67e74705SXin Li // Keep a stack of positions of lbrace tokens. We will
320*67e74705SXin Li // update information about whether an lbrace starts a
321*67e74705SXin Li // braced init list or a different block during the loop.
322*67e74705SXin Li SmallVector<FormatToken *, 8> LBraceStack;
323*67e74705SXin Li assert(Tok->Tok.is(tok::l_brace));
324*67e74705SXin Li do {
325*67e74705SXin Li // Get next non-comment token.
326*67e74705SXin Li FormatToken *NextTok;
327*67e74705SXin Li unsigned ReadTokens = 0;
328*67e74705SXin Li do {
329*67e74705SXin Li NextTok = Tokens->getNextToken();
330*67e74705SXin Li ++ReadTokens;
331*67e74705SXin Li } while (NextTok->is(tok::comment));
332*67e74705SXin Li
333*67e74705SXin Li switch (Tok->Tok.getKind()) {
334*67e74705SXin Li case tok::l_brace:
335*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
336*67e74705SXin Li PrevTok->is(tok::colon))
337*67e74705SXin Li // In TypeScript's TypeMemberLists, there can be semicolons between the
338*67e74705SXin Li // individual members.
339*67e74705SXin Li Tok->BlockKind = BK_BracedInit;
340*67e74705SXin Li else
341*67e74705SXin Li Tok->BlockKind = BK_Unknown;
342*67e74705SXin Li LBraceStack.push_back(Tok);
343*67e74705SXin Li break;
344*67e74705SXin Li case tok::r_brace:
345*67e74705SXin Li if (LBraceStack.empty())
346*67e74705SXin Li break;
347*67e74705SXin Li if (LBraceStack.back()->BlockKind == BK_Unknown) {
348*67e74705SXin Li bool ProbablyBracedList = false;
349*67e74705SXin Li if (Style.Language == FormatStyle::LK_Proto) {
350*67e74705SXin Li ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
351*67e74705SXin Li } else {
352*67e74705SXin Li // Using OriginalColumn to distinguish between ObjC methods and
353*67e74705SXin Li // binary operators is a bit hacky.
354*67e74705SXin Li bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
355*67e74705SXin Li NextTok->OriginalColumn == 0;
356*67e74705SXin Li
357*67e74705SXin Li // If there is a comma, semicolon or right paren after the closing
358*67e74705SXin Li // brace, we assume this is a braced initializer list. Note that
359*67e74705SXin Li // regardless how we mark inner braces here, we will overwrite the
360*67e74705SXin Li // BlockKind later if we parse a braced list (where all blocks
361*67e74705SXin Li // inside are by default braced lists), or when we explicitly detect
362*67e74705SXin Li // blocks (for example while parsing lambdas).
363*67e74705SXin Li //
364*67e74705SXin Li // We exclude + and - as they can be ObjC visibility modifiers.
365*67e74705SXin Li ProbablyBracedList =
366*67e74705SXin Li (Style.Language == FormatStyle::LK_JavaScript &&
367*67e74705SXin Li NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in)) ||
368*67e74705SXin Li NextTok->isOneOf(tok::comma, tok::period, tok::colon,
369*67e74705SXin Li tok::r_paren, tok::r_square, tok::l_brace,
370*67e74705SXin Li tok::l_square, tok::l_paren, tok::ellipsis) ||
371*67e74705SXin Li (NextTok->is(tok::semi) &&
372*67e74705SXin Li (!ExpectClassBody || LBraceStack.size() != 1)) ||
373*67e74705SXin Li (NextTok->isBinaryOperator() && !NextIsObjCMethod);
374*67e74705SXin Li }
375*67e74705SXin Li if (ProbablyBracedList) {
376*67e74705SXin Li Tok->BlockKind = BK_BracedInit;
377*67e74705SXin Li LBraceStack.back()->BlockKind = BK_BracedInit;
378*67e74705SXin Li } else {
379*67e74705SXin Li Tok->BlockKind = BK_Block;
380*67e74705SXin Li LBraceStack.back()->BlockKind = BK_Block;
381*67e74705SXin Li }
382*67e74705SXin Li }
383*67e74705SXin Li LBraceStack.pop_back();
384*67e74705SXin Li break;
385*67e74705SXin Li case tok::at:
386*67e74705SXin Li case tok::semi:
387*67e74705SXin Li case tok::kw_if:
388*67e74705SXin Li case tok::kw_while:
389*67e74705SXin Li case tok::kw_for:
390*67e74705SXin Li case tok::kw_switch:
391*67e74705SXin Li case tok::kw_try:
392*67e74705SXin Li case tok::kw___try:
393*67e74705SXin Li if (!LBraceStack.empty() && LBraceStack.back()->BlockKind == BK_Unknown)
394*67e74705SXin Li LBraceStack.back()->BlockKind = BK_Block;
395*67e74705SXin Li break;
396*67e74705SXin Li default:
397*67e74705SXin Li break;
398*67e74705SXin Li }
399*67e74705SXin Li PrevTok = Tok;
400*67e74705SXin Li Tok = NextTok;
401*67e74705SXin Li } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty());
402*67e74705SXin Li
403*67e74705SXin Li // Assume other blocks for all unclosed opening braces.
404*67e74705SXin Li for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) {
405*67e74705SXin Li if (LBraceStack[i]->BlockKind == BK_Unknown)
406*67e74705SXin Li LBraceStack[i]->BlockKind = BK_Block;
407*67e74705SXin Li }
408*67e74705SXin Li
409*67e74705SXin Li FormatTok = Tokens->setPosition(StoredPosition);
410*67e74705SXin Li }
411*67e74705SXin Li
parseBlock(bool MustBeDeclaration,bool AddLevel,bool MunchSemi)412*67e74705SXin Li void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel,
413*67e74705SXin Li bool MunchSemi) {
414*67e74705SXin Li assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) &&
415*67e74705SXin Li "'{' or macro block token expected");
416*67e74705SXin Li const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin);
417*67e74705SXin Li FormatTok->BlockKind = BK_Block;
418*67e74705SXin Li
419*67e74705SXin Li unsigned InitialLevel = Line->Level;
420*67e74705SXin Li nextToken();
421*67e74705SXin Li
422*67e74705SXin Li if (MacroBlock && FormatTok->is(tok::l_paren))
423*67e74705SXin Li parseParens();
424*67e74705SXin Li
425*67e74705SXin Li addUnwrappedLine();
426*67e74705SXin Li
427*67e74705SXin Li ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
428*67e74705SXin Li MustBeDeclaration);
429*67e74705SXin Li if (AddLevel)
430*67e74705SXin Li ++Line->Level;
431*67e74705SXin Li parseLevel(/*HasOpeningBrace=*/true);
432*67e74705SXin Li
433*67e74705SXin Li if (eof())
434*67e74705SXin Li return;
435*67e74705SXin Li
436*67e74705SXin Li if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd)
437*67e74705SXin Li : !FormatTok->is(tok::r_brace)) {
438*67e74705SXin Li Line->Level = InitialLevel;
439*67e74705SXin Li FormatTok->BlockKind = BK_Block;
440*67e74705SXin Li return;
441*67e74705SXin Li }
442*67e74705SXin Li
443*67e74705SXin Li nextToken(); // Munch the closing brace.
444*67e74705SXin Li
445*67e74705SXin Li if (MacroBlock && FormatTok->is(tok::l_paren))
446*67e74705SXin Li parseParens();
447*67e74705SXin Li
448*67e74705SXin Li if (MunchSemi && FormatTok->Tok.is(tok::semi))
449*67e74705SXin Li nextToken();
450*67e74705SXin Li Line->Level = InitialLevel;
451*67e74705SXin Li }
452*67e74705SXin Li
isGoogScope(const UnwrappedLine & Line)453*67e74705SXin Li static bool isGoogScope(const UnwrappedLine &Line) {
454*67e74705SXin Li // FIXME: Closure-library specific stuff should not be hard-coded but be
455*67e74705SXin Li // configurable.
456*67e74705SXin Li if (Line.Tokens.size() < 4)
457*67e74705SXin Li return false;
458*67e74705SXin Li auto I = Line.Tokens.begin();
459*67e74705SXin Li if (I->Tok->TokenText != "goog")
460*67e74705SXin Li return false;
461*67e74705SXin Li ++I;
462*67e74705SXin Li if (I->Tok->isNot(tok::period))
463*67e74705SXin Li return false;
464*67e74705SXin Li ++I;
465*67e74705SXin Li if (I->Tok->TokenText != "scope")
466*67e74705SXin Li return false;
467*67e74705SXin Li ++I;
468*67e74705SXin Li return I->Tok->is(tok::l_paren);
469*67e74705SXin Li }
470*67e74705SXin Li
ShouldBreakBeforeBrace(const FormatStyle & Style,const FormatToken & InitialToken)471*67e74705SXin Li static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
472*67e74705SXin Li const FormatToken &InitialToken) {
473*67e74705SXin Li if (InitialToken.is(tok::kw_namespace))
474*67e74705SXin Li return Style.BraceWrapping.AfterNamespace;
475*67e74705SXin Li if (InitialToken.is(tok::kw_class))
476*67e74705SXin Li return Style.BraceWrapping.AfterClass;
477*67e74705SXin Li if (InitialToken.is(tok::kw_union))
478*67e74705SXin Li return Style.BraceWrapping.AfterUnion;
479*67e74705SXin Li if (InitialToken.is(tok::kw_struct))
480*67e74705SXin Li return Style.BraceWrapping.AfterStruct;
481*67e74705SXin Li return false;
482*67e74705SXin Li }
483*67e74705SXin Li
parseChildBlock()484*67e74705SXin Li void UnwrappedLineParser::parseChildBlock() {
485*67e74705SXin Li FormatTok->BlockKind = BK_Block;
486*67e74705SXin Li nextToken();
487*67e74705SXin Li {
488*67e74705SXin Li bool GoogScope =
489*67e74705SXin Li Style.Language == FormatStyle::LK_JavaScript && isGoogScope(*Line);
490*67e74705SXin Li ScopedLineState LineState(*this);
491*67e74705SXin Li ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
492*67e74705SXin Li /*MustBeDeclaration=*/false);
493*67e74705SXin Li Line->Level += GoogScope ? 0 : 1;
494*67e74705SXin Li parseLevel(/*HasOpeningBrace=*/true);
495*67e74705SXin Li flushComments(isOnNewLine(*FormatTok));
496*67e74705SXin Li Line->Level -= GoogScope ? 0 : 1;
497*67e74705SXin Li }
498*67e74705SXin Li nextToken();
499*67e74705SXin Li }
500*67e74705SXin Li
parsePPDirective()501*67e74705SXin Li void UnwrappedLineParser::parsePPDirective() {
502*67e74705SXin Li assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
503*67e74705SXin Li ScopedMacroState MacroState(*Line, Tokens, FormatTok);
504*67e74705SXin Li nextToken();
505*67e74705SXin Li
506*67e74705SXin Li if (!FormatTok->Tok.getIdentifierInfo()) {
507*67e74705SXin Li parsePPUnknown();
508*67e74705SXin Li return;
509*67e74705SXin Li }
510*67e74705SXin Li
511*67e74705SXin Li switch (FormatTok->Tok.getIdentifierInfo()->getPPKeywordID()) {
512*67e74705SXin Li case tok::pp_define:
513*67e74705SXin Li parsePPDefine();
514*67e74705SXin Li return;
515*67e74705SXin Li case tok::pp_if:
516*67e74705SXin Li parsePPIf(/*IfDef=*/false);
517*67e74705SXin Li break;
518*67e74705SXin Li case tok::pp_ifdef:
519*67e74705SXin Li case tok::pp_ifndef:
520*67e74705SXin Li parsePPIf(/*IfDef=*/true);
521*67e74705SXin Li break;
522*67e74705SXin Li case tok::pp_else:
523*67e74705SXin Li parsePPElse();
524*67e74705SXin Li break;
525*67e74705SXin Li case tok::pp_elif:
526*67e74705SXin Li parsePPElIf();
527*67e74705SXin Li break;
528*67e74705SXin Li case tok::pp_endif:
529*67e74705SXin Li parsePPEndIf();
530*67e74705SXin Li break;
531*67e74705SXin Li default:
532*67e74705SXin Li parsePPUnknown();
533*67e74705SXin Li break;
534*67e74705SXin Li }
535*67e74705SXin Li }
536*67e74705SXin Li
conditionalCompilationCondition(bool Unreachable)537*67e74705SXin Li void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
538*67e74705SXin Li if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable))
539*67e74705SXin Li PPStack.push_back(PP_Unreachable);
540*67e74705SXin Li else
541*67e74705SXin Li PPStack.push_back(PP_Conditional);
542*67e74705SXin Li }
543*67e74705SXin Li
conditionalCompilationStart(bool Unreachable)544*67e74705SXin Li void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
545*67e74705SXin Li ++PPBranchLevel;
546*67e74705SXin Li assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
547*67e74705SXin Li if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
548*67e74705SXin Li PPLevelBranchIndex.push_back(0);
549*67e74705SXin Li PPLevelBranchCount.push_back(0);
550*67e74705SXin Li }
551*67e74705SXin Li PPChainBranchIndex.push(0);
552*67e74705SXin Li bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
553*67e74705SXin Li conditionalCompilationCondition(Unreachable || Skip);
554*67e74705SXin Li }
555*67e74705SXin Li
conditionalCompilationAlternative()556*67e74705SXin Li void UnwrappedLineParser::conditionalCompilationAlternative() {
557*67e74705SXin Li if (!PPStack.empty())
558*67e74705SXin Li PPStack.pop_back();
559*67e74705SXin Li assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
560*67e74705SXin Li if (!PPChainBranchIndex.empty())
561*67e74705SXin Li ++PPChainBranchIndex.top();
562*67e74705SXin Li conditionalCompilationCondition(
563*67e74705SXin Li PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
564*67e74705SXin Li PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
565*67e74705SXin Li }
566*67e74705SXin Li
conditionalCompilationEnd()567*67e74705SXin Li void UnwrappedLineParser::conditionalCompilationEnd() {
568*67e74705SXin Li assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
569*67e74705SXin Li if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
570*67e74705SXin Li if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
571*67e74705SXin Li PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
572*67e74705SXin Li }
573*67e74705SXin Li }
574*67e74705SXin Li // Guard against #endif's without #if.
575*67e74705SXin Li if (PPBranchLevel > 0)
576*67e74705SXin Li --PPBranchLevel;
577*67e74705SXin Li if (!PPChainBranchIndex.empty())
578*67e74705SXin Li PPChainBranchIndex.pop();
579*67e74705SXin Li if (!PPStack.empty())
580*67e74705SXin Li PPStack.pop_back();
581*67e74705SXin Li }
582*67e74705SXin Li
parsePPIf(bool IfDef)583*67e74705SXin Li void UnwrappedLineParser::parsePPIf(bool IfDef) {
584*67e74705SXin Li nextToken();
585*67e74705SXin Li bool IsLiteralFalse = (FormatTok->Tok.isLiteral() &&
586*67e74705SXin Li FormatTok->Tok.getLiteralData() != nullptr &&
587*67e74705SXin Li StringRef(FormatTok->Tok.getLiteralData(),
588*67e74705SXin Li FormatTok->Tok.getLength()) == "0") ||
589*67e74705SXin Li FormatTok->Tok.is(tok::kw_false);
590*67e74705SXin Li conditionalCompilationStart(!IfDef && IsLiteralFalse);
591*67e74705SXin Li parsePPUnknown();
592*67e74705SXin Li }
593*67e74705SXin Li
parsePPElse()594*67e74705SXin Li void UnwrappedLineParser::parsePPElse() {
595*67e74705SXin Li conditionalCompilationAlternative();
596*67e74705SXin Li parsePPUnknown();
597*67e74705SXin Li }
598*67e74705SXin Li
parsePPElIf()599*67e74705SXin Li void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
600*67e74705SXin Li
parsePPEndIf()601*67e74705SXin Li void UnwrappedLineParser::parsePPEndIf() {
602*67e74705SXin Li conditionalCompilationEnd();
603*67e74705SXin Li parsePPUnknown();
604*67e74705SXin Li }
605*67e74705SXin Li
parsePPDefine()606*67e74705SXin Li void UnwrappedLineParser::parsePPDefine() {
607*67e74705SXin Li nextToken();
608*67e74705SXin Li
609*67e74705SXin Li if (FormatTok->Tok.getKind() != tok::identifier) {
610*67e74705SXin Li parsePPUnknown();
611*67e74705SXin Li return;
612*67e74705SXin Li }
613*67e74705SXin Li nextToken();
614*67e74705SXin Li if (FormatTok->Tok.getKind() == tok::l_paren &&
615*67e74705SXin Li FormatTok->WhitespaceRange.getBegin() ==
616*67e74705SXin Li FormatTok->WhitespaceRange.getEnd()) {
617*67e74705SXin Li parseParens();
618*67e74705SXin Li }
619*67e74705SXin Li addUnwrappedLine();
620*67e74705SXin Li Line->Level = 1;
621*67e74705SXin Li
622*67e74705SXin Li // Errors during a preprocessor directive can only affect the layout of the
623*67e74705SXin Li // preprocessor directive, and thus we ignore them. An alternative approach
624*67e74705SXin Li // would be to use the same approach we use on the file level (no
625*67e74705SXin Li // re-indentation if there was a structural error) within the macro
626*67e74705SXin Li // definition.
627*67e74705SXin Li parseFile();
628*67e74705SXin Li }
629*67e74705SXin Li
parsePPUnknown()630*67e74705SXin Li void UnwrappedLineParser::parsePPUnknown() {
631*67e74705SXin Li do {
632*67e74705SXin Li nextToken();
633*67e74705SXin Li } while (!eof());
634*67e74705SXin Li addUnwrappedLine();
635*67e74705SXin Li }
636*67e74705SXin Li
637*67e74705SXin Li // Here we blacklist certain tokens that are not usually the first token in an
638*67e74705SXin Li // unwrapped line. This is used in attempt to distinguish macro calls without
639*67e74705SXin Li // trailing semicolons from other constructs split to several lines.
tokenCanStartNewLine(const clang::Token & Tok)640*67e74705SXin Li static bool tokenCanStartNewLine(const clang::Token &Tok) {
641*67e74705SXin Li // Semicolon can be a null-statement, l_square can be a start of a macro or
642*67e74705SXin Li // a C++11 attribute, but this doesn't seem to be common.
643*67e74705SXin Li return Tok.isNot(tok::semi) && Tok.isNot(tok::l_brace) &&
644*67e74705SXin Li Tok.isNot(tok::l_square) &&
645*67e74705SXin Li // Tokens that can only be used as binary operators and a part of
646*67e74705SXin Li // overloaded operator names.
647*67e74705SXin Li Tok.isNot(tok::period) && Tok.isNot(tok::periodstar) &&
648*67e74705SXin Li Tok.isNot(tok::arrow) && Tok.isNot(tok::arrowstar) &&
649*67e74705SXin Li Tok.isNot(tok::less) && Tok.isNot(tok::greater) &&
650*67e74705SXin Li Tok.isNot(tok::slash) && Tok.isNot(tok::percent) &&
651*67e74705SXin Li Tok.isNot(tok::lessless) && Tok.isNot(tok::greatergreater) &&
652*67e74705SXin Li Tok.isNot(tok::equal) && Tok.isNot(tok::plusequal) &&
653*67e74705SXin Li Tok.isNot(tok::minusequal) && Tok.isNot(tok::starequal) &&
654*67e74705SXin Li Tok.isNot(tok::slashequal) && Tok.isNot(tok::percentequal) &&
655*67e74705SXin Li Tok.isNot(tok::ampequal) && Tok.isNot(tok::pipeequal) &&
656*67e74705SXin Li Tok.isNot(tok::caretequal) && Tok.isNot(tok::greatergreaterequal) &&
657*67e74705SXin Li Tok.isNot(tok::lesslessequal) &&
658*67e74705SXin Li // Colon is used in labels, base class lists, initializer lists,
659*67e74705SXin Li // range-based for loops, ternary operator, but should never be the
660*67e74705SXin Li // first token in an unwrapped line.
661*67e74705SXin Li Tok.isNot(tok::colon) &&
662*67e74705SXin Li // 'noexcept' is a trailing annotation.
663*67e74705SXin Li Tok.isNot(tok::kw_noexcept);
664*67e74705SXin Li }
665*67e74705SXin Li
mustBeJSIdent(const AdditionalKeywords & Keywords,const FormatToken * FormatTok)666*67e74705SXin Li static bool mustBeJSIdent(const AdditionalKeywords &Keywords,
667*67e74705SXin Li const FormatToken *FormatTok) {
668*67e74705SXin Li // FIXME: This returns true for C/C++ keywords like 'struct'.
669*67e74705SXin Li return FormatTok->is(tok::identifier) &&
670*67e74705SXin Li (FormatTok->Tok.getIdentifierInfo() == nullptr ||
671*67e74705SXin Li !FormatTok->isOneOf(Keywords.kw_in, Keywords.kw_of, Keywords.kw_as,
672*67e74705SXin Li Keywords.kw_async, Keywords.kw_await,
673*67e74705SXin Li Keywords.kw_yield, Keywords.kw_finally,
674*67e74705SXin Li Keywords.kw_function, Keywords.kw_import,
675*67e74705SXin Li Keywords.kw_is, Keywords.kw_let, Keywords.kw_var,
676*67e74705SXin Li Keywords.kw_abstract, Keywords.kw_extends,
677*67e74705SXin Li Keywords.kw_implements, Keywords.kw_instanceof,
678*67e74705SXin Li Keywords.kw_interface, Keywords.kw_throws));
679*67e74705SXin Li }
680*67e74705SXin Li
mustBeJSIdentOrValue(const AdditionalKeywords & Keywords,const FormatToken * FormatTok)681*67e74705SXin Li static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords,
682*67e74705SXin Li const FormatToken *FormatTok) {
683*67e74705SXin Li return FormatTok->Tok.isLiteral() || mustBeJSIdent(Keywords, FormatTok);
684*67e74705SXin Li }
685*67e74705SXin Li
686*67e74705SXin Li // isJSDeclOrStmt returns true if |FormatTok| starts a declaration or statement
687*67e74705SXin Li // when encountered after a value (see mustBeJSIdentOrValue).
isJSDeclOrStmt(const AdditionalKeywords & Keywords,const FormatToken * FormatTok)688*67e74705SXin Li static bool isJSDeclOrStmt(const AdditionalKeywords &Keywords,
689*67e74705SXin Li const FormatToken *FormatTok) {
690*67e74705SXin Li return FormatTok->isOneOf(
691*67e74705SXin Li tok::kw_return, Keywords.kw_yield,
692*67e74705SXin Li // conditionals
693*67e74705SXin Li tok::kw_if, tok::kw_else,
694*67e74705SXin Li // loops
695*67e74705SXin Li tok::kw_for, tok::kw_while, tok::kw_do, tok::kw_continue, tok::kw_break,
696*67e74705SXin Li // switch/case
697*67e74705SXin Li tok::kw_switch, tok::kw_case,
698*67e74705SXin Li // exceptions
699*67e74705SXin Li tok::kw_throw, tok::kw_try, tok::kw_catch, Keywords.kw_finally,
700*67e74705SXin Li // declaration
701*67e74705SXin Li tok::kw_const, tok::kw_class, Keywords.kw_var, Keywords.kw_let,
702*67e74705SXin Li Keywords.kw_async, Keywords.kw_function,
703*67e74705SXin Li // import/export
704*67e74705SXin Li Keywords.kw_import, tok::kw_export);
705*67e74705SXin Li }
706*67e74705SXin Li
707*67e74705SXin Li // readTokenWithJavaScriptASI reads the next token and terminates the current
708*67e74705SXin Li // line if JavaScript Automatic Semicolon Insertion must
709*67e74705SXin Li // happen between the current token and the next token.
710*67e74705SXin Li //
711*67e74705SXin Li // This method is conservative - it cannot cover all edge cases of JavaScript,
712*67e74705SXin Li // but only aims to correctly handle certain well known cases. It *must not*
713*67e74705SXin Li // return true in speculative cases.
readTokenWithJavaScriptASI()714*67e74705SXin Li void UnwrappedLineParser::readTokenWithJavaScriptASI() {
715*67e74705SXin Li FormatToken *Previous = FormatTok;
716*67e74705SXin Li readToken();
717*67e74705SXin Li FormatToken *Next = FormatTok;
718*67e74705SXin Li
719*67e74705SXin Li bool IsOnSameLine =
720*67e74705SXin Li CommentsBeforeNextToken.empty()
721*67e74705SXin Li ? Next->NewlinesBefore == 0
722*67e74705SXin Li : CommentsBeforeNextToken.front()->NewlinesBefore == 0;
723*67e74705SXin Li if (IsOnSameLine)
724*67e74705SXin Li return;
725*67e74705SXin Li
726*67e74705SXin Li bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous);
727*67e74705SXin Li if (PreviousMustBeValue && Line && Line->Tokens.size() > 1) {
728*67e74705SXin Li // If the token before the previous one is an '@', the previous token is an
729*67e74705SXin Li // annotation and can precede another identifier/value.
730*67e74705SXin Li const FormatToken *PrePrevious = std::prev(Line->Tokens.end(), 2)->Tok;
731*67e74705SXin Li if (PrePrevious->is(tok::at))
732*67e74705SXin Li return;
733*67e74705SXin Li }
734*67e74705SXin Li if (Next->is(tok::exclaim) && PreviousMustBeValue)
735*67e74705SXin Li addUnwrappedLine();
736*67e74705SXin Li bool NextMustBeValue = mustBeJSIdentOrValue(Keywords, Next);
737*67e74705SXin Li if (NextMustBeValue && (PreviousMustBeValue ||
738*67e74705SXin Li Previous->isOneOf(tok::r_square, tok::r_paren,
739*67e74705SXin Li tok::plusplus, tok::minusminus)))
740*67e74705SXin Li addUnwrappedLine();
741*67e74705SXin Li if (PreviousMustBeValue && isJSDeclOrStmt(Keywords, Next))
742*67e74705SXin Li addUnwrappedLine();
743*67e74705SXin Li }
744*67e74705SXin Li
parseStructuralElement()745*67e74705SXin Li void UnwrappedLineParser::parseStructuralElement() {
746*67e74705SXin Li assert(!FormatTok->is(tok::l_brace));
747*67e74705SXin Li if (Style.Language == FormatStyle::LK_TableGen &&
748*67e74705SXin Li FormatTok->is(tok::pp_include)) {
749*67e74705SXin Li nextToken();
750*67e74705SXin Li if (FormatTok->is(tok::string_literal))
751*67e74705SXin Li nextToken();
752*67e74705SXin Li addUnwrappedLine();
753*67e74705SXin Li return;
754*67e74705SXin Li }
755*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
756*67e74705SXin Li case tok::at:
757*67e74705SXin Li nextToken();
758*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
759*67e74705SXin Li parseBracedList();
760*67e74705SXin Li break;
761*67e74705SXin Li }
762*67e74705SXin Li switch (FormatTok->Tok.getObjCKeywordID()) {
763*67e74705SXin Li case tok::objc_public:
764*67e74705SXin Li case tok::objc_protected:
765*67e74705SXin Li case tok::objc_package:
766*67e74705SXin Li case tok::objc_private:
767*67e74705SXin Li return parseAccessSpecifier();
768*67e74705SXin Li case tok::objc_interface:
769*67e74705SXin Li case tok::objc_implementation:
770*67e74705SXin Li return parseObjCInterfaceOrImplementation();
771*67e74705SXin Li case tok::objc_protocol:
772*67e74705SXin Li return parseObjCProtocol();
773*67e74705SXin Li case tok::objc_end:
774*67e74705SXin Li return; // Handled by the caller.
775*67e74705SXin Li case tok::objc_optional:
776*67e74705SXin Li case tok::objc_required:
777*67e74705SXin Li nextToken();
778*67e74705SXin Li addUnwrappedLine();
779*67e74705SXin Li return;
780*67e74705SXin Li case tok::objc_autoreleasepool:
781*67e74705SXin Li nextToken();
782*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
783*67e74705SXin Li if (Style.BraceWrapping.AfterObjCDeclaration)
784*67e74705SXin Li addUnwrappedLine();
785*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
786*67e74705SXin Li }
787*67e74705SXin Li addUnwrappedLine();
788*67e74705SXin Li return;
789*67e74705SXin Li case tok::objc_try:
790*67e74705SXin Li // This branch isn't strictly necessary (the kw_try case below would
791*67e74705SXin Li // do this too after the tok::at is parsed above). But be explicit.
792*67e74705SXin Li parseTryCatch();
793*67e74705SXin Li return;
794*67e74705SXin Li default:
795*67e74705SXin Li break;
796*67e74705SXin Li }
797*67e74705SXin Li break;
798*67e74705SXin Li case tok::kw_asm:
799*67e74705SXin Li nextToken();
800*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
801*67e74705SXin Li FormatTok->Type = TT_InlineASMBrace;
802*67e74705SXin Li nextToken();
803*67e74705SXin Li while (FormatTok && FormatTok->isNot(tok::eof)) {
804*67e74705SXin Li if (FormatTok->is(tok::r_brace)) {
805*67e74705SXin Li FormatTok->Type = TT_InlineASMBrace;
806*67e74705SXin Li nextToken();
807*67e74705SXin Li addUnwrappedLine();
808*67e74705SXin Li break;
809*67e74705SXin Li }
810*67e74705SXin Li FormatTok->Finalized = true;
811*67e74705SXin Li nextToken();
812*67e74705SXin Li }
813*67e74705SXin Li }
814*67e74705SXin Li break;
815*67e74705SXin Li case tok::kw_namespace:
816*67e74705SXin Li parseNamespace();
817*67e74705SXin Li return;
818*67e74705SXin Li case tok::kw_inline:
819*67e74705SXin Li nextToken();
820*67e74705SXin Li if (FormatTok->Tok.is(tok::kw_namespace)) {
821*67e74705SXin Li parseNamespace();
822*67e74705SXin Li return;
823*67e74705SXin Li }
824*67e74705SXin Li break;
825*67e74705SXin Li case tok::kw_public:
826*67e74705SXin Li case tok::kw_protected:
827*67e74705SXin Li case tok::kw_private:
828*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java ||
829*67e74705SXin Li Style.Language == FormatStyle::LK_JavaScript)
830*67e74705SXin Li nextToken();
831*67e74705SXin Li else
832*67e74705SXin Li parseAccessSpecifier();
833*67e74705SXin Li return;
834*67e74705SXin Li case tok::kw_if:
835*67e74705SXin Li parseIfThenElse();
836*67e74705SXin Li return;
837*67e74705SXin Li case tok::kw_for:
838*67e74705SXin Li case tok::kw_while:
839*67e74705SXin Li parseForOrWhileLoop();
840*67e74705SXin Li return;
841*67e74705SXin Li case tok::kw_do:
842*67e74705SXin Li parseDoWhile();
843*67e74705SXin Li return;
844*67e74705SXin Li case tok::kw_switch:
845*67e74705SXin Li parseSwitch();
846*67e74705SXin Li return;
847*67e74705SXin Li case tok::kw_default:
848*67e74705SXin Li nextToken();
849*67e74705SXin Li parseLabel();
850*67e74705SXin Li return;
851*67e74705SXin Li case tok::kw_case:
852*67e74705SXin Li parseCaseLabel();
853*67e74705SXin Li return;
854*67e74705SXin Li case tok::kw_try:
855*67e74705SXin Li case tok::kw___try:
856*67e74705SXin Li parseTryCatch();
857*67e74705SXin Li return;
858*67e74705SXin Li case tok::kw_extern:
859*67e74705SXin Li nextToken();
860*67e74705SXin Li if (FormatTok->Tok.is(tok::string_literal)) {
861*67e74705SXin Li nextToken();
862*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
863*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
864*67e74705SXin Li addUnwrappedLine();
865*67e74705SXin Li return;
866*67e74705SXin Li }
867*67e74705SXin Li }
868*67e74705SXin Li break;
869*67e74705SXin Li case tok::kw_export:
870*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
871*67e74705SXin Li parseJavaScriptEs6ImportExport();
872*67e74705SXin Li return;
873*67e74705SXin Li }
874*67e74705SXin Li break;
875*67e74705SXin Li case tok::identifier:
876*67e74705SXin Li if (FormatTok->is(TT_ForEachMacro)) {
877*67e74705SXin Li parseForOrWhileLoop();
878*67e74705SXin Li return;
879*67e74705SXin Li }
880*67e74705SXin Li if (FormatTok->is(TT_MacroBlockBegin)) {
881*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false, /*AddLevel=*/true,
882*67e74705SXin Li /*MunchSemi=*/false);
883*67e74705SXin Li return;
884*67e74705SXin Li }
885*67e74705SXin Li if (FormatTok->is(Keywords.kw_import)) {
886*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
887*67e74705SXin Li parseJavaScriptEs6ImportExport();
888*67e74705SXin Li return;
889*67e74705SXin Li }
890*67e74705SXin Li if (Style.Language == FormatStyle::LK_Proto) {
891*67e74705SXin Li nextToken();
892*67e74705SXin Li if (FormatTok->is(tok::kw_public))
893*67e74705SXin Li nextToken();
894*67e74705SXin Li if (!FormatTok->is(tok::string_literal))
895*67e74705SXin Li return;
896*67e74705SXin Li nextToken();
897*67e74705SXin Li if (FormatTok->is(tok::semi))
898*67e74705SXin Li nextToken();
899*67e74705SXin Li addUnwrappedLine();
900*67e74705SXin Li return;
901*67e74705SXin Li }
902*67e74705SXin Li }
903*67e74705SXin Li if (FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
904*67e74705SXin Li Keywords.kw_slots, Keywords.kw_qslots)) {
905*67e74705SXin Li nextToken();
906*67e74705SXin Li if (FormatTok->is(tok::colon)) {
907*67e74705SXin Li nextToken();
908*67e74705SXin Li addUnwrappedLine();
909*67e74705SXin Li }
910*67e74705SXin Li return;
911*67e74705SXin Li }
912*67e74705SXin Li // In all other cases, parse the declaration.
913*67e74705SXin Li break;
914*67e74705SXin Li default:
915*67e74705SXin Li break;
916*67e74705SXin Li }
917*67e74705SXin Li do {
918*67e74705SXin Li const FormatToken *Previous = getPreviousToken();
919*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
920*67e74705SXin Li case tok::at:
921*67e74705SXin Li nextToken();
922*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace))
923*67e74705SXin Li parseBracedList();
924*67e74705SXin Li break;
925*67e74705SXin Li case tok::kw_enum:
926*67e74705SXin Li // Ignore if this is part of "template <enum ...".
927*67e74705SXin Li if (Previous && Previous->is(tok::less)) {
928*67e74705SXin Li nextToken();
929*67e74705SXin Li break;
930*67e74705SXin Li }
931*67e74705SXin Li
932*67e74705SXin Li // parseEnum falls through and does not yet add an unwrapped line as an
933*67e74705SXin Li // enum definition can start a structural element.
934*67e74705SXin Li if (!parseEnum())
935*67e74705SXin Li break;
936*67e74705SXin Li // This only applies for C++.
937*67e74705SXin Li if (Style.Language != FormatStyle::LK_Cpp) {
938*67e74705SXin Li addUnwrappedLine();
939*67e74705SXin Li return;
940*67e74705SXin Li }
941*67e74705SXin Li break;
942*67e74705SXin Li case tok::kw_typedef:
943*67e74705SXin Li nextToken();
944*67e74705SXin Li if (FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
945*67e74705SXin Li Keywords.kw_CF_ENUM, Keywords.kw_CF_OPTIONS))
946*67e74705SXin Li parseEnum();
947*67e74705SXin Li break;
948*67e74705SXin Li case tok::kw_struct:
949*67e74705SXin Li case tok::kw_union:
950*67e74705SXin Li case tok::kw_class:
951*67e74705SXin Li // parseRecord falls through and does not yet add an unwrapped line as a
952*67e74705SXin Li // record declaration or definition can start a structural element.
953*67e74705SXin Li parseRecord();
954*67e74705SXin Li // This does not apply for Java and JavaScript.
955*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java ||
956*67e74705SXin Li Style.Language == FormatStyle::LK_JavaScript) {
957*67e74705SXin Li if (FormatTok->is(tok::semi))
958*67e74705SXin Li nextToken();
959*67e74705SXin Li addUnwrappedLine();
960*67e74705SXin Li return;
961*67e74705SXin Li }
962*67e74705SXin Li break;
963*67e74705SXin Li case tok::period:
964*67e74705SXin Li nextToken();
965*67e74705SXin Li // In Java, classes have an implicit static member "class".
966*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java && FormatTok &&
967*67e74705SXin Li FormatTok->is(tok::kw_class))
968*67e74705SXin Li nextToken();
969*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript && FormatTok &&
970*67e74705SXin Li FormatTok->Tok.getIdentifierInfo())
971*67e74705SXin Li // JavaScript only has pseudo keywords, all keywords are allowed to
972*67e74705SXin Li // appear in "IdentifierName" positions. See http://es5.github.io/#x7.6
973*67e74705SXin Li nextToken();
974*67e74705SXin Li break;
975*67e74705SXin Li case tok::semi:
976*67e74705SXin Li nextToken();
977*67e74705SXin Li addUnwrappedLine();
978*67e74705SXin Li return;
979*67e74705SXin Li case tok::r_brace:
980*67e74705SXin Li addUnwrappedLine();
981*67e74705SXin Li return;
982*67e74705SXin Li case tok::l_paren:
983*67e74705SXin Li parseParens();
984*67e74705SXin Li break;
985*67e74705SXin Li case tok::kw_operator:
986*67e74705SXin Li nextToken();
987*67e74705SXin Li if (FormatTok->isBinaryOperator())
988*67e74705SXin Li nextToken();
989*67e74705SXin Li break;
990*67e74705SXin Li case tok::caret:
991*67e74705SXin Li nextToken();
992*67e74705SXin Li if (FormatTok->Tok.isAnyIdentifier() ||
993*67e74705SXin Li FormatTok->isSimpleTypeSpecifier())
994*67e74705SXin Li nextToken();
995*67e74705SXin Li if (FormatTok->is(tok::l_paren))
996*67e74705SXin Li parseParens();
997*67e74705SXin Li if (FormatTok->is(tok::l_brace))
998*67e74705SXin Li parseChildBlock();
999*67e74705SXin Li break;
1000*67e74705SXin Li case tok::l_brace:
1001*67e74705SXin Li if (!tryToParseBracedList()) {
1002*67e74705SXin Li // A block outside of parentheses must be the last part of a
1003*67e74705SXin Li // structural element.
1004*67e74705SXin Li // FIXME: Figure out cases where this is not true, and add projections
1005*67e74705SXin Li // for them (the one we know is missing are lambdas).
1006*67e74705SXin Li if (Style.BraceWrapping.AfterFunction)
1007*67e74705SXin Li addUnwrappedLine();
1008*67e74705SXin Li FormatTok->Type = TT_FunctionLBrace;
1009*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1010*67e74705SXin Li addUnwrappedLine();
1011*67e74705SXin Li return;
1012*67e74705SXin Li }
1013*67e74705SXin Li // Otherwise this was a braced init list, and the structural
1014*67e74705SXin Li // element continues.
1015*67e74705SXin Li break;
1016*67e74705SXin Li case tok::kw_try:
1017*67e74705SXin Li // We arrive here when parsing function-try blocks.
1018*67e74705SXin Li parseTryCatch();
1019*67e74705SXin Li return;
1020*67e74705SXin Li case tok::identifier: {
1021*67e74705SXin Li if (FormatTok->is(TT_MacroBlockEnd)) {
1022*67e74705SXin Li addUnwrappedLine();
1023*67e74705SXin Li return;
1024*67e74705SXin Li }
1025*67e74705SXin Li
1026*67e74705SXin Li // Parse function literal unless 'function' is the first token in a line
1027*67e74705SXin Li // in which case this should be treated as a free-standing function.
1028*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript &&
1029*67e74705SXin Li (FormatTok->is(Keywords.kw_function) ||
1030*67e74705SXin Li FormatTok->startsSequence(Keywords.kw_async,
1031*67e74705SXin Li Keywords.kw_function)) &&
1032*67e74705SXin Li Line->Tokens.size() > 0) {
1033*67e74705SXin Li tryToParseJSFunction();
1034*67e74705SXin Li break;
1035*67e74705SXin Li }
1036*67e74705SXin Li if ((Style.Language == FormatStyle::LK_JavaScript ||
1037*67e74705SXin Li Style.Language == FormatStyle::LK_Java) &&
1038*67e74705SXin Li FormatTok->is(Keywords.kw_interface)) {
1039*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
1040*67e74705SXin Li // In JavaScript/TypeScript, "interface" can be used as a standalone
1041*67e74705SXin Li // identifier, e.g. in `var interface = 1;`. If "interface" is
1042*67e74705SXin Li // followed by another identifier, it is very like to be an actual
1043*67e74705SXin Li // interface declaration.
1044*67e74705SXin Li unsigned StoredPosition = Tokens->getPosition();
1045*67e74705SXin Li FormatToken *Next = Tokens->getNextToken();
1046*67e74705SXin Li FormatTok = Tokens->setPosition(StoredPosition);
1047*67e74705SXin Li if (Next && !mustBeJSIdent(Keywords, Next)) {
1048*67e74705SXin Li nextToken();
1049*67e74705SXin Li break;
1050*67e74705SXin Li }
1051*67e74705SXin Li }
1052*67e74705SXin Li parseRecord();
1053*67e74705SXin Li addUnwrappedLine();
1054*67e74705SXin Li return;
1055*67e74705SXin Li }
1056*67e74705SXin Li
1057*67e74705SXin Li // See if the following token should start a new unwrapped line.
1058*67e74705SXin Li StringRef Text = FormatTok->TokenText;
1059*67e74705SXin Li nextToken();
1060*67e74705SXin Li if (Line->Tokens.size() == 1 &&
1061*67e74705SXin Li // JS doesn't have macros, and within classes colons indicate fields,
1062*67e74705SXin Li // not labels.
1063*67e74705SXin Li Style.Language != FormatStyle::LK_JavaScript) {
1064*67e74705SXin Li if (FormatTok->Tok.is(tok::colon) && !Line->MustBeDeclaration) {
1065*67e74705SXin Li Line->Tokens.begin()->Tok->MustBreakBefore = true;
1066*67e74705SXin Li parseLabel();
1067*67e74705SXin Li return;
1068*67e74705SXin Li }
1069*67e74705SXin Li // Recognize function-like macro usages without trailing semicolon as
1070*67e74705SXin Li // well as free-standing macros like Q_OBJECT.
1071*67e74705SXin Li bool FunctionLike = FormatTok->is(tok::l_paren);
1072*67e74705SXin Li if (FunctionLike)
1073*67e74705SXin Li parseParens();
1074*67e74705SXin Li
1075*67e74705SXin Li bool FollowedByNewline =
1076*67e74705SXin Li CommentsBeforeNextToken.empty()
1077*67e74705SXin Li ? FormatTok->NewlinesBefore > 0
1078*67e74705SXin Li : CommentsBeforeNextToken.front()->NewlinesBefore > 0;
1079*67e74705SXin Li
1080*67e74705SXin Li if (FollowedByNewline && (Text.size() >= 5 || FunctionLike) &&
1081*67e74705SXin Li tokenCanStartNewLine(FormatTok->Tok) && Text == Text.upper()) {
1082*67e74705SXin Li addUnwrappedLine();
1083*67e74705SXin Li return;
1084*67e74705SXin Li }
1085*67e74705SXin Li }
1086*67e74705SXin Li break;
1087*67e74705SXin Li }
1088*67e74705SXin Li case tok::equal:
1089*67e74705SXin Li // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType
1090*67e74705SXin Li // TT_JsFatArrow. The always start an expression or a child block if
1091*67e74705SXin Li // followed by a curly.
1092*67e74705SXin Li if (FormatTok->is(TT_JsFatArrow)) {
1093*67e74705SXin Li nextToken();
1094*67e74705SXin Li if (FormatTok->is(tok::l_brace))
1095*67e74705SXin Li parseChildBlock();
1096*67e74705SXin Li break;
1097*67e74705SXin Li }
1098*67e74705SXin Li
1099*67e74705SXin Li nextToken();
1100*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1101*67e74705SXin Li parseBracedList();
1102*67e74705SXin Li }
1103*67e74705SXin Li break;
1104*67e74705SXin Li case tok::l_square:
1105*67e74705SXin Li parseSquare();
1106*67e74705SXin Li break;
1107*67e74705SXin Li case tok::kw_new:
1108*67e74705SXin Li parseNew();
1109*67e74705SXin Li break;
1110*67e74705SXin Li default:
1111*67e74705SXin Li nextToken();
1112*67e74705SXin Li break;
1113*67e74705SXin Li }
1114*67e74705SXin Li } while (!eof());
1115*67e74705SXin Li }
1116*67e74705SXin Li
tryToParseLambda()1117*67e74705SXin Li bool UnwrappedLineParser::tryToParseLambda() {
1118*67e74705SXin Li if (Style.Language != FormatStyle::LK_Cpp) {
1119*67e74705SXin Li nextToken();
1120*67e74705SXin Li return false;
1121*67e74705SXin Li }
1122*67e74705SXin Li const FormatToken* Previous = getPreviousToken();
1123*67e74705SXin Li if (Previous &&
1124*67e74705SXin Li (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
1125*67e74705SXin Li tok::kw_delete) ||
1126*67e74705SXin Li Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
1127*67e74705SXin Li nextToken();
1128*67e74705SXin Li return false;
1129*67e74705SXin Li }
1130*67e74705SXin Li assert(FormatTok->is(tok::l_square));
1131*67e74705SXin Li FormatToken &LSquare = *FormatTok;
1132*67e74705SXin Li if (!tryToParseLambdaIntroducer())
1133*67e74705SXin Li return false;
1134*67e74705SXin Li
1135*67e74705SXin Li while (FormatTok->isNot(tok::l_brace)) {
1136*67e74705SXin Li if (FormatTok->isSimpleTypeSpecifier()) {
1137*67e74705SXin Li nextToken();
1138*67e74705SXin Li continue;
1139*67e74705SXin Li }
1140*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
1141*67e74705SXin Li case tok::l_brace:
1142*67e74705SXin Li break;
1143*67e74705SXin Li case tok::l_paren:
1144*67e74705SXin Li parseParens();
1145*67e74705SXin Li break;
1146*67e74705SXin Li case tok::amp:
1147*67e74705SXin Li case tok::star:
1148*67e74705SXin Li case tok::kw_const:
1149*67e74705SXin Li case tok::comma:
1150*67e74705SXin Li case tok::less:
1151*67e74705SXin Li case tok::greater:
1152*67e74705SXin Li case tok::identifier:
1153*67e74705SXin Li case tok::numeric_constant:
1154*67e74705SXin Li case tok::coloncolon:
1155*67e74705SXin Li case tok::kw_mutable:
1156*67e74705SXin Li nextToken();
1157*67e74705SXin Li break;
1158*67e74705SXin Li case tok::arrow:
1159*67e74705SXin Li FormatTok->Type = TT_LambdaArrow;
1160*67e74705SXin Li nextToken();
1161*67e74705SXin Li break;
1162*67e74705SXin Li default:
1163*67e74705SXin Li return true;
1164*67e74705SXin Li }
1165*67e74705SXin Li }
1166*67e74705SXin Li LSquare.Type = TT_LambdaLSquare;
1167*67e74705SXin Li parseChildBlock();
1168*67e74705SXin Li return true;
1169*67e74705SXin Li }
1170*67e74705SXin Li
tryToParseLambdaIntroducer()1171*67e74705SXin Li bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
1172*67e74705SXin Li nextToken();
1173*67e74705SXin Li if (FormatTok->is(tok::equal)) {
1174*67e74705SXin Li nextToken();
1175*67e74705SXin Li if (FormatTok->is(tok::r_square)) {
1176*67e74705SXin Li nextToken();
1177*67e74705SXin Li return true;
1178*67e74705SXin Li }
1179*67e74705SXin Li if (FormatTok->isNot(tok::comma))
1180*67e74705SXin Li return false;
1181*67e74705SXin Li nextToken();
1182*67e74705SXin Li } else if (FormatTok->is(tok::amp)) {
1183*67e74705SXin Li nextToken();
1184*67e74705SXin Li if (FormatTok->is(tok::r_square)) {
1185*67e74705SXin Li nextToken();
1186*67e74705SXin Li return true;
1187*67e74705SXin Li }
1188*67e74705SXin Li if (!FormatTok->isOneOf(tok::comma, tok::identifier)) {
1189*67e74705SXin Li return false;
1190*67e74705SXin Li }
1191*67e74705SXin Li if (FormatTok->is(tok::comma))
1192*67e74705SXin Li nextToken();
1193*67e74705SXin Li } else if (FormatTok->is(tok::r_square)) {
1194*67e74705SXin Li nextToken();
1195*67e74705SXin Li return true;
1196*67e74705SXin Li }
1197*67e74705SXin Li do {
1198*67e74705SXin Li if (FormatTok->is(tok::amp))
1199*67e74705SXin Li nextToken();
1200*67e74705SXin Li if (!FormatTok->isOneOf(tok::identifier, tok::kw_this))
1201*67e74705SXin Li return false;
1202*67e74705SXin Li nextToken();
1203*67e74705SXin Li if (FormatTok->is(tok::ellipsis))
1204*67e74705SXin Li nextToken();
1205*67e74705SXin Li if (FormatTok->is(tok::comma)) {
1206*67e74705SXin Li nextToken();
1207*67e74705SXin Li } else if (FormatTok->is(tok::r_square)) {
1208*67e74705SXin Li nextToken();
1209*67e74705SXin Li return true;
1210*67e74705SXin Li } else {
1211*67e74705SXin Li return false;
1212*67e74705SXin Li }
1213*67e74705SXin Li } while (!eof());
1214*67e74705SXin Li return false;
1215*67e74705SXin Li }
1216*67e74705SXin Li
tryToParseJSFunction()1217*67e74705SXin Li void UnwrappedLineParser::tryToParseJSFunction() {
1218*67e74705SXin Li assert(FormatTok->is(Keywords.kw_function) ||
1219*67e74705SXin Li FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function));
1220*67e74705SXin Li if (FormatTok->is(Keywords.kw_async))
1221*67e74705SXin Li nextToken();
1222*67e74705SXin Li // Consume "function".
1223*67e74705SXin Li nextToken();
1224*67e74705SXin Li
1225*67e74705SXin Li // Consume * (generator function).
1226*67e74705SXin Li if (FormatTok->is(tok::star))
1227*67e74705SXin Li nextToken();
1228*67e74705SXin Li
1229*67e74705SXin Li // Consume function name.
1230*67e74705SXin Li if (FormatTok->is(tok::identifier))
1231*67e74705SXin Li nextToken();
1232*67e74705SXin Li
1233*67e74705SXin Li if (FormatTok->isNot(tok::l_paren))
1234*67e74705SXin Li return;
1235*67e74705SXin Li
1236*67e74705SXin Li // Parse formal parameter list.
1237*67e74705SXin Li parseParens();
1238*67e74705SXin Li
1239*67e74705SXin Li if (FormatTok->is(tok::colon)) {
1240*67e74705SXin Li // Parse a type definition.
1241*67e74705SXin Li nextToken();
1242*67e74705SXin Li
1243*67e74705SXin Li // Eat the type declaration. For braced inline object types, balance braces,
1244*67e74705SXin Li // otherwise just parse until finding an l_brace for the function body.
1245*67e74705SXin Li if (FormatTok->is(tok::l_brace))
1246*67e74705SXin Li tryToParseBracedList();
1247*67e74705SXin Li else
1248*67e74705SXin Li while (FormatTok->isNot(tok::l_brace) && !eof())
1249*67e74705SXin Li nextToken();
1250*67e74705SXin Li }
1251*67e74705SXin Li
1252*67e74705SXin Li parseChildBlock();
1253*67e74705SXin Li }
1254*67e74705SXin Li
tryToParseBracedList()1255*67e74705SXin Li bool UnwrappedLineParser::tryToParseBracedList() {
1256*67e74705SXin Li if (FormatTok->BlockKind == BK_Unknown)
1257*67e74705SXin Li calculateBraceTypes();
1258*67e74705SXin Li assert(FormatTok->BlockKind != BK_Unknown);
1259*67e74705SXin Li if (FormatTok->BlockKind == BK_Block)
1260*67e74705SXin Li return false;
1261*67e74705SXin Li parseBracedList();
1262*67e74705SXin Li return true;
1263*67e74705SXin Li }
1264*67e74705SXin Li
parseBracedList(bool ContinueOnSemicolons)1265*67e74705SXin Li bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
1266*67e74705SXin Li bool HasError = false;
1267*67e74705SXin Li nextToken();
1268*67e74705SXin Li
1269*67e74705SXin Li // FIXME: Once we have an expression parser in the UnwrappedLineParser,
1270*67e74705SXin Li // replace this by using parseAssigmentExpression() inside.
1271*67e74705SXin Li do {
1272*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
1273*67e74705SXin Li if (FormatTok->is(Keywords.kw_function) ||
1274*67e74705SXin Li FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function)) {
1275*67e74705SXin Li tryToParseJSFunction();
1276*67e74705SXin Li continue;
1277*67e74705SXin Li }
1278*67e74705SXin Li if (FormatTok->is(TT_JsFatArrow)) {
1279*67e74705SXin Li nextToken();
1280*67e74705SXin Li // Fat arrows can be followed by simple expressions or by child blocks
1281*67e74705SXin Li // in curly braces.
1282*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1283*67e74705SXin Li parseChildBlock();
1284*67e74705SXin Li continue;
1285*67e74705SXin Li }
1286*67e74705SXin Li }
1287*67e74705SXin Li }
1288*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
1289*67e74705SXin Li case tok::caret:
1290*67e74705SXin Li nextToken();
1291*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1292*67e74705SXin Li parseChildBlock();
1293*67e74705SXin Li }
1294*67e74705SXin Li break;
1295*67e74705SXin Li case tok::l_square:
1296*67e74705SXin Li tryToParseLambda();
1297*67e74705SXin Li break;
1298*67e74705SXin Li case tok::l_brace:
1299*67e74705SXin Li // Assume there are no blocks inside a braced init list apart
1300*67e74705SXin Li // from the ones we explicitly parse out (like lambdas).
1301*67e74705SXin Li FormatTok->BlockKind = BK_BracedInit;
1302*67e74705SXin Li parseBracedList();
1303*67e74705SXin Li break;
1304*67e74705SXin Li case tok::l_paren:
1305*67e74705SXin Li parseParens();
1306*67e74705SXin Li // JavaScript can just have free standing methods and getters/setters in
1307*67e74705SXin Li // object literals. Detect them by a "{" following ")".
1308*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
1309*67e74705SXin Li if (FormatTok->is(tok::l_brace))
1310*67e74705SXin Li parseChildBlock();
1311*67e74705SXin Li break;
1312*67e74705SXin Li }
1313*67e74705SXin Li break;
1314*67e74705SXin Li case tok::r_brace:
1315*67e74705SXin Li nextToken();
1316*67e74705SXin Li return !HasError;
1317*67e74705SXin Li case tok::semi:
1318*67e74705SXin Li // JavaScript (or more precisely TypeScript) can have semicolons in braced
1319*67e74705SXin Li // lists (in so-called TypeMemberLists). Thus, the semicolon cannot be
1320*67e74705SXin Li // used for error recovery if we have otherwise determined that this is
1321*67e74705SXin Li // a braced list.
1322*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript) {
1323*67e74705SXin Li nextToken();
1324*67e74705SXin Li break;
1325*67e74705SXin Li }
1326*67e74705SXin Li HasError = true;
1327*67e74705SXin Li if (!ContinueOnSemicolons)
1328*67e74705SXin Li return !HasError;
1329*67e74705SXin Li nextToken();
1330*67e74705SXin Li break;
1331*67e74705SXin Li case tok::comma:
1332*67e74705SXin Li nextToken();
1333*67e74705SXin Li break;
1334*67e74705SXin Li default:
1335*67e74705SXin Li nextToken();
1336*67e74705SXin Li break;
1337*67e74705SXin Li }
1338*67e74705SXin Li } while (!eof());
1339*67e74705SXin Li return false;
1340*67e74705SXin Li }
1341*67e74705SXin Li
parseParens()1342*67e74705SXin Li void UnwrappedLineParser::parseParens() {
1343*67e74705SXin Li assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected.");
1344*67e74705SXin Li nextToken();
1345*67e74705SXin Li do {
1346*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
1347*67e74705SXin Li case tok::l_paren:
1348*67e74705SXin Li parseParens();
1349*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_brace))
1350*67e74705SXin Li parseChildBlock();
1351*67e74705SXin Li break;
1352*67e74705SXin Li case tok::r_paren:
1353*67e74705SXin Li nextToken();
1354*67e74705SXin Li return;
1355*67e74705SXin Li case tok::r_brace:
1356*67e74705SXin Li // A "}" inside parenthesis is an error if there wasn't a matching "{".
1357*67e74705SXin Li return;
1358*67e74705SXin Li case tok::l_square:
1359*67e74705SXin Li tryToParseLambda();
1360*67e74705SXin Li break;
1361*67e74705SXin Li case tok::l_brace:
1362*67e74705SXin Li if (!tryToParseBracedList())
1363*67e74705SXin Li parseChildBlock();
1364*67e74705SXin Li break;
1365*67e74705SXin Li case tok::at:
1366*67e74705SXin Li nextToken();
1367*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace))
1368*67e74705SXin Li parseBracedList();
1369*67e74705SXin Li break;
1370*67e74705SXin Li case tok::identifier:
1371*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript &&
1372*67e74705SXin Li (FormatTok->is(Keywords.kw_function) ||
1373*67e74705SXin Li FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function)))
1374*67e74705SXin Li tryToParseJSFunction();
1375*67e74705SXin Li else
1376*67e74705SXin Li nextToken();
1377*67e74705SXin Li break;
1378*67e74705SXin Li default:
1379*67e74705SXin Li nextToken();
1380*67e74705SXin Li break;
1381*67e74705SXin Li }
1382*67e74705SXin Li } while (!eof());
1383*67e74705SXin Li }
1384*67e74705SXin Li
parseSquare()1385*67e74705SXin Li void UnwrappedLineParser::parseSquare() {
1386*67e74705SXin Li assert(FormatTok->Tok.is(tok::l_square) && "'[' expected.");
1387*67e74705SXin Li if (tryToParseLambda())
1388*67e74705SXin Li return;
1389*67e74705SXin Li do {
1390*67e74705SXin Li switch (FormatTok->Tok.getKind()) {
1391*67e74705SXin Li case tok::l_paren:
1392*67e74705SXin Li parseParens();
1393*67e74705SXin Li break;
1394*67e74705SXin Li case tok::r_square:
1395*67e74705SXin Li nextToken();
1396*67e74705SXin Li return;
1397*67e74705SXin Li case tok::r_brace:
1398*67e74705SXin Li // A "}" inside parenthesis is an error if there wasn't a matching "{".
1399*67e74705SXin Li return;
1400*67e74705SXin Li case tok::l_square:
1401*67e74705SXin Li parseSquare();
1402*67e74705SXin Li break;
1403*67e74705SXin Li case tok::l_brace: {
1404*67e74705SXin Li if (!tryToParseBracedList())
1405*67e74705SXin Li parseChildBlock();
1406*67e74705SXin Li break;
1407*67e74705SXin Li }
1408*67e74705SXin Li case tok::at:
1409*67e74705SXin Li nextToken();
1410*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace))
1411*67e74705SXin Li parseBracedList();
1412*67e74705SXin Li break;
1413*67e74705SXin Li default:
1414*67e74705SXin Li nextToken();
1415*67e74705SXin Li break;
1416*67e74705SXin Li }
1417*67e74705SXin Li } while (!eof());
1418*67e74705SXin Li }
1419*67e74705SXin Li
parseIfThenElse()1420*67e74705SXin Li void UnwrappedLineParser::parseIfThenElse() {
1421*67e74705SXin Li assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected");
1422*67e74705SXin Li nextToken();
1423*67e74705SXin Li if (FormatTok->Tok.is(tok::l_paren))
1424*67e74705SXin Li parseParens();
1425*67e74705SXin Li bool NeedsUnwrappedLine = false;
1426*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1427*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1428*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1429*67e74705SXin Li if (Style.BraceWrapping.BeforeElse)
1430*67e74705SXin Li addUnwrappedLine();
1431*67e74705SXin Li else
1432*67e74705SXin Li NeedsUnwrappedLine = true;
1433*67e74705SXin Li } else {
1434*67e74705SXin Li addUnwrappedLine();
1435*67e74705SXin Li ++Line->Level;
1436*67e74705SXin Li parseStructuralElement();
1437*67e74705SXin Li --Line->Level;
1438*67e74705SXin Li }
1439*67e74705SXin Li if (FormatTok->Tok.is(tok::kw_else)) {
1440*67e74705SXin Li nextToken();
1441*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1442*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1443*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1444*67e74705SXin Li addUnwrappedLine();
1445*67e74705SXin Li } else if (FormatTok->Tok.is(tok::kw_if)) {
1446*67e74705SXin Li parseIfThenElse();
1447*67e74705SXin Li } else {
1448*67e74705SXin Li addUnwrappedLine();
1449*67e74705SXin Li ++Line->Level;
1450*67e74705SXin Li parseStructuralElement();
1451*67e74705SXin Li if (FormatTok->is(tok::eof))
1452*67e74705SXin Li addUnwrappedLine();
1453*67e74705SXin Li --Line->Level;
1454*67e74705SXin Li }
1455*67e74705SXin Li } else if (NeedsUnwrappedLine) {
1456*67e74705SXin Li addUnwrappedLine();
1457*67e74705SXin Li }
1458*67e74705SXin Li }
1459*67e74705SXin Li
parseTryCatch()1460*67e74705SXin Li void UnwrappedLineParser::parseTryCatch() {
1461*67e74705SXin Li assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected");
1462*67e74705SXin Li nextToken();
1463*67e74705SXin Li bool NeedsUnwrappedLine = false;
1464*67e74705SXin Li if (FormatTok->is(tok::colon)) {
1465*67e74705SXin Li // We are in a function try block, what comes is an initializer list.
1466*67e74705SXin Li nextToken();
1467*67e74705SXin Li while (FormatTok->is(tok::identifier)) {
1468*67e74705SXin Li nextToken();
1469*67e74705SXin Li if (FormatTok->is(tok::l_paren))
1470*67e74705SXin Li parseParens();
1471*67e74705SXin Li if (FormatTok->is(tok::comma))
1472*67e74705SXin Li nextToken();
1473*67e74705SXin Li }
1474*67e74705SXin Li }
1475*67e74705SXin Li // Parse try with resource.
1476*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java && FormatTok->is(tok::l_paren)) {
1477*67e74705SXin Li parseParens();
1478*67e74705SXin Li }
1479*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1480*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1481*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1482*67e74705SXin Li if (Style.BraceWrapping.BeforeCatch) {
1483*67e74705SXin Li addUnwrappedLine();
1484*67e74705SXin Li } else {
1485*67e74705SXin Li NeedsUnwrappedLine = true;
1486*67e74705SXin Li }
1487*67e74705SXin Li } else if (!FormatTok->is(tok::kw_catch)) {
1488*67e74705SXin Li // The C++ standard requires a compound-statement after a try.
1489*67e74705SXin Li // If there's none, we try to assume there's a structuralElement
1490*67e74705SXin Li // and try to continue.
1491*67e74705SXin Li addUnwrappedLine();
1492*67e74705SXin Li ++Line->Level;
1493*67e74705SXin Li parseStructuralElement();
1494*67e74705SXin Li --Line->Level;
1495*67e74705SXin Li }
1496*67e74705SXin Li while (1) {
1497*67e74705SXin Li if (FormatTok->is(tok::at))
1498*67e74705SXin Li nextToken();
1499*67e74705SXin Li if (!(FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except,
1500*67e74705SXin Li tok::kw___finally) ||
1501*67e74705SXin Li ((Style.Language == FormatStyle::LK_Java ||
1502*67e74705SXin Li Style.Language == FormatStyle::LK_JavaScript) &&
1503*67e74705SXin Li FormatTok->is(Keywords.kw_finally)) ||
1504*67e74705SXin Li (FormatTok->Tok.isObjCAtKeyword(tok::objc_catch) ||
1505*67e74705SXin Li FormatTok->Tok.isObjCAtKeyword(tok::objc_finally))))
1506*67e74705SXin Li break;
1507*67e74705SXin Li nextToken();
1508*67e74705SXin Li while (FormatTok->isNot(tok::l_brace)) {
1509*67e74705SXin Li if (FormatTok->is(tok::l_paren)) {
1510*67e74705SXin Li parseParens();
1511*67e74705SXin Li continue;
1512*67e74705SXin Li }
1513*67e74705SXin Li if (FormatTok->isOneOf(tok::semi, tok::r_brace, tok::eof))
1514*67e74705SXin Li return;
1515*67e74705SXin Li nextToken();
1516*67e74705SXin Li }
1517*67e74705SXin Li NeedsUnwrappedLine = false;
1518*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1519*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1520*67e74705SXin Li if (Style.BraceWrapping.BeforeCatch)
1521*67e74705SXin Li addUnwrappedLine();
1522*67e74705SXin Li else
1523*67e74705SXin Li NeedsUnwrappedLine = true;
1524*67e74705SXin Li }
1525*67e74705SXin Li if (NeedsUnwrappedLine)
1526*67e74705SXin Li addUnwrappedLine();
1527*67e74705SXin Li }
1528*67e74705SXin Li
parseNamespace()1529*67e74705SXin Li void UnwrappedLineParser::parseNamespace() {
1530*67e74705SXin Li assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
1531*67e74705SXin Li
1532*67e74705SXin Li const FormatToken &InitialToken = *FormatTok;
1533*67e74705SXin Li nextToken();
1534*67e74705SXin Li while (FormatTok->isOneOf(tok::identifier, tok::coloncolon))
1535*67e74705SXin Li nextToken();
1536*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1537*67e74705SXin Li if (ShouldBreakBeforeBrace(Style, InitialToken))
1538*67e74705SXin Li addUnwrappedLine();
1539*67e74705SXin Li
1540*67e74705SXin Li bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
1541*67e74705SXin Li (Style.NamespaceIndentation == FormatStyle::NI_Inner &&
1542*67e74705SXin Li DeclarationScopeStack.size() > 1);
1543*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true, AddLevel);
1544*67e74705SXin Li // Munch the semicolon after a namespace. This is more common than one would
1545*67e74705SXin Li // think. Puttin the semicolon into its own line is very ugly.
1546*67e74705SXin Li if (FormatTok->Tok.is(tok::semi))
1547*67e74705SXin Li nextToken();
1548*67e74705SXin Li addUnwrappedLine();
1549*67e74705SXin Li }
1550*67e74705SXin Li // FIXME: Add error handling.
1551*67e74705SXin Li }
1552*67e74705SXin Li
parseNew()1553*67e74705SXin Li void UnwrappedLineParser::parseNew() {
1554*67e74705SXin Li assert(FormatTok->is(tok::kw_new) && "'new' expected");
1555*67e74705SXin Li nextToken();
1556*67e74705SXin Li if (Style.Language != FormatStyle::LK_Java)
1557*67e74705SXin Li return;
1558*67e74705SXin Li
1559*67e74705SXin Li // In Java, we can parse everything up to the parens, which aren't optional.
1560*67e74705SXin Li do {
1561*67e74705SXin Li // There should not be a ;, { or } before the new's open paren.
1562*67e74705SXin Li if (FormatTok->isOneOf(tok::semi, tok::l_brace, tok::r_brace))
1563*67e74705SXin Li return;
1564*67e74705SXin Li
1565*67e74705SXin Li // Consume the parens.
1566*67e74705SXin Li if (FormatTok->is(tok::l_paren)) {
1567*67e74705SXin Li parseParens();
1568*67e74705SXin Li
1569*67e74705SXin Li // If there is a class body of an anonymous class, consume that as child.
1570*67e74705SXin Li if (FormatTok->is(tok::l_brace))
1571*67e74705SXin Li parseChildBlock();
1572*67e74705SXin Li return;
1573*67e74705SXin Li }
1574*67e74705SXin Li nextToken();
1575*67e74705SXin Li } while (!eof());
1576*67e74705SXin Li }
1577*67e74705SXin Li
parseForOrWhileLoop()1578*67e74705SXin Li void UnwrappedLineParser::parseForOrWhileLoop() {
1579*67e74705SXin Li assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
1580*67e74705SXin Li "'for', 'while' or foreach macro expected");
1581*67e74705SXin Li nextToken();
1582*67e74705SXin Li if (FormatTok->Tok.is(tok::l_paren))
1583*67e74705SXin Li parseParens();
1584*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1585*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1586*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1587*67e74705SXin Li addUnwrappedLine();
1588*67e74705SXin Li } else {
1589*67e74705SXin Li addUnwrappedLine();
1590*67e74705SXin Li ++Line->Level;
1591*67e74705SXin Li parseStructuralElement();
1592*67e74705SXin Li --Line->Level;
1593*67e74705SXin Li }
1594*67e74705SXin Li }
1595*67e74705SXin Li
parseDoWhile()1596*67e74705SXin Li void UnwrappedLineParser::parseDoWhile() {
1597*67e74705SXin Li assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected");
1598*67e74705SXin Li nextToken();
1599*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1600*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1601*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1602*67e74705SXin Li if (Style.BraceWrapping.IndentBraces)
1603*67e74705SXin Li addUnwrappedLine();
1604*67e74705SXin Li } else {
1605*67e74705SXin Li addUnwrappedLine();
1606*67e74705SXin Li ++Line->Level;
1607*67e74705SXin Li parseStructuralElement();
1608*67e74705SXin Li --Line->Level;
1609*67e74705SXin Li }
1610*67e74705SXin Li
1611*67e74705SXin Li // FIXME: Add error handling.
1612*67e74705SXin Li if (!FormatTok->Tok.is(tok::kw_while)) {
1613*67e74705SXin Li addUnwrappedLine();
1614*67e74705SXin Li return;
1615*67e74705SXin Li }
1616*67e74705SXin Li
1617*67e74705SXin Li nextToken();
1618*67e74705SXin Li parseStructuralElement();
1619*67e74705SXin Li }
1620*67e74705SXin Li
parseLabel()1621*67e74705SXin Li void UnwrappedLineParser::parseLabel() {
1622*67e74705SXin Li nextToken();
1623*67e74705SXin Li unsigned OldLineLevel = Line->Level;
1624*67e74705SXin Li if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
1625*67e74705SXin Li --Line->Level;
1626*67e74705SXin Li if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
1627*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1628*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1629*67e74705SXin Li if (FormatTok->Tok.is(tok::kw_break)) {
1630*67e74705SXin Li if (Style.BraceWrapping.AfterControlStatement)
1631*67e74705SXin Li addUnwrappedLine();
1632*67e74705SXin Li parseStructuralElement();
1633*67e74705SXin Li }
1634*67e74705SXin Li addUnwrappedLine();
1635*67e74705SXin Li } else {
1636*67e74705SXin Li if (FormatTok->is(tok::semi))
1637*67e74705SXin Li nextToken();
1638*67e74705SXin Li addUnwrappedLine();
1639*67e74705SXin Li }
1640*67e74705SXin Li Line->Level = OldLineLevel;
1641*67e74705SXin Li if (FormatTok->isNot(tok::l_brace)) {
1642*67e74705SXin Li parseStructuralElement();
1643*67e74705SXin Li addUnwrappedLine();
1644*67e74705SXin Li }
1645*67e74705SXin Li }
1646*67e74705SXin Li
parseCaseLabel()1647*67e74705SXin Li void UnwrappedLineParser::parseCaseLabel() {
1648*67e74705SXin Li assert(FormatTok->Tok.is(tok::kw_case) && "'case' expected");
1649*67e74705SXin Li // FIXME: fix handling of complex expressions here.
1650*67e74705SXin Li do {
1651*67e74705SXin Li nextToken();
1652*67e74705SXin Li } while (!eof() && !FormatTok->Tok.is(tok::colon));
1653*67e74705SXin Li parseLabel();
1654*67e74705SXin Li }
1655*67e74705SXin Li
parseSwitch()1656*67e74705SXin Li void UnwrappedLineParser::parseSwitch() {
1657*67e74705SXin Li assert(FormatTok->Tok.is(tok::kw_switch) && "'switch' expected");
1658*67e74705SXin Li nextToken();
1659*67e74705SXin Li if (FormatTok->Tok.is(tok::l_paren))
1660*67e74705SXin Li parseParens();
1661*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1662*67e74705SXin Li CompoundStatementIndenter Indenter(this, Style, Line->Level);
1663*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1664*67e74705SXin Li addUnwrappedLine();
1665*67e74705SXin Li } else {
1666*67e74705SXin Li addUnwrappedLine();
1667*67e74705SXin Li ++Line->Level;
1668*67e74705SXin Li parseStructuralElement();
1669*67e74705SXin Li --Line->Level;
1670*67e74705SXin Li }
1671*67e74705SXin Li }
1672*67e74705SXin Li
parseAccessSpecifier()1673*67e74705SXin Li void UnwrappedLineParser::parseAccessSpecifier() {
1674*67e74705SXin Li nextToken();
1675*67e74705SXin Li // Understand Qt's slots.
1676*67e74705SXin Li if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
1677*67e74705SXin Li nextToken();
1678*67e74705SXin Li // Otherwise, we don't know what it is, and we'd better keep the next token.
1679*67e74705SXin Li if (FormatTok->Tok.is(tok::colon))
1680*67e74705SXin Li nextToken();
1681*67e74705SXin Li addUnwrappedLine();
1682*67e74705SXin Li }
1683*67e74705SXin Li
parseEnum()1684*67e74705SXin Li bool UnwrappedLineParser::parseEnum() {
1685*67e74705SXin Li // Won't be 'enum' for NS_ENUMs.
1686*67e74705SXin Li if (FormatTok->Tok.is(tok::kw_enum))
1687*67e74705SXin Li nextToken();
1688*67e74705SXin Li
1689*67e74705SXin Li // In TypeScript, "enum" can also be used as property name, e.g. in interface
1690*67e74705SXin Li // declarations. An "enum" keyword followed by a colon would be a syntax
1691*67e74705SXin Li // error and thus assume it is just an identifier.
1692*67e74705SXin Li if (Style.Language == FormatStyle::LK_JavaScript &&
1693*67e74705SXin Li FormatTok->isOneOf(tok::colon, tok::question))
1694*67e74705SXin Li return false;
1695*67e74705SXin Li
1696*67e74705SXin Li // Eat up enum class ...
1697*67e74705SXin Li if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
1698*67e74705SXin Li nextToken();
1699*67e74705SXin Li
1700*67e74705SXin Li while (FormatTok->Tok.getIdentifierInfo() ||
1701*67e74705SXin Li FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
1702*67e74705SXin Li tok::greater, tok::comma, tok::question)) {
1703*67e74705SXin Li nextToken();
1704*67e74705SXin Li // We can have macros or attributes in between 'enum' and the enum name.
1705*67e74705SXin Li if (FormatTok->is(tok::l_paren))
1706*67e74705SXin Li parseParens();
1707*67e74705SXin Li if (FormatTok->is(tok::identifier)) {
1708*67e74705SXin Li nextToken();
1709*67e74705SXin Li // If there are two identifiers in a row, this is likely an elaborate
1710*67e74705SXin Li // return type. In Java, this can be "implements", etc.
1711*67e74705SXin Li if (Style.Language == FormatStyle::LK_Cpp &&
1712*67e74705SXin Li FormatTok->is(tok::identifier))
1713*67e74705SXin Li return false;
1714*67e74705SXin Li }
1715*67e74705SXin Li }
1716*67e74705SXin Li
1717*67e74705SXin Li // Just a declaration or something is wrong.
1718*67e74705SXin Li if (FormatTok->isNot(tok::l_brace))
1719*67e74705SXin Li return true;
1720*67e74705SXin Li FormatTok->BlockKind = BK_Block;
1721*67e74705SXin Li
1722*67e74705SXin Li if (Style.Language == FormatStyle::LK_Java) {
1723*67e74705SXin Li // Java enums are different.
1724*67e74705SXin Li parseJavaEnumBody();
1725*67e74705SXin Li return true;
1726*67e74705SXin Li }
1727*67e74705SXin Li if (Style.Language == FormatStyle::LK_Proto) {
1728*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true);
1729*67e74705SXin Li return true;
1730*67e74705SXin Li }
1731*67e74705SXin Li
1732*67e74705SXin Li // Parse enum body.
1733*67e74705SXin Li bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true);
1734*67e74705SXin Li if (HasError) {
1735*67e74705SXin Li if (FormatTok->is(tok::semi))
1736*67e74705SXin Li nextToken();
1737*67e74705SXin Li addUnwrappedLine();
1738*67e74705SXin Li }
1739*67e74705SXin Li return true;
1740*67e74705SXin Li
1741*67e74705SXin Li // There is no addUnwrappedLine() here so that we fall through to parsing a
1742*67e74705SXin Li // structural element afterwards. Thus, in "enum A {} n, m;",
1743*67e74705SXin Li // "} n, m;" will end up in one unwrapped line.
1744*67e74705SXin Li }
1745*67e74705SXin Li
parseJavaEnumBody()1746*67e74705SXin Li void UnwrappedLineParser::parseJavaEnumBody() {
1747*67e74705SXin Li // Determine whether the enum is simple, i.e. does not have a semicolon or
1748*67e74705SXin Li // constants with class bodies. Simple enums can be formatted like braced
1749*67e74705SXin Li // lists, contracted to a single line, etc.
1750*67e74705SXin Li unsigned StoredPosition = Tokens->getPosition();
1751*67e74705SXin Li bool IsSimple = true;
1752*67e74705SXin Li FormatToken *Tok = Tokens->getNextToken();
1753*67e74705SXin Li while (Tok) {
1754*67e74705SXin Li if (Tok->is(tok::r_brace))
1755*67e74705SXin Li break;
1756*67e74705SXin Li if (Tok->isOneOf(tok::l_brace, tok::semi)) {
1757*67e74705SXin Li IsSimple = false;
1758*67e74705SXin Li break;
1759*67e74705SXin Li }
1760*67e74705SXin Li // FIXME: This will also mark enums with braces in the arguments to enum
1761*67e74705SXin Li // constants as "not simple". This is probably fine in practice, though.
1762*67e74705SXin Li Tok = Tokens->getNextToken();
1763*67e74705SXin Li }
1764*67e74705SXin Li FormatTok = Tokens->setPosition(StoredPosition);
1765*67e74705SXin Li
1766*67e74705SXin Li if (IsSimple) {
1767*67e74705SXin Li parseBracedList();
1768*67e74705SXin Li addUnwrappedLine();
1769*67e74705SXin Li return;
1770*67e74705SXin Li }
1771*67e74705SXin Li
1772*67e74705SXin Li // Parse the body of a more complex enum.
1773*67e74705SXin Li // First add a line for everything up to the "{".
1774*67e74705SXin Li nextToken();
1775*67e74705SXin Li addUnwrappedLine();
1776*67e74705SXin Li ++Line->Level;
1777*67e74705SXin Li
1778*67e74705SXin Li // Parse the enum constants.
1779*67e74705SXin Li while (FormatTok) {
1780*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1781*67e74705SXin Li // Parse the constant's class body.
1782*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1783*67e74705SXin Li /*MunchSemi=*/false);
1784*67e74705SXin Li } else if (FormatTok->is(tok::l_paren)) {
1785*67e74705SXin Li parseParens();
1786*67e74705SXin Li } else if (FormatTok->is(tok::comma)) {
1787*67e74705SXin Li nextToken();
1788*67e74705SXin Li addUnwrappedLine();
1789*67e74705SXin Li } else if (FormatTok->is(tok::semi)) {
1790*67e74705SXin Li nextToken();
1791*67e74705SXin Li addUnwrappedLine();
1792*67e74705SXin Li break;
1793*67e74705SXin Li } else if (FormatTok->is(tok::r_brace)) {
1794*67e74705SXin Li addUnwrappedLine();
1795*67e74705SXin Li break;
1796*67e74705SXin Li } else {
1797*67e74705SXin Li nextToken();
1798*67e74705SXin Li }
1799*67e74705SXin Li }
1800*67e74705SXin Li
1801*67e74705SXin Li // Parse the class body after the enum's ";" if any.
1802*67e74705SXin Li parseLevel(/*HasOpeningBrace=*/true);
1803*67e74705SXin Li nextToken();
1804*67e74705SXin Li --Line->Level;
1805*67e74705SXin Li addUnwrappedLine();
1806*67e74705SXin Li }
1807*67e74705SXin Li
parseRecord()1808*67e74705SXin Li void UnwrappedLineParser::parseRecord() {
1809*67e74705SXin Li const FormatToken &InitialToken = *FormatTok;
1810*67e74705SXin Li nextToken();
1811*67e74705SXin Li
1812*67e74705SXin Li // The actual identifier can be a nested name specifier, and in macros
1813*67e74705SXin Li // it is often token-pasted.
1814*67e74705SXin Li while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
1815*67e74705SXin Li tok::kw___attribute, tok::kw___declspec,
1816*67e74705SXin Li tok::kw_alignas) ||
1817*67e74705SXin Li ((Style.Language == FormatStyle::LK_Java ||
1818*67e74705SXin Li Style.Language == FormatStyle::LK_JavaScript) &&
1819*67e74705SXin Li FormatTok->isOneOf(tok::period, tok::comma))) {
1820*67e74705SXin Li bool IsNonMacroIdentifier =
1821*67e74705SXin Li FormatTok->is(tok::identifier) &&
1822*67e74705SXin Li FormatTok->TokenText != FormatTok->TokenText.upper();
1823*67e74705SXin Li nextToken();
1824*67e74705SXin Li // We can have macros or attributes in between 'class' and the class name.
1825*67e74705SXin Li if (!IsNonMacroIdentifier && FormatTok->Tok.is(tok::l_paren))
1826*67e74705SXin Li parseParens();
1827*67e74705SXin Li }
1828*67e74705SXin Li
1829*67e74705SXin Li // Note that parsing away template declarations here leads to incorrectly
1830*67e74705SXin Li // accepting function declarations as record declarations.
1831*67e74705SXin Li // In general, we cannot solve this problem. Consider:
1832*67e74705SXin Li // class A<int> B() {}
1833*67e74705SXin Li // which can be a function definition or a class definition when B() is a
1834*67e74705SXin Li // macro. If we find enough real-world cases where this is a problem, we
1835*67e74705SXin Li // can parse for the 'template' keyword in the beginning of the statement,
1836*67e74705SXin Li // and thus rule out the record production in case there is no template
1837*67e74705SXin Li // (this would still leave us with an ambiguity between template function
1838*67e74705SXin Li // and class declarations).
1839*67e74705SXin Li if (FormatTok->isOneOf(tok::colon, tok::less)) {
1840*67e74705SXin Li while (!eof()) {
1841*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1842*67e74705SXin Li calculateBraceTypes(/*ExpectClassBody=*/true);
1843*67e74705SXin Li if (!tryToParseBracedList())
1844*67e74705SXin Li break;
1845*67e74705SXin Li }
1846*67e74705SXin Li if (FormatTok->Tok.is(tok::semi))
1847*67e74705SXin Li return;
1848*67e74705SXin Li nextToken();
1849*67e74705SXin Li }
1850*67e74705SXin Li }
1851*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1852*67e74705SXin Li if (ShouldBreakBeforeBrace(Style, InitialToken))
1853*67e74705SXin Li addUnwrappedLine();
1854*67e74705SXin Li
1855*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
1856*67e74705SXin Li /*MunchSemi=*/false);
1857*67e74705SXin Li }
1858*67e74705SXin Li // There is no addUnwrappedLine() here so that we fall through to parsing a
1859*67e74705SXin Li // structural element afterwards. Thus, in "class A {} n, m;",
1860*67e74705SXin Li // "} n, m;" will end up in one unwrapped line.
1861*67e74705SXin Li }
1862*67e74705SXin Li
parseObjCProtocolList()1863*67e74705SXin Li void UnwrappedLineParser::parseObjCProtocolList() {
1864*67e74705SXin Li assert(FormatTok->Tok.is(tok::less) && "'<' expected.");
1865*67e74705SXin Li do
1866*67e74705SXin Li nextToken();
1867*67e74705SXin Li while (!eof() && FormatTok->Tok.isNot(tok::greater));
1868*67e74705SXin Li nextToken(); // Skip '>'.
1869*67e74705SXin Li }
1870*67e74705SXin Li
parseObjCUntilAtEnd()1871*67e74705SXin Li void UnwrappedLineParser::parseObjCUntilAtEnd() {
1872*67e74705SXin Li do {
1873*67e74705SXin Li if (FormatTok->Tok.isObjCAtKeyword(tok::objc_end)) {
1874*67e74705SXin Li nextToken();
1875*67e74705SXin Li addUnwrappedLine();
1876*67e74705SXin Li break;
1877*67e74705SXin Li }
1878*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1879*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/false);
1880*67e74705SXin Li // In ObjC interfaces, nothing should be following the "}".
1881*67e74705SXin Li addUnwrappedLine();
1882*67e74705SXin Li } else if (FormatTok->is(tok::r_brace)) {
1883*67e74705SXin Li // Ignore stray "}". parseStructuralElement doesn't consume them.
1884*67e74705SXin Li nextToken();
1885*67e74705SXin Li addUnwrappedLine();
1886*67e74705SXin Li } else {
1887*67e74705SXin Li parseStructuralElement();
1888*67e74705SXin Li }
1889*67e74705SXin Li } while (!eof());
1890*67e74705SXin Li }
1891*67e74705SXin Li
parseObjCInterfaceOrImplementation()1892*67e74705SXin Li void UnwrappedLineParser::parseObjCInterfaceOrImplementation() {
1893*67e74705SXin Li nextToken();
1894*67e74705SXin Li nextToken(); // interface name
1895*67e74705SXin Li
1896*67e74705SXin Li // @interface can be followed by either a base class, or a category.
1897*67e74705SXin Li if (FormatTok->Tok.is(tok::colon)) {
1898*67e74705SXin Li nextToken();
1899*67e74705SXin Li nextToken(); // base class name
1900*67e74705SXin Li } else if (FormatTok->Tok.is(tok::l_paren))
1901*67e74705SXin Li // Skip category, if present.
1902*67e74705SXin Li parseParens();
1903*67e74705SXin Li
1904*67e74705SXin Li if (FormatTok->Tok.is(tok::less))
1905*67e74705SXin Li parseObjCProtocolList();
1906*67e74705SXin Li
1907*67e74705SXin Li if (FormatTok->Tok.is(tok::l_brace)) {
1908*67e74705SXin Li if (Style.BraceWrapping.AfterObjCDeclaration)
1909*67e74705SXin Li addUnwrappedLine();
1910*67e74705SXin Li parseBlock(/*MustBeDeclaration=*/true);
1911*67e74705SXin Li }
1912*67e74705SXin Li
1913*67e74705SXin Li // With instance variables, this puts '}' on its own line. Without instance
1914*67e74705SXin Li // variables, this ends the @interface line.
1915*67e74705SXin Li addUnwrappedLine();
1916*67e74705SXin Li
1917*67e74705SXin Li parseObjCUntilAtEnd();
1918*67e74705SXin Li }
1919*67e74705SXin Li
parseObjCProtocol()1920*67e74705SXin Li void UnwrappedLineParser::parseObjCProtocol() {
1921*67e74705SXin Li nextToken();
1922*67e74705SXin Li nextToken(); // protocol name
1923*67e74705SXin Li
1924*67e74705SXin Li if (FormatTok->Tok.is(tok::less))
1925*67e74705SXin Li parseObjCProtocolList();
1926*67e74705SXin Li
1927*67e74705SXin Li // Check for protocol declaration.
1928*67e74705SXin Li if (FormatTok->Tok.is(tok::semi)) {
1929*67e74705SXin Li nextToken();
1930*67e74705SXin Li return addUnwrappedLine();
1931*67e74705SXin Li }
1932*67e74705SXin Li
1933*67e74705SXin Li addUnwrappedLine();
1934*67e74705SXin Li parseObjCUntilAtEnd();
1935*67e74705SXin Li }
1936*67e74705SXin Li
parseJavaScriptEs6ImportExport()1937*67e74705SXin Li void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
1938*67e74705SXin Li bool IsImport = FormatTok->is(Keywords.kw_import);
1939*67e74705SXin Li assert(IsImport || FormatTok->is(tok::kw_export));
1940*67e74705SXin Li nextToken();
1941*67e74705SXin Li
1942*67e74705SXin Li // Consume the "default" in "export default class/function".
1943*67e74705SXin Li if (FormatTok->is(tok::kw_default))
1944*67e74705SXin Li nextToken();
1945*67e74705SXin Li
1946*67e74705SXin Li // Consume "async function", "function" and "default function", so that these
1947*67e74705SXin Li // get parsed as free-standing JS functions, i.e. do not require a trailing
1948*67e74705SXin Li // semicolon.
1949*67e74705SXin Li if (FormatTok->is(Keywords.kw_async))
1950*67e74705SXin Li nextToken();
1951*67e74705SXin Li if (FormatTok->is(Keywords.kw_function)) {
1952*67e74705SXin Li nextToken();
1953*67e74705SXin Li return;
1954*67e74705SXin Li }
1955*67e74705SXin Li
1956*67e74705SXin Li // For imports, `export *`, `export {...}`, consume the rest of the line up
1957*67e74705SXin Li // to the terminating `;`. For everything else, just return and continue
1958*67e74705SXin Li // parsing the structural element, i.e. the declaration or expression for
1959*67e74705SXin Li // `export default`.
1960*67e74705SXin Li if (!IsImport && !FormatTok->isOneOf(tok::l_brace, tok::star) &&
1961*67e74705SXin Li !FormatTok->isStringLiteral())
1962*67e74705SXin Li return;
1963*67e74705SXin Li
1964*67e74705SXin Li while (!eof() && FormatTok->isNot(tok::semi)) {
1965*67e74705SXin Li if (FormatTok->is(tok::l_brace)) {
1966*67e74705SXin Li FormatTok->BlockKind = BK_Block;
1967*67e74705SXin Li parseBracedList();
1968*67e74705SXin Li } else {
1969*67e74705SXin Li nextToken();
1970*67e74705SXin Li }
1971*67e74705SXin Li }
1972*67e74705SXin Li }
1973*67e74705SXin Li
printDebugInfo(const UnwrappedLine & Line,StringRef Prefix="")1974*67e74705SXin Li LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line,
1975*67e74705SXin Li StringRef Prefix = "") {
1976*67e74705SXin Li llvm::dbgs() << Prefix << "Line(" << Line.Level << ")"
1977*67e74705SXin Li << (Line.InPPDirective ? " MACRO" : "") << ": ";
1978*67e74705SXin Li for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
1979*67e74705SXin Li E = Line.Tokens.end();
1980*67e74705SXin Li I != E; ++I) {
1981*67e74705SXin Li llvm::dbgs() << I->Tok->Tok.getName() << "[" << I->Tok->Type << "] ";
1982*67e74705SXin Li }
1983*67e74705SXin Li for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),
1984*67e74705SXin Li E = Line.Tokens.end();
1985*67e74705SXin Li I != E; ++I) {
1986*67e74705SXin Li const UnwrappedLineNode &Node = *I;
1987*67e74705SXin Li for (SmallVectorImpl<UnwrappedLine>::const_iterator
1988*67e74705SXin Li I = Node.Children.begin(),
1989*67e74705SXin Li E = Node.Children.end();
1990*67e74705SXin Li I != E; ++I) {
1991*67e74705SXin Li printDebugInfo(*I, "\nChild: ");
1992*67e74705SXin Li }
1993*67e74705SXin Li }
1994*67e74705SXin Li llvm::dbgs() << "\n";
1995*67e74705SXin Li }
1996*67e74705SXin Li
addUnwrappedLine()1997*67e74705SXin Li void UnwrappedLineParser::addUnwrappedLine() {
1998*67e74705SXin Li if (Line->Tokens.empty())
1999*67e74705SXin Li return;
2000*67e74705SXin Li DEBUG({
2001*67e74705SXin Li if (CurrentLines == &Lines)
2002*67e74705SXin Li printDebugInfo(*Line);
2003*67e74705SXin Li });
2004*67e74705SXin Li CurrentLines->push_back(std::move(*Line));
2005*67e74705SXin Li Line->Tokens.clear();
2006*67e74705SXin Li if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {
2007*67e74705SXin Li CurrentLines->append(
2008*67e74705SXin Li std::make_move_iterator(PreprocessorDirectives.begin()),
2009*67e74705SXin Li std::make_move_iterator(PreprocessorDirectives.end()));
2010*67e74705SXin Li PreprocessorDirectives.clear();
2011*67e74705SXin Li }
2012*67e74705SXin Li }
2013*67e74705SXin Li
eof() const2014*67e74705SXin Li bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); }
2015*67e74705SXin Li
isOnNewLine(const FormatToken & FormatTok)2016*67e74705SXin Li bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
2017*67e74705SXin Li return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
2018*67e74705SXin Li FormatTok.NewlinesBefore > 0;
2019*67e74705SXin Li }
2020*67e74705SXin Li
flushComments(bool NewlineBeforeNext)2021*67e74705SXin Li void UnwrappedLineParser::flushComments(bool NewlineBeforeNext) {
2022*67e74705SXin Li bool JustComments = Line->Tokens.empty();
2023*67e74705SXin Li for (SmallVectorImpl<FormatToken *>::const_iterator
2024*67e74705SXin Li I = CommentsBeforeNextToken.begin(),
2025*67e74705SXin Li E = CommentsBeforeNextToken.end();
2026*67e74705SXin Li I != E; ++I) {
2027*67e74705SXin Li if (isOnNewLine(**I) && JustComments)
2028*67e74705SXin Li addUnwrappedLine();
2029*67e74705SXin Li pushToken(*I);
2030*67e74705SXin Li }
2031*67e74705SXin Li if (NewlineBeforeNext && JustComments)
2032*67e74705SXin Li addUnwrappedLine();
2033*67e74705SXin Li CommentsBeforeNextToken.clear();
2034*67e74705SXin Li }
2035*67e74705SXin Li
nextToken()2036*67e74705SXin Li void UnwrappedLineParser::nextToken() {
2037*67e74705SXin Li if (eof())
2038*67e74705SXin Li return;
2039*67e74705SXin Li flushComments(isOnNewLine(*FormatTok));
2040*67e74705SXin Li pushToken(FormatTok);
2041*67e74705SXin Li if (Style.Language != FormatStyle::LK_JavaScript)
2042*67e74705SXin Li readToken();
2043*67e74705SXin Li else
2044*67e74705SXin Li readTokenWithJavaScriptASI();
2045*67e74705SXin Li }
2046*67e74705SXin Li
getPreviousToken()2047*67e74705SXin Li const FormatToken *UnwrappedLineParser::getPreviousToken() {
2048*67e74705SXin Li // FIXME: This is a dirty way to access the previous token. Find a better
2049*67e74705SXin Li // solution.
2050*67e74705SXin Li if (!Line || Line->Tokens.empty())
2051*67e74705SXin Li return nullptr;
2052*67e74705SXin Li return Line->Tokens.back().Tok;
2053*67e74705SXin Li }
2054*67e74705SXin Li
readToken()2055*67e74705SXin Li void UnwrappedLineParser::readToken() {
2056*67e74705SXin Li bool CommentsInCurrentLine = true;
2057*67e74705SXin Li do {
2058*67e74705SXin Li FormatTok = Tokens->getNextToken();
2059*67e74705SXin Li assert(FormatTok);
2060*67e74705SXin Li while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
2061*67e74705SXin Li (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
2062*67e74705SXin Li // If there is an unfinished unwrapped line, we flush the preprocessor
2063*67e74705SXin Li // directives only after that unwrapped line was finished later.
2064*67e74705SXin Li bool SwitchToPreprocessorLines = !Line->Tokens.empty();
2065*67e74705SXin Li ScopedLineState BlockState(*this, SwitchToPreprocessorLines);
2066*67e74705SXin Li // Comments stored before the preprocessor directive need to be output
2067*67e74705SXin Li // before the preprocessor directive, at the same level as the
2068*67e74705SXin Li // preprocessor directive, as we consider them to apply to the directive.
2069*67e74705SXin Li flushComments(isOnNewLine(*FormatTok));
2070*67e74705SXin Li parsePPDirective();
2071*67e74705SXin Li }
2072*67e74705SXin Li while (FormatTok->Type == TT_ConflictStart ||
2073*67e74705SXin Li FormatTok->Type == TT_ConflictEnd ||
2074*67e74705SXin Li FormatTok->Type == TT_ConflictAlternative) {
2075*67e74705SXin Li if (FormatTok->Type == TT_ConflictStart) {
2076*67e74705SXin Li conditionalCompilationStart(/*Unreachable=*/false);
2077*67e74705SXin Li } else if (FormatTok->Type == TT_ConflictAlternative) {
2078*67e74705SXin Li conditionalCompilationAlternative();
2079*67e74705SXin Li } else if (FormatTok->Type == TT_ConflictEnd) {
2080*67e74705SXin Li conditionalCompilationEnd();
2081*67e74705SXin Li }
2082*67e74705SXin Li FormatTok = Tokens->getNextToken();
2083*67e74705SXin Li FormatTok->MustBreakBefore = true;
2084*67e74705SXin Li }
2085*67e74705SXin Li
2086*67e74705SXin Li if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
2087*67e74705SXin Li !Line->InPPDirective) {
2088*67e74705SXin Li continue;
2089*67e74705SXin Li }
2090*67e74705SXin Li
2091*67e74705SXin Li if (!FormatTok->Tok.is(tok::comment))
2092*67e74705SXin Li return;
2093*67e74705SXin Li if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) {
2094*67e74705SXin Li CommentsInCurrentLine = false;
2095*67e74705SXin Li }
2096*67e74705SXin Li if (CommentsInCurrentLine) {
2097*67e74705SXin Li pushToken(FormatTok);
2098*67e74705SXin Li } else {
2099*67e74705SXin Li CommentsBeforeNextToken.push_back(FormatTok);
2100*67e74705SXin Li }
2101*67e74705SXin Li } while (!eof());
2102*67e74705SXin Li }
2103*67e74705SXin Li
pushToken(FormatToken * Tok)2104*67e74705SXin Li void UnwrappedLineParser::pushToken(FormatToken *Tok) {
2105*67e74705SXin Li Line->Tokens.push_back(UnwrappedLineNode(Tok));
2106*67e74705SXin Li if (MustBreakBeforeNextToken) {
2107*67e74705SXin Li Line->Tokens.back().Tok->MustBreakBefore = true;
2108*67e74705SXin Li MustBreakBeforeNextToken = false;
2109*67e74705SXin Li }
2110*67e74705SXin Li }
2111*67e74705SXin Li
2112*67e74705SXin Li } // end namespace format
2113*67e74705SXin Li } // end namespace clang
2114