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); +}