aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-17 20:54:10 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-17 20:54:10 -0400
commitad58adbd01d1f0481feceb5381f53adba541d021 (patch)
treec55293c89b386dab5f7551840d0e9db0c657ff65 /src
parentc96f264f8df3e83d82471f54b63e872ce5116f01 (diff)
Correctly handle fixed array #soa
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin27
-rw-r--r--src/server/completion.odin31
-rw-r--r--src/server/hover.odin20
3 files changed, 59 insertions, 19 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 19c4e0a..d1282bb 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1301,17 +1301,24 @@ resolve_type_assertion_expr :: proc(ast_context: ^AstContext, v: ^ast.Type_Asser
return symbol, ok
}
-resolve_soa_selector_field :: proc(ast_context: ^AstContext, expr: ^ast.Expr, name: string) -> (Symbol, bool) {
+resolve_soa_selector_field :: proc(ast_context: ^AstContext, expr: ^ast.Expr, size: ^ast.Expr, name: string) -> (Symbol, bool) {
if symbol, ok := resolve_type_expression(ast_context, expr); ok {
if v, ok := symbol.value.(SymbolStructValue); ok {
for n, i in v.names {
if n == name {
- value := SymbolMultiPointerValue {
- expr = v.types[i],
+ if size != nil {
+ symbol.value = SymbolFixedArrayValue{
+ expr = v.types[i],
+ len = size,
+ }
+ } else {
+ symbol.value = SymbolMultiPointerValue {
+ expr = v.types[i],
+ }
}
+
symbol.name = name
symbol.type = .Field
- symbol.value = value
symbol.range = v.ranges[i]
return symbol, true
}
@@ -1333,7 +1340,7 @@ resolve_selector_expression :: proc(ast_context: ^AstContext, node: ^ast.Selecto
#partial switch s in selector.value {
case SymbolFixedArrayValue:
if .Soa in selector.flags {
- return resolve_soa_selector_field(ast_context, s.expr, node.field.name)
+ return resolve_soa_selector_field(ast_context, s.expr, s.len, node.field.name)
}
components_count := 0
for c in node.field.name {
@@ -1409,11 +1416,11 @@ resolve_selector_expression :: proc(ast_context: ^AstContext, node: ^ast.Selecto
return selector, true
case SymbolSliceValue:
if .Soa in selector.flags {
- return resolve_soa_selector_field(ast_context, s.expr, node.field.name)
+ return resolve_soa_selector_field(ast_context, s.expr, nil, node.field.name)
}
case SymbolDynamicArrayValue:
if .Soa in selector.flags {
- return resolve_soa_selector_field(ast_context, s.expr, node.field.name)
+ return resolve_soa_selector_field(ast_context, s.expr, nil, node.field.name)
}
}
}
@@ -2632,15 +2639,15 @@ resolve_symbol_selector :: proc(
}
case SymbolSliceValue:
if .Soa in symbol.flags {
- return resolve_soa_selector_field(ast_context, v.expr, field)
+ return resolve_soa_selector_field(ast_context, v.expr, nil, field)
}
case SymbolDynamicArrayValue:
if .Soa in symbol.flags {
- return resolve_soa_selector_field(ast_context, v.expr, field)
+ return resolve_soa_selector_field(ast_context, v.expr, nil, field)
}
case SymbolFixedArrayValue:
if .Soa in symbol.flags {
- return resolve_soa_selector_field(ast_context, v.expr, field)
+ return resolve_soa_selector_field(ast_context, v.expr, v.len, field)
}
}
diff --git a/src/server/completion.odin b/src/server/completion.odin
index ea55091..9f795cc 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -504,7 +504,13 @@ get_comp_lit_completion :: proc(
return false
}
-add_soa_field_completion :: proc(ast_context: ^AstContext, expr: ^ast.Expr, results: ^[dynamic]CompletionResult, parent_name: string) {
+add_soa_field_completion :: proc(
+ ast_context: ^AstContext,
+ expr: ^ast.Expr,
+ size: ^ast.Expr,
+ results: ^[dynamic]CompletionResult,
+ parent_name: string,
+) {
if symbol, ok := resolve_type_expression(ast_context, expr); ok {
if v, ok := symbol.value.(SymbolStructValue); ok {
for name, i in v.names {
@@ -513,11 +519,20 @@ add_soa_field_completion :: proc(ast_context: ^AstContext, expr: ^ast.Expr, resu
}
resolved := Symbol {
- name = name,
- type = .Field,
+ name = name,
+ type = .Field,
range = v.ranges[i],
- pkg = parent_name,
- value = SymbolMultiPointerValue{expr = v.types[i]},
+ pkg = parent_name,
+ }
+ if size != nil {
+ resolved.value = SymbolFixedArrayValue{
+ expr = v.types[i],
+ len = size,
+ }
+ } else {
+ resolved.value = SymbolMultiPointerValue {
+ expr = v.types[i],
+ }
}
build_documentation(ast_context, &resolved)
append(results, CompletionResult{symbol = resolved})
@@ -677,7 +692,7 @@ get_selector_completion :: proc(
}
}
if .Soa in selector.flags {
- add_soa_field_completion(ast_context, v.expr, results, selector.name)
+ add_soa_field_completion(ast_context, v.expr, v.len, results, selector.name)
}
case SymbolUnionValue:
is_incomplete = false
@@ -867,13 +882,13 @@ get_selector_completion :: proc(
is_incomplete = false
append_magic_array_like_completion(position_context, selector, results)
if .Soa in selector.flags {
- add_soa_field_completion(ast_context, v.expr, results, selector.name)
+ add_soa_field_completion(ast_context, v.expr, nil, results, selector.name)
}
case SymbolSliceValue:
is_incomplete = false
append_magic_array_like_completion(position_context, selector, results)
if .Soa in selector.flags {
- add_soa_field_completion(ast_context, v.expr, results, selector.name)
+ add_soa_field_completion(ast_context, v.expr, nil, results, selector.name)
}
case SymbolMapValue:
is_incomplete = false
diff --git a/src/server/hover.odin b/src/server/hover.odin
index 44fde02..a36dc54 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -349,7 +349,25 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
case SymbolSliceValue:
if .Soa in selector.flags {
- if symbol, ok := resolve_soa_selector_field(&ast_context, v.expr, field); ok {
+ if symbol, ok := resolve_soa_selector_field(&ast_context, v.expr, nil, field); ok {
+ symbol.pkg = selector.name
+ build_documentation(&ast_context, &symbol, false)
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true, true
+ }
+ }
+ case SymbolDynamicArrayValue:
+ if .Soa in selector.flags {
+ if symbol, ok := resolve_soa_selector_field(&ast_context, v.expr, nil, field); ok {
+ symbol.pkg = selector.name
+ build_documentation(&ast_context, &symbol, false)
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true, true
+ }
+ }
+ case SymbolFixedArrayValue:
+ if .Soa in selector.flags {
+ if symbol, ok := resolve_soa_selector_field(&ast_context, v.expr, v.len, field); ok {
symbol.pkg = selector.name
build_documentation(&ast_context, &symbol, false)
hover.contents = write_hover_content(&ast_context, symbol)