Use more generic public api

This commit is contained in:
Kirill Bulatov 2020-03-23 13:34:56 +02:00
parent d5e11b33a3
commit 944f28fe5b
9 changed files with 58 additions and 47 deletions

2
Cargo.lock generated
View file

@ -884,6 +884,7 @@ version = "0.1.0"
name = "ra_assists" name = "ra_assists"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"either",
"format-buf", "format-buf",
"itertools 0.9.0", "itertools 0.9.0",
"join_to_string", "join_to_string",
@ -1045,6 +1046,7 @@ dependencies = [
name = "ra_ide_db" name = "ra_ide_db"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"either",
"fst", "fst",
"log", "log",
"once_cell", "once_cell",

View file

@ -12,6 +12,7 @@ format-buf = "1.0.0"
join_to_string = "0.1.3" join_to_string = "0.1.3"
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
itertools = "0.9.0" itertools = "0.9.0"
either = "1.5.3"
ra_syntax = { path = "../ra_syntax" } ra_syntax = { path = "../ra_syntax" }
ra_text_edit = { path = "../ra_text_edit" } ra_text_edit = { path = "../ra_text_edit" }

View file

@ -129,7 +129,7 @@ impl<'a> QualifyPaths<'a> {
let resolution = self.source_scope.resolve_hir_path(&hir_path?)?; let resolution = self.source_scope.resolve_hir_path(&hir_path?)?;
match resolution { match resolution {
PathResolution::Def(def) => { PathResolution::Def(def) => {
let found_path = from.find_use_path(self.source_scope.db, def.into())?; let found_path = from.find_use_path(self.source_scope.db, def)?;
let mut path = path_to_ast(found_path); let mut path = path_to_ast(found_path);
let type_args = p let type_args = p

View file

@ -4,7 +4,7 @@ use hir::{
AsAssocItem, AssocItemContainer, ModPath, Module, ModuleDef, PathResolution, Semantics, Trait, AsAssocItem, AssocItemContainer, ModPath, Module, ModuleDef, PathResolution, Semantics, Trait,
Type, Type,
}; };
use ra_ide_db::{defs::Definition, imports_locator::ImportsLocator, RootDatabase}; use ra_ide_db::{imports_locator::ImportsLocator, RootDatabase};
use ra_prof::profile; use ra_prof::profile;
use ra_syntax::{ use ra_syntax::{
ast::{self, AstNode}, ast::{self, AstNode},
@ -17,6 +17,7 @@ use crate::{
utils::insert_use_statement, utils::insert_use_statement,
AssistId, AssistId,
}; };
use either::Either;
// Assist: auto_import // Assist: auto_import
// //
@ -127,16 +128,14 @@ impl AutoImportAssets {
ImportsLocator::new(db) ImportsLocator::new(db)
.find_imports(&self.get_search_query()) .find_imports(&self.get_search_query())
.into_iter() .into_iter()
.filter_map(|definition| match &self.import_candidate { .filter_map(|candidate| match &self.import_candidate {
ImportCandidate::TraitAssocItem(assoc_item_type, _) => { ImportCandidate::TraitAssocItem(assoc_item_type, _) => {
let located_assoc_item = match definition { let located_assoc_item = match candidate {
Definition::ModuleDef(ModuleDef::Function(located_function)) => { Either::Left(ModuleDef::Function(located_function)) => located_function
located_function .as_assoc_item(db)
.as_assoc_item(db) .map(|assoc| assoc.container(db))
.map(|assoc| assoc.container(db)) .and_then(Self::assoc_to_trait),
.and_then(Self::assoc_to_trait) Either::Left(ModuleDef::Const(located_const)) => located_const
}
Definition::ModuleDef(ModuleDef::Const(located_const)) => located_const
.as_assoc_item(db) .as_assoc_item(db)
.map(|assoc| assoc.container(db)) .map(|assoc| assoc.container(db))
.and_then(Self::assoc_to_trait), .and_then(Self::assoc_to_trait),
@ -154,13 +153,12 @@ impl AutoImportAssets {
None, None,
|_, assoc| Self::assoc_to_trait(assoc.container(db)), |_, assoc| Self::assoc_to_trait(assoc.container(db)),
) )
.map(|located_trait| ModuleDef::from(located_trait).into()) .map(ModuleDef::from)
.map(Either::Left)
} }
ImportCandidate::TraitMethod(function_callee, _) => { ImportCandidate::TraitMethod(function_callee, _) => {
let located_assoc_item = let located_assoc_item =
if let Definition::ModuleDef(ModuleDef::Function(located_function)) = if let Either::Left(ModuleDef::Function(located_function)) = candidate {
definition
{
located_function located_function
.as_assoc_item(db) .as_assoc_item(db)
.map(|assoc| assoc.container(db)) .map(|assoc| assoc.container(db))
@ -182,15 +180,19 @@ impl AutoImportAssets {
Self::assoc_to_trait(function.as_assoc_item(db)?.container(db)) Self::assoc_to_trait(function.as_assoc_item(db)?.container(db))
}, },
) )
.map(|located_trait| ModuleDef::from(located_trait).into()) .map(ModuleDef::from)
.map(Either::Left)
}
_ => Some(candidate),
})
.filter_map(|candidate| match candidate {
Either::Left(module_def) => {
self.module_with_name_to_import.find_use_path(db, module_def)
}
Either::Right(macro_def) => {
self.module_with_name_to_import.find_use_path(db, macro_def)
} }
_ => match definition {
Definition::ModuleDef(module_def) => Some(module_def.into()),
Definition::Macro(macro_def) => Some(macro_def.into()),
_ => None,
},
}) })
.filter_map(|item| self.module_with_name_to_import.find_use_path(db, item))
.filter(|use_path| !use_path.segments.is_empty()) .filter(|use_path| !use_path.segments.is_empty())
.take(20) .take(20)
.collect::<BTreeSet<_>>() .collect::<BTreeSet<_>>()

View file

@ -154,8 +154,7 @@ fn resolve_tuple_of_enum_def(
} }
fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> { fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> {
let path = let path = crate::ast_transform::path_to_ast(module.find_use_path(db, ModuleDef::from(var))?);
crate::ast_transform::path_to_ast(module.find_use_path(db, ModuleDef::from(var).into())?);
// FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
let pat: ast::Pat = match var.source(db).value.kind() { let pat: ast::Pat = match var.source(db).value.kind() {

View file

@ -143,17 +143,6 @@ impl ModuleDef {
} }
} }
impl From<ModuleDef> for ItemInNs {
fn from(module_def: ModuleDef) -> Self {
match module_def {
ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::Function(_) => {
ItemInNs::Values(module_def.into())
}
_ => ItemInNs::Types(module_def.into()),
}
}
}
pub use hir_def::{ pub use hir_def::{
attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc, attr::Attrs, item_scope::ItemInNs, visibility::Visibility, AssocItemId, AssocItemLoc,
}; };
@ -290,9 +279,9 @@ impl Module {
pub fn find_use_path( pub fn find_use_path(
self, self,
db: &dyn DefDatabase, db: &dyn DefDatabase,
item: ItemInNs, item: impl Into<ItemInNs>,
) -> Option<hir_def::path::ModPath> { ) -> Option<hir_def::path::ModPath> {
hir_def::find_path::find_path(db, item, self.into()) hir_def::find_path::find_path(db, item.into(), self.into())
} }
} }
@ -764,12 +753,6 @@ impl MacroDef {
} }
} }
impl From<MacroDef> for ItemInNs {
fn from(macro_def: MacroDef) -> Self {
ItemInNs::Macros(macro_def.into())
}
}
/// Invariant: `inner.as_assoc_item(db).is_some()` /// Invariant: `inner.as_assoc_item(db).is_some()`
/// We do not actively enforce this invariant. /// We do not actively enforce this invariant.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]

View file

@ -9,8 +9,8 @@ use hir_def::{
}; };
use crate::{ use crate::{
Adt, AssocItem, AttrDef, DefWithBody, EnumVariant, GenericDef, Local, ModuleDef, StructField, code_model::ItemInNs, Adt, AssocItem, AttrDef, DefWithBody, EnumVariant, GenericDef, Local,
VariantDef, MacroDef, ModuleDef, StructField, VariantDef,
}; };
macro_rules! from_id { macro_rules! from_id {
@ -228,3 +228,20 @@ impl From<(DefWithBodyId, PatId)> for Local {
Local { parent, pat_id } Local { parent, pat_id }
} }
} }
impl From<MacroDef> for ItemInNs {
fn from(macro_def: MacroDef) -> Self {
ItemInNs::Macros(macro_def.into())
}
}
impl From<ModuleDef> for ItemInNs {
fn from(module_def: ModuleDef) -> Self {
match module_def {
ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::Function(_) => {
ItemInNs::Values(module_def.into())
}
_ => ItemInNs::Types(module_def.into()),
}
}
}

View file

@ -17,6 +17,7 @@ fst = { version = "0.4", default-features = false }
rustc-hash = "1.1.0" rustc-hash = "1.1.0"
superslice = "1.0.0" superslice = "1.0.0"
once_cell = "1.3.1" once_cell = "1.3.1"
either = "1.5.3"
ra_syntax = { path = "../ra_syntax" } ra_syntax = { path = "../ra_syntax" }
ra_text_edit = { path = "../ra_text_edit" } ra_text_edit = { path = "../ra_text_edit" }

View file

@ -1,7 +1,7 @@
//! This module contains an import search funcionality that is provided to the ra_assists module. //! This module contains an import search funcionality that is provided to the ra_assists module.
//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. //! Later, this should be moved away to a separate crate that is accessible from the ra_assists module.
use hir::Semantics; use hir::{MacroDef, ModuleDef, Semantics};
use ra_prof::profile; use ra_prof::profile;
use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
@ -10,6 +10,7 @@ use crate::{
symbol_index::{self, FileSymbol, Query}, symbol_index::{self, FileSymbol, Query},
RootDatabase, RootDatabase,
}; };
use either::Either;
pub struct ImportsLocator<'a> { pub struct ImportsLocator<'a> {
sema: Semantics<'a, RootDatabase>, sema: Semantics<'a, RootDatabase>,
@ -20,7 +21,7 @@ impl<'a> ImportsLocator<'a> {
Self { sema: Semantics::new(db) } Self { sema: Semantics::new(db) }
} }
pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Definition> { pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Either<ModuleDef, MacroDef>> {
let _p = profile("search_for_imports"); let _p = profile("search_for_imports");
let db = self.sema.db; let db = self.sema.db;
@ -42,6 +43,11 @@ impl<'a> ImportsLocator<'a> {
.into_iter() .into_iter()
.chain(lib_results.into_iter()) .chain(lib_results.into_iter())
.filter_map(|import_candidate| self.get_name_definition(&import_candidate)) .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,
})
.collect() .collect()
} }