|
2 | 2 |
|
3 | 3 | extern crate pyo3; |
4 | 4 | extern crate source_map_mappings; |
| 5 | +#[macro_use] extern crate serde_derive; |
| 6 | +extern crate serde; |
| 7 | +extern crate serde_json; |
5 | 8 |
|
6 | 9 | use std::fs::File; |
7 | | -use std::io::{BufReader, Read}; |
8 | 10 |
|
9 | 11 | use pyo3::prelude::*; |
10 | | -use source_map_mappings::{Bias, Mappings, parse_mappings}; |
| 12 | +use source_map_mappings::{Bias, Mapping, Mappings, parse_mappings}; |
| 13 | + |
| 14 | +#[derive(Serialize, Deserialize, Debug)] |
| 15 | +#[serde(rename_all = "camelCase")] |
| 16 | +struct RawSourceMap { |
| 17 | + version: u8, |
| 18 | + sources: Vec<String>, |
| 19 | + names: Vec<String>, |
| 20 | + mappings: String, |
| 21 | + file: String, |
| 22 | + source_root: Option<String>, |
| 23 | +} |
11 | 24 |
|
12 | 25 | #[pyclass] |
13 | 26 | struct SourcemapParser { |
14 | | - parsed_map: Mappings<()> |
| 27 | + parsed_map: Mappings<()>, |
| 28 | + sources: Vec<String>, |
| 29 | + names: Vec<String>, |
15 | 30 | } |
16 | 31 |
|
17 | 32 | #[pymethods] |
18 | 33 | impl SourcemapParser { |
19 | 34 | #[new] |
20 | 35 | fn __new__(obj: &PyRawObject, path: &str) -> PyResult<()> { |
21 | 36 | let file = File::open(path).map_err(PyErr::from)?; |
22 | | - let mut buffers = vec![]; |
23 | | - let mut reader = BufReader::new(file); |
24 | | - reader.read_to_end(&mut buffers).map_err(PyErr::from)?; |
25 | | - let mappings = parse_mappings(&buffers).map_err(|_| PyErr::new::<exc::TypeError, _>(format!("Parse Sourcemap failed: {}", path)))?; |
26 | | - obj.init(|_| SourcemapParser { |
| 37 | + let raw_sourcemap: RawSourceMap = serde_json::from_reader(file).map_err(|e| { |
| 38 | + PyErr::new::<exc::TypeError, _>(format!("{:?}", e)) |
| 39 | + })?; |
| 40 | + let mapping_bytes = raw_sourcemap.mappings.as_bytes(); |
| 41 | + let mappings = parse_mappings(mapping_bytes).map_err(|_| { |
| 42 | + PyErr::new::<exc::TypeError, _>(format!("Parse Sourcemap failed: {}", path)) |
| 43 | + })?; |
| 44 | + let sources = raw_sourcemap.sources; |
| 45 | + let names = raw_sourcemap.names; |
| 46 | + obj.init(move |_| SourcemapParser { |
27 | 47 | parsed_map: mappings, |
| 48 | + sources, |
| 49 | + names, |
28 | 50 | }) |
29 | 51 | } |
30 | 52 |
|
31 | | - fn original_location_for(&self, generated_line: u32, generated_column: u32) -> PyResult<(u32, u32)> { |
32 | | - if let Some(mapping) = self.parsed_map.original_location_for(generated_line, generated_column, Bias::LeastUpperBound) { |
33 | | - return Ok((mapping.generated_line, mapping.generated_column)) |
| 53 | + fn original_location_for(&self, generated_line: u32, generated_column: u32) -> PyResult<(u32, u32, Option<String>, Option<String>)> { |
| 54 | + if let Some(Mapping { original, .. }) = self.parsed_map.original_location_for(generated_line, generated_column, Bias::LeastUpperBound) { |
| 55 | + match original { |
| 56 | + Some(location) => { |
| 57 | + let name = location.name.and_then(|index| { |
| 58 | + self.names.get(index as usize).map(|str_slice| str_slice.to_string()) |
| 59 | + }); |
| 60 | + let source = self.sources.get(location.source as usize).map(|str_slice| str_slice.to_string()); |
| 61 | + return Ok((location.original_line, location.original_column, source, name)) |
| 62 | + }, |
| 63 | + None => return Err(PyErr::new::<exc::TypeError, _>("No original lines")) |
| 64 | + }; |
34 | 65 | } |
35 | 66 | Err(PyErr::new::<exc::TypeError, _>("No sources found")) |
36 | 67 | } |
|
0 commit comments