diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-17 11:13:54 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-17 11:13:54 +0000 |
commit | 0fbfab3b45af7a02b1224bca4a53e9b8f6ec049e (patch) | |
tree | 6ba39c051e758d64c75948716d599a9a2a427ee3 /crates/hir_def | |
parent | f7fbea509f1e5f840e715c912ee38aa997d1bfbc (diff) | |
parent | cdfb5c353f09138540ae66a2eb80a6a81802bbd6 (diff) |
Merge #8059
8059: Move doc-comment highlight injection from AST to HIR r=matklad,jonas-schievink a=Veykril
Fixes #5016
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_def')
-rw-r--r-- | crates/hir_def/src/attr.rs | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index b0b4b5052..7ba53ee5c 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -136,16 +136,15 @@ impl RawAttrs { | |||
136 | let new_attrs = self | 136 | let new_attrs = self |
137 | .iter() | 137 | .iter() |
138 | .flat_map(|attr| -> SmallVec<[_; 1]> { | 138 | .flat_map(|attr| -> SmallVec<[_; 1]> { |
139 | let attr = attr.clone(); | ||
140 | let is_cfg_attr = | 139 | let is_cfg_attr = |
141 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); | 140 | attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]); |
142 | if !is_cfg_attr { | 141 | if !is_cfg_attr { |
143 | return smallvec![attr]; | 142 | return smallvec![attr.clone()]; |
144 | } | 143 | } |
145 | 144 | ||
146 | let subtree = match &attr.input { | 145 | let subtree = match &attr.input { |
147 | Some(AttrInput::TokenTree(it)) => it, | 146 | Some(AttrInput::TokenTree(it)) => it, |
148 | _ => return smallvec![attr], | 147 | _ => return smallvec![attr.clone()], |
149 | }; | 148 | }; |
150 | 149 | ||
151 | // Input subtree is: `(cfg, $(attr),+)` | 150 | // Input subtree is: `(cfg, $(attr),+)` |
@@ -157,11 +156,13 @@ impl RawAttrs { | |||
157 | let cfg = parts.next().unwrap(); | 156 | let cfg = parts.next().unwrap(); |
158 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; | 157 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; |
159 | let cfg = CfgExpr::parse(&cfg); | 158 | let cfg = CfgExpr::parse(&cfg); |
159 | let index = attr.index; | ||
160 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { | 160 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { |
161 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; | 161 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; |
162 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | 162 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; |
163 | let hygiene = Hygiene::new_unhygienic(); // FIXME | 163 | // FIXME hygiene |
164 | Attr::from_src(attr, &hygiene) | 164 | let hygiene = Hygiene::new_unhygienic(); |
165 | Attr::from_src(attr, &hygiene).map(|attr| Attr { index, ..attr }) | ||
165 | }); | 166 | }); |
166 | 167 | ||
167 | let cfg_options = &crate_graph[krate].cfg_options; | 168 | let cfg_options = &crate_graph[krate].cfg_options; |
@@ -293,6 +294,13 @@ impl Attrs { | |||
293 | Arc::new(res) | 294 | Arc::new(res) |
294 | } | 295 | } |
295 | 296 | ||
297 | /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes. | ||
298 | /// | ||
299 | /// `owner` must be the original owner of the attributes. | ||
300 | pub fn source_map(&self, owner: &dyn AttrsOwner) -> AttrSourceMap { | ||
301 | AttrSourceMap { attrs: collect_attrs(owner).collect() } | ||
302 | } | ||
303 | |||
296 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { | 304 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { |
297 | AttrQuery { attrs: self, key } | 305 | AttrQuery { attrs: self, key } |
298 | } | 306 | } |
@@ -365,6 +373,24 @@ fn inner_attributes( | |||
365 | Some((attrs, docs)) | 373 | Some((attrs, docs)) |
366 | } | 374 | } |
367 | 375 | ||
376 | pub struct AttrSourceMap { | ||
377 | attrs: Vec<Either<ast::Attr, ast::Comment>>, | ||
378 | } | ||
379 | |||
380 | impl AttrSourceMap { | ||
381 | /// Maps the lowered `Attr` back to its original syntax node. | ||
382 | /// | ||
383 | /// `attr` must come from the `owner` used for AttrSourceMap | ||
384 | /// | ||
385 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of | ||
386 | /// the attribute represented by `Attr`. | ||
387 | pub fn source_of(&self, attr: &Attr) -> &Either<ast::Attr, ast::Comment> { | ||
388 | self.attrs | ||
389 | .get(attr.index as usize) | ||
390 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {}", attr.index)) | ||
391 | } | ||
392 | } | ||
393 | |||
368 | #[derive(Debug, Clone, PartialEq, Eq)] | 394 | #[derive(Debug, Clone, PartialEq, Eq)] |
369 | pub struct Attr { | 395 | pub struct Attr { |
370 | index: u32, | 396 | index: u32, |
@@ -448,6 +474,13 @@ impl Attr { | |||
448 | _ => None, | 474 | _ => None, |
449 | } | 475 | } |
450 | } | 476 | } |
477 | |||
478 | pub fn string_value(&self) -> Option<&SmolStr> { | ||
479 | match self.input.as_ref()? { | ||
480 | AttrInput::Literal(it) => Some(it), | ||
481 | _ => None, | ||
482 | } | ||
483 | } | ||
451 | } | 484 | } |
452 | 485 | ||
453 | #[derive(Debug, Clone, Copy)] | 486 | #[derive(Debug, Clone, Copy)] |
@@ -475,7 +508,7 @@ impl<'a> AttrQuery<'a> { | |||
475 | self.attrs().next().is_some() | 508 | self.attrs().next().is_some() |
476 | } | 509 | } |
477 | 510 | ||
478 | pub(crate) fn attrs(self) -> impl Iterator<Item = &'a Attr> { | 511 | pub fn attrs(self) -> impl Iterator<Item = &'a Attr> { |
479 | let key = self.key; | 512 | let key = self.key; |
480 | self.attrs | 513 | self.attrs |
481 | .iter() | 514 | .iter() |