@@ -26,12 +26,7 @@ pub(crate) type DocumentationLink = String;
26
26
27
27
/// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs)
28
28
pub ( crate ) fn rewrite_links ( db : & RootDatabase , markdown : & str , definition : & Definition ) -> String {
29
- let mut cb = |link : BrokenLink | {
30
- Some ( (
31
- /*url*/ link. reference . to_owned ( ) . into ( ) ,
32
- /*title*/ link. reference . to_owned ( ) . into ( ) ,
33
- ) )
34
- } ;
29
+ let mut cb = broken_link_clone_cb;
35
30
let doc = Parser :: new_with_broken_link_callback ( markdown, Options :: empty ( ) , Some ( & mut cb) ) ;
36
31
37
32
let doc = map_links ( doc, |target, title : & str | {
@@ -124,45 +119,49 @@ pub(crate) fn external_docs(
124
119
pub ( crate ) fn extract_definitions_from_markdown (
125
120
markdown : & str ,
126
121
) -> Vec < ( Range < usize > , String , Option < hir:: Namespace > ) > {
127
- let mut res = vec ! [ ] ;
128
- let mut cb = | link : BrokenLink | {
129
- // These allocations are actually unnecessary but the lifetimes on BrokenLinkCallback are wrong
130
- // this is fixed in the repo but not on the crates.io release yet
131
- Some ( (
132
- /*url*/ link . reference . to_owned ( ) . into ( ) ,
133
- /*title*/ link . reference . to_owned ( ) . into ( ) ,
134
- ) )
135
- } ;
136
- let doc = Parser :: new_with_broken_link_callback ( markdown , Options :: empty ( ) , Some ( & mut cb ) ) ;
137
- for ( event , range ) in doc . into_offset_iter ( ) {
138
- if let Event :: Start ( Tag :: Link ( _ , target, title) ) = event {
139
- let link = if target . is_empty ( ) { title } else { target } ;
140
- let ( link, ns) = parse_intra_doc_link ( & link ) ;
141
- res . push ( ( range , link . to_string ( ) , ns ) ) ;
142
- }
143
- }
144
- res
122
+ extract_definitions_from_markdown_ ( markdown , & mut broken_link_clone_cb ) . collect ( )
123
+ }
124
+
125
+ fn extract_definitions_from_markdown_ < ' a > (
126
+ markdown : & ' a str ,
127
+ cb : & ' a mut dyn FnMut ( BrokenLink < ' _ > ) -> Option < ( CowStr < ' a > , CowStr < ' a > ) > ,
128
+ ) -> impl Iterator < Item = ( Range < usize > , String , Option < hir :: Namespace > ) > + ' a {
129
+ Parser :: new_with_broken_link_callback ( markdown , Options :: empty ( ) , Some ( cb ) )
130
+ . into_offset_iter ( )
131
+ . filter_map ( | ( event , range ) | {
132
+ if let Event :: Start ( Tag :: Link ( _ , target , title ) ) = event {
133
+ let link = if target. is_empty ( ) { title } else { target } ;
134
+ let ( link , ns ) = parse_intra_doc_link ( & link ) ;
135
+ Some ( ( range , link. to_string ( ) , ns) )
136
+ } else {
137
+ None
138
+ }
139
+ } )
145
140
}
146
141
147
142
/// Extracts a link from a comment at the given position returning the spanning range, link and
148
143
/// optionally it's namespace.
149
144
pub ( crate ) fn extract_positioned_link_from_comment (
150
145
position : TextSize ,
151
146
comment : & ast:: Comment ,
147
+ docs : hir:: Documentation ,
152
148
) -> Option < ( TextRange , String , Option < hir:: Namespace > ) > {
153
- let doc_comment = comment. doc_comment ( ) ?;
149
+ let doc_comment = comment. doc_comment ( ) ?. to_string ( ) + " \n " + docs . as_str ( ) ;
154
150
let comment_start =
155
151
comment. syntax ( ) . text_range ( ) . start ( ) + TextSize :: from ( comment. prefix ( ) . len ( ) as u32 ) ;
156
- let def_links = extract_definitions_from_markdown ( doc_comment) ;
157
- let ( range, def_link, ns) =
158
- def_links. into_iter ( ) . find_map ( |( Range { start, end } , def_link, ns) | {
152
+ let len = comment. syntax ( ) . text_range ( ) . len ( ) . into ( ) ;
153
+ let mut cb = broken_link_clone_cb;
154
+ // because pulldown_cmarks lifetimes are wrong we gotta dance around a few temporaries here
155
+ let res = extract_definitions_from_markdown_ ( & doc_comment, & mut cb)
156
+ . take_while ( |& ( Range { end, .. } , ..) | end < len)
157
+ . find_map ( |( Range { start, end } , def_link, ns) | {
159
158
let range = TextRange :: at (
160
159
comment_start + TextSize :: from ( start as u32 ) ,
161
160
TextSize :: from ( ( end - start) as u32 ) ,
162
161
) ;
163
162
range. contains ( position) . then ( || ( range, def_link, ns) )
164
- } ) ? ;
165
- Some ( ( range , def_link , ns ) )
163
+ } ) ;
164
+ res
166
165
}
167
166
168
167
/// Turns a syntax node into it's [`Definition`] if it can hold docs.
@@ -220,6 +219,15 @@ pub(crate) fn resolve_doc_path_for_def(
220
219
}
221
220
}
222
221
222
+ fn broken_link_clone_cb < ' a , ' b > ( link : BrokenLink < ' a > ) -> Option < ( CowStr < ' b > , CowStr < ' b > ) > {
223
+ // These allocations are actually unnecessary but the lifetimes on BrokenLinkCallback are wrong
224
+ // this is fixed in the repo but not on the crates.io release yet
225
+ Some ( (
226
+ /*url*/ link. reference . to_owned ( ) . into ( ) ,
227
+ /*title*/ link. reference . to_owned ( ) . into ( ) ,
228
+ ) )
229
+ }
230
+
223
231
// FIXME:
224
232
// BUG: For Option::Some
225
233
// Returns https://doc.rust-lang.org/nightly/core/prelude/v1/enum.Option.html#variant.Some
0 commit comments