diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-09-11 20:53:36 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-09-11 20:53:36 -0400 |
| commit | 968712e40186abaf5447f69cc73b197af9d94600 (patch) | |
| tree | eac561845f431f145e055a4e333a851e13562d0f | |
| parent | 7b5eac698391e9d0b2d6fdac4ce4a857f92c33f2 (diff) | |
Resolve hover information for nested struct and bitfield fields
| -rw-r--r-- | src/server/hover.odin | 56 | ||||
| -rw-r--r-- | tests/hover_test.odin | 30 |
2 files changed, 68 insertions, 18 deletions
diff --git a/src/server/hover.odin b/src/server/hover.odin index 960a3a2..ef4c046 100644 --- a/src/server/hover.odin +++ b/src/server/hover.odin @@ -62,9 +62,9 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> return {}, false, true } - if position_context.type_cast != nil && // check that we're actually on the 'cast' word + if position_context.type_cast != nil && !position_in_node(position_context.type_cast.type, position_context.position) && - !position_in_node(position_context.type_cast.expr, position_context.position) { + !position_in_node(position_context.type_cast.expr, position_context.position) { // check that we're actually on the 'cast' word if str, ok := keywords_docs[position_context.type_cast.tok.text]; ok { hover.contents.kind = "markdown" hover.contents.value = str @@ -134,18 +134,24 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> if symbol, ok := resolve_type_expression(&ast_context, field.type); ok { if struct_symbol, ok := resolve_type_expression( &ast_context, - position_context.value_decl.names[0], + &position_context.struct_type.node, ); ok { - if value, ok := struct_symbol.value.(SymbolStructValue); ok { - construct_struct_field_symbol( - &symbol, - struct_symbol.name, - value, - field_index + name_index, - ) - build_documentation(&ast_context, &symbol, true) - hover.contents = write_hover_content(&ast_context, symbol) - return hover, true, true + if value_decl_symbol, ok := resolve_type_expression( + &ast_context, + position_context.value_decl.names[0], + ); ok { + name := get_field_parent_name(value_decl_symbol, struct_symbol) + if value, ok := struct_symbol.value.(SymbolStructValue); ok { + construct_struct_field_symbol( + &symbol, + name, + value, + field_index + name_index, + ) + build_documentation(&ast_context, &symbol, true) + hover.contents = write_hover_content(&ast_context, symbol) + return hover, true, true + } } } } @@ -162,12 +168,18 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> if symbol, ok := resolve_type_expression(&ast_context, field.type); ok { if bit_field_symbol, ok := resolve_type_expression( &ast_context, - position_context.value_decl.names[0], + &position_context.bit_field_type.node, ); ok { - if value, ok := bit_field_symbol.value.(SymbolBitFieldValue); ok { - construct_bit_field_field_symbol(&symbol, bit_field_symbol.name, value, i) - hover.contents = write_hover_content(&ast_context, symbol) - return hover, true, true + if value_decl_symbol, ok := resolve_type_expression( + &ast_context, + position_context.value_decl.names[0], + ); ok { + name := get_field_parent_name(value_decl_symbol, bit_field_symbol) + if value, ok := bit_field_symbol.value.(SymbolBitFieldValue); ok { + construct_bit_field_field_symbol(&symbol, name, value, i) + hover.contents = write_hover_content(&ast_context, symbol) + return hover, true, true + } } } } @@ -457,3 +469,11 @@ get_soa_field_hover :: proc( } return {}, false, true } + +@(private = "file") +get_field_parent_name :: proc(value_decl_symbol, symbol: Symbol) -> string { + if value_decl_symbol.range != symbol.range { + return symbol.name + } + return value_decl_symbol.name +} diff --git a/tests/hover_test.odin b/tests/hover_test.odin index 8660eb7..72a68b5 100644 --- a/tests/hover_test.odin +++ b/tests/hover_test.odin @@ -4650,6 +4650,36 @@ ast_hover_comp_lit_map_key :: proc(t: ^testing.T) { } test.expect_hover(t, &source, "Foo.a: int") } + +@(test) +ast_hover_inner_struct_field :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct { + a: int, + b: struct { + c{*}: int, + } + } + `, + } + test.expect_hover(t, &source, "struct.c: int") +} + +@(test) +ast_hover_using_bit_field_struct :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct { + a: int, + using _: bit_field u8 { + c{*}: u8 | 8, + }, + } + `, + } + test.expect_hover(t, &source, "bit_field.c: u8 | 8") +} /* Waiting for odin fix |