From 627fedb423343d3a26147986fdda1d8b18474597 Mon Sep 17 00:00:00 2001 From: Hayashi Mikihiro <34ttrweoewiwe28@gmail.com> Date: Wed, 7 May 2025 02:56:03 +0900 Subject: [PATCH] extract function: `doc_attributes` to find def from inner doc Signed-off-by: Hayashi Mikihiro <34ttrweoewiwe28@gmail.com> --- .../rust-analyzer/crates/ide/src/doc_links.rs | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs index 290420346060..2c983287d89c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs +++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs @@ -12,7 +12,9 @@ use pulldown_cmark_to_cmark::{Options as CMarkOptions, cmark_resume_with_options use stdx::format_to; use url::Url; -use hir::{Adt, AsAssocItem, AssocItem, AssocItemContainer, HasAttrs, db::HirDatabase, sym}; +use hir::{ + Adt, AsAssocItem, AssocItem, AssocItemContainer, AttrsWithOwner, HasAttrs, db::HirDatabase, sym, +}; use ide_db::{ RootDatabase, base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, RootQueryDb}, @@ -322,13 +324,7 @@ impl DocCommentToken { }; let token_start = t.text_range().start(); let abs_in_expansion_offset = token_start + relative_comment_offset + descended_prefix_len; - - let (attributes, def) = if is_inner && node.kind() != SOURCE_FILE { - let parent = node.parent()?; - doc_attributes(sema, &parent).unwrap_or(doc_attributes(sema, &parent.parent()?)?) - }else { - doc_attributes(sema, &node)? - }; + let (attributes, def) = Self::doc_attributes(sema, &node, is_inner)?; let (docs, doc_mapping) = docs_with_rangemap(sema.db, &attributes)?; let (in_expansion_range, link, ns, is_inner) = extract_definitions_from_docs(&docs).into_iter().find_map(|(range, link, ns)| { @@ -343,6 +339,28 @@ impl DocCommentToken { cb(def, node, absolute_range) }) } + + /// When we hover a inner doc item, this find a attached definition. + /// ``` + /// // node == ITEM_LIST + /// // node.parent == EXPR_BLOCK + /// // node.parent().parent() == FN + /// fn f() { + /// //! [`S$0`] + /// } + /// ``` + fn doc_attributes( + sema: &Semantics<'_, RootDatabase>, + node: &SyntaxNode, + is_inner_doc: bool, + ) -> Option<(AttrsWithOwner, Definition)> { + if is_inner_doc && node.kind() != SOURCE_FILE { + let parent = node.parent()?; + doc_attributes(sema, &parent).or(doc_attributes(sema, &parent.parent()?)) + } else { + doc_attributes(sema, node) + } + } } fn broken_link_clone_cb(link: BrokenLink<'_>) -> Option<(CowStr<'_>, CowStr<'_>)> {