commit b3f3605b8147b052944563e991d16437f2c45529
parent 8a4b4ecaeadbf90900eac911ea67e1b9e1b7676b
Author: Lou Woell <lou.woell@posteo.de>
Date:   Thu,  9 Oct 2025 18:57:29 +0200

[resolve] more consistent resolution of module names.

Diffstat:
Mcmd/harehelper/+test/resolve_test.ha | 18+++++++++++-------
Mcmd/harehelper/resolve.ha | 31+++++++++++++++++++++----------
2 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/cmd/harehelper/+test/resolve_test.ha b/cmd/harehelper/+test/resolve_test.ha @@ -3,6 +3,7 @@ use fmt; use hare::ast; use hare::module::*; use hare::parse; +use hare::parse::doc; use hare::unparse; use m = math; use memio::{concat, dynamic}; @@ -46,7 +47,6 @@ fn resolve_test_fn (in: str, out: str) void = { }; @test fn resolve_wildcard_module () void = { - test::expectabort(); resolve_test_fn("hare::module", "hare::module"); }; @@ -55,13 +55,19 @@ fn resolve_test_fn (in: str, out: str) void = { }; @test fn resolve_member_module () void = { - test::expectabort(); resolve_test_fn("memio", "memio"); }; +@test fn resolve_module_ns () void = { + resolve_test_fn ("doc", "hare::parse::doc"); +}; + @test fn resolve_module_noimport () void = { - test::expectabort(); - resolve_test_fn("bufio", "bufio"); + resolve_test_fn("bufio", "cmd::harehelper::bufio"); +}; + +@test fn resolve_module_noimport_2 () void = { + resolve_test_fn("hare::lex", "cmd::harehelper::hare::lex"); }; @test fn resolve_module_import () void = { @@ -69,13 +75,11 @@ fn resolve_test_fn (in: str, out: str) void = { }; @test fn resolve_module_fullname_import () void = { - test::expectabort(); resolve_test_fn("hare::parse", "hare::parse"); }; @test fn resolve_symbol_noimport () void = { - test::expectabort(); - resolve_test_fn("bufio::finish", "bufio::finish"); + resolve_test_fn("bufio::finish", "cmd::harehelper::bufio::finish"); }; @test fn resolve_symbol_import () void = { diff --git a/cmd/harehelper/resolve.ha b/cmd/harehelper/resolve.ha @@ -65,7 +65,6 @@ fn resolve_local ( let hp = strings::split(ctx.harepath, ":")!; defer free(hp); - for (let p .. hp) { if (strings::hasprefix(file, p)) { let new_id: ast::ident = []; @@ -122,17 +121,24 @@ fn resolve_uid ( for (let i .. imports) { let ident = i.ident; - let ns = ident_ns(id); + + // If id is the name of an imported module we still want to + // check if that name is shadowed by an import in the namespace. + // In the future this might be a case where we return multiple + // results. + let found_module = ast::ident_eq(ident, id); + let found_import = false; let interned = false; + let ns = ident_ns(id); - match (i.bindings) { + match :binding (i.bindings) { case let a: ast::import_alias => found_import = (ns[0] == a); case let members: ast::import_members => // if len(id) > 1 -> id is not an interned // symbol. - if (len(id) > 1) continue; + if (len(id) > 1) yield :binding; for (let s .. members) { found_import = (s == id[0]); if (found_import) { @@ -141,7 +147,9 @@ fn resolve_uid ( }; }; case ast::import_wildcard => - if (len(id) > 1) continue; + // if len(id) > 1 -> id is not an interned + // symbol. + if (len(id) > 1) yield :binding; let list = list_symbols(ctx, ident); defer idents_finish(list); @@ -158,16 +166,19 @@ fn resolve_uid ( ); }; - if (found_import) { - let id_exp = ast::ident_dup(ident); - if (len(id) > 1 || interned) { + if (found_import || found_module) { + let result = ast::ident_dup(ident); + if (found_import && (len(id) > 1 || interned)) { let end = ident_last(id); let id_end = ast::ident_dup(end); - append(id_exp, id_end[0])!; + append(result, id_end[0])!; }; - return id_exp; + return result; }; }; + // Treat id as a symbol defined in the current namespace. Note that this + // does no verification, i.e. symbols not defined nor imported in the + // current namespace will be misidentified. return resolve_local(ctx, id, path); };