Skip to content

Commit

Permalink
feat(sourcemaps): Improve sourcemaps resolve command output (#1880)
Browse files Browse the repository at this point in the history
This PR makes two improvements to the sourcemaps resolve command output:

  - The PR changes the output line and column values from zero-indexed to one-indexed values. By switching to one-indexed values, the output line and column numbers use the same scale as the input values and follow the standard convention for line and column numbers in source code files. This change fixes the off-by-one error reported in Source mapping is offset when using switch statements #1863.
  - The output text has been restructured and clarified to indicate that the sourcemap resolver locates the closest token to the line and column input that the user provides. With this change, it should be clear to users that the source and minified file line/column locations reported in the output are the locations of this nearest token that the sourcemap resolver locates. This change is specifically intended to help avoid confusion in cases where the nearest token may in a different location (perhaps even, on a different line) than the search location provided in the user's input.

Fixes GH-1863
  • Loading branch information
szokeasaurusrex authored Jan 5, 2024
1 parent 627559b commit c4f6b56
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 27 deletions.
81 changes: 62 additions & 19 deletions src/commands/sourcemaps/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cmp;
use std::fs;
use std::path::PathBuf;

Expand Down Expand Up @@ -73,28 +74,65 @@ pub fn print_source(token: &Token<'_>, view: &SourceView) {
}
}

fn dst_location(token: &Token) -> (u32, u32) {
(token.get_dst_line() + 1, token.get_dst_col() + 1)
}

fn src_location(token: &Token) -> (u32, u32) {
(token.get_src_line() + 1, token.get_src_col() + 1)
}

fn as_string_len<T: ToString>(to_string: T) -> usize {
to_string.to_string().len()
}

fn print_token(token: &Token<'_>) {
if let Some(name) = token.get_name() {
println!(" name: {name:?}");
} else {
println!(" name: not found");
}
if let Some(source) = token.get_source() {
println!(" source file: {source:?}");
} else {
println!(" source file: not found");
}
println!(" source line: {}", token.get_src_line());
println!(" source column: {}", token.get_src_col());
println!(" minified line: {}", token.get_dst_line());
println!(" minified column: {}", token.get_dst_col());
let token_display_name = match token.get_name() {
Some(name) => format!("token \"{name}\""),
None => String::from("token (unnamed)"),
};
let source_file = match token.get_source() {
Some(file) => format!("{file:>4}"),
None => String::from("(unknown path)"),
};

let (dst_line, dst_col) = dst_location(token);
let [dst_line_digits, dst_col_digits] = [dst_line, dst_col].map(as_string_len);

let (src_line, src_col) = src_location(token);
let [src_line_digits, src_col_digits] = [src_line, src_col].map(as_string_len);

let line_align = cmp::max(dst_line_digits, src_line_digits);
let col_align = cmp::max(dst_col_digits, src_col_digits);

let output_minified_line = format!(
"Found the nearest {token_display_name} at line {:>line_align$}, column {:>col_align$} in the minified file.",
dst_line,
dst_col,
);

let output_source_line = format!(
"- The same token is located at line {:>line_align$}, column {:>col_align$} in source file {}.",
src_line,
src_col,
source_file,
);

let output_minified_line_align = 2 + output_minified_line.len();
let output_source_line_align = output_minified_line.len() + source_file.len() - 3;

println!("{output_minified_line:>output_minified_line_align$}");
println!();
println!("{output_source_line:>output_source_line_align$}");
println!("\n");

if let Some(view) = token.get_source_view() {
println!(" source code:");
println!(" Source code:");
print_source(token, view);
} else if token.get_source_view().is_none() {
println!(" cannot find source");
println!(" Cannot find source");
} else {
println!(" cannot find source line");
println!(" Cannot find source line");
}
}

Expand All @@ -112,14 +150,19 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
};
println!("source map path: {sourcemap_path:?}");
println!("source map type: {ty}");
println!();

// perform a lookup
if let Some((line, column)) = lookup_pos(matches) {
println!("lookup line: {line}, column: {column}:");
println!(
"Searching for token nearest to line {}, column {} in the minified file:\n",
line + 1,
column + 1
);
if let Some(token) = sm.lookup_token(line, column) {
print_token(&token);
} else {
println!(" - no match");
println!(" - no token found!");
}
}

Expand Down
17 changes: 9 additions & 8 deletions tests/integration/_cases/sourcemaps/sourcemaps-resolve.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ $ sentry-cli sourcemaps resolve tests/integration/_fixtures/bundle.min.js.map -l
? success
source map path: "tests/integration/_fixtures/bundle.min.js.map"
source map type: regular
lookup line: 0, column: 39:
name: "bar"
source file: "webpack://webpack-plugin/./src/app.js"
source line: 1
source column: 2
minified line: 0
minified column: 39
source code:

Searching for token nearest to line 1, column 40 in the minified file:

Found the nearest token "bar" at line 1, column 40 in the minified file.

- The same token is located at line 2, column 3 in source file webpack://webpack-plugin/./src/app.js.


Source code:
function foo(msg) {
bar(msg);
}
Expand Down

0 comments on commit c4f6b56

Please sign in to comment.