Merge pull request #14395 from der-teufel-programming/master

autodoc: Add Struct, Union, Enum handling in exprName, add tags for Enum and Union, anonymous types "work"
This commit is contained in:
Loris Cro 2023-01-24 19:18:52 +01:00 committed by GitHub
commit 4e80253e20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 182 additions and 9 deletions

View File

@ -1641,7 +1641,11 @@ const NAV_MODES = {
return payloadHtml;
}
case "null": {
return "null";
if (opts.wantHtml) {
return '<span class="tok-null">null</span>';
} else {
return "null";
}
}
case "array": {
let payloadHtml = ".{";
@ -1766,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 = "&nbsp;&nbsp;&nbsp;&nbsp;"
}
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 = "&nbsp;&nbsp;&nbsp;&nbsp;";
} 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 = "&nbsp;&nbsp;&nbsp;&nbsp;"
}
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;
@ -3831,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 {
@ -3840,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 {

View File

@ -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;
};