| ... | ... | @@ -239,11 +239,47 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) ! |
| 239 | 239 | |
| 240 | 240 | if (fmt.stats) |stats| { |
| 241 | 241 | if (stats.files > 1) { |
| 242 | | try stats.root_struct.field("files", stats.files, .{}); |
| 243 | | try stats.root_struct.field("tokens", stats.tokens, .{}); |
| 244 | | try stats.root_struct.field("nodes", stats.nodes, .{}); |
| 242 | var agg_struct = try stats.root_struct.beginStructField("aggregate", .{}); |
| 243 | try agg_struct.field("file_count", stats.files, .{}); |
| 244 | try agg_struct.field("token_count", stats.tokens, .{}); |
| 245 | try agg_struct.field("node_count", stats.nodes, .{}); |
| 246 | |
| 247 | const token_names = @typeInfo(std.zig.Token.Tag).@"enum".field_names; |
| 248 | const node_names = @typeInfo(std.zig.Ast.Node.Tag).@"enum".field_names; |
| 249 | |
| 250 | var token_order: [token_names.len]usize = undefined; |
| 251 | var node_order: [node_names.len]usize = undefined; |
| 252 | { |
| 253 | for (&token_order, 0..) |*elem, i| elem.* = i; |
| 254 | std.mem.sortContext(0, token_names.len, @as(SortContext, .{ |
| 255 | .stats = stats.token_stats, |
| 256 | .order = &token_order, |
| 257 | })); |
| 258 | var tokens_struct = try agg_struct.beginStructField("tokens", .{}); |
| 259 | for (&token_order) |i| { |
| 260 | const n = stats.token_stats[i]; |
| 261 | if (n != 0) try tokens_struct.field(token_names[i], n, .{}); |
| 262 | } |
| 263 | try tokens_struct.end(); |
| 264 | } |
| 265 | { |
| 266 | for (&node_order, 0..) |*elem, i| elem.* = i; |
| 267 | std.mem.sortContext(0, node_names.len, @as(SortContext, .{ |
| 268 | .stats = stats.node_stats, |
| 269 | .order = &node_order, |
| 270 | })); |
| 271 | var nodes_struct = try agg_struct.beginStructField("nodes", .{}); |
| 272 | for (&node_order) |i| { |
| 273 | const n = stats.node_stats[i]; |
| 274 | if (n != 0) try nodes_struct.field(node_names[i], n, .{}); |
| 275 | } |
| 276 | try nodes_struct.end(); |
| 277 | } |
| 278 | |
| 279 | try agg_struct.end(); |
| 245 | 280 | } |
| 246 | 281 | try stats.root_struct.end(); |
| 282 | try fmt.stdout_writer.interface.writeByte('\n'); |
| 247 | 283 | } |
| 248 | 284 | |
| 249 | 285 | try fmt.stdout_writer.flush(); |
| ... | ... | @@ -413,19 +449,6 @@ fn fmtPathFile( |
| 413 | 449 | node_stats[@backingInt(tag)] += 1; |
| 414 | 450 | } |
| 415 | 451 | |
| 416 | | const SortContext = struct { |
| 417 | | stats: []const u64, |
| 418 | | order: []usize, |
| 419 | | |
| 420 | | pub fn lessThan(this: @This(), a_index: usize, b_index: usize) bool { |
| 421 | | return this.stats[this.order[b_index]] < this.stats[this.order[a_index]]; |
| 422 | | } |
| 423 | | |
| 424 | | pub fn swap(this: @This(), a_index: usize, b_index: usize) void { |
| 425 | | std.mem.swap(usize, &this.order[a_index], &this.order[b_index]); |
| 426 | | } |
| 427 | | }; |
| 428 | | |
| 429 | 452 | { |
| 430 | 453 | for (&token_order, 0..) |*elem, i| elem.* = i; |
| 431 | 454 | std.mem.sortContext(0, token_names.len, @as(SortContext, .{ |
| ... | ... | @@ -435,7 +458,7 @@ fn fmtPathFile( |
| 435 | 458 | var s = try zon_struct.beginStructField("tokens", .{}); |
| 436 | 459 | for (&token_order) |i| { |
| 437 | 460 | const n = token_stats[i]; |
| 438 | | if (n != 0) try zon_struct.field(token_names[i], n, .{}); |
| 461 | if (n != 0) try s.field(token_names[i], n, .{}); |
| 439 | 462 | } |
| 440 | 463 | try s.end(); |
| 441 | 464 | } |
| ... | ... | @@ -449,13 +472,14 @@ fn fmtPathFile( |
| 449 | 472 | var s = try zon_struct.beginStructField("nodes", .{}); |
| 450 | 473 | for (&node_order) |i| { |
| 451 | 474 | const n = node_stats[i]; |
| 452 | | if (n != 0) try zon_struct.field(node_names[i], n, .{}); |
| 475 | if (n != 0) try s.field(node_names[i], n, .{}); |
| 453 | 476 | } |
| 454 | 477 | try s.end(); |
| 455 | 478 | } |
| 456 | 479 | |
| 457 | 480 | stats.tokens += tree.tokens.len; |
| 458 | 481 | stats.nodes += tree.nodes.len; |
| 482 | stats.files += 1; |
| 459 | 483 | } |
| 460 | 484 | |
| 461 | 485 | // As a heuristic, we make enough capacity for the same as the input source. |
| ... | ... | @@ -485,6 +509,19 @@ fn fmtPathFile( |
| 485 | 509 | if (fmt.stats != null) try zon_struct.end(); |
| 486 | 510 | } |
| 487 | 511 | |
| 512 | const SortContext = struct { |
| 513 | stats: []const u64, |
| 514 | order: []usize, |
| 515 | |
| 516 | pub fn lessThan(this: @This(), a_index: usize, b_index: usize) bool { |
| 517 | return this.stats[this.order[b_index]] < this.stats[this.order[a_index]]; |
| 518 | } |
| 519 | |
| 520 | pub fn swap(this: @This(), a_index: usize, b_index: usize) void { |
| 521 | std.mem.swap(usize, &this.order[a_index], &this.order[b_index]); |
| 522 | } |
| 523 | }; |
| 524 | |
| 488 | 525 | /// Provided for debugging/testing purposes; unused by the compiler. |
| 489 | 526 | pub fn main(init: process.Init) !void { |
| 490 | 527 | const args = try init.minimal.args.toSlice(init.arena.allocator()); |