@@ -39,6 +39,7 @@ use std::io;
3939use std:: io:: { fs, File , BufferedWriter } ;
4040use std:: str;
4141use std:: vec;
42+ use std:: vec_ng:: Vec ;
4243use collections:: { HashMap , HashSet } ;
4344
4445use sync:: Arc ;
@@ -160,6 +161,13 @@ pub struct Cache {
160161 priv search_index : ~[ IndexItem ] ,
161162 priv privmod : bool ,
162163 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 ) > ,
163171}
164172
165173/// 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<()> {
249257 extern_locations : HashMap :: new ( ) ,
250258 privmod : false ,
251259 public_items : public_items,
260+ orphan_methods : Vec :: new ( ) ,
252261 }
253262 } ) ;
254263 cache. stack . push ( krate. name . clone ( ) ) ;
255264 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+ }
256285
257286 // Add all the static files
258287 let mut dst = cx. dst . join ( krate. name . as_slice ( ) ) ;
@@ -527,26 +556,33 @@ impl DocFolder for Cache {
527556 clean:: TyMethodItem ( ..) |
528557 clean:: StructFieldItem ( ..) |
529558 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 ) ) )
532561
533562 }
534563 clean:: MethodItem ( ..) => {
535564 if self . parent_stack . len ( ) == 0 {
536- None
565+ ( None , None )
537566 } else {
538567 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
542578 } ;
543- Some ( ( Some ( * last) , self . stack . slice_to ( amt ) ) )
579+ ( Some ( * last) , path )
544580 }
545581 }
546- _ => Some ( ( None , self . stack . as_slice ( ) ) )
582+ _ => ( None , Some ( self . stack . as_slice ( ) ) )
547583 } ;
548584 match parent {
549- Some ( ( parent, path) ) if !self . privmod => {
585+ ( parent, Some ( path) ) if !self . privmod => {
550586 self . search_index . push ( IndexItem {
551587 ty : shortty ( & item) ,
552588 name : s. to_owned ( ) ,
@@ -555,7 +591,12 @@ impl DocFolder for Cache {
555591 parent : parent,
556592 } ) ;
557593 }
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+ _ => { }
559600 }
560601 }
561602 None => { }
0 commit comments