Skip to content

Commit

Permalink
feat: Support react-native hermes sourcemaps (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
Swatinem committed Feb 5, 2020
1 parent 1247179 commit 5c8de65
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 15 deletions.
6 changes: 3 additions & 3 deletions cabi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sourcemap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ edition = "2018"

[dependencies]
failure = "0.1.5"
sourcemap = "4.1.0"
sourcemap = "5.0.0"
90 changes: 79 additions & 11 deletions sourcemap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use std::borrow::Cow;
use std::fmt;
use std::ops::Deref;

use failure::Fail;

Expand Down Expand Up @@ -44,12 +45,29 @@ pub struct SourceView<'a> {
sv: sourcemap::SourceView<'a>,
}

enum SourceMapType {
Regular(sourcemap::SourceMap),
Hermes(sourcemap::SourceMapHermes),
}

impl Deref for SourceMapType {
type Target = sourcemap::SourceMap;

fn deref(&self) -> &Self::Target {
match self {
SourceMapType::Regular(sm) => sm,
SourceMapType::Hermes(smh) => smh,
}
}
}

/// Represents a source map.
pub struct SourceMapView {
sm: sourcemap::SourceMap,
sm: SourceMapType,
}

/// A matched token.
#[derive(Debug, Default, PartialEq)]
pub struct TokenMatch<'a> {
/// The line number in the original source file.
pub src_line: u32,
Expand Down Expand Up @@ -116,8 +134,9 @@ impl SourceMapView {
pub fn from_json_slice(buffer: &[u8]) -> Result<Self, ParseSourceMapError> {
Ok(SourceMapView {
sm: match sourcemap::decode_slice(buffer)? {
sourcemap::DecodedMap::Regular(sm) => sm,
sourcemap::DecodedMap::Index(smi) => smi.flatten()?,
sourcemap::DecodedMap::Regular(sm) => SourceMapType::Regular(sm),
sourcemap::DecodedMap::Index(smi) => SourceMapType::Regular(smi.flatten()?),
sourcemap::DecodedMap::Hermes(smh) => SourceMapType::Hermes(smh),
},
})
}
Expand Down Expand Up @@ -169,14 +188,26 @@ impl SourceMapView {
minified_name: &str,
source: &SourceView<'b>,
) -> Option<TokenMatch<'a>> {
self.sm.lookup_token(line, col).map(|token| {
let mut rv = self.make_token_match(token);
rv.function_name = source
.sv
.get_original_function_name(token, minified_name)
.map(str::to_owned);
rv
})
match &self.sm {
SourceMapType::Regular(sm) => sm.lookup_token(line, col).map(|token| {
let mut rv = self.make_token_match(token);
rv.function_name = source
.sv
.get_original_function_name(token, minified_name)
.map(str::to_owned);
rv
}),
SourceMapType::Hermes(smh) => {
// we use `col + 1` here, since hermes uses bytecode offsets which are 0-based,
// and the upstream python code does a `- 1` here:
// https://github.com/getsentry/sentry/blob/fdabccac7576c80674c2fed556d4c5407657dc4c/src/sentry/lang/javascript/processor.py#L584-L586
smh.lookup_token(line, col + 1).map(|token| {
let mut rv = self.make_token_match(token);
rv.function_name = smh.get_original_function_name(col + 1).map(str::to_owned);
rv
})
}
}
}

fn make_token_match<'a>(&'a self, tok: sourcemap::Token<'a>) -> TokenMatch<'a> {
Expand All @@ -192,3 +223,40 @@ impl SourceMapView {
}
}
}

#[test]
fn test_react_native_hermes() {
let bytes = include_bytes!("../tests/fixtures/react-native-hermes.map");
let smv = SourceMapView::from_json_slice(bytes).unwrap();
let sv = SourceView::new("");

// at foo (address at unknown:1:11939)
assert_eq!(
smv.lookup_token_with_function_name(0, 11939, "", &sv),
Some(TokenMatch {
src_line: 1,
src_col: 10,
dst_line: 0,
dst_col: 11939,
src_id: 5,
name: None,
src: Some("module.js"),
function_name: Some("foo".into())
})
);

// at anonymous (address at unknown:1:11857)
assert_eq!(
smv.lookup_token_with_function_name(0, 11857, "", &sv),
Some(TokenMatch {
src_line: 2,
src_col: 0,
dst_line: 0,
dst_col: 11857,
src_id: 4,
name: None,
src: Some("input.js"),
function_name: Some("<global>".into())
})
);
}
5 changes: 5 additions & 0 deletions sourcemap/tests/fixtures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## react-native-hermes.map

This SourceMap is one generated by the `react-native` + `hermes` pipeline.
See the `rust-sourcemap` repo for instructions on how to generate it.
Additionally, it was processed by `sentry-cli`, which basically inlines all the `sourceContent`s.
1 change: 1 addition & 0 deletions sourcemap/tests/fixtures/react-native-hermes.map

Large diffs are not rendered by default.

0 comments on commit 5c8de65

Please sign in to comment.