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