commit 1f4be2a229924cca4e9cd38a146cf2d725557f20
parent 47188ebc5f81c4e4cd7f1b0cf96c37fdbd653ed1
Author: Lou Woell <lou.woell@posteo.de>
Date:   Mon,  6 Oct 2025 22:14:30 +0200

[find_refs] move printing to toplevel

Diffstat:
Mcmd/harehelper/find_refs.ha | 62++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/cmd/harehelper/find_refs.ha b/cmd/harehelper/find_refs.ha @@ -34,6 +34,11 @@ type xref = struct { context: str, }; +type fileref = struct { + path: str, + refs: []xref, +}; + fn finish_xref (ref: *xref) void = { ast::ident_free(ref.name); free(ref.context); @@ -85,18 +90,29 @@ fn find_refs (cmd: getopt::command, ctx: *module::context) void = { defer ast::ident_free(id); const path = path::init(cmd.args[1])!; - scan_tree(ctx, &path, id); + + let res = scan_tree(ctx, &path, id); + + for (let file .. res) { + for (let ref .. file.refs) { + print_ref(ref); + finish_xref(&ref); + }; + free(file.path); + free(file.refs); + }; + free(res); }; -fn scan_tree (ctx: *module::context, path: *path::buffer, id: ast::ident) ([]xref | void) = { +fn scan_tree (ctx: *module::context, path: *path::buffer, id: ast::ident) []fileref = { let mods: []module::module = []; - defer module::free_slice(mods); +defer module::free_slice(mods); let err = module::gather(ctx, &mods, path, false); let err = module::gather_submodules(ctx, &mods, path, false); - let res: []xref = []; + let res: []fileref = []; for (let mod .. mods) { if (mod.is_dep) continue; @@ -106,15 +122,28 @@ fn scan_tree (ctx: *module::context, path: *path::buffer, id: ast::ident) ([]xre // TODO: Move this check into [[scan_file]]. if (ast::ident_eq(ident_ns(id), mod.ns)) id_c = ident_last(id); - for (let s .. mod.srcs.ha) - scan_file(s, id_c, &res); - }; + for (let s &.. mod.srcs.ha) { + + let file_res = match (scan_file(*s, id_c)) { + case void => continue; + case let r: []xref => + yield r; + }; - for (let ref .. res) { - print_ref(ref); - finish_xref(&ref); + // if there's a reference in a file we're taking + // ownership of the path string, because the location + // already borrows it. + if (len(file_res) > 0) { + append(res, fileref { + path = *s, + refs = file_res, + })!; + *s = ""; + }; + }; }; - free(res); + + return res; }; // Returns [[[xref]]] for next identifier in [[hare::lex::lexer]]. Return value @@ -143,7 +172,7 @@ fn next_ref (lex: *lex::lexer) (xref | done | lex::error | parse::error) = { }; }; -fn scan_file (path: str, id: ast::ident, res: *[]xref) (size | void) = { +fn scan_file (path: str, id: ast::ident) ([]xref | void)= { const input = match (os::open(path)) { case let f: io::file => @@ -165,7 +194,7 @@ fn scan_file (path: str, id: ast::ident, res: *[]xref) (size | void) = { let found = false; let id_f: ast::ident = ["", ""]; - for :imps (let i .. imps) { + if (len(id) > 1) for :imps (let i .. imps) { found = ast::ident_eq(ns, i.ident); if (found) { @@ -189,18 +218,15 @@ fn scan_file (path: str, id: ast::ident, res: *[]xref) (size | void) = { }; }; - if (!found && len(id) > 1) return void; - - let s: size = 0; + let res: []xref = []; for (let ref => next_ref(&lexer)!) { if(ast::ident_eq(id_f, ref.name) || ast::ident_eq(id, ref.name)) { ref.context = get_line(lexer.in.src, &ref)!; append(res, ref)!; - s += 1; } else { finish_xref(&ref); }; }; - return s; + return res; };