fix(sourcemap): Handle multi-byte characters correctly (#5153)

This commit is contained in:
David Sherret 2022-07-08 23:47:52 -04:00 committed by GitHub
parent 2e79942051
commit bbbe0b6e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 33 deletions

View File

@ -1,5 +1,5 @@
{
"mappings": "AAUA,cAAe,CAAEA,CAAC,CATd,wDAAsF,CAStEC,CAAC,CALjB,yGAA6J,CAK1I,AAAC",
"mappings": "AAUA,cAAe,CAAEA,CAAC,CATd,yCAAsF,CAStEC,CAAC,CALjB,kFAA6J,CAK1I,AAAC",
"names": [
"a",
"b"

View File

@ -243,7 +243,7 @@ fn issue_4112() {
r#""use strict";
export { default as Selection } from "./selection";
export { default as RichTextarea } from "./richTextarea";
"#
.to_string(),
@ -268,7 +268,7 @@ fn issue_4112() {
r#""use strict";
import { React, window } from "easy";
window.assign({
React
});
@ -311,9 +311,13 @@ fn should_work_with_emit_source_map_columns() {
let fm = cm.new_source_file(
swc_common::FileName::Real("./app.js".into()),
r#"import { createElement } from "react";
createElement('div', null, {});"#
.to_string(),
createElement('div', null, {});
/* 패딩에 대 */ /* 한 더 많은 문자. */ "테스트" + "테스트";
function ƒ() {
}
"#
.to_string(),
);
let result = c.process_js_file(
fm.clone(),
@ -335,6 +339,8 @@ fn should_work_with_emit_source_map_columns() {
Ok(result) => {
assert!(result.map.is_some());
let map = result.map.unwrap();
// lookup createElement(...) function call
let source_map = sourcemap::SourceMap::from_slice(map.as_bytes())
.expect("failed to deserialize sourcemap");
let token = source_map
@ -344,6 +350,24 @@ fn should_work_with_emit_source_map_columns() {
assert_eq!(token.get_dst_col(), 14);
assert_eq!(token.get_src_line(), 2);
assert_eq!(token.get_src_col(), 16);
// lookup second string literal
let token = source_map
.lookup_token(2, 37)
.expect("failed to find token");
assert_eq!(token.get_dst_line(), 2);
assert_eq!(token.get_dst_col(), 37);
assert_eq!(token.get_src_line(), 3);
assert_eq!(token.get_src_col(), 39);
// lookup paren after multi-byte identifier
let token = source_map
.lookup_token(3, 10)
.expect("failed to find token");
assert_eq!(token.get_dst_line(), 3);
assert_eq!(token.get_dst_col(), 10);
assert_eq!(token.get_src_line(), 4);
assert_eq!(token.get_src_col(), 12);
}
Err(err) => {
panic!("Error: {:#?}", err);

View File

@ -1157,8 +1157,6 @@ impl SourceMap {
let mut cur_file: Option<Lrc<SourceFile>> = None;
let mut ch_start = 0;
let mut line_ch_start = 0;
let mut prev_dst_line = u32::MAX;
for (pos, lc) in mappings.iter() {
@ -1193,8 +1191,6 @@ impl SourceMap {
}
cur_file = Some(f.clone());
ch_start = 0;
line_ch_start = 0;
&f
}
};
@ -1228,9 +1224,8 @@ impl SourceMap {
pos,
linebpos,
);
let chpos = pos.to_u32() - self.calc_extra_bytes(f, &mut ch_start, pos);
let linechpos =
linebpos.to_u32() - self.calc_extra_bytes(f, &mut line_ch_start, linebpos);
let chpos = pos.to_u32() - self.calc_extra_bytes(f, &mut 0, pos);
let linechpos = linebpos.to_u32() - self.calc_extra_bytes(f, &mut 0, linebpos);
let mut col = max(chpos, linechpos) - min(chpos, linechpos);

View File

@ -1,4 +1,4 @@
use std::io::{self, Write};
use std::io::Write;
use rustc_hash::FxHashSet;
use swc_common::{sync::Lrc, BytePos, LineCol, SourceMap, Span};
@ -44,29 +44,26 @@ impl<'a, W: Write> JsWriter<'a, W> {
}
}
fn write_indent_string(&mut self) -> io::Result<usize> {
const INDENT: &[u8] = b" ";
fn write_indent_string(&mut self) -> Result {
const INDENT: &str = " ";
let mut cnt = 0;
for _ in 0..self.indent {
cnt += self.raw_write(INDENT)?;
self.raw_write(INDENT)?;
}
Ok(cnt)
Ok(())
}
fn raw_write(&mut self, data: &[u8]) -> io::Result<usize> {
let written = self.wr.write(data)?;
self.line_pos += written;
Ok(written)
fn raw_write(&mut self, data: &str) -> Result {
self.wr.write_all(data.as_bytes())?;
self.line_pos += data.chars().count();
Ok(())
}
fn write(&mut self, span: Option<Span>, data: &str) -> io::Result<usize> {
let mut cnt = 0;
fn write(&mut self, span: Option<Span>, data: &str) -> Result {
if !data.is_empty() {
if self.line_start {
cnt += self.write_indent_string()?;
self.write_indent_string()?;
self.line_start = false;
if let Some(pending) = self.pending_srcmap.take() {
@ -80,7 +77,7 @@ impl<'a, W: Write> JsWriter<'a, W> {
}
}
cnt += self.raw_write(data.as_bytes())?;
self.raw_write(data)?;
if let Some(span) = span {
if !span.is_dummy() {
@ -89,7 +86,7 @@ impl<'a, W: Write> JsWriter<'a, W> {
}
}
Ok(cnt)
Ok(())
}
fn srcmap(&mut self, byte_pos: BytePos) {
@ -156,7 +153,7 @@ impl<'a, W: Write> WriteJs for JsWriter<'a, W> {
fn write_line(&mut self) -> Result {
let pending = self.pending_srcmap.take();
if !self.line_start {
self.raw_write(self.new_line.as_bytes())?;
self.raw_write(self.new_line)?;
self.line_count += 1;
self.line_pos = 0;
self.line_start = true;
@ -180,7 +177,8 @@ impl<'a, W: Write> WriteJs for JsWriter<'a, W> {
let line_start_of_s = compute_line_starts(s);
if line_start_of_s.len() > 1 {
self.line_count = self.line_count + line_start_of_s.len() - 1;
self.line_pos = s.len() - line_start_of_s.last().cloned().unwrap_or(0);
let last_line_byte_index = line_start_of_s.last().cloned().unwrap_or(0);
self.line_pos = s[last_line_byte_index..].chars().count();
}
if !span.is_dummy() {
@ -197,7 +195,8 @@ impl<'a, W: Write> WriteJs for JsWriter<'a, W> {
let line_start_of_s = compute_line_starts(s);
if line_start_of_s.len() > 1 {
self.line_count = self.line_count + line_start_of_s.len() - 1;
self.line_pos = s.len() - line_start_of_s.last().cloned().unwrap_or(0);
let last_line_byte_index = line_start_of_s.last().cloned().unwrap_or(0);
self.line_pos = s[last_line_byte_index..].chars().count();
}
}
Ok(())
@ -214,7 +213,8 @@ impl<'a, W: Write> WriteJs for JsWriter<'a, W> {
let line_start_of_s = compute_line_starts(s);
if line_start_of_s.len() > 1 {
self.line_count = self.line_count + line_start_of_s.len() - 1;
self.line_pos = s.len() - line_start_of_s.last().cloned().unwrap_or(0);
let last_line_byte_index = line_start_of_s.last().cloned().unwrap_or(0);
self.line_pos = s[last_line_byte_index..].chars().count();
}
if !span.is_dummy() {