diff options
Diffstat (limited to 'compiler/rustc_ast_pretty/src/pp')
-rw-r--r-- | compiler/rustc_ast_pretty/src/pp/convenience.rs | 94 | ||||
-rw-r--r-- | compiler/rustc_ast_pretty/src/pp/ring.rs | 77 |
2 files changed, 171 insertions, 0 deletions
diff --git a/compiler/rustc_ast_pretty/src/pp/convenience.rs b/compiler/rustc_ast_pretty/src/pp/convenience.rs new file mode 100644 index 000000000..93310dd45 --- /dev/null +++ b/compiler/rustc_ast_pretty/src/pp/convenience.rs @@ -0,0 +1,94 @@ +use crate::pp::{BeginToken, BreakToken, Breaks, IndentStyle, Printer, Token, SIZE_INFINITY}; +use std::borrow::Cow; + +impl Printer { + /// "raw box" + pub fn rbox(&mut self, indent: isize, breaks: Breaks) { + self.scan_begin(BeginToken { indent: IndentStyle::Block { offset: indent }, breaks }) + } + + /// Inconsistent breaking box + pub fn ibox(&mut self, indent: isize) { + self.rbox(indent, Breaks::Inconsistent) + } + + /// Consistent breaking box + pub fn cbox(&mut self, indent: isize) { + self.rbox(indent, Breaks::Consistent) + } + + pub fn visual_align(&mut self) { + self.scan_begin(BeginToken { indent: IndentStyle::Visual, breaks: Breaks::Consistent }); + } + + pub fn break_offset(&mut self, n: usize, off: isize) { + self.scan_break(BreakToken { + offset: off, + blank_space: n as isize, + ..BreakToken::default() + }); + } + + pub fn end(&mut self) { + self.scan_end() + } + + pub fn eof(mut self) -> String { + self.scan_eof(); + self.out + } + + pub fn word<S: Into<Cow<'static, str>>>(&mut self, wrd: S) { + let string = wrd.into(); + self.scan_string(string) + } + + fn spaces(&mut self, n: usize) { + self.break_offset(n, 0) + } + + pub fn zerobreak(&mut self) { + self.spaces(0) + } + + pub fn space(&mut self) { + self.spaces(1) + } + + pub fn hardbreak(&mut self) { + self.spaces(SIZE_INFINITY as usize) + } + + pub fn is_beginning_of_line(&self) -> bool { + match self.last_token() { + Some(last_token) => last_token.is_hardbreak_tok(), + None => true, + } + } + + pub fn hardbreak_tok_offset(off: isize) -> Token { + Token::Break(BreakToken { + offset: off, + blank_space: SIZE_INFINITY, + ..BreakToken::default() + }) + } + + pub fn trailing_comma(&mut self) { + self.scan_break(BreakToken { pre_break: Some(','), ..BreakToken::default() }); + } + + pub fn trailing_comma_or_space(&mut self) { + self.scan_break(BreakToken { + blank_space: 1, + pre_break: Some(','), + ..BreakToken::default() + }); + } +} + +impl Token { + pub fn is_hardbreak_tok(&self) -> bool { + *self == Printer::hardbreak_tok_offset(0) + } +} diff --git a/compiler/rustc_ast_pretty/src/pp/ring.rs b/compiler/rustc_ast_pretty/src/pp/ring.rs new file mode 100644 index 000000000..8187394fe --- /dev/null +++ b/compiler/rustc_ast_pretty/src/pp/ring.rs @@ -0,0 +1,77 @@ +use std::collections::VecDeque; +use std::ops::{Index, IndexMut}; + +/// A view onto a finite range of an infinitely long sequence of T. +/// +/// The Ts are indexed 0..infinity. A RingBuffer begins as a view of elements +/// 0..0 (i.e. nothing). The user of the RingBuffer advances its left and right +/// position independently, although only in the positive direction, and only +/// with left <= right at all times. +/// +/// Holding a RingBuffer whose view is elements left..right gives the ability to +/// use Index and IndexMut to access elements i in the infinitely long queue for +/// which left <= i < right. +pub struct RingBuffer<T> { + data: VecDeque<T>, + // Abstract index of data[0] in the infinitely sized queue. + offset: usize, +} + +impl<T> RingBuffer<T> { + pub fn new() -> Self { + RingBuffer { data: VecDeque::new(), offset: 0 } + } + + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } + + pub fn push(&mut self, value: T) -> usize { + let index = self.offset + self.data.len(); + self.data.push_back(value); + index + } + + pub fn clear(&mut self) { + self.data.clear(); + } + + pub fn index_of_first(&self) -> usize { + self.offset + } + + pub fn first(&self) -> Option<&T> { + self.data.front() + } + + pub fn first_mut(&mut self) -> Option<&mut T> { + self.data.front_mut() + } + + pub fn pop_first(&mut self) -> Option<T> { + let first = self.data.pop_front()?; + self.offset += 1; + Some(first) + } + + pub fn last(&self) -> Option<&T> { + self.data.back() + } + + pub fn last_mut(&mut self) -> Option<&mut T> { + self.data.back_mut() + } +} + +impl<T> Index<usize> for RingBuffer<T> { + type Output = T; + fn index(&self, index: usize) -> &Self::Output { + &self.data[index.checked_sub(self.offset).unwrap()] + } +} + +impl<T> IndexMut<usize> for RingBuffer<T> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.data[index.checked_sub(self.offset).unwrap()] + } +} |