aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-09-11 20:53:36 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-09-11 20:53:36 -0400
commit968712e40186abaf5447f69cc73b197af9d94600 (patch)
treeeac561845f431f145e055a4e333a851e13562d0f
parent7b5eac698391e9d0b2d6fdac4ce4a857f92c33f2 (diff)
Resolve hover information for nested struct and bitfield fields
-rw-r--r--src/server/hover.odin56
-rw-r--r--tests/hover_test.odin30
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