diff --git a/.lldbinit b/.lldbinit index 2d527f4e63..5a59503d5d 100644 --- a/.lldbinit +++ b/.lldbinit @@ -1,2 +1,4 @@ command script import src/deps/zig/tools/lldb_pretty_printers.py command script import src/bun.js/WebKit/Tools/lldb/lldb_webkit.py + +# type summary add --summary-string "${var} | inner=${var[0-30]}, source=${var[33-64]}, tag=${var[31-32]}" "unsigned long" diff --git a/src/ast/base.zig b/src/ast/base.zig index 151a771919..20eb0183bb 100644 --- a/src/ast/base.zig +++ b/src/ast/base.zig @@ -2,6 +2,8 @@ const std = @import("std"); const bun = @import("root").bun; const unicode = std.unicode; +const js_ast = bun.JSAst; + pub const NodeIndex = u32; pub const NodeIndexNone = 4294967293; @@ -147,6 +149,34 @@ pub const Ref = packed struct(u64) { ); } + pub fn dump(ref: Ref, symbol_table: anytype) std.fmt.Formatter(dumpImpl) { + return .{ .data = .{ + .ref = ref, + .symbol_table = switch (@TypeOf(symbol_table)) { + *const std.ArrayList(js_ast.Symbol) => symbol_table.items, + *std.ArrayList(js_ast.Symbol) => symbol_table.items, + []const js_ast.Symbol => symbol_table, + []js_ast.Symbol => symbol_table, + else => |T| @compileError("Unsupported type to Ref.dump: " ++ @typeName(T)), + }, + } }; + } + + fn dumpImpl(data: struct { ref: Ref, symbol_table: []const js_ast.Symbol }, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { + const symbol = data.symbol_table[data.ref.inner_index]; + try std.fmt.format( + writer, + "Ref[inner={d}, src={d}, .{s}; original_name={s}, uses={d}]", + .{ + data.ref.inner_index, + data.ref.source_index, + @tagName(data.ref.tag), + symbol.original_name, + symbol.use_count_estimate, + }, + ); + } + pub fn isValid(this: Ref) bool { return this.tag != .invalid; } diff --git a/src/js_parser.zig b/src/js_parser.zig index ee975f28ea..4a23c03238 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -3783,10 +3783,12 @@ pub const Parser = struct { var remaining_stmts = all_stmts; for (p.imports_to_convert_from_require.items) |deferred_import| { - var stmts_ = remaining_stmts[0..1]; + var import_part_stmts = remaining_stmts[0..1]; remaining_stmts = remaining_stmts[1..]; - stmts_[0] = Stmt.alloc( + p.module_scope.generated.push(p.allocator, deferred_import.namespace.ref.?) catch bun.outOfMemory(); + + import_part_stmts[0] = Stmt.alloc( S.Import, S.Import{ .star_name_loc = deferred_import.namespace.loc, @@ -3798,10 +3800,11 @@ pub const Parser = struct { var declared_symbols = DeclaredSymbol.List.initCapacity(p.allocator, 1) catch unreachable; declared_symbols.appendAssumeCapacity(.{ .ref = deferred_import.namespace.ref.?, .is_top_level = true }); before.appendAssumeCapacity(.{ - .stmts = stmts_, + .stmts = import_part_stmts, .declared_symbols = declared_symbols, .tag = .import_to_convert_from_require, - .can_be_removed_if_unused = p.stmtsCanBeRemovedIfUnused(stmts_), + // This part has a single symbol, so it may be removed if unused. + .can_be_removed_if_unused = true, }); } bun.assert(remaining_stmts.len == 0); diff --git a/src/renamer.zig b/src/renamer.zig index e23d4aba2c..30c6a21ecf 100644 --- a/src/renamer.zig +++ b/src/renamer.zig @@ -383,6 +383,7 @@ pub fn assignNestedScopeSlots(allocator: std.mem.Allocator, module_scope: *js_as pub fn assignNestedScopeSlotsHelper(sorted_members: *std.ArrayList(u32), scope: *js_ast.Scope, symbols: []js_ast.Symbol, slot_to_copy: js_ast.SlotCounts) js_ast.SlotCounts { var slot = slot_to_copy; + // Sort member map keys for determinism { sorted_members.clearRetainingCapacity(); diff --git a/src/shell/shell.zig b/src/shell/shell.zig index 19cb9f1d8b..871cab7f92 100644 --- a/src/shell/shell.zig +++ b/src/shell/shell.zig @@ -3316,14 +3316,6 @@ pub fn NewLexer(comptime encoding: StringEncoding) type { fn read_char(self: *@This()) ?InputChar { return self.chars.read_char(); } - - // fn debug_tokens(self: *const @This()) void { - // std.debug.print("Tokens: \n", .{}); - // for (self.tokens.items, 0..) |tok, i| { - // std.debug.print("{d}: ", .{i}); - // tok.debug(self.strpool.items[0..self.strpool.items.len]); - // } - // } }; } diff --git a/test/bundler/bundler_cjs2esm.test.ts b/test/bundler/bundler_cjs2esm.test.ts index 6aff61dfbc..ddc0e5fc5e 100644 --- a/test/bundler/bundler_cjs2esm.test.ts +++ b/test/bundler/bundler_cjs2esm.test.ts @@ -307,4 +307,44 @@ describe("bundler", () => { }, minifySyntax: true, }); + itBundled("cjs2esm/ReactSpecificUnwrapping2", { + files: { + "/entry.js": /* js */ ` + import * as react from "react-dom"; + console.log(react); + `, + "/node_modules/react-dom/index.js": /* js */ ` + export const stuff = [ + require('./a.js'), + require('./b.js') + ]; + `, + "/node_modules/react-dom/a.js": /* js */ ` + (function () { + var React = require('react'); + var stream = require('stream'); + + console.log([React, stream]); + + exports.version = null; + })(); + `, + "/node_modules/react-dom/b.js": /* js */ ` + (function () { + var React = require('react'); + var util = require('util'); + + console.log([React, util]); + + exports.version = null; + })(); + `, + "/node_modules/react/index.js": /* js */ ` + module.exports = 123; + `, + }, + run: true, + minifyIdentifiers: true, + target: "bun", + }); }); diff --git a/test/bundler/bundler_edgecase.test.ts b/test/bundler/bundler_edgecase.test.ts index 6bc239e3cd..a5948940b3 100644 --- a/test/bundler/bundler_edgecase.test.ts +++ b/test/bundler/bundler_edgecase.test.ts @@ -674,7 +674,7 @@ describe("bundler", () => { const std = @import("std"); pub fn main() void { - std.debug.print("Hello, world!\\n", .{}); + std.log.info("Hello, world!\\n", .{}); } `, }, @@ -684,7 +684,7 @@ describe("bundler", () => { "/exec.js": ` import assert from 'node:assert'; import the_path from './out/entry.js'; - assert.strictEqual(the_path, './entry-6dhkdck1.zig'); + assert.strictEqual(the_path, './entry-z5artd5z.zig'); `, }, run: { diff --git a/test/bundler/bundler_npm.test.ts b/test/bundler/bundler_npm.test.ts index 0d7f48c7fc..dcbc14705d 100644 --- a/test/bundler/bundler_npm.test.ts +++ b/test/bundler/bundler_npm.test.ts @@ -57,15 +57,18 @@ describe("bundler", () => { "../entry.tsx", ], mappings: [ - ["react.development.js:524:'getContextName'", "1:5404:r1"], - ["react.development.js:2495:'actScopeDepth'", "1:26072:GJ++"], - ["react.development.js:696:''Component'", '1:7470:\'Component "%s"'], - ["entry.tsx:6:'\"Content-Type\"'", '1:221669:"Content-Type"'], - ["entry.tsx:11:''", "1:221925:void"], - ["entry.tsx:23:'await'", "1:222026:await"], + ["react.development.js:524:'getContextName'", "1:5428:Y1"], + ["react.development.js:2495:'actScopeDepth'", "1:26053:GJ++"], + ["react.development.js:696:''Component'", '1:7490:\'Component "%s"'], + ["entry.tsx:6:'\"Content-Type\"'", '1:221655:"Content-Type"'], + ["entry.tsx:11:''", "1:221911:void"], + ["entry.tsx:23:'await'", "1:222013:await"], ], }, }, + expectExactFilesize: { + "out/entry.js": 222283, + }, run: { stdout: "
This is an example.
", }, diff --git a/test/bundler/expectBundled.ts b/test/bundler/expectBundled.ts index 195a710cda..ce8c8131de 100644 --- a/test/bundler/expectBundled.ts +++ b/test/bundler/expectBundled.ts @@ -267,6 +267,8 @@ export interface BundlerTestInput { skipIfWeDidNotImplementWildcardSideEffects?: boolean; snapshotSourceMap?: Record