1
+ use std:: cell:: RefCell ;
1
2
use std:: fs:: { self , File } ;
2
3
use std:: io:: prelude:: * ;
3
4
use std:: io:: { self , BufReader } ;
4
5
use std:: path:: { Component , Path } ;
5
- use std:: rc:: Rc ;
6
+ use std:: rc:: { Rc , Weak } ;
6
7
7
8
use itertools:: Itertools ;
8
9
use rustc_data_structures:: flock;
@@ -184,23 +185,26 @@ pub(super) fn write_shared(
184
185
185
186
use std:: ffi:: OsString ;
186
187
187
- #[ derive( Debug ) ]
188
+ #[ derive( Debug , Default ) ]
188
189
struct Hierarchy {
190
+ parent : Weak < Self > ,
189
191
elem : OsString ,
190
- children : FxHashMap < OsString , Hierarchy > ,
191
- elems : FxHashSet < OsString > ,
192
+ children : RefCell < FxHashMap < OsString , Rc < Self > > > ,
193
+ elems : RefCell < FxHashSet < OsString > > ,
192
194
}
193
195
194
196
impl Hierarchy {
195
- fn new ( elem : OsString ) -> Hierarchy {
196
- Hierarchy { elem, children : FxHashMap :: default ( ) , elems : FxHashSet :: default ( ) }
197
+ fn with_parent ( elem : OsString , parent : & Rc < Self > ) -> Self {
198
+ Self { elem, parent : Rc :: downgrade ( parent ) , .. Self :: default ( ) }
197
199
}
198
200
199
201
fn to_json_string ( & self ) -> String {
200
- let mut subs: Vec < & Hierarchy > = self . children . values ( ) . collect ( ) ;
202
+ let borrow = self . children . borrow ( ) ;
203
+ let mut subs: Vec < _ > = borrow. values ( ) . collect ( ) ;
201
204
subs. sort_unstable_by ( |a, b| a. elem . cmp ( & b. elem ) ) ;
202
205
let mut files = self
203
206
. elems
207
+ . borrow ( )
204
208
. iter ( )
205
209
. map ( |s| format ! ( "\" {}\" " , s. to_str( ) . expect( "invalid osstring conversion" ) ) )
206
210
. collect :: < Vec < _ > > ( ) ;
@@ -220,36 +224,52 @@ pub(super) fn write_shared(
220
224
files = files
221
225
)
222
226
}
223
- }
224
227
225
- if cx. include_sources {
226
- let mut hierarchy = Hierarchy :: new ( OsString :: new ( ) ) ;
227
- for source in cx
228
- . shared
229
- . local_sources
230
- . iter ( )
231
- . filter_map ( |p| p. 0 . strip_prefix ( & cx. shared . src_root ) . ok ( ) )
232
- {
233
- let mut h = & mut hierarchy;
234
- let mut elems = source
228
+ fn add_path ( self : & Rc < Self > , path : & Path ) {
229
+ let mut h = Rc :: clone ( & self ) ;
230
+ let mut elems = path
235
231
. components ( )
236
232
. filter_map ( |s| match s {
237
233
Component :: Normal ( s) => Some ( s. to_owned ( ) ) ,
234
+ Component :: ParentDir => Some ( OsString :: from ( ".." ) ) ,
238
235
_ => None ,
239
236
} )
240
237
. peekable ( ) ;
241
238
loop {
242
239
let cur_elem = elems. next ( ) . expect ( "empty file path" ) ;
240
+ if cur_elem == ".." {
241
+ if let Some ( parent) = h. parent . upgrade ( ) {
242
+ h = parent;
243
+ }
244
+ continue ;
245
+ }
243
246
if elems. peek ( ) . is_none ( ) {
244
- h. elems . insert ( cur_elem) ;
247
+ h. elems . borrow_mut ( ) . insert ( cur_elem) ;
245
248
break ;
246
249
} else {
247
- let e = cur_elem. clone ( ) ;
248
- h = h. children . entry ( cur_elem. clone ( ) ) . or_insert_with ( || Hierarchy :: new ( e) ) ;
250
+ let entry = Rc :: clone (
251
+ h. children
252
+ . borrow_mut ( )
253
+ . entry ( cur_elem. clone ( ) )
254
+ . or_insert_with ( || Rc :: new ( Self :: with_parent ( cur_elem, & h) ) ) ,
255
+ ) ;
256
+ h = entry;
249
257
}
250
258
}
251
259
}
260
+ }
252
261
262
+ if cx. include_sources {
263
+ let hierarchy = Rc :: new ( Hierarchy :: default ( ) ) ;
264
+ for source in cx
265
+ . shared
266
+ . local_sources
267
+ . iter ( )
268
+ . filter_map ( |p| p. 0 . strip_prefix ( & cx. shared . src_root ) . ok ( ) )
269
+ {
270
+ hierarchy. add_path ( source) ;
271
+ }
272
+ let hierarchy = Rc :: try_unwrap ( hierarchy) . unwrap ( ) ;
253
273
let dst = cx. dst . join ( & format ! ( "source-files{}.js" , cx. shared. resource_suffix) ) ;
254
274
let make_sources = || {
255
275
let ( mut all_sources, _krates) =
0 commit comments