mirror of
https://github.com/ziglang/zig.git
synced 2026-02-03 13:13:40 +00:00
Merge pull request #15478 from der-teufel-programming/autodoc-decltests
autodoc: Gather and display decltests
This commit is contained in:
commit
13aaa16ab2
@ -563,12 +563,14 @@ const NAV_MODES = {
|
||||
|
||||
let currentType = getType(mod.main);
|
||||
curNav.declObjs = [currentType];
|
||||
let lastDecl = mod.main;
|
||||
for (let i = 0; i < curNav.declNames.length; i += 1) {
|
||||
let childDecl = findSubDecl(currentType, curNav.declNames[i]);
|
||||
window.last_decl = childDecl;
|
||||
if (childDecl == null) {
|
||||
return render404();
|
||||
}
|
||||
lastDecl = childDecl;
|
||||
|
||||
let childDeclValue = resolveValue(childDecl.value).expr;
|
||||
if ("type" in childDeclValue) {
|
||||
@ -593,9 +595,7 @@ const NAV_MODES = {
|
||||
let lastIsType = isType(last);
|
||||
let lastIsContainerType = isContainerType(last);
|
||||
|
||||
if (lastIsDecl) {
|
||||
renderDocTest(last);
|
||||
}
|
||||
renderDocTest(lastDecl);
|
||||
|
||||
if (lastIsContainerType) {
|
||||
return renderContainer(last);
|
||||
@ -642,7 +642,25 @@ const NAV_MODES = {
|
||||
if (!decl.decltest) return;
|
||||
const astNode = getAstNode(decl.decltest);
|
||||
domSectDocTests.classList.remove("hidden");
|
||||
domDocTestsCode.innerHTML = astNode.code;
|
||||
domDocTestsCode.innerHTML = renderZigSource(astNode.code);
|
||||
}
|
||||
|
||||
function renderZigSource(code) {
|
||||
let lines = code.split("\n");
|
||||
let result = "";
|
||||
let indent_level = 0;
|
||||
for(let i = 0; i < lines.length; i += 1) {
|
||||
let line = lines[i].trim();
|
||||
if(line[0] == "}") indent_level -= 1;
|
||||
for(let j = 0; j < indent_level; j += 1) {
|
||||
result += " ";
|
||||
}
|
||||
if (line.startsWith("\\\\")) result += " "
|
||||
result += line;
|
||||
result += "\n";
|
||||
if(line[line.length - 1] == "{") indent_level += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function renderUnknownDecl(decl) {
|
||||
|
||||
@ -3104,7 +3104,9 @@ fn analyzeAllDecls(
|
||||
while (it.next()) |d| {
|
||||
const decl_name_index = file.zir.extra[d.sub_index + 5];
|
||||
switch (decl_name_index) {
|
||||
0, 1, 2 => continue, // skip over usingnamespace decls
|
||||
0, 1 => continue, // skip over usingnamespace decls
|
||||
2 => continue, // skip decltests
|
||||
|
||||
else => if (file.zir.string_bytes[decl_name_index] == 0) {
|
||||
continue;
|
||||
},
|
||||
@ -3120,6 +3122,24 @@ fn analyzeAllDecls(
|
||||
);
|
||||
}
|
||||
|
||||
// Fourth loop to analyze decltests
|
||||
it = original_it;
|
||||
while (it.next()) |d| {
|
||||
const decl_name_index = file.zir.extra[d.sub_index + 5];
|
||||
switch (decl_name_index) {
|
||||
0, 1 => continue, // skip over usingnamespace decls
|
||||
2 => {},
|
||||
else => continue, // skip tests and normal decls
|
||||
}
|
||||
|
||||
try self.analyzeDecltest(
|
||||
file,
|
||||
scope,
|
||||
parent_src,
|
||||
d,
|
||||
);
|
||||
}
|
||||
|
||||
return it.extra_index;
|
||||
}
|
||||
|
||||
@ -3327,6 +3347,56 @@ fn analyzeUsingnamespaceDecl(
|
||||
}
|
||||
}
|
||||
|
||||
fn analyzeDecltest(
|
||||
self: *Autodoc,
|
||||
file: *File,
|
||||
scope: *Scope,
|
||||
parent_src: SrcLocInfo,
|
||||
d: Zir.DeclIterator.Item,
|
||||
) AutodocErrors!void {
|
||||
const data = file.zir.instructions.items(.data);
|
||||
|
||||
const value_index = file.zir.extra[d.sub_index + 6];
|
||||
const decl_name_index = file.zir.extra[d.sub_index + 7];
|
||||
|
||||
// This is known to work because decl values are always block_inlines
|
||||
const value_pl_node = data[value_index].pl_node;
|
||||
const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
|
||||
|
||||
const func_index = getBlockInlineBreak(file.zir, value_index).?;
|
||||
const pl_node = data[Zir.refToIndex(func_index).?].pl_node;
|
||||
const fn_src = try self.srcLocInfo(file, pl_node.src_node, decl_src);
|
||||
const tree = try file.getTree(self.comp_module.gpa);
|
||||
const test_source_code = tree.getNodeSource(fn_src.src_node);
|
||||
|
||||
const decl_name: ?[]const u8 = if (decl_name_index != 0)
|
||||
file.zir.nullTerminatedString(decl_name_index)
|
||||
else
|
||||
null;
|
||||
|
||||
// astnode
|
||||
const ast_node_index = idx: {
|
||||
const idx = self.ast_nodes.items.len;
|
||||
try self.ast_nodes.append(self.arena, .{
|
||||
.file = self.files.getIndex(file).?,
|
||||
.line = decl_src.line,
|
||||
.col = 0,
|
||||
.name = decl_name,
|
||||
.code = test_source_code,
|
||||
});
|
||||
break :idx idx;
|
||||
};
|
||||
|
||||
const decl_status = scope.resolveDeclName(decl_name_index, file, 0);
|
||||
|
||||
switch (decl_status.*) {
|
||||
.Analyzed => |idx| {
|
||||
self.decls.items[idx].decltest = ast_node_index;
|
||||
},
|
||||
else => unreachable, // we assume analyzeAllDecls analyzed other decls by this point
|
||||
}
|
||||
}
|
||||
|
||||
/// An unresolved path has a non-string WalkResult at its beginnig, while every
|
||||
/// other element is a string WalkResult. Resolving means iteratively map each
|
||||
/// string to a Decl / Type / Call / etc.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user