Skip to content

Commit 6fc0961

Browse files
progress
1 parent 2fd3914 commit 6fc0961

File tree

1 file changed

+59
-22
lines changed

1 file changed

+59
-22
lines changed

src/utils/sourcemaps.rs

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
175176
pub 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

Comments
 (0)