move auto-imoprter into IDE

auto-import is purely an IDE concern, so it should be done outside of
HIR
This commit is contained in:
Aleksey Kladov 2019-04-22 15:56:28 +03:00
parent 200032852b
commit e01052d1f0
7 changed files with 68 additions and 92 deletions

View file

@ -1,6 +1,8 @@
use rustc_hash::FxHashMap;
use ra_text_edit::TextEditBuilder;
use ra_syntax::SmolStr;
use ra_assists::auto_import;
use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext};
pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
@ -10,7 +12,8 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
}
if let Some(name) = ctx.path_ident.as_ref() {
let import_names = ctx.analyzer.all_import_names(ctx.db, name);
let import_resolver = ImportResolver::new();
let import_names = import_resolver.all_names(&name.to_string());
import_names.into_iter().for_each(|(name, path)| {
let edit = {
let mut builder = TextEditBuilder::default();
@ -64,6 +67,56 @@ fn fmt_import_path(path: &Vec<SmolStr>, buf: &mut String) {
}
}
#[derive(Debug, Clone, Default)]
pub(crate) struct ImportResolver {
// todo: use fst crate or something like that
dummy_names: Vec<(SmolStr, Vec<SmolStr>)>,
}
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("Debug"),
vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Debug")],
),
(
SmolStr::new("Display"),
vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Display")],
),
(
SmolStr::new("Hash"),
vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hash")],
),
(
SmolStr::new("Hasher"),
vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hasher")],
),
(
SmolStr::new("Iterator"),
vec![SmolStr::new("std"), SmolStr::new("iter"), SmolStr::new("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<SmolStr, Vec<SmolStr>> {
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::{CompletionKind, check_completion};

View file

@ -86,18 +86,6 @@ impl<'a> CompletionContext<'a> {
}
fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) {
// We heed the original NameRef before the "intellijRulezz" hack
if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(original_file.syntax(), offset)
{
if let Some(path) = name_ref.syntax().ancestors().find_map(ast::Path::cast) {
if let Some(path) = hir::Path::from_ast(path) {
if let Some(ident) = path.as_ident() {
self.path_ident = Some(ident.clone());
}
}
}
}
// Insert a fake ident to get a valid parse tree. We will use this file
// to determine context, though the original_file will be used for
// actual completion.