aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/attr.rs')
-rw-r--r--crates/hir_def/src/attr.rs66
1 files changed, 52 insertions, 14 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index ab77d924a..d9df7564d 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -16,7 +16,7 @@ use mbe::ast_to_token_tree;
16use smallvec::{smallvec, SmallVec}; 16use smallvec::{smallvec, SmallVec};
17use syntax::{ 17use syntax::{
18 ast::{self, AstNode, AttrsOwner}, 18 ast::{self, AstNode, AttrsOwner},
19 match_ast, AstToken, SmolStr, SyntaxNode, TextRange, TextSize, 19 match_ast, AstPtr, AstToken, SmolStr, SyntaxNode, TextRange, TextSize,
20}; 20};
21use tt::Subtree; 21use tt::Subtree;
22 22
@@ -215,12 +215,11 @@ impl Attrs {
215 let mut res = ArenaMap::default(); 215 let mut res = ArenaMap::default();
216 216
217 for (id, fld) in src.value.iter() { 217 for (id, fld) in src.value.iter() {
218 let attrs = match fld { 218 let owner: &dyn AttrsOwner = match fld {
219 Either::Left(_tuple) => Attrs::default(), 219 Either::Left(tuple) => tuple,
220 Either::Right(record) => { 220 Either::Right(record) => record,
221 RawAttrs::from_attrs_owner(db, src.with_value(record)).filter(db, krate)
222 }
223 }; 221 };
222 let attrs = RawAttrs::from_attrs_owner(db, src.with_value(owner)).filter(db, krate);
224 223
225 res.insert(id, attrs); 224 res.insert(id, attrs);
226 } 225 }
@@ -404,10 +403,14 @@ impl AttrsWithOwner {
404 return AttrSourceMap { attrs }; 403 return AttrSourceMap { attrs };
405 } 404 }
406 AttrDefId::FieldId(id) => { 405 AttrDefId::FieldId(id) => {
407 id.parent.child_source(db).map(|source| match &source[id.local_id] { 406 let map = db.fields_attrs_source_map(id.parent);
408 Either::Left(field) => ast::AttrsOwnerNode::new(field.clone()), 407 let file_id = id.parent.file_id(db);
409 Either::Right(field) => ast::AttrsOwnerNode::new(field.clone()), 408 let root = db.parse_or_expand(file_id).unwrap();
410 }) 409 let owner = match &map[id.local_id] {
410 Either::Left(it) => ast::AttrsOwnerNode::new(it.to_node(&root)),
411 Either::Right(it) => ast::AttrsOwnerNode::new(it.to_node(&root)),
412 };
413 InFile::new(file_id, owner)
411 } 414 }
412 AttrDefId::AdtId(adt) => match adt { 415 AttrDefId::AdtId(adt) => match adt {
413 AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 416 AdtId::StructId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
@@ -415,10 +418,12 @@ impl AttrsWithOwner {
415 AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 418 AdtId::EnumId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
416 }, 419 },
417 AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 420 AttrDefId::FunctionId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
418 AttrDefId::EnumVariantId(id) => id 421 AttrDefId::EnumVariantId(id) => {
419 .parent 422 let map = db.variants_attrs_source_map(id.parent);
420 .child_source(db) 423 let file_id = id.parent.lookup(db).id.file_id();
421 .map(|source| ast::AttrsOwnerNode::new(source[id.local_id].clone())), 424 let root = db.parse_or_expand(file_id).unwrap();
425 InFile::new(file_id, ast::AttrsOwnerNode::new(map[id.local_id].to_node(&root)))
426 }
422 AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 427 AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
423 AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 428 AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
424 AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new), 429 AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AttrsOwnerNode::new),
@@ -747,3 +752,36 @@ fn collect_attrs(
747 752
748 attrs.into_iter().map(|(_, attr)| attr) 753 attrs.into_iter().map(|(_, attr)| attr)
749} 754}
755
756pub(crate) fn variants_attrs_source_map(
757 db: &dyn DefDatabase,
758 def: EnumId,
759) -> Arc<ArenaMap<LocalEnumVariantId, AstPtr<ast::Variant>>> {
760 let mut res = ArenaMap::default();
761 let child_source = def.child_source(db);
762
763 for (idx, variant) in child_source.value.iter() {
764 res.insert(idx, AstPtr::new(variant));
765 }
766
767 Arc::new(res)
768}
769
770pub(crate) fn fields_attrs_source_map(
771 db: &dyn DefDatabase,
772 def: VariantId,
773) -> Arc<ArenaMap<LocalFieldId, Either<AstPtr<ast::TupleField>, AstPtr<ast::RecordField>>>> {
774 let mut res = ArenaMap::default();
775 let child_source = def.child_source(db);
776
777 for (idx, variant) in child_source.value.iter() {
778 res.insert(
779 idx,
780 variant
781 .as_ref()
782 .either(|l| Either::Left(AstPtr::new(l)), |r| Either::Right(AstPtr::new(r))),
783 );
784 }
785
786 Arc::new(res)
787}