aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-15 14:00:14 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-15 14:00:14 -0400
commit964fc14656d3698a9a4e69afaf31da538184a213 (patch)
tree1b9d2a115ac6be773c0ffa72074aac28d68e9006
parent9608768c31b81c0fc8681df6c6b1872396b529a0 (diff)
Add go to type definition for named proc params
-rw-r--r--src/server/analysis.odin22
-rw-r--r--src/server/type_definition.odin66
-rw-r--r--tests/type_definition_test.odin24
3 files changed, 84 insertions, 28 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 170b477..295c4b6 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2257,6 +2257,28 @@ resolve_type_location_proc_param_name :: proc(
return call_symbol, false
}
+// resolves the underlying location of type of the named param
+resolve_location_proc_param_name_type :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ call_symbol: Symbol,
+ ok: bool,
+) {
+ ident := position_context.field_value.field.derived.(^ast.Ident) or_return
+ call := position_context.call.derived.(^ast.Call_Expr) or_return
+ call_symbol = resolve_type_expression(ast_context, call) or_return
+
+ if value, ok := call_symbol.value.(SymbolProcedureValue); ok {
+ if arg_type, ok := get_proc_arg_type_from_name(value, ident.name); ok {
+ if symbol, ok := resolve_location_type_expression(ast_context, arg_type.type); ok {
+ return symbol, true
+ }
+ }
+ }
+ return call_symbol, false
+}
+
resolve_location_comp_lit_field :: proc(
ast_context: ^AstContext,
position_context: ^DocumentPositionContext,
diff --git a/src/server/type_definition.odin b/src/server/type_definition.odin
index 900c060..94fb211 100644
--- a/src/server/type_definition.odin
+++ b/src/server/type_definition.odin
@@ -66,6 +66,44 @@ get_type_definition_locations :: proc(document: ^Document, position: common.Posi
}
}
+ if position_context.field_value != nil && position_in_node(position_context.field_value.field, position_context.position) {
+ if position_context.comp_lit != nil {
+ if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
+ if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
+ if position_in_node(field, position_context.position) {
+ if v, ok := comp_symbol.value.(SymbolStructValue); ok {
+ for name, i in v.names {
+ if name == field.name {
+ if symbol, ok := resolve_location_type_expression(&ast_context, v.types[i]); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+ }
+ } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
+ for name, i in v.names {
+ if name == field.name {
+ if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if position_context.call != nil {
+ if symbol, ok := resolve_location_proc_param_name_type(&ast_context, &position_context); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+
+
if position_context.call != nil {
if call, ok := position_context.call.derived.(^ast.Call_Expr); ok {
if !position_in_exprs(call.args, position_context.position) {
@@ -97,34 +135,6 @@ get_type_definition_locations :: proc(document: ^Document, position: common.Posi
}
}
- if position_context.field_value != nil && position_context.comp_lit != nil {
- if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
- if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
- if position_in_node(field, position_context.position) {
- if v, ok := comp_symbol.value.(SymbolStructValue); ok {
- for name, i in v.names {
- if name == field.name {
- if symbol, ok := resolve_location_type_expression(&ast_context, v.types[i]); ok {
- append_symbol_to_locations(&locations, document, symbol)
- return locations[:], true
- }
- }
- }
- }
- } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
- for name, i in v.names {
- if name == field.name {
- if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
- append_symbol_to_locations(&locations, document, symbol)
- return locations[:], true
- }
- }
- }
- }
- }
- }
- }
-
if position_context.selector != nil &&
position_context.identifier != nil &&
position_context.field == position_context.identifier {
diff --git a/tests/type_definition_test.odin b/tests/type_definition_test.odin
index 0e41b5e..22fc4d2 100644
--- a/tests/type_definition_test.odin
+++ b/tests/type_definition_test.odin
@@ -868,3 +868,27 @@ ast_type_definition_type_cast :: proc(t: ^testing.T) {
test.expect_type_definition_locations(t, &source, {location})
}
+@(test)
+ast_type_definition_proc_named_param :: proc (t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+
+ Bar :: struct{
+ bar: int,
+ }
+
+ foo :: proc(a: Bar) {}
+
+ main :: proc() {
+ a := "hellope"
+ foo(a{*} = {})
+ }
+ `,
+ }
+
+ locations := []common.Location {
+ {range = {start = {line = 2, character = 2}, end = {line = 2, character = 5}}},
+ }
+
+ test.expect_type_definition_locations(t, &source, locations[:])
+}