aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpc <pmnarimani@gmail.com>2026-01-27 02:13:42 +0100
committerpc <pmnarimani@gmail.com>2026-01-27 02:13:42 +0100
commit219d0157cf409f23751b719080aa212cc1ebc1f5 (patch)
tree4ffe859f8da3b4371edc151c8745650ae5212119
parent23b5c69f52b0007a6727bd04a5fe373e97df0739 (diff)
feat: add completion edit text test for proc group with single argument
-rw-r--r--src/server/methods.odin19
-rw-r--r--src/testing/testing.odin44
-rw-r--r--tests/completions_test.odin27
3 files changed, 88 insertions, 2 deletions
diff --git a/src/server/methods.odin b/src/server/methods.odin
index 797a089..19d9ff4 100644
--- a/src/server/methods.odin
+++ b/src/server/methods.odin
@@ -250,8 +250,23 @@ add_proc_group_method_completion :: proc(
references, dereferences := compute_pointer_adjustments(first_arg.pointers, pointers)
- // Proc groups always have multiple args (the receiver plus at least one overload's additional args)
- new_text := build_method_call_text(ast_context, symbol, receiver, references, dereferences, true)
+ // Check if any member of the proc group has additional arguments beyond the receiver
+ has_additional_args := false
+ for member_expr in proc_group.args {
+ member: Symbol
+ member, ok = resolve_type_expression(ast_context, member_expr)
+ if !ok {
+ continue
+ }
+ if proc_val, is_proc_val := member.value.(SymbolProcedureValue); is_proc_val {
+ if len(proc_val.arg_types) > 1 {
+ has_additional_args = true
+ break
+ }
+ }
+ }
+
+ new_text := build_method_call_text(ast_context, symbol, receiver, references, dereferences, has_additional_args)
item := CompletionItem {
label = symbol.name,
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 20327a7..0ba7b0f 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -321,6 +321,50 @@ expect_completion_insert_text :: proc(
}
}
+expect_completion_edit_text :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ trigger_character: string,
+ label: string,
+ expected_text: string,
+) {
+ setup(src)
+ defer teardown(src)
+
+ completion_context := server.CompletionContext {
+ triggerCharacter = trigger_character,
+ }
+
+ completion_list, ok := server.get_completion_list(src.document, src.position, completion_context, &src.config)
+
+ if !ok {
+ log.error("Failed get_completion_list")
+ }
+
+ found := false
+ for completion in completion_list.items {
+ if completion.label == label {
+ found = true
+ if text_edit, has_edit := completion.textEdit.(server.TextEdit); has_edit {
+ if text_edit.newText != expected_text {
+ log.errorf(
+ "Completion '%v' expected textEdit.newText %q, but received %q",
+ label,
+ expected_text,
+ text_edit.newText,
+ )
+ }
+ } else {
+ log.errorf("Completion '%v' has no textEdit", label)
+ }
+ break
+ }
+ }
+ if !found {
+ log.errorf("Expected completion label '%v' not found in %v", label, completion_list.items)
+ }
+}
+
expect_hover :: proc(t: ^testing.T, src: ^Source, expect_hover_string: string) {
setup(src)
defer teardown(src)
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 8ed9b43..f0fa8c1 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -5441,3 +5441,30 @@ ast_completion_fake_method_builtin_type_uses_builtin_pkg :: proc(t: ^testing.T)
// the lookup correctly uses "$builtin" instead of "test" for the package
test.expect_completion_labels(t, &source, ".", {"square", "cube"})
}
+
+@(test)
+ast_completion_fake_method_proc_group_single_arg_cursor_position :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ import "methods"
+ main :: proc() {
+ n: int
+ n.{*}
+ }
+ `,
+ packages = {
+ {
+ pkg = "methods",
+ source = `package methods
+ // All members only take a single argument (the receiver)
+ negate_a :: proc(x: int) -> int { return -x }
+ negate_b :: proc(x: int) -> int { return 0 - x }
+ negate :: proc { negate_a, negate_b }
+ `,
+ },
+ },
+ config = {enable_fake_method = true},
+ }
+ // The proc group 'negate' should have cursor AFTER parentheses since no additional args
+ test.expect_completion_edit_text(t, &source, ".", "negate", "methods.negate(n)$0")
+}