Skip to content

Commit 7cf3ab4

Browse files
committed
implement completion render for callable fields
1 parent a0e690a commit 7cf3ab4

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

crates/ide-completion/src/render.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
2121
use text_edit::TextEdit;
2222

2323
use 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

Comments
 (0)