Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/hover.rs')
| -rw-r--r-- | crates/ide/src/hover.rs | 65 |
1 files changed, 8 insertions, 57 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index b8b2222a8b..4b7043bd9b 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, iter}; +use std::iter; use either::Either; use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo}; @@ -14,20 +14,13 @@ use ide_db::{ use itertools::Itertools; use stdx::format_to; use syntax::{ - algo, - ast::{self, IsString}, - display::fn_as_proc_macro_label, - match_ast, AstNode, AstToken, Direction, - SyntaxKind::*, - SyntaxNode, SyntaxToken, TextSize, T, + algo, ast, display::fn_as_proc_macro_label, match_ast, AstNode, Direction, SyntaxKind::*, + SyntaxNode, SyntaxToken, T, }; use crate::{ display::{macro_label, TryToNav}, - doc_links::{ - doc_attributes, extract_definitions_from_docs, remove_links, resolve_doc_path_for_def, - rewrite_links, - }, + doc_links::{remove_links, rewrite_links, token_as_doc_comment}, markdown_remove::remove_markdown, markup::Markup, runnables::{runnable_fn, runnable_mod}, @@ -118,57 +111,15 @@ pub(crate) fn hover( _ => 1, })?; - let descended = sema.descend_into_macros_many(original_token.clone()); - // magic intra doc link handling - // FIXME: Lift this out to some other place, goto def wants this as well - let comment_prefix_len = match_ast! { - match original_token { - ast::Comment(comment) => TextSize::try_from(comment.prefix().len()).ok(), - ast::String(string) => original_token.ancestors().find_map(ast::Attr::cast) - .filter(|attr| attr.simple_name().as_deref() == Some("doc")).and_then(|_| string.open_quote_text_range().map(|it| it.len())), - _ => None, - } - }; - if let Some(prefix_len) = comment_prefix_len { + if let Some(doc_comment) = token_as_doc_comment(&original_token) { cov_mark::hit!(no_highlight_on_comment_hover); - - // offset relative to the comments contents - let original_start = original_token.text_range().start(); - let relative_comment_offset = offset - original_start - prefix_len; - - return descended.iter().find_map(|t| { - let (node, descended_prefix_len) = match_ast! { - match t { - ast::Comment(comment) => (t.parent()?, TextSize::try_from(comment.prefix().len()).ok()?), - ast::String(string) => (t.ancestors().skip_while(|n| n.kind() != ATTR).nth(1)?, string.open_quote_text_range()?.len()), - _ => return None, - } - }; - let token_start = t.text_range().start(); - let abs_in_expansion_offset = token_start + relative_comment_offset + descended_prefix_len; - - let (attributes, def) = doc_attributes(sema, &node)?; - let (docs, doc_mapping) = attributes.docs_with_rangemap(sema.db)?; - let (in_expansion_range, link, ns) = extract_definitions_from_docs(&docs).into_iter().find_map( - |(range, link, ns)| { - let mapped = doc_mapping.map(range)?; - (mapped.value.contains(abs_in_expansion_offset)) - .then(|| (mapped.value, link, ns)) - }, - )?; - // get the relative range to the doc/attribute in the expansion - let in_expansion_relative_range = in_expansion_range - descended_prefix_len - token_start; - // Apply relative range to the original input comment - let absolute_range = in_expansion_relative_range + original_start + prefix_len; - let def = match resolve_doc_path_for_def(sema.db, def, &link, ns)? { - Either::Left(it) => Definition::ModuleDef(it), - Either::Right(it) => Definition::Macro(it), - }; + return doc_comment.get_definition_with_descend_at(sema, offset, |def, node, range| { let res = hover_for_definition(sema, file_id, def, &node, config)?; - Some(RangeInfo::new(absolute_range, res)) + Some(RangeInfo::new(range, res)) }); } + let descended = sema.descend_into_macros_many(original_token.clone()); // attributes, require special machinery as they are mere ident tokens // FIXME: Definition should include known lints and the like instead of having this special case here |