Commit c7328012 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[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: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56779}
parent d5ee4622
...@@ -712,8 +712,8 @@ class ParserBase { ...@@ -712,8 +712,8 @@ class ParserBase {
Next(); Next();
return; return;
} }
if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::RBRACE || if (scanner()->HasLineTerminatorBeforeNext() ||
tok == Token::EOS) { Token::IsAutoSemicolon(tok)) {
return; return;
} }
...@@ -5131,8 +5131,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement( ...@@ -5131,8 +5131,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
Expect(Token::CONTINUE, CHECK_OK); Expect(Token::CONTINUE, CHECK_OK);
IdentifierT label = impl()->NullIdentifier(); IdentifierT label = impl()->NullIdentifier();
Token::Value tok = peek(); Token::Value tok = peek();
if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON && if (!scanner()->HasLineTerminatorBeforeNext() &&
tok != Token::RBRACE && tok != Token::EOS) { !Token::IsAutoSemicolon(tok)) {
// ECMA allows "eval" or "arguments" as labels even in strict mode. // ECMA allows "eval" or "arguments" as labels even in strict mode.
label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
} }
...@@ -5168,8 +5168,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement( ...@@ -5168,8 +5168,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
Expect(Token::BREAK, CHECK_OK); Expect(Token::BREAK, CHECK_OK);
IdentifierT label = impl()->NullIdentifier(); IdentifierT label = impl()->NullIdentifier();
Token::Value tok = peek(); Token::Value tok = peek();
if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON && if (!scanner()->HasLineTerminatorBeforeNext() &&
tok != Token::RBRACE && tok != Token::EOS) { !Token::IsAutoSemicolon(tok)) {
// ECMA allows "eval" or "arguments" as labels even in strict mode. // ECMA allows "eval" or "arguments" as labels even in strict mode.
label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
} }
...@@ -5222,8 +5222,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement( ...@@ -5222,8 +5222,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
Token::Value tok = peek(); Token::Value tok = peek();
ExpressionT return_value = impl()->NullExpression(); ExpressionT return_value = impl()->NullExpression();
if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::SEMICOLON || if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
tok == Token::RBRACE || tok == Token::EOS) {
if (IsDerivedConstructor(function_state_->kind())) { if (IsDerivedConstructor(function_state_->kind())) {
return_value = impl()->ThisExpression(loc.beg_pos); return_value = impl()->ThisExpression(loc.beg_pos);
} }
......
...@@ -55,8 +55,6 @@ namespace internal { ...@@ -55,8 +55,6 @@ namespace internal {
T(name, string, precedence) T(name, string, precedence)
#define TOKEN_LIST(T, K, C) \ #define TOKEN_LIST(T, K, C) \
/* End of source indicator. */ \
T(EOS, "EOS", 0) \
\ \
/* BEGIN PropertyOrCall */ \ /* BEGIN PropertyOrCall */ \
/* ES6 Template Literals */ \ /* ES6 Template Literals */ \
...@@ -71,14 +69,18 @@ namespace internal { ...@@ -71,14 +69,18 @@ namespace internal {
T(RPAREN, ")", 0) \ T(RPAREN, ")", 0) \
T(RBRACK, "]", 0) \ T(RBRACK, "]", 0) \
T(LBRACE, "{", 0) \ T(LBRACE, "{", 0) \
T(RBRACE, "}", 0) \
T(COLON, ":", 0) \ T(COLON, ":", 0) \
T(SEMICOLON, ";", 0) \
T(ELLIPSIS, "...", 0) \ T(ELLIPSIS, "...", 0) \
T(CONDITIONAL, "?", 3) \ T(CONDITIONAL, "?", 3) \
T(INC, "++", 0) \ T(INC, "++", 0) \
T(DEC, "--", 0) \ T(DEC, "--", 0) \
T(ARROW, "=>", 0) \ T(ARROW, "=>", 0) \
/* BEGIN AutoSemicolon */ \
T(SEMICOLON, ";", 0) \
T(RBRACE, "}", 0) \
/* End of source indicator. */ \
T(EOS, "EOS", 0) \
/* END AutoSemicolon */ \
\ \
/* Assignment operators. */ \ /* Assignment operators. */ \
/* IsAssignmentOp() relies on this block of enum values being */ \ /* IsAssignmentOp() relies on this block of enum values being */ \
...@@ -241,6 +243,10 @@ class Token { ...@@ -241,6 +243,10 @@ class Token {
static bool IsCallable(Value token) { return IsInRange(token, SUPER, ENUM); } 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) { static bool IsAnyIdentifier(Value token) {
return IsInRange(token, IDENTIFIER, ENUM); return IsInRange(token, IDENTIFIER, ENUM);
} }
......
...@@ -79,6 +79,24 @@ TEST(IsContextualKeyword) { ...@@ -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) { bool TokenIsAnyIdentifier(Token::Value token) {
switch (token) { switch (token) {
case Token::IDENTIFIER: case Token::IDENTIFIER:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment