Skip to content

Commit 81b2389

Browse files
committed
Use usize as the TextSize
1 parent eefb363 commit 81b2389

File tree

7 files changed

+114
-30
lines changed

7 files changed

+114
-30
lines changed

src/chunk.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::{borrow::Cow, collections::VecDeque};
1+
use std::collections::VecDeque;
22

3-
use crate::{span::Span, ChunkIdx, CowStr};
3+
use crate::{span::Span, ChunkIdx, CowStr, TextSize};
44

55
#[derive(Debug, Default)]
66
pub struct Chunk<'str> {
@@ -21,15 +21,15 @@ impl<'s> Chunk<'s> {
2121
}
2222

2323
impl<'str> Chunk<'str> {
24-
pub fn start(&self) -> u32 {
24+
pub fn start(&self) -> TextSize {
2525
self.span.start()
2626
}
2727

28-
pub fn end(&self) -> u32 {
28+
pub fn end(&self) -> TextSize {
2929
self.span.end()
3030
}
3131

32-
pub fn contains(&self, text_index: u32) -> bool {
32+
pub fn contains(&self, text_index: TextSize) -> bool {
3333
self.start() < text_index && text_index < self.end()
3434
}
3535

@@ -49,7 +49,7 @@ impl<'str> Chunk<'str> {
4949
self.intro.push_front(content)
5050
}
5151

52-
pub fn split<'a>(&'a mut self, text_index: u32) -> Chunk<'str> {
52+
pub fn split<'a>(&'a mut self, text_index: TextSize) -> Chunk<'str> {
5353
let first_slice_span = Span(self.start(), text_index);
5454
let last_slice_span = Span(text_index, self.end());
5555
let mut new_chunk = Chunk::new(last_slice_span);

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ mod chunk;
33
mod span;
44
mod joiner;
55
mod magic_string;
6+
mod mappings;
7+
mod locator;
8+
69
use std::borrow::Cow;
710

811
type CowStr<'s> = Cow<'s, str>;
@@ -23,4 +26,4 @@ index_vec::define_index_type! {
2326
struct SourceIdx = u32;
2427
}
2528

26-
pub(crate) type TextSize = u32;
29+
pub(crate) type TextSize = usize;

src/locator.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
pub struct Locator {
2+
line_offsets: Box<[usize]>,
3+
}
4+
5+
impl Locator {
6+
pub fn new(source: &str) -> Self {
7+
let mut line_offsets = vec![];
8+
let mut line_start_pos = 0;
9+
for line in source.lines() {
10+
line_offsets.push(line_start_pos);
11+
line_start_pos += 1 + line.len();
12+
}
13+
Self {
14+
line_offsets: line_offsets.into_boxed_slice(),
15+
}
16+
}
17+
18+
pub fn locate(&self, index: usize) -> Location {
19+
let mut left_cursor = 0;
20+
let mut right_cursor = self.line_offsets.len();
21+
while left_cursor < right_cursor {
22+
let mid = (left_cursor + right_cursor) >> 1;
23+
if index < self.line_offsets[mid] {
24+
right_cursor = mid;
25+
} else {
26+
left_cursor = mid + 1;
27+
}
28+
}
29+
let line = left_cursor - 1;
30+
let column = index - self.line_offsets[line];
31+
Location { line, column }
32+
}
33+
}
34+
35+
pub struct Location {
36+
pub line: usize,
37+
pub column: usize,
38+
}

src/magic_string.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use std::collections::VecDeque;
22

33
use rustc_hash::FxHashMap;
44

5-
use crate::{chunk::Chunk, span::Span, ChunkIdx, ChunkVec, CowStr, TextSize};
5+
use crate::{
6+
chunk::Chunk, locator::Locator, mappings::Mappings, span::Span, ChunkIdx, ChunkVec, CowStr,
7+
TextSize,
8+
};
69

710
#[derive(Debug, Default)]
811
pub struct MagicStringOptions {
@@ -15,12 +18,11 @@ pub struct MagicString<'s> {
1518
outro: VecDeque<CowStr<'s>>,
1619

1720
source: CowStr<'s>,
18-
source_len: u32,
1921
chunks: ChunkVec<'s>,
2022
first_chunk_idx: ChunkIdx,
2123
last_chunk_idx: ChunkIdx,
22-
chunk_by_start: FxHashMap<u32, ChunkIdx>,
23-
chunk_by_end: FxHashMap<u32, ChunkIdx>,
24+
chunk_by_start: FxHashMap<TextSize, ChunkIdx>,
25+
chunk_by_end: FxHashMap<TextSize, ChunkIdx>,
2426
}
2527

2628
impl<'s> MagicString<'s> {
@@ -32,15 +34,13 @@ impl<'s> MagicString<'s> {
3234

3335
pub fn with_options(source: impl Into<CowStr<'s>>, options: MagicStringOptions) -> Self {
3436
let source = source.into();
35-
let source_len: u32 = source.len().try_into().expect("source is too big");
36-
let initial_chunk = Chunk::new(Span(0, source_len));
37+
let initial_chunk = Chunk::new(Span(0, source.len()));
3738
let mut chunks = ChunkVec::with_capacity(1);
3839
let initial_chunk_idx = chunks.push(initial_chunk);
3940
let mut magic_string = Self {
4041
intro: Default::default(),
4142
outro: Default::default(),
4243
source,
43-
source_len,
4444
first_chunk_idx: initial_chunk_idx,
4545
last_chunk_idx: initial_chunk_idx,
4646
chunks,
@@ -53,7 +53,7 @@ impl<'s> MagicString<'s> {
5353
magic_string.chunk_by_start.insert(0, initial_chunk_idx);
5454
magic_string
5555
.chunk_by_end
56-
.insert(source_len, initial_chunk_idx);
56+
.insert(magic_string.source.len(), initial_chunk_idx);
5757

5858
magic_string
5959
}
@@ -71,7 +71,11 @@ impl<'s> MagicString<'s> {
7171
/// s.append_left(2, "b");
7272
/// assert_eq!(s.to_string(), "01ab234")
7373
///```
74-
pub fn append_left(&mut self, text_index: u32, content: impl Into<CowStr<'s>>) -> &mut Self {
74+
pub fn append_left(
75+
&mut self,
76+
text_index: TextSize,
77+
content: impl Into<CowStr<'s>>,
78+
) -> &mut Self {
7579
match self.by_end_mut(text_index) {
7680
Some(chunk) => {
7781
chunk.append_outro(content.into());
@@ -91,7 +95,11 @@ impl<'s> MagicString<'s> {
9195
/// s.append_left(2, "b");
9296
/// assert_eq!(s.to_string(), "01abAB234")
9397
///```
94-
pub fn append_right(&mut self, text_index: u32, content: impl Into<CowStr<'s>>) -> &mut Self {
98+
pub fn append_right(
99+
&mut self,
100+
text_index: TextSize,
101+
content: impl Into<CowStr<'s>>,
102+
) -> &mut Self {
95103
match self.by_start_mut(text_index) {
96104
Some(chunk) => {
97105
chunk.append_intro(content.into());
@@ -143,12 +151,12 @@ impl<'s> MagicString<'s> {
143151
ret
144152
}
145153

146-
pub fn remove(&mut self, start: u32, end: u32) -> &mut Self {
154+
pub fn remove(&mut self, start: TextSize, end: TextSize) -> &mut Self {
147155
if start == end {
148156
return self;
149157
}
150-
151-
assert!(end <= self.source_len, "end is out of bounds");
158+
159+
assert!(end <= self.source.len(), "end is out of bounds");
152160
assert!(start < end, "end must be greater than start");
153161

154162
self.split_at(start);
@@ -171,6 +179,19 @@ impl<'s> MagicString<'s> {
171179
self
172180
}
173181

182+
pub fn generate_decoded_map(&self) {
183+
let mut mappings = Mappings::default();
184+
let locator = Locator::new(&self.source);
185+
186+
self.intro.iter().for_each(|frag| {
187+
mappings.advance(frag);
188+
});
189+
190+
self.iter_chunks().for_each(|chunk| {
191+
let loc = locator.locate(chunk.start());
192+
});
193+
}
194+
174195
// --- private
175196

176197
fn prepend_intro(&mut self, content: impl Into<CowStr<'s>>) {
@@ -218,7 +239,7 @@ impl<'s> MagicString<'s> {
218239
return;
219240
}
220241

221-
let mut target = if (self.source_len - text_index) > text_index {
242+
let mut target = if (self.source.len() - text_index) > text_index {
222243
self.first_chunk()
223244
} else {
224245
self.last_chunk()
@@ -255,7 +276,7 @@ impl<'s> MagicString<'s> {
255276
}
256277

257278
fn by_start_mut(&mut self, text_index: TextSize) -> Option<&mut Chunk<'s>> {
258-
if text_index == self.source_len {
279+
if text_index == self.source.len() {
259280
None
260281
} else {
261282
self.split_at(text_index);

src/mappings.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
3+
#[derive(Debug, Default)]
4+
pub struct Mappings {
5+
generated_code_line: usize,
6+
generated_code_column: usize,
7+
}
8+
9+
impl Mappings {
10+
pub fn advance(&mut self, content: &str) {
11+
if content.is_empty() {
12+
return;
13+
}
14+
let mut lines = content.lines();
15+
// SAFETY: The content at least has one line after checking of `content.is_empty()` .
16+
// `"\n".lines().collect::<Vec<_>>()` would create `[""]`.
17+
let last_line = unsafe { lines.next_back().unwrap_unchecked() };
18+
for _ in lines {
19+
self.generated_code_line += 1;
20+
self.generated_code_column = 0;
21+
}
22+
self.generated_code_column += last_line.len();
23+
}
24+
}

src/source_map.rs

Whitespace-only changes.

src/span.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1+
use crate::TextSize;
2+
13
#[derive(Debug, Default, Clone, Copy)]
2-
pub struct Span(pub u32, pub u32);
4+
pub struct Span(pub TextSize, pub TextSize);
35

46
impl Span {
5-
pub fn start(&self) -> u32 {
7+
pub fn start(&self) -> TextSize {
68
self.0
79
}
810

9-
pub fn end(&self) -> u32 {
11+
pub fn end(&self) -> TextSize {
1012
self.1
1113
}
1214

1315
pub fn text<'s>(&self, source: &'s str) -> &'s str {
14-
&source[self.start() as usize..self.end() as usize]
16+
&source[self.start()..self.end()]
1517
}
16-
17-
// pub fn size(&self) -> usize {
18-
// (self.1 - self.0) as usize
19-
// }
2018
}

0 commit comments

Comments
 (0)