mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
autodoc: added basic support for unresolved comptime expressions
This commit is contained in:
parent
ee16eddecf
commit
5d4c88c741
@ -80,7 +80,7 @@
|
||||
var rootIsStd = detectRootIsStd();
|
||||
|
||||
// map of decl index to list of non-generic fn indexes
|
||||
var nodesToFnsMap = indexNodesToFns();
|
||||
// var nodesToFnsMap = indexNodesToFns();
|
||||
// map of decl index to list of comptime fn calls
|
||||
var nodesToCallsMap = indexNodesToCalls();
|
||||
|
||||
@ -160,7 +160,7 @@
|
||||
console.assert(false);
|
||||
}
|
||||
|
||||
function resolveDeclValueTypeId(decl){
|
||||
function typeOfDecl(decl){
|
||||
var i = 0;
|
||||
while(i < 1000) {
|
||||
i += 1;
|
||||
@ -186,7 +186,12 @@
|
||||
return resolveTypeRefToTypeId(decl.value.struct.typeRef);
|
||||
}
|
||||
|
||||
console.log("TODO: handle in `resolveDeclValueTypeId` more cases: ", decl);
|
||||
if ("comptimeExpr" in decl.value) {
|
||||
const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr];
|
||||
return resolveTypeRefToTypeId(cte.typeRef);
|
||||
}
|
||||
|
||||
console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
|
||||
console.assert(false);
|
||||
}
|
||||
console.assert(false);
|
||||
@ -199,7 +204,7 @@
|
||||
}
|
||||
|
||||
if ("declRef" in ref) {
|
||||
return resolveDeclValueTypeId(ref.declRef);
|
||||
return typeOfDecl(ref.declRef);
|
||||
}
|
||||
|
||||
if ("type" in ref) {
|
||||
@ -265,7 +270,11 @@
|
||||
|
||||
var childDeclValue = resolveValue(childDecl.value);
|
||||
if ("type" in childDeclValue) {
|
||||
childDecl = zigAnalysis.types[childDeclValue.type];
|
||||
|
||||
const t = zigAnalysis.types[childDeclValue.type];
|
||||
if (t.kind != typeKinds.Fn) {
|
||||
childDecl = t;
|
||||
}
|
||||
}
|
||||
|
||||
currentType = childDecl;
|
||||
@ -280,21 +289,28 @@
|
||||
var lastIsContainerType = isContainerType(last);
|
||||
|
||||
if (lastIsContainerType) {
|
||||
renderContainer(last);
|
||||
return renderContainer(last);
|
||||
}
|
||||
|
||||
if (!lastIsDecl && !lastIsType) {
|
||||
return renderUnknownDecl(last);
|
||||
} else if (lastIsDecl && last.kind === 'var') {
|
||||
}
|
||||
|
||||
if (lastIsType) {
|
||||
return renderType(last);
|
||||
}
|
||||
|
||||
if (lastIsDecl && last.kind === 'var') {
|
||||
return renderVar(last);
|
||||
} else if (lastIsDecl && last.kind === 'const' && !(declContainsType(last))) {
|
||||
}
|
||||
|
||||
if (lastIsDecl && last.kind === 'const') {
|
||||
var typeObj = zigAnalysis.types[resolveValue(last.value).type];
|
||||
if (typeObj.kind === typeKinds.Fn) {
|
||||
if (typeObj && typeObj.kind === typeKinds.Fn) {
|
||||
return renderFn(last);
|
||||
} else {
|
||||
return renderValue(last);
|
||||
}
|
||||
} else {
|
||||
renderType(last);
|
||||
|
||||
return renderValue(last);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,7 +1118,7 @@
|
||||
|
||||
function renderValue(decl) {
|
||||
|
||||
var declTypeId = resolveDeclValueTypeId(decl);
|
||||
var declTypeId = typeOfDecl(decl);
|
||||
var declValueText = "";
|
||||
switch(Object.keys(decl.value)[0]) {
|
||||
case "int":
|
||||
@ -1111,6 +1127,9 @@
|
||||
case "float":
|
||||
declValueText += decl.value.float.value;
|
||||
break;
|
||||
case "comptimeExpr":
|
||||
declValueText += "[ComptimeExpr]";
|
||||
break;
|
||||
default:
|
||||
console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);
|
||||
declValueText += "#TODO#";
|
||||
@ -1130,7 +1149,7 @@
|
||||
}
|
||||
|
||||
function renderVar(decl) {
|
||||
var declTypeId = resolveDeclValueTypeId(decl);
|
||||
var declTypeId = typeOfDecl(decl);
|
||||
domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +
|
||||
escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true);
|
||||
|
||||
@ -1324,7 +1343,7 @@
|
||||
tdNameA.setAttribute('href', navLinkDecl(decl.name));
|
||||
tdNameA.textContent = decl.name;
|
||||
|
||||
tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);
|
||||
tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
|
||||
|
||||
var docs = zigAnalysis.astNodes[decl.src].docs;
|
||||
if (docs != null) {
|
||||
@ -1351,7 +1370,7 @@
|
||||
tdNameA.setAttribute('href', navLinkDecl(decl.name));
|
||||
tdNameA.textContent = decl.name;
|
||||
|
||||
tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);
|
||||
tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
|
||||
|
||||
var docs = zigAnalysis.astNodes[decl.src].docs;
|
||||
if (docs != null) {
|
||||
@ -2106,19 +2125,7 @@ function renderSearchCursor() {
|
||||
}
|
||||
}
|
||||
|
||||
function indexNodesToFns() {
|
||||
var map = {};
|
||||
for (var i = 0; i < zigAnalysis.fns.length; i += 1) {
|
||||
var fn = zigAnalysis.fns[i];
|
||||
if (typeIsGenericFn(fn.type)) continue;
|
||||
if (map[fn.src] == null) {
|
||||
map[fn.src] = [i];
|
||||
} else {
|
||||
map[fn.src].push(i);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
function indexNodesToCalls() {
|
||||
var map = {};
|
||||
|
||||
@ -12,6 +12,7 @@ arena: std.mem.Allocator,
|
||||
types: std.ArrayListUnmanaged(DocData.Type) = .{},
|
||||
decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
|
||||
ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
|
||||
comptimeExprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},
|
||||
|
||||
var arena_allocator: std.heap.ArenaAllocator = undefined;
|
||||
pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc {
|
||||
@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
|
||||
// append all the types in Zir.Inst.Ref
|
||||
{
|
||||
|
||||
// TODO: we don't want to add .none, but the index math has to check out
|
||||
var i: u32 = 0;
|
||||
try self.types.append(self.arena, .{
|
||||
.ComptimeExpr = .{ .name = "ComptimeExpr" },
|
||||
});
|
||||
// this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr
|
||||
var i: u32 = 1;
|
||||
while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
|
||||
var tmpbuf = std.ArrayList(u8).init(self.arena);
|
||||
try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());
|
||||
@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void {
|
||||
.types = self.types.items,
|
||||
.decls = self.decls.items,
|
||||
.astNodes = self.ast_nodes.items,
|
||||
.comptimeExprs = self.comptimeExprs.items,
|
||||
};
|
||||
|
||||
data.packages[0].main = main_type_index.type;
|
||||
@ -196,7 +200,7 @@ const Scope = struct {
|
||||
};
|
||||
|
||||
const DocData = struct {
|
||||
typeKinds: []const []const u8 = std.meta.fieldNames(std.builtin.TypeId),
|
||||
typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
|
||||
rootPkg: u32 = 0,
|
||||
params: struct {
|
||||
zigId: []const u8 = "arst",
|
||||
@ -208,7 +212,6 @@ const DocData = struct {
|
||||
},
|
||||
} = .{},
|
||||
packages: [1]Package = .{.{}},
|
||||
fns: []struct {} = &.{},
|
||||
errors: []struct {} = &.{},
|
||||
calls: []struct {} = &.{},
|
||||
|
||||
@ -217,11 +220,27 @@ const DocData = struct {
|
||||
files: []const []const u8,
|
||||
types: []Type,
|
||||
decls: []Decl,
|
||||
comptimeExprs: []ComptimeExpr,
|
||||
|
||||
const DocTypeKinds = blk: {
|
||||
var info = @typeInfo(std.builtin.TypeId);
|
||||
info.Enum.fields = info.Enum.fields ++ [1]std.builtin.TypeInfo.EnumField{
|
||||
.{
|
||||
.name = "ComptimeExpr",
|
||||
.value = info.Enum.fields.len,
|
||||
},
|
||||
};
|
||||
break :blk @Type(info);
|
||||
};
|
||||
|
||||
const ComptimeExpr = struct {
|
||||
code: []const u8,
|
||||
typeRef: TypeRef,
|
||||
};
|
||||
const Package = struct {
|
||||
name: []const u8 = "root",
|
||||
file: usize = 0, // index into files
|
||||
main: usize = 0, // index into decls
|
||||
file: usize = 0, // index into `files`
|
||||
main: usize = 0, // index into `decls`
|
||||
table: struct { root: usize } = .{
|
||||
.root = 0,
|
||||
},
|
||||
@ -244,7 +263,7 @@ const DocData = struct {
|
||||
fields: ?[]usize = null, // index into astNodes
|
||||
};
|
||||
|
||||
const Type = union(std.builtin.TypeId) {
|
||||
const Type = union(DocTypeKinds) {
|
||||
Type: struct { name: []const u8 },
|
||||
Void: struct { name: []const u8 },
|
||||
Bool: struct { name: []const u8 },
|
||||
@ -260,6 +279,7 @@ const DocData = struct {
|
||||
pubDecls: ?[]usize = null, // index into decls
|
||||
fields: ?[]TypeRef = null, // (use src->fields to find names)
|
||||
},
|
||||
ComptimeExpr: struct { name: []const u8 },
|
||||
ComptimeFloat: struct { name: []const u8 },
|
||||
ComptimeInt: struct { name: []const u8 },
|
||||
Undefined: struct { name: []const u8 },
|
||||
@ -309,6 +329,7 @@ const DocData = struct {
|
||||
.Array => |v| try printTypeBody(v, options, w),
|
||||
.Bool => |v| try printTypeBody(v, options, w),
|
||||
.Void => |v| try printTypeBody(v, options, w),
|
||||
.ComptimeExpr => |v| try printTypeBody(v, options, w),
|
||||
.ComptimeInt => |v| try printTypeBody(v, options, w),
|
||||
.ComptimeFloat => |v| try printTypeBody(v, options, w),
|
||||
.Null => |v| try printTypeBody(v, options, w),
|
||||
@ -355,6 +376,7 @@ const DocData = struct {
|
||||
unspecified,
|
||||
declRef: usize, // index in `decls`
|
||||
type: usize, // index in `types`
|
||||
comptimeExpr: usize, // index in `comptimeExprs`
|
||||
|
||||
pub fn fromWalkResult(wr: WalkResult) TypeRef {
|
||||
return switch (wr) {
|
||||
@ -376,7 +398,7 @@ const DocData = struct {
|
||||
, .{});
|
||||
},
|
||||
|
||||
.declRef, .type => |v| {
|
||||
.declRef, .type, .comptimeExpr => |v| {
|
||||
try w.print(
|
||||
\\{{ "{s}":{} }}
|
||||
, .{ @tagName(self), v });
|
||||
@ -386,6 +408,7 @@ const DocData = struct {
|
||||
};
|
||||
|
||||
const WalkResult = union(enum) {
|
||||
comptimeExpr: usize, // index in `comptimeExprs`
|
||||
void,
|
||||
@"unreachable",
|
||||
@"null": TypeRef,
|
||||
@ -421,7 +444,7 @@ const DocData = struct {
|
||||
\\{{ "{s}":{{}} }}
|
||||
, .{@tagName(self)});
|
||||
},
|
||||
.type, .declRef => |v| {
|
||||
.type, .declRef, .comptimeExpr => |v| {
|
||||
try w.print(
|
||||
\\{{ "{s}":{} }}
|
||||
, .{ @tagName(self), v });
|
||||
@ -493,6 +516,14 @@ fn walkInstruction(
|
||||
var new_scope = Scope{ .parent = null };
|
||||
return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst);
|
||||
},
|
||||
.block => {
|
||||
const res = DocData.WalkResult{ .comptimeExpr = self.comptimeExprs.items.len };
|
||||
try self.comptimeExprs.append(self.arena, .{
|
||||
.code = "if(banana) 1 else 0",
|
||||
.typeRef = .{ .type = 0 },
|
||||
});
|
||||
return res;
|
||||
},
|
||||
.int => {
|
||||
const int = data[inst_index].int;
|
||||
return DocData.WalkResult{
|
||||
@ -545,7 +576,9 @@ fn walkInstruction(
|
||||
// and we don't want to toss away the
|
||||
// decl_val information (eg by replacing it with
|
||||
// a WalkResult.type).
|
||||
|
||||
.comptimeExpr => {
|
||||
self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
|
||||
},
|
||||
.int => operand.int.typeRef = dest_type_ref,
|
||||
.@"struct" => operand.@"struct".typeRef = dest_type_ref,
|
||||
.@"undefined" => operand.@"undefined" = dest_type_ref,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user