summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-25 19:13:59 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-25 19:13:59 -0400
commit2bd0bb05fe74a5923b79c8dc674ee84c1fcb29f3 (patch)
tree3f63ab9a967b135d1128cee347a5d63c91467ec4
parent3c5a77c625d9946515235548165cad8e80db85ef (diff)
Fix provided incorrect completions for named call args
-rw-r--r--src/server/analysis.odin44
-rw-r--r--src/server/completion.odin3
-rw-r--r--tests/completions_test.odin26
3 files changed, 58 insertions, 15 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index ff94e41..32d38eb 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2096,21 +2096,8 @@ internal_resolve_comp_literal :: proc(
symbol = resolve_proc(ast_context, position_context.parent_comp_lit.type) or_return
} else if position_context.call != nil {
if call_expr, ok := position_context.call.derived.(^ast.Call_Expr); ok {
- arg_index := find_position_in_call_param(position_context, call_expr^) or_return
-
- symbol = resolve_proc(ast_context, position_context.call) or_return
-
- value := symbol.value.(SymbolProcedureValue) or_return
-
- if len(value.arg_types) <= arg_index {
- return {}, false
- }
-
- if value.arg_types[arg_index].type == nil {
- return {}, false
- }
-
- symbol = resolve_proc(ast_context, value.arg_types[arg_index].type) or_return
+ type := get_call_argument_type(ast_context, position_context, call_expr) or_return
+ symbol = resolve_proc(ast_context, type) or_return
}
} else if position_context.returns != nil {
return_index: int
@@ -3151,6 +3138,33 @@ find_position_in_call_param :: proc(position_context: ^DocumentPositionContext,
return len(call.args) - 1, true
}
+get_call_argument_type :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ call: ^ast.Call_Expr,
+) -> (
+ expr: ^ast.Expr,
+ ok: bool,
+) {
+ index := find_position_in_call_param(position_context, call^) or_return
+ symbol := resolve_type_expression(ast_context, call) or_return
+ value := symbol.value.(SymbolProcedureValue) or_return
+
+ arg: ^ast.Field
+ if field, ok := call.args[index].derived.(^ast.Field_Value); ok {
+ ident := field.field.derived.(^ast.Ident) or_return
+ arg = get_proc_arg_type_from_name(value, ident.name) or_return
+ } else {
+ arg = get_proc_arg_type_from_index(value, index) or_return
+ }
+
+ if arg.type == nil {
+ return arg.default_value, true
+ }
+
+ return arg.type, true
+}
+
make_pointer_ast :: proc(ast_context: ^AstContext, elem: ^ast.Expr) -> ^ast.Pointer_Type {
pointer := new_type(ast.Pointer_Type, elem.pos, elem.end, ast_context.allocator)
pointer.elem = elem
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 5d39109..f1bd9a8 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1353,6 +1353,9 @@ get_implicit_completion :: proc(
return is_incomplete
} else if s, ok := unwrap_bitset(ast_context, comp_symbol); ok {
for enum_name in s.names {
+ if field_exists_in_comp_lit(position_context.comp_lit, enum_name) {
+ continue
+ }
item := CompletionItem {
label = enum_name,
kind = .EnumMember,
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 74de905..01f718b 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -4802,3 +4802,29 @@ ast_completion_array_comp_lit :: proc(t: ^testing.T) {
}
test.expect_completion_docs(t, &source, "", {"test.foo1: int", "test.foo2: int"})
}
+
+@(test)
+ast_completion_named_proc_arg_comp_lit :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: int,
+ }
+
+ bazz :: proc(foos: []Foo = {}, bars: []Bar = {}) {}
+
+ main :: proc() {
+ bazz(bars = {
+ {
+ {*}
+ }
+ })
+ }
+ `,
+ }
+ test.expect_completion_docs(t, &source, "", {"Bar.bar: int"})
+}