@@ -34,11 +34,13 @@ impl From<Documentation> for String {
34
34
35
35
pub trait HasDocs : HasAttrs {
36
36
fn docs ( self , db : & dyn HirDatabase ) -> Option < Documentation > ;
37
+ fn docs_with_rangemap ( self , db : & dyn HirDatabase ) -> Option < ( Documentation , DocsRangeMap ) > ;
37
38
fn resolve_doc_path (
38
39
self ,
39
40
db : & dyn HirDatabase ,
40
41
link : & str ,
41
42
ns : Option < hir:: Namespace > ,
43
+ is_inner_doc : bool ,
42
44
) -> Option < hir:: DocLinkDef > ;
43
45
}
44
46
/// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree.
@@ -53,7 +55,7 @@ pub struct DocsRangeMap {
53
55
54
56
impl DocsRangeMap {
55
57
/// Maps a [`TextRange`] relative to the documentation string back to its AST range
56
- pub fn map ( & self , range : TextRange ) -> Option < InFile < TextRange > > {
58
+ pub fn map ( & self , range : TextRange ) -> Option < ( InFile < TextRange > , AttrId ) > {
57
59
let found = self . mapping . binary_search_by ( |( probe, ..) | probe. ordering ( range) ) . ok ( ) ?;
58
60
let ( line_docs_range, idx, original_line_src_range) = self . mapping [ found] ;
59
61
if !line_docs_range. contains_range ( range) {
@@ -71,7 +73,7 @@ impl DocsRangeMap {
71
73
text_range. end ( ) + original_line_src_range. start ( ) + relative_range. start ( ) ,
72
74
string. syntax ( ) . text_range ( ) . len ( ) . min ( range. len ( ) ) ,
73
75
) ;
74
- Some ( InFile { file_id, value : range } )
76
+ Some ( ( InFile { file_id, value : range } , idx ) )
75
77
}
76
78
Either :: Right ( comment) => {
77
79
let text_range = comment. syntax ( ) . text_range ( ) ;
@@ -82,10 +84,22 @@ impl DocsRangeMap {
82
84
+ relative_range. start ( ) ,
83
85
text_range. len ( ) . min ( range. len ( ) ) ,
84
86
) ;
85
- Some ( InFile { file_id, value : range } )
87
+ Some ( ( InFile { file_id, value : range } , idx ) )
86
88
}
87
89
}
88
90
}
91
+
92
+ pub fn shift_docstring_line_range ( self , offset : TextSize ) -> DocsRangeMap {
93
+ let mapping = self
94
+ . mapping
95
+ . into_iter ( )
96
+ . map ( |( buf_offset, id, base_offset) | {
97
+ let buf_offset = buf_offset. checked_add ( offset) . unwrap ( ) ;
98
+ ( buf_offset, id, base_offset)
99
+ } )
100
+ . collect_vec ( ) ;
101
+ DocsRangeMap { source_map : self . source_map , mapping }
102
+ }
89
103
}
90
104
91
105
pub fn docs_with_rangemap (
@@ -161,13 +175,20 @@ macro_rules! impl_has_docs {
161
175
fn docs( self , db: & dyn HirDatabase ) -> Option <Documentation > {
162
176
docs_from_attrs( & self . attrs( db) ) . map( Documentation )
163
177
}
178
+ fn docs_with_rangemap(
179
+ self ,
180
+ db: & dyn HirDatabase ,
181
+ ) -> Option <( Documentation , DocsRangeMap ) > {
182
+ docs_with_rangemap( db, & self . attrs( db) )
183
+ }
164
184
fn resolve_doc_path(
165
185
self ,
166
186
db: & dyn HirDatabase ,
167
187
link: & str ,
168
- ns: Option <hir:: Namespace >
188
+ ns: Option <hir:: Namespace >,
189
+ is_inner_doc: bool ,
169
190
) -> Option <hir:: DocLinkDef > {
170
- resolve_doc_path_on( db, self , link, ns)
191
+ resolve_doc_path_on( db, self , link, ns, is_inner_doc )
171
192
}
172
193
}
173
194
) * } ;
@@ -184,13 +205,21 @@ macro_rules! impl_has_docs_enum {
184
205
fn docs( self , db: & dyn HirDatabase ) -> Option <Documentation > {
185
206
hir:: $enum:: $variant( self ) . docs( db)
186
207
}
208
+
209
+ fn docs_with_rangemap(
210
+ self ,
211
+ db: & dyn HirDatabase ,
212
+ ) -> Option <( Documentation , DocsRangeMap ) > {
213
+ hir:: $enum:: $variant( self ) . docs_with_rangemap( db)
214
+ }
187
215
fn resolve_doc_path(
188
216
self ,
189
217
db: & dyn HirDatabase ,
190
218
link: & str ,
191
- ns: Option <hir:: Namespace >
219
+ ns: Option <hir:: Namespace >,
220
+ is_inner_doc: bool ,
192
221
) -> Option <hir:: DocLinkDef > {
193
- hir:: $enum:: $variant( self ) . resolve_doc_path( db, link, ns)
222
+ hir:: $enum:: $variant( self ) . resolve_doc_path( db, link, ns, is_inner_doc )
194
223
}
195
224
}
196
225
) * } ;
@@ -207,16 +236,25 @@ impl HasDocs for hir::AssocItem {
207
236
}
208
237
}
209
238
239
+ fn docs_with_rangemap ( self , db : & dyn HirDatabase ) -> Option < ( Documentation , DocsRangeMap ) > {
240
+ match self {
241
+ hir:: AssocItem :: Function ( it) => it. docs_with_rangemap ( db) ,
242
+ hir:: AssocItem :: Const ( it) => it. docs_with_rangemap ( db) ,
243
+ hir:: AssocItem :: TypeAlias ( it) => it. docs_with_rangemap ( db) ,
244
+ }
245
+ }
246
+
210
247
fn resolve_doc_path (
211
248
self ,
212
249
db : & dyn HirDatabase ,
213
250
link : & str ,
214
251
ns : Option < hir:: Namespace > ,
252
+ is_inner_doc : bool ,
215
253
) -> Option < hir:: DocLinkDef > {
216
254
match self {
217
- hir:: AssocItem :: Function ( it) => it. resolve_doc_path ( db, link, ns) ,
218
- hir:: AssocItem :: Const ( it) => it. resolve_doc_path ( db, link, ns) ,
219
- hir:: AssocItem :: TypeAlias ( it) => it. resolve_doc_path ( db, link, ns) ,
255
+ hir:: AssocItem :: Function ( it) => it. resolve_doc_path ( db, link, ns, is_inner_doc ) ,
256
+ hir:: AssocItem :: Const ( it) => it. resolve_doc_path ( db, link, ns, is_inner_doc ) ,
257
+ hir:: AssocItem :: TypeAlias ( it) => it. resolve_doc_path ( db, link, ns, is_inner_doc ) ,
220
258
}
221
259
}
222
260
}
@@ -238,13 +276,36 @@ impl HasDocs for hir::ExternCrateDecl {
238
276
}
239
277
. map ( Documentation :: new)
240
278
}
279
+
280
+ fn docs_with_rangemap ( self , db : & dyn HirDatabase ) -> Option < ( Documentation , DocsRangeMap ) > {
281
+ let crate_docs = docs_with_rangemap ( db, & self . resolved_crate ( db) ?. root_module ( ) . attrs ( db) ) ;
282
+ let decl_docs = docs_with_rangemap ( db, & self . attrs ( db) ) ;
283
+ match ( decl_docs, crate_docs) {
284
+ ( None , None ) => None ,
285
+ ( Some ( decl_docs) , None ) => Some ( decl_docs) ,
286
+ ( None , Some ( crate_docs) ) => Some ( crate_docs) ,
287
+ (
288
+ Some ( ( Documentation ( mut decl_docs) , mut decl_range_map) ) ,
289
+ Some ( ( Documentation ( crate_docs) , crate_range_map) ) ,
290
+ ) => {
291
+ decl_docs. push ( '\n' ) ;
292
+ decl_docs. push ( '\n' ) ;
293
+ let offset = TextSize :: new ( decl_docs. len ( ) as u32 ) ;
294
+ decl_docs += & crate_docs;
295
+ let crate_range_map = crate_range_map. shift_docstring_line_range ( offset) ;
296
+ decl_range_map. mapping . extend ( crate_range_map. mapping ) ;
297
+ Some ( ( Documentation ( decl_docs) , decl_range_map) )
298
+ }
299
+ }
300
+ }
241
301
fn resolve_doc_path (
242
302
self ,
243
303
db : & dyn HirDatabase ,
244
304
link : & str ,
245
305
ns : Option < hir:: Namespace > ,
306
+ is_inner_doc : bool ,
246
307
) -> Option < hir:: DocLinkDef > {
247
- resolve_doc_path_on ( db, self , link, ns)
308
+ resolve_doc_path_on ( db, self , link, ns, is_inner_doc )
248
309
}
249
310
}
250
311
0 commit comments