Move convert_to_def_in_trait
into ide-db
This commit is contained in:
parent
dcb4837b2d
commit
38c11bea21
@ -401,7 +401,7 @@ fn import_for_item(
|
||||
})
|
||||
}
|
||||
|
||||
fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
|
||||
pub fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
|
||||
Some(match item {
|
||||
ItemInNs::Types(_) | ItemInNs::Values(_) => match item_as_assoc(db, item) {
|
||||
Some(assoc_item) => match assoc_item.container(db) {
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
use base_db::{AnchoredPathBuf, FileId, FileRange};
|
||||
use either::Either;
|
||||
use hir::{AsAssocItem, FieldSource, HasSource, InFile, ModuleSource, Semantics};
|
||||
use hir::{FieldSource, HasSource, InFile, ModuleSource, Semantics};
|
||||
use stdx::never;
|
||||
use syntax::{
|
||||
ast::{self, HasName},
|
||||
@ -37,6 +37,7 @@
|
||||
search::FileReference,
|
||||
source_change::{FileSystemEdit, SourceChange},
|
||||
syntax_helpers::node_ext::expr_as_name_ref,
|
||||
traits::convert_to_def_in_trait,
|
||||
RootDatabase,
|
||||
};
|
||||
|
||||
@ -271,7 +272,7 @@ fn rename_reference(
|
||||
}
|
||||
}
|
||||
|
||||
let def = convert_to_def_in_trait(def, sema);
|
||||
let def = convert_to_def_in_trait(sema.db, def);
|
||||
let usages = def.usages(sema).all();
|
||||
|
||||
if !usages.is_empty() && ident_kind == IdentifierKind::Underscore {
|
||||
@ -298,47 +299,6 @@ fn rename_reference(
|
||||
Ok(source_change)
|
||||
}
|
||||
|
||||
pub(crate) fn convert_to_def_in_trait(
|
||||
def: Definition,
|
||||
sema: &Semantics<RootDatabase>,
|
||||
) -> Definition {
|
||||
// HACK: resolve trait impl items to the item def of the trait definition
|
||||
// so that we properly resolve all trait item references
|
||||
let assoc_item = match def {
|
||||
Definition::Function(it) => it.as_assoc_item(sema.db),
|
||||
Definition::TypeAlias(it) => it.as_assoc_item(sema.db),
|
||||
Definition::Const(it) => it.as_assoc_item(sema.db),
|
||||
_ => None,
|
||||
};
|
||||
match assoc_item {
|
||||
Some(assoc) => assoc
|
||||
.containing_trait_impl(sema.db)
|
||||
.and_then(|trait_| {
|
||||
trait_.items(sema.db).into_iter().find_map(|it| match (it, assoc) {
|
||||
(hir::AssocItem::Function(trait_func), hir::AssocItem::Function(func))
|
||||
if trait_func.name(sema.db) == func.name(sema.db) =>
|
||||
{
|
||||
Some(Definition::Function(trait_func))
|
||||
}
|
||||
(hir::AssocItem::Const(trait_konst), hir::AssocItem::Const(konst))
|
||||
if trait_konst.name(sema.db) == konst.name(sema.db) =>
|
||||
{
|
||||
Some(Definition::Const(trait_konst))
|
||||
}
|
||||
(
|
||||
hir::AssocItem::TypeAlias(trait_type_alias),
|
||||
hir::AssocItem::TypeAlias(type_alias),
|
||||
) if trait_type_alias.name(sema.db) == type_alias.name(sema.db) => {
|
||||
Some(Definition::TypeAlias(trait_type_alias))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
.unwrap_or(def),
|
||||
None => def,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source_edit_from_references(
|
||||
references: &[FileReference],
|
||||
def: Definition,
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use crate::{
|
||||
defs::{Definition, NameClass, NameRefClass},
|
||||
traits::convert_to_def_in_trait,
|
||||
RootDatabase,
|
||||
};
|
||||
|
||||
@ -620,7 +621,7 @@ fn found_name_ref(
|
||||
sink(file_id, reference)
|
||||
}
|
||||
Some(NameRefClass::Definition(def))
|
||||
if crate::rename::convert_to_def_in_trait(def, self.sema) == self.def =>
|
||||
if convert_to_def_in_trait(self.sema.db, def) == self.def =>
|
||||
{
|
||||
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
|
||||
let reference = FileReference {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Functionality for obtaining data related to traits from the DB.
|
||||
|
||||
use crate::RootDatabase;
|
||||
use hir::Semantics;
|
||||
use crate::{defs::Definition, RootDatabase};
|
||||
use hir::{db::HirDatabase, AsAssocItem, Semantics};
|
||||
use rustc_hash::FxHashSet;
|
||||
use syntax::{ast, AstNode};
|
||||
|
||||
@ -69,6 +69,28 @@ pub fn get_missing_assoc_items(
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts associated trait impl items to their trait definition counterpart
|
||||
pub(crate) fn convert_to_def_in_trait(db: &dyn HirDatabase, def: Definition) -> Definition {
|
||||
use hir::AssocItem::*;
|
||||
(|| {
|
||||
let assoc = def.as_assoc_item(db)?;
|
||||
let trait_ = assoc.containing_trait_impl(db)?;
|
||||
let name = match assoc {
|
||||
Function(it) => it.name(db),
|
||||
Const(it) => it.name(db)?,
|
||||
TypeAlias(it) => it.name(db),
|
||||
};
|
||||
let item = trait_.items(db).into_iter().find(|it| match (it, assoc) {
|
||||
(Function(trait_func), Function(_)) => trait_func.name(db) == name,
|
||||
(Const(trait_konst), Const(_)) => trait_konst.name(db).map_or(false, |it| it == name),
|
||||
(TypeAlias(trait_type_alias), TypeAlias(_)) => trait_type_alias.name(db) == name,
|
||||
_ => false,
|
||||
})?;
|
||||
Some(Definition::from(item))
|
||||
})()
|
||||
.unwrap_or(def)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::{fixture::ChangeFixture, FilePosition};
|
||||
|
Loading…
Reference in New Issue
Block a user