mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Have a better trait interface
This commit is contained in:
parent
bef5cf0b99
commit
d0a782ef1c
4 changed files with 53 additions and 72 deletions
|
@ -1,4 +1,4 @@
|
||||||
use hir::db::HirDatabase;
|
use hir::{db::HirDatabase, AsName};
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SmolStr, SyntaxElement,
|
SmolStr, SyntaxElement,
|
||||||
|
@ -41,15 +41,21 @@ pub(crate) fn auto_import<F: ImportsLocator>(
|
||||||
current_file.syntax().clone()
|
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 = &find_applicable_name_ref(ctx.covering_element())?.as_name();
|
||||||
let name_to_import = hir::InFile {
|
let proposed_imports = imports_locator
|
||||||
file_id: ctx.frange.file_id.into(),
|
.find_imports(&name_to_import.to_string())
|
||||||
value: &find_applicable_name_ref(ctx.covering_element())?,
|
.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())
|
||||||
let proposed_imports =
|
.take(20)
|
||||||
imports_locator.find_imports(name_to_import, module_with_name_to_import)?;
|
.collect::<std::collections::HashSet<_>>();
|
||||||
if proposed_imports.is_empty() {
|
if proposed_imports.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +63,7 @@ pub(crate) fn auto_import<F: ImportsLocator>(
|
||||||
ctx.add_assist_group(AssistId("auto_import"), "auto import", || {
|
ctx.add_assist_group(AssistId("auto_import"), "auto import", || {
|
||||||
proposed_imports
|
proposed_imports
|
||||||
.into_iter()
|
.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()
|
.collect()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ mod test_db;
|
||||||
pub mod ast_transform;
|
pub mod ast_transform;
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{db::HirDatabase, InFile, ModPath, Module};
|
use hir::{db::HirDatabase, ModuleDef};
|
||||||
use ra_db::FileRange;
|
use ra_db::FileRange;
|
||||||
use ra_syntax::{ast::NameRef, TextRange, TextUnit};
|
use ra_syntax::{TextRange, TextUnit};
|
||||||
use ra_text_edit::TextEdit;
|
use ra_text_edit::TextEdit;
|
||||||
|
|
||||||
pub(crate) use crate::assist_ctx::{Assist, AssistCtx};
|
pub(crate) use crate::assist_ctx::{Assist, AssistCtx};
|
||||||
|
@ -85,11 +85,7 @@ where
|
||||||
/// accessible from the ra_assists crate.
|
/// accessible from the ra_assists crate.
|
||||||
pub trait ImportsLocator {
|
pub trait ImportsLocator {
|
||||||
/// Finds all imports for the given name and the module that contains this name.
|
/// Finds all imports for the given name and the module that contains this name.
|
||||||
fn find_imports(
|
fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef>;
|
||||||
&mut self,
|
|
||||||
name_to_import: InFile<&NameRef>,
|
|
||||||
module_with_name_to_import: Module,
|
|
||||||
) -> Option<Vec<ModPath>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all the assists applicable at the given position
|
/// Return all the assists applicable at the given position
|
||||||
|
|
|
@ -58,6 +58,7 @@ pub use hir_def::{
|
||||||
type_ref::Mutability,
|
type_ref::Mutability,
|
||||||
};
|
};
|
||||||
pub use hir_expand::{
|
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};
|
pub use hir_ty::{display::HirDisplay, CallableDef};
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::RootDatabase,
|
db::RootDatabase,
|
||||||
references::{classify_name, classify_name_ref, NameDefinition, NameKind},
|
references::{classify_name, NameDefinition, NameKind},
|
||||||
symbol_index::{self, FileSymbol},
|
symbol_index::{self, FileSymbol},
|
||||||
Query,
|
Query,
|
||||||
};
|
};
|
||||||
use ast::NameRef;
|
use hir::{db::HirDatabase, ModuleDef, SourceBinder};
|
||||||
use hir::{db::HirDatabase, InFile, ModPath, Module, SourceBinder};
|
|
||||||
use itertools::Itertools;
|
|
||||||
use ra_assists::ImportsLocator;
|
use ra_assists::ImportsLocator;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
|
use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
|
||||||
|
@ -23,46 +21,6 @@ impl<'a> ImportsLocatorIde<'a> {
|
||||||
Self { source_binder: SourceBinder::new(db) }
|
Self { source_binder: SourceBinder::new(db) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search_for_imports(
|
|
||||||
&mut self,
|
|
||||||
name_to_import: &ast::NameRef,
|
|
||||||
module_with_name_to_import: Module,
|
|
||||||
) -> Vec<ModPath> {
|
|
||||||
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());
|
|
||||||
query.exact();
|
|
||||||
query.limit(40);
|
|
||||||
symbol_index::world_symbols(db, query)
|
|
||||||
};
|
|
||||||
let lib_results = {
|
|
||||||
let mut query = Query::new(name_to_import.to_string());
|
|
||||||
query.libs();
|
|
||||||
query.exact();
|
|
||||||
query.limit(40);
|
|
||||||
symbol_index::world_symbols(db, query)
|
|
||||||
};
|
|
||||||
|
|
||||||
project_results
|
|
||||||
.into_iter()
|
|
||||||
.chain(lib_results.into_iter())
|
|
||||||
.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)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(|use_path| !use_path.segments.is_empty())
|
|
||||||
.unique()
|
|
||||||
.take(20)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_name_definition(
|
fn get_name_definition(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
|
@ -84,15 +42,35 @@ impl<'a> ImportsLocatorIde<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ImportsLocator for ImportsLocatorIde<'a> {
|
impl<'a> ImportsLocator for ImportsLocatorIde<'a> {
|
||||||
fn find_imports(
|
fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> {
|
||||||
&mut self,
|
let _p = profile("search_for_imports");
|
||||||
name_to_import: InFile<&NameRef>,
|
let db = self.source_binder.db;
|
||||||
module_with_name_to_import: Module,
|
|
||||||
) -> Option<Vec<ModPath>> {
|
let project_results = {
|
||||||
if classify_name_ref(&mut self.source_binder, name_to_import).is_none() {
|
let mut query = Query::new(name_to_import.to_string());
|
||||||
Some(self.search_for_imports(name_to_import.value, module_with_name_to_import))
|
query.exact();
|
||||||
} else {
|
query.limit(40);
|
||||||
None
|
symbol_index::world_symbols(db, query)
|
||||||
}
|
};
|
||||||
|
let lib_results = {
|
||||||
|
let mut query = Query::new(name_to_import.to_string());
|
||||||
|
query.libs();
|
||||||
|
query.exact();
|
||||||
|
query.limit(40);
|
||||||
|
symbol_index::world_symbols(db, query)
|
||||||
|
};
|
||||||
|
|
||||||
|
project_results
|
||||||
|
.into_iter()
|
||||||
|
.chain(lib_results.into_iter())
|
||||||
|
.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 {
|
||||||
|
Some(module_def)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue