aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-09-11 22:03:52 -0400
committerGitHub <noreply@github.com>2025-09-11 22:03:52 -0400
commitaa2e8f609ad3a48f1bf7570a7f34c01f89d53c5d (patch)
tree2dab8c6a774f0be610048b145081f08f9f6f2282 /src/server
parent7b5eac698391e9d0b2d6fdac4ce4a857f92c33f2 (diff)
parent4cb9acda12fa0bb0a0b6fd6d46c163adc0544a4a (diff)
Merge pull request #998 from BradLewis/feat/nesting-structs-bitfield-improvements
Feat/nesting structs bitfield improvements
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin2
-rw-r--r--src/server/file_resolve.odin9
-rw-r--r--src/server/hover.odin56
-rw-r--r--src/server/references.odin93
-rw-r--r--src/server/symbol.odin9
5 files changed, 109 insertions, 60 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 4f70fbd..7538fe1 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -3432,7 +3432,7 @@ make_symbol_struct_from_ast :: proc(
}
b := symbol_struct_value_builder_make(symbol, ast_context.allocator)
- write_struct_type(ast_context, &b, v, attributes, -1, inlined)
+ write_struct_type(ast_context, &b, v, attributes, -1)
symbol = to_symbol(b)
return symbol
}
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index d4db280..53fda8f 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -561,6 +561,15 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
resolve_node(n.name, data)
resolve_node(n.type, data)
resolve_node(n.bit_size, data)
+ if data.flag != .None {
+ data.symbols[cast(uintptr)n.name] = SymbolAndNode {
+ node = n.name,
+ symbol = Symbol{
+ range = common.get_token_range(n.name, string(data.document.text)),
+ uri = strings.clone(common.create_uri(n.pos.file, data.ast_context.allocator).uri, data.ast_context.allocator),
+ },
+ }
+ }
case:
}
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/src/server/references.odin b/src/server/references.odin
index d3dc98f..f7be8c6 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -50,42 +50,13 @@ prepare_references :: proc(
ok = false
pkg := ""
- if position_context.struct_type != nil {
- found := false
- done_struct: for field in position_context.struct_type.fields.list {
- for name in field.names {
- if position_in_node(name, position_context.position) {
- symbol = Symbol {
- range = common.get_token_range(name, ast_context.file.src),
- pkg = ast_context.current_package,
- }
- found = true
- resolve_flag = .Field
- break done_struct
- }
- }
- if position_in_node(field.type, position_context.position) {
- node := get_desired_expr(field.type, position_context.position)
- symbol, ok = resolve_location_type_expression(ast_context, node)
- if !ok {
- return
- }
-
- found = true
- resolve_flag = .Identifier
- break done_struct
- }
- }
- if !found {
- return
- }
- } else if position_context.enum_type != nil {
+ if position_context.enum_type != nil {
found := false
done_enum: for field in position_context.enum_type.fields {
if ident, ok := field.derived.(^ast.Ident); ok {
if position_in_node(ident, position_context.position) {
symbol = Symbol {
- pkg = ast_context.current_package,
+ pkg = ast_context.current_package,
range = common.get_token_range(ident, ast_context.file.src),
}
found = true
@@ -96,7 +67,7 @@ prepare_references :: proc(
if position_in_node(value.field, position_context.position) {
symbol = Symbol {
range = common.get_token_range(value.field, ast_context.file.src),
- pkg = ast_context.current_package,
+ pkg = ast_context.current_package,
}
found = true
resolve_flag = .Field
@@ -198,17 +169,61 @@ prepare_references :: proc(
if !ok {
return
}
- } else if position_context.identifier != nil {
- ident := position_context.identifier.derived.(^ast.Ident)
- symbol, ok = resolve_location_identifier(ast_context, ident^)
+ } else {
+ // The order of these is important as a lot of the above can be defined within a struct so we
+ // need to make sure we resolve that last
+ if position_context.bit_field_type != nil {
+ for field in position_context.bit_field_type.fields {
+ if position_in_node(field.name, position_context.position) {
+ symbol = Symbol {
+ range = common.get_token_range(field.name, ast_context.file.src),
+ pkg = ast_context.current_package,
+ uri = document.uri.uri,
+ }
+ return symbol, .Field, true
+ }
+ if position_in_node(field.type, position_context.position) {
+ node := get_desired_expr(field.type, position_context.position)
+ if symbol, ok = resolve_location_type_expression(ast_context, node); ok {
+ return symbol, .Identifier, true
+ }
+ }
+ }
+ }
- resolve_flag = .Identifier
+ if position_context.struct_type != nil {
+ for field in position_context.struct_type.fields.list {
+ for name in field.names {
+ if position_in_node(name, position_context.position) {
+ symbol = Symbol {
+ range = common.get_token_range(name, ast_context.file.src),
+ pkg = ast_context.current_package,
+ uri = document.uri.uri,
+ }
+ return symbol, .Field, true
+ }
+ }
+ if position_in_node(field.type, position_context.position) {
+ node := get_desired_expr(field.type, position_context.position)
+ if symbol, ok = resolve_location_type_expression(ast_context, node); ok {
+ return symbol, .Identifier, true
+ }
+ }
+ }
+ }
- if !ok {
+ if position_context.identifier != nil {
+ ident := position_context.identifier.derived.(^ast.Ident)
+ symbol, ok = resolve_location_identifier(ast_context, ident^)
+
+ resolve_flag = .Identifier
+
+ if !ok {
+ return
+ }
+ } else {
return
}
- } else {
- return
}
if symbol.uri == "" {
symbol.uri = document.uri.uri
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 3d176f1..f140694 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -378,7 +378,6 @@ write_struct_type :: proc(
v: ^ast.Struct_Type,
attributes: []^ast.Attribute,
base_using_index: int,
- inlined := false,
) {
b.poly = v.poly_params
// We clone this so we don't override docs and comments with temp allocated docs and comments
@@ -542,7 +541,7 @@ expand_usings :: proc(ast_context: ^AstContext, b: ^SymbolStructValueBuilder) {
if ident, ok := derived.(^ast.Ident); ok {
if v, ok := struct_type_from_identifier(ast_context, ident^); ok {
- write_struct_type(ast_context, b, v, {}, u, true)
+ write_struct_type(ast_context, b, v, {}, u)
} else {
clear(&ast_context.recursion_map)
if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
@@ -563,6 +562,12 @@ expand_usings :: proc(ast_context: ^AstContext, b: ^SymbolStructValueBuilder) {
}
} else if v, ok := derived.(^ast.Struct_Type); ok {
write_struct_type(ast_context, b, v, {}, u)
+ } else if v, ok := derived.(^ast.Bit_Field_Type); ok {
+ if symbol, ok := resolve_type_expression(ast_context, field_expr); ok {
+ if v, ok := symbol.value.(SymbolBitFieldValue); ok {
+ write_symbol_bitfield_value(ast_context, b, v, u)
+ }
+ }
}
delete_key(&ast_context.recursion_map, b.types[u])
}