1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::mapping::OriginalLocation;
use crate::sourcemap_error::{SourceMapError, SourceMapErrorType};
use rkyv::{Archive, Deserialize, Serialize};
#[derive(Archive, Serialize, Deserialize, Debug, Clone, Copy, Default)]
pub struct LineMapping {
pub generated_column: u32,
pub original: Option<OriginalLocation>,
}
#[derive(Archive, Serialize, Deserialize, Debug, Default, Clone)]
pub struct MappingLine {
pub mappings: Vec<LineMapping>,
pub last_column: u32,
pub is_sorted: bool,
}
impl MappingLine {
pub fn new() -> Self {
Self {
mappings: Vec::new(),
last_column: 0,
is_sorted: true,
}
}
pub fn add_mapping(&mut self, generated_column: u32, original: Option<OriginalLocation>) {
if self.is_sorted && self.last_column > generated_column {
self.is_sorted = false;
}
self.mappings.push(LineMapping {
generated_column,
original,
});
self.last_column = generated_column;
}
pub fn ensure_sorted(&mut self) {
if !self.is_sorted {
self.mappings
.sort_by(|a, b| a.generated_column.cmp(&b.generated_column));
self.is_sorted = true
}
}
pub fn find_closest_mapping(&mut self, generated_column: u32) -> Option<LineMapping> {
if self.mappings.is_empty() {
return None;
}
self.ensure_sorted();
let index = match self
.mappings
.binary_search_by(|m| m.generated_column.cmp(&generated_column))
{
Ok(index) => index,
Err(index) => {
if index == 0 || index == self.mappings.len() {
return Some(LineMapping {
generated_column: 0,
original: self.mappings[0].original,
});
}
index - 1
}
};
Some(self.mappings[index])
}
pub fn offset_columns(
&mut self,
generated_column: u32,
generated_column_offset: i64,
) -> Result<(), SourceMapError> {
let (start_column, overflowed) =
(generated_column as i64).overflowing_add(generated_column_offset);
if overflowed || start_column > (u32::MAX as i64) {
return Err(SourceMapError::new_with_reason(
SourceMapErrorType::UnexpectedNegativeNumber,
"column + column_offset cannot be negative",
));
}
self.ensure_sorted();
let mut index = match self
.mappings
.binary_search_by(|m| m.generated_column.cmp(&generated_column))
{
Ok(index) => index,
Err(index) => index,
};
if generated_column_offset < 0 {
let u_start_column = start_column as u32;
let start_index = match self
.mappings
.binary_search_by(|m| m.generated_column.cmp(&u_start_column))
{
Ok(index) => index,
Err(index) => index,
};
self.mappings.drain(start_index..index);
index = start_index;
}
let abs_offset = generated_column_offset.unsigned_abs() as u32;
for i in index..self.mappings.len() {
let mapping = &mut self.mappings[i];
mapping.generated_column = if generated_column_offset < 0 {
mapping.generated_column - abs_offset
} else {
mapping.generated_column + abs_offset
};
}
Ok(())
}
}