|
@@ -315,6 +315,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
|
|
// definitions, too.
|
|
// definitions, too.
|
|
unsigned StoredPosition = Tokens->getPosition();
|
|
unsigned StoredPosition = Tokens->getPosition();
|
|
FormatToken *Tok = FormatTok;
|
|
FormatToken *Tok = FormatTok;
|
|
|
|
+ const FormatToken *PrevTok = getPreviousToken();
|
|
// Keep a stack of positions of lbrace tokens. We will
|
|
// Keep a stack of positions of lbrace tokens. We will
|
|
// update information about whether an lbrace starts a
|
|
// update information about whether an lbrace starts a
|
|
// braced init list or a different block during the loop.
|
|
// braced init list or a different block during the loop.
|
|
@@ -331,47 +332,53 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
|
|
|
|
|
|
switch (Tok->Tok.getKind()) {
|
|
switch (Tok->Tok.getKind()) {
|
|
case tok::l_brace:
|
|
case tok::l_brace:
|
|
- Tok->BlockKind = BK_Unknown;
|
|
|
|
|
|
+ if (Style.Language == FormatStyle::LK_JavaScript && PrevTok &&
|
|
|
|
+ PrevTok->is(tok::colon))
|
|
|
|
+ // In TypeScript's TypeMemberLists, there can be semicolons between the
|
|
|
|
+ // individual members.
|
|
|
|
+ Tok->BlockKind = BK_BracedInit;
|
|
|
|
+ else
|
|
|
|
+ Tok->BlockKind = 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.back()->BlockKind == BK_Unknown) {
|
|
|
|
- bool ProbablyBracedList = false;
|
|
|
|
- if (Style.Language == FormatStyle::LK_Proto) {
|
|
|
|
- ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
|
|
|
|
- } else {
|
|
|
|
- // Using OriginalColumn to distinguish between ObjC methods and
|
|
|
|
- // binary operators is a bit hacky.
|
|
|
|
- bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
|
|
|
|
- NextTok->OriginalColumn == 0;
|
|
|
|
-
|
|
|
|
- // If there is a comma, semicolon or right paren after the closing
|
|
|
|
- // brace, we assume this is a braced initializer list. Note that
|
|
|
|
- // regardless how we mark inner braces here, we will overwrite the
|
|
|
|
- // BlockKind later if we parse a braced list (where all blocks
|
|
|
|
- // inside are by default braced lists), or when we explicitly detect
|
|
|
|
- // blocks (for example while parsing lambdas).
|
|
|
|
- //
|
|
|
|
- // We exclude + and - as they can be ObjC visibility modifiers.
|
|
|
|
- ProbablyBracedList =
|
|
|
|
- NextTok->isOneOf(tok::comma, tok::period, tok::colon,
|
|
|
|
- tok::r_paren, tok::r_square, tok::l_brace,
|
|
|
|
- tok::l_square, tok::l_paren, tok::ellipsis) ||
|
|
|
|
- (NextTok->is(tok::semi) &&
|
|
|
|
- (!ExpectClassBody || LBraceStack.size() != 1)) ||
|
|
|
|
- (NextTok->isBinaryOperator() && !NextIsObjCMethod);
|
|
|
|
- }
|
|
|
|
- if (ProbablyBracedList) {
|
|
|
|
- Tok->BlockKind = BK_BracedInit;
|
|
|
|
- LBraceStack.back()->BlockKind = BK_BracedInit;
|
|
|
|
- } else {
|
|
|
|
- Tok->BlockKind = BK_Block;
|
|
|
|
- LBraceStack.back()->BlockKind = BK_Block;
|
|
|
|
- }
|
|
|
|
|
|
+ if (LBraceStack.empty())
|
|
|
|
+ break;
|
|
|
|
+ if (LBraceStack.back()->BlockKind == BK_Unknown) {
|
|
|
|
+ bool ProbablyBracedList = false;
|
|
|
|
+ if (Style.Language == FormatStyle::LK_Proto) {
|
|
|
|
+ ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
|
|
|
|
+ } else {
|
|
|
|
+ // Using OriginalColumn to distinguish between ObjC methods and
|
|
|
|
+ // binary operators is a bit hacky.
|
|
|
|
+ bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
|
|
|
|
+ NextTok->OriginalColumn == 0;
|
|
|
|
+
|
|
|
|
+ // If there is a comma, semicolon or right paren after the closing
|
|
|
|
+ // brace, we assume this is a braced initializer list. Note that
|
|
|
|
+ // regardless how we mark inner braces here, we will overwrite the
|
|
|
|
+ // BlockKind later if we parse a braced list (where all blocks
|
|
|
|
+ // inside are by default braced lists), or when we explicitly detect
|
|
|
|
+ // blocks (for example while parsing lambdas).
|
|
|
|
+ //
|
|
|
|
+ // We exclude + and - as they can be ObjC visibility modifiers.
|
|
|
|
+ ProbablyBracedList =
|
|
|
|
+ NextTok->isOneOf(tok::comma, tok::period, tok::colon,
|
|
|
|
+ tok::r_paren, tok::r_square, tok::l_brace,
|
|
|
|
+ tok::l_square, tok::l_paren, tok::ellipsis) ||
|
|
|
|
+ (NextTok->is(tok::semi) &&
|
|
|
|
+ (!ExpectClassBody || LBraceStack.size() != 1)) ||
|
|
|
|
+ (NextTok->isBinaryOperator() && !NextIsObjCMethod);
|
|
|
|
+ }
|
|
|
|
+ if (ProbablyBracedList) {
|
|
|
|
+ Tok->BlockKind = BK_BracedInit;
|
|
|
|
+ LBraceStack.back()->BlockKind = BK_BracedInit;
|
|
|
|
+ } else {
|
|
|
|
+ Tok->BlockKind = BK_Block;
|
|
|
|
+ LBraceStack.back()->BlockKind = BK_Block;
|
|
}
|
|
}
|
|
- LBraceStack.pop_back();
|
|
|
|
}
|
|
}
|
|
|
|
+ LBraceStack.pop_back();
|
|
break;
|
|
break;
|
|
case tok::at:
|
|
case tok::at:
|
|
case tok::semi:
|
|
case tok::semi:
|
|
@@ -381,14 +388,16 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
|
|
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())
|
|
|
|
|
|
+ if (!LBraceStack.empty() && LBraceStack.back()->BlockKind == BK_Unknown)
|
|
LBraceStack.back()->BlockKind = BK_Block;
|
|
LBraceStack.back()->BlockKind = BK_Block;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ 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]->BlockKind == BK_Unknown)
|
|
@@ -988,13 +997,11 @@ bool UnwrappedLineParser::tryToParseLambda() {
|
|
nextToken();
|
|
nextToken();
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- // FIXME: This is a dirty way to access the previous token. Find a better
|
|
|
|
- // solution.
|
|
|
|
- if (!Line->Tokens.empty() &&
|
|
|
|
- (Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator,
|
|
|
|
- tok::kw_new, tok::kw_delete) ||
|
|
|
|
- Line->Tokens.back().Tok->closesScope() ||
|
|
|
|
- Line->Tokens.back().Tok->isSimpleTypeSpecifier())) {
|
|
|
|
|
|
+ const FormatToken* Previous = getPreviousToken();
|
|
|
|
+ if (Previous &&
|
|
|
|
+ (Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
|
|
|
|
+ tok::kw_delete) ||
|
|
|
|
+ Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
|
|
nextToken();
|
|
nextToken();
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -1176,6 +1183,14 @@ bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
|
|
nextToken();
|
|
nextToken();
|
|
return !HasError;
|
|
return !HasError;
|
|
case tok::semi:
|
|
case tok::semi:
|
|
|
|
+ // JavaScript (or more precisely TypeScript) can have semicolons in braced
|
|
|
|
+ // lists (in so-called TypeMemberLists). Thus, the semicolon cannot be
|
|
|
|
+ // used for error recovery if we have otherwise determined that this is
|
|
|
|
+ // a braced list.
|
|
|
|
+ if (Style.Language == FormatStyle::LK_JavaScript) {
|
|
|
|
+ nextToken();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
HasError = true;
|
|
HasError = true;
|
|
if (!ContinueOnSemicolons)
|
|
if (!ContinueOnSemicolons)
|
|
return !HasError;
|
|
return !HasError;
|
|
@@ -1878,6 +1893,14 @@ void UnwrappedLineParser::nextToken() {
|
|
readToken();
|
|
readToken();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const FormatToken *UnwrappedLineParser::getPreviousToken() {
|
|
|
|
+ // FIXME: This is a dirty way to access the previous token. Find a better
|
|
|
|
+ // solution.
|
|
|
|
+ if (!Line || Line->Tokens.empty())
|
|
|
|
+ return nullptr;
|
|
|
|
+ return Line->Tokens.back().Tok;
|
|
|
|
+}
|
|
|
|
+
|
|
void UnwrappedLineParser::readToken() {
|
|
void UnwrappedLineParser::readToken() {
|
|
bool CommentsInCurrentLine = true;
|
|
bool CommentsInCurrentLine = true;
|
|
do {
|
|
do {
|