aboutsummaryrefslogtreecommitdiff
path: root/src/js_parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/js_parser.zig')
-rw-r--r--src/js_parser.zig393
1 files changed, 238 insertions, 155 deletions
diff --git a/src/js_parser.zig b/src/js_parser.zig
index 33a8cef6d..3c706b1bb 100644
--- a/src/js_parser.zig
+++ b/src/js_parser.zig
@@ -965,7 +965,7 @@ pub const ImportScanner = struct {
}
p.named_imports.ensureUnusedCapacity(
- st.items.len + @as(usize, @boolToInt(st.default_name != null)) + @as(usize, @boolToInt(st.star_name_loc != null)),
+ st.items.len + @as(usize, @intFromBool(st.default_name != null)) + @as(usize, @intFromBool(st.star_name_loc != null)),
) catch unreachable;
if (st.star_name_loc) |loc| {
@@ -1354,7 +1354,7 @@ const StaticSymbolName = struct {
pub const List = struct {
fn NewStaticSymbol(comptime basename: string) StaticSymbolName {
- const hash_value = std.hash.Wyhash.hash(0, basename);
+ const hash_value = bun.hash(basename);
return comptime StaticSymbolName{
.internal = basename ++ "_" ++ std.fmt.comptimePrint("{any}", .{bun.fmt.hexIntLower(hash_value)}),
.primary = basename,
@@ -1363,7 +1363,7 @@ const StaticSymbolName = struct {
}
fn NewStaticSymbolWithBackup(comptime basename: string, comptime backup: string) StaticSymbolName {
- const hash_value = std.hash.Wyhash.hash(0, basename);
+ const hash_value = bun.hash(basename);
return comptime StaticSymbolName{
.internal = basename ++ "_" ++ std.fmt.comptimePrint("{any}", .{bun.fmt.hexIntLower(hash_value)}),
.primary = basename,
@@ -1555,7 +1555,7 @@ pub const SideEffects = enum(u1) {
// can be removed. The annotation causes us to ignore the target.
if (call.can_be_unwrapped_if_unused) {
if (call.args.len > 0) {
- return Expr.joinAllWithCommaCallback(call.args.slice(), @TypeOf(p), p, simpifyUnusedExpr, p.allocator);
+ return Expr.joinAllWithCommaCallback(call.args.slice(), @TypeOf(p), p, comptime simpifyUnusedExpr, p.allocator);
}
}
},
@@ -1683,7 +1683,7 @@ pub const SideEffects = enum(u1) {
items,
@TypeOf(p),
p,
- simpifyUnusedExpr,
+ comptime simpifyUnusedExpr,
p.allocator,
);
},
@@ -1697,7 +1697,7 @@ pub const SideEffects = enum(u1) {
call.args.slice(),
@TypeOf(p),
p,
- simpifyUnusedExpr,
+ comptime simpifyUnusedExpr,
p.allocator,
);
}
@@ -2629,6 +2629,7 @@ pub const Parser = struct {
tree_shaking: bool = false,
bundle: bool = false,
+ package_version: string = "",
macro_context: *MacroContextType() = undefined,
@@ -3022,7 +3023,7 @@ pub const Parser = struct {
const uses_filename = p.symbols.items[p.filename_ref.innerIndex()].use_count_estimate > 0;
if (uses_dirname or uses_filename) {
- const count = @as(usize, @boolToInt(uses_dirname)) + @as(usize, @boolToInt(uses_filename));
+ const count = @as(usize, @intFromBool(uses_dirname)) + @as(usize, @intFromBool(uses_filename));
var declared_symbols = DeclaredSymbol.List.initCapacity(p.allocator, count) catch unreachable;
var decls = p.allocator.alloc(G.Decl, count) catch unreachable;
if (uses_dirname) {
@@ -3037,7 +3038,7 @@ pub const Parser = struct {
declared_symbols.appendAssumeCapacity(.{ .ref = p.dirname_ref, .is_top_level = true });
}
if (uses_filename) {
- decls[@as(usize, @boolToInt(uses_dirname))] = .{
+ decls[@as(usize, @intFromBool(uses_dirname))] = .{
.binding = p.b(B.Identifier{ .ref = p.filename_ref }, logger.Loc.Empty),
.value = p.newExpr(
E.String.init(p.source.path.text),
@@ -3102,70 +3103,28 @@ pub const Parser = struct {
var export_refs = p.commonjs_named_exports.values();
var export_names = p.commonjs_named_exports.keys();
- if (!p.commonjs_named_exports_deoptimized) {
-
- // This is a workaround for packages which have broken ESM checks
- // If they never actually assign to exports.foo, only check for it
- // and the package specifies type "module"
- // and the package uses ESM syntax
- // We should just say
- // You're ESM and lying about it.
- if (p.options.module_type == .esm and p.has_es_module_syntax) {
+ break_optimize: {
+ if (!p.commonjs_named_exports_deoptimized) {
var needs_decl_count: usize = 0;
for (export_refs) |*export_ref| {
- needs_decl_count += @as(usize, @boolToInt(export_ref.needs_decl));
+ needs_decl_count += @as(usize, @intFromBool(export_ref.needs_decl));
}
-
- if (needs_decl_count == export_names.len) {
- force_esm = true;
+ // This is a workaround for packages which have broken ESM checks
+ // If they never actually assign to exports.foo, only check for it
+ // and the package specifies type "module"
+ // and the package uses ESM syntax
+ // We should just say
+ // You're ESM and lying about it.
+ if (p.options.module_type == .esm or p.has_es_module_syntax) {
+ if (needs_decl_count == export_names.len) {
+ force_esm = true;
+ break :break_optimize;
+ }
}
- }
-
- if (!force_esm) {
- // We make this safe by doing toCommonJS() at runtime
- for (export_refs, export_names) |*export_ref, alias| {
- if (export_ref.needs_decl) {
- var this_stmts = p.allocator.alloc(Stmt, 2) catch unreachable;
- var decls = p.allocator.alloc(Decl, 1) catch unreachable;
- const ref = export_ref.loc_ref.ref.?;
- decls[0] = .{
- .binding = p.b(B.Identifier{ .ref = ref }, export_ref.loc_ref.loc),
- .value = null,
- };
- var declared_symbols = DeclaredSymbol.List.initCapacity(p.allocator, 1) catch unreachable;
- declared_symbols.appendAssumeCapacity(.{ .ref = ref, .is_top_level = true });
- this_stmts[0] = p.s(
- S.Local{
- .kind = .k_var,
- .is_export = false,
- .was_commonjs_export = true,
- .decls = Decl.List.init(decls),
- },
- export_ref.loc_ref.loc,
- );
- p.module_scope.generated.push(p.allocator, ref) catch unreachable;
- var clause_items = p.allocator.alloc(js_ast.ClauseItem, 1) catch unreachable;
- clause_items[0] = js_ast.ClauseItem{
- .alias = alias,
- .alias_loc = export_ref.loc_ref.loc,
- .name = export_ref.loc_ref,
- };
- this_stmts[1] = p.s(
- S.ExportClause{
- .items = clause_items,
- .is_single_line = true,
- },
- export_ref.loc_ref.loc,
- );
- export_ref.needs_decl = false;
- before.append(.{
- .stmts = this_stmts,
- .declared_symbols = declared_symbols,
- .tag = .commonjs_named_export,
- .can_be_removed_if_unused = p.stmtsCanBeRemovedIfUnused(this_stmts),
- }) catch unreachable;
- }
+ if (needs_decl_count > 0) {
+ p.symbols.items[p.exports_ref.innerIndex()].use_count_estimate += @truncate(u32, export_refs.len);
+ p.deoptimizeCommonJSNamedExports();
}
}
}
@@ -3200,22 +3159,53 @@ pub const Parser = struct {
const left = bin.left;
const right = bin.right;
if (bin.op == .bin_assign and
- right.data == .e_require_string and
left.data == .e_dot and
strings.eqlComptime(left.data.e_dot.name, "exports") and
left.data.e_dot.target.data == .e_identifier and
left.data.e_dot.target.data.e_identifier.ref.eql(p.module_ref))
{
- part.symbol_uses = .{};
- return js_ast.Result{
- .ast = js_ast.Ast{
- .allocator = p.allocator,
- .import_records = ImportRecord.List.init(p.import_records.items),
- .redirect_import_record_index = right.data.e_require_string.import_record_index,
- .named_imports = p.named_imports,
- .named_exports = p.named_exports,
- },
+ const redirect_import_record_index: ?u32 = brk: {
+ // general case:
+ //
+ // module.exports = require("foo");
+ //
+ if (right.data == .e_require_string) {
+ break :brk right.data.e_require_string.import_record_index;
+ }
+
+ // special case: a module for us to unwrap
+ //
+ // module.exports = require("react/jsx-runtime")
+ // ^ was converted into:
+ //
+ // import * as Foo from 'bar';
+ // module.exports = Foo;
+ //
+ // This is what fixes #3537
+ if (right.data == .e_identifier and
+ p.import_records.items.len == 1 and
+ p.imports_to_convert_from_require.items.len == 1 and
+ p.imports_to_convert_from_require.items[0].namespace.ref.?.eql(right.data.e_identifier.ref))
+ {
+ // We know it's 0 because there is only one import in the whole file
+ // so that one import must be the one we're looking for
+ break :brk 0;
+ }
+
+ break :brk null;
};
+ if (redirect_import_record_index) |id| {
+ part.symbol_uses = .{};
+ return js_ast.Result{
+ .ast = js_ast.Ast{
+ .allocator = p.allocator,
+ .import_records = ImportRecord.List.init(p.import_records.items),
+ .redirect_import_record_index = id,
+ .named_imports = p.named_imports,
+ .named_exports = p.named_exports,
+ },
+ };
+ }
}
}
}
@@ -3483,7 +3473,7 @@ pub const Parser = struct {
const items_count = brk: {
var count: usize = 0;
inline for (comptime std.meta.fieldNames(Jest)) |symbol_name| {
- count += @boolToInt(p.symbols.items[@field(jest, symbol_name).innerIndex()].use_count_estimate > 0);
+ count += @intFromBool(p.symbols.items[@field(jest, symbol_name).innerIndex()].use_count_estimate > 0);
}
break :brk count;
@@ -3611,21 +3601,21 @@ pub const Parser = struct {
// const decls_count: u32 =
// // "REACT_ELEMENT_TYPE"
// // "Symbol.for('react.element')"
- // @intCast(u32, @boolToInt(react_element_symbol.use_count_estimate > 0)) * 2 +
+ // @intCast(u32, @intFromBool(react_element_symbol.use_count_estimate > 0)) * 2 +
// // "JSX"
- // @intCast(u32, @boolToInt(jsx_symbol.use_count_estimate > 0)) * 2 +
- // @intCast(u32, @boolToInt(FeatureFlags.support_jsxs_in_jsx_transform and jsx_static_symbol.use_count_estimate > 0)) * 2 +
- // @intCast(u32, @boolToInt(jsx_factory_symbol.use_count_estimate > 0)) +
- // @intCast(u32, @boolToInt(jsx_fragment_symbol.use_count_estimate > 0));
- // // @intCast(u32, @boolToInt(jsx_filename_symbol.use_count_estimate > 0));
+ // @intCast(u32, @intFromBool(jsx_symbol.use_count_estimate > 0)) * 2 +
+ // @intCast(u32, @intFromBool(FeatureFlags.support_jsxs_in_jsx_transform and jsx_static_symbol.use_count_estimate > 0)) * 2 +
+ // @intCast(u32, @intFromBool(jsx_factory_symbol.use_count_estimate > 0)) +
+ // @intCast(u32, @intFromBool(jsx_fragment_symbol.use_count_estimate > 0));
+ // // @intCast(u32, @intFromBool(jsx_filename_symbol.use_count_estimate > 0));
// const imports_count =
- // @intCast(u32, @boolToInt(jsx_symbol.use_count_estimate > 0)) +
- // @intCast(u32, @boolToInt(jsx_classic_symbol.use_count_estimate > 0)) +
- // @intCast(u32, @boolToInt(jsx_fragment_symbol.use_count_estimate > 0)) +
- // @intCast(u32, @boolToInt(p.options.features.react_fast_refresh)) +
- // @intCast(u32, @boolToInt(FeatureFlags.support_jsxs_in_jsx_transform and jsx_static_symbol.use_count_estimate > 0));
+ // @intCast(u32, @intFromBool(jsx_symbol.use_count_estimate > 0)) +
+ // @intCast(u32, @intFromBool(jsx_classic_symbol.use_count_estimate > 0)) +
+ // @intCast(u32, @intFromBool(jsx_fragment_symbol.use_count_estimate > 0)) +
+ // @intCast(u32, @intFromBool(p.options.features.react_fast_refresh)) +
+ // @intCast(u32, @intFromBool(FeatureFlags.support_jsxs_in_jsx_transform and jsx_static_symbol.use_count_estimate > 0));
// const stmts_count = imports_count + 1;
// const symbols_count: u32 = imports_count + decls_count;
// const loc = logger.Loc{ .start = 0 };
@@ -3989,7 +3979,7 @@ pub const Parser = struct {
// // inject
// // var jsxFrag =
// if (jsx_fragment_symbol.use_count_estimate + jsx_factory_symbol.use_count_estimate > 0) {
- // const total = @as(usize, @boolToInt(jsx_fragment_symbol.use_count_estimate > 0)) + @as(usize, @boolToInt(jsx_factory_symbol.use_count_estimate > 0));
+ // const total = @as(usize, @intFromBool(jsx_fragment_symbol.use_count_estimate > 0)) + @as(usize, @intFromBool(jsx_factory_symbol.use_count_estimate > 0));
// var declared_symbols = DeclaredSymbol.List{};
// try declared_symbols.ensureTotalCapacity(p.allocator, total);
// var decls = try std.ArrayList(G.Decl).initCapacity(p.allocator, total);
@@ -4206,7 +4196,7 @@ pub const Parser = struct {
i += 1;
}
- std.sort.sort(
+ std.sort.block(
u8,
runtime_imports[0..i],
{},
@@ -5214,10 +5204,7 @@ fn NewParser_(
const symbol_name = p.import_records.items[import_record_index].path.name.nonUniqueNameString(p.allocator) catch unreachable;
const hash_value = @truncate(
u16,
- std.hash.Wyhash.hash(
- 0,
- p.import_records.items[import_record_index].path.text,
- ),
+ bun.hash(p.import_records.items[import_record_index].path.text),
);
const cjs_import_name = std.fmt.allocPrint(
@@ -6901,7 +6888,7 @@ fn NewParser_(
// Output.print("\n+Loc: {d}\n", .{loc.start});
// for (p.scopes_in_order.items[p.scopes_in_order_visitor_index..p.scopes_in_order.items.len]) |scope_order, i| {
// if (scope_order) |ord| {
- // Output.print("Scope ({d}, {d})\n", .{ @enumToInt(ord.scope.kind), ord.loc.start });
+ // Output.print("Scope ({d}, {d})\n", .{ @intFromEnum(ord.scope.kind), ord.loc.start });
// }
// }
const order = p.nextScopeInOrderForVisitPass();
@@ -8217,7 +8204,7 @@ fn NewParser_(
var item_refs = ImportItemForNamespaceMap.init(p.allocator);
const count_excluding_namespace = @intCast(u16, stmt.items.len) +
- @intCast(u16, @boolToInt(stmt.default_name != null));
+ @intCast(u16, @intFromBool(stmt.default_name != null));
try item_refs.ensureUnusedCapacity(count_excluding_namespace);
// Even though we allocate ahead of time here
@@ -8328,7 +8315,7 @@ fn NewParser_(
return p.s(S.Empty{}, loc);
} else if (remap_count > 0) {
- item_refs.shrinkAndFree(stmt.items.len + @as(usize, @boolToInt(stmt.default_name != null)));
+ item_refs.shrinkAndFree(stmt.items.len + @as(usize, @intFromBool(stmt.default_name != null)));
}
// Track the items for this namespace
@@ -11518,8 +11505,8 @@ fn NewParser_(
}
}
- if (@ptrToInt(p.source.contents.ptr) <= @ptrToInt(name.ptr) and (@ptrToInt(name.ptr) + name.len) <= (@ptrToInt(p.source.contents.ptr) + p.source.contents.len)) {
- const start = Ref.toInt(@ptrToInt(name.ptr) - @ptrToInt(p.source.contents.ptr));
+ if (@intFromPtr(p.source.contents.ptr) <= @intFromPtr(name.ptr) and (@intFromPtr(name.ptr) + name.len) <= (@intFromPtr(p.source.contents.ptr) + p.source.contents.len)) {
+ const start = Ref.toInt(@intFromPtr(name.ptr) - @intFromPtr(p.source.contents.ptr));
const end = Ref.toInt(name.len);
return Ref.initSourceEnd(.{ .source_index = start, .inner_index = end, .tag = .source_contents_slice });
} else {
@@ -11805,7 +11792,7 @@ fn NewParser_(
// to the expression "a().b()".
if (had_pure_comment_before and level.lt(.call)) {
- expr = try p.parseSuffix(expr, @intToEnum(Level, @enumToInt(Level.call) - 1), errors, flags);
+ expr = try p.parseSuffix(expr, @enumFromInt(Level, @intFromEnum(Level.call) - 1), errors, flags);
switch (expr.data) {
.e_call => |ex| {
ex.can_be_unwrapped_if_unused = true;
@@ -12996,7 +12983,7 @@ fn NewParser_(
}
try p.lexer.next();
- left = p.newExpr(E.Binary{ .op = .bin_add_assign, .left = left, .right = try p.parseExpr(@intToEnum(Op.Level, @enumToInt(Op.Level.assign) - 1)) }, left.loc);
+ left = p.newExpr(E.Binary{ .op = .bin_add_assign, .left = left, .right = try p.parseExpr(@enumFromInt(Op.Level, @intFromEnum(Op.Level.assign) - 1)) }, left.loc);
},
.t_minus => {
if (level.gte(.add)) {
@@ -13474,7 +13461,7 @@ fn NewParser_(
pub fn parsePrefix(p: *P, level: Level, errors: ?*DeferredErrors, flags: Expr.EFlags) anyerror!Expr {
const loc = p.lexer.loc();
- const l = @enumToInt(level);
+ const l = @intFromEnum(level);
// Output.print("Parse Prefix {s}:{s} @{s} ", .{ p.lexer.token, p.lexer.raw(), @tagName(level) });
switch (p.lexer.token) {
@@ -13484,7 +13471,7 @@ fn NewParser_(
switch (p.lexer.token) {
.t_open_paren => {
- if (l < @enumToInt(Level.call) and p.fn_or_arrow_data_parse.allow_super_call) {
+ if (l < @intFromEnum(Level.call) and p.fn_or_arrow_data_parse.allow_super_call) {
return p.newExpr(E.Super{}, loc);
}
},
@@ -14239,7 +14226,7 @@ fn NewParser_(
// Use NextInsideJSXElement() not Next() so we can parse a JSX-style string literal
try p.lexer.nextInsideJSXElement();
if (p.lexer.token == .t_string_literal) {
- previous_string_with_backslash_loc.start = std.math.max(p.lexer.loc().start, p.lexer.previous_backslash_quote_in_jsx.loc.start);
+ previous_string_with_backslash_loc.start = @max(p.lexer.loc().start, p.lexer.previous_backslash_quote_in_jsx.loc.start);
const expr = p.newExpr(p.lexer.toEString(), previous_string_with_backslash_loc.*);
try p.lexer.nextInsideJSXElement();
@@ -15155,7 +15142,7 @@ fn NewParser_(
var i: usize = 2;
args[0] = tag;
- const num_props = e_.properties.len + @boolToInt(e_.key != null);
+ const num_props = e_.properties.len + @intFromBool(e_.key != null);
if (num_props > 0) {
var props = p.allocator.alloc(G.Property, num_props) catch unreachable;
bun.copy(G.Property, props, e_.properties.slice());
@@ -15170,7 +15157,7 @@ fn NewParser_(
const children_elements = e_.children.slice()[0..children_count];
for (children_elements) |child| {
args[i] = p.visitExpr(child);
- i += @intCast(usize, @boolToInt(args[i].data != .e_missing));
+ i += @intCast(usize, @intFromBool(args[i].data != .e_missing));
}
const target = p.jsxStringsToMemberExpression(expr.loc, p.options.jsx.factory) catch unreachable;
@@ -15201,7 +15188,7 @@ fn NewParser_(
for (children) |child| {
e_.children.ptr[last_child] = p.visitExpr(child);
// if tree-shaking removes the element, we must also remove it here.
- last_child += @intCast(u32, @boolToInt(e_.children.ptr[last_child].data != .e_missing));
+ last_child += @intCast(u32, @intFromBool(e_.children.ptr[last_child].data != .e_missing));
}
e_.children.len = last_child;
}
@@ -15374,7 +15361,7 @@ fn NewParser_(
// Either:
// jsxDEV(type, arguments, key, isStaticChildren, source, self)
// jsx(type, arguments, key)
- const args = p.allocator.alloc(Expr, if (p.options.jsx.development) @as(usize, 6) else @as(usize, 2) + @as(usize, @boolToInt(e_.key != null))) catch unreachable;
+ const args = p.allocator.alloc(Expr, if (p.options.jsx.development) @as(usize, 6) else @as(usize, 2) + @as(usize, @intFromBool(e_.key != null))) catch unreachable;
args[0] = tag;
args[1] = p.newExpr(E.Object{
@@ -15838,7 +15825,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) << @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) << @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15846,7 +15833,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) >> @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) >> @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15854,7 +15841,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) >> @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) >> @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15862,7 +15849,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) >> @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) >> @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15870,7 +15857,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) >> @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) >> @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15878,7 +15865,7 @@ fn NewParser_(
// TODO:
// if (p.should_fold_typescript_constant_expressions) {
// if (Expr.extractNumericValues(e_.left.data, e_.right.data)) |vals| {
- // return p.newExpr(E.Number{ .value = ((@floatToInt(i32, vals[0]) >> @floatToInt(u32, vals[1])) & 31) }, expr.loc);
+ // return p.newExpr(E.Number{ .value = ((@intFromFloat(i32, vals[0]) >> @intFromFloat(u32, vals[1])) & 31) }, expr.loc);
// }
// }
},
@@ -15945,6 +15932,30 @@ fn NewParser_(
const is_call_target = std.meta.activeTag(p.call_target) == .e_index and expr.data.e_index == p.call_target.e_index;
const is_delete_target = std.meta.activeTag(p.delete_target) == .e_index and expr.data.e_index == p.delete_target.e_index;
+ if (p.options.features.minify_syntax) {
+ if (e_.index.data == .e_string and e_.index.data.e_string.isUTF8() and e_.index.data.e_string.isIdentifier(p.allocator)) {
+ const dot = p.newExpr(
+ E.Dot{
+ .name = e_.index.data.e_string.slice(p.allocator),
+ .name_loc = e_.index.loc,
+ .target = e_.target,
+ .optional_chain = e_.optional_chain,
+ },
+ expr.loc,
+ );
+
+ if (is_call_target) {
+ p.call_target = dot.data;
+ }
+
+ if (is_delete_target) {
+ p.delete_target = dot.data;
+ }
+
+ return p.visitExprInOut(dot, in);
+ }
+ }
+
const target = p.visitExprInOut(e_.target, ExprIn{
// this is awkward due to a zig compiler bug
.has_chain_parent = (e_.optional_chain orelse js_ast.OptionalChain.start) == js_ast.OptionalChain.ccontinue,
@@ -17757,7 +17768,7 @@ fn NewParser_(
if (p.options.features.minify_syntax) {
// minify "long-string".length to 11
if (strings.eqlComptime(name, "length")) {
- return p.newExpr(E.Number{ .value = @intToFloat(f64, str.javascriptLength()) }, loc);
+ return p.newExpr(E.Number{ .value = @floatFromInt(f64, str.javascriptLength()) }, loc);
}
}
},
@@ -18135,7 +18146,28 @@ fn NewParser_(
data.default_name = createDefaultName(p, stmt.loc) catch unreachable;
}
- stmts.append(stmt.*) catch unreachable;
+ // We only inject a name into classes when there is a decorator
+ if (class.class.has_decorators) {
+ if (class.class.class_name == null or
+ class.class.class_name.?.ref == null)
+ {
+ class.class.class_name = data.default_name;
+ }
+ }
+
+ // This is to handle TS decorators, mostly.
+ var class_stmts = p.lowerClass(.{ .stmt = s2 });
+ std.debug.assert(class_stmts[0].data == .s_class);
+
+ if (class_stmts.len > 1) {
+ data.value.stmt = class_stmts[0];
+ stmts.append(stmt.*) catch {};
+ stmts.appendSlice(class_stmts[1..]) catch {};
+ } else {
+ data.value.stmt = class_stmts[0];
+ stmts.append(stmt.*) catch {};
+ }
+
return;
},
else => {},
@@ -19457,7 +19489,7 @@ fn NewParser_(
for (arg.ts_decorators.ptr[0..arg.ts_decorators.len]) |arg_decorator| {
var decorators = if (is_constructor) class.ts_decorators.listManaged(p.allocator) else prop.ts_decorators.listManaged(p.allocator);
const args = p.allocator.alloc(Expr, 2) catch unreachable;
- args[0] = p.newExpr(E.Number{ .value = @intToFloat(f64, i) }, arg_decorator.loc);
+ args[0] = p.newExpr(E.Number{ .value = @floatFromInt(f64, i) }, arg_decorator.loc);
args[1] = arg_decorator;
decorators.append(p.callRuntime(arg_decorator.loc, "__decorateParam", args)) catch unreachable;
if (is_constructor) {
@@ -20088,7 +20120,7 @@ fn NewParser_(
if (constructor_function) |constructor| {
var to_add: usize = 0;
for (constructor.func.args) |arg| {
- to_add += @boolToInt(arg.is_typescript_ctor_field and arg.binding.data == .b_identifier);
+ to_add += @intFromBool(arg.is_typescript_ctor_field and arg.binding.data == .b_identifier);
}
// if this is an expression, we can move statements after super() because there will be 0 decorators
@@ -20368,7 +20400,7 @@ fn NewParser_(
}
before.items.len = 0;
- before.ensureUnusedCapacity(@as(usize, @boolToInt(let_decls.items.len > 0)) + @as(usize, @boolToInt(var_decls.items.len > 0)) + non_fn_stmts.items.len) catch unreachable;
+ before.ensureUnusedCapacity(@as(usize, @intFromBool(let_decls.items.len > 0)) + @as(usize, @intFromBool(var_decls.items.len > 0)) + non_fn_stmts.items.len) catch unreachable;
if (let_decls.items.len > 0) {
before.appendAssumeCapacity(p.s(
@@ -20994,7 +21026,7 @@ fn NewParser_(
// }
const bundling = p.options.bundle;
- var parts_end: usize = @as(usize, @boolToInt(bundling));
+ var parts_end: usize = @as(usize, @intFromBool(bundling));
// Handle import paths after the whole file has been visited because we need
// symbol usage counts to be able to remove unused type-only imports in
// TypeScript code.
@@ -21220,7 +21252,7 @@ fn NewParser_(
logger.Loc.Empty,
);
const cjsGlobal = p.newSymbol(.unbound, "$_BunCommonJSModule_$") catch unreachable;
- var call_args = allocator.alloc(Expr, 6) catch unreachable;
+ var all_call_args = allocator.alloc(Expr, 7) catch unreachable;
const this_module = p.newExpr(
E.Dot{
.name = "module",
@@ -21229,14 +21261,72 @@ fn NewParser_(
},
logger.Loc.Empty,
);
+ var call_args = all_call_args[1..];
+ var bind_args = all_call_args[0..1];
+ bind_args[0] = this_module;
+ const get_require = p.newExpr(
+ E.Dot{
+ .name = "require",
+ .target = this_module,
+ .name_loc = logger.Loc.Empty,
+ },
+ logger.Loc.Empty,
+ );
+
+ const create_binding = p.newExpr(
+ E.Call{
+ .target = p.newExpr(E.Dot{
+ .name = "bind",
+ .name_loc = logger.Loc.Empty,
+ .target = get_require,
+ }, logger.Loc.Empty),
+ .args = bun.BabyList(Expr).init(bind_args),
+ },
+ logger.Loc.Empty,
+ );
+
+ const module_id = p.newExpr(E.Dot{
+ .name = "id",
+ .target = this_module,
+ .name_loc = logger.Loc.Empty,
+ }, logger.Loc.Empty);
+
+ const require_path = p.newExpr(
+ E.Dot{
+ .name = "path",
+ .target = get_require,
+ .name_loc = logger.Loc.Empty,
+ },
+ logger.Loc.Empty,
+ );
+ const assign_binding = p.newExpr(
+ E.Binary{
+ .left = get_require,
+ .right = create_binding,
+ .op = .bin_assign,
+ },
+ logger.Loc.Empty,
+ );
+
+ const assign_id = p.newExpr(E.Binary{
+ .left = require_path,
+ .right = module_id,
+ .op = .bin_assign,
+ }, logger.Loc.Empty);
+
+ var create_require = [3]Expr{
+ assign_binding,
+ assign_id,
+ get_require,
+ };
//
- // (function(module, exports, require, __dirname, __filename) {}).call(this.exports, this.module, this.exports, this.require, __dirname, __filename)
+ // (function(module, exports, require, __dirname, __filename) {}).call(this.exports, this.module, this.exports, this.module.require = this.module.require.bind(module), (this.module.require.id = this.module.id, this.module.require), __dirname, __filename)
call_args[0..6].* = .{
p.newExpr(
E.Dot{
.name = "exports",
- .target = p.newExpr(E.Identifier{ .ref = cjsGlobal }, logger.Loc.Empty),
+ .target = this_module,
.name_loc = logger.Loc.Empty,
},
logger.Loc.Empty,
@@ -21245,33 +21335,12 @@ fn NewParser_(
p.newExpr(
E.Dot{
.name = "exports",
- .target = p.newExpr(E.Identifier{ .ref = cjsGlobal }, logger.Loc.Empty),
+ .target = this_module,
.name_loc = logger.Loc.Empty,
},
logger.Loc.Empty,
),
- p.newExpr(
- E.Binary{
- .left = p.newExpr(
- E.Dot{
- .name = "require",
- .target = this_module,
- .name_loc = logger.Loc.Empty,
- },
- logger.Loc.Empty,
- ),
- .op = .bin_assign,
- .right = p.newExpr(
- E.Dot{
- .name = "require",
- .target = p.newExpr(E.Identifier{ .ref = cjsGlobal }, logger.Loc.Empty),
- .name_loc = logger.Loc.Empty,
- },
- logger.Loc.Empty,
- ),
- },
- logger.Loc.Empty,
- ),
+ Expr.joinAllWithComma(&create_require, p.allocator),
p.newExpr(
E.Dot{
.name = "__dirname",
@@ -21371,7 +21440,7 @@ fn NewParser_(
// We still call exportAll just with an empty object.
const has_any_exports = named_exports_count > 0;
- const toplevel_stmts_count = 3 + (@intCast(usize, @boolToInt(has_any_exports)) * 2);
+ const toplevel_stmts_count = 3 + (@intCast(usize, @intFromBool(has_any_exports)) * 2);
var _stmts = allocator.alloc(
Stmt,
end_iife_stmts_count + toplevel_stmts_count + (named_exports_count * 2) + imports_count + exports_from_count,
@@ -21384,7 +21453,7 @@ fn NewParser_(
// in release: print ";" instead.
// this should never happen regardless, but i'm just being cautious here.
if (comptime !Environment.isDebug) {
- std.mem.set(Stmt, _stmts, Stmt.empty());
+ @memset(_stmts, Stmt.empty());
}
// Second pass: move any imports from the part's stmts array to the new stmts
@@ -21430,7 +21499,7 @@ fn NewParser_(
var new_call_args = call_args[0..new_call_args_count];
var hmr_module_ident = p.newExpr(E.Identifier{ .ref = p.hmr_module.ref }, logger.Loc.Empty);
- new_call_args[0] = p.newExpr(E.Number{ .value = @intToFloat(f64, p.options.filepath_hash_for_hmr) }, logger.Loc.Empty);
+ new_call_args[0] = p.newExpr(E.Number{ .value = @floatFromInt(f64, p.options.filepath_hash_for_hmr) }, logger.Loc.Empty);
// This helps us provide better error messages
new_call_args[1] = p.newExpr(E.String{ .data = p.source.path.pretty }, logger.Loc.Empty);
if (p.options.features.react_fast_refresh) {
@@ -21902,11 +21971,25 @@ fn NewParser_(
// Only enable during bundling
.commonjs_named_exports_deoptimized = !opts.bundle,
- .unwrap_all_requires = opts.bundle and
- if (source.path.packageName()) |pkg|
- opts.features.shouldUnwrapRequire(pkg)
- else
- false,
+ };
+
+ this.unwrap_all_requires = brk: {
+ if (opts.bundle) {
+ if (source.path.packageName()) |pkg| {
+ if (opts.features.shouldUnwrapRequire(pkg)) {
+ if (strings.eqlComptime(pkg, "react") or strings.eqlComptime(pkg, "react-dom")) {
+ const version = opts.package_version;
+ if (version.len > 2 and (version[0] == '0' or (version[0] == '1' and version[1] < '8'))) {
+ break :brk false;
+ }
+ }
+
+ break :brk true;
+ }
+ }
+ }
+
+ break :brk false;
};
this.symbols = std.ArrayList(Symbol).init(allocator);