about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-04-25 23:15:10 +0200
committerGitHub <noreply@github.com>2021-04-25 23:15:10 +0200
commite7e22b47ad25f03c9a085f0b99346cab201847db (patch)
tree8706296b6a48bc25cd69de2f973f8c96cb31867a /compiler/rustc_errors/src
parente7ed7e835494219eeab314ace8beef40b695ce30 (diff)
parent8ebd811b32de96c0e9e4208703465016da3d8764 (diff)
downloadrust-e7e22b47ad25f03c9a085f0b99346cab201847db.tar.gz
rust-e7e22b47ad25f03c9a085f0b99346cab201847db.zip
Rollup merge of #84235 - klensy:styled-buffer, r=lcnr
refactor StyledBuffer

Refactors StyledBuffer `text` and `styles` fields content into StyledChar and touches some other stuff.
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/styled_buffer.rs90
1 files changed, 55 insertions, 35 deletions
diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs
index ec122e7be6e..e262d95bb70 100644
--- a/compiler/rustc_errors/src/styled_buffer.rs
+++ b/compiler/rustc_errors/src/styled_buffer.rs
@@ -1,39 +1,52 @@
 // Code for creating styled buffers
 
 use crate::snippet::{Style, StyledString};
-use std::iter;
 
 #[derive(Debug)]
 pub struct StyledBuffer {
-    text: Vec<Vec<char>>,
-    styles: Vec<Vec<Style>>,
+    lines: Vec<Vec<StyledChar>>,
+}
+
+#[derive(Debug, Clone)]
+struct StyledChar {
+    chr: char,
+    style: Style,
+}
+
+impl StyledChar {
+    const SPACE: Self = StyledChar::new(' ', Style::NoStyle);
+
+    const fn new(chr: char, style: Style) -> Self {
+        StyledChar { chr, style }
+    }
 }
 
 impl StyledBuffer {
     pub fn new() -> StyledBuffer {
-        StyledBuffer { text: vec![], styles: vec![] }
+        StyledBuffer { lines: vec![] }
     }
 
+    /// Returns content of `StyledBuffer` splitted by lines and line styles
     pub fn render(&self) -> Vec<Vec<StyledString>> {
         // 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.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));
 
         let mut output: Vec<Vec<StyledString>> = vec![];
         let mut styled_vec: Vec<StyledString> = vec![];
 
-        for (row, row_style) in iter::zip(&self.text, &self.styles) {
+        for styled_line in &self.lines {
             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_line {
+                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 });
@@ -49,29 +62,25 @@ impl StyledBuffer {
     }
 
     fn ensure_lines(&mut self, line: usize) {
-        while line >= self.text.len() {
-            self.text.push(vec![]);
-            self.styles.push(vec![]);
+        if line >= self.lines.len() {
+            self.lines.resize(line + 1, Vec::new());
         }
     }
 
+    /// Sets `chr` with `style` for given `line`, `col`.
+    /// 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.text[line].len() {
-            self.text[line][col] = chr;
-            self.styles[line][col] = style;
-        } else {
-            let mut i = self.text[line].len();
-            while i < col {
-                self.text[line].push(' ');
-                self.styles[line].push(Style::NoStyle);
-                i += 1;
-            }
-            self.text[line].push(chr);
-            self.styles[line].push(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` 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() {
@@ -80,32 +89,40 @@ 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();
 
-        // 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, ' ');
+        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::SPACE);
+            }
         }
 
         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() {
+        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:
+    /// 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,
@@ -119,10 +136,13 @@ impl StyledBuffer {
         }
     }
 
+    /// Set `style` for `line`, `col` if:
+    /// 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.styles.get_mut(line) {
-            if let Some(s) = line.get_mut(col) {
-                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
+        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;
                 }
             }