diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-03 09:17:09 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-03 09:17:09 -0400 |
| commit | 21df3b2d793448f445bc67e2d99b1f3b1f56042b (patch) | |
| tree | 3713c2ea161e10b659274786b092412bfcf35c6b /src | |
| parent | 526b55af850b8ee6a64b5f9ffe074bf708d0f655 (diff) | |
Improve and consolidate resolving implicit selector comp literals
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 110 | ||||
| -rw-r--r-- | src/server/completion.odin | 167 |
2 files changed, 101 insertions, 176 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 264dfe6..581a326 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -2009,15 +2009,68 @@ get_field_value_name :: proc(field_value: ^ast.Field_Value) -> (string, bool) { return "", false } +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 +} + + resolve_implicit_selector_comp_literal :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, symbol: Symbol, - field_name: string, ) -> ( Symbol, bool, ) { + field_name := "" + if position_context.field_value != nil { + field_name, _ = get_field_value_name(position_context.field_value) + } if comp_symbol, comp_lit, ok := resolve_type_comp_literal( ast_context, position_context, @@ -2025,34 +2078,12 @@ resolve_implicit_selector_comp_literal :: proc( position_context.parent_comp_lit, ); ok { #partial switch v in comp_symbol.value { - case SymbolEnumValue: + case SymbolEnumValue, SymbolBitSetValue: return comp_symbol, ok case SymbolStructValue: 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 v.names { - if name != field_name { - continue - } - - type = v.types[i] - break - } - - if type == nil && elem_index != -1 && len(v.types) > elem_index { - type = v.types[elem_index] - } + type := get_struct_comp_lit_type(position_context, comp_lit, v, field_name) return resolve_type_expression(ast_context, type) case SymbolBitFieldValue: @@ -2161,15 +2192,9 @@ resolve_implicit_selector :: proc( } } - if position_context.comp_lit != nil && - position_context.parent_comp_lit != nil && - position_context.parent_comp_lit.type != nil { - if position_context.field_value != nil { - if field_name, ok := get_field_value_name(position_context.field_value); ok { - if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok { - return resolve_implicit_selector_comp_literal(ast_context, position_context, symbol, field_name) - } - } + if position_context.comp_lit != nil && position_context.parent_comp_lit != nil { + if symbol, ok := resolve_comp_literal(ast_context, position_context); ok { + return resolve_implicit_selector_comp_literal(ast_context, position_context, symbol) } } @@ -2179,9 +2204,7 @@ resolve_implicit_selector :: proc( return {}, false } if position_context.parent_comp_lit != nil && position_context.field_value != nil { - if field_name, ok := get_field_value_name(position_context.field_value); ok { - return resolve_implicit_selector_comp_literal(ast_context, position_context, symbol, field_name) - } + return resolve_implicit_selector_comp_literal(ast_context, position_context, symbol) } } } @@ -2223,14 +2246,11 @@ resolve_implicit_selector :: proc( return {}, false } if position_context.parent_comp_lit != nil && position_context.field_value != nil { - if field_name, ok := get_field_value_name(position_context.field_value); ok { - return resolve_implicit_selector_comp_literal( - ast_context, - position_context, - current_symbol, - field_name, - ) - } + return resolve_implicit_selector_comp_literal( + ast_context, + position_context, + current_symbol, + ) } return current_symbol, ok } diff --git a/src/server/completion.odin b/src/server/completion.odin index 4c39d04..a854f7d 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -889,23 +889,21 @@ get_implicit_completion :: proc( } } else if v, ok := symbol.value.(SymbolStructValue); ok { if position_context.field_value != nil { - if field_name, ok := get_field_value_name(position_context.field_value); ok { - if symbol, ok := resolve_implicit_selector_comp_literal(ast_context, position_context, symbol, field_name); ok { - if enum_value, ok := symbol.value.(SymbolEnumValue); ok { - for name in enum_value.names { - if position_context.comp_lit != nil && field_exists_in_comp_lit(position_context.comp_lit, name) { - continue - } - item := CompletionItem { - label = name, - kind = .EnumMember, - detail = name, - } - append(results, CompletionResult{completion_item = item}) + if symbol, ok := resolve_implicit_selector_comp_literal(ast_context, position_context, symbol); ok { + if enum_value, ok := symbol.value.(SymbolEnumValue); ok { + for name in enum_value.names { + if position_context.comp_lit != nil && field_exists_in_comp_lit(position_context.comp_lit, name) { + continue } - - return is_incomplete + item := CompletionItem { + label = name, + kind = .EnumMember, + detail = name, + } + append(results, CompletionResult{completion_item = item}) } + + return is_incomplete } } } @@ -1030,81 +1028,37 @@ get_implicit_completion :: proc( } } } + + //infer bitset and enums based on the identifier comp_lit, i.e. a := My_Struct { my_ident = . } + if position_context.comp_lit != nil && position_context.parent_comp_lit != nil { + if symbol, ok := resolve_comp_literal(ast_context, position_context); ok { + if comp_symbol, ok := resolve_implicit_selector_comp_literal(ast_context, position_context, symbol); ok { + if enum_value, ok := comp_symbol.value.(SymbolEnumValue); ok { + for enum_name in enum_value.names { + item := CompletionItem { + label = enum_name, + kind = .EnumMember, + detail = enum_name, + } - //infer bitset and enums based on the identifier comp_lit, i.e. a := My_Struct { my_ident = . } - if position_context.comp_lit != nil { - if position_context.parent_comp_lit != nil { - field_name: string + append(results, CompletionResult{completion_item = item}) + } - if position_context.field_value != nil { - if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok { - field_name = field.name - } else { return is_incomplete - } - } - - if symbol, ok := resolve_comp_literal(ast_context, position_context); ok { - if comp_symbol, comp_lit, ok := resolve_type_comp_literal( - ast_context, - position_context, - symbol, - position_context.parent_comp_lit, - ); ok { - if s, ok := comp_symbol.value.(SymbolStructValue); ok { - set_ast_package_set_scoped(ast_context, comp_symbol.pkg) - - 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 { - item := CompletionItem { - label = enum_name, - kind = .EnumMember, - detail = enum_name, - } - - append(results, CompletionResult{completion_item = item}) - } - - return is_incomplete - } else if bitset_symbol, ok := resolve_type_expression(ast_context, type); ok { - set_ast_package_set_scoped(ast_context, bitset_symbol.pkg) - - if value, ok := unwrap_bitset(ast_context, bitset_symbol); ok { - for name in value.names { - - item := CompletionItem { - label = name, - kind = .EnumMember, - detail = name, - } - - append(results, CompletionResult{completion_item = item}) - } - return is_incomplete - } + } else if s, ok := unwrap_bitset(ast_context, comp_symbol); ok { + for enum_name in s.names { + item := CompletionItem { + label = enum_name, + kind = .EnumMember, + detail = enum_name, } - } else { - set_ast_package_set_scoped(ast_context, comp_symbol.pkg) - if s, ok := unwrap_bitset(ast_context, comp_symbol); ok { - for enum_name in s.names { - item := CompletionItem { - label = enum_name, - kind = .EnumMember, - detail = enum_name, - } - append(results, CompletionResult{completion_item = item}) - } - - return is_incomplete - } + append(results, CompletionResult{completion_item = item}) } + + return is_incomplete } } - - reset_ast_context(ast_context) } } @@ -1337,55 +1291,6 @@ 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, |