1- use std:: { convert :: TryFrom , iter} ;
1+ use std:: iter;
22
33use either:: Either ;
44use hir:: { AsAssocItem , HasAttrs , HasSource , HirDisplay , Semantics , TypeInfo } ;
@@ -14,20 +14,13 @@ use ide_db::{
1414use itertools:: Itertools ;
1515use stdx:: format_to;
1616use syntax:: {
17- algo,
18- ast:: { self , IsString } ,
19- display:: fn_as_proc_macro_label,
20- match_ast, AstNode , AstToken , Direction ,
21- SyntaxKind :: * ,
22- SyntaxNode , SyntaxToken , TextSize , T ,
17+ algo, ast, display:: fn_as_proc_macro_label, match_ast, AstNode , Direction , SyntaxKind :: * ,
18+ SyntaxNode , SyntaxToken , T ,
2319} ;
2420
2521use crate :: {
2622 display:: { macro_label, TryToNav } ,
27- doc_links:: {
28- doc_attributes, extract_definitions_from_docs, remove_links, resolve_doc_path_for_def,
29- rewrite_links,
30- } ,
23+ doc_links:: { remove_links, rewrite_links, token_as_doc_comment} ,
3124 markdown_remove:: remove_markdown,
3225 markup:: Markup ,
3326 runnables:: { runnable_fn, runnable_mod} ,
@@ -118,57 +111,15 @@ pub(crate) fn hover(
118111 _ => 1 ,
119112 } ) ?;
120113
121- let descended = sema. descend_into_macros_many ( original_token. clone ( ) ) ;
122- // magic intra doc link handling
123- // FIXME: Lift this out to some other place, goto def wants this as well
124- let comment_prefix_len = match_ast ! {
125- match original_token {
126- ast:: Comment ( comment) => TextSize :: try_from( comment. prefix( ) . len( ) ) . ok( ) ,
127- ast:: String ( string) => original_token. ancestors( ) . find_map( ast:: Attr :: cast)
128- . filter( |attr| attr. simple_name( ) . as_deref( ) == Some ( "doc" ) ) . and_then( |_| string. open_quote_text_range( ) . map( |it| it. len( ) ) ) ,
129- _ => None ,
130- }
131- } ;
132- if let Some ( prefix_len) = comment_prefix_len {
114+ if let Some ( doc_comment) = token_as_doc_comment ( & original_token) {
133115 cov_mark:: hit!( no_highlight_on_comment_hover) ;
134-
135- // offset relative to the comments contents
136- let original_start = original_token. text_range ( ) . start ( ) ;
137- let relative_comment_offset = offset - original_start - prefix_len;
138-
139- return descended. iter ( ) . find_map ( |t| {
140- let ( node, descended_prefix_len) = match_ast ! {
141- match t {
142- ast:: Comment ( comment) => ( t. parent( ) ?, TextSize :: try_from( comment. prefix( ) . len( ) ) . ok( ) ?) ,
143- ast:: String ( string) => ( t. ancestors( ) . skip_while( |n| n. kind( ) != ATTR ) . nth( 1 ) ?, string. open_quote_text_range( ) ?. len( ) ) ,
144- _ => return None ,
145- }
146- } ;
147- let token_start = t. text_range ( ) . start ( ) ;
148- let abs_in_expansion_offset = token_start + relative_comment_offset + descended_prefix_len;
149-
150- let ( attributes, def) = doc_attributes ( sema, & node) ?;
151- let ( docs, doc_mapping) = attributes. docs_with_rangemap ( sema. db ) ?;
152- let ( in_expansion_range, link, ns) = extract_definitions_from_docs ( & docs) . into_iter ( ) . find_map (
153- |( range, link, ns) | {
154- let mapped = doc_mapping. map ( range) ?;
155- ( mapped. value . contains ( abs_in_expansion_offset) )
156- . then ( || ( mapped. value , link, ns) )
157- } ,
158- ) ?;
159- // get the relative range to the doc/attribute in the expansion
160- let in_expansion_relative_range = in_expansion_range - descended_prefix_len - token_start;
161- // Apply relative range to the original input comment
162- let absolute_range = in_expansion_relative_range + original_start + prefix_len;
163- let def = match resolve_doc_path_for_def ( sema. db , def, & link, ns) ? {
164- Either :: Left ( it) => Definition :: ModuleDef ( it) ,
165- Either :: Right ( it) => Definition :: Macro ( it) ,
166- } ;
116+ return doc_comment. get_definition_with_descend_at ( sema, offset, |def, node, range| {
167117 let res = hover_for_definition ( sema, file_id, def, & node, config) ?;
168- Some ( RangeInfo :: new ( absolute_range , res) )
118+ Some ( RangeInfo :: new ( range , res) )
169119 } ) ;
170120 }
171121
122+ let descended = sema. descend_into_macros_many ( original_token. clone ( ) ) ;
172123 // attributes, require special machinery as they are mere ident tokens
173124
174125 // FIXME: Definition should include known lints and the like instead of having this special case here
0 commit comments