From c18c06ff176fb4e2188b7aeff53120dd533e7ab3 Mon Sep 17 00:00:00 2001 From: Brad Lewis <22850972+BradLewis@users.noreply.github.com> Date: Sat, 2 Aug 2025 22:05:23 -0400 Subject: Correctly resolve comp lit implicit values when using nested structs and not naming the fields --- src/server/completion.odin | 73 +++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 23 deletions(-) (limited to 'src/server') diff --git a/src/server/completion.odin b/src/server/completion.odin index 16662fe..4c39d04 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -1054,29 +1054,7 @@ get_implicit_completion :: proc( if s, ok := comp_symbol.value.(SymbolStructValue); ok { set_ast_package_set_scoped(ast_context, comp_symbol.pkg) - //We can either have the final - elem_index := -1 - - for elem, i in comp_lit.elems { - if position_in_node(elem, position_context.position) { - elem_index = i - } - } - - type: ^ast.Expr - - for name, i in s.names { - if name != field_name { - continue - } - - type = s.types[i] - break - } - - if type == nil && len(s.types) > elem_index && elem_index != -1 { - type = s.types[elem_index] - } + type := get_struct_comp_lit_type(position_context, comp_lit, s, field_name) if enum_value, ok := unwrap_enum(ast_context, type); ok { for enum_name in enum_value.names { @@ -1359,6 +1337,55 @@ get_implicit_completion :: proc( return is_incomplete } +get_struct_comp_lit_type :: proc( + position_context: ^DocumentPositionContext, + comp_lit: ^ast.Comp_Lit, + s: SymbolStructValue, + field_name: string, +) -> ^ast.Expr { + elem_index := -1 + + for elem, i in comp_lit.elems { + if position_in_node(elem, position_context.position) { + elem_index = i + if field_value, ok := elem.derived.(^ast.Field_Value); ok { + // If our field is another comp_lit, check to see if we're actually in that one + if cl, ok := field_value.value.derived.(^ast.Comp_Lit); ok { + if type := get_struct_comp_lit_type( + position_context, + cl, + s, + field_name, + ); type != nil { + return type + } + } + } + } + } + + if elem_index == -1 { + return nil + } + + type: ^ast.Expr + + for name, i in s.names { + if name != field_name { + continue + } + + type = s.types[i] + break + } + + if type == nil && len(s.types) > elem_index && elem_index != -1 { + type = s.types[elem_index] + } + + return type +} + get_identifier_completion :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, -- cgit v1.2.3