@@ -287,53 +287,78 @@ impl SourceMapProcessor {
287
287
/// Collect references to sourcemaps in minified source files
288
288
/// and saves them in `self.sourcemap_references`.
289
289
fn collect_sourcemap_references ( & mut self ) {
290
- let sourcemaps = self
290
+ // Collect available sourcemaps
291
+ let sourcemaps: HashSet < _ > = self
291
292
. sources
292
293
. iter ( )
293
294
. map ( |x| x. 1 )
294
295
. filter ( |x| x. ty == SourceFileType :: SourceMap )
295
296
. map ( |x| x. url . clone ( ) )
296
297
. collect ( ) ;
297
298
298
- for source in self . sources . values_mut ( ) {
299
- // Skip everything but minified JS files.
300
- if source. ty != SourceFileType :: MinifiedSource {
301
- continue ;
302
- }
299
+ let mut already_associated_sourcemaps = HashSet :: new ( ) ;
303
300
304
- if self . sourcemap_references . contains_key ( & source. url ) {
305
- continue ;
306
- }
307
-
308
- let Ok ( contents) = std:: str:: from_utf8 ( & source. contents ) else {
309
- continue ;
310
- } ;
301
+ let unassociated_js_source_locations: HashMap < _ , _ > = self
302
+ . sources
303
+ . values_mut ( )
304
+ . filter ( |source| source. ty == SourceFileType :: MinifiedSource )
305
+ . filter ( |source| !self . sourcemap_references . contains_key ( & source. url ) )
306
+ . filter_map ( |source| {
307
+ str:: from_utf8 ( & source. contents . clone ( ) )
308
+ . map ( |contents| {
309
+ (
310
+ source,
311
+ discover_sourcemaps_location ( contents)
312
+ . filter ( |loc| !is_remote_sourcemap ( loc) )
313
+ . map ( String :: from) ,
314
+ )
315
+ } )
316
+ . ok ( )
317
+ } )
318
+ . collect ( ) ;
311
319
312
- // If this is a full external URL, the code below is going to attempt
313
- // to "normalize" it with the source path, resulting in a bogus path
314
- // like "path/to/source/dir/https://some-static-host.example.com/path/to/foo.js.map"
315
- // that can't be resolved to a source map file.
316
- // Instead, we pretend we failed to discover the location, and we fall back to
317
- // guessing the source map location based on the source location.
318
- let location =
319
- discover_sourcemaps_location ( contents) . filter ( |loc| !is_remote_sourcemap ( loc) ) ;
320
- let sourcemap_reference = match location {
321
- Some ( url) => SourceMapReference :: from_url ( url. to_owned ( ) ) ,
322
- None => match guess_sourcemap_reference ( & sourcemaps, & source. url ) {
323
- Ok ( target) => target,
324
- Err ( err) => {
320
+ // First pass: if location discovered, add to sourcemap_references
321
+ unassociated_js_source_locations
322
+ . iter ( )
323
+ . filter_map ( |( source, location) | location. as_ref ( ) . map ( |location| ( source, location) ) )
324
+ . for_each ( |( source, location) | {
325
+ // Add location to already associated sourcemaps, so we cannot guess it again.
326
+ already_associated_sourcemaps. insert ( location. to_owned ( ) ) ;
327
+
328
+ self . sourcemap_references . insert (
329
+ source. url . clone ( ) ,
330
+ Some ( SourceMapReference :: from_url ( location. to_owned ( ) ) ) ,
331
+ ) ;
332
+ } ) ;
333
+
334
+ // Second pass: for remaining sourcemaps, try to guess the location
335
+ unassociated_js_source_locations
336
+ . into_iter ( )
337
+ . filter ( |( _, location) | location. is_none ( ) )
338
+ . for_each ( |( source, _) | {
339
+ let sourcemap_reference = guess_sourcemap_reference ( & sourcemaps, & source. url )
340
+ . inspect_err ( |err| {
325
341
source. warn ( format ! (
326
342
"could not determine a source map reference ({err})"
327
343
) ) ;
328
- self . sourcemap_references . insert ( source. url . clone ( ) , None ) ;
329
- continue ;
330
- }
331
- } ,
332
- } ;
344
+ } )
345
+ . ok ( )
346
+ . filter ( |sourcemap_reference| {
347
+ !already_associated_sourcemaps. contains ( & sourcemap_reference. url )
348
+ } )
349
+ . inspect ( |sourcemap_reference| {
350
+ // In practice, original_url is always set in guess_sourcemap_reference
351
+ if let Some ( original_url) =
352
+ sourcemap_reference. original_url . as_ref ( ) . cloned ( )
353
+ {
354
+ // Add original url to already associated sourcemaps, so we cannot guess it again.
355
+ already_associated_sourcemaps. insert ( original_url) ;
356
+ }
357
+ } ) ;
333
358
334
- self . sourcemap_references
335
- . insert ( source. url . clone ( ) , Some ( sourcemap_reference) ) ;
336
- }
359
+ self . sourcemap_references
360
+ . insert ( source. url . clone ( ) , sourcemap_reference) ;
361
+ } ) ;
337
362
}
338
363
339
364
pub fn dump_log ( & self , title : & str ) {
0 commit comments