diff options
| author | Nathaniel Saxe <NathanielSaxophone@gmail.com> | 2026-02-04 15:35:08 -0500 |
|---|---|---|
| committer | Nathaniel Saxe <NathanielSaxophone@gmail.com> | 2026-02-04 15:35:08 -0500 |
| commit | 342a0e1a401627d76dbc20d22bf9d0788b3760c2 (patch) | |
| tree | dd9e310d0b82893099a5475bae04761529277240 | |
| parent | 857cfd03a5d3b66402105fafe0ec262b4cae5186 (diff) | |
qualify union case names with pointer / package when necessary
| -rw-r--r-- | src/server/action_populate_switch_cases.odin | 23 | ||||
| -rw-r--r-- | src/server/completion.odin | 35 |
2 files changed, 37 insertions, 21 deletions
diff --git a/src/server/action_populate_switch_cases.odin b/src/server/action_populate_switch_cases.odin index ca5c258..a733aa5 100644 --- a/src/server/action_populate_switch_cases.odin +++ b/src/server/action_populate_switch_cases.odin @@ -9,7 +9,7 @@ import "core:strings" import "src:common" -// Get the indentation (leading whitespace) of the line containing the given offset +// Get the offset of the start of the line containing the given offset get_line_start_offset :: proc(src: string, offset: int) -> int { line_start := offset for line_start > 0 && src[line_start - 1] != '\n' { @@ -63,18 +63,21 @@ get_switch_cases_info :: proc( for stmt in switch_block.stmts { if case_clause, ok := stmt.derived.(^ast.Case_Clause); ok { case_name := "" - for name in case_clause.list { + for clause in case_clause.list { if is_enum { - if implicit, ok := name.derived.(^ast.Implicit_Selector_Expr); ok { - case_name = implicit.field.name + if name, ok := get_used_switch_name(clause); ok { + case_name = name break } } else { reset_ast_context(ast_context) - if ty, ok := resolve_type_expression(ast_context, name); ok { + if symbol, ok := resolve_type_expression(ast_context, clause); ok { + case_name = get_qualified_union_case_name(&symbol, ast_context, position_context) //TODO: this is wrong for anonymous enums and structs, where the name field is "enum" or "struct" respectively but we want to use the full signature //we also can't use the signature all the time because type aliases need to use specifically the alias name here and not the signature - case_name = ty.name != "" ? ty.name : get_signature(ast_context, ty) + if case_name == "" { + case_name = get_signature(ast_context, symbol) + } break } } @@ -107,10 +110,14 @@ get_switch_cases_info :: proc( case_names := make([]string, len(union_value.types), context.temp_allocator) for t, i in union_value.types { reset_ast_context(ast_context) - if ty, ok := resolve_type_expression(ast_context, t); ok { + if symbol, ok := resolve_type_expression(ast_context, t); ok { + case_name := get_qualified_union_case_name(&symbol, ast_context, position_context) //TODO: this is wrong for anonymous enums and structs, where the name field is "enum" or "struct" respectively but we want to use the full signature //we also can't use the signature all the time because type aliases need to use specifically the alias name here and not the signature - case_names[i] = ty.name != "" ? ty.name : get_signature(ast_context, ty) + if case_name == "" { + case_name = get_signature(ast_context, symbol) + } + case_names[i] = case_name } else { case_names[i] = "invalid type expression" } diff --git a/src/server/completion.odin b/src/server/completion.odin index 8be6079..a7b1720 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -1943,12 +1943,32 @@ get_used_switch_name :: proc(node: ^ast.Expr) -> (string, bool) { return n.name, true case ^ast.Selector_Expr: return n.field.name, true + case ^ast.Implicit_Selector_Expr: + return n.field.name, true case ^ast.Pointer_Type: return get_used_switch_name(n.elem) } return "", false } +//handles pointers / packages +get_qualified_union_case_name :: proc( + symbol: ^Symbol, + ast_context: ^AstContext, + position_context: ^DocumentPositionContext, +) -> string { + if symbol.pkg == ast_context.document_package { + return fmt.aprintf("%v%v", repeat("^", symbol.pointers, context.temp_allocator), symbol.name) + } else { + return fmt.aprintf( + "%v%v.%v", + repeat("^", symbol.pointers, context.temp_allocator), + get_symbol_pkg_name(ast_context, symbol), + symbol.name, + ) + } +} + get_type_switch_completion :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, @@ -1987,19 +2007,8 @@ get_type_switch_completion :: proc( item := CompletionItem { kind = .EnumMember, } - - if symbol.pkg == ast_context.document_package { - item.label = fmt.aprintf("%v%v", repeat("^", symbol.pointers, context.temp_allocator), name) - item.detail = item.label - } else { - item.label = fmt.aprintf( - "%v%v.%v", - repeat("^", symbol.pointers, context.temp_allocator), - get_symbol_pkg_name(ast_context, &symbol), - name, - ) - item.detail = item.label - } + item.label = get_qualified_union_case_name(&symbol, ast_context, position_context) + item.detail = item.label if position_context.implicit_selector_expr != nil { if remove_edit, ok := create_implicit_selector_remove_edit(position_context); ok { item.additionalTextEdits = remove_edit |