|
@@ -1805,6 +1805,13 @@ NonnullRefPtr<Expression const> Parser::parse_unary_prefixed_expression()
|
|
|
auto rule_start = push_start();
|
|
|
auto precedence = g_operator_precedence.get_unary(m_state.current_token.type());
|
|
|
auto associativity = operator_associativity(m_state.current_token.type());
|
|
|
+
|
|
|
+ auto verify_next_token_is_not_exponentiation = [this]() {
|
|
|
+ auto lookahead_token = next_token();
|
|
|
+ if (lookahead_token.type() == TokenType::DoubleAsterisk)
|
|
|
+ syntax_error("Unary operator must not be used before exponentiation expression without brackets");
|
|
|
+ };
|
|
|
+
|
|
|
switch (m_state.current_token.type()) {
|
|
|
case TokenType::PlusPlus: {
|
|
|
consume();
|
|
@@ -1838,27 +1845,34 @@ NonnullRefPtr<Expression const> Parser::parse_unary_prefixed_expression()
|
|
|
}
|
|
|
case TokenType::ExclamationMark:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Not, parse_expression(precedence, associativity));
|
|
|
case TokenType::Tilde:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::BitwiseNot, parse_expression(precedence, associativity));
|
|
|
case TokenType::Plus:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Plus, parse_expression(precedence, associativity));
|
|
|
case TokenType::Minus:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Minus, parse_expression(precedence, associativity));
|
|
|
case TokenType::Typeof:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Typeof, parse_expression(precedence, associativity));
|
|
|
case TokenType::Void:
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
// FIXME: This check is really hiding the fact that we don't deal with different expressions correctly.
|
|
|
if (match(TokenType::Yield) && m_state.in_generator_function_context)
|
|
|
syntax_error("'yield' is not an identifier in generator function context");
|
|
|
return create_ast_node<UnaryExpression>({ m_source_code, rule_start.position(), position() }, UnaryOp::Void, parse_expression(precedence, associativity));
|
|
|
case TokenType::Delete: {
|
|
|
consume();
|
|
|
+ verify_next_token_is_not_exponentiation();
|
|
|
auto rhs_start = position();
|
|
|
auto rhs = parse_expression(precedence, associativity);
|
|
|
if (is<Identifier>(*rhs) && m_state.strict_mode) {
|