@@ -21,7 +21,7 @@ use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
2121use text_edit:: TextEdit ;
2222
2323use crate :: {
24- context:: { DotAccess , PathCompletionCtx , PathKind , PatternContext } ,
24+ context:: { DotAccess , DotAccessKind , PathCompletionCtx , PathKind , PatternContext } ,
2525 item:: { Builder , CompletionRelevanceTypeMatch } ,
2626 render:: {
2727 function:: render_fn,
@@ -150,17 +150,34 @@ pub(crate) fn render_field(
150150 . lookup_by ( name) ;
151151 if ty. is_fn ( ) || ty. is_closure ( ) {
152152 let mut builder = TextEdit :: builder ( ) ;
153- // Use TextEdit to insert / replace the ranges:
154- // 1. Insert one character ('(') before start of struct name
155- // 2. Insert one character (')') before call parens
156- // 3. Variable character of the actual field name
157- // 4. Optionally, two character ('()') for fn call
158- //
159- // TODO: Find a way to get the above ranges, especially the first two
153+ // Using TextEdit, insert '(' before the struct name and ')' before the
154+ // dot access, then comes the field name and optionally insert function
155+ // call parens.
156+
157+ if let Some ( receiver) = & dot_access. receiver {
158+ let range = receiver. syntax ( ) . text_range ( ) ;
159+ builder. insert ( range. start ( ) , "(" . to_string ( ) ) ;
160+ builder. insert ( range. end ( ) , ")" . to_string ( ) ) ;
161+ }
160162 builder. replace (
161163 ctx. source_range ( ) ,
162164 field_with_receiver ( db, receiver. as_ref ( ) , & escaped_name) . into ( ) ,
163165 ) ;
166+
167+ let is_fn_expected =
168+ ctx. completion . expected_type . as_ref ( ) . map_or ( false , |ty| ty. is_fn ( ) || ty. is_closure ( ) ) ;
169+
170+ // This could be refactored as method of DotAccessKind
171+ let is_parens_needed = if let DotAccessKind :: Method { has_parens } = dot_access. kind {
172+ !has_parens
173+ } else {
174+ true
175+ } ;
176+
177+ if !is_fn_expected && is_parens_needed {
178+ builder. insert ( ctx. source_range ( ) . end ( ) , "()" . to_string ( ) ) ;
179+ }
180+
164181 item. text_edit ( builder. finish ( ) ) ;
165182 } else {
166183 item. insert_text ( field_with_receiver ( db, receiver. as_ref ( ) , & escaped_name) ) ;
0 commit comments