@@ -26,7 +26,6 @@ use std::str::FromStr;
2626use std:: { fmt, fs} ;
2727
2828use indexmap:: IndexMap ;
29- use regex:: Regex ;
3029use rustc_ast:: join_path_syms;
3130use rustc_data_structures:: flock;
3231use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
@@ -376,12 +375,16 @@ fn hack_get_external_crate_names(
376375 } ;
377376 // this is only run once so it's fine not to cache it
378377 // !dot_matches_new_line: all crates on same line. greedy: match last bracket
379- let regex = Regex :: new ( r"\[.*\]" ) . unwrap ( ) ;
380- let Some ( content) = regex. find ( & content) else {
381- return Err ( Error :: new ( "could not find crates list in crates.js" , path) ) ;
382- } ;
383- let content: Vec < String > = try_err ! ( serde_json:: from_str( content. as_str( ) ) , & path) ;
384- Ok ( content)
378+
379+ if let Some ( start) = content. find ( '[' )
380+ && let Some ( end) = content[ start..] . find ( ']' )
381+ {
382+ let content: Vec < String > =
383+ try_err ! ( serde_json:: from_str( & content[ start..=start + end] ) , & path) ;
384+ Ok ( content)
385+ } else {
386+ Err ( Error :: new ( "could not find crates list in crates.js" , path) )
387+ }
385388}
386389
387390#[ derive( Serialize , Deserialize , Clone , Default , Debug ) ]
@@ -488,7 +491,15 @@ impl Hierarchy {
488491 let files = self . elems . borrow ( ) ;
489492 let name = OrderedJson :: serialize ( self . elem . to_str ( ) . expect ( "invalid osstring conversion" ) )
490493 . unwrap ( ) ;
491- let mut out = Vec :: from ( [ name] ) ;
494+ let needed_capacity = if !files. is_empty ( ) {
495+ 3
496+ } else if !subs. is_empty ( ) {
497+ 2
498+ } else {
499+ 1
500+ } ;
501+ let mut out = Vec :: with_capacity ( needed_capacity) ;
502+ out. push ( name) ;
492503 if !subs. is_empty ( ) || !files. is_empty ( ) {
493504 let subs = subs. iter ( ) . map ( |( _, s) | s. to_json_string ( ) ) ;
494505 out. push ( OrderedJson :: array_sorted ( subs) ) ;
@@ -504,33 +515,34 @@ impl Hierarchy {
504515
505516 fn add_path ( self : & Rc < Self > , path : & Path ) {
506517 let mut h = Rc :: clone ( self ) ;
507- let mut elems = path
508- . components ( )
509- . filter_map ( |s| match s {
510- Component :: Normal ( s) => Some ( s. to_owned ( ) ) ,
511- Component :: ParentDir => Some ( OsString :: from ( ".." ) ) ,
512- _ => None ,
513- } )
514- . peekable ( ) ;
515- loop {
516- let cur_elem = elems. next ( ) . expect ( "empty file path" ) ;
517- if cur_elem == ".." {
518- if let Some ( parent) = h. parent . upgrade ( ) {
519- h = parent;
518+ let mut components = path. components ( ) . peekable ( ) ;
519+
520+ while let Some ( component) = components. next ( ) {
521+ match component {
522+ Component :: Normal ( s) => {
523+ if components. peek ( ) . is_none ( ) {
524+ h. elems . borrow_mut ( ) . insert ( s. to_owned ( ) ) ;
525+ break ;
526+ }
527+ let next_h = {
528+ let mut children = h. children . borrow_mut ( ) ;
529+
530+ if let Some ( existing) = children. get ( s) {
531+ Rc :: clone ( existing)
532+ } else {
533+ let new_node = Rc :: new ( Self :: with_parent ( s. to_owned ( ) , & h) ) ;
534+ children. insert ( s. to_owned ( ) , Rc :: clone ( & new_node) ) ;
535+ new_node
536+ }
537+ } ;
538+ h = next_h;
520539 }
521- continue ;
522- }
523- if elems. peek ( ) . is_none ( ) {
524- h. elems . borrow_mut ( ) . insert ( cur_elem) ;
525- break ;
526- } else {
527- let entry = Rc :: clone (
528- h. children
529- . borrow_mut ( )
530- . entry ( cur_elem. clone ( ) )
531- . or_insert_with ( || Rc :: new ( Self :: with_parent ( cur_elem, & h) ) ) ,
532- ) ;
533- h = entry;
540+ Component :: ParentDir => {
541+ if let Some ( parent) = h. parent . upgrade ( ) {
542+ h = parent;
543+ }
544+ }
545+ _ => { }
534546 }
535547 }
536548 }
0 commit comments