diff options
author | 2022-03-10 05:39:46 -0800 | |
---|---|---|
committer | 2022-03-10 05:39:46 -0800 | |
commit | 14220553042733bce4c27c2566b5a1809a20e914 (patch) | |
tree | e000ad6589f4c7578018b1ac6cd08e1749f4b6c3 | |
parent | 3ca113059d690ae2692c1464e9ecc81c6542ef89 (diff) | |
download | bun-14220553042733bce4c27c2566b5a1809a20e914.tar.gz bun-14220553042733bce4c27c2566b5a1809a20e914.tar.zst bun-14220553042733bce4c27c2566b5a1809a20e914.zip |
[bun.js] Support sourcemaps!
-rw-r--r-- | src/js_printer.zig | 19 | ||||
-rw-r--r-- | src/sourcemap/sourcemap.zig | 137 | ||||
-rw-r--r-- | src/string_immutable.zig | 11 |
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; } |