@@ -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