]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide_completion/src/completions/fn_param.rs
Replace some String usages with SmolStr in completions
[rust.git] / crates / ide_completion / src / completions / fn_param.rs
index 0ea55848936cd02c38eb3495d12cb69d00afa46d..5acda464982cbf21a20d75ccbaecc17b539763bd 100644 (file)
@@ -1,20 +1,24 @@
-//! See `complete_fn_param`.
+//! See [`complete_fn_param`].
 
 use rustc_hash::FxHashMap;
 use syntax::{
-    ast::{self, ModuleItemOwner},
+    ast::{self, HasModuleItem},
     match_ast, AstNode,
 };
 
-use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
+use crate::{
+    context::{ParamKind, PatternContext},
+    CompletionContext, CompletionItem, CompletionItemKind, Completions,
+};
 
 /// Complete repeated parameters, both name and type. For example, if all
 /// functions in a file have a `spam: &mut Spam` parameter, a completion with
 /// `spam: &mut Spam` insert text/label and `spam` lookup string will be
 /// suggested.
-pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) {
-    if !ctx.is_param {
-        return;
+pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
+    if !matches!(ctx.pattern_ctx, Some(PatternContext { is_param: Some(ParamKind::Function), .. }))
+    {
+        return None;
     }
 
     let mut params = FxHashMap::default();
@@ -26,6 +30,7 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
         }
         func.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| {
             if let Some(pat) = param.pat() {
+                // FIXME: We should be able to turn these into SmolStr without having to allocate a String
                 let text = param.syntax().text().to_string();
                 let lookup = pat.syntax().text().to_string();
                 params.entry(text).or_insert(lookup);
@@ -53,79 +58,25 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
         };
     }
 
-    params.into_iter().for_each(|(label, lookup)| {
-        let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label);
-        item.kind(CompletionItemKind::Binding).lookup_by(lookup);
-        item.add_to(acc)
-    });
-}
-
-#[cfg(test)]
-mod tests {
-    use expect_test::{expect, Expect};
-
-    use crate::{test_utils::completion_list, CompletionKind};
-
-    fn check(ra_fixture: &str, expect: Expect) {
-        let actual = completion_list(ra_fixture, CompletionKind::Magic);
-        expect.assert_eq(&actual);
-    }
-
-    #[test]
-    fn test_param_completion_last_param() {
-        check(
-            r#"
-fn foo(file_id: FileId) {}
-fn bar(file_id: FileId) {}
-fn baz(file$0) {}
-"#,
-            expect![[r#"
-                bn file_id: FileId
-            "#]],
-        );
+    let self_completion_items = ["self", "&self", "mut self", "&mut self"];
+    if ctx.impl_def.is_some() && me?.param_list()?.params().next().is_none() {
+        self_completion_items.into_iter().for_each(|self_item| {
+            add_new_item_to_acc(ctx, acc, self_item.to_string(), self_item.to_string())
+        });
     }
 
-    #[test]
-    fn test_param_completion_nth_param() {
-        check(
-            r#"
-fn foo(file_id: FileId) {}
-fn baz(file$0, x: i32) {}
-"#,
-            expect![[r#"
-                bn file_id: FileId
-            "#]],
-        );
-    }
+    params.into_iter().for_each(|(label, lookup)| add_new_item_to_acc(ctx, acc, label, lookup));
 
-    #[test]
-    fn test_param_completion_trait_param() {
-        check(
-            r#"
-pub(crate) trait SourceRoot {
-    pub fn contains(&self, file_id: FileId) -> bool;
-    pub fn module_map(&self) -> &ModuleMap;
-    pub fn lines(&self, file_id: FileId) -> &LineIndex;
-    pub fn syntax(&self, file$0)
+    Some(())
 }
-"#,
-            expect![[r#"
-                bn file_id: FileId
-            "#]],
-        );
-    }
 
-    #[test]
-    fn completes_param_in_inner_function() {
-        check(
-            r#"
-fn outer(text: String) {
-    fn inner($0)
-}
-"#,
-            expect![[r#"
-                bn text: String
-            "#]],
-        )
-    }
+fn add_new_item_to_acc(
+    ctx: &CompletionContext,
+    acc: &mut Completions,
+    label: String,
+    lookup: String,
+) {
+    let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label);
+    item.lookup_by(lookup);
+    item.add_to(acc)
 }