mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Auto import macros
This commit is contained in:
parent
f9494f1147
commit
d221ff4f9e
5 changed files with 46 additions and 34 deletions
|
@ -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)?;
|
let found_path = from.find_use_path(self.source_scope.db, def.into())?;
|
||||||
let mut path = path_to_ast(found_path);
|
let mut path = path_to_ast(found_path);
|
||||||
|
|
||||||
let type_args = p
|
let type_args = p
|
||||||
|
|
|
@ -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::{imports_locator::ImportsLocator, RootDatabase};
|
use ra_ide_db::{defs::Definition, imports_locator::ImportsLocator, RootDatabase};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
|
@ -127,14 +127,16 @@ 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(|module_def| match &self.import_candidate {
|
.filter_map(|definition| match &self.import_candidate {
|
||||||
ImportCandidate::TraitAssocItem(assoc_item_type, _) => {
|
ImportCandidate::TraitAssocItem(assoc_item_type, _) => {
|
||||||
let located_assoc_item = match module_def {
|
let located_assoc_item = match definition {
|
||||||
ModuleDef::Function(located_function) => located_function
|
Definition::ModuleDef(ModuleDef::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)
|
||||||
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),
|
||||||
|
@ -152,11 +154,13 @@ impl AutoImportAssets {
|
||||||
None,
|
None,
|
||||||
|_, assoc| Self::assoc_to_trait(assoc.container(db)),
|
|_, assoc| Self::assoc_to_trait(assoc.container(db)),
|
||||||
)
|
)
|
||||||
.map(ModuleDef::from)
|
.map(|located_trait| ModuleDef::from(located_trait).into())
|
||||||
}
|
}
|
||||||
ImportCandidate::TraitMethod(function_callee, _) => {
|
ImportCandidate::TraitMethod(function_callee, _) => {
|
||||||
let located_assoc_item =
|
let located_assoc_item =
|
||||||
if let ModuleDef::Function(located_function) = module_def {
|
if let Definition::ModuleDef(ModuleDef::Function(located_function)) =
|
||||||
|
definition
|
||||||
|
{
|
||||||
located_function
|
located_function
|
||||||
.as_assoc_item(db)
|
.as_assoc_item(db)
|
||||||
.map(|assoc| assoc.container(db))
|
.map(|assoc| assoc.container(db))
|
||||||
|
@ -178,11 +182,15 @@ 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(ModuleDef::from)
|
.map(|located_trait| ModuleDef::from(located_trait).into())
|
||||||
}
|
}
|
||||||
_ => Some(module_def),
|
_ => match definition {
|
||||||
|
Definition::ModuleDef(module_def) => Some(module_def.into()),
|
||||||
|
Definition::Macro(macro_def) => Some(macro_def.into()),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.filter_map(|module_def| self.module_with_name_to_import.find_use_path(db, module_def))
|
.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<_>>()
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir::{Adt, HasSource, Semantics};
|
use hir::{Adt, HasSource, ModuleDef, Semantics};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
|
|
||||||
|
@ -154,7 +154,8 @@ 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 = crate::ast_transform::path_to_ast(module.find_use_path(db, var.into())?);
|
let path =
|
||||||
|
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() {
|
||||||
|
|
|
@ -139,6 +139,17 @@ 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,
|
||||||
};
|
};
|
||||||
|
@ -275,19 +286,9 @@ impl Module {
|
||||||
pub fn find_use_path(
|
pub fn find_use_path(
|
||||||
self,
|
self,
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
item: ModuleDef,
|
item: ItemInNs,
|
||||||
) -> Option<hir_def::path::ModPath> {
|
) -> Option<hir_def::path::ModPath> {
|
||||||
// FIXME expose namespace choice
|
hir_def::find_path::find_path(db.upcast(), item, self.into())
|
||||||
hir_def::find_path::find_path(db.upcast(), determine_item_namespace(item), self.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn determine_item_namespace(module_def: ModuleDef) -> ItemInNs {
|
|
||||||
match module_def {
|
|
||||||
ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::Function(_) => {
|
|
||||||
ItemInNs::Values(module_def.into())
|
|
||||||
}
|
|
||||||
_ => ItemInNs::Types(module_def.into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,6 +760,12 @@ 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)]
|
||||||
|
|
|
@ -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::{ModuleDef, Semantics};
|
use hir::Semantics;
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
|
use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
|
||||||
|
|
||||||
|
@ -20,7 +20,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<ModuleDef> {
|
pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Definition> {
|
||||||
let _p = profile("search_for_imports");
|
let _p = profile("search_for_imports");
|
||||||
let db = self.sema.db;
|
let db = self.sema.db;
|
||||||
|
|
||||||
|
@ -42,10 +42,6 @@ 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(module_def),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue