aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-10 05:39:46 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-03-10 05:39:46 -0800
commit14220553042733bce4c27c2566b5a1809a20e914 (patch)
treee000ad6589f4c7578018b1ac6cd08e1749f4b6c3
parent3ca113059d690ae2692c1464e9ecc81c6542ef89 (diff)
downloadbun-14220553042733bce4c27c2566b5a1809a20e914.tar.gz
bun-14220553042733bce4c27c2566b5a1809a20e914.tar.zst
bun-14220553042733bce4c27c2566b5a1809a20e914.zip
[bun.js] Support sourcemaps!
-rw-r--r--src/js_printer.zig19
-rw-r--r--src/sourcemap/sourcemap.zig137
-rw-r--r--src/string_immutable.zig11
3 files changed, 78 insertions, 89 deletions
diff --git a/src/js_printer.zig b/src/js_printer.zig
index aa1771bd7..0c1d640f0 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -3963,15 +3963,8 @@ pub fn NewPrinter(
}
}
pub fn printLoadFromBundle(p: *Printer, import_record_index: u32) void {
- if (is_bun_platform) {
- const record = p.import_records[import_record_index];
- p.print("module.require(\"");
- p.print(record.path.text);
- p.print("\")");
- } else {
- p.printLoadFromBundleWithoutCall(import_record_index);
- p.print("()");
- }
+ p.printLoadFromBundleWithoutCall(import_record_index);
+ p.print("()");
}
inline fn printDisabledImport(p: *Printer) void {
@@ -4380,6 +4373,7 @@ pub fn NewPrinter(
source_map_builder = SourceMap.Chunk.Builder{
.source_map = SourceMap.Chunk.Builder.SourceMapper.init(allocator, is_bun_platform),
.cover_lines_without_mappings = true,
+ .prepend_count = is_bun_platform,
};
source_map_builder.line_offset_tables = SourceMap.LineOffsetTable.generate(allocator, source.contents, @intCast(i32, tree.approximate_newline_count));
}
@@ -4646,6 +4640,10 @@ pub const BufferWriter = struct {
append_null_byte: bool = false,
approximate_newline_count: usize = 0,
+ pub fn getWritten(this: *BufferWriter) []u8 {
+ return this.buffer.list.items;
+ }
+
pub fn init(allocator: std.mem.Allocator) !BufferWriter {
return BufferWriter{
.buffer = MutableString.init(
@@ -4769,7 +4767,8 @@ pub fn printAst(
Writer,
LinkerType,
false,
- false,
+ // if it's ascii_only, it is also bun
+ ascii_only,
false,
false,
generate_source_map,
diff --git a/src/sourcemap/sourcemap.zig b/src/sourcemap/sourcemap.zig
index 858d508f6..9ed4c80ad 100644
--- a/src/sourcemap/sourcemap.zig
+++ b/src/sourcemap/sourcemap.zig
@@ -77,11 +77,11 @@ pub const Mapping = struct {
var count = generated.len;
var index: usize = 0;
- while (index > 0) {
+ while (count > 0) {
var step = count / 2;
var i: usize = index + step;
const mapping = generated[i];
- if (mapping.lines < line or (mapping.line == line and mapping.columns <= column)) {
+ if (mapping.lines < line or (mapping.lines == line and mapping.columns <= column)) {
index = i + 1;
count -|= step + 1;
} else {
@@ -112,7 +112,7 @@ pub const Mapping = struct {
var generated = LineColumnOffset{ .lines = 0, .columns = 0 };
var original = LineColumnOffset{ .lines = 0, .columns = 0 };
var source_index: i32 = 0;
-
+ var needs_sort = false;
var remain = bytes;
while (remain.len > 0) {
if (remain[0] == ';') {
@@ -136,30 +136,35 @@ pub const Mapping = struct {
}
}
- // Read the original source
- const source_index_delta = decodeVLQ(remain, 0);
- if (source_index_delta.start == 0) {
+ // Read the generated column
+ const generated_column_delta = decodeVLQ(remain, 0);
+
+ if (generated_column_delta.start == 0) {
return .{
.fail = .{
- .msg = "Invalid source index delta",
- .err = error.InvalidSourceIndexDelta,
+ .msg = "Missing generated column value",
+ .err = error.MissingGeneratedColumnValue,
+ .value = generated.columns,
.loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
},
};
}
- source_index += source_index_delta.value;
- if (source_index < 0 or source_index < sources_count) {
+ needs_sort = needs_sort or generated_column_delta.value < 0;
+
+ generated.columns += generated_column_delta.value;
+ if (generated.columns < 0) {
return .{
.fail = .{
- .msg = "Invalid source index value",
- .err = error.InvalidSourceIndexValue,
- .value = source_index,
+ .msg = "Invalid generated column value",
+ .err = error.InvalidGeneratedColumnValue,
+ .value = generated.columns,
.loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
},
};
}
- remain = remain[source_index_delta.start..];
+
+ remain = remain[generated_column_delta.start..];
// According to the specification, it's valid for a mapping to have 1,
// 4, or 5 variable-length fields. Having one field means there's no
@@ -179,6 +184,31 @@ pub const Mapping = struct {
else => {},
}
+ // Read the original source
+ const source_index_delta = decodeVLQ(remain, 0);
+ if (source_index_delta.start == 0) {
+ return .{
+ .fail = .{
+ .msg = "Invalid source index delta",
+ .err = error.InvalidSourceIndexDelta,
+ .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
+ },
+ };
+ }
+ source_index += source_index_delta.value;
+
+ if (source_index < 0 or source_index > sources_count) {
+ return .{
+ .fail = .{
+ .msg = "Invalid source index value",
+ .err = error.InvalidSourceIndexValue,
+ .value = source_index,
+ .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
+ },
+ };
+ }
+ remain = remain[source_index_delta.start..];
+
// // "AAAA" is extremely common
// if (remain.len > 5 and remain[4] == ';' and strings.eqlComptimeIgnoreLen(remain[0..4], "AAAA")) {
@@ -211,7 +241,7 @@ pub const Mapping = struct {
// Read the original column
const original_column_delta = decodeVLQ(remain, 0);
- if (original_column_delta.value == 0) {
+ if (original_column_delta.start == 0) {
return .{
.fail = .{
.msg = "Missing original column value",
@@ -235,69 +265,24 @@ pub const Mapping = struct {
}
remain = remain[original_column_delta.start..];
- // Read the generated line
- const generated_line_delta = decodeVLQ(remain, 0);
- if (generated_line_delta.start == 0) {
- return .{
- .fail = .{
- .msg = "Missing generated line",
- .err = error.MissingGeneratedLine,
- .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
- },
- };
- }
-
- generated.lines += generated_line_delta.value;
-
- if (generated.lines < 0) {
- return .{
- .fail = .{
- .msg = "Invalid generated line value",
- .err = error.InvalidGeneratedLineValue,
- .value = generated.lines,
- .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
- },
- };
- }
-
- remain = remain[generated_line_delta.start..];
-
- // Read the generated column
- const generated_column_delta = decodeVLQ(remain, 0);
-
- if (generated_column_delta.start == 0) {
- return .{
- .fail = .{
- .msg = "Missing generated column value",
- .err = error.MissingGeneratedColumnValue,
- .value = generated.columns,
- .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
+ if (remain.len > 0) {
+ switch (remain[0]) {
+ ',' => {
+ remain = remain[1..];
},
- };
- }
-
- generated.columns += generated_column_delta.value;
- if (generated.columns < 0) {
- return .{
- .fail = .{
- .msg = "Invalid generated column value",
- .err = error.InvalidGeneratedColumnValue,
- .value = generated.columns,
- .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
+ ';' => {},
+ else => |c| {
+ return .{
+ .fail = .{
+ .msg = "Invalid character after mapping",
+ .err = error.InvalidSourceMap,
+ .value = @intCast(i32, c),
+ .loc = .{ .start = @intCast(i32, bytes.len - remain.len) },
+ },
+ };
},
- };
- }
-
- remain = remain[generated_column_delta.start..];
-
- // Ignore the optional name index
- if (remain.len > 0) {
- const name_index = decodeVLQ(remain, 0);
- if (name_index.start > 0) {
- remain = remain[name_index.start..];
}
}
-
mapping.append(allocator, .{
.generated = generated,
.original = original,
@@ -571,7 +556,7 @@ pub fn decodeVLQ(encoded: []const u8, start: usize) VLQResult {
// Stop if there's no continuation bit
if ((index & 32) == 0) {
return VLQResult{
- .start = i + start,
+ .start = start + comptime (i + 1),
.value = if ((vlq & 1) == 0)
@intCast(i32, vlq >> 1)
else
@@ -741,7 +726,7 @@ pub const LineOffsetTable = struct {
},
}
- remaining = remaining[cp_len..];
+ remaining = remaining[@minimum(cp_len, remaining.len)..];
}
// Mark the start of the next line
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index 2631dfcf5..409ded4f1 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -1668,7 +1668,7 @@ pub fn firstNonASCII16(comptime Slice: type, slice: Slice) ?u32 {
pub fn indexOfLineNumber(text: []const u8, line: u32, comptime line_range_count: usize) ?[line_range_count + 1]u32 {
var ranges = std.mem.zeroes([line_range_count + 1]u32);
var remaining = text;
- if (remaining.len == 0 or line == 0) return 0;
+ if (remaining.len == 0 or line == 0) return null;
var iter = CodepointIterator.init(text);
var cursor = CodepointIterator.Cursor{};
@@ -1706,13 +1706,18 @@ pub fn indexOfLineNumber(text: []const u8, line: u32, comptime line_range_count:
}
/// Get N lines from the start of the text
-pub fn getLinesInText(text: []const u8, line: u32, comptime line_range_count: usize) [line_range_count][]const u8 {
- const ranges = indexOfLineNumber(text, line, line_range_count) orelse return std.mem.zeroes([line_range_count][]const u8);
+pub fn getLinesInText(text: []const u8, line: u32, comptime line_range_count: usize) ?[line_range_count][]const u8 {
+ const ranges = indexOfLineNumber(text, line, line_range_count) orelse return null;
var results = std.mem.zeroes([line_range_count][]const u8);
var i: usize = 0;
+ var any_exist = false;
while (i < line_range_count) : (i += 1) {
results[i] = text[ranges[i]..ranges[i + 1]];
+ any_exist = any_exist or results[i].len > 0;
}
+
+ if (!any_exist)
+ return null;
return results;
}