mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
autodoc: add support for anytype and improve semantics for array length
This commit is contained in:
parent
d745dde54f
commit
ec7f4d1faa
179
lib/docs/main.js
179
lib/docs/main.js
@ -187,7 +187,7 @@
|
||||
i += 1;
|
||||
console.assert(isDecl(decl));
|
||||
if ("type" in decl.value) {
|
||||
return typeTypeId;
|
||||
return { type: typeTypeId };
|
||||
}
|
||||
|
||||
if ("declPath" in decl.value) {
|
||||
@ -232,6 +232,10 @@
|
||||
return fn_type.ret;
|
||||
}
|
||||
|
||||
if ("void" in decl.value) {
|
||||
return { type: typeTypeId };
|
||||
}
|
||||
|
||||
console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
|
||||
console.assert(false);
|
||||
throw {};
|
||||
@ -472,22 +476,9 @@
|
||||
var html = '<pre>' + escapeHtml(fieldNode.name) + ": ";
|
||||
if (isVarArgs && i === typeObj.params.length - 1) {
|
||||
html += '...';
|
||||
} else if ("declRef" in value) {
|
||||
var decl = zigAnalysis.decls[value.declRef];
|
||||
var val = resolveValue(decl.value);
|
||||
var valType = zigAnalysis.types[argTypeIndex];
|
||||
|
||||
var valTypeName = typeShorthandName(valType);
|
||||
|
||||
html += '<a href="'+navLinkDecl(decl.name)+'">';
|
||||
html += '<span class="tok-kw" style="color:lightblue;">' + escapeHtml(decl.name) + '</span>';
|
||||
html += '</a>';
|
||||
html += ' ('+ valTypeName +')';
|
||||
} else if ("type" in value) {
|
||||
var name = zigAnalysis.types[value.type].name;
|
||||
html += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
|
||||
} else {
|
||||
html += '<span class="tok-kw">var</span>';
|
||||
var name = typeValueName(value);
|
||||
html += '<span class="tok-kw">' + name + '</span>';
|
||||
}
|
||||
|
||||
html += ',</pre>';
|
||||
@ -657,24 +648,52 @@
|
||||
}
|
||||
|
||||
function typeValueName(typeValue, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
|
||||
|
||||
if ("int" in typeValue) {
|
||||
return typeValue.int.value;
|
||||
}
|
||||
if ("call" in typeValue) {
|
||||
var result = "";
|
||||
var call = zigAnalysis.calls[typeValue.call];
|
||||
var functionName = typeValueName(call.func);
|
||||
result += functionName + "(";
|
||||
for (var j = 0; j < call.args.length; j += 1) {
|
||||
result += typeValueName(call.args[j]);
|
||||
if (j != call.args.length -1) result += ",";
|
||||
}
|
||||
|
||||
return result + ")";
|
||||
}
|
||||
if ("comptimeExpr" in typeValue) {
|
||||
return "[ComptimeExpr]";
|
||||
}
|
||||
if ("declPath" in typeValue) {
|
||||
if (typeValue.hasCte) {
|
||||
// TODO: find the cte, print it nicely
|
||||
if (wantLink) {
|
||||
return '<a href="">[ComptimeExpr]</a>';
|
||||
} else {
|
||||
return "[ComptimeExpr]";
|
||||
}
|
||||
}
|
||||
var declIndex = typeValue.declPath[0];
|
||||
var name = zigAnalysis.decls[declIndex].name;
|
||||
var declPath = getCanonDeclPath(declIndex);
|
||||
if (wantLink) {
|
||||
var nl = navLink(declPath.pkgNames, declPath.declNames);
|
||||
return '<a href="' + nl + '">' + name + '</a>';
|
||||
} else {
|
||||
return name;
|
||||
var result = "";
|
||||
for (var j = typeValue.declPath.length - 1; j >= 0; j--) {
|
||||
var decl = zigAnalysis.decls[typeValue.declPath[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);
|
||||
if (wantHtml) {
|
||||
result += '<a href="'+navLinkDecl(decl.name)+'">';
|
||||
result += '<span class="tok-kw" style="color:lightblue;">' +
|
||||
name + '</span>';
|
||||
result += '</a>';
|
||||
} else {
|
||||
result += name;
|
||||
}
|
||||
|
||||
if (j != 0) result += ".";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
console.assert("type" in typeValue)
|
||||
@ -760,10 +779,11 @@
|
||||
switch (typeObj.kind) {
|
||||
case typeKinds.Array:
|
||||
var name = "[";
|
||||
var lenName = typeValueName(typeObj.len, wantHtml);
|
||||
if (wantHtml) {
|
||||
name += '<span class="tok-number">' + typeObj.len + '</span>';
|
||||
name += '<span class="tok-number">' + lenName + '</span>';
|
||||
} else {
|
||||
name += typeObj.len;
|
||||
name += lenName;
|
||||
}
|
||||
name += "]";
|
||||
name += typeValueName(typeObj.child, wantHtml, wantSubLink, null);
|
||||
@ -986,12 +1006,16 @@
|
||||
} else {
|
||||
var decl = zigAnalysis.decls[value.declPath[0]];
|
||||
var val = resolveValue(decl.value);
|
||||
var valType = zigAnalysis.types[argTypeIndex];
|
||||
|
||||
var valTypeName = typeShorthandName(valType);
|
||||
payloadHtml += '<a href="'+navLinkDecl(decl.name)+'">';
|
||||
payloadHtml += '<span class="tok-kw" style="color:lightblue;">' + escapeHtml(decl.name) + '</span>';
|
||||
payloadHtml += '</a>';
|
||||
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 ("type" in value) {
|
||||
var name = typeValueName(value, false);
|
||||
@ -1258,6 +1282,43 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
errSetsList.sort(byNameProperty);
|
||||
@ -1349,35 +1410,9 @@
|
||||
html += ": ";
|
||||
if (field.failure === true) {
|
||||
html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
|
||||
} else if ("declPath" in field) {
|
||||
for (var j = field.declPath.length - 1; j >= 0; j--) {
|
||||
var decl = zigAnalysis.decls[field.declPath[j]];
|
||||
|
||||
// TODO: handle nested decl paths properly!
|
||||
if (field.hasCte) {
|
||||
html += "<a href=\"\">[ComptimeExpr]</a>";
|
||||
break;
|
||||
}
|
||||
|
||||
html += '<a href="'+navLinkDecl(decl.name)+'">';
|
||||
html += '<span class="tok-kw" style="color:lightblue;">' +
|
||||
escapeHtml(decl.name) + '</span>';
|
||||
html += '</a>';
|
||||
if (j != 0) html += ".";
|
||||
}
|
||||
// at the end of the for loop this is the value of `decl`
|
||||
//decl = zigAnalysis.decls[field.declPath[0]];
|
||||
|
||||
var val = resolveValue(decl.value);
|
||||
console.assert("type" in val);
|
||||
var valType = zigAnalysis.types[val.type];
|
||||
var valTypeName = typeShorthandName(valType);
|
||||
html += ' ('+ valTypeName +')';
|
||||
} else if ("type" in field) {
|
||||
var name = zigAnalysis.types[field.type].name;
|
||||
html += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
|
||||
} else {
|
||||
html += '<span class="tok-kw">var</span>';
|
||||
var name = typeValueName(field);
|
||||
html += '<span class="tok-kw">'+ name +'</span>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1544,6 +1579,14 @@
|
||||
return childDecl;
|
||||
}
|
||||
}
|
||||
if (!parentType.privDecls) return null;
|
||||
for (var i = 0; i < parentType.privDecls.length; i += 1) {
|
||||
var declIndex = parentType.privDecls[i];
|
||||
var childDecl = zigAnalysis.decls[declIndex];
|
||||
if (childDecl.name === childName) {
|
||||
return childDecl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +92,15 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
// instead of just assinging "array" to them.
|
||||
break :blk .{
|
||||
.Array = .{
|
||||
.len = 1,
|
||||
.len = .{
|
||||
.int = .{
|
||||
.typeRef = .{
|
||||
.type = @enumToInt(Ref.usize_type),
|
||||
},
|
||||
.value = 1,
|
||||
.negated = false,
|
||||
},
|
||||
},
|
||||
.child = .{ .type = 0 },
|
||||
},
|
||||
};
|
||||
@ -374,7 +382,7 @@ const DocData = struct {
|
||||
child: TypeRef,
|
||||
},
|
||||
Array: struct {
|
||||
len: usize,
|
||||
len: WalkResult,
|
||||
child: TypeRef,
|
||||
},
|
||||
Struct: struct {
|
||||
@ -516,6 +524,7 @@ const DocData = struct {
|
||||
/// An example of indidirectness is `const bar = foo;`.
|
||||
const TypeRef = union(enum) {
|
||||
unspecified,
|
||||
@"anytype",
|
||||
declPath: DeclPath,
|
||||
type: usize, // index in `types`
|
||||
comptimeExpr: usize, // index in `comptimeExprs`
|
||||
@ -530,10 +539,10 @@ const DocData = struct {
|
||||
w: anytype,
|
||||
) !void {
|
||||
switch (self) {
|
||||
.unspecified => {
|
||||
.unspecified, .@"anytype" => {
|
||||
try w.print(
|
||||
\\{{ "unspecified":{{}} }}
|
||||
, .{});
|
||||
\\{{ "{s}":{{}} }}
|
||||
, .{@tagName(self)});
|
||||
},
|
||||
|
||||
.type, .comptimeExpr, .call => |v| {
|
||||
@ -566,6 +575,7 @@ const DocData = struct {
|
||||
@"undefined": TypeRef,
|
||||
@"struct": Struct,
|
||||
bool: bool,
|
||||
@"anytype",
|
||||
type: usize, // index in `types`
|
||||
declPath: DeclPath,
|
||||
int: struct {
|
||||
@ -600,7 +610,7 @@ const DocData = struct {
|
||||
w: anytype,
|
||||
) !void {
|
||||
switch (self) {
|
||||
.void, .@"unreachable" => {
|
||||
.void, .@"unreachable", .@"anytype" => {
|
||||
try w.print(
|
||||
\\{{ "{s}":{{}} }}
|
||||
, .{@tagName(self)});
|
||||
@ -755,6 +765,13 @@ fn walkInstruction(
|
||||
},
|
||||
};
|
||||
},
|
||||
.error_union_type => {
|
||||
const pl_node = data[inst_index].pl_node;
|
||||
const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);
|
||||
|
||||
// TODO: return the actual error union instread of cheating
|
||||
return self.walkRef(file, parent_scope, extra.data.rhs);
|
||||
},
|
||||
.ptr_type_simple => {
|
||||
const ptr = data[inst_index].ptr_type_simple;
|
||||
const type_slot_index = self.types.items.len;
|
||||
@ -768,6 +785,20 @@ fn walkInstruction(
|
||||
|
||||
return DocData.WalkResult{ .type = type_slot_index };
|
||||
},
|
||||
.array_type => {
|
||||
const bin = data[inst_index].bin;
|
||||
const len = try self.walkRef(file, parent_scope, bin.lhs);
|
||||
const child = walkResultToTypeRef(try self.walkRef(file, parent_scope, bin.rhs));
|
||||
|
||||
const type_slot_index = self.types.items.len;
|
||||
try self.types.append(self.arena, .{
|
||||
.Array = .{
|
||||
.len = len,
|
||||
.child = child,
|
||||
},
|
||||
});
|
||||
return DocData.WalkResult{ .type = type_slot_index };
|
||||
},
|
||||
.array_init => {
|
||||
const pl_node = data[inst_index].pl_node;
|
||||
const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
|
||||
@ -780,7 +811,13 @@ fn walkInstruction(
|
||||
const type_slot_index = self.types.items.len;
|
||||
try self.types.append(self.arena, .{
|
||||
.Array = .{
|
||||
.len = operands.len,
|
||||
.len = .{
|
||||
.int = .{
|
||||
.typeRef = .{ .type = @enumToInt(Ref.usize_type) },
|
||||
.value = operands.len,
|
||||
.negated = false,
|
||||
},
|
||||
},
|
||||
.child = typeOfWalkResult(array_data[0]),
|
||||
},
|
||||
});
|
||||
@ -1017,6 +1054,23 @@ fn walkInstruction(
|
||||
.{@tagName(tags[param_index])},
|
||||
);
|
||||
},
|
||||
.param_anytype => {
|
||||
// TODO: where are the doc comments?
|
||||
const str_tok = data[param_index].str_tok;
|
||||
|
||||
const name = str_tok.get(file.zir);
|
||||
|
||||
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
||||
self.ast_nodes.appendAssumeCapacity(.{
|
||||
.name = name,
|
||||
.docs = "",
|
||||
.@"comptime" = true,
|
||||
});
|
||||
|
||||
param_type_refs.appendAssumeCapacity(
|
||||
DocData.TypeRef{ .@"anytype" = {} },
|
||||
);
|
||||
},
|
||||
.param, .param_comptime => {
|
||||
const pl_tok = data[param_index].pl_tok;
|
||||
const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
|
||||
@ -1024,10 +1078,11 @@ fn walkInstruction(
|
||||
file.zir.nullTerminatedString(extra.data.doc_comment)
|
||||
else
|
||||
"";
|
||||
const name = file.zir.nullTerminatedString(extra.data.name);
|
||||
|
||||
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
||||
self.ast_nodes.appendAssumeCapacity(.{
|
||||
.name = file.zir.nullTerminatedString(extra.data.name),
|
||||
.name = name,
|
||||
.docs = doc_comment,
|
||||
.@"comptime" = tags[param_index] == .param_comptime,
|
||||
});
|
||||
@ -1094,6 +1149,18 @@ fn walkInstruction(
|
||||
.{@tagName(extended.opcode)},
|
||||
);
|
||||
},
|
||||
.variable => {
|
||||
const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
|
||||
var extra_index: usize = extended.operand;
|
||||
if (small.has_lib_name) extra_index += 1;
|
||||
if (small.has_align) extra_index += 1;
|
||||
|
||||
const value: DocData.WalkResult =
|
||||
if (small.has_init)
|
||||
.{ .void = {} } else .{ .void = {} };
|
||||
|
||||
return value;
|
||||
},
|
||||
.union_decl => {
|
||||
var scope: Scope = .{
|
||||
.parent = parent_scope,
|
||||
@ -1887,7 +1954,7 @@ fn collectUnionFieldInfo(
|
||||
@intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index])
|
||||
else
|
||||
.void_type;
|
||||
extra_index += 1;
|
||||
if (has_type) extra_index += 1;
|
||||
|
||||
if (has_align) extra_index += 1;
|
||||
if (has_tag) extra_index += 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user