autodoc: reduce json payload size

this commit removes whitespace and changes Decl, AstNode and Type to be
json arrays instead of json objects. This change reduces json payload
size for the stdlib from 25mb to < 10mb.
This commit is contained in:
Loris Cro 2022-09-10 21:08:26 +02:00
parent 81939a4939
commit 2a96f80d03
2 changed files with 309 additions and 80 deletions

View File

@ -203,7 +203,7 @@ var zigAnalysis;
if (!("type" in resolvedExpr)) {
return null;
}
let type = zigAnalysis.types[resolvedExpr.type];
let type = getType(resolvedExpr.type);
outer: for (let i = 0; i < 10000; i += 1) {
switch (type.kind) {
@ -212,7 +212,7 @@ var zigAnalysis;
let child = type.child;
let resolvedChild = resolveValue(child);
if ("type" in resolvedChild) {
type = zigAnalysis.types[resolvedChild.type];
type = getType(resolvedChild.type);
continue;
} else {
return null;
@ -276,7 +276,7 @@ var zigAnalysis;
}
if ("declRef" in value.expr) {
value = zigAnalysis.decls[value.expr.declRef].value;
value = getDecl(value.expr.declRef).value;
continue;
}
@ -430,7 +430,7 @@ var zigAnalysis;
curNav.pkgObjs.push(pkg);
}
let currentType = zigAnalysis.types[pkg.main];
let currentType = getType(pkg.main);
curNav.declObjs = [currentType];
for (let i = 0; i < curNav.declNames.length; i += 1) {
let childDecl = findSubDecl(currentType, curNav.declNames[i]);
@ -440,7 +440,7 @@ var zigAnalysis;
let childDeclValue = resolveValue(childDecl.value).expr;
if ("type" in childDeclValue) {
const t = zigAnalysis.types[childDeclValue.type];
const t = getType(childDeclValue.type);
if (t.kind != typeKinds.Fn) {
childDecl = t;
}
@ -478,7 +478,7 @@ var zigAnalysis;
}
if (lastIsDecl && last.kind === "const") {
let typeObj = zigAnalysis.types[resolveValue(last.value).expr.type];
let typeObj = getType(resolveValue(last.value).expr.type);
if (typeObj && typeObj.kind === typeKinds.Fn) {
return renderFn(last);
}
@ -489,8 +489,8 @@ var zigAnalysis;
}
function renderDocTest(decl) {
if (!("decltest" in decl)) return;
const astNode = zigAnalysis.astNodes[decl.decltest];
if (!decl.decltest) return;
const astNode = getAstNode(decl.decltest);
domSectDocTests.classList.remove("hidden");
domDocTestsCode.innerHTML = astNode.code;
}
@ -498,7 +498,7 @@ var zigAnalysis;
function renderUnknownDecl(decl) {
domDeclNoRef.classList.remove("hidden");
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
domTldDocs.innerHTML = markdown(docs);
} else {
@ -509,18 +509,18 @@ var zigAnalysis;
}
function typeIsErrSet(typeIndex) {
let typeObj = zigAnalysis.types[typeIndex];
let typeObj = getType(typeIndex);
return typeObj.kind === typeKinds.ErrorSet;
}
function typeIsStructWithNoFields(typeIndex) {
let typeObj = zigAnalysis.types[typeIndex];
let typeObj = getType(typeIndex);
if (typeObj.kind !== typeKinds.Struct) return false;
return typeObj.fields.length == 0;
}
function typeIsGenericFn(typeIndex) {
let typeObj = zigAnalysis.types[typeIndex];
let typeObj = getType(typeIndex);
if (typeObj.kind !== typeKinds.Fn) {
return false;
}
@ -532,12 +532,12 @@ var zigAnalysis;
let last = fnDecl.value.expr.refPath.length - 1;
let lastExpr = fnDecl.value.expr.refPath[last];
console.assert("declRef" in lastExpr);
fnDecl = zigAnalysis.decls[lastExpr.declRef];
fnDecl = getDecl(lastExpr.declRef);
}
let value = resolveValue(fnDecl.value);
console.assert("type" in value.expr);
let typeObj = zigAnalysis.types[value.expr.type];
let typeObj = getType(value.expr.type);
domFnProtoCode.innerHTML = exprName(value.expr, {
wantHtml: true,
@ -546,7 +546,7 @@ var zigAnalysis;
});
let docsSource = null;
let srcNode = zigAnalysis.astNodes[fnDecl.src];
let srcNode = getAstNode(fnDecl.src);
if (srcNode.docs != null) {
docsSource = srcNode.docs;
}
@ -557,14 +557,14 @@ var zigAnalysis;
if ("type" in retExpr) {
let retIndex = retExpr.type;
let errSetTypeIndex = null;
let retType = zigAnalysis.types[retIndex];
let retType = getType(retIndex);
if (retType.kind === typeKinds.ErrorSet) {
errSetTypeIndex = retIndex;
} else if (retType.kind === typeKinds.ErrorUnion) {
errSetTypeIndex = retType.err.type;
}
if (errSetTypeIndex != null) {
let errSetType = zigAnalysis.types[errSetTypeIndex];
let errSetType = getType(errSetTypeIndex);
renderErrorSet(errSetType);
}
}
@ -578,7 +578,7 @@ var zigAnalysis;
let call = zigAnalysis.calls[resolvedGenericRet.expr.call];
let resolvedFunc = resolveValue({ expr: call.func });
if (!("type" in resolvedFunc.expr)) return;
let callee = zigAnalysis.types[resolvedFunc.expr.type];
let callee = getType(resolvedFunc.expr.type);
if (!callee.generic_ret) return;
resolvedGenericRet = resolveValue({ expr: callee.generic_ret });
}
@ -591,7 +591,7 @@ var zigAnalysis;
}
if (!("type" in resolvedGenericRet.expr)) return;
const genericType = zigAnalysis.types[resolvedGenericRet.expr.type];
const genericType = getType(resolvedGenericRet.expr.type);
if (isContainerType(genericType)) {
renderContainer(genericType);
}
@ -621,7 +621,7 @@ var zigAnalysis;
domFnNoExamples.classList.add("hidden");
}
let protoSrcNode = zigAnalysis.astNodes[protoSrcIndex];
let protoSrcNode = getAstNode(protoSrcIndex);
if (
docsSource == null &&
protoSrcNode != null &&
@ -639,13 +639,13 @@ var zigAnalysis;
function renderFnParamDocs(fnDecl, typeObj) {
let docCount = 0;
let fnNode = zigAnalysis.astNodes[fnDecl.src];
let fnNode = getAstNode(fnDecl.src);
let fields = fnNode.fields;
let isVarArgs = fnNode.varArgs;
for (let i = 0; i < fields.length; i += 1) {
let field = fields[i];
let fieldNode = zigAnalysis.astNodes[field];
let fieldNode = getAstNode(field);
if (fieldNode.docs != null) {
docCount += 1;
}
@ -659,7 +659,7 @@ var zigAnalysis;
for (let i = 0; i < fields.length; i += 1) {
let field = fields[i];
let fieldNode = zigAnalysis.astNodes[field];
let fieldNode = getAstNode(field);
let docs = fieldNode.docs;
if (fieldNode.docs == null) {
continue;
@ -967,17 +967,17 @@ var zigAnalysis;
}
case "switchOp": {
let condExpr = zigAnalysis.exprs[expr.switchOp.cond_index];
let ast = zigAnalysis.astNodes[expr.switchOp.ast];
let ast = getAstNode(expr.switchOp.src);
let file_name = expr.switchOp.file_name;
let outer_decl_index = expr.switchOp.outer_decl;
let outer_decl = zigAnalysis.types[outer_decl_index];
let outer_decl = getType(outer_decl_index);
let line = 0;
// console.log(expr.switchOp)
// console.log(outer_decl)
while (outer_decl_index !== 0 && outer_decl.line_number > 0) {
line += outer_decl.line_number;
outer_decl_index = outer_decl.outer_decl;
outer_decl = zigAnalysis.types[outer_decl_index];
outer_decl = getType(outer_decl_index);
// console.log(outer_decl)
}
line += ast.line + 1;
@ -1028,8 +1028,8 @@ var zigAnalysis;
case "fieldRef": {
const enumObj = exprName({ type: expr.fieldRef.type }, opts);
const field =
zigAnalysis.astNodes[enumObj.ast].fields[expr.fieldRef.index];
const name = zigAnalysis.astNodes[field].name;
getAstNode(enumObj.src).fields[expr.fieldRef.index];
const name = getAstNode(field).name;
return name;
}
case "enumToInt": {
@ -1452,13 +1452,13 @@ var zigAnalysis;
return print_lhs + " " + operator + " " + print_rhs;
}
case "errorSets": {
const errUnionObj = zigAnalysis.types[expr.errorSets];
const errUnionObj = getType(expr.errorSets);
let lhs = exprName(errUnionObj.lhs, opts);
let rhs = exprName(errUnionObj.rhs, opts);
return lhs + " || " + rhs;
}
case "errorUnion": {
const errUnionObj = zigAnalysis.types[expr.errorUnion];
const errUnionObj = getType(expr.errorUnion);
let lhs = exprName(errUnionObj.lhs, opts);
let rhs = exprName(errUnionObj.rhs, opts);
return lhs + "!" + rhs;
@ -1574,7 +1574,7 @@ var zigAnalysis;
return exprName(exprArg, opts);
}
case "declRef": {
return zigAnalysis.decls[expr.declRef].name;
return getDecl(expr.declRef).name;
}
case "refPath": {
return expr.refPath.map((x) => exprName(x, opts)).join(".");
@ -1611,7 +1611,7 @@ var zigAnalysis;
let name = "";
let typeObj = expr.type;
if (typeof typeObj === "number") typeObj = zigAnalysis.types[typeObj];
if (typeof typeObj === "number") typeObj = getType(typeObj);
switch (typeObj.kind) {
default:
throw "TODO";
@ -1865,7 +1865,7 @@ var zigAnalysis;
if (fnObj.params) {
let fields = null;
let isVarArgs = false;
let fnNode = zigAnalysis.astNodes[fnObj.src];
let fnNode = getAstNode(fnObj.src);
fields = fnNode.fields;
isVarArgs = fnNode.varArgs;
@ -1880,7 +1880,7 @@ var zigAnalysis;
let paramValue = resolveValue({ expr: value });
if (fields != null) {
let paramNode = zigAnalysis.astNodes[fields[i]];
let paramNode = getAstNode(fields[i]);
if (paramNode.varArgs) {
payloadHtml += "...";
@ -2046,7 +2046,7 @@ var zigAnalysis;
function shouldSkipParamName(typeRef, paramName) {
let resolvedTypeRef = resolveValue({ expr: typeRef });
if ("type" in resolvedTypeRef) {
let typeObj = zigAnalysis.types[resolvedTypeRef.type];
let typeObj = getType(resolvedTypeRef.type);
if (typeObj.kind === typeKinds.Pointer) {
let ptrObj = typeObj;
if (getPtrSize(ptrObj) === pointerSizeEnum.One) {
@ -2067,7 +2067,7 @@ var zigAnalysis;
if (
rootIsStd &&
typeObj ===
zigAnalysis.types[zigAnalysis.packages[zigAnalysis.rootPkg].main]
getType(zigAnalysis.packages[zigAnalysis.rootPkg].main)
) {
name = "std";
} else {
@ -2189,7 +2189,7 @@ var zigAnalysis;
if (resolvedValue.expr.fieldRef) {
const declRef = decl.value.expr.refPath[0].declRef;
const type = zigAnalysis.decls[declRef];
const type = getDecl(declRef);
domFnProtoCode.innerHTML =
'<span class="tok-kw">const</span> ' +
escapeHtml(decl.name) +
@ -2229,7 +2229,7 @@ var zigAnalysis;
";";
}
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
domTldDocs.innerHTML = markdown(docs);
domTldDocs.classList.remove("hidden");
@ -2246,7 +2246,7 @@ var zigAnalysis;
": " +
typeValueName(declTypeRef, true, true);
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
domTldDocs.innerHTML = markdown(docs);
domTldDocs.classList.remove("hidden");
@ -2266,7 +2266,7 @@ var zigAnalysis;
testsList
) {
for (let i = 0; i < decls.length; i += 1) {
let decl = zigAnalysis.decls[decls[i]];
let decl = getDecl(decls[i]);
let declValue = resolveValue(decl.value);
if (decl.isTest) {
@ -2282,7 +2282,7 @@ var zigAnalysis;
if (decl.kind === "const") {
if ("type" in declValue.expr) {
// We have the actual type expression at hand.
const typeExpr = zigAnalysis.types[declValue.expr.type];
const typeExpr = getType(declValue.expr.type);
if (typeExpr.kind == typeKinds.Fn) {
const funcRetExpr = resolveValue({
expr: typeExpr.ret,
@ -2310,7 +2310,7 @@ var zigAnalysis;
typesList.push(decl);
}
}
} else if ("typeRef" in declValue) {
} else if (declValue.typeRef) {
if ("type" in declValue.typeRef && declValue.typeRef == typeTypeId) {
// We don't know what the type expression is, but we know it's a type.
typesList.push(decl);
@ -2324,7 +2324,7 @@ var zigAnalysis;
}
}
function renderSourceFileLink(decl) {
let srcNode = zigAnalysis.astNodes[decl.src];
let srcNode = getAstNode(decl.src);
return "<a style=\"float: right;\" href=\"" +
sourceFileUrlTemplate.replace("{{file}}",
@ -2377,7 +2377,7 @@ var zigAnalysis;
testsList.sort(byNameProperty);
if (container.src != null) {
let docs = zigAnalysis.astNodes[container.src].docs;
let docs = getAstNode(container.src).docs;
if (docs != null) {
domTldDocs.innerHTML = markdown(docs);
domTldDocs.classList.remove("hidden");
@ -2457,7 +2457,7 @@ var zigAnalysis;
});
tdFnSrc.innerHTML = renderSourceFileLink(decl);
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
tdDesc.innerHTML = shortDescMarkdown(docs);
} else {
@ -2467,12 +2467,12 @@ var zigAnalysis;
domSectFns.classList.remove("hidden");
}
let containerNode = zigAnalysis.astNodes[container.src];
let containerNode = getAstNode(container.src);
if (containerNode.fields && containerNode.fields.length > 0) {
resizeDomList(domListFields, containerNode.fields.length, "<div></div>");
for (let i = 0; i < containerNode.fields.length; i += 1) {
let fieldNode = zigAnalysis.astNodes[containerNode.fields[i]];
let fieldNode = getAstNode(containerNode.fields[i]);
let divDom = domListFields.children[i];
let fieldName = fieldNode.name;
let docs = fieldNode.docs;
@ -2528,7 +2528,7 @@ var zigAnalysis;
tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
tdDesc.innerHTML = shortDescMarkdown(docs);
} else {
@ -2561,7 +2561,7 @@ var zigAnalysis;
wantLink: true,
});
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
tdDesc.innerHTML = shortDescMarkdown(docs);
} else {
@ -2594,7 +2594,7 @@ var zigAnalysis;
wantLink: true,
});
let docs = zigAnalysis.astNodes[decl.src].docs;
let docs = getAstNode(decl.src).docs;
if (docs != null) {
tdDesc.innerHTML = shortDescMarkdown(docs);
} else {
@ -2668,7 +2668,7 @@ var zigAnalysis;
function findTypeTypeId() {
for (let i = 0; i < zigAnalysis.types.length; i += 1) {
if (zigAnalysis.types[i].kind == typeKinds.Type) {
if (getType(i).kind == typeKinds.Type) {
return i;
}
}
@ -2732,11 +2732,11 @@ var zigAnalysis;
if ("value" in parentType) {
const rv = resolveValue(parentType.value);
if ("type" in rv.expr) {
const t = zigAnalysis.types[rv.expr.type];
const t = getType(rv.expr.type);
if (t.kind == typeKinds.Fn && t.generic_ret != null) {
const rgr = resolveValue({ expr: t.generic_ret });
if ("type" in rgr.expr) {
parentType = zigAnalysis.types[rgr.expr.type];
parentType = getType(rgr.expr.type);
}
}
}
@ -2746,7 +2746,7 @@ var zigAnalysis;
if (!parentType.pubDecls) return null;
for (let i = 0; i < parentType.pubDecls.length; i += 1) {
let declIndex = parentType.pubDecls[i];
let childDecl = zigAnalysis.decls[declIndex];
let childDecl = getDecl(declIndex);
if (childDecl.name === childName) {
return childDecl;
}
@ -2754,7 +2754,7 @@ var zigAnalysis;
if (!parentType.privDecls) return null;
for (let i = 0; i < parentType.privDecls.length; i += 1) {
let declIndex = parentType.privDecls[i];
let childDecl = zigAnalysis.decls[declIndex];
let childDecl = getDecl(declIndex);
if (childDecl.name === childName) {
return childDecl;
}
@ -2805,7 +2805,7 @@ var zigAnalysis;
let stack = [
{
declNames: [],
type: zigAnalysis.types[pkg.main],
type: getType(pkg.main),
},
];
while (stack.length !== 0) {
@ -2819,7 +2819,7 @@ var zigAnalysis;
let mainDeclIndex = t.pubDecls[declI];
if (list[mainDeclIndex] != null) continue;
let decl = zigAnalysis.decls[mainDeclIndex];
let decl = getDecl(mainDeclIndex);
let declVal = resolveValue(decl.value);
let declNames = item.declNames.concat([decl.name]);
list[mainDeclIndex] = {
@ -2827,7 +2827,7 @@ var zigAnalysis;
declNames: declNames,
};
if ("type" in declVal.expr) {
let value = zigAnalysis.types[declVal.expr.type];
let value = getType(declVal.expr.type);
if (declCanRepresentTypeKind(value.kind)) {
canonTypeDecls[declVal.type] = mainDeclIndex;
}
@ -2843,7 +2843,7 @@ var zigAnalysis;
if (value.kind == typeKinds.Fn && value.generic_ret != null) {
let resolvedVal = resolveValue({ expr: value.generic_ret });
if ("type" in resolvedVal.expr) {
let generic_type = zigAnalysis.types[resolvedVal.expr.type];
let generic_type = getType(resolvedVal.expr.type);
if (isContainerType(generic_type)) {
stack.push({
declNames: declNames,
@ -3394,11 +3394,11 @@ var zigAnalysis;
let canonPath = getCanonDeclPath(declIndex);
if (canonPath == null) continue;
let decl = zigAnalysis.decls[declIndex];
let decl = getDecl(declIndex);
let lastPkgName = canonPath.pkgNames[canonPath.pkgNames.length - 1];
let fullPathSearchText =
lastPkgName + "." + canonPath.declNames.join(".");
let astNode = zigAnalysis.astNodes[decl.src];
let astNode = getAstNode(decl.src);
let fileAndDocs = ""; //zigAnalysis.files[astNode.file];
// TODO: understand what this piece of code is trying to achieve
// also right now `files` are expressed as a hashmap.
@ -3513,4 +3513,169 @@ var zigAnalysis;
function byNameProperty(a, b) {
return operatorCompare(a.name, b.name);
}
function getDecl(idx) {
const decl = zigAnalysis.decls[idx];
return {
name: decl[0],
kind: decl[1],
isTest: decl[2],
src: decl[3],
value: decl[4],
decltest: decl[5],
};
}
function getAstNode(idx) {
const ast = zigAnalysis.astNodes[idx];
return {
file: ast[0],
line: ast[1],
col: ast[2],
name: ast[3],
code: ast[4],
docs: ast[5],
fields: ast[6],
comptime: ast[7],
};
}
function getType(idx){
const ty = zigAnalysis.types[idx];
switch(ty[0]) {
default:
throw "unhandled type kind!";
case 0: // Unanalyzed
throw "unanalyzed type!";
case 1: // Type
case 2: // Void
case 3: // Bool
case 4: // NoReturn
case 5: // Int
case 6: // Float
return { kind: ty[0], name: ty[1]};
case 7: // Pointer
return {
kind: ty[0],
size: ty[1],
child: ty[2],
sentinel: ty[3],
align: ty[4],
address_space: ty[5],
bit_start: ty[6],
host_size: ty[7],
is_ref: ty[8],
is_allowzero: ty[9],
is_mutable: ty[10],
is_volatile: ty[11],
has_sentinel: ty[12],
has_align: ty[13],
has_addrspace: ty[14],
has_bit_range: ty[15],
};
case 8: // Array
return {
kind: ty[0],
len: ty[1],
child: ty[2],
sentinel: ty[3],
};
case 9: // Struct
return {
kind: ty[0],
name: ty[1],
src: ty[2],
privDecls: ty[3],
pubDecls: ty[4],
fields: ty[5],
line_number: ty[6],
outer_decl: ty[7],
};
case 10: // ComptimeExpr
case 11: // ComptimeFloat
case 12: // ComptimeInt
case 13: // Undefined
case 14: // Null
return { kind: ty[0], name: ty[1] };
case 15: // Optional
return {
kind: ty[0],
name: ty[1],
child: ty[2],
};
case 16: // ErrorUnion
return {
kind: ty[0],
lhs: ty[1],
rhs: ty[2],
};
case 17: // InferredErrorUnion
return {
kind: ty[0],
payload: ty[1],
};
case 18: // ErrorSet
return {
kind: ty[0],
name: ty[1],
fields: ty[2],
};
case 19: // Enum
return {
kind: ty[0],
name: ty[1],
src: ty[2],
privDecls: ty[3],
pubDecls: ty[4],
};
case 20: // Union
return {
kind: ty[0],
name: ty[1],
src: ty[2],
privDecls: ty[3],
pubDecls: ty[4],
fields: ty[5],
};
case 21: // Fn
return {
kind: ty[0],
name: ty[1],
src: ty[2],
ret: ty[3],
generic_ret: ty[4],
params: ty[5],
lib_name: ty[6],
is_var_args: ty[7],
is_inferred_error: ty[8],
has_lib_name: ty[9],
has_cc: ty[10],
cc: ty[11],
align: ty[12],
has_align: ty[13],
is_test: ty[14],
is_extern: ty[15],
};
case 22: // BoundFn
return { kind: ty[0], name: ty[1] };
case 23: // Opaque
return {
kind: ty[0],
name: ty[1],
src: ty[2],
privDecls: ty[3],
pubDecls: ty[4],
};
case 24: // Frame
case 25: // AnyFrame
case 26: // Vector
case 27: // EnumLiteral
return { kind: ty[0], name: ty[1] };
}
}
})();

View File

@ -280,8 +280,8 @@ pub fn generateZirData(self: *Autodoc) !void {
try std.json.stringify(
data,
.{
.whitespace = .{ .indent = if (builtin.mode == .Debug) .{ .Space = 4 } else .None },
.emit_null_optional_fields = false,
.whitespace = .{ .indent = .None, .separator = false },
.emit_null_optional_fields = true,
},
out,
);
@ -404,6 +404,7 @@ const DocData = struct {
w: anytype,
) !void {
var jsw = std.json.writeStream(w, 15);
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginObject();
inline for (comptime std.meta.tags(std.meta.FieldEnum(DocData))) |f| {
const f_name = @tagName(f);
@ -449,6 +450,8 @@ const DocData = struct {
w: anytype,
) !void {
var jsw = std.json.writeStream(w, 15);
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginObject();
inline for (comptime std.meta.tags(std.meta.FieldEnum(DocPackage))) |f| {
const f_name = @tagName(f);
@ -474,6 +477,22 @@ const DocData = struct {
// The index in astNodes of the `test declname { }` node
decltest: ?usize = null,
_analyzed: bool, // omitted in json data
pub fn jsonStringify(
self: Decl,
opts: std.json.StringifyOptions,
w: anytype,
) !void {
var jsw = std.json.writeStream(w, 15);
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginArray();
inline for (comptime std.meta.fields(Decl)) |f| {
try jsw.arrayElem();
try std.json.stringify(@field(self, f.name), opts, w);
jsw.state_index -= 1;
}
try jsw.endArray();
}
};
const AstNode = struct {
@ -485,6 +504,22 @@ const DocData = struct {
docs: ?[]const u8 = null,
fields: ?[]usize = null, // index into astNodes
@"comptime": bool = false,
pub fn jsonStringify(
self: AstNode,
opts: std.json.StringifyOptions,
w: anytype,
) !void {
var jsw = std.json.writeStream(w, 15);
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginArray();
inline for (comptime std.meta.fields(AstNode)) |f| {
try jsw.arrayElem();
try std.json.stringify(@field(self, f.name), opts, w);
jsw.state_index -= 1;
}
try jsw.endArray();
}
};
const Type = union(enum) {
@ -525,7 +560,6 @@ const DocData = struct {
fields: ?[]Expr = null, // (use src->fields to find names)
line_number: usize,
outer_decl: usize,
ast: usize,
},
ComptimeExpr: struct { name: []const u8 },
ComptimeFloat: struct { name: []const u8 },
@ -548,7 +582,6 @@ const DocData = struct {
src: usize, // index into astNodes
privDecls: []usize = &.{}, // index into decls
pubDecls: []usize = &.{}, // index into decls
ast: usize,
// (use src->fields to find field names)
},
Union: struct {
@ -557,7 +590,6 @@ const DocData = struct {
privDecls: []usize = &.{}, // index into decls
pubDecls: []usize = &.{}, // index into decls
fields: []Expr = &.{}, // (use src->fields to find names)
ast: usize,
},
Fn: struct {
name: []const u8,
@ -582,7 +614,6 @@ const DocData = struct {
src: usize, // index into astNodes
privDecls: []usize = &.{}, // index into decls
pubDecls: []usize = &.{}, // index into decls
ast: usize,
},
Frame: struct { name: []const u8 },
AnyFrame: struct { name: []const u8 },
@ -601,14 +632,15 @@ const DocData = struct {
) !void {
const active_tag = std.meta.activeTag(self);
var jsw = std.json.writeStream(w, 15);
try jsw.beginObject();
try jsw.objectField("kind");
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginArray();
try jsw.arrayElem();
try jsw.emitNumber(@enumToInt(active_tag));
inline for (comptime std.meta.fields(Type)) |case| {
if (@field(Type, case.name) == active_tag) {
const current_value = @field(self, case.name);
inline for (comptime std.meta.fields(case.field_type)) |f| {
try jsw.objectField(f.name);
try jsw.arrayElem();
if (f.field_type == std.builtin.TypeInfo.Pointer.Size) {
try jsw.emitNumber(@enumToInt(@field(current_value, f.name)));
} else {
@ -618,7 +650,7 @@ const DocData = struct {
}
}
}
try jsw.endObject();
try jsw.endArray();
}
};
@ -686,7 +718,7 @@ const DocData = struct {
const SwitchOp = struct {
cond_index: usize,
file_name: []const u8,
ast: usize,
src: usize,
outer_decl: usize, // index in `types`
};
const BuiltinBin = struct {
@ -704,7 +736,15 @@ const DocData = struct {
end: ?usize = null,
sentinel: ?usize = null, // index in `exprs`
};
const Cmpxchg = struct { name: []const u8, type: usize, ptr: usize, expected_value: usize, new_value: usize, success_order: usize, failure_order: usize };
const Cmpxchg = struct {
name: []const u8,
type: usize,
ptr: usize,
expected_value: usize,
new_value: usize,
success_order: usize,
failure_order: usize,
};
const As = struct {
typeRefArg: ?usize, // index in `exprs`
exprArg: usize, // index in `exprs`
@ -721,11 +761,12 @@ const DocData = struct {
pub fn jsonStringify(
self: Expr,
opt: std.json.StringifyOptions,
opts: std.json.StringifyOptions,
w: anytype,
) !void {
const active_tag = std.meta.activeTag(self);
var jsw = std.json.writeStream(w, 15);
if (opts.whitespace) |ws| jsw.whitespace = ws;
try jsw.beginObject();
try jsw.objectField(@tagName(active_tag));
switch (self) {
@ -742,7 +783,7 @@ const DocData = struct {
if (comptime std.mem.eql(u8, case.name, "builtinField"))
continue;
if (@field(Expr, case.name) == active_tag) {
try std.json.stringify(@field(self, case.name), opt, w);
try std.json.stringify(@field(self, case.name), opts, w);
jsw.state_index -= 1;
// TODO: we should not reach into the state of the
// json writer, but alas, this is what's
@ -1874,7 +1915,12 @@ fn walkInstruction(
// log.debug("{s}", .{sep});
const switch_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .switchOp = .{ .cond_index = cond_index, .file_name = file.sub_file_path, .ast = ast_index, .outer_decl = type_index } });
try self.exprs.append(self.arena, .{ .switchOp = .{
.cond_index = cond_index,
.file_name = file.sub_file_path,
.src = ast_index,
.outer_decl = type_index,
} });
return DocData.WalkResult{
.typeRef = .{ .type = @enumToInt(Ref.type_type) },
@ -2505,7 +2551,6 @@ fn walkInstruction(
.src = self_ast_node_index,
.privDecls = priv_decl_indexes.items,
.pubDecls = decl_indexes.items,
.ast = self_ast_node_index,
},
};
if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
@ -2644,7 +2689,13 @@ fn walkInstruction(
self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
self.types.items[type_slot_index] = .{
.Union = .{ .name = "todo_name", .src = self_ast_node_index, .privDecls = priv_decl_indexes.items, .pubDecls = decl_indexes.items, .fields = field_type_refs.items, .ast = self_ast_node_index },
.Union = .{
.name = "todo_name",
.src = self_ast_node_index,
.privDecls = priv_decl_indexes.items,
.pubDecls = decl_indexes.items,
.fields = field_type_refs.items,
},
};
if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
@ -2796,7 +2847,12 @@ fn walkInstruction(
self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
self.types.items[type_slot_index] = .{
.Enum = .{ .name = "todo_name", .src = self_ast_node_index, .privDecls = priv_decl_indexes.items, .pubDecls = decl_indexes.items, .ast = self_ast_node_index },
.Enum = .{
.name = "todo_name",
.src = self_ast_node_index,
.privDecls = priv_decl_indexes.items,
.pubDecls = decl_indexes.items,
},
};
if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
for (paths.items) |resume_info| {
@ -2910,7 +2966,15 @@ fn walkInstruction(
self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
self.types.items[type_slot_index] = .{
.Struct = .{ .name = "todo_name", .src = self_ast_node_index, .privDecls = priv_decl_indexes.items, .pubDecls = decl_indexes.items, .fields = field_type_refs.items, .line_number = self.ast_nodes.items[self_ast_node_index].line, .outer_decl = type_slot_index - 1, .ast = self_ast_node_index },
.Struct = .{
.name = "todo_name",
.src = self_ast_node_index,
.privDecls = priv_decl_indexes.items,
.pubDecls = decl_indexes.items,
.fields = field_type_refs.items,
.line_number = self.ast_nodes.items[self_ast_node_index].line,
.outer_decl = type_slot_index - 1,
},
};
if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
for (paths.items) |resume_info| {