Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/Format/UnwrappedLineParser.cpp
Show First 20 Lines • Show All 466 Lines • ▼ Show 20 Lines | case tok::l_brace: | ||||
// following a label in an object literal ({a: {b: 1}}). | // following a label in an object literal ({a: {b: 1}}). | ||||
// A '<' could be an object used in a comparison, but that is nonsense | // A '<' could be an object used in a comparison, but that is nonsense | ||||
// code (can never return true), so more likely it is a generic type | // code (can never return true), so more likely it is a generic type | ||||
// argument (`X<{a: string; b: number}>`). | // argument (`X<{a: string; b: number}>`). | ||||
// The code below could be confused by semicolons between the | // The code below could be confused by semicolons between the | ||||
// individual members in a type member list, which would normally | // individual members in a type member list, which would normally | ||||
// trigger BK_Block. In both cases, this must be parsed as an inline | // trigger BK_Block. In both cases, this must be parsed as an inline | ||||
// braced init. | // braced init. | ||||
Tok->BlockKind = BK_BracedInit; | Tok->setBlockKind(BK_BracedInit); | ||||
else if (PrevTok->is(tok::r_paren)) | else if (PrevTok->is(tok::r_paren)) | ||||
// `) { }` can only occur in function or method declarations in JS. | // `) { }` can only occur in function or method declarations in JS. | ||||
Tok->BlockKind = BK_Block; | Tok->setBlockKind(BK_Block); | ||||
} else { | } else { | ||||
Tok->BlockKind = BK_Unknown; | Tok->setBlockKind(BK_Unknown); | ||||
} | } | ||||
LBraceStack.push_back(Tok); | LBraceStack.push_back(Tok); | ||||
break; | break; | ||||
case tok::r_brace: | case tok::r_brace: | ||||
if (LBraceStack.empty()) | if (LBraceStack.empty()) | ||||
break; | break; | ||||
if (LBraceStack.back()->BlockKind == BK_Unknown) { | if (LBraceStack.back()->is(BK_Unknown)) { | ||||
bool ProbablyBracedList = false; | bool ProbablyBracedList = false; | ||||
if (Style.Language == FormatStyle::LK_Proto) { | if (Style.Language == FormatStyle::LK_Proto) { | ||||
ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); | ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); | ||||
} else { | } else { | ||||
// Using OriginalColumn to distinguish between ObjC methods and | // Using OriginalColumn to distinguish between ObjC methods and | ||||
// binary operators is a bit hacky. | // binary operators is a bit hacky. | ||||
bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && | bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && | ||||
NextTok->OriginalColumn == 0; | NextTok->OriginalColumn == 0; | ||||
Show All 23 Lines | case tok::r_brace: | ||||
// We can have an array subscript after a braced init | // We can have an array subscript after a braced init | ||||
// list, but C++11 attributes are expected after blocks. | // list, but C++11 attributes are expected after blocks. | ||||
NextTok = Tokens->getNextToken(); | NextTok = Tokens->getNextToken(); | ||||
++ReadTokens; | ++ReadTokens; | ||||
ProbablyBracedList = NextTok->isNot(tok::l_square); | ProbablyBracedList = NextTok->isNot(tok::l_square); | ||||
} | } | ||||
} | } | ||||
if (ProbablyBracedList) { | if (ProbablyBracedList) { | ||||
Tok->BlockKind = BK_BracedInit; | Tok->setBlockKind(BK_BracedInit); | ||||
LBraceStack.back()->BlockKind = BK_BracedInit; | LBraceStack.back()->setBlockKind(BK_BracedInit); | ||||
} else { | } else { | ||||
Tok->BlockKind = BK_Block; | Tok->setBlockKind(BK_Block); | ||||
LBraceStack.back()->BlockKind = BK_Block; | LBraceStack.back()->setBlockKind(BK_Block); | ||||
} | } | ||||
} | } | ||||
LBraceStack.pop_back(); | LBraceStack.pop_back(); | ||||
break; | break; | ||||
case tok::identifier: | case tok::identifier: | ||||
if (!Tok->is(TT_StatementMacro)) | if (!Tok->is(TT_StatementMacro)) | ||||
break; | break; | ||||
LLVM_FALLTHROUGH; | LLVM_FALLTHROUGH; | ||||
case tok::at: | case tok::at: | ||||
case tok::semi: | case tok::semi: | ||||
case tok::kw_if: | case tok::kw_if: | ||||
case tok::kw_while: | case tok::kw_while: | ||||
case tok::kw_for: | case tok::kw_for: | ||||
case tok::kw_switch: | case tok::kw_switch: | ||||
case tok::kw_try: | case tok::kw_try: | ||||
case tok::kw___try: | case tok::kw___try: | ||||
if (!LBraceStack.empty() && LBraceStack.back()->BlockKind == BK_Unknown) | if (!LBraceStack.empty() && LBraceStack.back()->is(BK_Unknown)) | ||||
LBraceStack.back()->BlockKind = BK_Block; | LBraceStack.back()->setBlockKind(BK_Block); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
PrevTok = Tok; | PrevTok = Tok; | ||||
Tok = NextTok; | Tok = NextTok; | ||||
} while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty()); | } while (Tok->Tok.isNot(tok::eof) && !LBraceStack.empty()); | ||||
// Assume other blocks for all unclosed opening braces. | // Assume other blocks for all unclosed opening braces. | ||||
for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { | for (unsigned i = 0, e = LBraceStack.size(); i != e; ++i) { | ||||
if (LBraceStack[i]->BlockKind == BK_Unknown) | if (LBraceStack[i]->is(BK_Unknown)) | ||||
LBraceStack[i]->BlockKind = BK_Block; | LBraceStack[i]->setBlockKind(BK_Block); | ||||
} | } | ||||
FormatTok = Tokens->setPosition(StoredPosition); | FormatTok = Tokens->setPosition(StoredPosition); | ||||
} | } | ||||
template <class T> | template <class T> | ||||
static inline void hash_combine(std::size_t &seed, const T &v) { | static inline void hash_combine(std::size_t &seed, const T &v) { | ||||
std::hash<T> hasher; | std::hash<T> hasher; | ||||
Show All 9 Lines | size_t UnwrappedLineParser::computePPHash() const { | ||||
return h; | return h; | ||||
} | } | ||||
void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, | void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, | ||||
bool MunchSemi) { | bool MunchSemi) { | ||||
assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) && | assert(FormatTok->isOneOf(tok::l_brace, TT_MacroBlockBegin) && | ||||
"'{' or macro block token expected"); | "'{' or macro block token expected"); | ||||
const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin); | const bool MacroBlock = FormatTok->is(TT_MacroBlockBegin); | ||||
FormatTok->BlockKind = BK_Block; | FormatTok->setBlockKind(BK_Block); | ||||
size_t PPStartHash = computePPHash(); | size_t PPStartHash = computePPHash(); | ||||
unsigned InitialLevel = Line->Level; | unsigned InitialLevel = Line->Level; | ||||
nextToken(/*LevelDifference=*/AddLevel ? 1 : 0); | nextToken(/*LevelDifference=*/AddLevel ? 1 : 0); | ||||
if (MacroBlock && FormatTok->is(tok::l_paren)) | if (MacroBlock && FormatTok->is(tok::l_paren)) | ||||
parseParens(); | parseParens(); | ||||
Show All 13 Lines | void UnwrappedLineParser::parseBlock(bool MustBeDeclaration, bool AddLevel, | ||||
parseLevel(/*HasOpeningBrace=*/true); | parseLevel(/*HasOpeningBrace=*/true); | ||||
if (eof()) | if (eof()) | ||||
return; | return; | ||||
if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd) | if (MacroBlock ? !FormatTok->is(TT_MacroBlockEnd) | ||||
: !FormatTok->is(tok::r_brace)) { | : !FormatTok->is(tok::r_brace)) { | ||||
Line->Level = InitialLevel; | Line->Level = InitialLevel; | ||||
FormatTok->BlockKind = BK_Block; | FormatTok->setBlockKind(BK_Block); | ||||
return; | return; | ||||
} | } | ||||
size_t PPEndHash = computePPHash(); | size_t PPEndHash = computePPHash(); | ||||
// Munch the closing brace. | // Munch the closing brace. | ||||
nextToken(/*LevelDifference=*/AddLevel ? -1 : 0); | nextToken(/*LevelDifference=*/AddLevel ? -1 : 0); | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | static bool ShouldBreakBeforeBrace(const FormatStyle &Style, | ||||
if (InitialToken.is(tok::kw_union)) | if (InitialToken.is(tok::kw_union)) | ||||
return Style.BraceWrapping.AfterUnion; | return Style.BraceWrapping.AfterUnion; | ||||
if (InitialToken.is(tok::kw_struct)) | if (InitialToken.is(tok::kw_struct)) | ||||
return Style.BraceWrapping.AfterStruct; | return Style.BraceWrapping.AfterStruct; | ||||
return false; | return false; | ||||
} | } | ||||
void UnwrappedLineParser::parseChildBlock() { | void UnwrappedLineParser::parseChildBlock() { | ||||
FormatTok->BlockKind = BK_Block; | FormatTok->setBlockKind(BK_Block); | ||||
nextToken(); | nextToken(); | ||||
{ | { | ||||
bool SkipIndent = (Style.Language == FormatStyle::LK_JavaScript && | bool SkipIndent = (Style.Language == FormatStyle::LK_JavaScript && | ||||
(isGoogScope(*Line) || isIIFE(*Line, Keywords))); | (isGoogScope(*Line) || isIIFE(*Line, Keywords))); | ||||
ScopedLineState LineState(*this); | ScopedLineState LineState(*this); | ||||
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, | ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack, | ||||
/*MustBeDeclaration=*/false); | /*MustBeDeclaration=*/false); | ||||
Line->Level += SkipIndent ? 0 : 1; | Line->Level += SkipIndent ? 0 : 1; | ||||
▲ Show 20 Lines • Show All 769 Lines • ▼ Show 20 Lines | case tok::equal: | ||||
} | } | ||||
nextToken(); | nextToken(); | ||||
if (FormatTok->Tok.is(tok::l_brace)) { | if (FormatTok->Tok.is(tok::l_brace)) { | ||||
// Block kind should probably be set to BK_BracedInit for any language. | // Block kind should probably be set to BK_BracedInit for any language. | ||||
// C# needs this change to ensure that array initialisers and object | // C# needs this change to ensure that array initialisers and object | ||||
// initialisers are indented the same way. | // initialisers are indented the same way. | ||||
if (Style.isCSharp()) | if (Style.isCSharp()) | ||||
FormatTok->BlockKind = BK_BracedInit; | FormatTok->setBlockKind(BK_BracedInit); | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(); | parseBracedList(); | ||||
} else if (Style.Language == FormatStyle::LK_Proto && | } else if (Style.Language == FormatStyle::LK_Proto && | ||||
FormatTok->Tok.is(tok::less)) { | FormatTok->Tok.is(tok::less)) { | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, | parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, | ||||
/*ClosingBraceKind=*/tok::greater); | /*ClosingBraceKind=*/tok::greater); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | void UnwrappedLineParser::tryToParseJSFunction() { | ||||
if (FormatTok->is(tok::semi)) | if (FormatTok->is(tok::semi)) | ||||
return; | return; | ||||
parseChildBlock(); | parseChildBlock(); | ||||
} | } | ||||
bool UnwrappedLineParser::tryToParseBracedList() { | bool UnwrappedLineParser::tryToParseBracedList() { | ||||
if (FormatTok->BlockKind == BK_Unknown) | if (FormatTok->is(BK_Unknown)) | ||||
calculateBraceTypes(); | calculateBraceTypes(); | ||||
assert(FormatTok->BlockKind != BK_Unknown); | assert(FormatTok->isNot(BK_Unknown)); | ||||
if (FormatTok->BlockKind == BK_Block) | if (FormatTok->is(BK_Block)) | ||||
return false; | return false; | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(); | parseBracedList(); | ||||
return true; | return true; | ||||
} | } | ||||
bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons, | bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons, | ||||
bool IsEnum, | bool IsEnum, | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | case tok::l_paren: | ||||
if (FormatTok->is(tok::l_brace)) | if (FormatTok->is(tok::l_brace)) | ||||
parseChildBlock(); | parseChildBlock(); | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
case tok::l_brace: | case tok::l_brace: | ||||
// Assume there are no blocks inside a braced init list apart | // Assume there are no blocks inside a braced init list apart | ||||
// from the ones we explicitly parse out (like lambdas). | // from the ones we explicitly parse out (like lambdas). | ||||
FormatTok->BlockKind = BK_BracedInit; | FormatTok->setBlockKind(BK_BracedInit); | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(); | parseBracedList(); | ||||
break; | break; | ||||
case tok::less: | case tok::less: | ||||
if (Style.Language == FormatStyle::LK_Proto) { | if (Style.Language == FormatStyle::LK_Proto) { | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, | parseBracedList(/*ContinueOnSemicolons=*/false, /*IsEnum=*/false, | ||||
/*ClosingBraceKind=*/tok::greater); | /*ClosingBraceKind=*/tok::greater); | ||||
▲ Show 20 Lines • Show All 471 Lines • ▼ Show 20 Lines | if (FormatTok->is(tok::identifier)) { | ||||
if (Style.isCpp() && FormatTok->is(tok::identifier)) | if (Style.isCpp() && FormatTok->is(tok::identifier)) | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// Just a declaration or something is wrong. | // Just a declaration or something is wrong. | ||||
if (FormatTok->isNot(tok::l_brace)) | if (FormatTok->isNot(tok::l_brace)) | ||||
return true; | return true; | ||||
FormatTok->BlockKind = BK_Block; | FormatTok->setBlockKind(BK_Block); | ||||
if (Style.Language == FormatStyle::LK_Java) { | if (Style.Language == FormatStyle::LK_Java) { | ||||
// Java enums are different. | // Java enums are different. | ||||
parseJavaEnumBody(); | parseJavaEnumBody(); | ||||
return true; | return true; | ||||
} | } | ||||
if (Style.Language == FormatStyle::LK_Proto) { | if (Style.Language == FormatStyle::LK_Proto) { | ||||
parseBlock(/*MustBeDeclaration=*/true); | parseBlock(/*MustBeDeclaration=*/true); | ||||
▲ Show 20 Lines • Show All 391 Lines • ▼ Show 20 Lines | while (!eof()) { | ||||
if (FormatTok->is(tok::semi)) | if (FormatTok->is(tok::semi)) | ||||
return; | return; | ||||
if (Line->Tokens.empty()) { | if (Line->Tokens.empty()) { | ||||
// Common issue: Automatic Semicolon Insertion wrapped the line, so the | // Common issue: Automatic Semicolon Insertion wrapped the line, so the | ||||
// import statement should terminate. | // import statement should terminate. | ||||
return; | return; | ||||
} | } | ||||
if (FormatTok->is(tok::l_brace)) { | if (FormatTok->is(tok::l_brace)) { | ||||
FormatTok->BlockKind = BK_Block; | FormatTok->setBlockKind(BK_Block); | ||||
nextToken(); | nextToken(); | ||||
parseBracedList(); | parseBracedList(); | ||||
} else { | } else { | ||||
nextToken(); | nextToken(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 334 Lines • Show Last 20 Lines |