dont complete () if they are already there

This commit is contained in:
Aleksey Kladov 2019-01-10 21:38:04 +03:00
parent f96312b836
commit faa1d35cbc
4 changed files with 26 additions and 6 deletions

View file

@ -16,7 +16,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca
None => return Ok(()), None => return Ok(()),
}; };
let receiver_ty = infer_result[expr].clone(); let receiver_ty = infer_result[expr].clone();
if !ctx.is_method_call { if !ctx.is_call {
complete_fields(acc, ctx, receiver_ty)?; complete_fields(acc, ctx, receiver_ty)?;
} }
Ok(()) Ok(())

View file

@ -125,4 +125,18 @@ mod tests {
"foo", "foo",
) )
} }
#[test]
fn dont_render_function_parens_if_already_call() {
check_reference_completion(
"
//- /lib.rs
fn frobnicate() {}
fn main() {
frob<|>();
}
",
"main;frobnicate",
)
}
} }

View file

@ -32,8 +32,8 @@ pub(super) struct CompletionContext<'a> {
pub(super) is_new_item: bool, pub(super) is_new_item: bool,
/// The receiver if this is a field or method access, i.e. writing something.<|> /// The receiver if this is a field or method access, i.e. writing something.<|>
pub(super) dot_receiver: Option<&'a ast::Expr>, pub(super) dot_receiver: Option<&'a ast::Expr>,
/// If this is a method call in particular, i.e. the () are already there. /// If this is a call (method or function) in particular, i.e. the () are already there.
pub(super) is_method_call: bool, pub(super) is_call: bool,
} }
impl<'a> CompletionContext<'a> { impl<'a> CompletionContext<'a> {
@ -60,7 +60,7 @@ impl<'a> CompletionContext<'a> {
can_be_stmt: false, can_be_stmt: false,
is_new_item: false, is_new_item: false,
dot_receiver: None, dot_receiver: None,
is_method_call: false, is_call: false,
}; };
ctx.fill(original_file, position.offset); ctx.fill(original_file, position.offset);
Ok(Some(ctx)) Ok(Some(ctx))
@ -172,6 +172,12 @@ impl<'a> CompletionContext<'a> {
} }
} }
} }
self.is_call = path
.syntax()
.parent()
.and_then(ast::PathExpr::cast)
.and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast))
.is_some()
} }
if let Some(field_expr) = ast::FieldExpr::cast(parent) { if let Some(field_expr) = ast::FieldExpr::cast(parent) {
// The receiver comes before the point of insertion of the fake // The receiver comes before the point of insertion of the fake
@ -187,7 +193,7 @@ impl<'a> CompletionContext<'a> {
.expr() .expr()
.map(|e| e.syntax().range()) .map(|e| e.syntax().range())
.and_then(|r| find_node_with_range(original_file.syntax(), r)); .and_then(|r| find_node_with_range(original_file.syntax(), r));
self.is_method_call = true; self.is_call = true;
} }
} }
} }

View file

@ -165,7 +165,7 @@ impl Builder {
fn from_function(mut self, ctx: &CompletionContext, function: hir::Function) -> Builder { fn from_function(mut self, ctx: &CompletionContext, function: hir::Function) -> Builder {
// If not an import, add parenthesis automatically. // If not an import, add parenthesis automatically.
if ctx.use_item_syntax.is_none() { if ctx.use_item_syntax.is_none() && !ctx.is_call {
if function.signature(ctx.db).args().is_empty() { if function.signature(ctx.db).args().is_empty() {
self.snippet = Some(format!("{}()$0", self.label)); self.snippet = Some(format!("{}()$0", self.label));
} else { } else {