Skip to content

Fix SourceMap #672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ name = "swc"
swc_atoms = { path ="./atoms" }
swc_common = { path ="./common" }
swc_ecmascript = { path ="./ecmascript" }
log = { version = "0.4", features = ["release_max_level_info"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
failure = "0.1"
Expand All @@ -26,11 +27,12 @@ hashbrown = "0.6"
regex = "1"
either = "1"
dashmap = "=3.4.0"
sourcemap = "4.1.1 "
sourcemap = "5"

[dev-dependencies]
testing = { path = "./testing" }
walkdir = "2"
rayon = "1"

[[example]]
name = "usage"
Expand Down
4 changes: 0 additions & 4 deletions common/src/fold/and_then.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ pub struct AndThen<A, B> {
pub second: B,
}

// fn type_name<T>() -> String {
// format!("{}", unsafe { std::intrinsics::type_name::<T>() })
// }

impl<T, A, B> Fold<T> for AndThen<A, B>
where
T: FoldWith<Self>,
Expand Down
1 change: 1 addition & 0 deletions common/src/pass.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "fold")]
use crate::{Fold, FoldWith};
use serde::export::PhantomData;
use std::borrow::Cow;
Expand Down
80 changes: 45 additions & 35 deletions common/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ use crate::{
use hashbrown::HashMap;
use log::debug;
use std::{
cmp, env, fs,
cmp,
cmp::{max, min},
env, fs,
hash::Hash,
io::{self, Read},
path::{Path, PathBuf},
sync::Arc,
sync::{
atomic::{AtomicUsize, Ordering::SeqCst},
Arc,
},
};

// _____________________________________________________________________________
Expand Down Expand Up @@ -101,6 +106,7 @@ pub(super) struct SourceMapFiles {

pub struct SourceMap {
pub(super) files: Lock<SourceMapFiles>,
start_pos: AtomicUsize,
file_loader: Box<dyn FileLoader + Sync + Send>,
// This is used to apply the file path remapping as specified via
// --remap-path-prefix to all SourceFiles allocated within this SourceMap.
Expand All @@ -120,25 +126,20 @@ impl SourceMap {
pub fn new(path_mapping: FilePathMapping) -> SourceMap {
SourceMap {
files: Default::default(),
start_pos: Default::default(),
file_loader: Box::new(RealFileLoader),
path_mapping,
doctest_offset: None,
}
}

pub fn new_doctest(path_mapping: FilePathMapping, file: FileName, line: isize) -> SourceMap {
SourceMap {
doctest_offset: Some((file, line)),
..SourceMap::new(path_mapping)
}
}

pub fn with_file_loader(
file_loader: Box<dyn FileLoader + Sync + Send>,
path_mapping: FilePathMapping,
) -> SourceMap {
SourceMap {
files: Default::default(),
start_pos: Default::default(),
file_loader,
path_mapping,
doctest_offset: None,
Expand All @@ -155,11 +156,7 @@ impl SourceMap {

pub fn load_file(&self, path: &Path) -> io::Result<Arc<SourceFile>> {
let src = self.file_loader.read_file(path)?;
let filename = if let Some((ref name, _)) = self.doctest_offset {
name.clone()
} else {
path.to_owned().into()
};
let filename = path.to_owned().into();
Ok(self.new_source_file(filename, src))
}

Expand All @@ -178,19 +175,19 @@ impl SourceMap {
.cloned()
}

fn next_start_pos(&self) -> usize {
fn next_start_pos(&self, len: usize) -> usize {
match self.files.borrow().source_files.last() {
None => 0,
None => self.start_pos.fetch_add(len + 1, SeqCst),
// Add one so there is some space between files. This lets us distinguish
// positions in the source_map, even in the presence of zero-length files.
Some(last) => last.end_pos.to_usize() + 1,
Some(last) => self.start_pos.fetch_add(len + 1, SeqCst),
}
}

/// Creates a new source_file.
/// This does not ensure that only one SourceFile exists per file name.
pub fn new_source_file(&self, filename: FileName, src: String) -> Arc<SourceFile> {
let start_pos = self.next_start_pos();
let start_pos = self.next_start_pos(src.len());

// The path is used to determine the directory for loading submodules and
// include files, so it must be before remapping.
Expand All @@ -214,12 +211,14 @@ impl SourceMap {
Pos::from_usize(start_pos),
));

let mut files = self.files.borrow_mut();
{
let mut files = self.files.borrow_mut();

files.source_files.push(source_file.clone());
files
.stable_id_to_source_file
.insert(StableSourceFileId::new(&source_file), source_file.clone());
files.source_files.push(source_file.clone());
files
.stable_id_to_source_file
.insert(StableSourceFileId::new(&source_file), source_file.clone());
}

source_file
}
Expand Down Expand Up @@ -253,8 +252,17 @@ impl SourceMap {
Ok(SourceFileAndLine { sf: f, line: a }) => {
let line = a + 1; // Line numbers start at 1
let linebpos = f.lines[a];
assert!(
pos >= linebpos,
"{}: bpos = {:?}; linebpos = {:?};",
f.name,
pos,
linebpos,
);

let linechpos = self.bytepos_to_file_charpos(linebpos);
let col = chpos - linechpos;

let col = max(chpos, linechpos) - min(chpos, linechpos);

let col_display = {
let start_width_idx = f
Expand All @@ -281,7 +289,7 @@ impl SourceMap {
chpos, linechpos
);
debug!("byte is on line: {}", line);
assert!(chpos >= linechpos);
// assert!(chpos >= linechpos);
Loc {
file: f,
line,
Expand Down Expand Up @@ -313,9 +321,7 @@ impl SourceMap {

// If the relevant source_file is empty, we don't return a line number.
pub fn lookup_line(&self, pos: BytePos) -> Result<SourceFileAndLine, Arc<SourceFile>> {
let idx = self.lookup_source_file_idx(pos);

let f = (*self.files.borrow().source_files)[idx].clone();
let f = self.lookup_source_file(pos);

match f.lookup_line(pos) {
Some(line) => Ok(SourceFileAndLine { sf: f, line }),
Expand Down Expand Up @@ -774,16 +780,14 @@ impl SourceMap {
/// For a global BytePos compute the local offset within the containing
/// SourceFile
pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos {
let idx = self.lookup_source_file_idx(bpos);
let sf = (*self.files.borrow().source_files)[idx].clone();
let sf = self.lookup_source_file(bpos);
let offset = bpos - sf.start_pos;
SourceFileAndBytePos { sf, pos: offset }
}

/// Converts an absolute BytePos to a CharPos relative to the source_file.
pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
let idx = self.lookup_source_file_idx(bpos);
let map = &(*self.files.borrow().source_files)[idx];
let map = self.lookup_source_file(bpos);

// The number of extra bytes due to multibyte chars in the SourceFile
let mut total_extra_bytes = 0;
Expand All @@ -802,12 +806,18 @@ impl SourceMap {
}
}

assert!(map.start_pos.to_u32() + total_extra_bytes <= bpos.to_u32());
assert!(
map.start_pos.to_u32() + total_extra_bytes <= bpos.to_u32(),
"map.start_pos = {:?}; total_extra_bytes = {}; bpos = {:?}",
map.start_pos,
total_extra_bytes,
bpos,
);
CharPos(bpos.to_usize() - map.start_pos.to_usize() - total_extra_bytes as usize)
}

// Return the index of the source_file (in self.files) which contains pos.
pub fn lookup_source_file_idx(&self, pos: BytePos) -> usize {
fn lookup_source_file(&self, pos: BytePos) -> Arc<SourceFile> {
let files = self.files.borrow();
let files = &files.source_files;
let count = files.len();
Expand All @@ -830,7 +840,7 @@ impl SourceMap {
pos.to_usize()
);

a
files[a].clone()
}

pub fn count_lines(&self) -> usize {
Expand Down
Loading