diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-17 20:54:10 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-17 20:54:10 -0400 |
| commit | ad58adbd01d1f0481feceb5381f53adba541d021 (patch) | |
| tree | c55293c89b386dab5f7551840d0e9db0c657ff65 /src | |
| parent | c96f264f8df3e83d82471f54b63e872ce5116f01 (diff) | |
Correctly handle fixed array #soa
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 27 | ||||
| -rw-r--r-- | src/server/completion.odin | 31 | ||||
| -rw-r--r-- | src/server/hover.odin | 20 |
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) |