1use std::cell::RefCell;
8use std::collections::HashMap;
9use std::collections::hash_map::Entry;
10use std::path::{Path, PathBuf};
11
12use ion::utils::normalise_path;
13use ion::{Error, ErrorReport, Exception};
14use swc_sourcemap::SourceMap;
15
16thread_local!(static SOURCEMAP_CACHE: RefCell<HashMap<PathBuf, SourceMap>> = RefCell::new(HashMap::new()));
17
18pub fn find_sourcemap<P: AsRef<Path>>(path: P) -> Option<SourceMap> {
19 SOURCEMAP_CACHE.with_borrow_mut(|cache| {
20 let path = path.as_ref().to_path_buf();
21 match cache.entry(path) {
22 Entry::Occupied(o) => Some(o.get().clone()),
23 Entry::Vacant(_) => None,
24 }
25 })
26}
27
28pub fn save_sourcemap<P: AsRef<Path>>(path: P, sourcemap: SourceMap) -> bool {
29 SOURCEMAP_CACHE.with_borrow_mut(|cache| {
30 let path = normalise_path(path);
31 match cache.entry(path) {
32 Entry::Vacant(v) => {
33 v.insert(sourcemap);
34 true
35 }
36 Entry::Occupied(_) => false,
37 }
38 })
39}
40
41pub fn transform_error_report_with_sourcemaps(report: &mut ErrorReport) {
42 if let Exception::Error(Error { location: Some(location), .. }) = &mut report.exception
43 && let Some(sourcemap) = find_sourcemap(&location.file)
44 {
45 report.exception.transform_with_sourcemap(&sourcemap);
46 }
47 if let Some(stack) = &mut report.stack {
48 for record in &mut stack.records {
49 if let Some(sourcemap) = find_sourcemap(&record.location.file) {
50 record.transform_with_sourcemap(&sourcemap);
51 }
52 }
53 }
54}