@@ -21,7 +21,7 @@ use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
21
21
use text_edit:: TextEdit ;
22
22
23
23
use crate :: {
24
- context:: { DotAccess , PathCompletionCtx , PathKind , PatternContext } ,
24
+ context:: { DotAccess , DotAccessKind , PathCompletionCtx , PathKind , PatternContext } ,
25
25
item:: { Builder , CompletionRelevanceTypeMatch } ,
26
26
render:: {
27
27
function:: render_fn,
@@ -150,17 +150,34 @@ pub(crate) fn render_field(
150
150
. lookup_by ( name) ;
151
151
if ty. is_fn ( ) || ty. is_closure ( ) {
152
152
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
+ }
160
162
builder. replace (
161
163
ctx. source_range ( ) ,
162
164
field_with_receiver ( db, receiver. as_ref ( ) , & escaped_name) . into ( ) ,
163
165
) ;
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
+
164
181
item. text_edit ( builder. finish ( ) ) ;
165
182
} else {
166
183
item. insert_text ( field_with_receiver ( db, receiver. as_ref ( ) , & escaped_name) ) ;
0 commit comments