diff options
-rw-r--r-- | .vscode/launch.json | 28 | ||||
-rw-r--r-- | .vscode/tasks.json | 8 | ||||
-rw-r--r-- | src/cli.zig | 86 | ||||
-rw-r--r-- | src/js_ast.zig | 9 | ||||
-rw-r--r-- | src/js_parser/imports.zig | 2 | ||||
-rw-r--r-- | src/js_parser/js_parser.zig | 77 | ||||
-rw-r--r-- | src/js_printer.zig | 4 | ||||
-rw-r--r-- | src/logger.zig | 6 | ||||
-rw-r--r-- | src/test/fixtures/img-bug.js | 25 |
9 files changed, 134 insertions, 111 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index 11eb418eb..db273b198 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,23 @@ "cwd": "${workspaceFolder}", "console": "internalConsole" }, + // { + // "type": "lldb", + // "request": "launch", + // "name": "Dev Launch", + // "program": "${workspaceFolder}/build/bin/debug/esdev", + // "preLaunchTask": "build", + // "args": [ + // "--resolve=dev", + // "--cwd", + // "./src/api/demo", + // "pages/index.js", + // "-o", + // "out" + // ], + // "cwd": "${workspaceFolder}", + // "console": "internalConsole" + // } { "type": "lldb", "request": "launch", @@ -20,13 +37,18 @@ "args": [ "--resolve=dev", "--cwd", - "./src/test", - "./fixtures/for-loop-bug", + "/", + "/Users/jarredsumner/Code/esdev/src/test/fixtures/img-bug.js", "-o", "out" ], "cwd": "${workspaceFolder}", - "console": "internalConsole" + "console": "internalConsole", + "presentation": { + "hidden": false, + "group": "", + "order": 1 + } } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 313818895..43bda5eea 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,6 +6,14 @@ "type": "process", "command": "zig", "args": ["build"], + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared", + "showReuseMessage": false, + "clear": false + }, "group": { "kind": "build", "isDefault": true diff --git a/src/cli.zig b/src/cli.zig index 022c09cba..d26e41d65 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -305,52 +305,52 @@ pub const Cli = struct { var writer = stdout.writer(); - // if (args.write) |write| { - // if (write) { - // did_write = true; - // var root_dir = try std.fs.openDirAbsolute(args.absolute_working_dir.?, std.fs.Dir.OpenDirOptions{}); - // defer root_dir.close(); - // for (result.output_files) |f| { - // try root_dir.makePath(std.fs.path.dirname(f.path) orelse unreachable); - - // var _handle = try std.fs.createFileAbsolute(f.path, std.fs.File.CreateFlags{ - // .truncate = true, - // }); - // try _handle.seekTo(0); - - // defer _handle.close(); - - // try _handle.writeAll(f.contents); - // } - - var max_path_len: usize = 0; - var max_padded_size: usize = 0; - for (result.output_files) |file| { - max_path_len = std.math.max(file.path.len, max_path_len); - } + if (args.write) |write| { + if (write) { + did_write = true; + var root_dir = try std.fs.openDirAbsolute(args.absolute_working_dir.?, std.fs.Dir.OpenDirOptions{}); + defer root_dir.close(); + // for (result.output_files) |f| { + // try root_dir.makePath(std.fs.path.dirname(f.path) orelse unreachable); + + // var _handle = try std.fs.createFileAbsolute(f.path, std.fs.File.CreateFlags{ + // .truncate = true, + // }); + // try _handle.seekTo(0); + + // defer _handle.close(); + + // try _handle.writeAll(f.contents); + // } + + var max_path_len: usize = 0; + var max_padded_size: usize = 0; + for (result.output_files) |file| { + max_path_len = std.math.max(file.path.len, max_path_len); + } - _ = try writer.write("\n"); - for (result.output_files) |file| { - const padding_count = 2 + (max_path_len - file.path.len); + _ = try writer.write("\n"); + for (result.output_files) |file| { + const padding_count = 2 + (max_path_len - file.path.len); + + try writer.writeByteNTimes(' ', 2); + try writer.writeAll(file.path); + try writer.writeByteNTimes(' ', padding_count); + const size = @intToFloat(f64, file.contents.len) / 1000.0; + try std.fmt.formatFloatDecimal(size, .{ .precision = 2 }, writer); + try writer.writeAll(" KB\n"); + } + } + } - try writer.writeByteNTimes(' ', 2); - try writer.writeAll(file.path); - try writer.writeByteNTimes(' ', padding_count); - const size = @intToFloat(f64, file.contents.len) / 1000.0; - try std.fmt.formatFloatDecimal(size, .{ .precision = 2 }, writer); - try writer.writeAll(" KB\n"); + if (!did_write) { + for (result.output_files) |file, i| { + try writer.writeAll(file.contents); + if (i > 0) { + _ = try writer.write("\n\n"); + } + } } - // } - // } - - // if (!did_write) { - // for (result.output_files) |file, i| { - // try writer.writeAll(file.contents); - // if (i > 0) { - // _ = try writer.write("\n\n"); - // } - // } - // } var err_writer = stderr.writer(); for (result.errors) |err| { diff --git a/src/js_ast.zig b/src/js_ast.zig index b2e3a6ecb..e3b1c62d5 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -950,7 +950,7 @@ pub const E = struct { } } - pub fn string(s: *String, allocator: *std.mem.Allocator) !string { + pub fn string(s: *const String, allocator: *std.mem.Allocator) !string { if (s.isUTF8()) { return s.utf8; } else { @@ -1387,13 +1387,13 @@ pub const Expr = struct { pub fn getProperty(expr: *const Expr, name: string) ?Query { if (std.meta.activeTag(expr.data) != .e_object) return null; - const obj: *E.Object = expr.data.e_object; + const obj: *const E.Object = expr.data.e_object; for (obj.properties) |prop| { const value = prop.value orelse continue; const key = prop.key orelse continue; if (std.meta.activeTag(key.data) != .e_string) continue; - const key_str: *E.String = key.data.e_string; + const key_str: *const E.String = key.data.e_string; if (key_str.eql(string, name)) { return Query{ .expr = value, .loc = key.loc }; } @@ -1405,7 +1405,7 @@ pub const Expr = struct { pub fn getString(expr: *const Expr, allocator: *std.mem.Allocator) ?string { if (std.meta.activeTag(expr.data) != .e_string) return null; - const key_str: *E.String = expr.data.e_string; + const key_str: *const E.String = expr.data.e_string; return if (key_str.isUTF8()) key_str.utf8 else key_str.string(allocator) catch null; } @@ -3193,6 +3193,7 @@ pub const StrictModeKind = packed enum(u7) { }; pub const Scope = struct { + id: usize = 0, kind: Kind = Kind.block, parent: ?*Scope, children: std.ArrayList(*Scope), diff --git a/src/js_parser/imports.zig b/src/js_parser/imports.zig index 9ac9f2a3e..fcda8b9f5 100644 --- a/src/js_parser/imports.zig +++ b/src/js_parser/imports.zig @@ -37,4 +37,4 @@ pub const Symbol = js_ast.Symbol; pub const Level = js_ast.Op.Level; pub const Op = js_ast.Op; pub const Scope = js_ast.Scope; -pub const locModuleScope = logger.Loc.Empty; +pub const locModuleScope = logger.Loc{ .start = -100 }; diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig index 4441a7867..cb48f08e3 100644 --- a/src/js_parser/js_parser.zig +++ b/src/js_parser/js_parser.zig @@ -1,6 +1,10 @@ usingnamespace @import("imports.zig"); const TemplatePartTuple = std.meta.Tuple(&[_]type{ []E.TemplatePart, logger.Loc }); +const ScopeOrderList = std.ArrayListUnmanaged(?ScopeOrder); + +var panic_buffer = std.mem.zeros(32 * 1024); +var panic_stream = std.io.fixedBufferStream(&panic_buffer); pub fn ExpressionTransposer(comptime ctx: type, visitor: fn (ptr: *ctx, arg: Expr, state: anytype) Expr) type { return struct { @@ -1573,7 +1577,7 @@ pub const P = struct { module_ref: js_ast.Ref = js_ast.Ref.None, import_meta_ref: js_ast.Ref = js_ast.Ref.None, promise_ref: ?js_ast.Ref = null, - + scopes_in_order_visitor_index: usize = 0, has_classic_runtime_warned: bool = false, data: js_ast.AstData, @@ -1652,7 +1656,7 @@ pub const P = struct { // symbols must be separate from the pass that binds identifiers to declared // symbols to handle declaring a hoisted "var" symbol in a nested scope and // binding a name to it in a parent or sibling scope. - scopes_in_order: std.ArrayListUnmanaged(?ScopeOrder), + scopes_in_order: ScopeOrderList, // These properties are for the visit pass, which runs after the parse pass. // The visit pass binds identifiers to declared symbols, does constant @@ -2261,22 +2265,26 @@ pub const P = struct { } } - pub fn pushScopeForVisitPass(p: *P, comptime kind: js_ast.Scope.Kind, loc: logger.Loc) !void { - assert(p.scopes_in_order.items.len > 0); - var i: usize = 0; - while (p.scopes_in_order.items[i] == null and i < p.scopes_in_order.items.len) : (i += 1) {} - const order = p.scopes_in_order.items[i].?; - i += 1; - if (p.scopes_in_order.items.len > i) { - p.scopes_in_order.items = p.scopes_in_order.items[i..p.scopes_in_order.items.len]; - } else { - p.scopes_in_order.items = &([_]?ScopeOrder{}); + pub fn nextScopeInOrderForVisitPass(p: *P) ScopeOrder { + while (p.scopes_in_order.items[p.scopes_in_order_visitor_index] == null) { + p.scopes_in_order_visitor_index += 1; + } + const scope_order = p.scopes_in_order.items[p.scopes_in_order_visitor_index].?; + p.scopes_in_order_visitor_index += 1; + return scope_order; + } + + pub fn pushScopeForVisitPass(p: *P, kind: js_ast.Scope.Kind, loc: logger.Loc) !void { + for (p.scopes_in_order.items[p.scopes_in_order_visitor_index..p.scopes_in_order.items.len]) |scope_order, i| { + if (scope_order) |ord| { + Output.print("Scope ({d}, {d})\n", .{ @enumToInt(ord.scope.kind), ord.loc.start }); + } } + const order = p.nextScopeInOrderForVisitPass(); // Sanity-check that the scopes generated by the first and second passes match if (order.loc.start != loc.start or order.scope.kind != kind) { - Output.print("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start }); - p.panic("", .{}); + p.panic("Expected scope ({s}, {d}) in {s}, found scope ({s}, {d})", .{ kind, loc.start, p.source.path.pretty, order.scope.kind, order.loc.start }); } p.current_scope = order.scope; @@ -2284,21 +2292,27 @@ pub const P = struct { try p.scopes_for_current_part.append(order.scope); } - pub fn pushScopeForParsePass(p: *P, comptime kind: js_ast.Scope.Kind, loc: logger.Loc) !usize { + pub fn pushScopeForParsePass(p: *P, kind: js_ast.Scope.Kind, loc: logger.Loc) !usize { debugl("<pushScopeForParsePass>"); defer debugl("</pushScopeForParsePass>"); - var scope = try Scope.initPtr(p.allocator); - scope.kind = kind; - scope.label_ref = null; + var parent: *Scope = p.current_scope; + p.scope_id += 1; - var parent: *Scope = undefined; + var scope = try p.allocator.create(Scope); + scope.* = Scope{ + .members = @TypeOf(scope.members).init(p.allocator), + .children = @TypeOf(scope.children).init( + p.allocator, + ), + .generated = @TypeOf(scope.generated).init(p.allocator), + .kind = kind, + .label_ref = null, + .parent = parent, + .id = p.scope_id, + }; - if (kind != .entry) { - parent = p.current_scope; - scope.parent = parent; - try parent.children.append(scope); - scope.strict_mode = parent.strict_mode; - } + try parent.children.append(scope); + scope.strict_mode = parent.strict_mode; p.current_scope = scope; @@ -5083,8 +5097,7 @@ pub const P = struct { p.fn_or_arrow_data_parse = old_fn_or_arrow_data; var stmts = try p.allocator.alloc(Stmt, 1); - stmts[0] = p.s(S.Return{ .value = expr }, arrow_loc); - + stmts[0] = p.s(S.Return{ .value = expr }, expr.loc); return E.Arrow{ .args = args, .prefer_expr = true, .body = G.FnBody{ .loc = arrow_loc, .stmts = stmts } }; } @@ -6742,12 +6755,8 @@ pub const P = struct { pub fn panic(p: *P, comptime str: string, args: anytype) noreturn { p.log.addRangeErrorFmt(p.source, p.lexer.range(), p.allocator, str, args) catch unreachable; - - var fixedBuffer = [_]u8{0} ** (1024 * 1024); - var stream = std.io.fixedBufferStream(&fixedBuffer); - - p.log.print(stream.writer()) catch unreachable; - Global.panic("{s}", .{fixedBuffer}); + p.log.print(panic_stream.writer()) catch unreachable; + Global.panic("{s}", .{panic_buffer}); } pub fn _parsePrefix(p: *P, level: Level, errors: *DeferredErrors, flags: Expr.EFlags) anyerror!Expr { @@ -10959,7 +10968,7 @@ pub const P = struct { } pub fn init(allocator: *std.mem.Allocator, log: *logger.Log, source: *const logger.Source, define: *Define, lexer: js_lexer.Lexer, opts: Parser.Options) !*P { - var scope_order = try std.ArrayListUnmanaged(?ScopeOrder).initCapacity(allocator, 1); + var scope_order = try ScopeOrderList.initCapacity(allocator, 1); var scope = try allocator.create(Scope); scope.* = Scope{ .members = @TypeOf(scope.members).init(allocator), diff --git a/src/js_printer.zig b/src/js_printer.zig index 0f5b41123..f3b735688 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -2618,7 +2618,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type { }, } } - pub fn printIf(p: *Printer, s: *S.If) void { + pub fn printIf(p: *Printer, s: *const S.If) void { p.printSpaceBeforeIdentifier(); p.print("if"); p.printSpace(); @@ -2693,7 +2693,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type { } } - pub fn wrapToAvoidAmbiguousElse(_s: *Stmt.Data) bool { + pub fn wrapToAvoidAmbiguousElse(_s: *const Stmt.Data) bool { var s = _s; while (true) { diff --git a/src/logger.zig b/src/logger.zig index 72c7ebc3d..98149cb5b 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -366,11 +366,7 @@ pub const Log = struct { }; pub fn usize2Loc(loc: usize) Loc { - if (loc > std.math.maxInt(i32)) { - return Loc.Empty; - } else { - return Loc{ .start = @intCast(i32, loc) }; - } + return Loc{ .start = std.math.lossyCast(i32, loc) }; } pub const Source = struct { diff --git a/src/test/fixtures/img-bug.js b/src/test/fixtures/img-bug.js index 207f59a09..1d5ec8a82 100644 --- a/src/test/fixtures/img-bug.js +++ b/src/test/fixtures/img-bug.js @@ -1,23 +1,10 @@ -function get() { - if (true) { - if (true) { - if (true) { - console.log("HI"); - if (true) { - return { hi: () => true }; - } - } - } +const hi = () => ({ + its_ireelevant: () => true, +}); +const hey = () => ({ + any_name_will_do: () => true, +}); - if (true) { - if (true) { - if (true) { - return { hi: () => true }; - } - } - } - } -} // function getWidths(width, layout, sizes) { // if (sizes && (layout === "fill" || layout === "responsive")) { // // Find all the "vw" percent sizes used in the sizes prop |