fix repro panic
This commit is contained in:
parent
118585d133
commit
5463fc44bc
1 changed files with 48 additions and 6 deletions
|
@ -315,11 +315,28 @@ impl TabSnapshot {
|
||||||
let expanded = output.column();
|
let expanded = output.column();
|
||||||
let (collapsed, expanded_char_column, to_next_stop) =
|
let (collapsed, expanded_char_column, to_next_stop) =
|
||||||
self.collapse_tabs(tab_cursor, expanded, bias);
|
self.collapse_tabs(tab_cursor, expanded, bias);
|
||||||
(
|
|
||||||
|
let result = (
|
||||||
FoldPoint::new(output.row(), collapsed),
|
FoldPoint::new(output.row(), collapsed),
|
||||||
expanded_char_column,
|
expanded_char_column,
|
||||||
to_next_stop,
|
to_next_stop,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
// let expected = self.test_to_fold_point(output, bias);
|
||||||
|
|
||||||
|
// if result != expected {
|
||||||
|
// let text = self.buffer_snapshot().text();
|
||||||
|
// let bias = if bias == Bias::Left { "left" } else { "right" };
|
||||||
|
// panic!(
|
||||||
|
// "text: {text}, output: {}, bias: {bias}, result: {:?},{},{}, expected: {expected:?}",
|
||||||
|
// output.row(),
|
||||||
|
// result.0,
|
||||||
|
// result.1,
|
||||||
|
// result.2
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint {
|
pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint {
|
||||||
|
@ -364,9 +381,10 @@ impl TabSnapshot {
|
||||||
fn collapse_tabs(&self, mut cursor: TabStopCursor, column: u32, bias: Bias) -> (u32, u32, u32) {
|
fn collapse_tabs(&self, mut cursor: TabStopCursor, column: u32, bias: Bias) -> (u32, u32, u32) {
|
||||||
let tab_size = self.tab_size.get();
|
let tab_size = self.tab_size.get();
|
||||||
let mut collapsed_column = column;
|
let mut collapsed_column = column;
|
||||||
let mut seek_target = column;
|
let mut seek_target = column.min(self.max_expansion_column);
|
||||||
let mut tab_count = 0;
|
let mut tab_count = 0;
|
||||||
let mut expanded_tab_len = 0;
|
let mut expanded_tab_len = 0;
|
||||||
|
|
||||||
while let Some(tab_stop) = cursor.seek(seek_target) {
|
while let Some(tab_stop) = cursor.seek(seek_target) {
|
||||||
// Calculate how much we want to expand this tab stop (into spaces)
|
// Calculate how much we want to expand this tab stop (into spaces)
|
||||||
let expanded_chars_old = tab_stop.char_offset - tab_count + expanded_tab_len;
|
let expanded_chars_old = tab_stop.char_offset - tab_count + expanded_tab_len;
|
||||||
|
@ -378,6 +396,7 @@ impl TabSnapshot {
|
||||||
|
|
||||||
// The count of bytes at this point in the iteration while considering tab_count and previous expansions
|
// The count of bytes at this point in the iteration while considering tab_count and previous expansions
|
||||||
let expanded_bytes = tab_stop.byte_offset - tab_count + expanded_tab_len;
|
let expanded_bytes = tab_stop.byte_offset - tab_count + expanded_tab_len;
|
||||||
|
dbg!(expanded_bytes, column);
|
||||||
|
|
||||||
// Did we expand past the search target?
|
// Did we expand past the search target?
|
||||||
if expanded_bytes > column {
|
if expanded_bytes > column {
|
||||||
|
@ -734,6 +753,25 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_to_fold_point_panic_reproduction(cx: &mut gpui::App) {
|
||||||
|
// This test reproduces a specific panic where to_fold_point returns incorrect results
|
||||||
|
let text = "use macro_rules_attribute::apply;\nuse serde_json::Value;\nuse smol::{\n io::AsyncReadExt,\n process::{Command, Stdio},\n};\nuse smol_macros::main;\nuse std::io;\n\nfn test_random() {\n // Generate a random value\n let random_value = std::time::SystemTime::now()\n .duration_since(std::time::UNIX_EPOCH)\n .unwrap()\n .as_secs()\n % 100;\n\n // Create some complex nested data structures\n let mut vector = Vec::new();\n for i in 0..random_value {\n vector.push(i);\n }\n ";
|
||||||
|
|
||||||
|
let buffer = MultiBuffer::build_simple(text, cx);
|
||||||
|
let buffer_snapshot = buffer.read(cx).snapshot(cx);
|
||||||
|
let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||||
|
let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
||||||
|
let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
|
||||||
|
|
||||||
|
// This should panic with the expected vs actual mismatch
|
||||||
|
let tab_point = TabPoint::new(6, 6);
|
||||||
|
let result = tab_snapshot.to_fold_point(tab_point, Bias::Right);
|
||||||
|
let expected = tab_snapshot.test_to_fold_point(tab_point, Bias::Right);
|
||||||
|
|
||||||
|
assert_eq!(result, expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
fn test_collapse_tabs_random(cx: &mut gpui::App, mut rng: StdRng) {
|
fn test_collapse_tabs_random(cx: &mut gpui::App, mut rng: StdRng) {
|
||||||
// Generate random input string with up to 200 characters including tabs
|
// Generate random input string with up to 200 characters including tabs
|
||||||
|
@ -750,7 +788,7 @@ mod tests {
|
||||||
let ch = loop {
|
let ch = loop {
|
||||||
let ascii_code = rng.gen_range(32..=126); // printable ASCII range
|
let ascii_code = rng.gen_range(32..=126); // printable ASCII range
|
||||||
let ch = ascii_code as u8 as char;
|
let ch = ascii_code as u8 as char;
|
||||||
if ch != '\t' && ch != '\n' && ch != '\r' {
|
if ch != '\t' {
|
||||||
break ch;
|
break ch;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -762,7 +800,8 @@ mod tests {
|
||||||
let buffer_snapshot = buffer.read(cx).snapshot(cx);
|
let buffer_snapshot = buffer.read(cx).snapshot(cx);
|
||||||
let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||||
let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
||||||
let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
|
let (_, mut tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
|
||||||
|
tab_snapshot.max_expansion_column = rng.gen_range(0..323);
|
||||||
|
|
||||||
for (ix, _) in input.char_indices() {
|
for (ix, _) in input.char_indices() {
|
||||||
let range = TabPoint::new(0, ix as u32)..tab_snapshot.max_point();
|
let range = TabPoint::new(0, ix as u32)..tab_snapshot.max_point();
|
||||||
|
@ -1000,7 +1039,9 @@ mod tests {
|
||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
let mut cursor = TabStopCursor::new(chunks);
|
let mut cursor = TabStopCursor::new(chunks);
|
||||||
|
assert!(cursor.seek(0).is_none());
|
||||||
let mut tab_stops = Vec::new();
|
let mut tab_stops = Vec::new();
|
||||||
|
|
||||||
while let Some(tab_stop) = cursor.seek(u32::MAX) {
|
while let Some(tab_stop) = cursor.seek(u32::MAX) {
|
||||||
tab_stops.push(tab_stop);
|
tab_stops.push(tab_stop);
|
||||||
}
|
}
|
||||||
|
@ -1243,13 +1284,14 @@ impl<'a> TabStopCursor<'a> {
|
||||||
while let Some(mut chunk) = self.chunks.next() {
|
while let Some(mut chunk) = self.chunks.next() {
|
||||||
if chunk.tabs == 0 {
|
if chunk.tabs == 0 {
|
||||||
let chunk_distance = chunk.text.len() as u32;
|
let chunk_distance = chunk.text.len() as u32;
|
||||||
if chunk_distance + distance_traversed > distance {
|
if chunk_distance + distance_traversed >= distance {
|
||||||
let overshoot = chunk_distance + distance_traversed - distance;
|
let overshoot = chunk_distance + distance_traversed - distance;
|
||||||
self.bytes_offset += distance_traversed.abs_diff(distance);
|
self.bytes_offset += distance_traversed.abs_diff(distance);
|
||||||
self.end_of_chunk = Some(overshoot);
|
self.end_of_chunk = Some(overshoot);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.bytes_offset += chunk.text.len() as u32;
|
self.bytes_offset += chunk.text.len() as u32;
|
||||||
|
distance_traversed += chunk.text.len() as u32;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue