diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-10-11 04:28:28 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-10-11 04:28:28 -0400 |
| commit | 3e6c49805a003e224b709bfa15d42f3f1081db11 (patch) | |
| tree | a768954471c4d2e3ff185e5d52d44615e3b4d922 | |
| parent | ed91e4409c4605baa58d3ab333d9d093a112212c (diff) | |
Resolve proc groups called with an implicit selector
| -rw-r--r-- | src/server/analysis.odin | 32 | ||||
| -rw-r--r-- | src/server/hover.odin | 2 | ||||
| -rw-r--r-- | tests/hover_test.odin | 26 |
3 files changed, 56 insertions, 4 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 3c896fe..8bc311a 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -747,6 +747,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou arg_symbol: Symbol ok: bool is_call_arg_nil: bool + implicit_selector: ^ast.Implicit_Selector_Expr if _, ok = call_arg.derived.(^ast.Bad_Expr); ok { continue @@ -755,9 +756,13 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou //named parameter if field, is_field := call_arg.derived.(^ast.Field_Value); is_field { named = true - if ident, is_ident := field.field.derived.(^ast.Ident); is_ident && ident.name == "nil" { + if ident, is_ident := field.value.derived.(^ast.Ident); is_ident && ident.name == "nil" { is_call_arg_nil = true ok = true + } else if implicit, is_implicit := field.value.derived.(^ast.Implicit_Selector_Expr); + is_implicit { + implicit_selector = implicit + ok = true } else { call_symbol, ok = resolve_call_arg_type_expression(ast_context, field.value) if !ok { @@ -781,6 +786,10 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou if ident, is_ident := call_arg.derived.(^ast.Ident); is_ident && ident.name == "nil" { is_call_arg_nil = true ok = true + } else if implicit, is_implicit_selector := call_arg.derived.(^ast.Implicit_Selector_Expr); + is_implicit_selector { + implicit_selector = implicit + ok = true } else { call_symbol, ok = resolve_call_arg_type_expression(ast_context, call_arg) } @@ -790,6 +799,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou break next_fn } + if p, ok := call_symbol.value.(SymbolProcedureValue); ok { if len(p.return_types) != 1 { break next_fn @@ -822,6 +832,23 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou break next_fn } + if implicit_selector != nil { + if value, ok := arg_symbol.value.(SymbolEnumValue); ok { + found: bool + for name in value.names { + if implicit_selector.field.name == name { + found = true + break + } + } + if found { + continue + } + + } + break next_fn + } + if is_call_arg_nil { if is_valid_nil_symbol(arg_symbol) { continue @@ -2296,7 +2323,6 @@ resolve_implicit_selector_comp_literal :: proc( resolve_implicit_selector :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, - selector_expr: ^ast.Implicit_Selector_Expr, ) -> ( Symbol, bool, @@ -2787,7 +2813,7 @@ resolve_location_implicit_selector :: proc( set_ast_package_set_scoped(ast_context, ast_context.document_package) - symbol = resolve_implicit_selector(ast_context, position_context, implicit_selector) or_return + symbol = resolve_implicit_selector(ast_context, position_context) or_return #partial switch v in symbol.value { case SymbolEnumValue: diff --git a/src/server/hover.odin b/src/server/hover.odin index 89935ea..20651e4 100644 --- a/src/server/hover.odin +++ b/src/server/hover.odin @@ -373,7 +373,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> } else if position_context.implicit_selector_expr != nil { implicit_selector := position_context.implicit_selector_expr hover.range = common.get_token_range(implicit_selector, document.ast.src) - if symbol, ok := resolve_implicit_selector(&ast_context, &position_context, implicit_selector); ok { + if symbol, ok := resolve_implicit_selector(&ast_context, &position_context); ok { #partial switch v in symbol.value { case SymbolEnumValue: for name, i in v.names { diff --git a/tests/hover_test.odin b/tests/hover_test.odin index cffd779..6461621 100644 --- a/tests/hover_test.odin +++ b/tests/hover_test.odin @@ -5208,6 +5208,32 @@ ast_hover_typeid_with_specialization :: proc(t: ^testing.T) { } test.expect_hover(t, &source, "test.foo :: proc($T: typeid/[]$E)") } + +@(test) +ast_hover_proc_group_with_enum_arg :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: enum { + A, + B, + C, + } + + bar_none :: proc() {} + bar_foo :: proc(foo: Foo) {} + bar :: proc { + bar_none, + bar_foo, + } + + main :: proc() { + b{*}ar(.B) + } + + `, + } + test.expect_hover(t, &source, "test.bar :: proc(foo: Foo)") +} /* Waiting for odin fix |