autodoc: more js type fixes

This commit is contained in:
Loris Cro 2022-04-01 19:41:43 +02:00 committed by Andrew Kelley
parent 919b8e400c
commit 80f9490e06
2 changed files with 255 additions and 134 deletions

View File

@ -33,26 +33,27 @@
*/
/**
* @typedef {
| { void: {} }
| { unreachable: {} }
| { anytype: {} }
| { type: number }
| { comptimeExpr: number }
| { call: number }
| { int: { typeRef: WalkResult; value: number } }
| { float: { typeRef: WalkResult; value: number } }
| { bool: boolean }
| { undefined: WalkResult }
| { null: WalkResult }
| { typeOf: WalkResult }
| { compileError: string }
| { string: string }
| { struct: Struct }
| { refPath: WalkResult[] }
| { array: ZigArray }
| { enumLiteral: string }
} WalkResult
* @typedef {{
void: {},
unreachable: {},
anytype: {},
type: number,
comptimeExpr: number,
call: number,
int: { typeRef: WalkResult; value: number },
float: { typeRef: WalkResult; value: number },
bool: boolean,
undefined: WalkResult,
null: WalkResult,
typeOf: WalkResult,
compileError: string,
string: string,
struct: Struct,
refPath: WalkResult[],
declRef: number,
array: ZigArray,
enumLiteral: string,
}} WalkResult
*/
/**
@ -76,16 +77,70 @@
}} Fn
*/
/**
* @typedef {{
kind: number,
name: string,
fields: { name: string, docs: string }[]
fn: number | undefined,
}} ErrSetType
*/
/**
* @typedef {{
kind: number,
err: WalkResult,
payload: WalkResult,
}} ErrUnionType
*/
// Type, Void, Bool, NoReturn, Int, Float, ComptimeExpr, ComptimeFloat, ComptimeInt, Undefined, Null, ErrorUnion, BoundFn, Opaque, Frame, AnyFrame, Vector, EnumLiteral
/**
* @typedef {{
kind: number,
name: string
}} NumberType
*/
/**
* @typedef {{
kind: number,
size: number,
child: WalkResult
align: number,
bitOffsetInHost: number,
hostIntBytes: number,
volatile: boolean,
const: boolean,
}} PointerType
*/
/**
* @typedef {{
kind: number,
len: WalkResult
child: WalkResult
}} ArrayType
*/
/**
* @typedef {{
kind: number,
name: string,
child: WalkResult
}} OptionalType
*/
/**
* @typedef {
| { kind: number, name: string } // Type, Void, Bool, NoReturn, Int, Float, ComptimeExpr, ComptimeFloat, ComptimeInt, Undefined, Null, ErrorUnion, BoundFn, Opaque, Frame, AnyFrame, Vector, EnumLiteral
| { kind: number, name: string; child: WalkResult } // Optional
| { kind: number, len: WalkResult; child: WalkResult } // Array
| { kind: number, name: string; fields: { name: string; docs: string }[] } // ErrorSet
| { kind: number, size: "One" | "Many" | "Slice" | "C"; child: WalkResult } // Pointer
| OptionalType
| ArrayType
| PointerType
| ContainerType
| Fn
| ErrSetType
| ErrUnionType
| NumberType
} Type
*/
@ -107,6 +162,8 @@
docs?: string,
fields?: number[],
comptime: boolean,
noalias: boolean,
varArgs: boolean,
}} AstNode
*/
@ -117,7 +174,7 @@
src: number,
value: WalkResult,
decltest?: number,
isTest: bool,
isTest: boolean,
}} Decl
*/
@ -223,7 +280,7 @@ var zigAnalysis;
var domSectSearchNoResults = /** @type HTMLElement */(document.getElementById("sectSearchNoResults"));
var domSectInfo = /** @type HTMLElement */(document.getElementById("sectInfo"));
var domTdTarget = /** @type HTMLElement */(document.getElementById("tdTarget"));
var domPrivDeclsBox = /** @type HTMLElement */(document.getElementById("privDeclsBox"));
var domPrivDeclsBox = /** @type HTMLCheckboxElement */(document.getElementById("privDeclsBox"));
var domTdZigVer = /** @type HTMLElement */(document.getElementById("tdZigVer"));
var domHdrName = /** @type HTMLElement */(document.getElementById("hdrName"));
var domHelpModal = /** @type HTMLElement */(document.getElementById("helpDialog"));
@ -252,7 +309,7 @@ var zigAnalysis;
var canonTypeDecls = null; // lazy; use getCanonTypeDecl
/** @typedef {{
* showPrivDecls: bool,
* showPrivDecls: boolean,
* pkgNames: string[],
* pkgObjs: Package[],
* declNames: string[],
@ -598,6 +655,7 @@ var zigAnalysis;
return typeObj.generic;
}
/** @param {Decl} fnDecl */
function renderFn(fnDecl) {
var value = resolveValue(fnDecl.value);
console.assert("type" in value);
@ -622,31 +680,32 @@ var zigAnalysis;
errSetTypeIndex = retType.err;
}
if (errSetTypeIndex != null) {
var errSetType = zigAnalysis.types[errSetTypeIndex];
var errSetType = /** @type {ErrSetType} */(zigAnalysis.types[errSetTypeIndex]);
renderErrorSet(errSetType);
}
var protoSrcIndex = fnDecl.src;
if (typeIsGenericFn(value.type)) {
var instantiations = nodesToFnsMap[protoSrcIndex];
var calls = nodesToCallsMap[protoSrcIndex];
if (instantiations == null && calls == null) {
domFnNoExamples.classList.remove("hidden");
} else if (calls != null) {
// if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
if (fnObj.combined != null) renderContainer(fnObj.combined);
throw "TODO";
// var instantiations = nodesToFnsMap[protoSrcIndex];
// var calls = nodesToCallsMap[protoSrcIndex];
// if (instantiations == null && calls == null) {
// domFnNoExamples.classList.remove("hidden");
// } else if (calls != null) {
// // if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
// if (fnObj.combined != null) renderContainer(fnObj.combined);
resizeDomList(domListFnExamples, calls.length, '<li></li>');
// resizeDomList(domListFnExamples, calls.length, '<li></li>');
for (var callI = 0; callI < calls.length; callI += 1) {
var liDom = domListFnExamples.children[callI];
liDom.innerHTML = getCallHtml(fnDecl, calls[callI]);
}
// for (var callI = 0; callI < calls.length; callI += 1) {
// var liDom = domListFnExamples.children[callI];
// liDom.innerHTML = getCallHtml(fnDecl, calls[callI]);
// }
domFnExamples.classList.remove("hidden");
} else if (instantiations != null) {
// TODO
}
// domFnExamples.classList.remove("hidden");
// } else if (instantiations != null) {
// // TODO
// }
} else {
domFnExamples.classList.add("hidden");
@ -664,11 +723,15 @@ var zigAnalysis;
domFnProto.classList.remove("hidden");
}
/**
* @param {Decl} fnDecl
* @param {Fn} typeObj
*/
function renderFnParamDocs(fnDecl, typeObj) {
var docCount = 0;
var fnNode = zigAnalysis.astNodes[fnDecl.src];
var fields = fnNode.fields;
var fields = /** @type {number[]} */(fnNode.fields);
var isVarArgs = fnNode.varArgs;
for (var i = 0; i < fields.length; i += 1) {
@ -696,11 +759,11 @@ var zigAnalysis;
var value = typeObj.params[i];
var html = '<pre>' + escapeHtml(fieldNode.name) + ": ";
var html = '<pre>' + escapeHtml(/** @type {string} */(fieldNode.name)) + ": ";
if (isVarArgs && i === typeObj.params.length - 1) {
html += '...';
} else {
var name = typeValueName(value);
var name = typeValueName(value, false, false);
html += '<span class="tok-kw">' + name + '</span>';
}
@ -720,7 +783,7 @@ var zigAnalysis;
resizeDomList(domListNav, len, '<li><a href="#"></a></li>');
var list = [];
var hrefPkgNames = [];
var hrefDeclNames = [];
var hrefDeclNames = /** @type {string[]} */([]);
for (var i = 0; i < curNav.pkgNames.length; i += 1) {
hrefPkgNames.push(curNav.pkgNames[i]);
list.push({
@ -753,7 +816,7 @@ var zigAnalysis;
function renderInfo() {
domTdZigVer.textContent = zigAnalysis.params.zigVersion;
domTdTarget.textContent = zigAnalysis.params.builds[0].target;
//domTdTarget.textContent = zigAnalysis.params.builds[0].target;
domSectInfo.classList.remove("hidden");
}
@ -809,6 +872,12 @@ var zigAnalysis;
}
}
/**
* @param {string[]} pkgNames
* @param {string[]} declNames
* @param {string} [callName]
*/
function navLink(pkgNames, declNames, callName) {
let base = '#';
if (curNav.showPrivDecls) {
@ -826,23 +895,26 @@ var zigAnalysis;
}
}
/** @param {number} pkgIndex */
function navLinkPkg(pkgIndex) {
return navLink(canonPkgPaths[pkgIndex], []);
}
/** @param {string} childName */
function navLinkDecl(childName) {
return navLink(curNav.pkgNames, curNav.declNames.concat([childName]));
}
/** @param {Call} callObj */
function navLinkCall(callObj) {
var declNamesCopy = curNav.declNames.concat([]);
var callName = declNamesCopy.pop();
var callName = /** @type {string} */(declNamesCopy.pop());
callName += '(';
for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) {
if (arg_i !== 0) callName += ',';
var argObj = callObj.args[arg_i];
callName += getValueText(argObj.type, argObj.value, false, false);
callName += getValueText(argObj, argObj, false, false);
}
callName += ')';
@ -850,6 +922,10 @@ var zigAnalysis;
return navLink(curNav.pkgNames, declNamesCopy);
}
/**
* @param {any} dlDom
* @param {number} desiredLen
*/
function resizeDomListDl(dlDom, desiredLen) {
// add the missing dom entries
var i, ev;
@ -863,6 +939,11 @@ var zigAnalysis;
}
}
/**
* @param {any} listDom
* @param {number} desiredLen
* @param {string} templateHtml
*/
function resizeDomList(listDom, desiredLen, templateHtml) {
// add the missing dom entries
var i, ev;
@ -879,14 +960,14 @@ var zigAnalysis;
* @param {WalkResult} typeValue,
* @param {boolean} wantHtml,
* @param {boolean} wantLink,
* @param {number} [fnDecl],
* @param {Decl | null} [fnDecl],
* @param {string} [linkFnNameDecl],
* @return {string}
*/
function typeValueName(typeValue, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
if ("int" in typeValue) {
return typeValue.int.value;
return "" + typeValue.int.value;
}
if ("call" in typeValue) {
var result = "";
@ -963,38 +1044,51 @@ var zigAnalysis;
}
}
/**
* @param {WalkResult} typeRef
* @param {string} paramName
*/
function shouldSkipParamName(typeRef, paramName) {
var resolvedTypeRef = resolveValue(typeRef);
if ("type" in resolvedTypeRef) {
var typeObj = zigAnalysis.types[resolvedTypeRef.type];
if (typeObj.kind === typeKinds.Pointer &&
getPtrSize(typeObj) === pointerSizeEnum.One) {
const value = resolveValue(typeObj.child);
return typeValueName(value, false, true).toLowerCase() === paramName;
if (typeObj.kind === typeKinds.Pointer){
let ptrObj = /** @type {PointerType} */(typeObj);
if (getPtrSize(ptrObj) === pointerSizeEnum.One) {
const value = resolveValue(ptrObj.child);
return typeValueName(value, false, true).toLowerCase() === paramName;
}
}
}
return false;
}
/** @param {PointerType} typeObj */
function getPtrSize(typeObj) {
return (typeObj.len == null) ? pointerSizeEnum.One : typeObj.len;
return (typeObj.size == null) ? pointerSizeEnum.One : typeObj.size;
}
function getCallHtml(fnDecl, callIndex) {
var callObj = zigAnalysis.calls[callIndex];
// function getCallHtml(fnDecl, callIndex) {
// var callObj = zigAnalysis.calls[callIndex];
// TODO make these links work
//var html = '<a href="' + navLinkCall(callObj) + '">' + escapeHtml(fnDecl.name) + '</a>(';
var html = escapeHtml(fnDecl.name) + '(';
for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) {
if (arg_i !== 0) html += ', ';
var argObj = callObj.args[arg_i];
html += getValueText(argObj, argObj.value, true, true);
}
html += ')';
return html;
}
// // TODO make these links work
// //var html = '<a href="' + navLinkCall(callObj) + '">' + escapeHtml(fnDecl.name) + '</a>(';
// var html = escapeHtml(fnDecl.name) + '(';
// for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) {
// if (arg_i !== 0) html += ', ';
// var argObj = callObj.args[arg_i];
// html += getValueText(argObj, argObj.value, true, true);
// }
// html += ')';
// return html;
// }
/**
* @param {WalkResult} typeRef
* @param {any} value
* @param {boolean} wantHtml
* @param {boolean} wantLink
*/
function getValueText(typeRef, value, wantHtml, wantLink) {
var resolvedTypeRef = resolveValue(typeRef);
if ("comptimeExpr" in resolvedTypeRef) {
@ -1004,10 +1098,10 @@ var zigAnalysis;
var typeObj = zigAnalysis.types[typeRef.type];
switch (typeObj.kind) {
case typeKinds.Type:
return typeIndexName(value, wantHtml, wantLink);
return typeValueName(value, wantHtml, wantLink);
case typeKinds.Fn:
var fnObj = zigAnalysis.fns[value];
return typeValueName(fnObj, wantHtml, wantLink);
return typeName(fnObj, wantHtml, wantLink);
case typeKinds.Int:
if (wantHtml) {
return '<span class="tok-number">' + value + '</span>';
@ -1023,29 +1117,34 @@ var zigAnalysis;
* @param {Type} typeObj,
* @param {boolean} wantHtml,
* @param {boolean} wantSubLink,
* @param {number} [fnDecl],
* @param {Decl | null} [fnDecl],
* @param {string} [linkFnNameDecl],
* @return {string}
*/
function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {
switch (typeObj.kind) {
case typeKinds.Array:
{
let arrayObj = /** @type {ArrayType} */(typeObj);
var name = "[";
var lenName = typeValueName(typeObj.len, wantHtml);
var lenName = typeValueName(arrayObj.len, wantHtml, wantSubLink);
if (wantHtml) {
name += '<span class="tok-number">' + lenName + '</span>';
} else {
name += lenName;
}
name += "]";
name += typeValueName(typeObj.child, wantHtml, wantSubLink, null);
name += typeValueName(arrayObj.child, wantHtml, wantSubLink, null);
return name;
}
case typeKinds.Optional:
return "?" + typeValueName(typeObj.child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
return "?" + typeValueName(/**@type {OptionalType} */(typeObj).child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
case typeKinds.Pointer:
var name = "";
switch (typeObj.size) {
{
let ptrObj = /** @type {PointerType} */(typeObj);
var name = "";
switch (ptrObj.size) {
default:
console.log("TODO: implement unhandled pointer size case");
case pointerSizeEnum.One:
@ -1061,62 +1160,70 @@ var zigAnalysis;
name += "[*c]";
break;
}
if (typeObj['const']) {
if (ptrObj['const']) {
if (wantHtml) {
name += '<span class="tok-kw">const</span> ';
} else {
name += "const ";
}
}
if (typeObj['volatile']) {
if (ptrObj['volatile']) {
if (wantHtml) {
name += '<span class="tok-kw">volatile</span> ';
} else {
name += "volatile ";
}
}
if (typeObj.align != null) {
if (ptrObj.align != null) {
if (wantHtml) {
name += '<span class="tok-kw">align</span>(';
} else {
name += "align(";
}
if (wantHtml) {
name += '<span class="tok-number">' + typeObj.align + '</span>';
name += '<span class="tok-number">' + ptrObj.align + '</span>';
} else {
name += typeObj.align;
name += ptrObj.align;
}
if (typeObj.hostIntBytes != null) {
if (ptrObj.hostIntBytes != null) {
name += ":";
if (wantHtml) {
name += '<span class="tok-number">' + typeObj.bitOffsetInHost + '</span>';
name += '<span class="tok-number">' + ptrObj.bitOffsetInHost + '</span>';
} else {
name += typeObj.bitOffsetInHost;
name += ptrObj.bitOffsetInHost;
}
name += ":";
if (wantHtml) {
name += '<span class="tok-number">' + typeObj.hostIntBytes + '</span>';
name += '<span class="tok-number">' + ptrObj.hostIntBytes + '</span>';
} else {
name += typeObj.hostIntBytes;
name += ptrObj.hostIntBytes;
}
}
name += ") ";
}
name += typeValueName(typeObj.child, wantHtml, wantSubLink, null);
name += typeValueName(ptrObj.child, wantHtml, wantSubLink, null);
return name;
}
case typeKinds.Float:
{
let floatObj = /** @type {NumberType} */ (typeObj);
if (wantHtml) {
return '<span class="tok-type">f' + typeObj.bits + '</span>';
return '<span class="tok-type">' + floatObj.name + '</span>';
} else {
return "f" + typeObj.bits;
return floatObj.name;
}
}
case typeKinds.Int:
var name = typeObj.name;
{
let intObj = /** @type {NumberType} */(typeObj);
var name = intObj.name;
if (wantHtml) {
return '<span class="tok-type">' + name + '</span>';
} else {
return name;
}
}
case typeKinds.ComptimeInt:
if (wantHtml) {
return '<span class="tok-type">comptime_int</span>';
@ -1160,29 +1267,41 @@ var zigAnalysis;
return "noreturn";
}
case typeKinds.ErrorSet:
if (typeObj.errors == null) {
{
let errSetObj = /** @type {ErrSetType} */(typeObj);
if (errSetObj.fields == null) {
if (wantHtml) {
return '<span class="tok-type">anyerror</span>';
} else {
return "anyerror";
}
} else {
if (wantHtml) {
return escapeHtml(typeObj.name);
} else {
return typeObj.name;
}
throw "TODO";
// if (wantHtml) {
// return escapeHtml(typeObj.name);
// } else {
// return typeObj.name;
// }
}
}
case typeKinds.ErrorUnion:
var errSetTypeObj = zigAnalysis.types[typeObj.err];
var payloadHtml = typeIndexName(typeObj.payload, wantHtml, wantSubLink, null);
if (fnDecl != null && errSetTypeObj.fn === fnDecl.value) {
// function index parameter supplied and this is the inferred error set of it
return "!" + payloadHtml;
} else {
return typeIndexName(typeObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml;
}
{
throw "TODO";
// TODO: implement error union printing assuming that both
// payload and error union are walk results!
// let errUnionObj = /** @type {ErrUnionType} */(typeObj);
// var errSetTypeObj = /** @type {ErrSetType} */ (zigAnalysis.types[errUnionObj.err]);
// var payloadHtml = typeValueName(errUnionObj.payload, wantHtml, wantSubLink, null);
// if (fnDecl != null && errSetTypeObj.fn === fnDecl.value.type) {
// // function index parameter supplied and this is the inferred error set of it
// return "!" + payloadHtml;
// } else {
// return typeValueName(errUnionObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml;
// }
}
case typeKinds.Fn:
{
let fnObj = /** @type {Fn} */(typeObj);
var payloadHtml = "";
if (wantHtml) {
payloadHtml += '<span class="tok-kw">fn</span>';
@ -1200,19 +1319,19 @@ var zigAnalysis;
payloadHtml += 'fn'
}
payloadHtml += '(';
if (typeObj.params) {
if (fnObj.params) {
var fields = null;
var isVarArgs = false;
var fnNode = zigAnalysis.astNodes[typeObj.src];
var fnNode = zigAnalysis.astNodes[fnObj.src];
fields = fnNode.fields;
isVarArgs = fnNode.varArgs;
for (var i = 0; i < typeObj.params.length; i += 1) {
for (var i = 0; i < fnObj.params.length; i += 1) {
if (i != 0) {
payloadHtml += ', ';
}
var value = typeObj.params[i];
var value = fnObj.params[i];
var paramValue = resolveValue(value);
var isCte = "comptimeExpr" in paramValue;
@ -1249,7 +1368,7 @@ var zigAnalysis;
}
}
if (isVarArgs && i === typeObj.params.length - 1) {
if (isVarArgs && i === fnObj.params.length - 1) {
payloadHtml += '...';
} else if ("refPath" in value) {
payloadHtml += '<a href="">';
@ -1257,7 +1376,7 @@ var zigAnalysis;
payloadHtml += '</a>';
} else if ("type" in value) {
var name = typeValueName(value, false);
var name = typeValueName(value, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
} else if ("comptimeExpr" in value) {
payloadHtml += '<span class="tok-kw">[ComptimeExpr]</span>';
@ -1270,23 +1389,26 @@ var zigAnalysis;
}
payloadHtml += ') ';
if (typeObj.ret != null) {
payloadHtml += typeValueName(typeObj.ret, wantHtml, wantSubLink, fnDecl);
if (fnObj.ret != null) {
payloadHtml += typeValueName(fnObj.ret, wantHtml, wantSubLink, fnDecl);
} else if (wantHtml) {
payloadHtml += '<span class="tok-kw">anytype</span>';
} else {
payloadHtml += 'anytype';
}
return payloadHtml;
}
default:
if (wantHtml) {
return escapeHtml(typeObj.name);
} else {
return typeObj.name;
}
throw "TODO";
// if (wantHtml) {
// return escapeHtml(typeObj.name);
// } else {
// return typeObj.name;
// }
}
}
/** @param {Type} typeObj */
function renderType(typeObj) {
var name;
if (rootIsStd && typeObj === zigAnalysis.types[zigAnalysis.packages[zigAnalysis.rootPkg].main]) {
@ -1299,32 +1421,30 @@ var zigAnalysis;
domHdrName.classList.remove("hidden");
}
if (typeObj.kind == typeKinds.ErrorSet) {
renderErrorSet(typeObj);
renderErrorSet(/** @type {ErrSetType} */(typeObj));
}
}
/** @param {ErrSetType} errSetType */
function renderErrorSet(errSetType) {
if (errSetType.errors == null) {
if (errSetType.fields == null) {
domFnErrorsAnyError.classList.remove("hidden");
} else {
var errorList = [];
for (var i = 0; i < errSetType.errors.length; i += 1) {
var errObj = zigAnalysis.errors[errSetType.errors[i]];
var srcObj = zigAnalysis.astNodes[errObj.src];
errorList.push({
err: errObj,
docs: srcObj.docs,
});
for (var i = 0; i < errSetType.fields.length; i += 1) {
var errObj = errSetType.fields[i];
//var srcObj = zigAnalysis.astNodes[errObj.src];
errorList.push(errObj);
}
errorList.sort(function(a, b) {
return operatorCompare(a.err.name.toLowerCase(), b.err.name.toLowerCase());
return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase());
});
resizeDomListDl(domListFnErrors, errorList.length);
for (var i = 0; i < errorList.length; i += 1) {
var nameTdDom = domListFnErrors.children[i * 2 + 0];
var descTdDom = domListFnErrors.children[i * 2 + 1];
nameTdDom.textContent = errorList[i].err.name;
nameTdDom.textContent = errorList[i].name;
var docs = errorList[i].docs;
if (docs != null) {
descTdDom.innerHTML = markdown(docs);
@ -1517,7 +1637,7 @@ var zigAnalysis;
let fDecl = resolveValue(c.func);
if ("type" in fDecl) {
console.assert("type" in fDecl);
let fType = zigAnalysis.types[fDecl.type];
let fType = /** @type {Fn} */(zigAnalysis.types[fDecl.type]);
console.assert("type" in fType.ret);
if (fType.ret.type === typeTypeId) {
typesList.push(decl);
@ -1671,7 +1791,7 @@ var zigAnalysis;
} else {
var field = container.fields[i];
html += ": ";
var name = typeValueName(field);
var name = typeValueName(field, false, false);
html += '<span class="tok-kw">'+ name +'</span>';
}

View File

@ -409,6 +409,7 @@ const DocData = struct {
ErrorSet: struct {
name: []const u8,
fields: []const Field,
// TODO: fn field for inferred error sets?
},
Enum: struct {
name: []const u8,