Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions crates/ra_assists/src/handlers/auto_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use hir::{
AsAssocItem, AssocItemContainer, ModPath, Module, ModuleDef, PathResolution, Semantics, Trait,
Type,
};
use ra_ide_db::{imports_locator::ImportsLocator, RootDatabase};
use ra_ide_db::{imports_locator, RootDatabase};
use ra_prof::profile;
use ra_syntax::{
ast::{self, AstNode},
Expand Down Expand Up @@ -35,8 +35,8 @@ use crate::{utils::insert_use_statement, AssistContext, AssistId, Assists, Group
// # pub mod std { pub mod collections { pub struct HashMap { } } }
// ```
pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let auto_import_assets = AutoImportAssets::new(&ctx)?;
let proposed_imports = auto_import_assets.search_for_imports(ctx.db());
let auto_import_assets = AutoImportAssets::new(ctx)?;
let proposed_imports = auto_import_assets.search_for_imports(ctx);
if proposed_imports.is_empty() {
return None;
}
Expand Down Expand Up @@ -127,11 +127,11 @@ impl AutoImportAssets {
GroupLabel(name)
}

fn search_for_imports(&self, db: &RootDatabase) -> BTreeSet<ModPath> {
fn search_for_imports(&self, ctx: &AssistContext) -> BTreeSet<ModPath> {
let _p = profile("auto_import::search_for_imports");
let db = ctx.db();
let current_crate = self.module_with_name_to_import.krate();
ImportsLocator::new(db, current_crate)
.find_imports(&self.get_search_query())
imports_locator::find_imports(&ctx.sema, current_crate, &self.get_search_query())
.into_iter()
.filter_map(|candidate| match &self.import_candidate {
ImportCandidate::TraitAssocItem(assoc_item_type, _) => {
Expand Down
88 changes: 42 additions & 46 deletions crates/ra_ide_db/src/imports_locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,53 @@ use crate::{
use either::Either;
use rustc_hash::FxHashSet;

pub struct ImportsLocator<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍

bors r+

sema: Semantics<'a, RootDatabase>,
pub fn find_imports<'a>(
sema: &Semantics<'a, RootDatabase>,
krate: Crate,
}

impl<'a> ImportsLocator<'a> {
pub fn new(db: &'a RootDatabase, krate: Crate) -> Self {
Self { sema: Semantics::new(db), krate }
}
name_to_import: &str,
) -> Vec<Either<ModuleDef, MacroDef>> {
let _p = profile("search_for_imports");
let db = sema.db;

pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Either<ModuleDef, MacroDef>> {
let _p = profile("search_for_imports");
let db = self.sema.db;
// Query dependencies first.
let mut candidates: FxHashSet<_> =
krate.query_external_importables(db, name_to_import).collect();

// Query dependencies first.
let mut candidates: FxHashSet<_> =
self.krate.query_external_importables(db, name_to_import).collect();
// Query the local crate using the symbol index.
let local_results = {
let mut query = Query::new(name_to_import.to_string());
query.exact();
query.limit(40);
symbol_index::crate_symbols(db, krate.into(), query)
};

// Query the local crate using the symbol index.
let local_results = {
let mut query = Query::new(name_to_import.to_string());
query.exact();
query.limit(40);
symbol_index::crate_symbols(db, self.krate.into(), query)
};
candidates.extend(
local_results
.into_iter()
.filter_map(|import_candidate| get_name_definition(sema, &import_candidate))
.filter_map(|name_definition_to_import| match name_definition_to_import {
Definition::ModuleDef(module_def) => Some(Either::Left(module_def)),
Definition::Macro(macro_def) => Some(Either::Right(macro_def)),
_ => None,
}),
);

candidates.extend(
local_results
.into_iter()
.filter_map(|import_candidate| self.get_name_definition(&import_candidate))
.filter_map(|name_definition_to_import| match name_definition_to_import {
Definition::ModuleDef(module_def) => Some(Either::Left(module_def)),
Definition::Macro(macro_def) => Some(Either::Right(macro_def)),
_ => None,
}),
);

candidates.into_iter().collect()
}
candidates.into_iter().collect()
}

fn get_name_definition(&mut self, import_candidate: &FileSymbol) -> Option<Definition> {
let _p = profile("get_name_definition");
let file_id = import_candidate.file_id;
fn get_name_definition<'a>(
sema: &Semantics<'a, RootDatabase>,
import_candidate: &FileSymbol,
) -> Option<Definition> {
let _p = profile("get_name_definition");
let file_id = import_candidate.file_id;

let candidate_node = import_candidate.ptr.to_node(self.sema.parse(file_id).syntax());
let candidate_name_node = if candidate_node.kind() != NAME {
candidate_node.children().find(|it| it.kind() == NAME)?
} else {
candidate_node
};
let name = ast::Name::cast(candidate_name_node)?;
classify_name(&self.sema, &name)?.into_definition()
}
let candidate_node = import_candidate.ptr.to_node(sema.parse(file_id).syntax());
let candidate_name_node = if candidate_node.kind() != NAME {
candidate_node.children().find(|it| it.kind() == NAME)?
} else {
candidate_node
};
let name = ast::Name::cast(candidate_name_node)?;
classify_name(sema, &name)?.into_definition()
}