mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 20:39:05 +00:00
### What does this PR do? <img width="577" height="273" alt="image" src="https://github.com/user-attachments/assets/0b20f0a5-45d2-4acf-bb72-85d52f7f1bfb" /> not sure if its a good idea though. ### How did you verify your code works? --------- Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
246 lines
10 KiB
Zig
246 lines
10 KiB
Zig
const string = []const u8;
|
|
|
|
/// Represents a single frame in a stack trace
|
|
pub const ZigStackFrame = extern struct {
|
|
function_name: String,
|
|
source_url: String,
|
|
position: ZigStackFramePosition,
|
|
code_type: ZigStackFrameCode,
|
|
is_async: bool,
|
|
|
|
/// This informs formatters whether to display as a blob URL or not
|
|
remapped: bool = false,
|
|
|
|
pub fn deinit(this: *ZigStackFrame) void {
|
|
this.function_name.deref();
|
|
this.source_url.deref();
|
|
}
|
|
|
|
pub fn toAPI(this: *const ZigStackFrame, root_path: string, origin: ?*const ZigURL, allocator: std.mem.Allocator) !api.StackFrame {
|
|
var frame: api.StackFrame = comptime std.mem.zeroes(api.StackFrame);
|
|
if (!this.function_name.isEmpty()) {
|
|
var slicer = this.function_name.toUTF8(allocator);
|
|
frame.function_name = (try slicer.cloneIfNeeded(allocator)).slice();
|
|
}
|
|
|
|
if (!this.source_url.isEmpty()) {
|
|
frame.file = try std.fmt.allocPrint(allocator, "{}", .{this.sourceURLFormatter(root_path, origin, true, false)});
|
|
}
|
|
|
|
frame.position = this.position;
|
|
frame.scope = @as(api.StackFrameScope, @enumFromInt(@intFromEnum(this.code_type)));
|
|
|
|
return frame;
|
|
}
|
|
|
|
pub const SourceURLFormatter = struct {
|
|
source_url: bun.String,
|
|
position: ZigStackFramePosition,
|
|
enable_color: bool,
|
|
origin: ?*const ZigURL,
|
|
exclude_line_column: bool = false,
|
|
remapped: bool = false,
|
|
root_path: string = "",
|
|
|
|
pub fn format(this: SourceURLFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
|
if (this.enable_color) {
|
|
try writer.writeAll(Output.prettyFmt("<r><cyan>", true));
|
|
}
|
|
|
|
var source_slice_ = this.source_url.toUTF8(bun.default_allocator);
|
|
var source_slice = source_slice_.slice();
|
|
defer source_slice_.deinit();
|
|
|
|
if (!this.remapped) {
|
|
if (this.origin) |origin| {
|
|
try writer.writeAll(origin.displayProtocol());
|
|
try writer.writeAll("://");
|
|
try writer.writeAll(origin.displayHostname());
|
|
try writer.writeAll(":");
|
|
try writer.writeAll(origin.port);
|
|
try writer.writeAll("/blob:");
|
|
|
|
if (strings.startsWith(source_slice, this.root_path)) {
|
|
source_slice = source_slice[this.root_path.len..];
|
|
}
|
|
}
|
|
try writer.writeAll(source_slice);
|
|
} else {
|
|
if (this.enable_color) {
|
|
const not_root = if (comptime bun.Environment.isWindows) this.root_path.len > "C:\\".len else this.root_path.len > "/".len;
|
|
if (not_root and strings.startsWith(source_slice, this.root_path)) {
|
|
const relative_path = strings.withoutLeadingPathSeparator(source_slice[this.root_path.len..]);
|
|
try writer.writeAll(comptime Output.prettyFmt("<d>", true));
|
|
try writer.writeAll(this.root_path);
|
|
try writer.writeByte(std.fs.path.sep);
|
|
try writer.writeAll(comptime Output.prettyFmt("<r><cyan>", true));
|
|
try writer.writeAll(relative_path);
|
|
} else {
|
|
try writer.writeAll(source_slice);
|
|
}
|
|
} else {
|
|
try writer.writeAll(source_slice);
|
|
}
|
|
}
|
|
|
|
if (source_slice.len > 0 and (this.position.line.isValid() or this.position.column.isValid())) {
|
|
if (this.enable_color) {
|
|
try writer.writeAll(comptime Output.prettyFmt("<r><d>:", true));
|
|
} else {
|
|
try writer.writeAll(":");
|
|
}
|
|
}
|
|
|
|
if (this.enable_color) {
|
|
if (this.position.line.isValid() or this.position.column.isValid()) {
|
|
try writer.writeAll(comptime Output.prettyFmt("<r>", true));
|
|
} else {
|
|
try writer.writeAll(comptime Output.prettyFmt("<r>", true));
|
|
}
|
|
}
|
|
|
|
if (!this.exclude_line_column) {
|
|
if (this.position.line.isValid() and this.position.column.isValid()) {
|
|
if (this.enable_color) {
|
|
try std.fmt.format(
|
|
writer,
|
|
comptime Output.prettyFmt("<yellow>{d}<r><d>:<yellow>{d}<r>", true),
|
|
.{ this.position.line.oneBased(), this.position.column.oneBased() },
|
|
);
|
|
} else {
|
|
try std.fmt.format(writer, "{d}:{d}", .{
|
|
this.position.line.oneBased(),
|
|
this.position.column.oneBased(),
|
|
});
|
|
}
|
|
} else if (this.position.line.isValid()) {
|
|
if (this.enable_color) {
|
|
try std.fmt.format(
|
|
writer,
|
|
comptime Output.prettyFmt("<yellow>{d}<r>", true),
|
|
.{
|
|
this.position.line.oneBased(),
|
|
},
|
|
);
|
|
} else {
|
|
try std.fmt.format(writer, "{d}", .{
|
|
this.position.line.oneBased(),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
pub const NameFormatter = struct {
|
|
function_name: String,
|
|
code_type: ZigStackFrameCode,
|
|
enable_color: bool,
|
|
is_async: bool,
|
|
|
|
pub fn format(this: NameFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
|
const name = this.function_name;
|
|
|
|
switch (this.code_type) {
|
|
.Eval => {
|
|
if (this.enable_color) {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt("<r><d>", true) ++ "eval" ++ Output.prettyFmt("<r>", true), .{});
|
|
} else {
|
|
try writer.writeAll("eval");
|
|
}
|
|
if (!name.isEmpty()) {
|
|
if (this.enable_color) {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt(" <r><b><i>{}<r>", true), .{name});
|
|
} else {
|
|
try std.fmt.format(writer, " {}", .{name});
|
|
}
|
|
}
|
|
},
|
|
.Function => {
|
|
if (!name.isEmpty()) {
|
|
if (this.enable_color) {
|
|
if (this.is_async) {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt("<r><b><i>async {}<r>", true), .{name});
|
|
} else {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt("<r><b><i>{}<r>", true), .{name});
|
|
}
|
|
} else {
|
|
if (this.is_async) {
|
|
try std.fmt.format(writer, "async {}", .{name});
|
|
} else {
|
|
try std.fmt.format(writer, "{}", .{name});
|
|
}
|
|
}
|
|
} else {
|
|
if (this.enable_color) {
|
|
if (this.is_async) {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt("<r><d>", true) ++ "async <anonymous>" ++ Output.prettyFmt("<r>", true), .{});
|
|
} else {
|
|
try std.fmt.format(writer, comptime Output.prettyFmt("<r><d>", true) ++ "<anonymous>" ++ Output.prettyFmt("<r>", true), .{});
|
|
}
|
|
} else {
|
|
if (this.is_async) {
|
|
try writer.writeAll("async ");
|
|
}
|
|
try writer.writeAll("<anonymous>");
|
|
}
|
|
}
|
|
},
|
|
.Global => {},
|
|
.Wasm => {
|
|
if (!name.isEmpty()) {
|
|
try std.fmt.format(writer, "{}", .{name});
|
|
} else {
|
|
try writer.writeAll("WASM");
|
|
}
|
|
},
|
|
.Constructor => {
|
|
try std.fmt.format(writer, "new {}", .{name});
|
|
},
|
|
else => {
|
|
if (!name.isEmpty()) {
|
|
try std.fmt.format(writer, "{}", .{name});
|
|
}
|
|
},
|
|
}
|
|
}
|
|
};
|
|
|
|
pub const Zero: ZigStackFrame = .{
|
|
.function_name = .empty,
|
|
.code_type = .None,
|
|
.source_url = .empty,
|
|
.position = .invalid,
|
|
.is_async = false,
|
|
};
|
|
|
|
pub fn nameFormatter(this: *const ZigStackFrame, comptime enable_color: bool) NameFormatter {
|
|
return NameFormatter{ .function_name = this.function_name, .code_type = this.code_type, .enable_color = enable_color, .is_async = this.is_async };
|
|
}
|
|
|
|
pub fn sourceURLFormatter(this: *const ZigStackFrame, root_path: string, origin: ?*const ZigURL, exclude_line_column: bool, comptime enable_color: bool) SourceURLFormatter {
|
|
return SourceURLFormatter{
|
|
.source_url = this.source_url,
|
|
.exclude_line_column = exclude_line_column,
|
|
.origin = origin,
|
|
.root_path = root_path,
|
|
.position = this.position,
|
|
.enable_color = enable_color,
|
|
.remapped = this.remapped,
|
|
};
|
|
}
|
|
};
|
|
|
|
const std = @import("std");
|
|
const ZigURL = @import("../../url.zig").URL;
|
|
|
|
const bun = @import("bun");
|
|
const Output = bun.Output;
|
|
const String = bun.String;
|
|
const strings = bun.strings;
|
|
const api = bun.schema.api;
|
|
|
|
const jsc = bun.jsc;
|
|
const ZigStackFrameCode = jsc.ZigStackFrameCode;
|
|
const ZigStackFramePosition = jsc.ZigStackFramePosition;
|