aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/attr.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-17 11:13:54 +0000
committerGitHub <[email protected]>2021-03-17 11:13:54 +0000
commit0fbfab3b45af7a02b1224bca4a53e9b8f6ec049e (patch)
tree6ba39c051e758d64c75948716d599a9a2a427ee3 /crates/hir_def/src/attr.rs
parentf7fbea509f1e5f840e715c912ee38aa997d1bfbc (diff)
parentcdfb5c353f09138540ae66a2eb80a6a81802bbd6 (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/src/attr.rs')
-rw-r--r--crates/hir_def/src/attr.rs45
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
376pub struct AttrSourceMap {
377 attrs: Vec<Either<ast::Attr, ast::Comment>>,
378}
379
380impl 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)]
369pub struct Attr { 395pub 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()