From 941711b384d795a12b4413dd3daf0065fa37f93f Mon Sep 17 00:00:00 2001 From: Patrick Ribbsaeter Date: Tue, 4 Aug 2026 07:20:32 -0700 Subject: [PATCH] Avoid duplicate completions while defining methods (#4304) Summary: Method-name completion was combining the dedicated class/magic-method candidates with ordinary value completions. That caused existing methods to appear twice and leaked unrelated names into the list. This change keeps method definitions on the dedicated completion paths and adds a focused regression test proving that a prefixed existing method is returned exactly once. Fixes https://github.com/facebook/pyrefly/issues/4126. ## Validation - `cargo fmt --check` passes - targeted regression coverage added for method-definition completion deduplication AI disclosure: this change was developed with Codex assistance and reviewed against the repository contribution guidance. Pull Request resolved: https://github.com/facebook/pyrefly/pull/4304 Reviewed By: yangdanny97 Differential Revision: D114414452 Pulled By: NathanTempest fbshipit-source-id: 6c955dfd96e48d0070bd023be62e1c761076a965 --- pyrefly/lib/lsp/wasm/completion.rs | 2 +- pyrefly/lib/test/lsp/completion.rs | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pyrefly/lib/lsp/wasm/completion.rs b/pyrefly/lib/lsp/wasm/completion.rs index f001fb7..2851eec 100644 --- a/pyrefly/lib/lsp/wasm/completion.rs +++ b/pyrefly/lib/lsp/wasm/completion.rs @@ -1186,7 +1186,7 @@ impl Transaction<'_> { let skip_value_completions = covering_nodes .as_deref() .is_some_and(|nodes| Self::is_typing_keyword_argument_name(nodes, position)); - if !skip_value_completions { + if !skip_value_completions && !is_method_def { let at_statement_start = matches!( covering_nodes.as_deref().and_then(|nodes| nodes.get(1)), Some(AnyNodeRef::StmtExpr(_)) diff --git a/pyrefly/lib/test/lsp/completion.rs b/pyrefly/lib/test/lsp/completion.rs index 0fc6ffa..3c71de0 100644 --- a/pyrefly/lib/test/lsp/completion.rs +++ b/pyrefly/lib/test/lsp/completion.rs @@ -71,6 +71,29 @@ class Foo: } } +#[test] +fn completion_method_definition_has_unique_suggestions() { + let code = r#" +class Foo: + def get_value(self) -> int: + return 1 + + def get_ +# ^ +"#; + let (handles, state) = mk_multi_file_state(&[("main", code)], Require::Exports, false); + let handle = handles.get("main").unwrap(); + let position = extract_cursors_for_test(code)[0]; + let get_value_suggestions = state + .transaction() + .completion(handle, position, ImportFormat::Absolute, true, None) + .into_iter() + .filter(|item| item.label == "get_value") + .count(); + + assert_eq!(get_value_suggestions, 1); +} + fn get_default_test_report() -> impl Fn(&State, &Handle, TextSize) -> String { get_test_report(ResultsFilter::default(), ImportFormat::Absolute) } -- 2.55.0.windows.3