aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-22 04:08:40 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-09-22 04:08:40 -0700
commit9f7d05bab4f76ee1e51204bd3479c65ab3b9d824 (patch)
treec186e76fcea40dc7834093afc3dc8d7e1d004bea /src
parent53c0a4b5685908abc2f8ebdfa511925edb6b4110 (diff)
downloadbun-9f7d05bab4f76ee1e51204bd3479c65ab3b9d824.tar.gz
bun-9f7d05bab4f76ee1e51204bd3479c65ab3b9d824.tar.zst
bun-9f7d05bab4f76ee1e51204bd3479c65ab3b9d824.zip
Print how many lines of code was parsed in `bun bun`
Diffstat (limited to 'src')
-rw-r--r--src/bundler.zig16
-rw-r--r--src/cli/bun_command.zig31
-rw-r--r--src/js_parser/js_parser.zig31
-rw-r--r--src/resolver/resolver.zig1
4 files changed, 62 insertions, 17 deletions
diff --git a/src/bundler.zig b/src/bundler.zig
index d832c01fe..5a947b656 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -431,6 +431,8 @@ pub fn NewBundler(cache_files: bool) type {
while (generator.queue.next()) |item| {
try generator.processFile(worker, item);
}
+
+ generator.estimated_input_lines_of_code = worker.data.estimated_input_lines_of_code;
return;
}
@@ -475,6 +477,7 @@ pub fn NewBundler(cache_files: bool) type {
shared_buffer: MutableString = undefined,
scan_pass_result: js_parser.ScanPassResult = undefined,
log: *logger.Log,
+ estimated_input_lines_of_code: usize = 0,
pub fn deinit(this: *WorkerData, allocator: *std.mem.Allocator) void {
this.shared_buffer.deinit();
@@ -530,6 +533,7 @@ pub fn NewBundler(cache_files: bool) type {
this.data = this.generator.allocator.create(WorkerData) catch unreachable;
this.data.* = WorkerData{
.log = this.generator.allocator.create(logger.Log) catch unreachable,
+ .estimated_input_lines_of_code = 0,
};
this.data.log.* = logger.Log.init(this.generator.allocator);
this.data.shared_buffer = try MutableString.init(this.generator.allocator, 0);
@@ -539,6 +543,7 @@ pub fn NewBundler(cache_files: bool) type {
{
this.generator.log_lock.lock();
this.data.log.appendTo(this.generator.log) catch {};
+ this.generator.estimated_input_lines_of_code += this.data.estimated_input_lines_of_code;
this.generator.log_lock.unlock();
}
@@ -576,6 +581,7 @@ pub fn NewBundler(cache_files: bool) type {
tmpfile_byte_offset: u32 = 0,
code_end_byte_offset: u32 = 0,
has_jsx: bool = false,
+ estimated_input_lines_of_code: usize = 0,
work_waiter: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0),
list_lock: Lock = Lock.init(),
@@ -666,6 +672,7 @@ pub fn NewBundler(cache_files: bool) type {
framework_config: ?Api.LoadedFramework,
route_config: ?Api.LoadedRouteConfig,
destination: [*:0]const u8,
+ estimated_input_lines_of_code: *usize,
) !?Api.JavascriptBundleContainer {
var tmpdir: std.fs.Dir = try bundler.fs.fs.openTmpDir();
var tmpname_buf: [64]u8 = undefined;
@@ -694,6 +701,7 @@ pub fn NewBundler(cache_files: bool) type {
.header_string_buffer = try MutableString.init(allocator, "dist/index.js".len),
.allocator = allocator,
.queue = queue,
+ .estimated_input_lines_of_code = 0,
// .resolve_queue = queue,
.bundler = bundler,
.tmpfile = tmpfile,
@@ -834,6 +842,7 @@ pub fn NewBundler(cache_files: bool) type {
try this.pool.start(this);
try this.pool.wait(this);
+ estimated_input_lines_of_code.* = generator.estimated_input_lines_of_code;
// if (comptime !isRelease) {
// this.queue.checkDuplicatesSlow();
@@ -1023,7 +1032,6 @@ pub fn NewBundler(cache_files: bool) type {
0000010 | 0000100 | 0000001 | 0001000 | 0000040 | 0000004 | 0000002 | 0000400 | 0000200 | 0000020,
);
try std.os.renameatZ(tmpdir.fd, tmpname, top_dir.fd, destination);
-
// Print any errors at the end
// try this.log.print(Output.errorWriter());
return javascript_bundle_container;
@@ -1275,6 +1283,9 @@ pub fn NewBundler(cache_files: bool) type {
};
};
+ var approximate_newline_count: usize = 0;
+ defer worker.data.estimated_input_lines_of_code += approximate_newline_count;
+
// Handle empty files
// We can't just ignore them. Sometimes code will try to import it. Often because of TypeScript types.
// So we just say it's an empty object. Empty object mimicks what "browser": false does as well.
@@ -1313,6 +1324,7 @@ pub fn NewBundler(cache_files: bool) type {
log,
&source,
)) orelse return;
+ approximate_newline_count = ast.approximate_newline_count;
if (ast.import_records.len > 0) {
for (ast.import_records) |*import_record, record_id| {
@@ -1553,7 +1565,6 @@ pub fn NewBundler(cache_files: bool) type {
// It should only have one part.
ast.parts = ast.parts[ast.parts.len - 1 ..];
-
const write_result =
try js_printer.printCommonJSThreaded(
@TypeOf(writer),
@@ -1631,6 +1642,7 @@ pub fn NewBundler(cache_files: bool) type {
log,
&source,
);
+ worker.data.estimated_input_lines_of_code += scan_pass_result.approximate_newline_count;
{
for (scan_pass_result.import_records.items) |*import_record, i| {
diff --git a/src/cli/bun_command.zig b/src/cli/bun_command.zig
index 89a7d2360..66bd2ccee 100644
--- a/src/cli/bun_command.zig
+++ b/src/cli/bun_command.zig
@@ -26,6 +26,7 @@ const fs = @import("../fs.zig");
const Router = @import("../router.zig");
var wait_group: sync.WaitGroup = undefined;
+var estimated_input_lines_of_code_: usize = undefined;
const ServerBundleGeneratorThread = struct {
inline fn _generate(
logs: *logger.Log,
@@ -51,13 +52,14 @@ const ServerBundleGeneratorThread = struct {
Output.prettyErrorln("<r><red>{s}<r> loading --define or .env values for node_modules.server.bun\n", .{@errorName(err)});
return err;
};
-
+ var estimated_input_lines_of_code: usize = 0;
_ = try bundler.ServeBundler.GenerateNodeModuleBundle.generate(
&server_bundler,
allocator_,
server_conf,
route_conf_,
_filepath,
+ &estimated_input_lines_of_code,
);
std.mem.doNotOptimizeAway(&server_bundler);
}
@@ -95,6 +97,7 @@ pub const BunCommand = struct {
) !void {
var allocator = ctx.allocator;
var log = ctx.log;
+ estimated_input_lines_of_code_ = 0;
var this_bundler = try bundler.ServeBundler.init(allocator, log, ctx.args, null, null);
this_bundler.configureLinker();
@@ -164,6 +167,7 @@ pub const BunCommand = struct {
}
{
+
// Always generate the client-only bundle
// we can revisit this decision if people ask
var node_modules_ = try bundler.ServeBundler.GenerateNodeModuleBundle.generate(
@@ -172,8 +176,10 @@ pub const BunCommand = struct {
loaded_framework,
loaded_route_config,
filepath,
+ &estimated_input_lines_of_code_,
);
+ const estimated_input_lines_of_code = estimated_input_lines_of_code_;
if (server_bundler_generator_thread) |thread| {
wait_group.wait();
}
@@ -189,6 +195,27 @@ pub const BunCommand = struct {
bundle.printSummary();
}
const indent = comptime " ";
+
+ switch (estimated_input_lines_of_code) {
+ 0...99999 => {
+ if (generated_server) {
+ Output.prettyln(indent ++ "<d>{d:<5} LOC parsed x2", .{estimated_input_lines_of_code});
+ } else {
+ Output.prettyln(indent ++ "<d>{d:<5} LOC parsed", .{estimated_input_lines_of_code});
+ }
+ },
+ else => {
+ const formatted_loc: f32 = @floatCast(f32, @intToFloat(f128, estimated_input_lines_of_code) / 1000);
+ if (generated_server) {
+ Output.prettyln(indent ++ "<d>{d:<5.2}k LOC parsed x2", .{formatted_loc});
+ } else {
+ Output.prettyln(indent ++ "<d>{d:<5.2}k LOC parsed", .{
+ formatted_loc,
+ });
+ }
+ },
+ }
+
Output.prettyln(indent ++ "<d>{d:6}ms elapsed", .{@intCast(u32, elapsed)});
if (generated_server) {
@@ -197,6 +224,8 @@ pub const BunCommand = struct {
Output.prettyln(indent ++ "<r>Saved to ./{s}", .{filepath});
}
+ Output.flush();
+
try log.printForLogLevel(Output.errorWriter());
}
} else {
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index a32a077ac..043b11b37 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1730,6 +1730,7 @@ pub const ScanPassResult = struct {
named_imports: js_ast.Ast.NamedImports,
used_symbols: ParsePassSymbolUsageMap,
import_records_to_keep: List(u32),
+ approximate_newline_count: usize = 0,
pub fn init(allocator: *std.mem.Allocator) ScanPassResult {
return .{
@@ -1737,6 +1738,7 @@ pub const ScanPassResult = struct {
.named_imports = js_ast.Ast.NamedImports.init(allocator),
.used_symbols = ParsePassSymbolUsageMap.init(allocator),
.import_records_to_keep = List(u32).init(allocator),
+ .approximate_newline_count = 0,
};
}
@@ -1744,6 +1746,7 @@ pub const ScanPassResult = struct {
scan_pass.named_imports.clearRetainingCapacity();
scan_pass.import_records.shrinkRetainingCapacity(0);
scan_pass.used_symbols.clearRetainingCapacity();
+ scan_pass.approximate_newline_count = 0;
}
};
@@ -1871,6 +1874,8 @@ pub const Parser = struct {
p.options.jsx.classic_import_source,
);
}
+
+ scan_pass.approximate_newline_count = p.lexer.approximate_newline_count;
}
pub fn parse(self: *Parser) !js_ast.Result {
@@ -3919,7 +3924,6 @@ pub fn NewParser(
fn convertExprToBindingAndInitializer(p: *P, _expr: *ExprNodeIndex, invalid_log: *LocList, is_spread: bool) ExprBindingTuple {
var initializer: ?ExprNodeIndex = null;
var expr = _expr;
- var override: ?ExprNodeIndex = null;
// zig syntax is sometimes painful
switch (expr.*.data) {
.e_binary => |bin| {
@@ -4234,7 +4238,7 @@ pub fn NewParser(
try p.lexer.next();
}
if (args.items.len > 0) {
- func.args = args.toOwnedSlice();
+ func.args = args.items;
}
// Reserve the special name "arguments" in this scope. This ensures that it
@@ -4293,7 +4297,7 @@ pub fn NewParser(
try decorators.append(try p.parseExprWithFlags(.new, Expr.EFlags.ts_decorator));
}
- return decorators.toOwnedSlice();
+ return decorators.items;
}
pub const TypeScript = struct {
@@ -5708,10 +5712,10 @@ pub fn NewParser(
},
}
}
- try cases.append(js_ast.Case{ .value = value, .body = body.toOwnedSlice(), .loc = logger.Loc.Empty });
+ try cases.append(js_ast.Case{ .value = value, .body = body.items, .loc = logger.Loc.Empty });
}
try p.lexer.expect(.t_close_brace);
- return p.s(S.Switch{ .test_ = test_, .body_loc = body_loc, .cases = cases.toOwnedSlice() }, loc);
+ return p.s(S.Switch{ .test_ = test_, .body_loc = body_loc, .cases = cases.items }, loc);
},
.t_try => {
try p.lexer.next();
@@ -6361,7 +6365,7 @@ pub fn NewParser(
for (local.decls) |decl| {
try extractDeclsForBinding(decl.binding, &_decls);
}
- decls = _decls.toOwnedSlice();
+ decls = _decls.items;
},
else => {},
}
@@ -6548,7 +6552,7 @@ pub fn NewParser(
}
return p.s(
- S.Namespace{ .name = name, .arg = arg_ref orelse Ref.None, .stmts = stmts.toOwnedSlice(), .is_export = opts.is_export },
+ S.Namespace{ .name = name, .arg = arg_ref orelse Ref.None, .stmts = stmts.items, .is_export = opts.is_export },
loc,
);
}
@@ -6724,7 +6728,7 @@ pub fn NewParser(
}
try p.lexer.expect(.t_close_brace);
- return ImportClause{ .items = items.toOwnedSlice(), .is_single_line = is_single_line };
+ return ImportClause{ .items = items.items, .is_single_line = is_single_line };
}
fn forbidInitializers(p: *P, decls: []G.Decl, loop_type: string, is_var: bool) !void {
@@ -6880,7 +6884,7 @@ pub fn NewParser(
}
try p.lexer.expect(.t_close_bracket);
return p.b(B.Array{
- .items = items.toOwnedSlice(),
+ .items = items.items,
.has_spread = has_spread,
.is_single_line = is_single_line,
}, loc);
@@ -6926,7 +6930,7 @@ pub fn NewParser(
try p.lexer.expect(.t_close_brace);
return p.b(B.Object{
- .properties = properties.toOwnedSlice(),
+ .properties = properties.items,
.is_single_line = is_single_line,
}, loc);
},
@@ -13956,7 +13960,7 @@ pub fn NewParser(
// Eat the comma token
try p.lexer.next();
}
- var items = if (items_list.capacity > 0) items_list.toOwnedSlice() else &([_]Expr{});
+ var items = items_list.items;
// The parenthetical construct must end with a close parenthesis
try p.lexer.expect(.t_close_paren);
@@ -13993,10 +13997,11 @@ pub fn NewParser(
else => {},
}
- const tuple = p.convertExprToBindingAndInitializer(&items[i], &invalidLog, is_spread);
+ var item = items[i];
+ const tuple = p.convertExprToBindingAndInitializer(&item, &invalidLog, is_spread);
// double allocations
args.append(G.Arg{
- .binding = tuple.binding orelse Binding{ .data = Prefill.Data.BMissing, .loc = items[i].loc },
+ .binding = tuple.binding orelse Binding{ .data = Prefill.Data.BMissing, .loc = item.loc },
.default = tuple.expr,
}) catch unreachable;
}
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 31c1ac1fc..72a3febf7 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -1201,7 +1201,6 @@ pub fn NewResolver(cache_files: bool) type {
// paths. We also want to avoid any "%" characters in the absolute
// directory path accidentally being interpreted as URL escapes.
var esm_resolution = esmodule.resolve("/", esm.subpath, exports_map.root);
- defer Output.debug("ESM Resolution Status {s}: {s}\n", .{ abs_package_path, esm_resolution.status });
if ((esm_resolution.status == .Inexact or esm_resolution.status == .Exact) and strings.startsWith(esm_resolution.path, "/")) {
const abs_esm_path: string = brk: {