From d0a782ef1c53ef5c5d3b49b02c498f7a688c3a4d Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 24 Jan 2020 09:33:18 +0200 Subject: Have a better trait interface --- crates/ra_assists/src/assists/auto_import.rs | 26 +++++++---- crates/ra_assists/src/lib.rs | 10 ++-- crates/ra_hir/src/lib.rs | 3 +- crates/ra_ide/src/imports_locator.rs | 70 ++++++++++------------------ 4 files changed, 45 insertions(+), 64 deletions(-) (limited to 'crates') diff --git a/crates/ra_assists/src/assists/auto_import.rs b/crates/ra_assists/src/assists/auto_import.rs index ae216944b..d196f6c5c 100644 --- a/crates/ra_assists/src/assists/auto_import.rs +++ b/crates/ra_assists/src/assists/auto_import.rs @@ -1,4 +1,4 @@ -use hir::db::HirDatabase; +use hir::{db::HirDatabase, AsName}; use ra_syntax::{ ast::{self, AstNode}, SmolStr, SyntaxElement, @@ -41,15 +41,21 @@ pub(crate) fn auto_import( current_file.syntax().clone() } }; + let source_analyzer = ctx.source_analyzer(&position, None); + let module_with_name_to_import = source_analyzer.module()?; + let path_to_import = ctx.covering_element().ancestors().find_map(ast::Path::cast)?; + if source_analyzer.resolve_path(ctx.db, &path_to_import).is_some() { + return None; + } - let module_with_name_to_import = ctx.source_analyzer(&position, None).module()?; - let name_to_import = hir::InFile { - file_id: ctx.frange.file_id.into(), - value: &find_applicable_name_ref(ctx.covering_element())?, - }; - - let proposed_imports = - imports_locator.find_imports(name_to_import, module_with_name_to_import)?; + let name_to_import = &find_applicable_name_ref(ctx.covering_element())?.as_name(); + let proposed_imports = imports_locator + .find_imports(&name_to_import.to_string()) + .into_iter() + .filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def)) + .filter(|use_path| !use_path.segments.is_empty()) + .take(20) + .collect::>(); if proposed_imports.is_empty() { return None; } @@ -57,7 +63,7 @@ pub(crate) fn auto_import( ctx.add_assist_group(AssistId("auto_import"), "auto import", || { proposed_imports .into_iter() - .map(|import| import_to_action(import.to_string(), &position, &path)) + .map(|import| import_to_action(import.to_string(), &position, &path_to_import)) .collect() }) } diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index 381a51df6..9e4ebec47 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs @@ -14,9 +14,9 @@ mod test_db; pub mod ast_transform; use either::Either; -use hir::{db::HirDatabase, InFile, ModPath, Module}; +use hir::{db::HirDatabase, ModuleDef}; use ra_db::FileRange; -use ra_syntax::{ast::NameRef, TextRange, TextUnit}; +use ra_syntax::{TextRange, TextUnit}; use ra_text_edit::TextEdit; pub(crate) use crate::assist_ctx::{Assist, AssistCtx}; @@ -85,11 +85,7 @@ where /// accessible from the ra_assists crate. pub trait ImportsLocator { /// Finds all imports for the given name and the module that contains this name. - fn find_imports( - &mut self, - name_to_import: InFile<&NameRef>, - module_with_name_to_import: Module, - ) -> Option>; + fn find_imports(&mut self, name_to_import: &str) -> Vec; } /// Return all the assists applicable at the given position diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index be6dced53..21b0553be 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -58,6 +58,7 @@ pub use hir_def::{ type_ref::Mutability, }; pub use hir_expand::{ - name, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, + name::{AsName, Name}, + HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, }; pub use hir_ty::{display::HirDisplay, CallableDef}; diff --git a/crates/ra_ide/src/imports_locator.rs b/crates/ra_ide/src/imports_locator.rs index e69fb4070..b2fc48159 100644 --- a/crates/ra_ide/src/imports_locator.rs +++ b/crates/ra_ide/src/imports_locator.rs @@ -3,13 +3,11 @@ use crate::{ db::RootDatabase, - references::{classify_name, classify_name_ref, NameDefinition, NameKind}, + references::{classify_name, NameDefinition, NameKind}, symbol_index::{self, FileSymbol}, Query, }; -use ast::NameRef; -use hir::{db::HirDatabase, InFile, ModPath, Module, SourceBinder}; -use itertools::Itertools; +use hir::{db::HirDatabase, ModuleDef, SourceBinder}; use ra_assists::ImportsLocator; use ra_prof::profile; use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; @@ -23,14 +21,30 @@ impl<'a> ImportsLocatorIde<'a> { Self { source_binder: SourceBinder::new(db) } } - fn search_for_imports( + fn get_name_definition( &mut self, - name_to_import: &ast::NameRef, - module_with_name_to_import: Module, - ) -> Vec { + db: &impl HirDatabase, + import_candidate: &FileSymbol, + ) -> Option { + let _p = profile("get_name_definition"); + let file_id = import_candidate.file_id.into(); + let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); + let candidate_name_node = if candidate_node.kind() != NAME { + candidate_node.children().find(|it| it.kind() == NAME)? + } else { + candidate_node + }; + classify_name( + &mut self.source_binder, + hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, + ) + } +} + +impl<'a> ImportsLocator for ImportsLocatorIde<'a> { + fn find_imports(&mut self, name_to_import: &str) -> Vec { let _p = profile("search_for_imports"); let db = self.source_binder.db; - let name_to_import = name_to_import.text(); let project_results = { let mut query = Query::new(name_to_import.to_string()); @@ -52,47 +66,11 @@ impl<'a> ImportsLocatorIde<'a> { .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) .filter_map(|name_definition_to_import| { if let NameKind::Def(module_def) = name_definition_to_import.kind { - module_with_name_to_import.find_use_path(db, module_def) + Some(module_def) } else { None } }) - .filter(|use_path| !use_path.segments.is_empty()) - .unique() - .take(20) .collect() } - - fn get_name_definition( - &mut self, - db: &impl HirDatabase, - import_candidate: &FileSymbol, - ) -> Option { - let _p = profile("get_name_definition"); - let file_id = import_candidate.file_id.into(); - let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); - let candidate_name_node = if candidate_node.kind() != NAME { - candidate_node.children().find(|it| it.kind() == NAME)? - } else { - candidate_node - }; - classify_name( - &mut self.source_binder, - hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, - ) - } -} - -impl<'a> ImportsLocator for ImportsLocatorIde<'a> { - fn find_imports( - &mut self, - name_to_import: InFile<&NameRef>, - module_with_name_to_import: Module, - ) -> Option> { - if classify_name_ref(&mut self.source_binder, name_to_import).is_none() { - Some(self.search_for_imports(name_to_import.value, module_with_name_to_import)) - } else { - None - } - } } -- cgit v1.2.3