aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-05 19:02:14 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-05 19:02:14 -0700
commit41c9896e11948b91dea278636c226516f7c01f3d (patch)
treebced3884ebd9a523cce68edf5caa7f8003e5fe7b /src
parent7a4084a23fc5045b479ed4fc08853e251e904d77 (diff)
downloadbun-41c9896e11948b91dea278636c226516f7c01f3d.tar.gz
bun-41c9896e11948b91dea278636c226516f7c01f3d.tar.zst
bun-41c9896e11948b91dea278636c226516f7c01f3d.zip
I think that fixes the scopes bug
Former-commit-id: 2cbd4c9d809cff90dc4a2305c0acbaf46c3a1578
Diffstat (limited to 'src')
-rw-r--r--src/js_parser/js_parser.zig63
-rw-r--r--src/js_parser/js_parser_test.zig161
-rw-r--r--src/js_printer.zig9
-rw-r--r--src/json_parser.zig2
-rw-r--r--src/logger.zig57
-rw-r--r--src/main.zig1
-rw-r--r--src/renamer.zig19
7 files changed, 99 insertions, 213 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 3321d0ed3..26dfc9bc2 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1650,7 +1650,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: std.ArrayListUnmanaged(?ScopeOrder),
// These properties are for the visit pass, which runs after the parse pass.
// The visit pass binds identifiers to declared symbols, does constant
@@ -2242,11 +2242,14 @@ 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);
- const order = p.scopes_in_order.items[0];
- if (p.scopes_in_order.items.len > 1) {
- p.scopes_in_order.items = p.scopes_in_order.items[1..p.scopes_in_order.items.len];
+ 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{});
+ p.scopes_in_order.items = &([_]?ScopeOrder{});
}
// Sanity-check that the scopes generated by the first and second passes match
@@ -2281,9 +2284,15 @@ pub const P = struct {
// Enforce that scope locations are strictly increasing to help catch bugs
// where the pushed scopes are mistmatched between the first and second passes
if (std.builtin.mode != std.builtin.Mode.ReleaseFast and p.scopes_in_order.items.len > 0) {
- const prev_start = p.scopes_in_order.items[p.scopes_in_order.items.len - 1].loc.start;
- if (prev_start >= loc.start) {
- p.panic("Scope location {d} must be greater than {d}", .{ loc.start, prev_start });
+ var last_i = p.scopes_in_order.items.len - 1;
+ while (p.scopes_in_order.items[last_i] == null and last_i > 0) {
+ last_i -= 1;
+ }
+
+ if (p.scopes_in_order.items[last_i]) |prev_scope| {
+ if (prev_scope.loc.start >= loc.start) {
+ p.panic("Scope location {d} must be greater than {d}", .{ loc.start, prev_scope.loc.start });
+ }
}
}
@@ -4050,7 +4059,9 @@ pub const P = struct {
// Remove any direct children from their parent
var scope = p.current_scope;
var children = scope.children;
- for (p.scopes_in_order.items[scope_index..]) |child| {
+ for (p.scopes_in_order.items[scope_index..]) |_child| {
+ const child = _child orelse continue;
+
if (child.scope.parent == p.current_scope) {
var i: usize = children.items.len - 1;
while (i >= 0) {
@@ -5000,24 +5011,6 @@ pub const P = struct {
}
}
- // Saves us from allocating a slice to the heap
- pub fn parseArrowBodySingleArg(p: *P, arg: G.Arg, data: anytype) !E.Arrow {
- switch (@TypeOf(data)) {
- FnOrArrowDataParse => {
- var args = [_]G.Arg{arg};
-
- var d = data;
-
- return p.parseArrowBody(args[0..], &d);
- },
- *FnOrArrowDataParse => {
- var args = [_]G.Arg{arg};
- return p.parseArrowBody(args[0..], data);
- },
- else => unreachable,
- }
- }
-
// This is where the allocate memory to the heap for AST objects.
// This is a short name to keep the code more readable.
// It also swallows errors, but I think that's correct here.
@@ -5085,9 +5078,9 @@ pub const P = struct {
async_range.loc,
) };
_ = p.pushScopeForParsePass(.function_args, async_range.loc) catch unreachable;
- defer p.popScope();
var data = FnOrArrowDataParse{};
var arrow_body = try p.parseArrowBody(args, &data);
+ p.popScope();
return p.e(arrow_body, async_range.loc);
}
},
@@ -5806,7 +5799,8 @@ pub const P = struct {
var value = p.parseExpr(.lowest);
var tail_loc = p.lexer.loc();
p.lexer.rescanCloseBraceAsTemplateToken();
- var tail = p.allocator.dupe(u16, p.lexer.string_literal) catch unreachable;
+
+ var tail = p.lexer.stringLiteralUTF16();
var tail_raw: string = "";
if (include_raw) {
@@ -6655,7 +6649,7 @@ 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} ** 4096;
+ var fixedBuffer = [_]u8{0} ** (1024 * 1024);
var stream = std.io.fixedBufferStream(&fixedBuffer);
p.log.print(stream.writer()) catch unreachable;
@@ -6833,7 +6827,7 @@ pub const P = struct {
},
.t_template_head => {
var legacy_octal_loc = logger.Loc.Empty;
- var head = p.lexer.string_literal;
+ var head = p.lexer.stringLiteralUTF16();
var head_raw = p.lexer.raw();
if (p.lexer.legacy_octal_loc.start > loc.start) {
legacy_octal_loc = p.lexer.legacy_octal_loc;
@@ -8184,7 +8178,7 @@ pub const P = struct {
},
.bin_logical_and => {
const side_effects = SideEffects.toBoolean(e_.left.data);
- if (side_effects.ok and side_effects.value) {
+ if (side_effects.ok and !side_effects.value) {
// "false && dead"
const old = p.is_control_flow_dead;
p.is_control_flow_dead = true;
@@ -10715,8 +10709,7 @@ pub const P = struct {
// These scopes were all created in between this scope's push and pop
// operations, so they should all be child scopes and should all be popped
// by the time we get here.
- _ = p.scopes_in_order.swapRemove(scope_index);
-
+ p.scopes_in_order.items[scope_index] = null;
// Remove the last child from the parent scope
const last = parent.children.items.len - 1;
assert(parent.children.items[last] == to_flatten);
@@ -10906,7 +10899,7 @@ pub const P = struct {
.named_exports = @TypeOf(_parser.named_exports).init(allocator),
.top_level_symbol_to_parts = @TypeOf(_parser.top_level_symbol_to_parts).init(allocator),
.import_namespace_cc_map = @TypeOf(_parser.import_namespace_cc_map).init(allocator),
- .scopes_in_order = try std.ArrayListUnmanaged(ScopeOrder).initCapacity(allocator, 1),
+ .scopes_in_order = try std.ArrayListUnmanaged(?ScopeOrder).initCapacity(allocator, 1),
.temp_refs_to_declare = @TypeOf(_parser.temp_refs_to_declare).init(allocator),
.relocated_top_level_vars = @TypeOf(_parser.relocated_top_level_vars).init(allocator),
.log = log,
diff --git a/src/js_parser/js_parser_test.zig b/src/js_parser/js_parser_test.zig
index 62cb2525b..05b9b1f8e 100644
--- a/src/js_parser/js_parser_test.zig
+++ b/src/js_parser/js_parser_test.zig
@@ -1,6 +1,6 @@
usingnamespace @import("./imports.zig");
usingnamespace @import("./js_parser.zig");
-
+usingnamespace @import("../test/tester.zig");
usingnamespace @import("../linker.zig");
const SymbolList = [][]Symbol;
@@ -175,161 +175,6 @@ const SymbolList = [][]Symbol;
// }
// };
-const RED = "\x1b[31;1m";
-const GREEN = "\x1b[32;1m";
-const CYAN = "\x1b[36;1m";
-const WHITE = "\x1b[37;1m";
-const DIM = "\x1b[2m";
-const RESET = "\x1b[0m";
-
-pub const Tester = struct {
- pass: std.ArrayList(Expectation),
- fail: std.ArrayList(Expectation),
- allocator: *std.mem.Allocator,
-
- pub fn t(allocator: *std.mem.Allocator) Tester {
- return Tester{
- .allocator = allocator,
- .pass = std.ArrayList(Expectation).init(allocator),
- .fail = std.ArrayList(Expectation).init(allocator),
- };
- }
-
- pub const Expectation = struct {
- expected: string,
- result: string,
- source: std.builtin.SourceLocation,
-
- pub fn init(expected: string, result: string, src: std.builtin.SourceLocation) Expectation {
- return Expectation{
- .expected = expected,
- .result = result,
- .source = src,
- };
- }
- const PADDING = 0;
- pub fn print(self: *const @This()) void {
- var pad = &([_]u8{' '} ** PADDING);
- var stderr = std.io.getStdErr();
-
- stderr.writeAll(RESET) catch unreachable;
- stderr.writeAll(pad) catch unreachable;
- stderr.writeAll(DIM) catch unreachable;
- std.fmt.format(stderr.writer(), "{s}:{d}:{d}", .{ self.source.file, self.source.line, self.source.column }) catch unreachable;
- stderr.writeAll(RESET) catch unreachable;
- stderr.writeAll("\n") catch unreachable;
-
- stderr.writeAll(pad) catch unreachable;
- stderr.writeAll("Expected: ") catch unreachable;
- stderr.writeAll(RESET) catch unreachable;
- stderr.writeAll(GREEN) catch unreachable;
- std.fmt.format(stderr.writer(), "\"{s}\"", .{self.expected}) catch unreachable;
- stderr.writeAll(GREEN) catch unreachable;
- stderr.writeAll(RESET) catch unreachable;
-
- stderr.writeAll("\n") catch unreachable;
- stderr.writeAll(pad) catch unreachable;
- stderr.writeAll("Received: ") catch unreachable;
- stderr.writeAll(RESET) catch unreachable;
- stderr.writeAll(RED) catch unreachable;
- std.fmt.format(stderr.writer(), "\"{s}\"", .{self.result}) catch unreachable;
- stderr.writeAll(RED) catch unreachable;
- stderr.writeAll(RESET) catch unreachable;
- stderr.writeAll("\n") catch unreachable;
- }
-
- pub fn evaluate_outcome(self: *const @This()) Outcome {
- for (self.expected) |char, i| {
- if (char != self.result[i]) {
- return Outcome.fail;
- }
- }
-
- return Outcome.pass;
- }
- };
-
- pub const Outcome = enum {
- pass,
- fail,
- };
- pub fn expect(tester: *Tester, expected: string, result: string, src: std.builtin.SourceLocation) callconv(.Inline) bool {
- var expectation = Expectation.init(expected, result, src);
- switch (expectation.evaluate_outcome()) {
- .pass => {
- tester.pass.append(expectation) catch unreachable;
- return true;
- },
- .fail => {
- tester.fail.append(expectation) catch unreachable;
- return false;
- },
- }
- }
-
- const ReportType = enum {
- none,
- pass,
- fail,
- some_fail,
-
- pub fn init(tester: *Tester) ReportType {
- if (tester.fail.items.len == 0 and tester.pass.items.len == 0) {
- return .none;
- } else if (tester.fail.items.len == 0) {
- return .pass;
- } else if (tester.pass.items.len == 0) {
- return .fail;
- } else {
- return .some_fail;
- }
- }
- };
-
- pub fn report(tester: *Tester, src: std.builtin.SourceLocation) void {
- var stderr = std.io.getStdErr();
-
- if (tester.fail.items.len > 0) {
- std.fmt.format(stderr.writer(), "\n\n", .{}) catch unreachable;
- }
-
- for (tester.fail.items) |item| {
- item.print();
- std.fmt.format(stderr.writer(), "\n", .{}) catch unreachable;
- }
-
- switch (ReportType.init(tester)) {
- .none => {
- std.log.info("No expectations.\n\n", .{});
- },
- .pass => {
- std.fmt.format(stderr.writer(), "{s}All {d} expectations passed.{s}\n", .{ GREEN, tester.pass.items.len, GREEN }) catch unreachable;
- std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable;
- std.testing.expect(true);
- },
- .fail => {
- std.fmt.format(stderr.writer(), "{s}All {d} expectations failed.{s}\n\n", .{ RED, tester.fail.items.len, RED }) catch unreachable;
- std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable;
- std.testing.expect(false);
- },
- .some_fail => {
- std.fmt.format(stderr.writer(), "{s}{d} failed{s} and {s}{d} passed{s} of {d} expectations{s}\n\n", .{
- RED,
- tester.fail.items.len,
- RED ++ RESET,
- GREEN,
- tester.pass.items.len,
- GREEN ++ RESET,
- tester.fail.items.len + tester.pass.items.len,
- RESET,
- }) catch unreachable;
- std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable;
- std.testing.expect(false);
- },
- }
- }
-};
-
fn expectPrinted(t: *Tester, contents: string, expected: string, src: anytype) !void {
if (alloc.needs_setup) {
try alloc.setup(std.heap.page_allocator);
@@ -369,7 +214,7 @@ fn expectPrinted(t: *Tester, contents: string, expected: string, src: anytype) !
try ast.toJSON(alloc.dynamic, std.io.getStdErr().writer());
}
- const result = js_printer.printAst(alloc.dynamic, ast, symbol_map, true, js_printer.Options{ .to_module_ref = res.ast.module_ref orelse Ref{ .inner_index = 0 } }, &linker) catch unreachable;
+ const result = js_printer.printAst(alloc.dynamic, ast, symbol_map, &source, true, js_printer.Options{ .to_module_ref = res.ast.module_ref orelse Ref{ .inner_index = 0 } }, &linker) catch unreachable;
var copied = try std.mem.dupe(alloc.dynamic, u8, result.js);
_ = t.expect(contents, copied, src);
// std.testing.expectEqualStrings(contents, copied);
@@ -380,7 +225,7 @@ const PRINT_AST = false;
test "expectPrint" {
var t_ = Tester.t(std.heap.page_allocator);
var t = &t_;
- try expectPrinted(t, @embedFile("../test/fixtures/function-scope-bug.jsx"), @embedFile("../test/fixtures/function-scope-bug.jsx"), @src());
+ // try expectPrinted(t, @embedFile("../test/fixtures/function-scope-bug.jsx"), @embedFile("../test/fixtures/function-scope-bug.jsx"), @src());
try expectPrinted(t, @embedFile("../test/fixtures/simple.jsx"), @embedFile("../test/fixtures/simple.jsx"), @src());
// try expectPrinted(t, "if (true) { console.log(\"hi\"); }", "if (true) { console.log(\"hi\"); }", @src());
diff --git a/src/js_printer.zig b/src/js_printer.zig
index a22f407fb..40894f2c9 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -2735,7 +2735,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
}
}
- pub fn init(allocator: *std.mem.Allocator, tree: Ast, symbols: Symbol.Map, opts: Options, linker: *Linker) !Printer {
+ pub fn init(allocator: *std.mem.Allocator, tree: Ast, source: *logger.Source, symbols: Symbol.Map, opts: Options, linker: *Linker) !Printer {
var js = try MutableString.init(allocator, 0);
return Printer{
.allocator = allocator,
@@ -2745,7 +2745,7 @@ pub fn NewPrinter(comptime ascii_only: bool) type {
.js = js,
.writer = js.writer(),
.linker = linker,
- .renamer = rename.Renamer.init(symbols),
+ .renamer = rename.Renamer.init(symbols, source),
};
}
};
@@ -2774,12 +2774,14 @@ pub fn quoteIdentifier(js: *MutableString, identifier: string) !void {
const UnicodePrinter = NewPrinter(false);
const AsciiPrinter = NewPrinter(true);
-pub fn printAst(allocator: *std.mem.Allocator, tree: Ast, symbols: js_ast.Symbol.Map, ascii_only: bool, opts: Options, linker: *Linker) !PrintResult {
+pub fn printAst(allocator: *std.mem.Allocator, tree: Ast, symbols: js_ast.Symbol.Map, source: *logger.Source, ascii_only: bool, opts: Options, linker: *Linker) !PrintResult {
if (ascii_only) {
var printer = try AsciiPrinter.init(
allocator,
tree,
+ source,
symbols,
+
opts,
linker,
);
@@ -2796,6 +2798,7 @@ pub fn printAst(allocator: *std.mem.Allocator, tree: Ast, symbols: js_ast.Symbol
var printer = try UnicodePrinter.init(
allocator,
tree,
+ source,
symbols,
opts,
linker,
diff --git a/src/json_parser.zig b/src/json_parser.zig
index 732cbbbe5..cf1a9382d 100644
--- a/src/json_parser.zig
+++ b/src/json_parser.zig
@@ -253,7 +253,7 @@ fn expectPrintedJSON(_contents: string, expected: string) void {
}
var linker = @import("linker.zig").Linker{};
- const result = js_printer.printAst(alloc.dynamic, tree, symbol_map, true, js_printer.Options{ .to_module_ref = Ref{ .inner_index = 0 } }, &linker) catch unreachable;
+ const result = js_printer.printAst(alloc.dynamic, tree, symbol_map, &source, true, js_printer.Options{ .to_module_ref = Ref{ .inner_index = 0 } }, &linker) catch unreachable;
var js = result.js;
diff --git a/src/logger.zig b/src/logger.zig
index ce5960050..1731bc31b 100644
--- a/src/logger.zig
+++ b/src/logger.zig
@@ -72,7 +72,7 @@ pub const Location = struct {
};
}
- pub fn init_or_nil(_source: ?*Source, r: Range) ?Location {
+ pub fn init_or_nil(_source: ?*const Source, r: Range) ?Location {
if (_source) |source| {
var data = source.initErrorPosition(r.loc);
return Location{
@@ -382,21 +382,23 @@ pub const Source = struct {
pub fn initErrorPosition(self: *const Source, _offset: Loc) ErrorPosition {
var prev_code_point: u21 = 0;
- var offset: usize = if (_offset.start < 0) 0 else @intCast(usize, _offset.start);
+ var offset: usize = std.math.min(if (_offset.start < 0) 0 else @intCast(usize, _offset.start), self.contents.len - 1);
const contents = self.contents;
var iter = unicode.Utf8Iterator{
.bytes = self.contents[0..offset],
- .i = std.math.min(offset, self.contents.len),
+ .i = 0,
};
var line_start: usize = 0;
- var line_count: usize = 0;
+ var line_count: usize = 1;
+ var column_number: usize = 1;
while (iter.nextCodepoint()) |code_point| {
switch (code_point) {
'\n' => {
+ column_number = 1;
line_start = iter.i + 1;
if (prev_code_point != '\r') {
line_count += 1;
@@ -404,6 +406,7 @@ pub const Source = struct {
},
'\r' => {
+ column_number = 0;
line_start = iter.i + 1;
line_count += 1;
},
@@ -411,8 +414,11 @@ pub const Source = struct {
0x2028, 0x2029 => {
line_start = iter.i + 3; // These take three bytes to encode in UTF-8
line_count += 1;
+ column_number = 1;
+ },
+ else => {
+ column_number += 1;
},
- else => {},
}
prev_code_point = code_point;
@@ -420,7 +426,7 @@ pub const Source = struct {
iter = unicode.Utf8Iterator{
.bytes = self.contents[offset..],
- .i = std.math.min(offset, self.contents.len),
+ .i = 0,
};
// Scan to the end of the line (or end of file if this is the last line)
@@ -436,15 +442,15 @@ pub const Source = struct {
}
}
return ErrorPosition{
- .line_start = line_start,
+ .line_start = if (line_start > 0) line_start - 1 else line_start,
.line_end = line_end,
.line_count = line_count,
- .column_count = offset - line_start,
+ .column_count = column_number,
};
}
};
-pub fn rangeData(source: ?*Source, r: Range, text: string) Data {
+pub fn rangeData(source: ?*const Source, r: Range, text: string) Data {
return Data{ .text = text, .location = Location.init_or_nil(source, r) };
}
@@ -453,16 +459,45 @@ test "print msg" {
var log = Log{ .msgs = msgs };
defer log.msgs.deinit();
var filename = "test.js".*;
- var syntax = "for(i = 0;)".*;
+ 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 },
+ .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{ .contents = @embedFile("./test/fixtures/simple.jsx"), .path = fs.Path.init("/src/test/fixtures/simple.jsx"), .identifier_name = "simple" };
+ const error_position = source.initErrorPosition(Loc{ .start = 979 });
+
+ std.testing.expectEqual(973, error_position.line_start);
+ std.testing.expectEqual(1016, error_position.line_end);
+
+ 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 = rangeData(&source, Range{ .loc = Loc{
+ .start = 979,
+ }, .len = 15 }, "Oh no"),
+ });
+
+ const stdout = std.io.getStdOut().writer();
+ try log.print(stdout);
+}
diff --git a/src/main.zig b/src/main.zig
index 07c1d6954..5f735412d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -87,6 +87,7 @@ pub fn main() anyerror!void {
alloc.dynamic,
ast,
js_ast.Symbol.Map.initList(symbols),
+ &source,
false,
js_printer.Options{ .to_module_ref = ast.module_ref orelse js_ast.Ref{ .inner_index = 0 } },
&_linker,
diff --git a/src/renamer.zig b/src/renamer.zig
index c39a51847..eef40d111 100644
--- a/src/renamer.zig
+++ b/src/renamer.zig
@@ -1,18 +1,27 @@
const js_ast = @import("js_ast.zig");
usingnamespace @import("strings.zig");
const std = @import("std");
+const logger = @import("logger.zig");
pub const Renamer = struct {
symbols: js_ast.Symbol.Map,
- pub fn init(symbols: js_ast.Symbol.Map) Renamer {
- return Renamer{ .symbols = symbols };
+ source: *logger.Source,
+
+ pub fn init(symbols: js_ast.Symbol.Map, source: *logger.Source) Renamer {
+ return Renamer{ .symbols = symbols, .source = source };
}
pub fn nameForSymbol(renamer: *Renamer, ref: js_ast.Ref) string {
- const resolved = renamer.symbols.follow(ref);
- const symbol = renamer.symbols.get(resolved) orelse std.debug.panic("Internal error: symbol not found for ref: {s}", .{resolved});
+ if (ref.is_source_contents_slice) {
+ return renamer.source.contents[ref.source_index .. ref.source_index + ref.inner_index];
+ }
- return symbol.original_name;
+ const resolved = renamer.symbols.follow(ref);
+ if (renamer.symbols.get(resolved)) |symbol| {
+ return symbol.original_name;
+ } else {
+ std.debug.panic("Invalid symbol {s}", .{ref});
+ }
}
};