[parser] Introduce a range for automatic semicolon insertion tokens

Change-Id: Ib41ddbf15c6f9395b747b78c081e466a9f2e44bd
Reviewed-on: https://chromium-review.googlesource.com/c/1286682
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56779}
This commit is contained in:
Toon Verwaest 2018-10-17 16:25:44 +02:00 committed by Commit Bot
parent d5ee4622dd
commit c732801267
3 changed files with 35 additions and 12 deletions

View File

@ -712,8 +712,8 @@ class ParserBase {
Next();
return;
}
if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::RBRACE ||
tok == Token::EOS) {
if (scanner()->HasLineTerminatorBeforeNext() ||
Token::IsAutoSemicolon(tok)) {
return;
}
@ -5131,8 +5131,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
Expect(Token::CONTINUE, CHECK_OK);
IdentifierT label = impl()->NullIdentifier();
Token::Value tok = peek();
if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
tok != Token::RBRACE && tok != Token::EOS) {
if (!scanner()->HasLineTerminatorBeforeNext() &&
!Token::IsAutoSemicolon(tok)) {
// ECMA allows "eval" or "arguments" as labels even in strict mode.
label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
}
@ -5168,8 +5168,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
Expect(Token::BREAK, CHECK_OK);
IdentifierT label = impl()->NullIdentifier();
Token::Value tok = peek();
if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
tok != Token::RBRACE && tok != Token::EOS) {
if (!scanner()->HasLineTerminatorBeforeNext() &&
!Token::IsAutoSemicolon(tok)) {
// ECMA allows "eval" or "arguments" as labels even in strict mode.
label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
}
@ -5222,8 +5222,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
Token::Value tok = peek();
ExpressionT return_value = impl()->NullExpression();
if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
tok == Token::RBRACE || tok == Token::EOS) {
if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
if (IsDerivedConstructor(function_state_->kind())) {
return_value = impl()->ThisExpression(loc.beg_pos);
}

View File

@ -55,8 +55,6 @@ namespace internal {
T(name, string, precedence)
#define TOKEN_LIST(T, K, C) \
/* End of source indicator. */ \
T(EOS, "EOS", 0) \
\
/* BEGIN PropertyOrCall */ \
/* ES6 Template Literals */ \
@ -71,14 +69,18 @@ namespace internal {
T(RPAREN, ")", 0) \
T(RBRACK, "]", 0) \
T(LBRACE, "{", 0) \
T(RBRACE, "}", 0) \
T(COLON, ":", 0) \
T(SEMICOLON, ";", 0) \
T(ELLIPSIS, "...", 0) \
T(CONDITIONAL, "?", 3) \
T(INC, "++", 0) \
T(DEC, "--", 0) \
T(ARROW, "=>", 0) \
/* BEGIN AutoSemicolon */ \
T(SEMICOLON, ";", 0) \
T(RBRACE, "}", 0) \
/* End of source indicator. */ \
T(EOS, "EOS", 0) \
/* END AutoSemicolon */ \
\
/* Assignment operators. */ \
/* IsAssignmentOp() relies on this block of enum values being */ \
@ -241,6 +243,10 @@ class Token {
static bool IsCallable(Value token) { return IsInRange(token, SUPER, ENUM); }
static bool IsAutoSemicolon(Value token) {
return IsInRange(token, SEMICOLON, EOS);
}
static bool IsAnyIdentifier(Value token) {
return IsInRange(token, IDENTIFIER, ENUM);
}

View File

@ -79,6 +79,24 @@ TEST(IsContextualKeyword) {
}
}
bool TokenIsAutoSemicolon(Token::Value token) {
switch (token) {
case Token::SEMICOLON:
case Token::EOS:
case Token::RBRACE:
return true;
default:
return false;
}
}
TEST(AutoSemicolonToken) {
for (int i = 0; i < Token::NUM_TOKENS; i++) {
Token::Value token = static_cast<Token::Value>(i);
CHECK_EQ(TokenIsAutoSemicolon(token), Token::IsAutoSemicolon(token));
}
}
bool TokenIsAnyIdentifier(Token::Value token) {
switch (token) {
case Token::IDENTIFIER: