From d3b8c9bf3bba9b53ede7b3685ebe9a120a36c7a0 Mon Sep 17 00:00:00 2001 From: CreeperFace <165158232+dy-tea@users.noreply.github.com> Date: Sun, 28 Dec 2025 21:21:52 +0000 Subject: [PATCH] checker,vls: support gotodef for fn param and []Type (#26193) --- vlib/v/checker/fn.v | 12 +++++ vlib/v/checker/struct.v | 29 +++++++++-- vlib/v/tests/vls/goto_def_test.v | 66 ++++++++++++++++++++++++++ vlib/v/tests/vls/goto_def_test_data.vv | 21 ++++++++ 4 files changed, 124 insertions(+), 4 deletions(-) diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index cc9b41e4d..7910a2cf5 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -311,6 +311,18 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if node.language == .v { // Make sure all types are valid for mut param in node.params { + // handle vls go to definition for parameter types + if c.pref.is_vls && c.pref.linfo.method == .definition { + if c.vls_is_the_node(param.type_pos) { + typ_str := c.table.type_to_str(param.typ) + if np := c.name_pos_gotodef(typ_str) { + if np.file_idx != -1 { + println('${c.table.filelist[np.file_idx]}:${np.line_nr + 1}:${np.col}') + } + exit(0) + } + } + } if !c.ensure_type_exists(param.typ, param.type_pos) { return } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index adcbe384d..0763042fc 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -190,10 +190,31 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { if c.pref.is_vls && c.pref.linfo.method == .definition { if c.vls_is_the_node(field.type_pos) { sym := c.table.sym(field.typ) - pos := sym.info.get_name_pos() or { token.Pos{} } - if pos.file_idx != -1 { - println('${c.table.filelist[pos.file_idx]}:${pos.line_nr + 1}:${pos.col}') - exit(0) + elem_type := match sym.kind { + .array { + (sym.info as ast.Array).elem_type + } + .array_fixed { + (sym.info as ast.ArrayFixed).elem_type + } + else { + ast.Type(0) + } + } + if elem_type == 0 { + pos := sym.info.get_name_pos() or { token.Pos{} } + if pos.file_idx != -1 { + println('${c.table.filelist[pos.file_idx]}:${pos.line_nr + 1}:${pos.col}') + exit(0) + } + } else { + elem_sym := c.table.sym(elem_type) + if np := elem_sym.info.get_name_pos() { + if np.file_idx != -1 { + println('${c.table.filelist[np.file_idx]}:${np.line_nr + 1}:${np.col}') + exit(0) + } + } } } } diff --git a/vlib/v/tests/vls/goto_def_test.v b/vlib/v/tests/vls/goto_def_test.v index 46329cfc3..2d404c51c 100644 --- a/vlib/v/tests/vls/goto_def_test.v +++ b/vlib/v/tests/vls/goto_def_test.v @@ -198,6 +198,72 @@ const test_cases = [ expected: '${mod1_text_file}:25:1' description: 'Go to imported enum value definition' }, + // test_operator_overload() tests + TestCase{ + name: 'operator_receiver_type' + line: 137 + col: 8 + expected: '${test_file}:133:7' + description: 'Go to struct definition from operator overload receiver type' + }, + TestCase{ + name: 'operator_param_type' + line: 137 + col: 22 + expected: '${test_file}:133:7' + description: 'Go to struct definition from operator overload parameter type' + }, + TestCase{ + name: 'operator_return_type' + line: 137 + col: 33 + expected: '${test_file}:133:7' + description: 'Go to struct definition from operator overload return type' + }, + TestCase{ + name: 'struct_init_field_in_params_left' + line: 138 + col: 23 + expected: '${test_file}:137:4' + description: 'Go to param definition from struct init variable (left fn param)' + }, + TestCase{ + name: 'struct_init_field_in_params_right' + line: 138 + col: 31 + expected: '${test_file}:137:19' + description: 'Go to param definition from struct init variable (right fn param)' + }, + TestCase{ + name: 'field_selector_in_struct_init' + line: 138 + col: 25 + expected: '${test_file}:134:1' + description: 'Go to field definition from selector expression in struct init value (a.val)' + }, + // test_function_params() tests + TestCase{ + name: 'function_param_type' + line: 141 + col: 24 + expected: '${test_file}:133:7' + description: 'Go to struct definition from function parameter type' + }, + // test_array_field_types() tests + TestCase{ + name: 'array_elem_type_in_struct_field' + line: 150 + col: 10 + expected: '${test_file}:145:7' + description: 'Go to element type definition from array type in struct field ([]ArrayElemStruct)' + }, + TestCase{ + name: 'fixed_array_elem_type_in_struct_field' + line: 151 + col: 17 + expected: '${test_file}:145:7' + description: 'Go to element type definition from fixed array type in struct field ([5]ArrayElemStruct)' + }, ] fn test_goto_definition() { diff --git a/vlib/v/tests/vls/goto_def_test_data.vv b/vlib/v/tests/vls/goto_def_test_data.vv index 9351ff1cc..8fe329585 100644 --- a/vlib/v/tests/vls/goto_def_test_data.vv +++ b/vlib/v/tests/vls/goto_def_test_data.vv @@ -129,3 +129,24 @@ fn test_imported_enum() { imported_e := s.PublicEnum1.a println(imported_e) } + +struct OpStruct { + val int +} + +fn (a OpStruct) + (b OpStruct) OpStruct { + return OpStruct{val: a.val + b.val} +} + +fn takes_struct(param OpStruct) string { + return param.str() +} + +struct ArrayElemStruct { + value int +} + +struct ContainerStruct { + items []ArrayElemStruct + fixed_items [5]ArrayElemStruct +} -- 2.39.5