Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/attr.rs')
| -rw-r--r-- | crates/hir-def/src/attr.rs | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index fa3025e030..35c9d63979 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -7,7 +7,10 @@ mod tests; use std::{hash::Hash, ops, slice::Iter as SliceIter}; -use base_db::CrateId; +use base_db::{ + span::{ErasedFileAstId, SpanAnchor}, + CrateId, +}; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ @@ -28,8 +31,8 @@ use crate::{ lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, - AdtId, AssocItemLoc, AttrDefId, EnumId, GenericParamId, ItemLoc, LocalEnumVariantId, - LocalFieldId, Lookup, MacroId, VariantId, + AdtId, AssocItemLoc, AttrDefId, EnumId, GenericDefId, GenericParamId, ItemLoc, + LocalEnumVariantId, LocalFieldId, Lookup, MacroId, VariantId, }; #[derive(Default, Debug, Clone, PartialEq, Eq)] @@ -415,26 +418,48 @@ impl AttrsWithOwner { AttrDefId::StaticId(it) => attrs_from_item_tree_assoc(db, it), AttrDefId::FunctionId(it) => attrs_from_item_tree_assoc(db, it), AttrDefId::TypeAliasId(it) => attrs_from_item_tree_assoc(db, it), - AttrDefId::GenericParamId(it) => match it { - GenericParamId::ConstParamId(it) => { - let src = it.parent().child_source(db); - RawAttrs::from_attrs_owner( - db.upcast(), - src.with_value(&src.value[it.local_id()]), - ) - } - GenericParamId::TypeParamId(it) => { - let src = it.parent().child_source(db); - RawAttrs::from_attrs_owner( - db.upcast(), - src.with_value(&src.value[it.local_id()]), - ) - } - GenericParamId::LifetimeParamId(it) => { - let src = it.parent.child_source(db); - RawAttrs::from_attrs_owner(db.upcast(), src.with_value(&src.value[it.local_id])) + AttrDefId::GenericParamId(it) => { + let ast_id = |p| match p { + GenericDefId::AdtId(AdtId::StructId(it)) => { + erased_ast_id_from_item_tree(db, it) + } + GenericDefId::AdtId(AdtId::EnumId(it)) => erased_ast_id_from_item_tree(db, it), + GenericDefId::AdtId(AdtId::UnionId(it)) => erased_ast_id_from_item_tree(db, it), + GenericDefId::TraitId(it) => erased_ast_id_from_item_tree(db, it), + GenericDefId::TraitAliasId(it) => erased_ast_id_from_item_tree(db, it), + GenericDefId::ImplId(it) => erased_ast_id_from_item_tree(db, it), + GenericDefId::EnumVariantId(it) => erased_ast_id_from_item_tree(db, it.parent), + GenericDefId::TypeAliasId(it) => erased_ast_id_from_item_tree_assoc(db, it), + GenericDefId::FunctionId(it) => erased_ast_id_from_item_tree_assoc(db, it), + GenericDefId::ConstId(it) => erased_ast_id_from_item_tree_assoc(db, it), + }; + match it { + GenericParamId::ConstParamId(it) => { + let src = it.parent().child_source(db); + RawAttrs::from_attrs_owner( + db.upcast(), + SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent()) }, + src.with_value(&src.value[it.local_id()]), + ) + } + GenericParamId::TypeParamId(it) => { + let src = it.parent().child_source(db); + RawAttrs::from_attrs_owner( + db.upcast(), + SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent()) }, + src.with_value(&src.value[it.local_id()]), + ) + } + GenericParamId::LifetimeParamId(it) => { + let src = it.parent.child_source(db); + RawAttrs::from_attrs_owner( + db.upcast(), + SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent) }, + src.with_value(&src.value[it.local_id]), + ) + } } - }, + } AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::ExternCrateId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it), @@ -638,6 +663,26 @@ fn any_has_attrs( id.lookup(db).source(db).map(ast::AnyHasAttrs::new) } +fn erased_ast_id_from_item_tree<N: ItemTreeNode>( + db: &dyn DefDatabase, + lookup: impl Lookup<Data = ItemLoc<N>>, +) -> ErasedFileAstId { + let id = lookup.lookup(db).id; + let tree = id.item_tree(db); + let mod_item = N::id_to_mod_item(id.value); + mod_item.ast_id(&tree).erase() +} + +fn erased_ast_id_from_item_tree_assoc<N: ItemTreeNode>( + db: &dyn DefDatabase, + lookup: impl Lookup<Data = AssocItemLoc<N>>, +) -> ErasedFileAstId { + let id = lookup.lookup(db).id; + let tree = id.item_tree(db); + let mod_item = N::id_to_mod_item(id.value); + mod_item.ast_id(&tree).erase() +} + fn attrs_from_item_tree<N: ItemTreeNode>(db: &dyn DefDatabase, id: ItemTreeId<N>) -> RawAttrs { let tree = id.item_tree(db); let mod_item = N::id_to_mod_item(id.value); |