From 6dae5cbb1190cde6a20aa1758c7d87e84933378e Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 2 Feb 2020 14:06:51 +0200 Subject: Require ModPath for importing --- crates/ra_ide/src/completion/complete_scope.rs | 71 +++++++++++++++++--------- 1 file changed, 47 insertions(+), 24 deletions(-) (limited to 'crates/ra_ide/src/completion/complete_scope.rs') diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs index 458d7525e..fe0795984 100644 --- a/crates/ra_ide/src/completion/complete_scope.rs +++ b/crates/ra_ide/src/completion/complete_scope.rs @@ -6,6 +6,7 @@ use ra_text_edit::TextEditBuilder; use rustc_hash::FxHashMap; use crate::completion::{CompletionContext, CompletionItem, CompletionKind, Completions}; +use hir::{ModPath, PathKind}; pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { if !ctx.is_trivial_path { @@ -54,58 +55,80 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { } } -fn build_import_label(name: &str, path: &[SmolStr]) -> String { +fn build_import_label(name: &str, path: &ModPath) -> String { let mut buf = String::with_capacity(64); buf.push_str(name); buf.push_str(" ("); - fmt_import_path(path, &mut buf); + buf.push_str(&path.to_string()); buf.push_str(")"); buf } -fn fmt_import_path(path: &[SmolStr], buf: &mut String) { - let mut segments = path.iter(); - if let Some(s) = segments.next() { - buf.push_str(&s); - } - for s in segments { - buf.push_str("::"); - buf.push_str(&s); - } -} - #[derive(Debug, Clone, Default)] pub(crate) struct ImportResolver { // todo: use fst crate or something like that - dummy_names: Vec<(SmolStr, Vec)>, + dummy_names: Vec<(SmolStr, ModPath)>, } impl ImportResolver { pub(crate) fn new() -> Self { let dummy_names = vec![ - (SmolStr::new("fmt"), vec![SmolStr::new("std"), SmolStr::new("fmt")]), - (SmolStr::new("io"), vec![SmolStr::new("std"), SmolStr::new("io")]), - (SmolStr::new("iter"), vec![SmolStr::new("std"), SmolStr::new("iter")]), - (SmolStr::new("hash"), vec![SmolStr::new("std"), SmolStr::new("hash")]), + ( + SmolStr::new("fmt"), + ModPath { kind: PathKind::Plain, segments: vec![hir::known::std, hir::known::fmt] }, + ), + ( + SmolStr::new("io"), + ModPath { kind: PathKind::Plain, segments: vec![hir::known::std, hir::known::io] }, + ), + ( + SmolStr::new("iter"), + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::iter], + }, + ), + ( + SmolStr::new("hash"), + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::hash], + }, + ), ( SmolStr::new("Debug"), - vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Debug")], + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::fmt, hir::known::Debug], + }, ), ( SmolStr::new("Display"), - vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Display")], + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::fmt, hir::known::Display], + }, ), ( SmolStr::new("Hash"), - vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hash")], + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::hash, hir::known::Hash], + }, ), ( SmolStr::new("Hasher"), - vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hasher")], + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::hash, hir::known::Hasher], + }, ), ( SmolStr::new("Iterator"), - vec![SmolStr::new("std"), SmolStr::new("iter"), SmolStr::new("Iterator")], + ModPath { + kind: PathKind::Plain, + segments: vec![hir::known::std, hir::known::iter, hir::known::Iterator], + }, ), ]; @@ -115,7 +138,7 @@ impl ImportResolver { // Returns a map of importable items filtered by name. // The map associates item name with its full path. // todo: should return Resolutions - pub(crate) fn all_names(&self, name: &str) -> FxHashMap> { + pub(crate) fn all_names(&self, name: &str) -> FxHashMap { if name.len() > 1 { self.dummy_names.iter().filter(|(n, _)| n.contains(name)).cloned().collect() } else { -- cgit v1.2.3 From c669b2f489cb551fbe53fd01f7532b5d55ffe704 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 2 Feb 2020 14:27:52 +0200 Subject: Code review fixes --- crates/ra_ide/src/completion/complete_scope.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'crates/ra_ide/src/completion/complete_scope.rs') diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs index fe0795984..64b04ec2b 100644 --- a/crates/ra_ide/src/completion/complete_scope.rs +++ b/crates/ra_ide/src/completion/complete_scope.rs @@ -72,62 +72,58 @@ pub(crate) struct ImportResolver { impl ImportResolver { pub(crate) fn new() -> Self { + use hir::name; + let dummy_names = vec![ ( SmolStr::new("fmt"), - ModPath { kind: PathKind::Plain, segments: vec![hir::known::std, hir::known::fmt] }, + ModPath { kind: PathKind::Plain, segments: vec![name![std], name![fmt]] }, ), ( SmolStr::new("io"), - ModPath { kind: PathKind::Plain, segments: vec![hir::known::std, hir::known::io] }, + ModPath { kind: PathKind::Plain, segments: vec![name![std], name![io]] }, ), ( SmolStr::new("iter"), - ModPath { - kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::iter], - }, + ModPath { kind: PathKind::Plain, segments: vec![name![std], name![iter]] }, ), ( SmolStr::new("hash"), - ModPath { - kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::hash], - }, + ModPath { kind: PathKind::Plain, segments: vec![name![std], name![hash]] }, ), ( SmolStr::new("Debug"), ModPath { kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::fmt, hir::known::Debug], + segments: vec![name![std], name![fmt], name![Debug]], }, ), ( SmolStr::new("Display"), ModPath { kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::fmt, hir::known::Display], + segments: vec![name![std], name![fmt], name![Display]], }, ), ( SmolStr::new("Hash"), ModPath { kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::hash, hir::known::Hash], + segments: vec![name![std], name![hash], name![Hash]], }, ), ( SmolStr::new("Hasher"), ModPath { kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::hash, hir::known::Hasher], + segments: vec![name![std], name![hash], name![Hasher]], }, ), ( SmolStr::new("Iterator"), ModPath { kind: PathKind::Plain, - segments: vec![hir::known::std, hir::known::iter, hir::known::Iterator], + segments: vec![name![std], name![iter], name![Iterator]], }, ), ]; -- cgit v1.2.3 From 740a26b7d26a68cc46becda3cca39091e8da67fc Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 7 Feb 2020 23:35:34 +0200 Subject: Rename add import assist --- crates/ra_ide/src/completion/complete_scope.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'crates/ra_ide/src/completion/complete_scope.rs') diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs index 64b04ec2b..aaa9985d4 100644 --- a/crates/ra_ide/src/completion/complete_scope.rs +++ b/crates/ra_ide/src/completion/complete_scope.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use ra_assists::auto_import_text_edit; +use ra_assists::insert_use_statement; use ra_syntax::{ast, AstNode, SmolStr}; use ra_text_edit::TextEditBuilder; use rustc_hash::FxHashMap; @@ -26,12 +26,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { let edit = { let mut builder = TextEditBuilder::default(); builder.replace(ctx.source_range(), name.to_string()); - auto_import_text_edit( - &ctx.token.parent(), - &ctx.token.parent(), - &path, - &mut builder, - ); + insert_use_statement(&ctx.token.parent(), &ctx.token.parent(), &path, &mut builder); builder.finish() }; -- cgit v1.2.3 From 409f8e1fb058748ddd11fa10389ac4f710ea4a4c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 9 Feb 2020 10:04:47 +0100 Subject: Remove hard-coded auto-import during completion We now have a real auto-import system, so we can do a proper thing. --- crates/ra_ide/src/completion/complete_scope.rs | 131 +------------------------ 1 file changed, 3 insertions(+), 128 deletions(-) (limited to 'crates/ra_ide/src/completion/complete_scope.rs') diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs index aaa9985d4..e2ee86dd1 100644 --- a/crates/ra_ide/src/completion/complete_scope.rs +++ b/crates/ra_ide/src/completion/complete_scope.rs @@ -1,12 +1,6 @@ //! FIXME: write short doc here -use ra_assists::insert_use_statement; -use ra_syntax::{ast, AstNode, SmolStr}; -use ra_text_edit::TextEditBuilder; -use rustc_hash::FxHashMap; - -use crate::completion::{CompletionContext, CompletionItem, CompletionKind, Completions}; -use hir::{ModPath, PathKind}; +use crate::completion::{CompletionContext, Completions}; pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { if !ctx.is_trivial_path { @@ -16,133 +10,14 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { acc.add_resolution(ctx, name.to_string(), &res) }); - - // auto-import - // We fetch ident from the original file, because we need to pre-filter auto-imports - if ast::NameRef::cast(ctx.token.parent()).is_some() { - let import_resolver = ImportResolver::new(); - let import_names = import_resolver.all_names(ctx.token.text()); - import_names.into_iter().for_each(|(name, path)| { - let edit = { - let mut builder = TextEditBuilder::default(); - builder.replace(ctx.source_range(), name.to_string()); - insert_use_statement(&ctx.token.parent(), &ctx.token.parent(), &path, &mut builder); - builder.finish() - }; - - // Hack: copied this check form conv.rs beacause auto import can produce edits - // that invalidate assert in conv_with. - if edit - .as_atoms() - .iter() - .filter(|atom| !ctx.source_range().is_subrange(&atom.delete)) - .all(|atom| ctx.source_range().intersection(&atom.delete).is_none()) - { - CompletionItem::new( - CompletionKind::Reference, - ctx.source_range(), - build_import_label(&name, &path), - ) - .text_edit(edit) - .add_to(acc); - } - }); - } -} - -fn build_import_label(name: &str, path: &ModPath) -> String { - let mut buf = String::with_capacity(64); - buf.push_str(name); - buf.push_str(" ("); - buf.push_str(&path.to_string()); - buf.push_str(")"); - buf -} - -#[derive(Debug, Clone, Default)] -pub(crate) struct ImportResolver { - // todo: use fst crate or something like that - dummy_names: Vec<(SmolStr, ModPath)>, -} - -impl ImportResolver { - pub(crate) fn new() -> Self { - use hir::name; - - let dummy_names = vec![ - ( - SmolStr::new("fmt"), - ModPath { kind: PathKind::Plain, segments: vec![name![std], name![fmt]] }, - ), - ( - SmolStr::new("io"), - ModPath { kind: PathKind::Plain, segments: vec![name![std], name![io]] }, - ), - ( - SmolStr::new("iter"), - ModPath { kind: PathKind::Plain, segments: vec![name![std], name![iter]] }, - ), - ( - SmolStr::new("hash"), - ModPath { kind: PathKind::Plain, segments: vec![name![std], name![hash]] }, - ), - ( - SmolStr::new("Debug"), - ModPath { - kind: PathKind::Plain, - segments: vec![name![std], name![fmt], name![Debug]], - }, - ), - ( - SmolStr::new("Display"), - ModPath { - kind: PathKind::Plain, - segments: vec![name![std], name![fmt], name![Display]], - }, - ), - ( - SmolStr::new("Hash"), - ModPath { - kind: PathKind::Plain, - segments: vec![name![std], name![hash], name![Hash]], - }, - ), - ( - SmolStr::new("Hasher"), - ModPath { - kind: PathKind::Plain, - segments: vec![name![std], name![hash], name![Hasher]], - }, - ), - ( - SmolStr::new("Iterator"), - ModPath { - kind: PathKind::Plain, - segments: vec![name![std], name![iter], name![Iterator]], - }, - ), - ]; - - ImportResolver { dummy_names } - } - - // Returns a map of importable items filtered by name. - // The map associates item name with its full path. - // todo: should return Resolutions - pub(crate) fn all_names(&self, name: &str) -> FxHashMap { - if name.len() > 1 { - self.dummy_names.iter().filter(|(n, _)| n.contains(name)).cloned().collect() - } else { - FxHashMap::default() - } - } } #[cfg(test)] mod tests { - use crate::completion::{do_completion, CompletionItem, CompletionKind}; use insta::assert_debug_snapshot; + use crate::completion::{do_completion, CompletionItem, CompletionKind}; + fn do_reference_completion(code: &str) -> Vec { do_completion(code, CompletionKind::Reference) } -- cgit v1.2.3