autodoc: improve rendering and add "show priv decls" checkbox

This commit is contained in:
Loris Cro
2022-03-24 18:52:07 +01:00
committed by Andrew Kelley
parent df3074aa98
commit 36c4b1aac9
3 changed files with 179 additions and 190 deletions

View File

@@ -26,17 +26,17 @@
--search-sh-color: rgba(0, 0, 0, 0.18);
--help-sh-color: rgba(0, 0, 0, 0.75);
}
html, body { margin: 0; padding:0; height: 100%; }
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.hidden {
display: none;
}
@@ -58,7 +58,7 @@
width: 100%;
height: 100%;
justify-content: center;
z-index: 100;
}
@@ -76,7 +76,7 @@
overflow-wrap: break-word;
flex-shrink: 0;
flex-grow: 0;
z-index: 300;
}
@@ -86,7 +86,7 @@
-webkit-overflow-scrolling: touch;
flex-grow: 1;
flex-shrink: 1;
z-index: 200;
}
@@ -95,44 +95,44 @@
max-width: 85vw;
flex-shrink: 1;
}
.help-modal {
z-index: 400;
}
/* sidebar */
.sidebar {
font-size: 1rem;
background-color: var(--bg-color);
box-shadow: 0 0 1rem var(--sidebar-sh-color);
}
.sidebar .logo {
padding: 1rem 0.35rem 0.35rem 0.35rem;
}
.sidebar .logo > svg {
display: block;
overflow: visible;
}
.sidebar h2 {
margin: 0.5rem;
padding: 0;
font-size: 1.2rem;
}
.sidebar h2 > span {
border-bottom: 0.125rem dotted var(--tx-color);
}
.sidebar .packages {
list-style-type: none;
margin: 0;
padding: 0;
background-color: var(--sidebar-pkg-bg-color);
}
.sidebar .packages > li > a {
display: block;
padding: 0.5rem 1rem;
@@ -140,17 +140,17 @@
background-color: var(--sidebar-pkglnk-bg-color);
text-decoration: none;
}
.sidebar .packages > li > a:hover {
color: var(--sidebar-pkglnk-tx-color-hover);
background-color: var(--sidebar-pkglnk-bg-color-hover);
}
.sidebar .packages > li > a.active {
color: var(--sidebar-pkglnk-tx-color-active);
background-color: var(--sidebar-pkglnk-bg-color-active);
}
.sidebar p.str {
margin: 0.5rem;
font-family: var(--mono);
@@ -183,28 +183,28 @@
border-radius: 0;
-webkit-appearance: none;
}
.docs .search:focus {
background-color: var(--search-bg-color-focus);
border-bottom-color: #ffbb4d;
box-shadow: 0 0.3em 1em 0.125em var(--search-sh-color);
}
.docs .search::placeholder {
font-size: 1rem;
font-family: var(--ui);
color: var(--tx-color);
opacity: 0.5;
}
.docs a {
color: var(--link-color);
}
.docs p {
margin: 0.8rem 0;
}
.docs pre {
font-family: var(--mono);
font-size:1em;
@@ -212,19 +212,19 @@
padding:1em;
overflow-x: auto;
}
.docs code {
font-family: var(--mono);
font-size: 1em;
}
.docs h1 {
font-size: 1.4em;
margin: 0.8em 0;
padding: 0;
border-bottom: 0.0625rem dashed;
}
.docs h2 {
font-size: 1.3em;
margin: 0.5em 0;
@@ -264,7 +264,7 @@
#tableFnErrors dt {
font-weight: bold;
}
.examples {
list-style-type: none;
margin: 0;
@@ -275,7 +275,7 @@
white-space: nowrap;
overflow-x: auto;
}
.docs td {
margin: 0;
padding: 0.5em;
@@ -283,7 +283,7 @@
text-overflow: ellipsis;
overflow-x: hidden;
}
/* help dialog */
.help-modal {
display: flex;
@@ -308,23 +308,23 @@
border: 0.125rem solid #000;
box-shadow: 0 0.5rem 2.5rem 0.3rem var(--help-sh-color);
}
.help-modal h1 {
margin: 0.75em 2.5em 1em 2.5em;
font-size: 1.5em;
text-align: center;
}
.help-modal dt, .help-modal dd {
display: inline;
margin: 0 0.2em;
}
.help-modal dl {
margin-left: 0.5em;
margin-right: 0.5em;
}
.help-modal kbd {
display: inline-block;
padding: 0.3em 0.2em;
@@ -341,7 +341,7 @@
box-shadow: inset 0 -0.0625em 0 #c6cbd1;
cursor: default;
}
/* tokens */
.tok-kw {
color: #333;
@@ -371,10 +371,10 @@
color: #458;
font-weight: bold;
}
/* dark mode */
@media (prefers-color-scheme: dark) {
:root {
--tx-color: #bbb;
--bg-color: #111;
@@ -392,7 +392,7 @@
--search-sh-color: rgba(255, 255, 255, 0.28);
--help-sh-color: rgba(142, 142, 142, 0.5);
}
.docs pre {
background-color:#2A2A2A;
}
@@ -440,7 +440,7 @@
.tok-type {
color: #68f;
}
}
@media only screen and (max-width: 750px) {
@@ -545,6 +545,9 @@
<h2><span>Target</span></h2>
<p class="str" id="tdTarget"></p>
</div>
<div>
<input id="privDeclsBox" type="checkbox"/> Show Private Decls
</div>
</nav>
</div>
<div class="flex-right">

View File

@@ -32,18 +32,6 @@
} TypeKind
*/
/**
* @typedef {
| WalkResult
| { unspecified: {} }
| { anytype: {} }
| { type: number }
| { comptimeExpr: number }
| { call: number }
| { hasCte: boolean; declPath: number[] }
} TypeRef
*/
/**
* @typedef {
| { void: {} }
@@ -52,16 +40,16 @@
| { type: number }
| { comptimeExpr: number }
| { call: number }
| { int: { typeRef: TypeRef; value: number } }
| { float: { typeRef: TypeRef; value: number } }
| { int: { typeRef: WalkResult; value: number } }
| { float: { typeRef: WalkResult; value: number } }
| { bool: boolean }
| { undefined: TypeRef }
| { null: TypeRef }
| { undefined: WalkResult }
| { null: WalkResult }
| { typeOf: WalkResult }
| { compileError: string }
| { string: string }
| { struct: Struct }
| { hasCte: boolean; declPath: number[] }
| { refPath: WalkResult[] }
| { array: ZigArray }
| { enumLiteral: string }
} WalkResult
@@ -75,8 +63,8 @@
| { len: WalkResult; child: TypeRef } // Array
| { name: string; fields: { name: string; docs: string }[] } // ErrorSet
| { size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer
| { name: string; src?: number; privDecls: number[]; pubDecls: number[]; fields?: TypeRef[] } // Struct, Enum, Union
| { name: string; src?: number; ret: TypeRef; params?: TypeRef[] } // Fn
| { name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union
| { name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn
)
} Type
*/
@@ -85,14 +73,14 @@
* @typedef {{
name: string,
src: number | null,
ret: TypeRef,
params: TypeRef[] | null,
ret: WalkResult,
params: WalkResult[] | null,
}} Fn
*/
/**
* @typedef {{
func: TypeRef,
func: WalkResult,
args: WalkResult[],
ret: WalkResult,
}} Call
@@ -135,21 +123,21 @@
src?: number,
privDecls: number[],
pubDecls: number[],
fields?: TypeRef[],
fields?: WalkResult[],
}} Struct
*/
/**
* @typedef {{
len: WalkResult,
child: TypeRef,
child: WalkResult,
}} ZigArray
*/
/**
* @typedef {{
code: string,
typeRef: TypeRef,
typeRef: WalkResult,
}} ComptimeExpr
*/
@@ -219,6 +207,7 @@ var zigAnalysis;
var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
var domSectInfo = document.getElementById("sectInfo");
var domTdTarget = document.getElementById("tdTarget");
var domPrivDeclsBox = document.getElementById("privDeclsBox");
var domTdZigVer = document.getElementById("tdZigVer");
var domHdrName = document.getElementById("hdrName");
var domHelpModal = document.getElementById("helpDialog");
@@ -238,6 +227,7 @@ var zigAnalysis;
var canonTypeDecls = null; // lazy; use getCanonTypeDecl
var curNav = {
showPrivDecls: false,
// each element is a package name, e.g. @import("a") then within there @import("b")
// starting implicitly from root package
pkgNames: [],
@@ -264,6 +254,18 @@ var zigAnalysis;
// var nodesToCallsMap = indexNodesToCalls();
domSearch.addEventListener('keydown', onSearchKeyDown, false);
domPrivDeclsBox.addEventListener('change', function() {
if (this.checked != curNav.showPrivDecls) {
if (this.checked && location.hash.length > 1 && location.hash[1] != '*'){
location.hash = "#*" + location.hash.substring(1);
return;
}
if (!this.checked && location.hash.length > 1 && location.hash[1] == '*') {
location.hash = "#" + location.hash.substring(2);
return;
}
}
}, false);
window.addEventListener('hashchange', onHashChange, false);
window.addEventListener('keydown', onWindowKeyDown, false);
onHashChange();
@@ -323,19 +325,13 @@ var zigAnalysis;
return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind);
}
function findCteInDeclPath(path) {
function findCteInRefPath(path) {
for (var i = path.length - 1; i >= 0; i -= 1) {
const decl = zigAnalysis.decls[path[i]];
if ("comptimeExpr" in decl.value) {
return decl;
}
if ("declPath" in decl.value) {
const res = findCteInDeclPath(decl.value.declPath);
if (res !== null) {
return res;
}
}
const ref = path[i];
if ("string" in ref) continue;
if ("comptimeExpr" in ref) return ref;
if ("refPath" in ref) return findCteinRefPath(ref.refPath);
return null;
}
return null;
@@ -346,14 +342,15 @@ var zigAnalysis;
while(i < 1000) {
i += 1;
if ("declPath" in value) {
if (value.hasCte) {
return findCteInDeclPath(value.declPath).value;
}
value = zigAnalysis.decls[value.declPath[0]].value;
if ("refPath" in value) {
value = value.refPath[value.refPath.length -1];
continue;
}
if ("declRef" in value) {
value = zigAnalysis.decls[value.declRef].value;
}
return value;
}
@@ -369,13 +366,15 @@ var zigAnalysis;
return { type: typeTypeId };
}
if ("declPath" in decl.value) {
if (decl.value.hasCte) {
decl = findCteInDeclPath(decl.value.declPath);
} else {
decl = zigAnalysis.decls[decl.value.declPath[0]];
}
if ("refPath" in decl.value) {
decl = {
value: decl.value.refPath[decl.value.refPath.length -1]
};
continue;
}
if ("declRef" in decl.value) {
decl = zigAnalysis.decls[decl.value.declRef];
continue;
}
@@ -402,8 +401,14 @@ var zigAnalysis;
if ("call" in decl.value) {
const fn_call = zigAnalysis.calls[decl.value.call];
console.assert("declPath" in fn_call.func);
const fn_decl = zigAnalysis.decls[fn_call.func.declPath[0]];
var fn_decl = undefined;
if ("declRef" in fn_call.func) {
fn_decl = zigAnalysis.decls[fn_call.func.declRef];
} else if ("refPath" in fn_call.func) {
console.assert("declRef" in fn_call.func.refPath[fn_call.func.refPath.length -1]);
fn_decl = zigAnalysis.decls[fn_call.func.refPath[fn_call.func.refPath.length -1].declRef.value];
} else throw {};
const fn_decl_value = resolveValue(fn_decl.value);
console.assert("type" in fn_decl_value); //TODO handle comptimeExpr
const fn_type = zigAnalysis.types[fn_decl_value.type];
@@ -456,6 +461,8 @@ var zigAnalysis;
renderInfo();
renderPkgList();
domPrivDeclsBox.checked = curNav.showPrivDecls;
if (curNavSearch !== "") {
return renderSearch();
}
@@ -547,7 +554,7 @@ var zigAnalysis;
var typeObj = zigAnalysis.types[typeIndex];
if (typeObj.kind !== typeKinds.Struct)
return false;
return !typeObj.fields;
return typeObj.fields.length == 0;
}
function typeIsGenericFn(typeIndex) {
@@ -850,22 +857,14 @@ var zigAnalysis;
if ("comptimeExpr" in typeValue) {
return "[ComptimeExpr]";
}
if ("declPath" in typeValue) {
if ("refPath" in typeValue) {
var result = "";
for (var j = typeValue.declPath.length - 1; j >= 0; j--) {
var decl = zigAnalysis.decls[typeValue.declPath[j]];
for (var j = 0; j < typeValue.refPath.length; j++) {
// TODO: handle nested decl paths properly!
if (typeValue.hasCte) {
if (wantHtml)
result += "<a href=\"\">[ComptimeExpr]</a>";
else
result += "[ComptimeExpr]";
break;
}
var name = escapeHtml(decl.name);
var name = "[RefPath]";
if (wantHtml) {
result += '<a href="'+navLinkDecl(decl.name)+'">';
//result += '<a href="'+navLinkDecl(decl.name)+'">';
result += '<a href="">';
result += '<span class="tok-kw" style="color:lightblue;">' +
name + '</span>';
result += '</a>';
@@ -1182,24 +1181,11 @@ var zigAnalysis;
if (isVarArgs && i === typeObj.params.length - 1) {
payloadHtml += '...';
} else if ("declPath" in value) {
if (value.hasCte) {
var cte = findCteInDeclPath(value.declPath);
payloadHtml += "[ComptimeExpr]";
} else {
var decl = zigAnalysis.decls[value.declPath[0]];
var val = resolveValue(decl.value);
if ("comptimeExpr" in val) {
payloadHtml += "[ComptimeExpr]";
} else {
console.assert("type" in val);
var valType = zigAnalysis.types[val.type];
var valTypeName = typeShorthandName(valType);
payloadHtml += '<a href="'+navLinkDecl(decl.name)+'">';
payloadHtml += '<span class="tok-kw" style="color:lightblue;">' + escapeHtml(decl.name) + '</span>';
payloadHtml += '</a>';
}
}
} else if ("refPath" in value) {
payloadHtml += '<a href="">';
payloadHtml += '<span class="tok-kw" style="color:lightblue;">[Ref Path]</span>';
payloadHtml += '</a>';
} else if ("type" in value) {
var name = typeValueName(value, false);
payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
@@ -1422,6 +1408,59 @@ var zigAnalysis;
domFnProto.classList.remove("hidden");
}
function categorizeDecls(decls,
typesList, namespacesList, errSetsList,
fnsList, varsList, valsList) {
for (var i = 0; i < decls.length; i += 1) {
var decl = zigAnalysis.decls[decls[i]];
var declValue = resolveValue(decl.value);
if (decl.kind === 'var') {
varsList.push(decl);
continue;
}
if (decl.kind === 'const') {
if ("call" in declValue) {
let c = zigAnalysis.calls[declValue.call];
console.assert("comptimeExpr" in c.ret);
let fDecl = resolveValue(c.func);
console.assert("type" in fDecl);
let fType = zigAnalysis.types[fDecl.type];
console.assert("type" in fType.ret);
if (fType.ret.type === typeTypeId) {
typesList.push(decl);
} else {
valsList.push(decl);
}
} else if (!("type" in declValue)){
valsList.push(decl);
} else {
var value = zigAnalysis.types[declValue.type];
var kind = value.kind;
if (kind === typeKinds.Fn) {
// TODO: handle CTE return types when we know their type.
const resVal = resolveValue(value.ret);
if ("type" in resVal && resVal.type == typeTypeId) {
typesList.push(decl);
} else {
fnsList.push(decl);
}
} else if (typeIsErrSet(declValue.type)) {
errSetsList.push(decl);
} else if (typeIsStructWithNoFields(declValue.type)) {
namespacesList.push(decl);
} else {
typesList.push(decl);
}
}
}
}
}
function renderContainer(container) {
var typesList = [];
var namespacesList = [];
@@ -1430,77 +1469,13 @@ var zigAnalysis;
var varsList = [];
var valsList = [];
var declLen = container.pubDecls ? container.pubDecls.length : 0;
for (var i = 0; i < declLen; i += 1) {
var decl = zigAnalysis.decls[container.pubDecls[i]];
var declValue = resolveValue(decl.value);
categorizeDecls(container.pubDecls,
typesList, namespacesList, errSetsList,
fnsList, varsList, valsList);
if (curNav.showPrivDecls) categorizeDecls(container.privDecls,
typesList, namespacesList, errSetsList,
fnsList, varsList, valsList);
if (decl.kind === 'var') {
varsList.push(decl);
continue;
}
if (decl.kind === 'const') {
if (!("type" in declValue)){
valsList.push(decl);
} else {
var value = zigAnalysis.types[declValue.type];
var kind = value.kind;
if (kind === typeKinds.Fn) {
// TODO: handle CTE return types when we know their type.
const resVal = resolveValue(value.ret);
if ("type" in resVal && resVal.type == typeTypeId) {
typesList.push(decl);
} else {
fnsList.push(decl);
}
} else if (typeIsErrSet(declValue.type)) {
errSetsList.push(decl);
} else if (typeIsStructWithNoFields(declValue.type)) {
namespacesList.push(decl);
} else {
typesList.push(decl);
}
}
}
}
declLen = container.privDecls ? container.privDecls.length : 0;
for (var i = 0; i < declLen; i += 1) {
var decl = zigAnalysis.decls[container.privDecls[i]];
var declValue = resolveValue(decl.value);
if (decl.kind === 'var') {
varsList.push(decl);
continue;
}
if (decl.kind === 'const') {
if (!("type" in declValue)){
valsList.push(decl);
} else {
var value = zigAnalysis.types[declValue.type];
var kind = value.kind;
if (kind === typeKinds.Fn) {
// TODO: handle CTE return types when we know their type.
const resVal = resolveValue(value.ret);
if ("type" in resVal && resVal.type == typeTypeId) {
typesList.push(decl);
} else {
fnsList.push(decl);
}
} else if (typeIsErrSet(declValue.type)) {
errSetsList.push(decl);
} else if (typeIsStructWithNoFields(declValue.type)) {
namespacesList.push(decl);
} else {
typesList.push(decl);
}
}
}
}
typesList.sort(byNameProperty);
namespacesList.sort(byNameProperty);
@@ -1712,6 +1687,7 @@ var zigAnalysis;
function updateCurNav() {
curNav = {
showPrivDecls: false,
pkgNames: [],
pkgObjs: [],
declNames: [],
@@ -1721,6 +1697,11 @@ var zigAnalysis;
if (location.hash[0] === '#' && location.hash.length > 1) {
var query = location.hash.substring(1);
if (query[0] === '*') {
curNav.showPrivDecls = true;
query = query.substring(1);
}
var qpos = query.indexOf("?");
var nonSearchPart;
if (qpos === -1) {

View File

@@ -608,6 +608,7 @@ const DocData = struct {
\\, "value": {s}1 }} }}
, .{neg});
// TODO: uncomment once float panic is fixed in stdlib
// See: https://github.com/ziglang/zig/issues/11283
// try w.print(
// \\, "value": {s}{e} }} }}
// , .{ neg, v.value });
@@ -621,7 +622,6 @@ const DocData = struct {
.@"null" => |v| try std.json.stringify(v, options, w),
.typeOf, .sizeOf => |v| try std.json.stringify(v, options, w),
.compileError => |v| try std.json.stringify(v, options, w),
.string => |v| try std.json.stringify(v, options, w),
.fieldRef => |v| try std.json.stringify(
struct { fieldRef: FieldRef }{ .fieldRef = v },
options,
@@ -645,6 +645,11 @@ const DocData = struct {
options,
w,
),
.string => |v| try std.json.stringify(
struct { string: []const u8 }{ .string = v },
options,
w,
),
.enumLiteral => |v| try std.json.stringify(
struct { @"enumLiteral": []const u8 }{ .@"enumLiteral" = v },
options,