]> git.lizzy.rs Git - rust.git/commitdiff
dont complete () if they are already there
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 10 Jan 2019 18:38:04 +0000 (21:38 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 10 Jan 2019 18:38:04 +0000 (21:38 +0300)
crates/ra_ide_api/src/completion/complete_dot.rs
crates/ra_ide_api/src/completion/complete_path.rs
crates/ra_ide_api/src/completion/completion_context.rs
crates/ra_ide_api/src/completion/completion_item.rs

index 65bba6dc76a625e079599af0113f544738858743..80d0b166396e1d28f37f9b83d9c871ef892dc8f0 100644 (file)
@@ -16,7 +16,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca
         None => return Ok(()),
     };
     let receiver_ty = infer_result[expr].clone();
-    if !ctx.is_method_call {
+    if !ctx.is_call {
         complete_fields(acc, ctx, receiver_ty)?;
     }
     Ok(())
index 4723a65a6b0645f197233ab397b7001fce944fb7..2494d28edc8bd6d894f0fd3e3fa4181e8d09bede 100644 (file)
@@ -125,4 +125,18 @@ mod m { pub fn foo() {} }
             "foo",
         )
     }
+
+    #[test]
+    fn dont_render_function_parens_if_already_call() {
+        check_reference_completion(
+            "
+            //- /lib.rs
+            fn frobnicate() {}
+            fn main() {
+                frob<|>();
+            }
+            ",
+            "main;frobnicate",
+        )
+    }
 }
index 01786bb69e91d695ae855f7bd2ba158bd7b3dc7b..113f6c070b6847f8354dc57efdc8d723b18a6d3e 100644 (file)
@@ -32,8 +32,8 @@ pub(super) struct CompletionContext<'a> {
     pub(super) is_new_item: bool,
     /// The receiver if this is a field or method access, i.e. writing something.<|>
     pub(super) dot_receiver: Option<&'a ast::Expr>,
-    /// If this is a method call in particular, i.e. the () are already there.
-    pub(super) is_method_call: bool,
+    /// If this is a call (method or function) in particular, i.e. the () are already there.
+    pub(super) is_call: bool,
 }
 
 impl<'a> CompletionContext<'a> {
@@ -60,7 +60,7 @@ pub(super) fn new(
             can_be_stmt: false,
             is_new_item: false,
             dot_receiver: None,
-            is_method_call: false,
+            is_call: false,
         };
         ctx.fill(original_file, position.offset);
         Ok(Some(ctx))
@@ -172,6 +172,12 @@ fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::N
                     }
                 }
             }
+            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) {
             // The receiver comes before the point of insertion of the fake
@@ -187,7 +193,7 @@ fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::N
                 .expr()
                 .map(|e| e.syntax().range())
                 .and_then(|r| find_node_with_range(original_file.syntax(), r));
-            self.is_method_call = true;
+            self.is_call = true;
         }
     }
 }
index 334449faec637699eaba7b9af5964618b24d068f..6a97704299ec074995c59393265c651431ada9a4 100644 (file)
@@ -165,7 +165,7 @@ pub(super) fn from_resolution(
 
     fn from_function(mut self, ctx: &CompletionContext, function: hir::Function) -> Builder {
         // 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() {
                 self.snippet = Some(format!("{}()$0", self.label));
             } else {