From 756be4a052cf43d5dec2b7ee99e611d2127d989e Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 03:14:05 +0300 Subject: [PATCH 1/7] refactored StyledBuffer parts into StyledChar --- compiler/rustc_errors/src/styled_buffer.rs | 47 ++++++++++++---------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index ec122e7be6e..89b8afdc7ab 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -1,39 +1,49 @@ // Code for creating styled buffers use crate::snippet::{Style, StyledString}; -use std::iter; #[derive(Debug)] pub struct StyledBuffer { - text: Vec>, - styles: Vec>, + text: Vec>, +} + +#[derive(Debug)] +struct StyledChar { + chr: char, + style: Style, +} + +impl StyledChar { + fn new(chr: char, style: Style) -> Self { + StyledChar { chr, style } + } } impl StyledBuffer { pub fn new() -> StyledBuffer { - StyledBuffer { text: vec![], styles: vec![] } + StyledBuffer { text: vec![] } } pub fn render(&self) -> Vec> { // Tabs are assumed to have been replaced by spaces in calling code. - debug_assert!(self.text.iter().all(|r| !r.contains(&'\t'))); + debug_assert!(self.text.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t'))); let mut output: Vec> = vec![]; let mut styled_vec: Vec = vec![]; - for (row, row_style) in iter::zip(&self.text, &self.styles) { + for styled_row in &self.text { let mut current_style = Style::NoStyle; let mut current_text = String::new(); - for (&c, &s) in iter::zip(row, row_style) { - if s != current_style { + for sc in styled_row { + if sc.style != current_style { if !current_text.is_empty() { styled_vec.push(StyledString { text: current_text, style: current_style }); } - current_style = s; + current_style = sc.style; current_text = String::new(); } - current_text.push(c); + current_text.push(sc.chr); } if !current_text.is_empty() { styled_vec.push(StyledString { text: current_text, style: current_style }); @@ -51,24 +61,20 @@ impl StyledBuffer { fn ensure_lines(&mut self, line: usize) { while line >= self.text.len() { self.text.push(vec![]); - self.styles.push(vec![]); } } pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { self.ensure_lines(line); if col < self.text[line].len() { - self.text[line][col] = chr; - self.styles[line][col] = style; + self.text[line][col] = StyledChar::new(chr, style); } else { let mut i = self.text[line].len(); while i < col { - self.text[line].push(' '); - self.styles[line].push(Style::NoStyle); + self.text[line].push(StyledChar::new(' ', Style::NoStyle)); i += 1; } - self.text[line].push(chr); - self.styles[line].push(style); + self.text[line].push(StyledChar::new(chr, style)); } } @@ -86,8 +92,7 @@ impl StyledBuffer { // Push the old content over to make room for new content for _ in 0..string_len { - self.styles[line].insert(0, Style::NoStyle); - self.text[line].insert(0, ' '); + self.text[line].insert(0, StyledChar::new(' ', Style::NoStyle)); } self.puts(line, 0, string, style); @@ -120,8 +125,8 @@ impl StyledBuffer { } pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { - if let Some(ref mut line) = self.styles.get_mut(line) { - if let Some(s) = line.get_mut(col) { + if let Some(ref mut line) = self.text.get_mut(line) { + if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { if *s == Style::NoStyle || *s == Style::Quotation || overwrite { *s = style; } From f5229916e350e5b70a6db4f3378f63993eaecb3d Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 03:20:07 +0300 Subject: [PATCH 2/7] added default for StyledChar --- compiler/rustc_errors/src/styled_buffer.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 89b8afdc7ab..8ce9c4bbfa1 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -19,6 +19,12 @@ impl StyledChar { } } +impl Default for StyledChar { + fn default() -> Self { + StyledChar::new(' ', Style::NoStyle) + } +} + impl StyledBuffer { pub fn new() -> StyledBuffer { StyledBuffer { text: vec![] } @@ -71,7 +77,7 @@ impl StyledBuffer { } else { let mut i = self.text[line].len(); while i < col { - self.text[line].push(StyledChar::new(' ', Style::NoStyle)); + self.text[line].push(StyledChar::default()); i += 1; } self.text[line].push(StyledChar::new(chr, style)); @@ -92,7 +98,7 @@ impl StyledBuffer { // Push the old content over to make room for new content for _ in 0..string_len { - self.text[line].insert(0, StyledChar::new(' ', Style::NoStyle)); + self.text[line].insert(0, StyledChar::default()); } self.puts(line, 0, string, style); From e97ddedac644fb192c25490f6f6eab711bc1bea8 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 04:14:59 +0300 Subject: [PATCH 3/7] added some docs for StyledBuffer --- compiler/rustc_errors/src/styled_buffer.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 8ce9c4bbfa1..a89d0aeaffd 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -30,6 +30,7 @@ impl StyledBuffer { StyledBuffer { text: vec![] } } + /// Returns content of `StyledBuffer` splitted by lines and line styles pub fn render(&self) -> Vec> { // Tabs are assumed to have been replaced by spaces in calling code. debug_assert!(self.text.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t'))); @@ -70,6 +71,9 @@ impl StyledBuffer { } } + /// Sets `chr` with `style` for given `line`, `col`. + /// If line not exist in `StyledBuffer`, adds lines up to given + /// and fills last line with spaces and `Style::NoStyle` style pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { self.ensure_lines(line); if col < self.text[line].len() { @@ -84,6 +88,9 @@ impl StyledBuffer { } } + /// Sets `string` with `style` for given `line`, starting from `col`. + /// If line not exist in `StyledBuffer`, adds lines up to given + /// and fills last line with spaces and `Style::NoStyle` style pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) { let mut n = col; for c in string.chars() { @@ -92,6 +99,8 @@ impl StyledBuffer { } } + /// For given `line` inserts `string` with `style` before old content of that line, + /// adding lines if needed pub fn prepend(&mut self, line: usize, string: &str, style: Style) { self.ensure_lines(line); let string_len = string.chars().count(); @@ -104,6 +113,8 @@ impl StyledBuffer { self.puts(line, 0, string, style); } + /// For given `line` inserts `string` with `style` after old content of that line, + /// adding lines if needed pub fn append(&mut self, line: usize, string: &str, style: Style) { if line >= self.text.len() { self.puts(line, 0, string, style); @@ -117,6 +128,9 @@ impl StyledBuffer { self.text.len() } + /// Set `style` for `line`, `col_start..col_end` range if: + /// 1. That line and column range exist in `StyledBuffer` + /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation` pub fn set_style_range( &mut self, line: usize, @@ -130,6 +144,9 @@ impl StyledBuffer { } } + /// Set `style` for `line`, `col` if: + /// 1. That line and column exist in `StyledBuffer` + /// 2. Existing style is `Style::NoStyle` or `Style::Quotation` or `overwrite` is `true` pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { if let Some(ref mut line) = self.text.get_mut(line) { if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { From 7e9d3c6f6cf3956dbf2a7870cebe89ebeb5d9ea5 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 05:11:45 +0300 Subject: [PATCH 4/7] StyledBuffer::prepend: if line is empty, insert content without inserting spaces --- compiler/rustc_errors/src/styled_buffer.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index a89d0aeaffd..9c19c96d64f 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -105,9 +105,11 @@ impl StyledBuffer { self.ensure_lines(line); let string_len = string.chars().count(); - // Push the old content over to make room for new content - for _ in 0..string_len { - self.text[line].insert(0, StyledChar::default()); + if !self.text[line].is_empty() { + // Push the old content over to make room for new content + for _ in 0..string_len { + self.text[line].insert(0, StyledChar::default()); + } } self.puts(line, 0, string, style); From 247d74f207633a5aeceb1e0ede878427465c5093 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 05:23:40 +0300 Subject: [PATCH 5/7] StyledBuffer::set_style: check overwrite first --- compiler/rustc_errors/src/styled_buffer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 9c19c96d64f..01d2a8de39d 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -148,11 +148,11 @@ impl StyledBuffer { /// Set `style` for `line`, `col` if: /// 1. That line and column exist in `StyledBuffer` - /// 2. Existing style is `Style::NoStyle` or `Style::Quotation` or `overwrite` is `true` + /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation` pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { if let Some(ref mut line) = self.text.get_mut(line) { if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { - if *s == Style::NoStyle || *s == Style::Quotation || overwrite { + if overwrite || *s == Style::NoStyle || *s == Style::Quotation { *s = style; } } From cb2d52282fb3c226c370a86c9111892384bbcb21 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 16 Apr 2021 05:38:32 +0300 Subject: [PATCH 6/7] rename StyledBuffer.text to lines --- compiler/rustc_errors/src/styled_buffer.rs | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index 01d2a8de39d..fb9575b290a 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -4,7 +4,7 @@ use crate::snippet::{Style, StyledString}; #[derive(Debug)] pub struct StyledBuffer { - text: Vec>, + lines: Vec>, } #[derive(Debug)] @@ -27,22 +27,22 @@ impl Default for StyledChar { impl StyledBuffer { pub fn new() -> StyledBuffer { - StyledBuffer { text: vec![] } + StyledBuffer { lines: vec![] } } /// Returns content of `StyledBuffer` splitted by lines and line styles pub fn render(&self) -> Vec> { // Tabs are assumed to have been replaced by spaces in calling code. - debug_assert!(self.text.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t'))); + debug_assert!(self.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t'))); let mut output: Vec> = vec![]; let mut styled_vec: Vec = vec![]; - for styled_row in &self.text { + for styled_line in &self.lines { let mut current_style = Style::NoStyle; let mut current_text = String::new(); - for sc in styled_row { + for sc in styled_line { if sc.style != current_style { if !current_text.is_empty() { styled_vec.push(StyledString { text: current_text, style: current_style }); @@ -66,8 +66,8 @@ impl StyledBuffer { } fn ensure_lines(&mut self, line: usize) { - while line >= self.text.len() { - self.text.push(vec![]); + while line >= self.lines.len() { + self.lines.push(vec![]); } } @@ -76,15 +76,15 @@ impl StyledBuffer { /// and fills last line with spaces and `Style::NoStyle` style pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { self.ensure_lines(line); - if col < self.text[line].len() { - self.text[line][col] = StyledChar::new(chr, style); + if col < self.lines[line].len() { + self.lines[line][col] = StyledChar::new(chr, style); } else { - let mut i = self.text[line].len(); + let mut i = self.lines[line].len(); while i < col { - self.text[line].push(StyledChar::default()); + self.lines[line].push(StyledChar::default()); i += 1; } - self.text[line].push(StyledChar::new(chr, style)); + self.lines[line].push(StyledChar::new(chr, style)); } } @@ -105,10 +105,10 @@ impl StyledBuffer { self.ensure_lines(line); let string_len = string.chars().count(); - if !self.text[line].is_empty() { + if !self.lines[line].is_empty() { // Push the old content over to make room for new content for _ in 0..string_len { - self.text[line].insert(0, StyledChar::default()); + self.lines[line].insert(0, StyledChar::default()); } } @@ -118,16 +118,16 @@ impl StyledBuffer { /// For given `line` inserts `string` with `style` after old content of that line, /// adding lines if needed pub fn append(&mut self, line: usize, string: &str, style: Style) { - if line >= self.text.len() { + if line >= self.lines.len() { self.puts(line, 0, string, style); } else { - let col = self.text[line].len(); + let col = self.lines[line].len(); self.puts(line, col, string, style); } } pub fn num_lines(&self) -> usize { - self.text.len() + self.lines.len() } /// Set `style` for `line`, `col_start..col_end` range if: @@ -150,7 +150,7 @@ impl StyledBuffer { /// 1. That line and column exist in `StyledBuffer` /// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation` pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) { - if let Some(ref mut line) = self.text.get_mut(line) { + if let Some(ref mut line) = self.lines.get_mut(line) { if let Some(StyledChar { style: s, .. }) = line.get_mut(col) { if overwrite || *s == Style::NoStyle || *s == Style::Quotation { *s = style; From 8ebd811b32de96c0e9e4208703465016da3d8764 Mon Sep 17 00:00:00 2001 From: klensy Date: Sun, 18 Apr 2021 02:15:15 +0300 Subject: [PATCH 7/7] review --- compiler/rustc_errors/src/styled_buffer.rs | 38 ++++++++-------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs index fb9575b290a..e262d95bb70 100644 --- a/compiler/rustc_errors/src/styled_buffer.rs +++ b/compiler/rustc_errors/src/styled_buffer.rs @@ -7,21 +7,17 @@ pub struct StyledBuffer { lines: Vec>, } -#[derive(Debug)] +#[derive(Debug, Clone)] struct StyledChar { chr: char, style: Style, } impl StyledChar { - fn new(chr: char, style: Style) -> Self { - StyledChar { chr, style } - } -} + const SPACE: Self = StyledChar::new(' ', Style::NoStyle); -impl Default for StyledChar { - fn default() -> Self { - StyledChar::new(' ', Style::NoStyle) + const fn new(chr: char, style: Style) -> Self { + StyledChar { chr, style } } } @@ -66,31 +62,25 @@ impl StyledBuffer { } fn ensure_lines(&mut self, line: usize) { - while line >= self.lines.len() { - self.lines.push(vec![]); + if line >= self.lines.len() { + self.lines.resize(line + 1, Vec::new()); } } /// Sets `chr` with `style` for given `line`, `col`. - /// If line not exist in `StyledBuffer`, adds lines up to given - /// and fills last line with spaces and `Style::NoStyle` style + /// If `line` does not exist in our buffer, adds empty lines up to the given + /// and fills the last line with unstyled whitespace. pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) { self.ensure_lines(line); - if col < self.lines[line].len() { - self.lines[line][col] = StyledChar::new(chr, style); - } else { - let mut i = self.lines[line].len(); - while i < col { - self.lines[line].push(StyledChar::default()); - i += 1; - } - self.lines[line].push(StyledChar::new(chr, style)); + if col >= self.lines[line].len() { + self.lines[line].resize(col + 1, StyledChar::SPACE); } + self.lines[line][col] = StyledChar::new(chr, style); } /// Sets `string` with `style` for given `line`, starting from `col`. - /// If line not exist in `StyledBuffer`, adds lines up to given - /// and fills last line with spaces and `Style::NoStyle` style + /// If `line` does not exist in our buffer, adds empty lines up to the given + /// and fills the last line with unstyled whitespace. pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) { let mut n = col; for c in string.chars() { @@ -108,7 +98,7 @@ impl StyledBuffer { if !self.lines[line].is_empty() { // Push the old content over to make room for new content for _ in 0..string_len { - self.lines[line].insert(0, StyledChar::default()); + self.lines[line].insert(0, StyledChar::SPACE); } }