autodoc: improve linking of decl references

there are still some bugs to solve when a decl is re-exported but
straight-forward cases are handled correctly
This commit is contained in:
Loris Cro 2023-01-08 16:25:14 +01:00
parent 87b223428a
commit 18f6ef613c

View File

@ -93,8 +93,7 @@ var zigAnalysis;
// empty array means refers to the package itself
declNames: [],
// these will be all types, except the last one may be a type or a decl
declObjs: [],
declObjs: [],
// (a, b, c, d) comptime call; result is the value the docs refer to
callName: null,
};
@ -451,6 +450,8 @@ var zigAnalysis;
curNav.declObjs.push(currentType);
}
window.x = currentType;
renderNav();
@ -819,6 +820,27 @@ var zigAnalysis;
return navLink(curNav.pkgNames, curNav.declNames.concat([childName]));
}
function findDeclNavLink(declName) {
if (curNav.declObjs.length == 0) return null;
const curFile = getAstNode(curNav.declObjs[curNav.declObjs.length-1].src).file;
for (let i = curNav.declObjs.length -1; i >= 0; i--) {
const curDecl = curNav.declObjs[i];
const curDeclName = curNav.declNames[i-1];
if (curDeclName == declName) {
const declPath = curNav.declNames.slice(0,i);
return navLink(curNav.pkgNames, declPath);
}
if (findSubDecl(curDecl, declName) != null) {
const declPath = curNav.declNames.slice(0,i).concat([declName]);
return navLink(curNav.pkgNames, declPath);
}
}
//throw("could not resolve links for '" + declName + "'");
}
//
// function navLinkCall(callObj) {
// let declNamesCopy = curNav.declNames.concat([]);
@ -879,7 +901,7 @@ var zigAnalysis;
return "false";
}
case "&": {
return "&" + exprName(zigAnalysis.exprs[expr["&"]]);
return "&" + exprName(zigAnalysis.exprs[expr["&"]], opts);
}
case "compileError": {
let compileError = expr.compileError;
@ -896,18 +918,18 @@ var zigAnalysis;
let payloadHtml = "";
const lhsExpr = zigAnalysis.exprs[expr.slice.lhs];
const startExpr = zigAnalysis.exprs[expr.slice.start];
let decl = exprName(lhsExpr);
let start = exprName(startExpr);
let decl = exprName(lhsExpr, opts);
let start = exprName(startExpr, opts);
let end = "";
let sentinel = "";
if (expr.slice["end"]) {
const endExpr = zigAnalysis.exprs[expr.slice.end];
let end_ = exprName(endExpr);
let end_ = exprName(endExpr, opts);
end += end_;
}
if (expr.slice["sentinel"]) {
const sentinelExpr = zigAnalysis.exprs[expr.slice.sentinel];
let sentinel_ = exprName(sentinelExpr);
let sentinel_ = exprName(sentinelExpr, opts);
sentinel += " :" + sentinel_;
}
payloadHtml += decl + "[" + start + ".." + end + sentinel + "]";
@ -915,7 +937,7 @@ var zigAnalysis;
}
case "sliceIndex": {
const sliceIndex = zigAnalysis.exprs[expr.sliceIndex];
return exprName(sliceIndex, opts);
return exprName(sliceIndex, opts, opts);
}
case "cmpxchg": {
const typeIndex = zigAnalysis.exprs[expr.cmpxchg.type];
@ -1019,19 +1041,6 @@ var zigAnalysis;
const switchIndex = zigAnalysis.exprs[expr.switchIndex];
return exprName(switchIndex, opts);
}
case "refPath": {
let name = exprName(expr.refPath[0]);
for (let i = 1; i < expr.refPath.length; i++) {
let component = undefined;
if ("string" in expr.refPath[i]) {
component = expr.refPath[i].string;
} else {
component = exprName(expr.refPath[i]);
}
name += "." + component;
}
return name;
}
case "fieldRef": {
const enumObj = exprName({ type: expr.fieldRef.type }, opts);
const field =
@ -1581,10 +1590,46 @@ var zigAnalysis;
return exprName(exprArg, opts);
}
case "declRef": {
return getDecl(expr.declRef).name;
const name = getDecl(expr.declRef).name;
if (opts.wantHtml) {
let payloadHtml = "";
if (opts.wantLink) {
payloadHtml += '<a href="'+ findDeclNavLink(name) +'">';
}
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
name +
"</span>";
if (opts.wantLink) payloadHtml += "</a>";
return payloadHtml;
} else {
return name;
}
}
case "refPath": {
return expr.refPath.map((x) => exprName(x, opts)).join(".");
let firstComponent = expr.refPath[0];
let name = exprName(firstComponent, opts);
let url = undefined;
if (opts.wantLink && "declRef" in firstComponent) {
url = findDeclNavLink(getDecl(firstComponent.declRef).name);
}
for (let i = 1; i < expr.refPath.length; i++) {
let component = undefined;
if ("string" in expr.refPath[i]) {
component = expr.refPath[i].string;
} else {
component = exprName(expr.refPath[i], {...opts, wantLink: false});
if (opts.wantLink && "declRef" in expr.refPath[i]) {
url += "." + getDecl(expr.refPath[i].declRef).name;
component = '<a href="'+ url +'">' +
component +
"</a>";
}
}
name += "." + component;
}
return name;
}
case "int": {
return "" + expr.int;
@ -1929,78 +1974,20 @@ var zigAnalysis;
if (isVarArgs && i === fnObj.params.length - 1) {
payloadHtml += "...";
} else if ("alignOf" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
payloadHtml += exprName(value, opts);
} else if ("typeOf" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
payloadHtml += exprName(value, opts);
} else if ("typeOf_peer" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
} else if ("declRef" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
} else if ("call" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
} else if ("refPath" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
payloadHtml +=
'<span class="tok-kw" style="color:lightblue;">' +
exprName(value, opts) +
"</span>";
payloadHtml += "</a>";
} else {
payloadHtml += exprName(value, opts);
}
} else if ("type" in value) {
let name = exprName(value, {
...opts,
wantHtml: false,
wantLink: false,
});
payloadHtml += '<span class="tok-kw">' + name + "</span>";
payloadHtml += exprName(value, opts);
//payloadHtml += '<span class="tok-kw">' + name + "</span>";
} else if ("binOpIndex" in value) {
payloadHtml += exprName(value, opts);
} else if ("comptimeExpr" in value) {
@ -2405,11 +2392,10 @@ var zigAnalysis;
}
if (typesList.length !== 0) {
window.x = typesList;
resizeDomList(
domListTypes,
typesList.length,
'<li><a href="#"></a></li>'
'<li><a href=""></a></li>'
);
for (let i = 0; i < typesList.length; i += 1) {
let liDom = domListTypes.children[i];
@ -2511,8 +2497,7 @@ var zigAnalysis;
} else {
let fieldTypeExpr = container.fields[i];
html += ": ";
let name = exprName(fieldTypeExpr, false, false);
html += '<span class="tok-kw">' + name + "</span>";
html += exprName(fieldTypeExpr, {wantHtml:true, wantLink:true});
let tsn = typeShorthandName(fieldTypeExpr);
if (tsn) {
html += "<span> (" + tsn + ")</span>";
@ -2746,13 +2731,15 @@ var zigAnalysis;
}
}
function findSubDecl(parentType, childName) {
function findSubDecl(parentTypeOrDecl, childName) {
let parentType = parentTypeOrDecl;
{
// Generic functions
// Generic functions / resorlving decls
if ("value" in parentType) {
const rv = resolveValue(parentType.value);
if ("type" in rv.expr) {
const t = getType(rv.expr.type);
parentType = t;
if (t.kind == typeKinds.Fn && t.generic_ret != null) {
let resolvedGenericRet = resolveValue({ expr: t.generic_ret });