diff options
author | 2022-02-14 19:03:25 -0800 | |
---|---|---|
committer | 2022-02-14 19:03:25 -0800 | |
commit | 423d208790d400a3676cb6f71f05b785d1939dce (patch) | |
tree | 74dddea189875e3bb2c098872a74e0626d2b9fe0 /src/json_parser.zig | |
parent | 83659b898db085c37e0cc4899d1d272763092f29 (diff) | |
download | bun-423d208790d400a3676cb6f71f05b785d1939dce.tar.gz bun-423d208790d400a3676cb6f71f05b785d1939dce.tar.zst bun-423d208790d400a3676cb6f71f05b785d1939dce.zip |
[bun.js] Handle recursive macros and handle stack overflow
Diffstat (limited to 'src/json_parser.zig')
-rw-r--r-- | src/json_parser.zig | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/src/json_parser.zig b/src/json_parser.zig index c732bfd12..c0c695e35 100644 --- a/src/json_parser.zig +++ b/src/json_parser.zig @@ -178,7 +178,11 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { is_single_line = false; } try p.lexer.expect(.t_close_bracket); - return p.e(E.Array{ .items = ExprNodeList.fromList(exprs), .is_single_line = is_single_line }, loc); + return p.e(E.Array{ + .items = ExprNodeList.fromList(exprs), + .is_single_line = is_single_line, + .was_originally_macro = comptime opts.was_originally_macro, + }, loc); }, .t_open_brace => { try p.lexer.next(); @@ -247,6 +251,7 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { return p.e(E.Object{ .properties = G.Property.List.fromList(properties), .is_single_line = is_single_line, + .was_originally_macro = comptime opts.was_originally_macro, }, loc); }, else => { @@ -482,10 +487,21 @@ const DotEnvJSONParser = JSONLikeParser(js_lexer.JSONOptions{ .allow_trailing_commas = true, .is_json = true, }); -var empty_string = E.String{ .utf8 = "" }; + const TSConfigParser = JSONLikeParser(js_lexer.JSONOptions{ .allow_comments = true, .is_json = true, .allow_trailing_commas = true }); +const JSONParserForMacro = JSONLikeParser( + js_lexer.JSONOptions{ + .allow_comments = true, + .is_json = true, + .json_warn_duplicate_keys = false, + .allow_trailing_commas = true, + .was_originally_macro = true, + }, +); + var empty_object = E.Object{}; var empty_array = E.Array{}; +var empty_string = E.String{ .utf8 = "" }; var empty_string_data = Expr.Data{ .e_string = &empty_string }; var empty_object_data = Expr.Data{ .e_object = &empty_object }; var empty_array_data = Expr.Data{ .e_array = &empty_array }; @@ -513,6 +529,29 @@ pub fn ParseJSON(source: *const logger.Source, log: *logger.Log, allocator: std. return try parser.parseExpr(false); } +pub fn ParseJSONForMacro(source: *const logger.Source, log: *logger.Log, allocator: std.mem.Allocator) !Expr { + var parser = try JSONParserForMacro.init(allocator, source.*, log); + switch (source.contents.len) { + // This is to be consisntent with how disabled JS files are handled + 0 => { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }; + }, + // This is a fast pass I guess + 2 => { + if (strings.eqlComptime(source.contents[0..1], "\"\"") or strings.eqlComptime(source.contents[0..1], "''")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_string_data }; + } else if (strings.eqlComptime(source.contents[0..1], "{}")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_object_data }; + } else if (strings.eqlComptime(source.contents[0..1], "[]")) { + return Expr{ .loc = logger.Loc{ .start = 0 }, .data = empty_array_data }; + } + }, + else => {}, + } + + return try parser.parseExpr(false); +} + pub const JSONParseResult = struct { expr: Expr, tag: Tag, |