@@ -172,6 +172,7 @@ fn guess_sourcemap_reference(
172172/// and original url with which the file was added to the processor.
173173/// This enable us to look up the source map file based on the original url.
174174/// Which can be used for example for debug id referencing.
175+ #[ derive( Eq , Hash , PartialEq ) ]
175176pub struct SourceMapReference {
176177 url : String ,
177178 original_url : Option < String > ,
@@ -287,6 +288,7 @@ impl SourceMapProcessor {
287288 /// Collect references to sourcemaps in minified source files
288289 /// and saves them in `self.sourcemap_references`.
289290 fn collect_sourcemap_references ( & mut self ) {
291+ dbg ! ( & self . sources. iter( ) . map( |x| x. 0 . clone( ) ) . collect:: <Vec <_>>( ) ) ;
290292 // Collect available sourcemaps
291293 let sourcemaps: HashSet < _ > = self
292294 . sources
@@ -296,7 +298,7 @@ impl SourceMapProcessor {
296298 . map ( |x| x. url . clone ( ) )
297299 . collect ( ) ;
298300
299- let mut already_associated_sourcemaps = HashSet :: new ( ) ;
301+ let mut explicitly_associated_sourcemaps = HashMap :: new ( ) ;
300302
301303 let unassociated_js_source_locations: HashMap < _ , _ > = self
302304 . sources
@@ -323,7 +325,7 @@ impl SourceMapProcessor {
323325 . filter_map ( |( source, location) | location. as_ref ( ) . map ( |location| ( source, location) ) )
324326 . for_each ( |( source, location) | {
325327 // 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 ( ) ) ;
327329
328330 self . sourcemap_references . insert (
329331 source. url . clone ( ) ,
@@ -335,29 +337,64 @@ impl SourceMapProcessor {
335337 unassociated_js_source_locations
336338 . into_iter ( )
337339 . 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| {
341387 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
343394 ) ) ;
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 ) ;
357396 } ) ;
358-
359- self . sourcemap_references
360- . insert ( source. url . clone ( ) , sourcemap_reference) ;
397+ }
361398 } ) ;
362399 }
363400
0 commit comments