aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/attr.rs25
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs3
2 files changed, 27 insertions, 1 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index e7019e0c9..7a6a41dc2 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -294,6 +294,13 @@ impl Attrs {
294 Arc::new(res) 294 Arc::new(res)
295 } 295 }
296 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
297 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { 304 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
298 AttrQuery { attrs: self, key } 305 AttrQuery { attrs: self, key }
299 } 306 }
@@ -366,6 +373,24 @@ fn inner_attributes(
366 Some((attrs, docs)) 373 Some((attrs, docs))
367} 374}
368 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
369#[derive(Debug, Clone, PartialEq, Eq)] 394#[derive(Debug, Clone, PartialEq, Eq)]
370pub struct Attr { 395pub struct Attr {
371 index: u32, 396 index: u32,
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 0f1de4fb8..d4c367f66 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -153,6 +153,7 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
153 if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) { 153 if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) {
154 return; 154 return;
155 } 155 }
156 let attrs_source_map = attributes.source_map(&owner);
156 157
157 let mut inj = Injector::default(); 158 let mut inj = Injector::default();
158 inj.add_unmapped("fn doctest() {\n"); 159 inj.add_unmapped("fn doctest() {\n");
@@ -165,7 +166,7 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
165 let mut new_comments = Vec::new(); 166 let mut new_comments = Vec::new();
166 let mut string; 167 let mut string;
167 for attr in attributes.by_key("doc").attrs() { 168 for attr in attributes.by_key("doc").attrs() {
168 let src = attr.to_src(&owner); 169 let src = attrs_source_map.source_of(&attr);
169 let (line, range, prefix) = match &src { 170 let (line, range, prefix) = match &src {
170 Either::Left(it) => { 171 Either::Left(it) => {
171 string = match find_doc_string_in_attr(attr, it) { 172 string = match find_doc_string_in_attr(attr, it) {