| ... | ... | @@ -3104,7 +3104,9 @@ fn analyzeAllDecls( |
| 3104 | 3104 | while (it.next()) |d| { |
| 3105 | 3105 | const decl_name_index = file.zir.extra[d.sub_index + 5]; |
| 3106 | 3106 | switch (decl_name_index) { |
| 3107 | | 0, 1, 2 => continue, // skip over usingnamespace decls |
| 3107 | 0, 1 => continue, // skip over usingnamespace decls |
| 3108 | 2 => continue, // skip decltests |
| 3109 | |
| 3108 | 3110 | else => if (file.zir.string_bytes[decl_name_index] == 0) { |
| 3109 | 3111 | continue; |
| 3110 | 3112 | }, |
| ... | ... | @@ -3120,6 +3122,24 @@ fn analyzeAllDecls( |
| 3120 | 3122 | ); |
| 3121 | 3123 | } |
| 3122 | 3124 | |
| 3125 | // Fourth loop to analyze decltests |
| 3126 | it = original_it; |
| 3127 | while (it.next()) |d| { |
| 3128 | const decl_name_index = file.zir.extra[d.sub_index + 5]; |
| 3129 | switch (decl_name_index) { |
| 3130 | 0, 1 => continue, // skip over usingnamespace decls |
| 3131 | 2 => {}, |
| 3132 | else => continue, // skip tests and normal decls |
| 3133 | } |
| 3134 | |
| 3135 | try self.analyzeDecltest( |
| 3136 | file, |
| 3137 | scope, |
| 3138 | parent_src, |
| 3139 | d, |
| 3140 | ); |
| 3141 | } |
| 3142 | |
| 3123 | 3143 | return it.extra_index; |
| 3124 | 3144 | } |
| 3125 | 3145 | |
| ... | ... | @@ -3327,6 +3347,56 @@ fn analyzeUsingnamespaceDecl( |
| 3327 | 3347 | } |
| 3328 | 3348 | } |
| 3329 | 3349 | |
| 3350 | fn analyzeDecltest( |
| 3351 | self: *Autodoc, |
| 3352 | file: *File, |
| 3353 | scope: *Scope, |
| 3354 | parent_src: SrcLocInfo, |
| 3355 | d: Zir.DeclIterator.Item, |
| 3356 | ) AutodocErrors!void { |
| 3357 | const data = file.zir.instructions.items(.data); |
| 3358 | |
| 3359 | const value_index = file.zir.extra[d.sub_index + 6]; |
| 3360 | const decl_name_index = file.zir.extra[d.sub_index + 7]; |
| 3361 | |
| 3362 | // This is known to work because decl values are always block_inlines |
| 3363 | const value_pl_node = data[value_index].pl_node; |
| 3364 | const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src); |
| 3365 | |
| 3366 | const func_index = getBlockInlineBreak(file.zir, value_index).?; |
| 3367 | const pl_node = data[Zir.refToIndex(func_index).?].pl_node; |
| 3368 | const fn_src = try self.srcLocInfo(file, pl_node.src_node, decl_src); |
| 3369 | const tree = try file.getTree(self.comp_module.gpa); |
| 3370 | const test_source_code = tree.getNodeSource(fn_src.src_node); |
| 3371 | |
| 3372 | const decl_name: ?[]const u8 = if (decl_name_index != 0) |
| 3373 | file.zir.nullTerminatedString(decl_name_index) |
| 3374 | else |
| 3375 | null; |
| 3376 | |
| 3377 | // astnode |
| 3378 | const ast_node_index = idx: { |
| 3379 | const idx = self.ast_nodes.items.len; |
| 3380 | try self.ast_nodes.append(self.arena, .{ |
| 3381 | .file = self.files.getIndex(file).?, |
| 3382 | .line = decl_src.line, |
| 3383 | .col = 0, |
| 3384 | .name = decl_name, |
| 3385 | .code = test_source_code, |
| 3386 | }); |
| 3387 | break :idx idx; |
| 3388 | }; |
| 3389 | |
| 3390 | const decl_status = scope.resolveDeclName(decl_name_index, file, 0); |
| 3391 | |
| 3392 | switch (decl_status.*) { |
| 3393 | .Analyzed => |idx| { |
| 3394 | self.decls.items[idx].decltest = ast_node_index; |
| 3395 | }, |
| 3396 | else => unreachable, // we assume analyzeAllDecls analyzed other decls by this point |
| 3397 | } |
| 3398 | } |
| 3399 | |
| 3330 | 3400 | /// An unresolved path has a non-string WalkResult at its beginnig, while every |
| 3331 | 3401 | /// other element is a string WalkResult. Resolving means iteratively map each |
| 3332 | 3402 | /// string to a Decl / Type / Call / etc. |