diff options
| author | 2021-09-16 17:37:22 -0700 | |
|---|---|---|
| committer | 2021-09-16 17:37:22 -0700 | |
| commit | 9511bf94d5eac2360e1d8bf201c1f3195f919763 (patch) | |
| tree | 6de440cbac834f50106b52ac5c9f4770206e3bd9 /src | |
| parent | 03983ac24ee48fecc3364bcb50570f1476cf6acd (diff) | |
| download | bun-9511bf94d5eac2360e1d8bf201c1f3195f919763.tar.gz bun-9511bf94d5eac2360e1d8bf201c1f3195f919763.tar.zst bun-9511bf94d5eac2360e1d8bf201c1f3195f919763.zip | |
Colorize build/resolve errors and add a ^
Diffstat (limited to 'src')
| -rw-r--r-- | src/cli/build_command.zig | 26 | ||||
| -rw-r--r-- | src/cli/bun_command.zig | 4 | ||||
| -rw-r--r-- | src/global.zig | 37 | ||||
| -rw-r--r-- | src/http.zig | 42 | ||||
| -rw-r--r-- | src/javascript/jsc/javascript.zig | 14 | ||||
| -rw-r--r-- | src/js_parser/js_parser.zig | 9 | ||||
| -rw-r--r-- | src/logger.zig | 205 |
7 files changed, 210 insertions, 127 deletions
diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig index 0779a691a..2a85f48b2 100644 --- a/src/cli/build_command.zig +++ b/src/cli/build_command.zig @@ -140,14 +140,26 @@ pub const BuildCommand = struct { }) catch {}; } - for (result.errors) |err| { - try err.writeFormat(err_writer); - _ = try err_writer.write("\n"); - } + if (Output.enable_ansi_colors) { + for (result.errors) |err| { + try err.writeFormat(err_writer, true); + _ = try err_writer.write("\n"); + } + + for (result.warnings) |err| { + try err.writeFormat(err_writer, true); + _ = try err_writer.write("\n"); + } + } else { + for (result.errors) |err| { + try err.writeFormat(err_writer, false); + _ = try err_writer.write("\n"); + } - for (result.warnings) |err| { - try err.writeFormat(err_writer); - _ = try err_writer.write("\n"); + for (result.warnings) |err| { + try err.writeFormat(err_writer, false); + _ = try err_writer.write("\n"); + } } const duration = std.time.nanoTimestamp() - ctx.start_time; diff --git a/src/cli/bun_command.zig b/src/cli/bun_command.zig index afe2a345a..32b62367d 100644 --- a/src/cli/bun_command.zig +++ b/src/cli/bun_command.zig @@ -170,7 +170,7 @@ pub const BunCommand = struct { if (node_modules_) |node_modules| { if (log.errors > 0) { - try log.print(Output.errorWriter()); + try log.printForLogLevel(Output.errorWriter()); } else { var elapsed = @divTrunc(std.time.nanoTimestamp() - ctx.start_time, @as(i128, std.time.ns_per_ms)); const print_summary = !(ctx.args.no_summary orelse false); @@ -190,7 +190,7 @@ pub const BunCommand = struct { try log.printForLogLevel(Output.errorWriter()); } } else { - try log.print(Output.errorWriter()); + try log.printForLogLevel(Output.errorWriter()); } } } diff --git a/src/global.zig b/src/global.zig index 1d696cc65..1fec9ac5c 100644 --- a/src/global.zig +++ b/src/global.zig @@ -192,10 +192,23 @@ pub const Output = struct { // <d> - dim // </r> - reset // <r> - reset + const ED = "\x1b["; + pub const color_map = std.ComptimeStringMap(string, .{ + &.{ "black", ED ++ "30m" }, + &.{ "blue", ED ++ "34m" }, + &.{ "b", ED ++ "1m" }, + &.{ "d", ED ++ "2m" }, + &.{ "cyan", ED ++ "36m" }, + &.{ "green", ED ++ "32m" }, + &.{ "magenta", ED ++ "35m" }, + &.{ "red", ED ++ "31m" }, + &.{ "white", ED ++ "37m" }, + &.{ "yellow", ED ++ "33m" }, + }); + pub fn prettyFmt(comptime fmt: string, comptime is_enabled: bool) string { comptime var new_fmt: [fmt.len * 4]u8 = undefined; comptime var new_fmt_i: usize = 0; - const ED = comptime "\x1b["; @setEvalBranchQuota(9999); comptime var i: usize = 0; @@ -239,26 +252,8 @@ pub const Output = struct { const color_name = fmt[start..i]; const color_str = color_picker: { - if (std.mem.eql(u8, color_name, "black")) { - break :color_picker ED ++ "30m"; - } else if (std.mem.eql(u8, color_name, "blue")) { - break :color_picker ED ++ "34m"; - } else if (std.mem.eql(u8, color_name, "b")) { - break :color_picker ED ++ "1m"; - } else if (std.mem.eql(u8, color_name, "d")) { - break :color_picker ED ++ "2m"; - } else if (std.mem.eql(u8, color_name, "cyan")) { - break :color_picker ED ++ "36m"; - } else if (std.mem.eql(u8, color_name, "green")) { - break :color_picker ED ++ "32m"; - } else if (std.mem.eql(u8, color_name, "magenta")) { - break :color_picker ED ++ "35m"; - } else if (std.mem.eql(u8, color_name, "red")) { - break :color_picker ED ++ "31m"; - } else if (std.mem.eql(u8, color_name, "white")) { - break :color_picker ED ++ "37m"; - } else if (std.mem.eql(u8, color_name, "yellow")) { - break :color_picker ED ++ "33m"; + if (color_map.get(color_name)) |color_name_literal| { + break :color_picker color_name_literal; } else if (std.mem.eql(u8, color_name, "r")) { is_reset = true; break :color_picker ""; diff --git a/src/http.zig b/src/http.zig index 65a769e59..93deb5556 100644 --- a/src/http.zig +++ b/src/http.zig @@ -957,9 +957,17 @@ pub const RequestContext = struct { defer this.log.msgs.clearRetainingCapacity(); - if (this.log.msgs.items.len > 0) { - for (this.log.msgs.items) |msg| { - msg.writeFormat(Output.errorWriter()) catch continue; + if (Output.enable_ansi_colors) { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), true) catch continue; + } + } + } else { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), false) catch continue; + } } } @@ -995,9 +1003,17 @@ pub const RequestContext = struct { &exception_list, ); } else { - if (this.log.msgs.items.len > 0) { - for (this.log.msgs.items) |msg| { - msg.writeFormat(Output.errorWriter()) catch continue; + if (Output.enable_ansi_colors) { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), true) catch continue; + } + } + } else { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), false) catch continue; + } } } @@ -1036,9 +1052,17 @@ pub const RequestContext = struct { ); did_log_messages = start_count != this.log.msgs.items.len and exception_list.items.len == 0; } else { - if (this.log.msgs.items.len > 0) { - for (this.log.msgs.items) |msg| { - msg.writeFormat(Output.errorWriter()) catch continue; + if (Output.enable_ansi_colors) { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), true) catch continue; + } + } + } else { + if (this.log.msgs.items.len > 0) { + for (this.log.msgs.items) |msg| { + msg.writeFormat(Output.errorWriter(), false) catch continue; + } } } diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig index a84437851..bd9b470a9 100644 --- a/src/javascript/jsc/javascript.zig +++ b/src/javascript/jsc/javascript.zig @@ -834,9 +834,17 @@ pub const VirtualMachine = struct { if (log.warnings > 0) { var writer = Output.errorWriter(); - for (log.msgs.items) |msg| { - if (msg.kind == .warn) { - msg.writeFormat(writer) catch {}; + if (Output.enable_ansi_colors) { + for (log.msgs.items) |msg| { + if (msg.kind == .warn) { + msg.writeFormat(writer, true) catch {}; + } + } + } else { + for (log.msgs.items) |msg| { + if (msg.kind == .warn) { + msg.writeFormat(writer, false) catch {}; + } } } } diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig index d4dc4f0d0..1c70212a0 100644 --- a/src/js_parser/js_parser.zig +++ b/src/js_parser/js_parser.zig @@ -3237,8 +3237,8 @@ pub fn NewParser( js_lexer.rangeOfIdentifier(p.source, loc), p.allocator, notes, - "Multiple exports with the same name {s}", - .{alias}, + "Multiple exports with the same name \"{s}\"", + .{std.mem.trim(u8, alias, "\"'")}, ); } else { try p.named_exports.put(alias, js_ast.NamedExport{ .alias_loc = loc, .ref = ref }); @@ -9467,7 +9467,10 @@ pub fn NewParser( var panic_buffer = p.allocator.alloc(u8, 32 * 1024) catch unreachable; var panic_stream = std.io.fixedBufferStream(panic_buffer); p.log.addRangeErrorFmt(p.source, p.lexer.range(), p.allocator, str, args) catch unreachable; - p.log.print(panic_stream.writer()) catch unreachable; + + p.log.printForLogLevel( + panic_stream.writer(), + ) catch unreachable; Global.panic("{s}", .{panic_buffer[0..panic_stream.pos]}); } diff --git a/src/logger.zig b/src/logger.zig index b693584a4..177bee189 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -61,12 +61,10 @@ pub const Loc = packed struct { return if (loc.start == -1) null else loc.*; } - // TODO: remove this stupidity pub inline fn toUsize(self: *const Loc) usize { return @intCast(usize, self.start); } - // TODO: remove this stupidity pub inline fn i(self: *const Loc) usize { return @intCast(usize, self.start); } @@ -179,24 +177,123 @@ pub const Data = struct { this: *const Data, to: anytype, kind: Kind, + comptime enable_ansi_colors: bool, + comptime is_note: bool, ) !void { if (this.text.len == 0) return; + const message_color = switch (kind) { + .err => comptime Output.color_map.get("b").?, + .note => comptime Output.color_map.get("cyan").? ++ Output.color_map.get("d").?, + else => comptime Output.color_map.get("d").? ++ Output.color_map.get("b").?, + }; + + const color_name: string = switch (kind) { + .err => comptime Output.color_map.get("red").?, + .note => comptime Output.color_map.get("cyan").?, + else => comptime Output.color_map.get("d").?, + }; + + try to.writeAll("\n\n"); + + if (comptime enable_ansi_colors) { + try to.writeAll(color_name); + } + + try to.writeAll(kind.string()); + + try std.fmt.format(to, comptime Output.prettyFmt("<r><d>: <r>", enable_ansi_colors), .{}); + + if (comptime enable_ansi_colors) { + try to.writeAll(message_color); + } + + try std.fmt.format(to, comptime Output.prettyFmt("{s}<r>\n", enable_ansi_colors), .{this.text}); + if (this.location) |location| { - try std.fmt.format(to, "\n\n{s}: {s}\n{s}\n{s}:{}:{} {d}", .{ - kind.string(), - this.text, - location.line_text, - location.file, - location.line, - location.column, - location.offset, - }); - } else { - try std.fmt.format(to, "\n\n{s}: {s}\n", .{ - kind.string(), - this.text, - }); + if (location.line_text) |line_text_| { + const line_text = std.mem.trimRight(u8, line_text_, "\r\n\t"); + + const location_in_line_text = @intCast(u32, std.math.max(location.column, 1) - 1); + const has_position = location.column > -1 and line_text.len > 0 and location_in_line_text < line_text.len; + + if (has_position) { + if (comptime enable_ansi_colors) { + const is_colored = message_color.len > 0; + + const before_segment = line_text[0..location_in_line_text]; + + try to.writeAll(before_segment); + + if (is_colored) { + try to.writeAll(color_name); + } + + var end_of_segment: usize = 1; + // extremely naive: we should really use IsIdentifierContinue || isIdentifierStart here + var rest_of_line = line_text[location_in_line_text..]; + while (end_of_segment < rest_of_line.len) : (end_of_segment += 1) { + if (!switch (rest_of_line[end_of_segment]) { + 'A'...'Z', 'a'...'z', '0'...'9', '_', '$', '(', ')' => true, + else => false, + }) break; + } + + try to.writeAll(rest_of_line[0..end_of_segment]); + if (is_colored) { + try to.writeAll("\x1b[0m"); + } + + try to.writeAll(rest_of_line[end_of_segment..]); + } else { + try to.writeAll(line_text); + } + + try to.writeAll("\n"); + + try to.writeByteNTimes(' ', location_in_line_text); + if (comptime enable_ansi_colors) { + const is_colored = message_color.len > 0; + if (is_colored) { + try to.writeAll(message_color); + try to.writeAll(color_name); + } + + try to.writeByte('^'); + + if (is_colored) { + try to.writeAll("\x1b[0m\n"); + } + } else { + try to.writeAll("^\n"); + } + } + } + + if (location.file.len > 0) { + if (comptime enable_ansi_colors) { + if (!is_note and kind == .err) { + try to.writeAll(comptime Output.color_map.get("b").?); + } else {} + } + + try std.fmt.format(to, comptime Output.prettyFmt("{s}<r>", enable_ansi_colors), .{ + location.file, + }); + + if (location.line > -1 and location.column > -1) { + try std.fmt.format(to, comptime Output.prettyFmt("<d>:<r><yellow>{d}<r><d>:<r><yellow>{d}<r> <d>{d}<r>", enable_ansi_colors), .{ + location.line, + location.column, + location.offset, + }); + } else if (location.line > -1) { + try std.fmt.format(to, comptime Output.prettyFmt("<d>:<r><yellow>{d}<r> <d>{d}<r>", enable_ansi_colors), .{ + location.line, + location.offset, + }); + } + } } } }; @@ -286,28 +383,17 @@ pub const Msg = struct { pub fn writeFormat( msg: *const Msg, to: anytype, + comptime enable_ansi_colors: bool, ) !void { - try msg.data.writeFormat(to, msg.kind); + try msg.data.writeFormat(to, msg.kind, enable_ansi_colors, false); if (msg.notes) |notes| { for (notes) |note| { - try note.writeFormat(to, msg.kind); + try note.writeFormat(to, .note, enable_ansi_colors, true); } } } - pub fn doFormat(msg: *const Msg, to: anytype, formatterFunc: anytype) !void { - try formatterFunc(to, "\n\n{s}: {s}\n{s}\n{s}:{s}:{s} {d}", .{ - msg.kind.string(), - msg.data.text, - msg.data.location.?.line_text, - msg.data.location.?.file, - msg.data.location.?.line, - msg.data.location.?.column, - msg.data.location.?.offset, - }); - } - pub fn formatWriter( msg: *const Msg, comptime Writer: type, @@ -694,29 +780,28 @@ pub const Log = struct { }); } - // TODO: pub fn addMsg(self: *Log, msg: Msg) !void { try self.msgs.append(msg); } - // TODO: pub fn addError(self: *Log, _source: ?*const Source, loc: Loc, text: string) !void { self.errors += 1; try self.addMsg(Msg{ .kind = .err, .data = rangeData(_source, Range{ .loc = loc }, text) }); } - // TODO: - pub fn print(self: *Log, to: anytype) !void { - for (self.msgs.items) |msg| { - try msg.writeFormat(to); + pub fn printForLogLevel(self: *Log, to: anytype) !void { + if (Output.enable_ansi_colors) { + return self.printForLogLevelWithEnableAnsiColors(to, true); + } else { + return self.printForLogLevelWithEnableAnsiColors(to, false); } } - pub fn printForLogLevel(self: *Log, to: anytype) !void { + pub fn printForLogLevelWithEnableAnsiColors(self: *Log, to: anytype, comptime enable_ansi_colors: bool) !void { var printed = false; for (self.msgs.items) |msg| { if (msg.kind.shouldPrint(self.level)) { - try msg.writeFormat(to); + try msg.writeFormat(to, enable_ansi_colors); printed = true; } } @@ -923,47 +1008,3 @@ pub const Source = struct { pub fn rangeData(source: ?*const Source, r: Range, text: string) Data { return Data{ .text = text, .location = Location.init_or_nil(source, r) }; } - -test "print msg" { - var msgs = ArrayList(Msg).init(std.testing.allocator); - var log = Log{ .msgs = msgs }; - defer log.msgs.deinit(); - var filename = "test.js".*; - var syntax = "for (i".*; - var err = "invalid syntax".*; - var namespace = "file".*; - - try log.addMsg(Msg{ - .kind = .err, - .data = Data{ - .location = Location.init_file(&filename, 1, 3, 0, &syntax, ""), - .text = &err, - }, - }); - - const stdout = std.io.getStdOut().writer(); - - // try log.print(stdout); -} - -test "ErrorPosition" { - const source = Source.initPathString("/src/test/fixtures/simple.jsx", @embedFile("./test/fixtures/simple.jsx")); - const error_position = source.initErrorPosition(Loc{ .start = 979 }); - - std.testing.expectEqual(@as(usize, 973), @as(usize, error_position.line_start)); - std.testing.expectEqual(@as(usize, 1016), @as(usize, error_position.line_end)); - - var msgs = ArrayList(Msg).init(std.testing.allocator); - var log = Log{ .msgs = msgs }; - defer log.msgs.deinit(); - - try log.addMsg(Msg{ - .kind = .err, - .data = rangeData(&source, Range{ .loc = Loc{ - .start = 979, - }, .len = 15 }, "Oh no"), - }); - - const stdout = std.io.getStdOut().writer(); - try log.print(stdout); -} |
