diff --git a/.gitignore b/.gitignore index a9d37c5..d6b0901 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.DS_Store target Cargo.lock diff --git a/examples/read.rs b/examples/read.rs index e1e6d7d..b43bd81 100644 --- a/examples/read.rs +++ b/examples/read.rs @@ -13,6 +13,7 @@ fn load_from_reader(mut rdr: R) -> SourceMap { ..Default::default() }) .unwrap(), + _ => panic!("unexpected sourcemap format"), } } diff --git a/examples/rewrite.rs b/examples/rewrite.rs index 56e18c2..9b987c1 100644 --- a/examples/rewrite.rs +++ b/examples/rewrite.rs @@ -30,6 +30,7 @@ fn load_from_reader(mut rdr: R) -> SourceMap { ..Default::default() }) .unwrap(), + _ => panic!("unexpected sourcemap format"), } } diff --git a/examples/split_ram_bundle.rs b/examples/split_ram_bundle.rs index 186b462..ccacd4e 100644 --- a/examples/split_ram_bundle.rs +++ b/examples/split_ram_bundle.rs @@ -16,7 +16,7 @@ source files and their sourcemaps. Both indexed and file RAM bundles are supported. "; -fn main() -> Result<(), Box> { +fn main() -> Result<(), Box> { let args: Vec<_> = env::args().collect(); if args.len() < 4 { println!("{}", USAGE); diff --git a/src/decoder.rs b/src/decoder.rs index 5b19f2c..baf7679 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -6,6 +6,7 @@ use serde_json; use serde_json::Value; use crate::errors::{Error, Result}; +use crate::hermes::decode_hermes; use crate::jsontypes::RawSourceMap; use crate::types::{DecodedMap, RawToken, SourceMap, SourceMapIndex, SourceMapSection}; use crate::vlq::parse_vlq_segment; @@ -121,7 +122,7 @@ pub fn strip_junk_header(slice: &[u8]) -> io::Result<&[u8]> { Ok(&slice[slice.len()..]) } -fn decode_regular(rsm: RawSourceMap) -> Result { +pub fn decode_regular(rsm: RawSourceMap) -> Result { let mut dst_col; let mut src_id = 0; let mut src_line = 0; @@ -267,6 +268,8 @@ fn decode_index(rsm: RawSourceMap) -> Result { fn decode_common(rsm: RawSourceMap) -> Result { Ok(if rsm.sections.is_some() { DecodedMap::Index(decode_index(rsm)?) + } else if rsm.x_facebook_sources.is_some() { + DecodedMap::Hermes(decode_hermes(rsm)?) } else { DecodedMap::Regular(decode_regular(rsm)?) }) diff --git a/src/encoder.rs b/src/encoder.rs index f05397d..2961df4 100644 --- a/src/encoder.rs +++ b/src/encoder.rs @@ -94,6 +94,7 @@ impl Encodable for SourceMap { mappings: Some(serialize_mappings(self)), x_facebook_offsets: None, x_metro_module_paths: None, + x_facebook_sources: None, } } } @@ -124,6 +125,7 @@ impl Encodable for SourceMapIndex { mappings: None, x_facebook_offsets: None, x_metro_module_paths: None, + x_facebook_sources: None, } } } @@ -133,6 +135,7 @@ impl Encodable for DecodedMap { match *self { DecodedMap::Regular(ref sm) => sm.as_raw_sourcemap(), DecodedMap::Index(ref smi) => smi.as_raw_sourcemap(), + DecodedMap::Hermes(ref smh) => smh.as_raw_sourcemap(), } } } diff --git a/src/errors.rs b/src/errors.rs index 2f78556..4c0d2fa 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -31,12 +31,8 @@ pub enum Error { BadSourceReference(u32), /// a reference to a non existing name was encountered BadNameReference(u32), - /// Indicates that an indexed sourcemap was encountered when - /// a regular sourcemap was expected - IndexedSourcemap, - /// Indicates that an regular (non-indexed) sourcemap was when - /// a sourcemap index was expected - RegularSourcemap, + /// Indicates that an incompatible sourcemap format was encountered + IncompatibleSourceMap, /// Indicates an invalid data URL InvalidDataUrl, /// Flatten failed @@ -97,8 +93,7 @@ impl error::Error for Error { BadSegmentSize(_) => "bad segment size", BadSourceReference(_) => "bad source reference", BadNameReference(_) => "bad name reference", - IndexedSourcemap => "unexpected indexed sourcemap", - RegularSourcemap => "unexpected sourcemap", + IncompatibleSourceMap => "incompatible sourcemap", InvalidDataUrl => "invalid data URL", CannotFlatten(_) => "cannot flatten the given indexed sourcemap", InvalidRamBundleMagic => "invalid magic number for ram bundle", @@ -133,11 +128,7 @@ impl fmt::Display for Error { BadSegmentSize(size) => write!(f, "got {} segments, expected 4 or 5", size), BadSourceReference(id) => write!(f, "bad reference to source #{}", id), BadNameReference(id) => write!(f, "bad reference to name #{}", id), - IndexedSourcemap => write!(f, "encountered unexpected indexed sourcemap"), - RegularSourcemap => write!( - f, - "encountered unexpected sourcemap where index was expected" - ), + IncompatibleSourceMap => write!(f, "encountered incompatible sourcemap format"), InvalidDataUrl => write!(f, "the provided data URL is invalid"), CannotFlatten(ref msg) => write!(f, "cannot flatten the indexed sourcemap: {}", msg), InvalidRamBundleMagic => write!(f, "invalid magic number for ram bundle"), diff --git a/src/hermes.rs b/src/hermes.rs new file mode 100644 index 0000000..c88fd2d --- /dev/null +++ b/src/hermes.rs @@ -0,0 +1,196 @@ +use crate::decoder::{decode, decode_regular, decode_slice}; +use crate::encoder::{encode, Encodable}; +use crate::errors::{Error, Result}; +use crate::jsontypes::{FacebookScopeMapping, FacebookSources, RawSourceMap}; +use crate::types::{DecodedMap, RewriteOptions, SourceMap}; +use crate::vlq::parse_vlq_segment; +use std::cmp::Ordering; +use std::io::{Read, Write}; +use std::ops::{Deref, DerefMut}; + +/// These are starting locations of scopes. +/// The `name_index` represents the index into the `HermesFunctionMap.names` vec, +/// which represents the function names/scopes. +pub struct HermesScopeOffset { + line: u32, + column: u32, + name_index: u32, +} + +pub struct HermesFunctionMap { + names: Vec, + mappings: Vec, +} + +/// Represents a `react-native`-style SourceMap, which has additional scope +/// information embedded. +pub struct SourceMapHermes { + pub(crate) sm: SourceMap, + // There should be one `HermesFunctionMap` per each `sources` entry in the main SourceMap. + function_maps: Vec>, + // XXX: right now, I am too lazy to actually serialize the above `function_maps` + // back into json types, so just keep the original json. Might be a bit inefficient, but meh. + raw_facebook_sources: FacebookSources, +} + +impl Deref for SourceMapHermes { + type Target = SourceMap; + + fn deref(&self) -> &Self::Target { + &self.sm + } +} + +impl DerefMut for SourceMapHermes { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.sm + } +} + +impl Encodable for SourceMapHermes { + fn as_raw_sourcemap(&self) -> RawSourceMap { + // TODO: need to serialize the `HermesFunctionMap` mappings + let mut rsm = self.sm.as_raw_sourcemap(); + rsm.x_facebook_sources = self.raw_facebook_sources.clone(); + rsm + } +} + +impl SourceMapHermes { + /// Creates a sourcemap from a reader over a JSON stream in UTF-8 + /// format. + /// + /// See [`SourceMap::from_reader`](struct.SourceMap.html#method.from_reader) + pub fn from_reader(rdr: R) -> Result { + match decode(rdr)? { + DecodedMap::Hermes(sm) => Ok(sm), + _ => Err(Error::IncompatibleSourceMap), + } + } + + /// Creates a sourcemap from a reader over a JSON byte slice in UTF-8 + /// format. + /// + /// See [`SourceMap::from_slice`](struct.SourceMap.html#method.from_slice) + pub fn from_slice(slice: &[u8]) -> Result { + match decode_slice(slice)? { + DecodedMap::Hermes(sm) => Ok(sm), + _ => Err(Error::IncompatibleSourceMap), + } + } + + /// Writes a sourcemap into a writer. + /// + /// See [`SourceMap::to_writer`](struct.SourceMap.html#method.to_writer) + pub fn to_writer(&self, w: W) -> Result<()> { + encode(self, w) + } + + /// Given a bytecode offset, this will find the enclosing scopes function + /// name. + pub fn get_original_function_name(&self, bytecode_offset: u32) -> Option<&str> { + let token = self.sm.lookup_token(0, bytecode_offset)?; + + let function_map = (self.function_maps.get(token.get_src_id() as usize))?.as_ref()?; + + // Find the closest mapping, just like here: + // https://github.com/facebook/metro/blob/63b523eb20e7bdf62018aeaf195bb5a3a1a67f36/packages/metro-symbolicate/src/SourceMetadataMapConsumer.js#L204-L231 + let mapping = + function_map + .mappings + .binary_search_by(|o| match o.line.cmp(&token.get_src_line()) { + Ordering::Equal => o.column.cmp(&token.get_src_col()), + x => x, + }); + let name_index = function_map + .mappings + .get(match mapping { + Ok(a) => a, + Err(a) => a.saturating_sub(1), + })? + .name_index; + + function_map + .names + .get(name_index as usize) + .map(|n| n.as_str()) + } + + /// This rewrites the sourcemap according to the provided rewrite + /// options. + /// + /// See [`SourceMap::rewrite`](struct.SourceMap.html#method.rewrite) + pub fn rewrite(self, options: &RewriteOptions<'_>) -> Result { + let Self { + sm, + function_maps, + raw_facebook_sources, + } = self; + let sm = sm.rewrite(options)?; + Ok(Self { + sm, + function_maps, + raw_facebook_sources, + }) + } +} + +pub fn decode_hermes(mut rsm: RawSourceMap) -> Result { + let x_facebook_sources = rsm + .x_facebook_sources + .take() + .ok_or(Error::IncompatibleSourceMap)?; + + // This is basically the logic from here: + // https://github.com/facebook/metro/blob/63b523eb20e7bdf62018aeaf195bb5a3a1a67f36/packages/metro-symbolicate/src/SourceMetadataMapConsumer.js#L182-L202 + + let function_maps = x_facebook_sources + .iter() + .map(|v| { + let FacebookScopeMapping { + names, + mappings: raw_mappings, + } = v.as_ref()?.iter().next()?; + + let mut mappings = vec![]; + let mut line = 1; + let mut name_index = 0; + + for line_mapping in raw_mappings.split(';') { + if line_mapping.is_empty() { + continue; + } + + let mut column = 0; + + for mapping in line_mapping.split(',') { + if mapping.is_empty() { + continue; + } + + let mut nums = parse_vlq_segment(mapping).ok()?.into_iter(); + + column = (i64::from(column) + nums.next()?) as u32; + name_index = (i64::from(name_index) + nums.next().unwrap_or(0)) as u32; + line = (i64::from(line) + nums.next().unwrap_or(0)) as u32; + mappings.push(HermesScopeOffset { + column, + line, + name_index, + }); + } + } + Some(HermesFunctionMap { + names: names.clone(), + mappings, + }) + }) + .collect(); + + let sm = decode_regular(rsm)?; + Ok(SourceMapHermes { + sm, + function_maps, + raw_facebook_sources: Some(x_facebook_sources), + }) +} diff --git a/src/jsontypes.rs b/src/jsontypes.rs index 021c4da..77fa574 100644 --- a/src/jsontypes.rs +++ b/src/jsontypes.rs @@ -15,6 +15,18 @@ pub struct RawSection { pub map: Option>, } +#[derive(Serialize, Deserialize, Clone)] +pub struct FacebookScopeMapping { + pub names: Vec, + pub mappings: String, +} + +// Each element here is matching the `sources` of the outer SourceMap. +// It has a list of metadata, the first one of which is a *function map*, +// containing scope information as a nested source map. +// See the decoder in `hermes.rs` for details. +pub type FacebookSources = Option>>>; + #[derive(Serialize, Deserialize)] pub struct RawSourceMap { pub version: Option, @@ -35,6 +47,8 @@ pub struct RawSourceMap { pub x_facebook_offsets: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub x_metro_module_paths: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub x_facebook_sources: FacebookSources, } #[derive(Deserialize)] diff --git a/src/lib.rs b/src/lib.rs index b2e1e14..03f5521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,10 +55,11 @@ pub use crate::detector::{ SourceMapRef, }; pub use crate::errors::{Error, Result}; +pub use crate::hermes::SourceMapHermes; pub use crate::sourceview::SourceView; pub use crate::types::{ - DecodedMap, RawToken, RewriteOptions, SourceMap, SourceMapIndex, SourceMapSection, - SourceMapSectionIter, Token, TokenIter, + DecodedMap, IndexIter, NameIter, RawToken, RewriteOptions, SourceContentsIter, SourceIter, + SourceMap, SourceMapIndex, SourceMapSection, SourceMapSectionIter, Token, TokenIter, }; pub use crate::utils::make_relative_path; @@ -67,6 +68,7 @@ mod decoder; mod detector; mod encoder; mod errors; +mod hermes; mod jsontypes; mod sourceview; mod types; diff --git a/src/ram_bundle.rs b/src/ram_bundle.rs index 88eb9a6..64a8e75 100644 --- a/src/ram_bundle.rs +++ b/src/ram_bundle.rs @@ -429,7 +429,7 @@ impl<'a> Iterator for SplitRamBundleModuleIter<'a> { } } -/// Decontstructs a RAM bundle into a sequence of sources and their sourcemaps +/// Deconstructs a RAM bundle into a sequence of sources and their sourcemaps /// /// With the help of the RAM bundle's indexed sourcemap, the bundle is split into modules, /// where each module is represented by its minified source and the corresponding sourcemap that @@ -487,7 +487,7 @@ pub fn is_unbundle_path(bundle_path: &Path) -> bool { } #[test] -fn test_indexed_ram_bundle_parse() -> std::result::Result<(), Box> { +fn test_indexed_ram_bundle_parse() -> std::result::Result<(), Box> { let mut bundle_file = File::open("./tests/fixtures/ram_bundle/indexed_bundle_1/basic.jsbundle")?; let mut bundle_data = Vec::new(); @@ -536,7 +536,7 @@ fn test_indexed_ram_bundle_parse() -> std::result::Result<(), Box std::result::Result<(), Box> { +fn test_indexed_ram_bundle_split() -> std::result::Result<(), Box> { let ram_bundle = RamBundle::parse_indexed_from_path(Path::new( "./tests/fixtures/ram_bundle/indexed_bundle_1/basic.jsbundle", ))?; @@ -573,7 +573,7 @@ fn test_indexed_ram_bundle_split() -> std::result::Result<(), Box std::result::Result<(), Box> { +fn test_file_ram_bundle_parse() -> std::result::Result<(), Box> { let valid_bundle_path = Path::new("./tests/fixtures/ram_bundle/file_bundle_1/basic.bundle"); assert!(is_unbundle_path(&valid_bundle_path)); diff --git a/src/sourceview.rs b/src/sourceview.rs index 89138a5..63508c4 100644 --- a/src/sourceview.rs +++ b/src/sourceview.rs @@ -133,7 +133,7 @@ impl<'a> Iterator for Lines<'a> { /// Provides efficient access to minified sources. /// -/// This type is used to implement farily efficient source mapping +/// This type is used to implement fairly efficient source mapping /// operations. pub struct SourceView<'a> { source: Cow<'a, str>, diff --git a/src/types.rs b/src/types.rs index 558c523..fe4d5cc 100644 --- a/src/types.rs +++ b/src/types.rs @@ -8,6 +8,7 @@ use crate::builder::SourceMapBuilder; use crate::decoder::{decode, decode_slice}; use crate::encoder::encode; use crate::errors::{Error, Result}; +use crate::hermes::SourceMapHermes; use crate::sourceview::SourceView; use crate::utils::find_common_prefix; @@ -60,6 +61,8 @@ pub enum DecodedMap { Regular(SourceMap), /// Indicates a sourcemap index Index(SourceMapIndex), + /// Indicates a sourcemap as generated by Metro+Hermes, as used by react-native + Hermes(SourceMapHermes), } impl DecodedMap { @@ -73,6 +76,7 @@ impl DecodedMap { match *self { DecodedMap::Regular(ref sm) => encode(sm, w), DecodedMap::Index(ref smi) => encode(smi, w), + DecodedMap::Hermes(ref smh) => encode(smh, w), } } @@ -84,6 +88,7 @@ impl DecodedMap { match *self { DecodedMap::Regular(ref sm) => sm.lookup_token(line, col), DecodedMap::Index(ref smi) => smi.lookup_token(line, col), + DecodedMap::Hermes(ref smh) => smh.lookup_token(line, col), } } } @@ -445,7 +450,7 @@ impl SourceMap { pub fn from_reader(rdr: R) -> Result { match decode(rdr)? { DecodedMap::Regular(sm) => Ok(sm), - DecodedMap::Index(_) => Err(Error::IndexedSourcemap), + _ => Err(Error::IncompatibleSourceMap), } } @@ -491,7 +496,7 @@ impl SourceMap { pub fn from_slice(slice: &[u8]) -> Result { match decode_slice(slice)? { DecodedMap::Regular(sm) => Ok(sm), - DecodedMap::Index(_) => Err(Error::IndexedSourcemap), + _ => Err(Error::IncompatibleSourceMap), } } @@ -698,7 +703,7 @@ impl SourceMap { } } - /// This rewrites the sourcemap accoridng to the provided rewrite + /// This rewrites the sourcemap according to the provided rewrite /// options. /// /// The default behavior is to just deduplicate the sourcemap, something @@ -769,8 +774,8 @@ impl SourceMapIndex { /// sourcemap is encountered an error is returned. pub fn from_reader(rdr: R) -> Result { match decode(rdr)? { - DecodedMap::Regular(_) => Err(Error::RegularSourcemap), DecodedMap::Index(smi) => Ok(smi), + _ => Err(Error::IncompatibleSourceMap), } } @@ -785,8 +790,8 @@ impl SourceMapIndex { /// sourcemap is encountered an error is returned. pub fn from_slice(slice: &[u8]) -> Result { match decode_slice(slice)? { - DecodedMap::Regular(_) => Err(Error::RegularSourcemap), DecodedMap::Index(smi) => Ok(smi), + _ => Err(Error::IncompatibleSourceMap), } } @@ -889,6 +894,7 @@ impl SourceMapIndex { Some(map) => match map { DecodedMap::Regular(sm) => Cow::Borrowed(sm), DecodedMap::Index(idx) => Cow::Owned(idx.flatten()?), + DecodedMap::Hermes(smh) => Cow::Borrowed(&smh.sm), }, None => { return Err(Error::CannotFlatten(format!( diff --git a/tests/fixtures/react-native-hermes/README.md b/tests/fixtures/react-native-hermes/README.md new file mode 100644 index 0000000..a5050b5 --- /dev/null +++ b/tests/fixtures/react-native-hermes/README.md @@ -0,0 +1,23 @@ +The sourcemap here was generated like this: + +Basically this is the same that the `react-native` gradle file does, see: +https://github.com/facebook/react-native/blob/4185a45be40e014d5e6315c70de00fe5f76c726a/react.gradle#L156-L204 + +```sh + $ npx react-native bundle --platform android --entry-file input.js --bundle-output intermediate.js --sourcemap-output intermediate.js.map + $ hermes -O -emit-binary -output-source-map -out=intermediate2 intermediate.js + $ node react-native/scripts/compose-source-maps.js intermediate.js.map intermediate2.map -o output.map +``` + +When running the bytecode, we will get the following stacktrace +(probably a bit different when done in react-native properly): + +``` +Error: lets throw! + at foo (address at unknown:1:11939) + at anonymous (address at unknown:1:11857) + at loadModuleImplementation (address at unknown:1:2608) + at guardedLoadModule (address at unknown:1:1973) + at metroRequire (address at unknown:1:1494) + at global (address at unknown:1:508) +``` diff --git a/tests/fixtures/react-native-hermes/input.js b/tests/fixtures/react-native-hermes/input.js new file mode 100644 index 0000000..8e4a742 --- /dev/null +++ b/tests/fixtures/react-native-hermes/input.js @@ -0,0 +1,3 @@ +import { foo } from "./module.js" + +foo(); diff --git a/tests/fixtures/react-native-hermes/module.js b/tests/fixtures/react-native-hermes/module.js new file mode 100644 index 0000000..836c03e --- /dev/null +++ b/tests/fixtures/react-native-hermes/module.js @@ -0,0 +1,3 @@ +export function foo() { + throw new Error("lets throw!"); +} diff --git a/tests/fixtures/react-native-hermes/output.map b/tests/fixtures/react-native-hermes/output.map new file mode 100644 index 0000000..8b15e6c --- /dev/null +++ b/tests/fixtures/react-native-hermes/output.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/metro/src/lib/polyfills/require.js","node_modules/react-native/Libraries/polyfills/console.js","node_modules/react-native/Libraries/polyfills/error-guard.js","node_modules/react-native/Libraries/polyfills/Object.es7.js","input.js","module.js"],"names":["__DEV__","Object","metroRequire","metroImportDefault","metroImportAll","unpackModuleId","modules","EMPTY","createHotReloadingObject","verboseNamesToModuleIds","global","console","initializingModuleIds","module","guardedLoadModule","Error","exports","hasOwnProperty","inGuard","loadModuleImplementation","ID_MASK_SHIFT","moduleId","LOCAL_ID_MASK","value","moduleDefinersBySegmentID","unknownModuleError","RefreshRuntime","registerExportsForReactRefresh","moduleThrewError","hot","Set","pendingModuleIDs","isReactRefreshBoundary","performFullRefresh","runUpdatedModule","updatedID","shouldInvalidateReactRefreshBoundary","reactRefreshTimeout","setTimeout","Refresh","window","hasExports","getRefreshBoundarySignature","moduleID","LOG_LEVELS","Array","level","INSPECTOR_LEVELS","INSPECTOR_FRAMES_TO_SKIP","groupStack","groupFormat","inspect","element","OBJECT_COLUMN_NAME","rows","columnWidths","stringRows","space","repeat","cell","Math","msg","GROUP_OPEN","GROUP_PAD","GROUP_CLOSE","stylizeNoColor","formatValue","hash","formatPrimitive","arrayToHash","isError","isFunction","isRegExp","isDate","isArray","RegExp","Date","formatError","formatArray","reduceToSingleString","braces","formatProperty","ctx","recurseTimes","visibleKeys","array","isUndefined","isString","isNumber","isBoolean","isNull","JSON","String","output","name","base","numLinesEst","prev","arg","isObject","objectToString","e","originalConsole","methodName","reactNativeMethod","_globalHandler","_inGuard","ErrorUtils","fun","context","guardName","TypeError"],"mappings":"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","x_facebook_sources":[[{"names":["","global.$RefreshReg$","global.$RefreshSig$","","clear","define","metroRequire","initializingModuleIds.slice.map$argument_0","metroImportDefault","metroImportAll","guardedLoadModule","unpackModuleId","packModuleId","registerSegment","loadModuleImplementation","unknownModuleError","moduleThrewError","metroRequire.Systrace.beginEvent","metroRequire.Systrace.endEvent","metroRequire.getModules","createHotReloadingObject","hot.accept","hot.dispose","metroHotUpdateModule","parentIDs.forEach$argument_0","setTimeout$argument_0","runUpdatedModule","performFullRefresh","isReactRefreshBoundary","shouldInvalidateReactRefreshBoundary","getRefreshBoundarySignature","registerExportsForReactRefresh"],"mappings":"AAA;wBCyB,QD;wBEE,MC,YH;AIG;CJM;AKO;CL2C;AME;aCyB,2DD;CNe;AQE;CRoB;ASI;CTmC;AUK;CViB;AWK;CXO;AYI;CZE;AaK;CbE;AcE;8BbqE;SaE;CduD;AeE;CfU;AgBE;ChBK;gBiBI,QjB;ckBC,QlB;4BmBG;GnBE;iCoBE;cCK;ODG;eEC;OFE;GpBG;+BuBI;wBCgG,2CD;yCEgG;SFI;GvBG;2B0BE;G1BuE;6B2BE;G3BkB;+B4BE;G5BmC;6C6BE;G7BmB;oC8BE;G9B2B;uC+BE;G/BqB"}],[{"names":["","","inspect","stylizeNoColor","arrayToHash","array.forEach$argument_0","formatValue","keys.map$argument_0","formatPrimitive","formatError","formatArray","keys.forEach$argument_0","formatProperty","str.split.map$argument_0","reduceToSingleString","output.reduce$argument_0","isArray","isBoolean","isNull","isNullOrUndefined","isNumber","isString","isSymbol","isUndefined","isRegExp","isObject","isDate","isError","isFunction","objectToString","hasOwnProperty","getNativeLogFunction","Array.prototype.map.call$argument_1","repeat","Array.apply.map$argument_0","consoleTablePolyfill","columns.forEach$argument_0","joinRow","row.map$argument_0","columnWidths.map$argument_0","groupFormat","consoleGroupPolyfill","consoleGroupCollapsedPolyfill","consoleGroupEndPolyfill","consoleAssertPolyfill","Object.keys.forEach$argument_0","methodName","forEach$argument_0","consoleLoggingStub"],"mappings":"AAA;iBCiB;ECwB;GDO;EEE;GFE;EGE;kBCG;KDE;GHG;EKE;wBC6F;ODS;GLM;EOE;GPgB;EQE;GRE;ESE;iBCkB;KDM;GTE;EWE;mBC4B;eDE;qBCQ;iBDE;GX0B;EaE;+BCE;KDI;Gbc;EeI;GfE;EgBE;GhBE;EiBE;GjBE;EkBE;GlBE;EmBE;GnBE;EoBE;GpBE;EqBE;GrBE;EsBE;GtBE;EuBE;GvBE;EwBE;GxBE;EyBE;GzBE;E0BE;G1BK;E2BE;G3BE;E4BE;G5BE;E6BE;G7BE;CDG;A+BmB;S9BC;yB+BM;S/BE;G8BuB;C/BC;AiCE;yCCC;GDE;CjCC;AmCE;kBCwB;GDQ;EEI;wBCC;KDG;GFG;oCIE;GJE;CnCc;AwCQ;CxCG;AyCE;CzCG;A0CE;C1CG;A2CE;C3CG;A4CE;C5CI;iC6CmC;8BCG;SDW;K7CE;c+CY;8BDE;SCE;K/CE;8BgDG,gChD"}],[{"names":["","onError","ErrorUtils.setGlobalHandler","ErrorUtils.getGlobalHandler","ErrorUtils.reportError","ErrorUtils.reportFatalError","ErrorUtils.applyWithGuard","ErrorUtils.applyWithGuardIfNeeded","ErrorUtils.inGuard","ErrorUtils.guard","guarded"],"mappings":"AAA;mCCqB;CDK;EEW;GFE;EGC;GHE;EIC;GJE;EKC;GLG;EMC;GNmB;EOC;GPY;EQC;GRE;ESC;ICY;KDQ;GTG"}],[{"names":["","","entries","values"],"mappings":"AAA;CCW;qBCU;KDa;oBEQ;KFa;CDE"}],[{"names":[""],"mappings":"AAA"}],[{"names":["","foo"],"mappings":"AAA,OC;CDE"}]]} \ No newline at end of file diff --git a/tests/test_hermes.rs b/tests/test_hermes.rs new file mode 100644 index 0000000..d9dafbd --- /dev/null +++ b/tests/test_hermes.rs @@ -0,0 +1,21 @@ +use sourcemap::SourceMapHermes; + +#[test] +fn test_react_native_hermes() { + let input = include_bytes!("./fixtures/react-native-hermes/output.map"); + let sm = SourceMapHermes::from_reader(&input[..]).unwrap(); + + // at foo (address at unknown:1:11939) + assert_eq!( + sm.lookup_token(0, 11939).unwrap().to_tuple(), + ("module.js", 1, 10, None) + ); + assert_eq!(sm.get_original_function_name(11939), Some("foo")); + + // at anonymous (address at unknown:1:11857) + assert_eq!( + sm.lookup_token(0, 11857).unwrap().to_tuple(), + ("input.js", 2, 0, None) + ); + assert_eq!(sm.get_original_function_name(11857), Some("")); +} diff --git a/tests/test_index.rs b/tests/test_index.rs index 3914704..df5965d 100644 --- a/tests/test_index.rs +++ b/tests/test_index.rs @@ -56,8 +56,8 @@ fn test_basic_indexed_sourcemap() { for section_id in 0..ism.get_section_count() { let section = ism.get_section_mut(section_id).unwrap(); let map = match section.get_sourcemap_mut().unwrap() { - DecodedMap::Index(_) => panic!("Invalid section type!"), DecodedMap::Regular(sm) => sm, + _ => panic!("Invalid section type!"), }; let contents = { let filename = map.get_source(0).unwrap();