diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/js_parser/js_parser.zig | 30 | ||||
-rw-r--r-- | src/test/fixtures/in-keyword.js | 1 |
2 files changed, 29 insertions, 2 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig index 641fa312d..e95d93bf0 100644 --- a/src/js_parser/js_parser.zig +++ b/src/js_parser/js_parser.zig @@ -3738,7 +3738,7 @@ pub const P = struct { if (p.lexer.token == .t_in) { try p.forbidInitializers(decls, "in", false); try p.lexer.next(); - const value = try p.parseExpr(.comma); + const value = try p.parseExpr(.lowest); try p.lexer.expect(.t_close_paren); var stmtOpts = ParseStatementOptions{}; const body = try p.parseStmt(&stmtOpts); @@ -4431,6 +4431,7 @@ pub const P = struct { // "in" expressions are allowed var old_allow_in = p.allow_in; p.allow_in = true; + while (p.lexer.token != .t_close_bracket) { if (p.lexer.token == .t_comma) { items.append(js_ast.ArrayBinding{ @@ -4478,6 +4479,7 @@ pub const P = struct { is_single_line = false; } } + p.allow_in = old_allow_in; if (p.lexer.has_newline_before) { @@ -6870,12 +6872,14 @@ pub const P = struct { // Arrow functions aren't allowed in the middle of expressions if (level.gt(.assign)) { + // Allow "in" inside parentheses const oldAllowIn = p.allow_in; p.allow_in = true; var value = try p.parseExpr(Level.lowest); p.markExprAsParenthesized(&value); try p.lexer.expect(.t_close_paren); + p.allow_in = oldAllowIn; return value; } @@ -6898,6 +6902,21 @@ pub const P = struct { try p.lexer.next(); return Expr{ .data = Prefill.Data.This, .loc = loc }; }, + .t_private_identifier => { + if (!p.allow_private_identifiers or !p.allow_in) { + try p.lexer.unexpected(); + } + + const name = p.lexer.identifier; + try p.lexer.next(); + + // Check for "#foo in bar" + if (p.lexer.token != .t_in) { + try p.lexer.expected(.t_in); + } + + return p.e(E.PrivateIdentifier{ .ref = try p.storeNameInRef(name) }, loc); + }, .t_identifier => { const name = p.lexer.identifier; const name_range = p.lexer.range(); @@ -7237,7 +7256,10 @@ pub const P = struct { try p.lexer.expect(.t_close_bracket); p.allow_in = old_allow_in; - if (p.willNeedBindingPattern()) {} else if (errors.isEmpty()) { + // Is this a binding pattern? + if (p.willNeedBindingPattern()) { + // noop + } else if (errors.isEmpty()) { // Is this an expression? p.logExprErrors(&self_errors); } else { @@ -11070,6 +11092,10 @@ pub const P = struct { var _parser = try allocator.create(P); _parser.* = P{ + // This must default to true or else parsing "in" won't work right. + // It will fail for the case in the "in-keyword.js" file + .allow_in = true, + .symbol_uses = SymbolUseMap.init(allocator), .call_target = nullExprData, .delete_target = nullExprData, diff --git a/src/test/fixtures/in-keyword.js b/src/test/fixtures/in-keyword.js new file mode 100644 index 000000000..cd758463e --- /dev/null +++ b/src/test/fixtures/in-keyword.js @@ -0,0 +1 @@ +const foo = "name" in Function.prototype === false; |