Skip to content

Commit d91fe12

Browse files
fix: only compose matching inner map source in remapping
compose_pair previously returned the inner map for every outer source, so unrelated sources were incorrectly rewritten through the inner map. Restrict the match to outer sources that equal inner.file (or the sole outer source when inner.file is unset), leaving passthrough sources untouched.
1 parent 039feb2 commit d91fe12

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

crates/remapping/src/lib.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,23 @@ pub fn remap_chain(maps: &[&SourceMap]) -> Option<SourceMap> {
825825
/// Compose two source maps: outer maps generated → intermediate, inner maps intermediate → original.
826826
/// All sources in outer are resolved through inner.
827827
fn compose_pair(outer: &SourceMap, inner: &SourceMap) -> SourceMap {
828-
remap(outer, |_source| Some(inner.clone()))
828+
let fallback_source = if inner.file.is_none() {
829+
let mut sources = outer.sources.iter().filter(|source| !source.is_empty());
830+
match (sources.next(), sources.next()) {
831+
(Some(source), None) => Some(source.clone()),
832+
_ => None,
833+
}
834+
} else {
835+
None
836+
};
837+
838+
remap(outer, |source| {
839+
if inner.file.as_deref() == Some(source) || fallback_source.as_deref() == Some(source) {
840+
Some(inner.clone())
841+
} else {
842+
None
843+
}
844+
})
829845
}
830846

831847
/// Per-source entry for streaming variant.
@@ -1936,6 +1952,29 @@ mod tests {
19361952
assert_eq!(loc.line, 1);
19371953
}
19381954

1955+
#[test]
1956+
fn remap_chain_only_composes_matching_inner_file() {
1957+
let inner = SourceMap::from_json(
1958+
r#"{"version":3,"file":"intermediate.js","sources":["original.js"],"names":[],"mappings":"AAAA"}"#,
1959+
)
1960+
.unwrap();
1961+
let outer = SourceMap::from_json(
1962+
r#"{"version":3,"file":"output.js","sources":["intermediate.js","passthrough.js"],"names":[],"mappings":"AAAA,KCAA"}"#,
1963+
)
1964+
.unwrap();
1965+
1966+
let result = remap_chain(&[&outer, &inner]).unwrap();
1967+
1968+
assert!(result.sources.contains(&"original.js".to_string()));
1969+
assert!(result.sources.contains(&"passthrough.js".to_string()));
1970+
1971+
let remapped = result.original_position_for(0, 0).unwrap();
1972+
assert_eq!(result.source(remapped.source), "original.js");
1973+
1974+
let passthrough = result.original_position_for(0, 5).unwrap();
1975+
assert_eq!(result.source(passthrough.source), "passthrough.js");
1976+
}
1977+
19391978
// ── Empty-string source filtering ────────────────────────────
19401979

19411980
#[test]

0 commit comments

Comments
 (0)