diff options
| author | moonz <pmnarimani@gmail.com> | 2026-01-26 19:25:58 +0100 |
|---|---|---|
| committer | pc <pmnarimani@gmail.com> | 2026-01-27 00:12:25 +0100 |
| commit | ef82ca514e3740b26dee115be9be2a2554a58f58 (patch) | |
| tree | 98d66a0112c4c776c060e365b9078fffc403cf98 /src/server | |
| parent | 7349330c3ff8dba777ff01dfcf284588c3b01471 (diff) | |
feat: go to resolved proc from a proc overload group when performing go-to-definition
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/definition.odin | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/src/server/definition.odin b/src/server/definition.odin index c793f32..34d1315 100644 --- a/src/server/definition.odin +++ b/src/server/definition.odin @@ -100,6 +100,12 @@ get_definition_location :: proc(document: ^Document, position: common.Position) } if resolved, ok := resolve_location_selector(&ast_context, position_context.selector_expr); ok { + resolved = try_resolve_proc_group_overload( + &ast_context, + &position_context, + resolved, + position_context.selector_expr, + ) location.range = resolved.range uri = resolved.uri } else { @@ -139,12 +145,10 @@ get_definition_location :: proc(document: ^Document, position: common.Position) &ast_context, position_context.identifier.derived.(^ast.Ident)^, ); ok { + resolved = try_resolve_proc_group_overload(&ast_context, &position_context, resolved) if v, ok := resolved.value.(SymbolAggregateValue); ok { for symbol in v.symbols { - append(&locations, common.Location { - range = symbol.range, - uri = symbol.uri, - }) + append(&locations, common.Location{range = symbol.range, uri = symbol.uri}) } } location.range = resolved.range @@ -167,3 +171,84 @@ get_definition_location :: proc(document: ^Document, position: common.Position) return locations[:], true } + + +try_resolve_proc_group_overload :: proc( + ast_context: ^AstContext, + position_context: ^DocumentPositionContext, + symbol: Symbol, + selector_expr: ^ast.Node = nil, +) -> Symbol { + if position_context.call == nil { + return symbol + } + + call, is_call := position_context.call.derived.(^ast.Call_Expr) + if !is_call { + return symbol + } + + if position_in_exprs(call.args, position_context.position) { + return symbol + } + + // For selector expressions, we need to look up the full symbol to check if it's a proc group + full_symbol := symbol + if selector_expr != nil { + if selector, ok := selector_expr.derived.(^ast.Selector_Expr); ok { + if _, is_pkg := symbol.value.(SymbolPackageValue); is_pkg || symbol.value == nil { + if selector.field != nil { + if ident, ok := selector.field.derived.(^ast.Ident); ok { + if pkg_symbol, ok := lookup(ident.name, symbol.pkg, ast_context.fullpath); ok { + full_symbol = pkg_symbol + } + } + } + } + } + } else if position_context.identifier != nil && symbol.value == nil { + // For identifiers (non-selector), the symbol from resolve_location_identifier may not have + // value set (e.g., for globals). We need to do a lookup to get the full symbol. + if ident, ok := position_context.identifier.derived.(^ast.Ident); ok { + pkg := symbol.pkg + if pkg == "" do pkg = ast_context.document_package + + if pkg_symbol, ok := lookup(ident.name, pkg, ast_context.fullpath); ok { + full_symbol = pkg_symbol + } else if global, ok := ast_context.globals[ident.name]; ok { + // If lookup fails (e.g., in tests without full indexing), try checking if it's a proc group + if proc_group, is_proc_group := global.expr.derived.(^ast.Proc_Group); is_proc_group { + full_symbol.value = SymbolProcedureGroupValue { + group = global.expr, + } + } + } + } + } + + proc_group_value, is_proc_group := full_symbol.value.(SymbolProcedureGroupValue) + if !is_proc_group { + return symbol + } + + old_call := ast_context.call + ast_context.call = call + defer { + ast_context.call = old_call + } + + if resolved, ok := resolve_function_overload(ast_context, proc_group_value.group.derived.(^ast.Proc_Group)); ok { + if resolved.name != "" { + if global, ok := ast_context.globals[resolved.name]; ok { + resolved.range = common.get_token_range(global.name_expr, ast_context.file.src) + resolved.uri = common.create_uri(global.name_expr.pos.file, ast_context.allocator).uri + } else if indexed_symbol, ok := lookup(resolved.name, resolved.pkg, ast_context.fullpath); ok { + resolved.range = indexed_symbol.range + resolved.uri = indexed_symbol.uri + } + } + return resolved + } + + return symbol +} |