authorgravatar for ian@ianjohnson.devIan Johnson <ian@ianjohnson.dev> 2024-07-07 22:12:37-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-09 15:58:03-04:00
log2511830442fd96d04f578f2c4251b1994f08c994
treeac06639737e8e3edc8fcb30a95fe2a85efefc5bc
parent854e86c5676de82bc46b5c13a0c9c807596e438d

Autodoc: only group structs under "namespaces"

The old heuristic of checking only for the number of fields has the downside of classifying all opaque types, such as `std.c.FILE`, as "namespaces" rather than "types".

4 files changed, 53 insertions(+), 47 deletions(-)

lib/docs/main.js+14-16
...@@ -1,14 +1,15 @@...@@ -1,14 +1,15 @@
1(function() {1(function() {
2 const CAT_namespace = 0;2 const CAT_namespace = 0;
3 const CAT_global_variable = 1;3 const CAT_container = 1;
4 const CAT_function = 2;4 const CAT_global_variable = 2;
5 const CAT_primitive = 3;5 const CAT_function = 3;
6 const CAT_error_set = 4;6 const CAT_primitive = 4;
7 const CAT_global_const = 5;7 const CAT_error_set = 5;
8 const CAT_alias = 6;8 const CAT_global_const = 6;
9 const CAT_type = 7;9 const CAT_alias = 7;
10 const CAT_type_type = 8;10 const CAT_type = 8;
11 const CAT_type_function = 9;11 const CAT_type_type = 9;
12 const CAT_type_function = 10;
1213
13 const domDocTestsCode = document.getElementById("docTestsCode");14 const domDocTestsCode = document.getElementById("docTestsCode");
14 const domFnErrorsAnyError = document.getElementById("fnErrorsAnyError");15 const domFnErrorsAnyError = document.getElementById("fnErrorsAnyError");
...@@ -184,6 +185,7 @@...@@ -184,6 +185,7 @@
184 const category = wasm_exports.categorize_decl(decl_index, 0);185 const category = wasm_exports.categorize_decl(decl_index, 0);
185 switch (category) {186 switch (category) {
186 case CAT_namespace:187 case CAT_namespace:
188 case CAT_container:
187 return renderNamespacePage(decl_index);189 return renderNamespacePage(decl_index);
188 case CAT_global_variable:190 case CAT_global_variable:
189 case CAT_primitive:191 case CAT_primitive:
...@@ -426,16 +428,12 @@...@@ -426,16 +428,12 @@
426 while (true) {428 while (true) {
427 const member_category = wasm_exports.categorize_decl(member, 0);429 const member_category = wasm_exports.categorize_decl(member, 0);
428 switch (member_category) {430 switch (member_category) {
429 case CAT_namespace:
430 if (wasm_exports.decl_field_count(member) > 0) {
431 typesList.push({original: original, member: member});
432 } else {
433 namespacesList.push({original: original, member: member});
434 }
435 continue member_loop;
436 case CAT_namespace:431 case CAT_namespace:
437 namespacesList.push({original: original, member: member});432 namespacesList.push({original: original, member: member});
438 continue member_loop;433 continue member_loop;
434 case CAT_container:
435 typesList.push({original: original, member: member});
436 continue member_loop;
439 case CAT_global_variable:437 case CAT_global_variable:
440 varsList.push(member);438 varsList.push(member);
441 continue member_loop;439 continue member_loop;
lib/docs/wasm/Decl.zig+2-2
...@@ -115,7 +115,7 @@ pub fn categorize(decl: *const Decl) Walk.Category {...@@ -115,7 +115,7 @@ pub fn categorize(decl: *const Decl) Walk.Category {
115pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index {115pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index {
116 switch (decl.categorize()) {116 switch (decl.categorize()) {
117 .alias => |aliasee| return aliasee.get().get_child(name),117 .alias => |aliasee| return aliasee.get().get_child(name),
118 .namespace => |node| {118 .namespace, .container => |node| {
119 const file = decl.file.get();119 const file = decl.file.get();
120 const scope = file.scopes.get(node) orelse return null;120 const scope = file.scopes.get(node) orelse return null;
121 const child_node = scope.get_child(name) orelse return null;121 const child_node = scope.get_child(name) orelse return null;
...@@ -128,7 +128,7 @@ pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index {...@@ -128,7 +128,7 @@ pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index {
128/// Looks up a decl by name accessible in `decl`'s namespace.128/// Looks up a decl by name accessible in `decl`'s namespace.
129pub fn lookup(decl: *const Decl, name: []const u8) ?Decl.Index {129pub fn lookup(decl: *const Decl, name: []const u8) ?Decl.Index {
130 const namespace_node = switch (decl.categorize()) {130 const namespace_node = switch (decl.categorize()) {
131 .namespace => |node| node,131 .namespace, .container => |node| node,
132 else => decl.parent.get().ast_node,132 else => decl.parent.get().ast_node,
133 };133 };
134 const file = decl.file.get();134 const file = decl.file.get();
lib/docs/wasm/Walk.zig+36-21
...@@ -7,7 +7,10 @@ file: File.Index,...@@ -7,7 +7,10 @@ file: File.Index,
77
8/// keep in sync with "CAT_" constants in main.js8/// keep in sync with "CAT_" constants in main.js
9pub const Category = union(enum(u8)) {9pub const Category = union(enum(u8)) {
10 /// A struct type used only to group declarations.
10 namespace: Ast.Node.Index,11 namespace: Ast.Node.Index,
12 /// A container type (struct, union, enum, opaque).
13 container: Ast.Node.Index,
11 global_variable: Ast.Node.Index,14 global_variable: Ast.Node.Index,
12 /// A function that has not been detected as returning a type.15 /// A function that has not been detected as returning a type.
13 function: Ast.Node.Index,16 function: Ast.Node.Index,
...@@ -45,13 +48,6 @@ pub const File = struct {...@@ -45,13 +48,6 @@ pub const File = struct {
45 return file.node_decls.get(decl_node) orelse return .none;48 return file.node_decls.get(decl_node) orelse return .none;
46 }49 }
4750
48 pub fn field_count(file: *const File, node: Ast.Node.Index) u32 {
49 const scope = file.scopes.get(node) orelse return 0;
50 if (scope.tag != .namespace) return 0;
51 const namespace: *Scope.Namespace = @alignCast(@fieldParentPtr("base", scope));
52 return namespace.field_count;
53 }
54
55 pub const Index = enum(u32) {51 pub const Index = enum(u32) {
56 _,52 _,
5753
...@@ -87,7 +83,18 @@ pub const File = struct {...@@ -87,7 +83,18 @@ pub const File = struct {
87 const node_tags = ast.nodes.items(.tag);83 const node_tags = ast.nodes.items(.tag);
88 const token_tags = ast.tokens.items(.tag);84 const token_tags = ast.tokens.items(.tag);
89 switch (node_tags[node]) {85 switch (node_tags[node]) {
90 .root => return .{ .namespace = node },86 .root => {
87 for (ast.rootDecls()) |member| {
88 switch (node_tags[member]) {
89 .container_field_init,
90 .container_field_align,
91 .container_field,
92 => return .{ .container = node },
93 else => {},
94 }
95 }
96 return .{ .namespace = node };
97 },
9198
92 .global_var_decl,99 .global_var_decl,
93 .local_var_decl,100 .local_var_decl,
...@@ -122,7 +129,7 @@ pub const File = struct {...@@ -122,7 +129,7 @@ pub const File = struct {
122 full: Ast.full.FnProto,129 full: Ast.full.FnProto,
123 ) Category {130 ) Category {
124 return switch (categorize_expr(file_index, full.ast.return_type)) {131 return switch (categorize_expr(file_index, full.ast.return_type)) {
125 .namespace, .error_set, .type_type => .{ .type_function = node },132 .namespace, .container, .error_set, .type_type => .{ .type_function = node },
126 else => .{ .function = node },133 else => .{ .function = node },
127 };134 };
128 }135 }
...@@ -140,6 +147,7 @@ pub const File = struct {...@@ -140,6 +147,7 @@ pub const File = struct {
140 const node_tags = ast.nodes.items(.tag);147 const node_tags = ast.nodes.items(.tag);
141 const node_datas = ast.nodes.items(.data);148 const node_datas = ast.nodes.items(.data);
142 const main_tokens = ast.nodes.items(.main_token);149 const main_tokens = ast.nodes.items(.main_token);
150 const token_tags = ast.tokens.items(.tag);
143 //log.debug("categorize_expr tag {s}", .{@tagName(node_tags[node])});151 //log.debug("categorize_expr tag {s}", .{@tagName(node_tags[node])});
144 return switch (node_tags[node]) {152 return switch (node_tags[node]) {
145 .container_decl,153 .container_decl,
...@@ -154,7 +162,23 @@ pub const File = struct {...@@ -154,7 +162,23 @@ pub const File = struct {
154 .tagged_union_enum_tag_trailing,162 .tagged_union_enum_tag_trailing,
155 .tagged_union_two,163 .tagged_union_two,
156 .tagged_union_two_trailing,164 .tagged_union_two_trailing,
157 => .{ .namespace = node },165 => {
166 var buf: [2]Ast.Node.Index = undefined;
167 const container_decl = ast.fullContainerDecl(&buf, node).?;
168 if (token_tags[container_decl.ast.main_token] != .keyword_struct) {
169 return .{ .container = node };
170 }
171 for (container_decl.ast.members) |member| {
172 switch (node_tags[member]) {
173 .container_field_init,
174 .container_field_align,
175 .container_field,
176 => return .{ .container = node },
177 else => {},
178 }
179 }
180 return .{ .namespace = node };
181 },
158182
159 .error_set_decl,183 .error_set_decl,
160 .merge_error_sets,184 .merge_error_sets,
...@@ -240,6 +264,7 @@ pub const File = struct {...@@ -240,6 +264,7 @@ pub const File = struct {
240 return .{ .error_set = node };264 return .{ .error_set = node };
241 } else if (then_cat == .type or else_cat == .type or265 } else if (then_cat == .type or else_cat == .type or
242 then_cat == .namespace or else_cat == .namespace or266 then_cat == .namespace or else_cat == .namespace or
267 then_cat == .container or else_cat == .container or
243 then_cat == .error_set or else_cat == .error_set or268 then_cat == .error_set or else_cat == .error_set or
244 then_cat == .type_function or else_cat == .type_function)269 then_cat == .type_function or else_cat == .type_function)
245 {270 {
...@@ -346,7 +371,7 @@ pub const File = struct {...@@ -346,7 +371,7 @@ pub const File = struct {
346 any_type = true;371 any_type = true;
347 all_type_type = false;372 all_type_type = false;
348 },373 },
349 .type, .namespace, .type_function => {374 .type, .namespace, .container, .type_function => {
350 any_type = true;375 any_type = true;
351 all_error_set = false;376 all_error_set = false;
352 all_type_type = false;377 all_type_type = false;
...@@ -431,7 +456,6 @@ pub const Scope = struct {...@@ -431,7 +456,6 @@ pub const Scope = struct {
431 names: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{},456 names: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{},
432 doctests: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{},457 doctests: std.StringArrayHashMapUnmanaged(Ast.Node.Index) = .{},
433 decl_index: Decl.Index,458 decl_index: Decl.Index,
434 field_count: u32,
435 };459 };
436460
437 fn getNamespaceDecl(start_scope: *Scope) Decl.Index {461 fn getNamespaceDecl(start_scope: *Scope) Decl.Index {
...@@ -500,7 +524,6 @@ fn struct_decl(...@@ -500,7 +524,6 @@ fn struct_decl(
500 namespace.* = .{524 namespace.* = .{
501 .parent = scope,525 .parent = scope,
502 .decl_index = parent_decl,526 .decl_index = parent_decl,
503 .field_count = 0,
504 };527 };
505 try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base);528 try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base);
506 try w.scanDecls(namespace, container_decl.ast.members);529 try w.scanDecls(namespace, container_decl.ast.members);
...@@ -1061,14 +1084,6 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In...@@ -1061,14 +1084,6 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In
1061 continue;1084 continue;
1062 },1085 },
10631086
1064 .container_field_init,
1065 .container_field_align,
1066 .container_field,
1067 => {
1068 namespace.field_count += 1;
1069 continue;
1070 },
1071
1072 else => continue,1087 else => continue,
1073 };1088 };
10741089
lib/docs/wasm/main.zig+1-8
...@@ -274,13 +274,6 @@ export fn fn_error_set_decl(decl_index: Decl.Index, node: Ast.Node.Index) Decl.I...@@ -274,13 +274,6 @@ export fn fn_error_set_decl(decl_index: Decl.Index, node: Ast.Node.Index) Decl.I
274 };274 };
275}275}
276276
277export fn decl_field_count(decl_index: Decl.Index) u32 {
278 switch (decl_index.get().categorize()) {
279 .namespace => |node| return decl_index.get().file.get().field_count(node),
280 else => return 0,
281 }
282}
283
284fn decl_error_set_fallible(decl_index: Decl.Index) Oom![]ErrorIdentifier {277fn decl_error_set_fallible(decl_index: Decl.Index) Oom![]ErrorIdentifier {
285 error_set_result.clearRetainingCapacity();278 error_set_result.clearRetainingCapacity();
286 try addErrorsFromDecl(decl_index, &error_set_result);279 try addErrorsFromDecl(decl_index, &error_set_result);
...@@ -583,7 +576,7 @@ export fn decl_category_name(decl_index: Decl.Index) String {...@@ -583,7 +576,7 @@ export fn decl_category_name(decl_index: Decl.Index) String {
583 const ast = decl.file.get_ast();576 const ast = decl.file.get_ast();
584 const token_tags = ast.tokens.items(.tag);577 const token_tags = ast.tokens.items(.tag);
585 const name = switch (decl.categorize()) {578 const name = switch (decl.categorize()) {
586 .namespace => |node| {579 .namespace, .container => |node| {
587 const node_tags = ast.nodes.items(.tag);580 const node_tags = ast.nodes.items(.tag);
588 if (node_tags[decl.ast_node] == .root)581 if (node_tags[decl.ast_node] == .root)
589 return String.init("struct");582 return String.init("struct");