diff options
Diffstat (limited to 'crates/hir_def/src/attr.rs')
-rw-r--r-- | crates/hir_def/src/attr.rs | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 8a25b8731..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; | |||
16 | use smallvec::{smallvec, SmallVec}; | 16 | use smallvec::{smallvec, SmallVec}; |
17 | use syntax::{ | 17 | use 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 | }; |
21 | use tt::Subtree; | 21 | use tt::Subtree; |
22 | 22 | ||
@@ -403,10 +403,14 @@ impl AttrsWithOwner { | |||
403 | return AttrSourceMap { attrs }; | 403 | return AttrSourceMap { attrs }; |
404 | } | 404 | } |
405 | AttrDefId::FieldId(id) => { | 405 | AttrDefId::FieldId(id) => { |
406 | id.parent.child_source(db).map(|source| match &source[id.local_id] { | 406 | let map = db.fields_attrs_source_map(id.parent); |
407 | Either::Left(field) => ast::AttrsOwnerNode::new(field.clone()), | 407 | let file_id = id.parent.file_id(db); |
408 | Either::Right(field) => ast::AttrsOwnerNode::new(field.clone()), | 408 | let root = db.parse_or_expand(file_id).unwrap(); |
409 | }) | 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) | ||
410 | } | 414 | } |
411 | AttrDefId::AdtId(adt) => match adt { | 415 | AttrDefId::AdtId(adt) => match adt { |
412 | 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), |
@@ -414,10 +418,12 @@ impl AttrsWithOwner { | |||
414 | 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), |
415 | }, | 419 | }, |
416 | 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), |
417 | AttrDefId::EnumVariantId(id) => id | 421 | AttrDefId::EnumVariantId(id) => { |
418 | .parent | 422 | let map = db.variants_attrs_source_map(id.parent); |
419 | .child_source(db) | 423 | let file_id = id.parent.lookup(db).id.file_id(); |
420 | .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 | } | ||
421 | 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), |
422 | 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), |
423 | 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), |
@@ -746,3 +752,36 @@ fn collect_attrs( | |||
746 | 752 | ||
747 | attrs.into_iter().map(|(_, attr)| attr) | 753 | attrs.into_iter().map(|(_, attr)| attr) |
748 | } | 754 | } |
755 | |||
756 | pub(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 | |||
770 | pub(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 | } | ||