|
@@ -1458,11 +1458,11 @@ Parser::PrimaryExpressionParseResult Parser::parse_primary_expression()
|
|
|
case TokenType::BigIntLiteral:
|
|
|
return { create_ast_node<BigIntLiteral>({ m_source_code, rule_start.position(), position() }, consume().value()) };
|
|
|
case TokenType::BoolLiteral:
|
|
|
- return { create_ast_node<BooleanLiteral>({ m_source_code, rule_start.position(), position() }, consume().bool_value()) };
|
|
|
+ return { create_ast_node<BooleanLiteral>({ m_source_code, rule_start.position(), position() }, consume_and_allow_division().bool_value()) };
|
|
|
case TokenType::StringLiteral:
|
|
|
return { parse_string_literal(consume()) };
|
|
|
case TokenType::NullLiteral:
|
|
|
- consume();
|
|
|
+ consume_and_allow_division();
|
|
|
return { create_ast_node<NullLiteral>({ m_source_code, rule_start.position(), position() }) };
|
|
|
case TokenType::CurlyOpen:
|
|
|
return { parse_object_expression() };
|
|
@@ -2168,7 +2168,7 @@ Parser::ExpressionResult Parser::parse_secondary_expression(NonnullRefPtr<Expres
|
|
|
expected("IdentifierName");
|
|
|
}
|
|
|
|
|
|
- return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, consume().DeprecatedFlyString_value()));
|
|
|
+ return create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), create_ast_node<Identifier>({ m_source_code, rule_start.position(), position() }, consume_and_allow_division().DeprecatedFlyString_value()));
|
|
|
case TokenType::BracketOpen: {
|
|
|
consume(TokenType::BracketOpen);
|
|
|
auto expression = create_ast_node<MemberExpression>({ m_source_code, rule_start.position(), position() }, move(lhs), parse_expression(0), true);
|
|
@@ -4010,6 +4010,18 @@ bool Parser::done() const
|
|
|
}
|
|
|
|
|
|
Token Parser::consume()
|
|
|
+{
|
|
|
+ auto old_token = m_state.current_token;
|
|
|
+ m_state.current_token = m_state.lexer.next();
|
|
|
+
|
|
|
+ // If an IdentifierName is not parsed as an Identifier a slash after it should not be a division
|
|
|
+ if (old_token.is_identifier_name() && (m_state.current_token.type() == TokenType::Slash || m_state.current_token.type() == TokenType::SlashEquals)) {
|
|
|
+ m_state.current_token = m_state.lexer.force_slash_as_regex();
|
|
|
+ }
|
|
|
+ return old_token;
|
|
|
+}
|
|
|
+
|
|
|
+Token Parser::consume_and_allow_division()
|
|
|
{
|
|
|
auto old_token = m_state.current_token;
|
|
|
m_state.current_token = m_state.lexer.next();
|
|
@@ -4057,26 +4069,26 @@ Token Parser::consume_identifier()
|
|
|
if (match(TokenType::Let)) {
|
|
|
if (m_state.strict_mode)
|
|
|
syntax_error("'let' is not allowed as an identifier in strict mode");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Yield)) {
|
|
|
if (m_state.strict_mode || m_state.in_generator_function_context)
|
|
|
syntax_error("Identifier must not be a reserved word in strict mode ('yield')");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Await)) {
|
|
|
if (m_program_type == Program::Type::Module || m_state.await_expression_is_valid || m_state.in_class_static_init_block)
|
|
|
syntax_error("Identifier must not be a reserved word in modules ('await')");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Async))
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
|
|
|
expected("Identifier");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
// https://tc39.es/ecma262/#prod-IdentifierReference
|
|
@@ -4092,33 +4104,33 @@ Token Parser::consume_identifier_reference()
|
|
|
if (m_program_type == Program::Type::Module && name == "await"sv)
|
|
|
syntax_error("'await' is not allowed as an identifier in module");
|
|
|
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
// See note in Parser::parse_identifier().
|
|
|
if (match(TokenType::Let)) {
|
|
|
if (m_state.strict_mode)
|
|
|
syntax_error("'let' is not allowed as an identifier in strict mode");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Yield)) {
|
|
|
if (m_state.strict_mode)
|
|
|
syntax_error("Identifier reference may not be 'yield' in strict mode");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Await)) {
|
|
|
if (m_program_type == Program::Type::Module)
|
|
|
syntax_error("'await' is not allowed as an identifier in module");
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
if (match(TokenType::Async))
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
|
|
|
expected(Token::name(TokenType::Identifier));
|
|
|
- return consume();
|
|
|
+ return consume_and_allow_division();
|
|
|
}
|
|
|
|
|
|
Token Parser::consume(TokenType expected_type)
|
|
@@ -4126,7 +4138,7 @@ Token Parser::consume(TokenType expected_type)
|
|
|
if (!match(expected_type)) {
|
|
|
expected(Token::name(expected_type));
|
|
|
}
|
|
|
- auto token = consume();
|
|
|
+ auto token = expected_type == TokenType::Identifier ? consume_and_allow_division() : consume();
|
|
|
if (expected_type == TokenType::Identifier) {
|
|
|
if (m_state.strict_mode && is_strict_reserved_word(token.value()))
|
|
|
syntax_error(DeprecatedString::formatted("Identifier must not be a reserved word in strict mode ('{}')", token.value()));
|