mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 10:22:05 -05:00
LibJS: Allow 'name = value' in object literals as the spec does
Currently, these are _always_ a syntax error, future commits will make it valid in certain contexts.
This commit is contained in:
parent
7dae25eceb
commit
7fc6cd6b20
2 changed files with 28 additions and 4 deletions
|
@ -1134,9 +1134,10 @@ private:
|
||||||
|
|
||||||
class ObjectExpression final : public Expression {
|
class ObjectExpression final : public Expression {
|
||||||
public:
|
public:
|
||||||
explicit ObjectExpression(SourceRange source_range, NonnullRefPtrVector<ObjectProperty> properties = {})
|
explicit ObjectExpression(SourceRange source_range, NonnullRefPtrVector<ObjectProperty> properties = {}, Optional<SourceRange> first_invalid_property_range = {})
|
||||||
: Expression(source_range)
|
: Expression(source_range)
|
||||||
, m_properties(move(properties))
|
, m_properties(move(properties))
|
||||||
|
, m_first_invalid_property_range(move(first_invalid_property_range))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,8 +1145,11 @@ public:
|
||||||
virtual void dump(int indent) const override;
|
virtual void dump(int indent) const override;
|
||||||
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
||||||
|
|
||||||
|
Optional<SourceRange> const& invalid_property_range() const { return m_first_invalid_property_range; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NonnullRefPtrVector<ObjectProperty> m_properties;
|
NonnullRefPtrVector<ObjectProperty> m_properties;
|
||||||
|
Optional<SourceRange> m_first_invalid_property_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayExpression final : public Expression {
|
class ArrayExpression final : public Expression {
|
||||||
|
|
|
@ -881,6 +881,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
|
|
||||||
NonnullRefPtrVector<ObjectProperty> properties;
|
NonnullRefPtrVector<ObjectProperty> properties;
|
||||||
ObjectProperty::Type property_type;
|
ObjectProperty::Type property_type;
|
||||||
|
Optional<SourceRange> invalid_object_literal_property_range;
|
||||||
|
|
||||||
auto skip_to_next_property = [&] {
|
auto skip_to_next_property = [&] {
|
||||||
while (!done() && !match(TokenType::Comma) && !match(TokenType::CurlyOpen))
|
while (!done() && !match(TokenType::Comma) && !match(TokenType::CurlyOpen))
|
||||||
|
@ -931,8 +932,14 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (match(TokenType::Equals)) {
|
||||||
if (match(TokenType::ParenOpen)) {
|
// Not a valid object literal, but a valid assignment target
|
||||||
|
consume();
|
||||||
|
// Parse the expression and throw it away
|
||||||
|
auto expression = parse_expression(2);
|
||||||
|
if (!invalid_object_literal_property_range.has_value())
|
||||||
|
invalid_object_literal_property_range = expression->source_range();
|
||||||
|
} else if (match(TokenType::ParenOpen)) {
|
||||||
VERIFY(property_name);
|
VERIFY(property_name);
|
||||||
u8 parse_options = FunctionNodeParseOptions::AllowSuperPropertyLookup;
|
u8 parse_options = FunctionNodeParseOptions::AllowSuperPropertyLookup;
|
||||||
if (property_type == ObjectProperty::Type::Getter)
|
if (property_type == ObjectProperty::Type::Getter)
|
||||||
|
@ -965,7 +972,10 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(TokenType::CurlyClose);
|
consume(TokenType::CurlyClose);
|
||||||
return create_ast_node<ObjectExpression>({ m_state.current_token.filename(), rule_start.position(), position() }, properties);
|
return create_ast_node<ObjectExpression>(
|
||||||
|
{ m_state.current_token.filename(), rule_start.position(), position() },
|
||||||
|
move(properties),
|
||||||
|
move(invalid_object_literal_property_range));
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
|
NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
|
||||||
|
@ -1086,6 +1096,12 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
|
||||||
{
|
{
|
||||||
auto rule_start = push_start();
|
auto rule_start = push_start();
|
||||||
auto [expression, should_continue_parsing] = parse_primary_expression();
|
auto [expression, should_continue_parsing] = parse_primary_expression();
|
||||||
|
auto check_for_invalid_object_property = [&](auto& expression) {
|
||||||
|
if (is<ObjectExpression>(*expression)) {
|
||||||
|
if (auto range = static_cast<ObjectExpression&>(*expression).invalid_property_range(); range.has_value())
|
||||||
|
syntax_error("Invalid property in object literal", range->start);
|
||||||
|
}
|
||||||
|
};
|
||||||
while (match(TokenType::TemplateLiteralStart)) {
|
while (match(TokenType::TemplateLiteralStart)) {
|
||||||
auto template_literal = parse_template_literal(true);
|
auto template_literal = parse_template_literal(true);
|
||||||
expression = create_ast_node<TaggedTemplateLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, move(expression), move(template_literal));
|
expression = create_ast_node<TaggedTemplateLiteral>({ m_state.current_token.filename(), rule_start.position(), position() }, move(expression), move(template_literal));
|
||||||
|
@ -1097,6 +1113,7 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
|
||||||
break;
|
break;
|
||||||
if (new_precedence == min_precedence && associativity == Associativity::Left)
|
if (new_precedence == min_precedence && associativity == Associativity::Left)
|
||||||
break;
|
break;
|
||||||
|
check_for_invalid_object_property(expression);
|
||||||
|
|
||||||
Associativity new_associativity = operator_associativity(m_state.current_token.type());
|
Associativity new_associativity = operator_associativity(m_state.current_token.type());
|
||||||
expression = parse_secondary_expression(move(expression), new_precedence, new_associativity);
|
expression = parse_secondary_expression(move(expression), new_precedence, new_associativity);
|
||||||
|
@ -1106,6 +1123,9 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_for_invalid_object_property(expression);
|
||||||
|
|
||||||
if (match(TokenType::Comma) && min_precedence <= 1) {
|
if (match(TokenType::Comma) && min_precedence <= 1) {
|
||||||
NonnullRefPtrVector<Expression> expressions;
|
NonnullRefPtrVector<Expression> expressions;
|
||||||
expressions.append(expression);
|
expressions.append(expression);
|
||||||
|
|
Loading…
Add table
Reference in a new issue