@@ -39,6 +39,7 @@ use std::io;
39
39
use std:: io:: { fs, File , BufferedWriter } ;
40
40
use std:: str;
41
41
use std:: vec;
42
+ use std:: vec_ng:: Vec ;
42
43
use collections:: { HashMap , HashSet } ;
43
44
44
45
use sync:: Arc ;
@@ -160,6 +161,13 @@ pub struct Cache {
160
161
priv search_index : ~[ IndexItem ] ,
161
162
priv privmod : bool ,
162
163
priv public_items : NodeSet ,
164
+
165
+ // In rare case where a structure is defined in one module but implemented
166
+ // in another, if the implementing module is parsed before defining module,
167
+ // then the fully qualified name of the structure isn't presented in `paths`
168
+ // yet when its implementation methods are being indexed. Caches such methods
169
+ // and their parent id here and indexes them at the end of crate parsing.
170
+ priv orphan_methods : Vec < ( ast:: NodeId , clean:: Item ) > ,
163
171
}
164
172
165
173
/// Helper struct to render all source code to HTML pages
@@ -249,10 +257,31 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
249
257
extern_locations : HashMap :: new ( ) ,
250
258
privmod : false ,
251
259
public_items : public_items,
260
+ orphan_methods : Vec :: new ( ) ,
252
261
}
253
262
} ) ;
254
263
cache. stack . push ( krate. name . clone ( ) ) ;
255
264
krate = cache. fold_crate ( krate) ;
265
+ {
266
+ // Attach all orphan methods to the type's definition if the type
267
+ // has since been learned.
268
+ let Cache { search_index : ref mut index,
269
+ orphan_methods : ref meths, paths : ref paths, ..} = cache;
270
+ for & ( ref pid, ref item) in meths. iter ( ) {
271
+ match paths. find ( pid) {
272
+ Some ( & ( ref fqp, _) ) => {
273
+ index. push ( IndexItem {
274
+ ty : shortty ( item) ,
275
+ name : item. name . clone ( ) . unwrap ( ) ,
276
+ path : fqp. slice_to ( fqp. len ( ) - 1 ) . connect ( "::" ) ,
277
+ desc : shorter ( item. doc_value ( ) ) . to_owned ( ) ,
278
+ parent : Some ( * pid) ,
279
+ } ) ;
280
+ } ,
281
+ None => { }
282
+ }
283
+ } ;
284
+ }
256
285
257
286
// Add all the static files
258
287
let mut dst = cx. dst . join ( krate. name . as_slice ( ) ) ;
@@ -527,26 +556,33 @@ impl DocFolder for Cache {
527
556
clean:: TyMethodItem ( ..) |
528
557
clean:: StructFieldItem ( ..) |
529
558
clean:: VariantItem ( ..) => {
530
- Some ( ( Some ( * self . parent_stack . last ( ) . unwrap ( ) ) ,
531
- self . stack . slice_to ( self . stack . len ( ) - 1 ) ) )
559
+ ( Some ( * self . parent_stack . last ( ) . unwrap ( ) ) ,
560
+ Some ( self . stack . slice_to ( self . stack . len ( ) - 1 ) ) )
532
561
533
562
}
534
563
clean:: MethodItem ( ..) => {
535
564
if self . parent_stack . len ( ) == 0 {
536
- None
565
+ ( None , None )
537
566
} else {
538
567
let last = self . parent_stack . last ( ) . unwrap ( ) ;
539
- let amt = match self . paths . find ( last) {
540
- Some ( & ( _, "trait" ) ) => self . stack . len ( ) - 1 ,
541
- Some ( ..) | None => self . stack . len ( ) ,
568
+ let path = match self . paths . find ( last) {
569
+ Some ( & ( _, "trait" ) ) =>
570
+ Some ( self . stack . slice_to ( self . stack . len ( ) - 1 ) ) ,
571
+ // The current stack not necessarily has correlation for
572
+ // where the type was defined. On the other hand,
573
+ // `paths` always has the right information if present.
574
+ Some ( & ( ref fqp, "struct" ) ) | Some ( & ( ref fqp, "enum" ) ) =>
575
+ Some ( fqp. slice_to ( fqp. len ( ) - 1 ) ) ,
576
+ Some ( ..) => Some ( self . stack . as_slice ( ) ) ,
577
+ None => None
542
578
} ;
543
- Some ( ( Some ( * last) , self . stack . slice_to ( amt ) ) )
579
+ ( Some ( * last) , path )
544
580
}
545
581
}
546
- _ => Some ( ( None , self . stack . as_slice ( ) ) )
582
+ _ => ( None , Some ( self . stack . as_slice ( ) ) )
547
583
} ;
548
584
match parent {
549
- Some ( ( parent, path) ) if !self . privmod => {
585
+ ( parent, Some ( path) ) if !self . privmod => {
550
586
self . search_index . push ( IndexItem {
551
587
ty : shortty ( & item) ,
552
588
name : s. to_owned ( ) ,
@@ -555,7 +591,12 @@ impl DocFolder for Cache {
555
591
parent : parent,
556
592
} ) ;
557
593
}
558
- Some ( ..) | None => { }
594
+ ( Some ( parent) , None ) if !self . privmod => {
595
+ // We have a parent, but we don't know where they're
596
+ // defined yet. Wait for later to index this item.
597
+ self . orphan_methods . push ( ( parent, item. clone ( ) ) )
598
+ }
599
+ _ => { }
559
600
}
560
601
}
561
602
None => { }
0 commit comments