diff options
Diffstat (limited to 'crates/hir_def/src/attr.rs')
-rw-r--r-- | crates/hir_def/src/attr.rs | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 3886b6c04..d07adb084 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -106,7 +106,9 @@ impl RawAttrs { | |||
106 | ) -> Self { | 106 | ) -> Self { |
107 | let entries = collect_attrs(owner) | 107 | let entries = collect_attrs(owner) |
108 | .flat_map(|(id, attr)| match attr { | 108 | .flat_map(|(id, attr)| match attr { |
109 | Either::Left(attr) => Attr::from_src(db, attr, hygiene, id), | 109 | Either::Left(attr) => { |
110 | attr.meta().and_then(|meta| Attr::from_src(db, meta, hygiene, id)) | ||
111 | } | ||
110 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { | 112 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { |
111 | id, | 113 | id, |
112 | input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))), | 114 | input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))), |
@@ -172,10 +174,9 @@ impl RawAttrs { | |||
172 | let index = attr.id; | 174 | let index = attr.id; |
173 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { | 175 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { |
174 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; | 176 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; |
175 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | ||
176 | // FIXME hygiene | 177 | // FIXME hygiene |
177 | let hygiene = Hygiene::new_unhygienic(); | 178 | let hygiene = Hygiene::new_unhygienic(); |
178 | Attr::from_src(db, attr, &hygiene, index) | 179 | Attr::from_tt(db, &tree, &hygiene, index) |
179 | }); | 180 | }); |
180 | 181 | ||
181 | let cfg_options = &crate_graph[krate].cfg_options; | 182 | let cfg_options = &crate_graph[krate].cfg_options; |
@@ -582,13 +583,13 @@ impl AttrSourceMap { | |||
582 | .get(id.ast_index as usize) | 583 | .get(id.ast_index as usize) |
583 | .unwrap_or_else(|| panic!("cannot find doc comment at index {:?}", id)) | 584 | .unwrap_or_else(|| panic!("cannot find doc comment at index {:?}", id)) |
584 | .clone() | 585 | .clone() |
585 | .map(|attr| Either::Right(attr)) | 586 | .map(Either::Right) |
586 | } else { | 587 | } else { |
587 | self.attrs | 588 | self.attrs |
588 | .get(id.ast_index as usize) | 589 | .get(id.ast_index as usize) |
589 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {:?}", id)) | 590 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {:?}", id)) |
590 | .clone() | 591 | .clone() |
591 | .map(|attr| Either::Left(attr)) | 592 | .map(Either::Left) |
592 | } | 593 | } |
593 | } | 594 | } |
594 | } | 595 | } |
@@ -605,7 +606,7 @@ pub struct DocsRangeMap { | |||
605 | impl DocsRangeMap { | 606 | impl DocsRangeMap { |
606 | pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> { | 607 | pub fn map(&self, range: TextRange) -> Option<InFile<TextRange>> { |
607 | let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?; | 608 | let found = self.mapping.binary_search_by(|(probe, ..)| probe.ordering(range)).ok()?; |
608 | let (line_docs_range, idx, original_line_src_range) = self.mapping[found].clone(); | 609 | let (line_docs_range, idx, original_line_src_range) = self.mapping[found]; |
609 | if !line_docs_range.contains_range(range) { | 610 | if !line_docs_range.contains_range(range) { |
610 | return None; | 611 | return None; |
611 | } | 612 | } |
@@ -664,7 +665,7 @@ impl fmt::Display for AttrInput { | |||
664 | impl Attr { | 665 | impl Attr { |
665 | fn from_src( | 666 | fn from_src( |
666 | db: &dyn DefDatabase, | 667 | db: &dyn DefDatabase, |
667 | ast: ast::Attr, | 668 | ast: ast::Meta, |
668 | hygiene: &Hygiene, | 669 | hygiene: &Hygiene, |
669 | id: AttrId, | 670 | id: AttrId, |
670 | ) -> Option<Attr> { | 671 | ) -> Option<Attr> { |
@@ -683,6 +684,19 @@ impl Attr { | |||
683 | Some(Attr { id, path, input }) | 684 | Some(Attr { id, path, input }) |
684 | } | 685 | } |
685 | 686 | ||
687 | fn from_tt( | ||
688 | db: &dyn DefDatabase, | ||
689 | tt: &tt::Subtree, | ||
690 | hygiene: &Hygiene, | ||
691 | id: AttrId, | ||
692 | ) -> Option<Attr> { | ||
693 | let (parse, _) = | ||
694 | mbe::token_tree_to_syntax_node(tt, hir_expand::FragmentKind::MetaItem).ok()?; | ||
695 | let ast = ast::Meta::cast(parse.syntax_node())?; | ||
696 | |||
697 | Self::from_src(db, ast, hygiene, id) | ||
698 | } | ||
699 | |||
686 | /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths | 700 | /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths |
687 | /// to derive macros. | 701 | /// to derive macros. |
688 | /// | 702 | /// |