autodoc: Add tag handling to enums and unions. Add support for Struct, Enum, Union types in exprName.
Anonymous types now work via a hack to ast_nodes.
This commit is contained in:
157
lib/docs/main.js
157
lib/docs/main.js
@@ -1770,11 +1770,160 @@ const NAV_MODES = {
|
||||
throw "TODO";
|
||||
case typeKinds.Struct: {
|
||||
let structObj = typeObj;
|
||||
return structObj;
|
||||
let name = "";
|
||||
if (opts.wantHtml) {
|
||||
name = "<span class='tok-kw'>struct</span> { ";
|
||||
} else {
|
||||
name = "struct { ";
|
||||
}
|
||||
if (structObj.fields.length > 1 && opts.wantHtml) {name += "</br>";}
|
||||
let indent = "";
|
||||
if (structObj.fields.length > 1 && opts.wantHtml) {
|
||||
indent = " "
|
||||
}
|
||||
if (opts.indent) {
|
||||
indent = opts.indent + indent;
|
||||
}
|
||||
let structNode = getAstNode(structObj.src);
|
||||
let field_end = ",";
|
||||
if (structObj.fields.length > 1 && opts.wantHtml) {
|
||||
field_end += "</br>";
|
||||
} else {
|
||||
field_end += " ";
|
||||
}
|
||||
|
||||
for(let i = 0; i < structObj.fields.length; i += 1) {
|
||||
let fieldNode = getAstNode(structNode.fields[i]);
|
||||
let fieldName = fieldNode.name;
|
||||
let html = indent + escapeHtml(fieldName);
|
||||
|
||||
let fieldTypeExpr = structObj.fields[i];
|
||||
html += ": ";
|
||||
|
||||
html += exprName(fieldTypeExpr, {...opts, indent: indent});
|
||||
|
||||
html += field_end;
|
||||
|
||||
name += html;
|
||||
}
|
||||
if (opts.indent) {
|
||||
name += opts.indent;
|
||||
}
|
||||
name += "}";
|
||||
return name;
|
||||
}
|
||||
case typeKinds.Enum: {
|
||||
let enumObj = typeObj;
|
||||
return enumObj;
|
||||
let name = "";
|
||||
if (opts.wantHtml) {
|
||||
name = "<span class='tok-kw'>enum</span>";
|
||||
} else {
|
||||
name = "enum";
|
||||
}
|
||||
if (enumObj.tag) {
|
||||
name += " (" + exprName(enumObj.tag, opts) + ")";
|
||||
}
|
||||
name += " { ";
|
||||
let enumNode = getAstNode(enumObj.src);
|
||||
let fields_len = enumNode.fields.length;
|
||||
if (enumObj.nonexhaustive) {
|
||||
fields_len += 1;
|
||||
}
|
||||
if (fields_len > 1 && opts.wantHtml) {name += "</br>";}
|
||||
let indent = "";
|
||||
if (fields_len > 1) {
|
||||
if (opts.wantHtml) {
|
||||
indent = " ";
|
||||
} else {
|
||||
indent = " ";
|
||||
}
|
||||
}
|
||||
if (opts.indent) {
|
||||
indent = opts.indent + indent;
|
||||
}
|
||||
let field_end = ",";
|
||||
if (fields_len > 1 && opts.wantHtml) {
|
||||
field_end += "</br>";
|
||||
} else {
|
||||
field_end += " ";
|
||||
}
|
||||
for(let i = 0; i < enumNode.fields.length; i += 1) {
|
||||
let fieldNode = getAstNode(enumNode.fields[i]);
|
||||
let fieldName = fieldNode.name;
|
||||
let html = indent + escapeHtml(fieldName);
|
||||
|
||||
html += field_end;
|
||||
|
||||
name += html;
|
||||
}
|
||||
if (enumObj.nonexhaustive) {
|
||||
name += indent + "_" + field_end;
|
||||
}
|
||||
if (opts.indent) {
|
||||
name += opts.indent;
|
||||
}
|
||||
name += "}";
|
||||
return name;
|
||||
}
|
||||
case typeKinds.Union: {
|
||||
let unionObj = typeObj;
|
||||
let name = "";
|
||||
if (opts.wantHtml) {
|
||||
name = "<span class='tok-kw'>union</span>";
|
||||
} else {
|
||||
name = "union";
|
||||
}
|
||||
if (unionObj.auto_tag) {
|
||||
if (opts.wantHtml) {
|
||||
name += " (<span class='tok-kw'>enum</span>";
|
||||
} else {
|
||||
name += " (enum";
|
||||
}
|
||||
if (unionObj.tag) {
|
||||
name += "(" + exprName(unionObj.tag, opts) + "))";
|
||||
} else {
|
||||
name += ")";
|
||||
}
|
||||
} else if (unionObj.tag) {
|
||||
name += " (" + exprName(unionObj.tag, opts) + ")";
|
||||
}
|
||||
name += " { ";
|
||||
if (unionObj.fields.length > 1 && opts.wantHtml) {
|
||||
name += "</br>";
|
||||
}
|
||||
let indent = "";
|
||||
if (unionObj.fields.length > 1 && opts.wantHtml) {
|
||||
indent = " "
|
||||
}
|
||||
if (opts.indent) {
|
||||
indent = opts.indent + indent;
|
||||
}
|
||||
let unionNode = getAstNode(unionObj.src);
|
||||
let field_end = ",";
|
||||
if (unionObj.fields.length > 1 && opts.wantHtml) {
|
||||
field_end += "</br>";
|
||||
} else {
|
||||
field_end += " ";
|
||||
}
|
||||
for(let i = 0; i < unionObj.fields.length; i += 1) {
|
||||
let fieldNode = getAstNode(unionNode.fields[i]);
|
||||
let fieldName = fieldNode.name;
|
||||
let html = indent + escapeHtml(fieldName);
|
||||
|
||||
let fieldTypeExpr = unionObj.fields[i];
|
||||
html += ": ";
|
||||
|
||||
html += exprName(fieldTypeExpr, {...opts, indent: indent});
|
||||
|
||||
html += field_end;
|
||||
|
||||
name += html;
|
||||
}
|
||||
if (opts.indent) {
|
||||
name += opts.indent;
|
||||
}
|
||||
name += "}";
|
||||
return name;
|
||||
}
|
||||
case typeKinds.Opaque: {
|
||||
let opaqueObj = typeObj;
|
||||
@@ -3835,6 +3984,8 @@ const NAV_MODES = {
|
||||
src: ty[2],
|
||||
privDecls: ty[3],
|
||||
pubDecls: ty[4],
|
||||
tag: ty[5],
|
||||
nonexhaustive: ty[6],
|
||||
};
|
||||
case 20: // Union
|
||||
return {
|
||||
@@ -3844,6 +3995,8 @@ const NAV_MODES = {
|
||||
privDecls: ty[3],
|
||||
pubDecls: ty[4],
|
||||
fields: ty[5],
|
||||
tag: ty[6],
|
||||
auto_tag: ty[7],
|
||||
};
|
||||
case 21: // Fn
|
||||
return {
|
||||
|
||||
@@ -586,6 +586,8 @@ const DocData = struct {
|
||||
privDecls: []usize = &.{}, // index into decls
|
||||
pubDecls: []usize = &.{}, // index into decls
|
||||
// (use src->fields to find field names)
|
||||
tag: ?Expr = null, // tag type if specified
|
||||
nonexhaustive: bool,
|
||||
},
|
||||
Union: struct {
|
||||
name: []const u8,
|
||||
@@ -593,6 +595,8 @@ const DocData = struct {
|
||||
privDecls: []usize = &.{}, // index into decls
|
||||
pubDecls: []usize = &.{}, // index into decls
|
||||
fields: []Expr = &.{}, // (use src->fields to find names)
|
||||
tag: ?Expr, // tag type if specified
|
||||
auto_enum: bool, // tag is an auto enum
|
||||
},
|
||||
Fn: struct {
|
||||
name: []const u8,
|
||||
@@ -2559,12 +2563,13 @@ fn walkInstruction(
|
||||
else
|
||||
parent_src;
|
||||
|
||||
const tag_type: ?Ref = if (small.has_tag_type) blk: {
|
||||
const tag_type: ?DocData.Expr = if (small.has_tag_type) blk: {
|
||||
const tag_type = file.zir.extra[extra_index];
|
||||
extra_index += 1;
|
||||
break :blk @intToEnum(Ref, tag_type);
|
||||
const tag_ref = @intToEnum(Ref, tag_type);
|
||||
const wr = try self.walkRef(file, parent_scope, parent_src, tag_ref, false);
|
||||
break :blk wr.expr;
|
||||
} else null;
|
||||
_ = tag_type;
|
||||
|
||||
const body_len = if (small.has_body_len) blk: {
|
||||
const body_len = file.zir.extra[extra_index];
|
||||
@@ -2652,6 +2657,8 @@ fn walkInstruction(
|
||||
.privDecls = priv_decl_indexes.items,
|
||||
.pubDecls = decl_indexes.items,
|
||||
.fields = field_type_refs.items,
|
||||
.tag = tag_type,
|
||||
.auto_enum = small.auto_enum_tag,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2698,12 +2705,13 @@ fn walkInstruction(
|
||||
else
|
||||
parent_src;
|
||||
|
||||
const tag_type: ?Ref = if (small.has_tag_type) blk: {
|
||||
const tag_type: ?DocData.Expr = if (small.has_tag_type) blk: {
|
||||
const tag_type = file.zir.extra[extra_index];
|
||||
extra_index += 1;
|
||||
break :blk @intToEnum(Ref, tag_type);
|
||||
const tag_ref = @intToEnum(Ref, tag_type);
|
||||
const wr = try self.walkRef(file, parent_scope, parent_src, tag_ref, false);
|
||||
break :blk wr.expr;
|
||||
} else null;
|
||||
_ = tag_type;
|
||||
|
||||
const body_len = if (small.has_body_len) blk: {
|
||||
const body_len = file.zir.extra[extra_index];
|
||||
@@ -2816,6 +2824,8 @@ fn walkInstruction(
|
||||
.src = self_ast_node_index,
|
||||
.privDecls = priv_decl_indexes.items,
|
||||
.pubDecls = decl_indexes.items,
|
||||
.tag = tag_type,
|
||||
.nonexhaustive = small.nonexhaustive,
|
||||
},
|
||||
};
|
||||
if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
|
||||
@@ -4185,6 +4195,12 @@ fn collectStructFieldInfo(
|
||||
|
||||
const break_inst = body[body.len - 1];
|
||||
const operand = data[break_inst].@"break".operand;
|
||||
try self.ast_nodes.append(self.arena, .{
|
||||
.file = self.files.getIndex(file).?,
|
||||
.line = parent_src.line,
|
||||
.col = 0,
|
||||
.fields = null, // walkInstruction will fill `fields` if necessary
|
||||
});
|
||||
const walk_result = try self.walkRef(file, scope, parent_src, operand, false);
|
||||
break :expr walk_result.expr;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user