Remove quadratic attr source lookup
This commit is contained in:
@@ -294,6 +294,13 @@ impl Attrs {
|
|||||||
Arc::new(res)
|
Arc::new(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes.
|
||||||
|
///
|
||||||
|
/// `owner` must be the original owner of the attributes.
|
||||||
|
pub fn source_map(&self, owner: &dyn AttrsOwner) -> AttrSourceMap {
|
||||||
|
AttrSourceMap { attrs: collect_attrs(owner).collect() }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
||||||
AttrQuery { attrs: self, key }
|
AttrQuery { attrs: self, key }
|
||||||
}
|
}
|
||||||
@@ -366,6 +373,24 @@ fn inner_attributes(
|
|||||||
Some((attrs, docs))
|
Some((attrs, docs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AttrSourceMap {
|
||||||
|
attrs: Vec<Either<ast::Attr, ast::Comment>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AttrSourceMap {
|
||||||
|
/// Maps the lowered `Attr` back to its original syntax node.
|
||||||
|
///
|
||||||
|
/// `attr` must come from the `owner` used for AttrSourceMap
|
||||||
|
///
|
||||||
|
/// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
|
||||||
|
/// the attribute represented by `Attr`.
|
||||||
|
pub fn source_of(&self, attr: &Attr) -> &Either<ast::Attr, ast::Comment> {
|
||||||
|
self.attrs
|
||||||
|
.get(attr.index as usize)
|
||||||
|
.unwrap_or_else(|| panic!("cannot find `Attr` at index {}", attr.index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Attr {
|
pub struct Attr {
|
||||||
index: u32,
|
index: u32,
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
|
|||||||
if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) {
|
if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let attrs_source_map = attributes.source_map(&owner);
|
||||||
|
|
||||||
let mut inj = Injector::default();
|
let mut inj = Injector::default();
|
||||||
inj.add_unmapped("fn doctest() {\n");
|
inj.add_unmapped("fn doctest() {\n");
|
||||||
@@ -165,7 +166,7 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
|
|||||||
let mut new_comments = Vec::new();
|
let mut new_comments = Vec::new();
|
||||||
let mut string;
|
let mut string;
|
||||||
for attr in attributes.by_key("doc").attrs() {
|
for attr in attributes.by_key("doc").attrs() {
|
||||||
let src = attr.to_src(&owner);
|
let src = attrs_source_map.source_of(&attr);
|
||||||
let (line, range, prefix) = match &src {
|
let (line, range, prefix) = match &src {
|
||||||
Either::Left(it) => {
|
Either::Left(it) => {
|
||||||
string = match find_doc_string_in_attr(attr, it) {
|
string = match find_doc_string_in_attr(attr, it) {
|
||||||
|
|||||||
Reference in New Issue
Block a user