generated docs: function parameters have links

This commit is contained in:
Andrew Kelley 2019-10-08 11:52:06 -04:00
parent a55db08a7b
commit 6814d6b332
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
3 changed files with 298 additions and 10 deletions

View File

@ -145,6 +145,34 @@
#listSearchResults li.selected {
background-color: #93e196;
}
.tok-kw {
color: #333;
font-weight: bold;
}
.tok-str {
color: #d14;
}
.tok-builtin {
color: #0086b3;
}
.tok-comment {
color: #777;
font-style: italic;
}
.tok-fn {
color: #900;
font-weight: bold;
}
.tok-null {
color: #008080;
}
.tok-number {
color: #008080;
}
.tok-type {
color: #458;
font-weight: bold;
}
@media (prefers-color-scheme: dark) {
body{
@ -183,6 +211,30 @@
#listSearchResults li.selected a {
color: #fff;
}
.tok-kw {
color: #eee;
}
.tok-str {
color: #2e5;
}
.tok-builtin {
color: #ff894c;
}
.tok-comment {
color: #aa7;
}
.tok-fn {
color: #e33;
}
.tok-null {
color: #ff8080;
}
.tok-number {
color: #ff8080;
}
.tok-type {
color: #68f;
}
}
</style>
</head>

View File

@ -29,11 +29,17 @@
var typeKindTypeId;
var typeKindFnId;
var typeKindPtrId;
var typeKindFloatId;
var typeKindIntId;
findTypeKinds();
// for each package, is an array with packages to get to this one
var canonPkgPaths = computeCanonicalPackagePaths();
// for each decl, is an array with {declNames, pkgNames} to get to this one
var canonDeclPaths = null; // lazy; use getCanonDeclPath
// for each type, is an array with {declNames, pkgNames} to get to this one
var canonTypeDecls = null; // lazy; use getCanonTypeDecl
var curNav = {
// each element is a package name, e.g. @import("a") then within there @import("b")
@ -158,7 +164,29 @@
function renderFn(fnDecl) {
var typeObj = zigAnalysis.types[fnDecl.type];
domFnProtoCode.textContent = "fn " + fnDecl.name + typeObj.name.substring(2);
var protoHtml = '<span class="tok-kw">fn</span> <span class="tok-fn">'
+ escapeHtml(fnDecl.name) + '</span>(';
if (typeObj.args != null) {
for (var i = 0; i < typeObj.args.length; i += 1) {
if (i != 0) {
protoHtml += ', ';
}
var argTypeIndex = typeObj.args[i];
if (argTypeIndex != null) {
protoHtml += typeIndexName(argTypeIndex, true, true);
} else {
protoHtml += '<span class="tok-kw">var</span>';
}
}
}
protoHtml += ') ';
if (typeObj.ret != null) {
protoHtml += typeIndexName(typeObj.ret, true, true);
} else {
protoHtml += '<span class="tok-kw">var</span>';
}
domFnProtoCode.innerHTML = protoHtml;
var docsSource = null;
var srcNode = zigAnalysis.astNodes[fnDecl.src];
@ -306,9 +334,107 @@
}
}
function typeIndexName(typeIndex, wantHtml, wantLink) {
var typeObj = zigAnalysis.types[typeIndex];
if (wantLink) {
var declIndex = getCanonTypeDecl(typeIndex);
var declPath = getCanonDeclPath(declIndex);
var haveLink = declPath != null;
var typeNameHtml = typeName(typeObj, true, !haveLink);
if (haveLink) {
return '<a href="' + navLink(declPath.pkgNames, declPath.declNames) + '">' + typeNameHtml + '</a>';
} else {
return typeNameHtml;
}
} else {
return typeName(typeObj, wantHtml);
}
}
function typeName(typeObj, wantHtml, wantSubLink) {
switch (typeObj.kind) {
case typeKindPtrId:
var name = "";
switch (typeObj.len) {
case 0:
default:
name += "*";
break;
case 1:
name += "[*]";
break;
case 2:
name += "[]";
break;
case 3:
name += "[*c]";
break;
}
if (typeObj['const']) {
if (wantHtml) {
name += '<span class="tok-kw">const</span> ';
} else {
name += "const ";
}
}
if (typeObj['volatile']) {
if (wantHtml) {
name += '<span class="tok-kw">volatile</span> ';
} else {
name += "volatile ";
}
}
if (typeObj.align != null) {
if (wantHtml) {
name += '<span class="tok-kw">align</span>(';
} else {
name += "align(";
}
if (wantHtml) {
name += '<span class="tok-number">' + typeObj.align + '</span>';
} else {
name += typeObj.align;
}
if (typeObj.hostIntBytes != null) {
name += ":" + typeObj.bitOffsetInHost + ":" + typeObj.hostIntBytes;
}
name += ") ";
}
name += typeIndexName(typeObj.elem, wantHtml, wantSubLink);
return name;
case typeKindFloatId:
if (wantHtml) {
return '<span class="tok-type">f' + typeObj.bits + '</span>';
} else {
return "f" + typeObj.bits;
}
case typeKindIntId:
var signed = (typeObj.i != null) ? 'i' : 'u';
var bits = typeObj[signed];
if (wantHtml) {
return '<span class="tok-type">' + signed + bits + '</span>';
} else {
return signed + bits;
}
case typeKindTypeId:
if (wantHtml) {
return '<span class="tok-type">type</span>';
} else {
return "type";
}
default:
if (wantHtml) {
return escapeHtml(typeObj.name);
} else {
return typeObj.name;
}
}
}
function renderType(typeObj) {
if (typeObj.name != null && typeObj.name != "") {
domHdrName.innerText = zigAnalysis.typeKinds[typeObj.kind] + " " + typeObj.name;
var name = typeName(typeObj);
if (name != null && name != "") {
domHdrName.innerText = zigAnalysis.typeKinds[typeObj.kind] + " " + name;
domHdrName.classList.remove("hidden");
}
}
@ -402,6 +528,12 @@
typeKindTypeId = i;
} else if (zigAnalysis.typeKinds[i] === "Fn") {
typeKindFnId = i;
} else if (zigAnalysis.typeKinds[i] === "Pointer") {
typeKindPtrId = i;
} else if (zigAnalysis.typeKinds[i] === "Float") {
typeKindFloatId = i;
} else if (zigAnalysis.typeKinds[i] === "Int") {
typeKindIntId = i;
}
}
if (typeKindTypeId == null) {
@ -410,6 +542,15 @@
if (typeKindFnId == null) {
throw new Error("No type kind 'Fn' found");
}
if (typeKindPtrId == null) {
throw new Error("No type kind 'Pointer' found");
}
if (typeKindFloatId == null) {
throw new Error("No type kind 'Float' found");
}
if (typeKindIntId == null) {
throw new Error("No type kind 'Int' found");
}
}
function findTypeTypeId() {
@ -500,6 +641,7 @@
function computeCanonDeclPaths() {
var list = new Array(zigAnalysis.decls.length);
canonTypeDecls = new Array(zigAnalysis.types.length);
for (var pkgI = 0; pkgI < zigAnalysis.packages.length; pkgI += 1) {
if (pkgI === zigAnalysis.rootPkg && rootIsStd) continue;
@ -518,6 +660,9 @@
if (list[mainDeclIndex] != null) continue;
var decl = zigAnalysis.decls[mainDeclIndex];
if (decl.type === typeTypeId) {
canonTypeDecls[decl.value] = mainDeclIndex;
}
var declNames = item.declNames.concat([decl.name]);
list[mainDeclIndex] = {
pkgNames: pkgNames,
@ -544,12 +689,22 @@
return canonDeclPaths[index];
}
function markdown(mdText) {
return mdText.replace(/[&"<>]/g, function (m) {
function getCanonTypeDecl(index) {
getCanonDeclPath(0);
return canonTypeDecls[index];
}
function escapeHtml(text) {
return text.replace(/[&"<>]/g, function (m) {
return escapeHtmlReplacements[m];
});
}
function markdown(mdText) {
// TODO implement more
return escapeHtml(mdText);
}
function onSearchKeyDown(ev) {
switch (ev.which) {
case 13:

View File

@ -683,24 +683,57 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty,
zig_unreachable();
}
static void anal_dump_pointer_attrs(AnalDumpCtx *ctx, ZigType *ty) {
JsonWriter *jw = &ctx->jw;
if (ty->data.pointer.explicit_alignment != 0) {
jw_object_field(jw, "align");
jw_int(jw, ty->data.pointer.explicit_alignment);
}
if (ty->data.pointer.is_const) {
jw_object_field(jw, "const");
jw_bool(jw, true);
}
if (ty->data.pointer.is_volatile) {
jw_object_field(jw, "volatile");
jw_bool(jw, true);
}
if (ty->data.pointer.allow_zero) {
jw_object_field(jw, "allowZero");
jw_bool(jw, true);
}
if (ty->data.pointer.host_int_bytes != 0) {
jw_object_field(jw, "hostIntBytes");
jw_int(jw, ty->data.pointer.host_int_bytes);
jw_object_field(jw, "bitOffsetInHost");
jw_int(jw, ty->data.pointer.bit_offset_in_host);
}
jw_object_field(jw, "elem");
anal_dump_type_ref(ctx, ty->data.pointer.child_type);
}
static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
JsonWriter *jw = &ctx->jw;
jw_array_elem(jw);
jw_begin_object(jw);
jw_object_field(jw, "name");
jw_string(jw, buf_ptr(&ty->name));
jw_object_field(jw, "kind");
jw_int(jw, type_id_index(ty));
switch (ty->id) {
case ZigTypeIdMetaType:
break;
case ZigTypeIdStruct: {
if (ty->data.structure.is_slice) {
// TODO
jw_object_field(jw, "len");
jw_int(jw, 2);
anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index].type_entry);
break;
}
jw_object_field(jw, "name");
jw_string(jw, buf_ptr(&ty->name));
{
jw_object_field(jw, "pubDecls");
jw_begin_array(jw);
@ -755,13 +788,61 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
jw_int(jw, ty->data.floating.bit_count);
break;
}
case ZigTypeIdInt: {
if (ty->data.integral.is_signed) {
jw_object_field(jw, "i");
} else {
jw_object_field(jw, "u");
}
jw_int(jw, ty->data.integral.bit_count);
break;
}
case ZigTypeIdFn: {
jw_object_field(jw, "name");
jw_string(jw, buf_ptr(&ty->name));
jw_object_field(jw, "generic");
jw_bool(jw, ty->data.fn.is_generic);
if (ty->data.fn.fn_type_id.return_type != nullptr) {
jw_object_field(jw, "ret");
anal_dump_type_ref(ctx, ty->data.fn.fn_type_id.return_type);
}
if (ty->data.fn.fn_type_id.param_count != 0) {
jw_object_field(jw, "args");
jw_begin_array(jw);
for (size_t i = 0; i < ty->data.fn.fn_type_id.param_count; i += 1) {
jw_array_elem(jw);
if (ty->data.fn.fn_type_id.param_info[i].type != nullptr) {
anal_dump_type_ref(ctx, ty->data.fn.fn_type_id.param_info[i].type);
} else {
jw_null(jw);
}
}
jw_end_array(jw);
}
break;
}
case ZigTypeIdPointer: {
switch (ty->data.pointer.ptr_len) {
case PtrLenSingle:
break;
case PtrLenUnknown:
jw_object_field(jw, "len");
jw_int(jw, 1);
break;
case PtrLenC:
jw_object_field(jw, "len");
jw_int(jw, 3);
break;
}
anal_dump_pointer_attrs(ctx, ty);
break;
}
default:
// TODO
jw_object_field(jw, "name");
jw_string(jw, buf_ptr(&ty->name));
break;
}
jw_end_object(jw);