| ... | ... | @@ -23,6 +23,7 @@ const usage_fmt = |
| 23 | 23 | \\ --ast-check Run zig ast-check on every file |
| 24 | 24 | \\ --exclude [file] Exclude file or directory from formatting |
| 25 | 25 | \\ --zon Treat all input files as ZON, regardless of file extension |
| 26 | \\ --complexity Print a complexity report for each file as well as total |
| 26 | 27 | \\ |
| 27 | 28 | \\ |
| 28 | 29 | ; |
| ... | ... | @@ -39,6 +40,10 @@ const Fmt = struct { |
| 39 | 40 | out_buffer: std.Io.Writer.Allocating, |
| 40 | 41 | stdout_writer: *Io.File.Writer, |
| 41 | 42 | |
| 43 | complexity: bool, |
| 44 | total_tokens: u64, |
| 45 | total_nodes: u64, |
| 46 | |
| 42 | 47 | const SeenMap = std.AutoHashMap(Io.File.INode, void); |
| 43 | 48 | }; |
| 44 | 49 | |
| ... | ... | @@ -48,8 +53,11 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 48 | 53 | var check_flag = false; |
| 49 | 54 | var check_ast_flag = false; |
| 50 | 55 | var force_zon = false; |
| 56 | var complexity = false; |
| 57 | |
| 51 | 58 | var input_files = std.array_list.Managed([]const u8).init(gpa); |
| 52 | 59 | defer input_files.deinit(); |
| 60 | |
| 53 | 61 | var excluded_files = std.array_list.Managed([]const u8).init(gpa); |
| 54 | 62 | defer excluded_files.deinit(); |
| 55 | 63 | |
| ... | ... | @@ -68,7 +76,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 68 | 76 | i += 1; |
| 69 | 77 | const next_arg = args[i]; |
| 70 | 78 | color = std.meta.stringToEnum(Color, next_arg) orelse { |
| 71 | | fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg}); |
| 79 | fatal("expected [auto|on|off] after --color, found {q}", .{next_arg}); |
| 72 | 80 | }; |
| 73 | 81 | } else if (mem.eql(u8, arg, "--stdin")) { |
| 74 | 82 | stdin_flag = true; |
| ... | ... | @@ -76,6 +84,8 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 76 | 84 | check_flag = true; |
| 77 | 85 | } else if (mem.eql(u8, arg, "--ast-check")) { |
| 78 | 86 | check_ast_flag = true; |
| 87 | } else if (mem.eql(u8, arg, "--complexity")) { |
| 88 | complexity = true; |
| 79 | 89 | } else if (mem.eql(u8, arg, "--exclude")) { |
| 80 | 90 | if (i + 1 >= args.len) { |
| 81 | 91 | fatal("expected parameter after --exclude", .{}); |
| ... | ... | @@ -86,7 +96,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 86 | 96 | } else if (mem.eql(u8, arg, "--zon")) { |
| 87 | 97 | force_zon = true; |
| 88 | 98 | } else { |
| 89 | | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 99 | fatal("unrecognized parameter: {q}", .{arg}); |
| 90 | 100 | } |
| 91 | 101 | } else { |
| 92 | 102 | try input_files.append(arg); |
| ... | ... | @@ -175,6 +185,9 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 175 | 185 | .color = color, |
| 176 | 186 | .out_buffer = .init(gpa), |
| 177 | 187 | .stdout_writer = &stdout_writer, |
| 188 | .complexity = complexity, |
| 189 | .total_tokens = 0, |
| 190 | .total_nodes = 0, |
| 178 | 191 | }; |
| 179 | 192 | defer fmt.seen.deinit(); |
| 180 | 193 | defer fmt.out_buffer.deinit(); |
| ... | ... | @@ -198,7 +211,12 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 198 | 211 | for (input_files.items) |file_path| { |
| 199 | 212 | try fmtPath(&fmt, file_path, check_flag, Io.Dir.cwd(), file_path); |
| 200 | 213 | } |
| 201 | | try fmt.stdout_writer.interface.flush(); |
| 214 | |
| 215 | if (complexity) { |
| 216 | std.log.info("total: tokens={d} nodes={d}", .{ fmt.total_tokens, fmt.total_nodes }); |
| 217 | } |
| 218 | |
| 219 | try fmt.stdout_writer.flush(); |
| 202 | 220 | if (fmt.any_error) { |
| 203 | 221 | process.exit(1); |
| 204 | 222 | } |
| ... | ... | @@ -208,7 +226,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: Io.Dir, sub_ |
| 208 | 226 | fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) { |
| 209 | 227 | error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path), |
| 210 | 228 | else => { |
| 211 | | std.log.err("unable to format '{s}': {s}", .{ file_path, @errorName(err) }); |
| 229 | std.log.err("formatting {q}: {t}", .{ file_path, err }); |
| 212 | 230 | fmt.any_error = true; |
| 213 | 231 | return; |
| 214 | 232 | }, |
| ... | ... | @@ -244,7 +262,7 @@ fn fmtPathDir( |
| 244 | 262 | try fmtPathDir(fmt, full_path, check_mode, dir, entry.name); |
| 245 | 263 | } else { |
| 246 | 264 | fmtPathFile(fmt, full_path, check_mode, dir, entry.name) catch |err| { |
| 247 | | std.log.err("unable to format '{s}': {t}", .{ full_path, err }); |
| 265 | std.log.err("unable to format {q}: {t}", .{ full_path, err }); |
| 248 | 266 | fmt.any_error = true; |
| 249 | 267 | return; |
| 250 | 268 | }; |
| ... | ... | @@ -341,6 +359,12 @@ fn fmtPathFile( |
| 341 | 359 | } |
| 342 | 360 | } |
| 343 | 361 | |
| 362 | if (fmt.complexity) { |
| 363 | std.log.info("{s}: tokens={d} nodes={d}", .{ file_path, tree.tokens.len, tree.nodes.len }); |
| 364 | fmt.total_tokens += tree.tokens.len; |
| 365 | fmt.total_nodes += tree.nodes.len; |
| 366 | } |
| 367 | |
| 344 | 368 | // As a heuristic, we make enough capacity for the same as the input source. |
| 345 | 369 | fmt.out_buffer.clearRetainingCapacity(); |
| 346 | 370 | try fmt.out_buffer.ensureTotalCapacity(source_code.len); |
| ... | ... | @@ -365,13 +389,7 @@ fn fmtPathFile( |
| 365 | 389 | } |
| 366 | 390 | |
| 367 | 391 | /// Provided for debugging/testing purposes; unused by the compiler. |
| 368 | | pub fn main() !void { |
| 369 | | const gpa = std.heap.smp_allocator; |
| 370 | | var arena_instance = std.heap.ArenaAllocator.init(gpa); |
| 371 | | const arena = arena_instance.allocator(); |
| 372 | | const args = try process.argsAlloc(arena); |
| 373 | | var threaded: std.Io.Threaded = .init(gpa, .{}); |
| 374 | | defer threaded.deinit(); |
| 375 | | const io = threaded.io(); |
| 376 | | return run(gpa, arena, io, args[1..]); |
| 392 | pub fn main(init: process.Init) !void { |
| 393 | const args = try init.minimal.args.toSlice(init.arena.allocator()); |
| 394 | return run(init.gpa, init.arena.allocator(), init.io, args[1..]); |
| 377 | 395 | } |