summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ast_pretty/src/pp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_pretty/src/pp')
-rw-r--r--compiler/rustc_ast_pretty/src/pp/convenience.rs94
-rw-r--r--compiler/rustc_ast_pretty/src/pp/ring.rs77
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()]
+ }
+}