commit 83e5dced4a175b582ee1cc56fc0479416678f05e
parent c8678714d48058c85a7da33297a03d7fdaea1670
Author: Lou Woell <lou.woell@posteo.de>
Date: Tue, 17 Feb 2026 06:52:54 +0100
[locate] return member location instead of enum location
Diffstat:
2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/cmd/harehelper/+test/locate_test.ha b/cmd/harehelper/+test/locate_test.ha
@@ -43,6 +43,13 @@ fn loc_test_fn (in: str, out: lex::location) void = {
};
};
+type test_enum1 = enum {
+ NONE
+};
+
+type test_enum2 = enum {
+ NONE
+};
let os_loc = lex::location {
path = "os",
@@ -65,6 +72,20 @@ let loc_test_loc = lex::location {
...
};
+let loc_enum1_test_loc = lex::location {
+ path = "locate_test.ha",
+ line = 46,
+ col = 1,
+ ...
+};
+
+let loc_enum2_test_loc = lex::location {
+ path = "locate_test.ha",
+ line = 50,
+ col = 1,
+ ...
+};
+
let locate_loc = lex::location {
path = "locate.ha",
line = 25,
@@ -159,8 +180,45 @@ let fake_loc = lex::location {
loc_test_fn("hare::ast::builtin_type", type_loc);
};
+let glob_non_loc = lex::location {
+ path = "glob.ha",
+ line = 16,
+ col = 9,
+ ...
+};
@test fn locate_enum_member() void = {
- loc_test_fn("hare::ast::builtin_type", type_loc);
+ loc_test_fn("glob::flag::NONE", glob_non_loc);
+};
+
+@test fn locate_enum_member_false() void = {
+ test::expectabort();
+ loc_test_fn("hare::lex::flag::NONE", glob_non_loc);
+};
+
+@test fn locate_local_enum1() void = {
+ loc_test_fn("cmd::harehelper::test_enum1", loc_enum1_test_loc);
+};
+
+@test fn locate_local_enum1_member() void = {
+ loc_enum1_test_loc.line += 1;
+ loc_enum1_test_loc.col = 9;
+ loc_test_fn("cmd::harehelper::test_enum1::NONE", loc_enum1_test_loc);
+};
+
+@test fn locate_local_enum2() void = {
+ loc_test_fn("cmd::harehelper::test_enum2", loc_enum2_test_loc);
+};
+
+@test fn locate_local_enum2_member() void = {
+ loc_enum2_test_loc.line += 1;
+ loc_enum2_test_loc.col = 9;
+ loc_test_fn("cmd::harehelper::test_enum2::NONE", loc_enum2_test_loc);
+};
+
+
+@test fn locate_local_enum_member_false() void = {
+ test::expectabort();
+ loc_test_fn("cmd::harehelper::test_enum2::NONE", loc_enum1_test_loc);
};
@test fn locate_enum_member_nonexisting() void = {
diff --git a/cmd/harehelper/locate.ha b/cmd/harehelper/locate.ha
@@ -143,6 +143,19 @@ fn locate_symbol (
found = ast::ident_eq(decl_name, d.ident);
case let d: ast::decl_type =>
found = ast::ident_eq(decl_name, d.ident);
+ if (found) match (d._type.repr) {
+ case let e: ast::enum_type => for (let v .. e.values) {
+ if (v.name == ident_last(id)[0]) {
+ return lex::location {
+ path = strings::dup(decl.loc.start.path)!,
+ line = v.loc.start.line,
+ col = v.loc.start.col,
+ off = v.loc.start.off,
+ };
+ };
+ };
+ case => void;
+ };
case let d: ast::decl_func =>
found = ast::ident_eq(decl_name, d.ident);
case ast::assert_expr => void;