From ae69dfe6e739b1b2d4ae76923d04bc69c23b07fa Mon Sep 17 00:00:00 2001
From: Krzysztof Wolicki
<46651553+der-teufel-programming@users.noreply.github.com>
Date: Mon, 16 Jan 2023 17:28:07 +0100
Subject: [PATCH] autodoc: Better handling of variable decls (#14301)
---
lib/docs/main.js | 54 +++++++++++++++++++++++++++++++++++++++++-------
src/Autodoc.zig | 41 ++++++++++++++++++++++++++++++------
2 files changed, 82 insertions(+), 13 deletions(-)
diff --git a/lib/docs/main.js b/lib/docs/main.js
index f35a20f57f..253b7c02b4 100644
--- a/lib/docs/main.js
+++ b/lib/docs/main.js
@@ -2250,12 +2250,49 @@ var zigAnalysis;
}
function renderVar(decl) {
- let declTypeRef = typeOfDecl(decl);
- domFnProtoCode.innerHTML =
- 'var ' +
- escapeHtml(decl.name) +
- ": " +
- typeValueName(declTypeRef, true, true);
+ let resolvedVar = resolveValue(decl.value);
+
+ if (resolvedVar.expr.fieldRef) {
+ const declRef = decl.value.expr.refPath[0].declRef;
+ const type = getDecl(declRef);
+ domFnProtoCode.innerHTML =
+ 'var ' +
+ escapeHtml(decl.name) +
+ ": " +
+ type.name +
+ " = " +
+ exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
+ ";";
+ } else if (
+ resolvedVar.expr.string !== undefined ||
+ resolvedVar.expr.call !== undefined ||
+ resolvedVar.expr.comptimeExpr
+ ) {
+ domFnProtoCode.innerHTML =
+ 'var ' +
+ escapeHtml(decl.name) +
+ ": " +
+ exprName(resolvedVar.expr, { wantHtml: true, wantLink: true }) +
+ " = " +
+ exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
+ ";";
+ } else if (resolvedVar.expr.compileError) {
+ domFnProtoCode.innerHTML =
+ 'var ' +
+ escapeHtml(decl.name) +
+ " = " +
+ exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
+ ";";
+ } else {
+ domFnProtoCode.innerHTML =
+ 'var ' +
+ escapeHtml(decl.name) +
+ ": " +
+ exprName(resolvedVar.typeRef, { wantHtml: true, wantLink: true }) +
+ " = " +
+ exprName(decl.value.expr, { wantHtml: true, wantLink: true }) +
+ ";";
+ }
let docs = getAstNode(decl.src).docs;
if (docs != null) {
@@ -2546,7 +2583,10 @@ var zigAnalysis;
tdNameA.setAttribute("href", navLinkDecl(decl.name));
tdNameA.textContent = decl.name;
- tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);
+ tdType.innerHTML = exprName(walkResultTypeRef(decl.value), {
+ wantHtml: true,
+ wantLink: true,
+ });
let docs = getAstNode(decl.src).docs;
if (docs != null) {
diff --git a/src/Autodoc.zig b/src/Autodoc.zig
index fa0b64a929..b368626847 100644
--- a/src/Autodoc.zig
+++ b/src/Autodoc.zig
@@ -2506,16 +2506,25 @@ fn walkInstruction(
};
},
.variable => {
+ const extra = file.zir.extraData(Zir.Inst.ExtendedVar, extended.operand);
+
const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
- var extra_index: usize = extended.operand;
+ var extra_index: usize = extra.end;
if (small.has_lib_name) extra_index += 1;
if (small.has_align) extra_index += 1;
- const value: DocData.WalkResult = if (small.has_init) .{
- .expr = .{ .void = .{} },
- } else .{
- .expr = .{ .void = .{} },
+ const var_type = try self.walkRef(file, parent_scope, parent_src, extra.data.var_type, need_type);
+
+ var value: DocData.WalkResult = .{
+ .typeRef = var_type.expr,
+ .expr = .{ .undefined = .{} },
};
+
+ if (small.has_init) {
+ const var_init_ref = @intToEnum(Ref, file.zir.extra[extra_index]);
+ const var_init = try self.walkRef(file, parent_scope, parent_src, var_init_ref, need_type);
+ value.expr = var_init.expr;
+ }
return value;
},
@@ -3213,13 +3222,15 @@ fn walkDecls(
// .declRef => |d| .{ .declRef = d },
// };
+ const kind: []const u8 = if (try self.declIsVar(file, value_pl_node.src_node, parent_src)) "var" else "const";
+
self.decls.items[decls_slot_index] = .{
._analyzed = true,
.name = name,
.src = ast_node_index,
//.typeRef = decl_type_ref,
.value = walk_result,
- .kind = "const", // find where this information can be found
+ .kind = kind,
};
// Unblock any pending decl path that was waiting for this decl.
@@ -4383,3 +4394,21 @@ fn srcLocInfo(
.src_node = sn,
};
}
+
+fn declIsVar(
+ self: Autodoc,
+ file: *File,
+ src_node: i32,
+ parent_src: SrcLocInfo,
+) !bool {
+ const sn = @intCast(u32, @intCast(i32, parent_src.src_node) + src_node);
+ const tree = try file.getTree(self.module.gpa);
+ const node_idx = @bitCast(Ast.Node.Index, sn);
+ const tokens = tree.nodes.items(.main_token);
+ const tags = tree.tokens.items(.tag);
+
+ const tok_idx = tokens[node_idx];
+
+ // tags[tok_idx] is the token called 'mut token' in AstGen
+ return (tags[tok_idx] == .keyword_var);
+}