aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-02 22:05:23 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-02 22:12:52 -0400
commitc18c06ff176fb4e2188b7aeff53120dd533e7ab3 (patch)
treef4b1f09be7e8566da19bee119a1e103aadc53945 /src/server
parentd86b093c6e0623ec7ced3bbd6cf5970926a8a0ab (diff)
Correctly resolve comp lit implicit values when using nested structs and not naming the fields
Diffstat (limited to 'src/server')
-rw-r--r--src/server/completion.odin73
1 files changed, 50 insertions, 23 deletions
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,