@@ -39,7 +39,7 @@ use syntax::ast_map;
3939use syntax:: attr;
4040use syntax:: parse:: token:: { ident_interner, special_idents} ;
4141use syntax:: print:: pprust;
42- use syntax:: { ast, ast_util } ;
42+ use syntax:: ast;
4343use syntax:: codemap;
4444use syntax:: parse:: token;
4545
@@ -702,33 +702,114 @@ impl<'self> EachItemContext<'self> {
702702 }
703703}
704704
705- /// Iterates over all the paths in the given crate.
706- pub fn each_path ( intr : @ident_interner ,
707- cdata : cmd ,
708- get_crate_data : GetCrateDataCb ,
709- f : & fn ( & str , def_like , ast:: visibility ) -> bool )
710- -> bool {
711- // FIXME #4572: This function needs to be nuked, as it's impossible to
712- // make fast. It's the source of most of the performance problems when
713- // compiling small crates.
705+ fn each_child_of_item_or_crate ( intr : @ident_interner ,
706+ cdata : cmd ,
707+ item_doc : ebml:: Doc ,
708+ get_crate_data : GetCrateDataCb ,
709+ callback : & fn ( def_like , ast:: ident ) ) {
710+ // Iterate over all children.
711+ let _ = do reader:: tagged_docs ( item_doc, tag_mod_child) |child_info_doc| {
712+ let child_def_id = reader:: with_doc_data ( child_info_doc,
713+ parse_def_id) ;
714+ let child_def_id = translate_def_id ( cdata, child_def_id) ;
715+
716+ // This item may be in yet another crate if it was the child of a
717+ // reexport.
718+ let other_crates_items = if child_def_id. crate == cdata. cnum {
719+ reader:: get_doc ( reader:: Doc ( cdata. data ) , tag_items)
720+ } else {
721+ let crate_data = get_crate_data ( child_def_id. crate ) ;
722+ reader:: get_doc ( reader:: Doc ( crate_data. data ) , tag_items)
723+ } ;
724+
725+ // Get the item.
726+ match maybe_find_item ( child_def_id. node , other_crates_items) {
727+ None => { }
728+ Some ( child_item_doc) => {
729+ // Hand off the item to the callback.
730+ let child_name = item_name ( intr, child_item_doc) ;
731+ let def_like = item_to_def_like ( child_item_doc,
732+ child_def_id,
733+ cdata. cnum ) ;
734+ callback ( def_like, child_name) ;
735+ }
736+ }
737+
738+ true
739+ } ;
740+
741+ // Iterate over all reexports.
742+ let _ = do each_reexport ( item_doc) |reexport_doc| {
743+ let def_id_doc = reader:: get_doc ( reexport_doc,
744+ tag_items_data_item_reexport_def_id) ;
745+ let child_def_id = reader:: with_doc_data ( def_id_doc,
746+ parse_def_id) ;
747+ let child_def_id = translate_def_id ( cdata, child_def_id) ;
748+
749+ let name_doc = reader:: get_doc ( reexport_doc,
750+ tag_items_data_item_reexport_name) ;
751+ let name = name_doc. as_str_slice ( ) ;
752+
753+ // This reexport may be in yet another crate.
754+ let other_crates_items = if child_def_id. crate == cdata. cnum {
755+ reader:: get_doc ( reader:: Doc ( cdata. data ) , tag_items)
756+ } else {
757+ let crate_data = get_crate_data ( child_def_id. crate ) ;
758+ reader:: get_doc ( reader:: Doc ( crate_data. data ) , tag_items)
759+ } ;
760+
761+ // Get the item.
762+ match maybe_find_item ( child_def_id. node , other_crates_items) {
763+ None => { }
764+ Some ( child_item_doc) => {
765+ // Hand off the item to the callback.
766+ let def_like = item_to_def_like ( child_item_doc,
767+ child_def_id,
768+ cdata. cnum ) ;
769+ callback ( def_like, token:: str_to_ident ( name) ) ;
770+ }
771+ }
772+
773+ true
774+ } ;
775+ }
714776
777+ /// Iterates over each child of the given item.
778+ pub fn each_child_of_item ( intr : @ident_interner ,
779+ cdata : cmd ,
780+ id : ast:: NodeId ,
781+ get_crate_data : GetCrateDataCb ,
782+ callback : & fn ( def_like , ast:: ident ) ) {
783+ // Find the item.
784+ let root_doc = reader:: Doc ( cdata. data ) ;
785+ let items = reader:: get_doc ( root_doc, tag_items) ;
786+ let item_doc = match maybe_find_item ( id, items) {
787+ None => return ,
788+ Some ( item_doc) => item_doc,
789+ } ;
790+
791+ each_child_of_item_or_crate ( intr,
792+ cdata,
793+ item_doc,
794+ get_crate_data,
795+ callback)
796+ }
797+
798+ /// Iterates over all the top-level crate items.
799+ pub fn each_top_level_item_of_crate ( intr : @ident_interner ,
800+ cdata : cmd ,
801+ get_crate_data : GetCrateDataCb ,
802+ callback : & fn ( def_like , ast:: ident ) ) {
715803 let root_doc = reader:: Doc ( cdata. data ) ;
716804 let misc_info_doc = reader:: get_doc ( root_doc, tag_misc_info) ;
717805 let crate_items_doc = reader:: get_doc ( misc_info_doc,
718806 tag_misc_info_crate_items) ;
719807
720- let mut path_builder = ~"";
721-
722- let mut context = EachItemContext {
723- intr : intr,
724- cdata : cdata,
725- get_crate_data : get_crate_data,
726- path_builder : & mut path_builder,
727- callback : f,
728- } ;
729-
730- // Iterate over all top-level crate items.
731- context. each_child_of_module_or_crate ( crate_items_doc)
808+ each_child_of_item_or_crate ( intr,
809+ cdata,
810+ crate_items_doc,
811+ get_crate_data,
812+ callback)
732813}
733814
734815pub fn get_item_path ( cdata : cmd , id : ast:: NodeId ) -> ast_map:: path {
@@ -1268,21 +1349,6 @@ pub fn get_crate_vers(data: @~[u8]) -> @str {
12681349 }
12691350}
12701351
1271- fn iter_crate_items ( intr : @ident_interner , cdata : cmd ,
1272- get_crate_data : GetCrateDataCb ,
1273- proc : & fn ( path : & str , ast:: def_id ) ) {
1274- do each_path ( intr, cdata, get_crate_data) |path_string, def_like, _| {
1275- match def_like {
1276- dl_impl( * ) | dl_field => { }
1277- dl_def( def) => {
1278- proc ( path_string,
1279- ast_util:: def_id_of_def ( def) )
1280- }
1281- }
1282- true
1283- } ;
1284- }
1285-
12861352pub fn list_crate_metadata ( intr : @ident_interner , bytes : @~[ u8 ] ,
12871353 out : @io:: Writer ) {
12881354 let hash = get_crate_hash ( bytes) ;
0 commit comments