diff options
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibJS/Parser.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Tests/object-basic.js | 48 |
2 files changed, 56 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 6a43b17824..c8f5690798 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -1497,6 +1497,8 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression() auto lookahead_token = next_token(); if (lookahead_token.type() != TokenType::ParenOpen && lookahead_token.type() != TokenType::Colon + && lookahead_token.type() != TokenType::Comma && lookahead_token.type() != TokenType::CurlyClose + && lookahead_token.type() != TokenType::Async && !lookahead_token.trivia_contains_line_terminator()) { consume(TokenType::Async); function_kind = FunctionKind::Async; @@ -1567,6 +1569,12 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression() } properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, parse_expression(2), property_type, false)); } else if (property_name && property_value) { + if (m_state.strict_mode && is<StringLiteral>(*property_name)) { + auto& string_literal = static_cast<StringLiteral const&>(*property_name); + if (is_strict_reserved_word(string_literal.value())) + syntax_error(String::formatted("'{}' is a reserved keyword", string_literal.value())); + } + properties.append(create_ast_node<ObjectProperty>({ m_state.current_token.filename(), rule_start.position(), position() }, *property_name, *property_value, property_type, false)); } else { expected("a property"); diff --git a/Userland/Libraries/LibJS/Tests/object-basic.js b/Userland/Libraries/LibJS/Tests/object-basic.js index 5b3b78fb19..15b1906fbb 100644 --- a/Userland/Libraries/LibJS/Tests/object-basic.js +++ b/Userland/Libraries/LibJS/Tests/object-basic.js @@ -151,6 +151,54 @@ describe("side effects", () => { }); }); +describe("shorthanded properties with special names", () => { + test("keywords cannot be used", () => { + expect("({ function, })").not.toEval(); + expect("({ var, })").not.toEval(); + expect("({ const, })").not.toEval(); + expect("({ class, })").not.toEval(); + }); + + test("reserved words are allowed in non-strict mode", () => { + { + var implements = 3; + expect({ implements }).toEqual({ implements: 3 }); + } + { + var public = "a"; + expect({ public }).toEqual({ public: "a" }); + } + { + var let = 9; + expect({ let }).toEqual({ let: 9 }); + } + { + var await = 8; + expect({ await }).toEqual({ await: 8 }); + } + { + var async = 7; + expect({ async }).toEqual({ async: 7 }); + } + { + var yield = 6; + expect({ yield }).toEqual({ yield: 6 }); + } + }); + + test("reserved words are not allowed in strict mode", () => { + expect('"use strict"; var implements = 3; ({ implements })').not.toEval(); + expect("\"use strict\"; var public = 'a'; ({ public })").not.toEval(); + expect('"use strict"; var let = 9; ({ let, })').not.toEval(); + expect('"use strict"; var yield = 6; ({ yield, })').not.toEval(); + }); + + test("special non reserved words are allowed even in strict mode", () => { + expect('"use strict"; var await = 8; ({ await, })').toEval(); + expect('"use strict"; var async = 7; ({ async, })').toEval(); + }); +}); + describe("errors", () => { test("syntax errors", () => { expect("({ foo: function() { super.bar; } })").not.toEval(); |