@@ -172,6 +172,7 @@ fn guess_sourcemap_reference(
172
172
/// and original url with which the file was added to the processor.
173
173
/// This enable us to look up the source map file based on the original url.
174
174
/// Which can be used for example for debug id referencing.
175
+ #[ derive( Eq , Hash , PartialEq ) ]
175
176
pub struct SourceMapReference {
176
177
url : String ,
177
178
original_url : Option < String > ,
@@ -287,6 +288,7 @@ impl SourceMapProcessor {
287
288
/// Collect references to sourcemaps in minified source files
288
289
/// and saves them in `self.sourcemap_references`.
289
290
fn collect_sourcemap_references ( & mut self ) {
291
+ dbg ! ( & self . sources. iter( ) . map( |x| x. 0 . clone( ) ) . collect:: <Vec <_>>( ) ) ;
290
292
// Collect available sourcemaps
291
293
let sourcemaps: HashSet < _ > = self
292
294
. sources
@@ -296,7 +298,7 @@ impl SourceMapProcessor {
296
298
. map ( |x| x. url . clone ( ) )
297
299
. collect ( ) ;
298
300
299
- let mut already_associated_sourcemaps = HashSet :: new ( ) ;
301
+ let mut explicitly_associated_sourcemaps = HashMap :: new ( ) ;
300
302
301
303
let unassociated_js_source_locations: HashMap < _ , _ > = self
302
304
. sources
@@ -323,7 +325,7 @@ impl SourceMapProcessor {
323
325
. filter_map ( |( source, location) | location. as_ref ( ) . map ( |location| ( source, location) ) )
324
326
. for_each ( |( source, location) | {
325
327
// Add location to already associated sourcemaps, so we cannot guess it again.
326
- already_associated_sourcemaps . insert ( location. to_owned ( ) ) ;
328
+ explicitly_associated_sourcemaps . insert ( location. to_owned ( ) , source . url . clone ( ) ) ;
327
329
328
330
self . sourcemap_references . insert (
329
331
source. url . clone ( ) ,
@@ -335,29 +337,64 @@ impl SourceMapProcessor {
335
337
unassociated_js_source_locations
336
338
. into_iter ( )
337
339
. filter ( |( _, location) | location. is_none ( ) )
338
- . for_each ( |( source, _) | {
339
- let sourcemap_reference = guess_sourcemap_reference ( & sourcemaps, & source. url )
340
- . inspect_err ( |err| {
340
+ . fold (
341
+ // Collect sources guessed as associated with each sourcemap. This way, we ensure
342
+ // we only associate the sourcemap with any sources if it is only guessed once.
343
+ HashMap :: new ( ) ,
344
+ |mut sources_associated_with_sm, ( source, _) | {
345
+ let sourcemap_reference = guess_sourcemap_reference ( & sourcemaps, & source. url )
346
+ . inspect_err ( |err| {
347
+ source. warn ( format ! (
348
+ "could not determine a source map reference ({err})"
349
+ ) ) ;
350
+ self . sourcemap_references . insert ( source. url . clone ( ) , None ) ;
351
+ } )
352
+ . ok ( )
353
+ . filter ( |sourcemap_reference| {
354
+ explicitly_associated_sourcemaps
355
+ . get ( & sourcemap_reference. url )
356
+ . inspect ( |url| {
357
+ source. warn ( format ! (
358
+ "based on the file name, we guessed a source map \
359
+ reference ({}), which is already associated with source \
360
+ {url}. Please explicitly set the sourcemap URL with a \
361
+ `//# sourceMappingURL=...` comment in the source file.",
362
+ sourcemap_reference. url
363
+ ) ) ;
364
+ } )
365
+ . is_none ( )
366
+ } ) ;
367
+
368
+ if let Some ( sourcemap_reference) = sourcemap_reference {
369
+ sources_associated_with_sm
370
+ . entry ( sourcemap_reference)
371
+ . or_insert_with ( Vec :: new)
372
+ . push ( source) ;
373
+ }
374
+ sources_associated_with_sm
375
+ } ,
376
+ )
377
+ . into_iter ( )
378
+ . for_each ( |( sourcemap_reference, mut sources) | {
379
+ if let [ source] = sources. as_slice ( ) {
380
+ // One source -> we can safely associate the sourcemap with it.
381
+ self . sourcemap_references
382
+ . insert ( source. url . clone ( ) , Some ( sourcemap_reference) ) ;
383
+ } else {
384
+ // Multiple sources -> it is unclear which source we should associate
385
+ // the sourcemap with, so don't associate it with any of them.
386
+ sources. iter_mut ( ) . for_each ( |source| {
341
387
source. warn ( format ! (
342
- "could not determine a source map reference ({err})"
388
+ "Could not associate this source with a source map. We \
389
+ guessed the sourcemap reference {} for multiple sources, including \
390
+ this one. Please explicitly set the sourcemap URL with a \
391
+ `//# sourceMappingURL=...` comment in the source file, to make the \
392
+ association clear.",
393
+ sourcemap_reference. url
343
394
) ) ;
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
- }
395
+ self . sourcemap_references . insert ( source. url . clone ( ) , None ) ;
357
396
} ) ;
358
-
359
- self . sourcemap_references
360
- . insert ( source. url . clone ( ) , sourcemap_reference) ;
397
+ }
361
398
} ) ;
362
399
}
363
400
0 commit comments