diff --git a/Userland/Libraries/LibJS/Lexer.cpp b/Userland/Libraries/LibJS/Lexer.cpp index 450755f21f65d2..78c4c09a269ade 100644 --- a/Userland/Libraries/LibJS/Lexer.cpp +++ b/Userland/Libraries/LibJS/Lexer.cpp @@ -363,7 +363,7 @@ bool Lexer::is_whitespace() const if (!is_unicode_character()) return false; auto code_point = current_code_point(); - if (code_point == NO_BREAK_SPACE) + if (code_point == NO_BREAK_SPACE || code_point == ZERO_WIDTH_NO_BREAK_SPACE) return true; static auto space_separator_category = Unicode::general_category_from_string("Space_Separator"sv); diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 68b5e53e0962c9..190fba7908c20f 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -1518,6 +1518,7 @@ NonnullRefPtr Parser::parse_assignment_expression(Assignme parser.m_state.allow_super_property_lookup = m_state.allow_super_property_lookup; parser.m_state.allow_super_constructor_call = m_state.allow_super_constructor_call; parser.m_state.in_function_context = m_state.in_function_context; + parser.m_state.in_formal_parameter_context = m_state.in_formal_parameter_context; parser.m_state.in_generator_function_context = m_state.in_generator_function_context; parser.m_state.in_arrow_function_context = m_state.in_arrow_function_context; parser.m_state.in_break_context = m_state.in_break_context; @@ -1631,6 +1632,10 @@ NonnullRefPtr Parser::parse_new_expression() NonnullRefPtr Parser::parse_yield_expression() { auto rule_start = push_start(); + + if (m_state.in_formal_parameter_context) + syntax_error("'Yield' expression is not allowed in formal parameters of generator function"); + consume(TokenType::Yield); RefPtr argument; bool yield_from = false; @@ -1841,6 +1846,7 @@ Vector Parser::parse_formal_parameters(int& function_le auto rule_start = push_start(); bool has_default_parameter = false; bool has_rest_parameter = false; + TemporaryChange formal_parameter_context_change { m_state.in_formal_parameter_context, true }; Vector parameters; @@ -1914,8 +1920,6 @@ Vector Parser::parse_formal_parameters(int& function_le bool is_generator = parse_options & FunctionNodeParseOptions::IsGeneratorFunction; if ((is_generator || m_state.strict_mode) && default_value && default_value->fast_is() && static_cast(*default_value).string() == "yield"sv) syntax_error("Generator function parameter initializer cannot contain a reference to an identifier named \"yield\""); - if (default_value && is(*default_value)) - syntax_error("Yield expression not allowed in formal parameter"); } parameters.append({ move(parameter), default_value, is_rest }); if (match(TokenType::ParenClose)) diff --git a/Userland/Libraries/LibJS/Parser.h b/Userland/Libraries/LibJS/Parser.h index 6597072736f845..29f4c10e774d96 100644 --- a/Userland/Libraries/LibJS/Parser.h +++ b/Userland/Libraries/LibJS/Parser.h @@ -250,6 +250,7 @@ class Parser { bool allow_super_property_lookup { false }; bool allow_super_constructor_call { false }; bool in_function_context { false }; + bool in_formal_parameter_context { false }; bool in_generator_function_context { false }; bool in_arrow_function_context { false }; bool in_break_context { false }; diff --git a/Userland/Libraries/LibJS/Token.h b/Userland/Libraries/LibJS/Token.h index da5161771c40a9..c4d073219fec64 100644 --- a/Userland/Libraries/LibJS/Token.h +++ b/Userland/Libraries/LibJS/Token.h @@ -29,6 +29,9 @@ constexpr const u32 NO_BREAK_SPACE { 0x00A0 }; // U+200C ZERO WIDTH NON-JOINER constexpr const u32 ZERO_WIDTH_NON_JOINER { 0x200C }; +// U+FEFF ZERO WIDTH NO-BREAK SPACE +constexpr const u32 ZERO_WIDTH_NO_BREAK_SPACE { 0xFEFF }; + // U+200D ZERO WIDTH JOINER constexpr const u32 ZERO_WIDTH_JOINER { 0x200D };