66// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
77
88use crate :: RootDatabase ;
9- use crate :: documentation:: { Documentation , HasDocs } ;
9+ use crate :: documentation:: { DocsRangeMap , Documentation , HasDocs } ;
1010use crate :: famous_defs:: FamousDefs ;
1111use arrayvec:: ArrayVec ;
1212use either:: Either ;
@@ -21,7 +21,7 @@ use hir::{
2121use span:: Edition ;
2222use stdx:: { format_to, impl_from} ;
2323use syntax:: {
24- SyntaxKind , SyntaxNode , SyntaxToken ,
24+ SyntaxKind , SyntaxNode , SyntaxToken , TextSize ,
2525 ast:: { self , AstNode } ,
2626 match_ast,
2727} ;
@@ -210,29 +210,40 @@ impl Definition {
210210 famous_defs : Option < & FamousDefs < ' _ , ' _ > > ,
211211 display_target : DisplayTarget ,
212212 ) -> Option < Documentation > {
213+ self . docs_with_rangemap ( db, famous_defs, display_target) . map ( |( docs, _) | docs)
214+ }
215+
216+ pub fn docs_with_rangemap (
217+ & self ,
218+ db : & RootDatabase ,
219+ famous_defs : Option < & FamousDefs < ' _ , ' _ > > ,
220+ display_target : DisplayTarget ,
221+ ) -> Option < ( Documentation , Option < DocsRangeMap > ) > {
213222 let docs = match self {
214- Definition :: Macro ( it) => it. docs ( db) ,
215- Definition :: Field ( it) => it. docs ( db) ,
216- Definition :: Module ( it) => it. docs ( db) ,
217- Definition :: Crate ( it) => it. docs ( db) ,
218- Definition :: Function ( it) => it. docs ( db) ,
219- Definition :: Adt ( it) => it. docs ( db) ,
220- Definition :: Variant ( it) => it. docs ( db) ,
221- Definition :: Const ( it) => it. docs ( db) ,
222- Definition :: Static ( it) => it. docs ( db) ,
223- Definition :: Trait ( it) => it. docs ( db) ,
224- Definition :: TraitAlias ( it) => it. docs ( db) ,
223+ Definition :: Macro ( it) => it. docs_with_rangemap ( db) ,
224+ Definition :: Field ( it) => it. docs_with_rangemap ( db) ,
225+ Definition :: Module ( it) => it. docs_with_rangemap ( db) ,
226+ Definition :: Crate ( it) => it. docs_with_rangemap ( db) ,
227+ Definition :: Function ( it) => it. docs_with_rangemap ( db) ,
228+ Definition :: Adt ( it) => it. docs_with_rangemap ( db) ,
229+ Definition :: Variant ( it) => it. docs_with_rangemap ( db) ,
230+ Definition :: Const ( it) => it. docs_with_rangemap ( db) ,
231+ Definition :: Static ( it) => it. docs_with_rangemap ( db) ,
232+ Definition :: Trait ( it) => it. docs_with_rangemap ( db) ,
233+ Definition :: TraitAlias ( it) => it. docs_with_rangemap ( db) ,
225234 Definition :: TypeAlias ( it) => {
226- it. docs ( db) . or_else ( || {
235+ it. docs_with_rangemap ( db) . or_else ( || {
227236 // docs are missing, try to fall back to the docs of the aliased item.
228237 let adt = it. ty ( db) . as_adt ( ) ?;
229- let docs = adt. docs ( db) ?;
230- let docs = format ! (
231- "*This is the documentation for* `{}`\n \n {}" ,
232- adt. display( db, display_target) ,
233- docs. as_str( )
238+ let ( docs, range_map) = adt. docs_with_rangemap ( db) ?;
239+ let header_docs = format ! (
240+ "*This is the documentation for* `{}`\n \n " ,
241+ adt. display( db, display_target)
234242 ) ;
235- Some ( Documentation :: new ( docs) )
243+ let offset = TextSize :: new ( header_docs. len ( ) as u32 ) ;
244+ let range_map = range_map. shift_docstring_line_range ( offset) ;
245+ let docs = header_docs + docs. as_str ( ) ;
246+ Some ( ( Documentation :: new ( docs) , range_map) )
236247 } )
237248 }
238249 Definition :: BuiltinType ( it) => {
@@ -241,17 +252,17 @@ impl Definition {
241252 let primitive_mod =
242253 format ! ( "prim_{}" , it. name( ) . display( fd. 0 . db, display_target. edition) ) ;
243254 let doc_owner = find_std_module ( fd, & primitive_mod, display_target. edition ) ?;
244- doc_owner. docs ( fd. 0 . db )
255+ doc_owner. docs_with_rangemap ( fd. 0 . db )
245256 } )
246257 }
247258 Definition :: BuiltinLifetime ( StaticLifetime ) => None ,
248259 Definition :: Local ( _) => None ,
249260 Definition :: SelfType ( impl_def) => {
250- impl_def. self_ty ( db) . as_adt ( ) . map ( |adt| adt. docs ( db) ) ?
261+ impl_def. self_ty ( db) . as_adt ( ) . map ( |adt| adt. docs_with_rangemap ( db) ) ?
251262 }
252263 Definition :: GenericParam ( _) => None ,
253264 Definition :: Label ( _) => None ,
254- Definition :: ExternCrateDecl ( it) => it. docs ( db) ,
265+ Definition :: ExternCrateDecl ( it) => it. docs_with_rangemap ( db) ,
255266
256267 Definition :: BuiltinAttr ( it) => {
257268 let name = it. name ( db) ;
@@ -276,7 +287,8 @@ impl Definition {
276287 name_value_str
277288 ) ;
278289 }
279- Some ( Documentation :: new ( docs. replace ( '*' , "\\ *" ) ) )
290+
291+ return Some ( ( Documentation :: new ( docs. replace ( '*' , "\\ *" ) ) , None ) ) ;
280292 }
281293 Definition :: ToolModule ( _) => None ,
282294 Definition :: DeriveHelper ( _) => None ,
@@ -291,8 +303,9 @@ impl Definition {
291303 let trait_ = assoc. implemented_trait ( db) ?;
292304 let name = Some ( assoc. name ( db) ?) ;
293305 let item = trait_. items ( db) . into_iter ( ) . find ( |it| it. name ( db) == name) ?;
294- item. docs ( db)
306+ item. docs_with_rangemap ( db)
295307 } )
308+ . map ( |( docs, range_map) | ( docs, Some ( range_map) ) )
296309 }
297310
298311 pub fn label ( & self , db : & RootDatabase , display_target : DisplayTarget ) -> String {
0 commit comments