╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ fmt.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
236 } 237 238 fn fmtPathDir( 239 fmt: *Fmt, 240 file_path: []const u8, 241 check_mode: bool, 242 parent_dir: Io.Dir, 243 parent_sub_path: []const u8, 244 ) !void { 245 const io = fmt.io; 246 247 var dir = try parent_dir.openDir(io, parent_sub_path, .{ .iterate = true }); 248 defer dir.close(io); 249 250 const stat = try dir.stat(io); 251 if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; 252 253 var dir_it = dir.iterate(); 254 while (try dir_it.next(io)) |entry| { 255 const is_dir = entry.kind == .directory; 256 257 if (mem.startsWith(u8, entry.name, ".")) continue; 258 259 if (is_dir or entry.kind == .file and (mem.endsWith(u8, entry.name, ".zig") or mem.endsWith(u8, entry.name, ".zon"))) { 260 const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); 261 defer fmt.gpa.free(full_path); 262 263 if (is_dir) { 264 try fmtPathDir(fmt, full_path, check_mode, dir, entry.name); 265 } else { 266 fmtPathFile(fmt, full_path, check_mode, dir, entry.name) catch |err| { 267 std.log.err("unable to format {q}: {t}", .{ full_path, err }); 268 fmt.any_error = true; 269 return; 270 }; 271 } 272 } 273 } 274 } 275 276 fn fmtPathFile( 277 fmt: *Fmt, 278 file_path: []const u8, 279 check_mode: bool, 280 dir: Io.Dir, 281 sub_path: []const u8, 282 ) !void { 283 const io = fmt.io; 284 285 const source_file = try dir.openFile(io, sub_path, .{}); 286 var file_closed = false; 287 errdefer if (!file_closed) source_file.close(io); 288 289 const stat = try source_file.stat(io); 290 291 if (stat.kind == .directory) 292 return error.IsDir; 293 294 var read_buffer: [1024]u8 = undefined; 295 var file_reader: Io.File.Reader = source_file.reader(io, &read_buffer); 296 file_reader.size = stat.size; 297 298 const gpa = fmt.gpa; 299 const source_code = std.zig.readSourceFileToEndAlloc(gpa, &file_reader) catch |err| switch (err) { 300 error.ReadFailed => return file_reader.err.?, 301 else => |e| return e, 302 }; 303 defer gpa.free(source_code); 304 305 source_file.close(io); 306 file_closed = true; 307 308 // Add to set after no longer possible to get error.IsDir. 309 if (try fmt.seen.fetchPut(stat.inode, {})) |_| return; 310 311 const mode: std.zig.Ast.Mode = mode: { 312 if (fmt.force_zon) break :mode .zon; 313 if (mem.endsWith(u8, sub_path, ".zon")) break :mode .zon; 314 break :mode .zig; 315 }; 316 317 var tree = try std.zig.Ast.parse(gpa, source_code, .{ .mode = mode }); 318 defer tree.deinit(gpa); 319 320 if (tree.errors.len != 0) { 321 try std.zig.printAstErrorsToStderr(gpa, io, tree, file_path, fmt.color); 322 fmt.any_error = true; 323 return; 324 } 325 326 if (fmt.check_ast) { 327 if (stat.size > std.zig.max_src_size) 328 return error.FileTooBig; 329 330 switch (mode) { 331 .zig => { 332 var zir = try std.zig.AstGen.generate(gpa, tree); 333 defer zir.deinit(gpa); 334 335 if (zir.hasCompileErrors()) { 336 var wip_errors: std.zig.ErrorBundle.Wip = undefined; 337 try wip_errors.init(gpa); 338 defer wip_errors.deinit(); 339 try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path); 340 var error_bundle = try wip_errors.toOwnedBundle(""); 341 defer error_bundle.deinit(gpa); 342 try error_bundle.renderToStderr(io, .{}, fmt.color); 343 fmt.any_error = true; 344 } 345 }, 346 .zon => { 347 var zoir = try std.zig.ZonGen.generate(gpa, tree, .{}); 348 defer zoir.deinit(gpa); 349 350 if (zoir.hasCompileErrors()) { 351 var wip_errors: std.zig.ErrorBundle.Wip = undefined; 352 try wip_errors.init(gpa); 353 defer wip_errors.deinit(); 354 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path); 355 var error_bundle = try wip_errors.toOwnedBundle(""); 356 defer error_bundle.deinit(gpa); 357 try error_bundle.renderToStderr(io, .{}, fmt.color); 358 fmt.any_error = true; 359 } 360 }, 361 } 362 } 363 364 if (fmt.complexity) { 365 std.log.info("{s}: tokens={d} nodes={d}", .{ file_path, tree.tokens.len, tree.nodes.len }); 366 fmt.total_tokens += tree.tokens.len; 367 fmt.total_nodes += tree.nodes.len; 368 } 369 370 // As a heuristic, we make enough capacity for the same as the input source. 371 fmt.out_buffer.clearRetainingCapacity(); 372 try fmt.out_buffer.ensureTotalCapacity(source_code.len); 373 374 tree.render(gpa, &fmt.out_buffer.writer, .{}) catch |err| switch (err) { 375 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, 376 }; 377 if (mem.eql(u8, fmt.out_buffer.written(), source_code)) 378 return; 379 380 if (check_mode) { 381 try fmt.stdout_writer.interface.print("{s}\n", .{file_path}); 382 fmt.any_error = true; 383 } else { 384 var af = try dir.createFileAtomic(io, sub_path, .{ .permissions = stat.permissions, .replace = true }); 385 defer af.deinit(io); 386 387 try af.file.writeStreamingAll(io, fmt.out_buffer.written()); 388 try af.replace(io); 389 try fmt.stdout_writer.interface.print("{s}\n", .{file_path}); 390 } 391 } 392 393 /// Provided for debugging/testing purposes; unused by the compiler. 394 pub fn main(init: process.Init) !void { 395 const args = try init.minimal.args.toSlice(init.arena.allocator()); 396 return run(init.gpa, init.arena.allocator(), init.io, args[1..]); 397 } 398