@@ -124,13 +124,17 @@ impl StableFilemapId {
124
124
// CodeMap
125
125
//
126
126
127
+ pub ( super ) struct CodeMapFiles {
128
+ pub ( super ) file_maps : Vec < Lrc < FileMap > > ,
129
+ stable_id_to_filemap : FxHashMap < StableFilemapId , Lrc < FileMap > >
130
+ }
131
+
127
132
pub struct CodeMap {
128
- pub ( super ) files : Lock < Vec < Lrc < FileMap > > > ,
133
+ pub ( super ) files : Lock < CodeMapFiles > ,
129
134
file_loader : Box < FileLoader + Sync + Send > ,
130
135
// This is used to apply the file path remapping as specified via
131
136
// --remap-path-prefix to all FileMaps allocated within this CodeMap.
132
137
path_mapping : FilePathMapping ,
133
- stable_id_to_filemap : Lock < FxHashMap < StableFilemapId , Lrc < FileMap > > > ,
134
138
/// In case we are in a doctest, replace all file names with the PathBuf,
135
139
/// and add the given offsets to the line info
136
140
doctest_offset : Option < ( FileName , isize ) > ,
@@ -139,10 +143,12 @@ pub struct CodeMap {
139
143
impl CodeMap {
140
144
pub fn new ( path_mapping : FilePathMapping ) -> CodeMap {
141
145
CodeMap {
142
- files : Lock :: new ( Vec :: new ( ) ) ,
146
+ files : Lock :: new ( CodeMapFiles {
147
+ file_maps : Vec :: new ( ) ,
148
+ stable_id_to_filemap : FxHashMap ( ) ,
149
+ } ) ,
143
150
file_loader : Box :: new ( RealFileLoader ) ,
144
151
path_mapping,
145
- stable_id_to_filemap : Lock :: new ( FxHashMap ( ) ) ,
146
152
doctest_offset : None ,
147
153
}
148
154
}
@@ -160,10 +166,12 @@ impl CodeMap {
160
166
path_mapping : FilePathMapping )
161
167
-> CodeMap {
162
168
CodeMap {
163
- files : Lock :: new ( Vec :: new ( ) ) ,
169
+ files : Lock :: new ( CodeMapFiles {
170
+ file_maps : Vec :: new ( ) ,
171
+ stable_id_to_filemap : FxHashMap ( ) ,
172
+ } ) ,
164
173
file_loader : file_loader,
165
174
path_mapping,
166
- stable_id_to_filemap : Lock :: new ( FxHashMap ( ) ) ,
167
175
doctest_offset : None ,
168
176
}
169
177
}
@@ -187,16 +195,15 @@ impl CodeMap {
187
195
}
188
196
189
197
pub fn files ( & self ) -> LockGuard < Vec < Lrc < FileMap > > > {
190
- self . files . borrow ( )
198
+ LockGuard :: map ( self . files . borrow ( ) , |files| & mut files . file_maps )
191
199
}
192
200
193
201
pub fn filemap_by_stable_id ( & self , stable_id : StableFilemapId ) -> Option < Lrc < FileMap > > {
194
- self . stable_id_to_filemap . borrow ( ) . get ( & stable_id) . map ( |fm| fm. clone ( ) )
202
+ self . files . borrow ( ) . stable_id_to_filemap . get ( & stable_id) . map ( |fm| fm. clone ( ) )
195
203
}
196
204
197
205
fn next_start_pos ( & self ) -> usize {
198
- let files = self . files . borrow ( ) ;
199
- match files. last ( ) {
206
+ match self . files . borrow ( ) . file_maps . last ( ) {
200
207
None => 0 ,
201
208
// Add one so there is some space between files. This lets us distinguish
202
209
// positions in the codemap, even in the presence of zero-length files.
@@ -206,6 +213,7 @@ impl CodeMap {
206
213
207
214
/// Creates a new filemap without setting its line information. If you don't
208
215
/// intend to set the line information yourself, you should use new_filemap_and_lines.
216
+ /// This does not ensure that only one FileMap exists per file name.
209
217
pub fn new_filemap ( & self , filename : FileName , src : String ) -> Lrc < FileMap > {
210
218
let start_pos = self . next_start_pos ( ) ;
211
219
@@ -231,16 +239,16 @@ impl CodeMap {
231
239
Pos :: from_usize ( start_pos) ,
232
240
) ) ;
233
241
234
- self . files . borrow_mut ( ) . push ( filemap . clone ( ) ) ;
242
+ let mut files = self . files . borrow_mut ( ) ;
235
243
236
- self . stable_id_to_filemap
237
- . borrow_mut ( )
238
- . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
244
+ files. file_maps . push ( filemap. clone ( ) ) ;
245
+ files. stable_id_to_filemap . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
239
246
240
247
filemap
241
248
}
242
249
243
250
/// Creates a new filemap and sets its line information.
251
+ /// This does not ensure that only one FileMap exists per file name.
244
252
pub fn new_filemap_and_lines ( & self , filename : & Path , src : & str ) -> Lrc < FileMap > {
245
253
let fm = self . new_filemap ( filename. to_owned ( ) . into ( ) , src. to_owned ( ) ) ;
246
254
let mut byte_pos: u32 = fm. start_pos . 0 ;
@@ -303,11 +311,10 @@ impl CodeMap {
303
311
name_hash,
304
312
} ) ;
305
313
306
- self . files . borrow_mut ( ) . push ( filemap . clone ( ) ) ;
314
+ let mut files = self . files . borrow_mut ( ) ;
307
315
308
- self . stable_id_to_filemap
309
- . borrow_mut ( )
310
- . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
316
+ files. file_maps . push ( filemap. clone ( ) ) ;
317
+ files. stable_id_to_filemap . insert ( StableFilemapId :: new ( & filemap) , filemap. clone ( ) ) ;
311
318
312
319
filemap
313
320
}
@@ -398,7 +405,7 @@ impl CodeMap {
398
405
pub fn lookup_line ( & self , pos : BytePos ) -> Result < FileMapAndLine , Lrc < FileMap > > {
399
406
let idx = self . lookup_filemap_idx ( pos) ;
400
407
401
- let f = ( * self . files . borrow ( ) ) [ idx] . clone ( ) ;
408
+ let f = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
402
409
403
410
match f. lookup_line ( pos) {
404
411
Some ( line) => Ok ( FileMapAndLine { fm : f, line : line } ) ,
@@ -452,7 +459,7 @@ impl CodeMap {
452
459
}
453
460
454
461
pub fn span_to_string ( & self , sp : Span ) -> String {
455
- if self . files . borrow ( ) . is_empty ( ) && sp. source_equal ( & DUMMY_SP ) {
462
+ if self . files . borrow ( ) . file_maps . is_empty ( ) && sp. source_equal ( & DUMMY_SP ) {
456
463
return "no-location" . to_string ( ) ;
457
464
}
458
465
@@ -787,7 +794,7 @@ impl CodeMap {
787
794
}
788
795
789
796
pub fn get_filemap ( & self , filename : & FileName ) -> Option < Lrc < FileMap > > {
790
- for fm in self . files . borrow ( ) . iter ( ) {
797
+ for fm in self . files . borrow ( ) . file_maps . iter ( ) {
791
798
if * filename == fm. name {
792
799
return Some ( fm. clone ( ) ) ;
793
800
}
@@ -798,15 +805,15 @@ impl CodeMap {
798
805
/// For a global BytePos compute the local offset within the containing FileMap
799
806
pub fn lookup_byte_offset ( & self , bpos : BytePos ) -> FileMapAndBytePos {
800
807
let idx = self . lookup_filemap_idx ( bpos) ;
801
- let fm = ( * self . files . borrow ( ) ) [ idx] . clone ( ) ;
808
+ let fm = ( * self . files . borrow ( ) . file_maps ) [ idx] . clone ( ) ;
802
809
let offset = bpos - fm. start_pos ;
803
810
FileMapAndBytePos { fm : fm, pos : offset}
804
811
}
805
812
806
813
/// Converts an absolute BytePos to a CharPos relative to the filemap.
807
814
pub fn bytepos_to_file_charpos ( & self , bpos : BytePos ) -> CharPos {
808
815
let idx = self . lookup_filemap_idx ( bpos) ;
809
- let map = & ( * self . files . borrow ( ) ) [ idx] ;
816
+ let map = & ( * self . files . borrow ( ) . file_maps ) [ idx] ;
810
817
811
818
// The number of extra bytes due to multibyte chars in the FileMap
812
819
let mut total_extra_bytes = 0 ;
@@ -832,7 +839,7 @@ impl CodeMap {
832
839
// Return the index of the filemap (in self.files) which contains pos.
833
840
pub fn lookup_filemap_idx ( & self , pos : BytePos ) -> usize {
834
841
let files = self . files . borrow ( ) ;
835
- let files = & * files;
842
+ let files = & files. file_maps ;
836
843
let count = files. len ( ) ;
837
844
838
845
// Binary search for the filemap.
0 commit comments