Replace pretty-printer Box<dyn Write> with &mut String

This commit is contained in:
Mark Rousskov 2019-06-24 12:42:21 -04:00
parent 209bde16c5
commit 1aff8af213
4 changed files with 47 additions and 60 deletions

View File

@ -17,7 +17,7 @@ use crate::hir::{GenericParam, GenericParamKind, GenericArg};
use std::borrow::Cow;
use std::cell::Cell;
use std::io::{self, Write, Read};
use std::io::{self, Read};
use std::vec;
pub enum AnnNode<'a> {
@ -101,10 +101,6 @@ impl<'a> PrintState<'a> for State<'a> {
#[allow(non_upper_case_globals)]
pub const indent_unit: usize = 4;
#[allow(non_upper_case_globals)]
pub const default_columns: usize = 78;
/// Requires you to pass an input filename and reader so that
/// it can scan the input text for comments to copy forward.
pub fn print_crate<'a>(cm: &'a SourceMap,
@ -112,7 +108,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
krate: &hir::Crate,
filename: FileName,
input: &mut dyn Read,
out: Box<dyn Write + 'a>,
out: &'a mut String,
ann: &'a dyn PpAnn)
-> io::Result<()> {
let mut s = State::new_from_input(cm, sess, filename, input, out, ann);
@ -130,7 +126,7 @@ impl<'a> State<'a> {
sess: &ParseSess,
filename: FileName,
input: &mut dyn Read,
out: Box<dyn Write + 'a>,
out: &'a mut String,
ann: &'a dyn PpAnn)
-> State<'a> {
let comments = comments::gather_comments(sess, filename, input);
@ -138,12 +134,12 @@ impl<'a> State<'a> {
}
pub fn new(cm: &'a SourceMap,
out: Box<dyn Write + 'a>,
out: &'a mut String,
ann: &'a dyn PpAnn,
comments: Option<Vec<comments::Comment>>)
-> State<'a> {
State {
s: pp::mk_printer(out, default_columns),
s: pp::mk_printer(out),
cm: Some(cm),
comments,
cur_cmnt: 0,
@ -156,10 +152,10 @@ impl<'a> State<'a> {
pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
where F: FnOnce(&mut State<'_>) -> io::Result<()>
{
let mut wr = Vec::new();
let mut wr = String::new();
{
let mut printer = State {
s: pp::mk_printer(Box::new(&mut wr), default_columns),
s: pp::mk_printer(&mut wr),
cm: None,
comments: None,
cur_cmnt: 0,
@ -169,7 +165,7 @@ pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
f(&mut printer).unwrap();
printer.s.eof().unwrap();
}
String::from_utf8(wr).unwrap()
wr
}
pub fn visibility_qualified<S: Into<Cow<'static, str>>>(vis: &hir::Visibility, w: S) -> String {

View File

@ -728,11 +728,11 @@ pub fn print_after_parsing(sess: &Session,
let (src, src_name) = get_source(input, sess);
let mut rdr = &*src;
let mut out = Vec::new();
let mut out = String::new();
if let PpmSource(s) = ppm {
// Silently ignores an identified node.
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support(sess, None, move |annotation| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
@ -741,7 +741,7 @@ pub fn print_after_parsing(sess: &Session,
krate,
src_name,
&mut rdr,
box out,
out,
annotation.pp_ann(),
false)
}).unwrap()
@ -749,7 +749,7 @@ pub fn print_after_parsing(sess: &Session,
unreachable!();
};
write_output(out, ofile);
write_output(out.into_bytes(), ofile);
}
pub fn print_after_hir_lowering<'tcx>(
@ -773,12 +773,12 @@ pub fn print_after_hir_lowering<'tcx>(
let (src, src_name) = get_source(input, tcx.sess);
let mut rdr = &src[..];
let mut out = Vec::new();
let mut out = String::new();
match (ppm, opt_uii) {
(PpmSource(s), _) => {
// Silently ignores an identified node.
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support(tcx.sess, Some(tcx), move |annotation| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
@ -787,14 +787,14 @@ pub fn print_after_hir_lowering<'tcx>(
krate,
src_name,
&mut rdr,
box out,
out,
annotation.pp_ann(),
true)
})
}
(PpmHir(s), None) => {
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support_hir(tcx, move |annotation, krate| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
@ -803,21 +803,21 @@ pub fn print_after_hir_lowering<'tcx>(
krate,
src_name,
&mut rdr,
box out,
out,
annotation.pp_ann())
})
}
(PpmHirTree(s), None) => {
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support_hir(tcx, move |_annotation, krate| {
debug!("pretty printing source code {:?}", s);
write!(out, "{:#?}", krate)
})
*out = format!("{:#?}", krate);
});
}
(PpmHir(s), Some(uii)) => {
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support_hir(tcx, move |annotation, _| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
@ -826,7 +826,7 @@ pub fn print_after_hir_lowering<'tcx>(
&sess.parse_sess,
src_name,
&mut rdr,
box out,
out,
annotation.pp_ann());
for node_id in uii.all_matching_node_ids(hir_map) {
let hir_id = tcx.hir().node_to_hir_id(node_id);
@ -843,13 +843,13 @@ pub fn print_after_hir_lowering<'tcx>(
}
(PpmHirTree(s), Some(uii)) => {
let out: &mut dyn Write = &mut out;
let out = &mut out;
s.call_with_pp_support_hir(tcx, move |_annotation, _krate| {
debug!("pretty printing source code {:?}", s);
for node_id in uii.all_matching_node_ids(tcx.hir()) {
let hir_id = tcx.hir().node_to_hir_id(node_id);
let node = tcx.hir().get(hir_id);
write!(out, "{:#?}", node)?;
out.push_str(&format!("{:#?}", node));
}
Ok(())
})
@ -859,7 +859,7 @@ pub fn print_after_hir_lowering<'tcx>(
}
.unwrap();
write_output(out, ofile);
write_output(out.into_bytes(), ofile);
}
// In an ideal world, this would be a public function called by the driver after

View File

@ -236,7 +236,8 @@ crate struct PrintStackElem {
const SIZE_INFINITY: isize = 0xffff;
pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'a> {
pub fn mk_printer(out: &mut String) -> Printer<'_> {
let linewidth = 78;
// Yes 55, it makes the ring buffers big enough to never fall behind.
let n: usize = 55 * linewidth;
debug!("mk_printer {}", linewidth);
@ -259,7 +260,7 @@ pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'
}
pub struct Printer<'a> {
out: Box<dyn io::Write+'a>,
out: &'a mut String,
buf_max_len: usize,
/// Width of lines we're constrained to
margin: isize,
@ -300,8 +301,6 @@ impl Default for BufEntry {
}
}
const SPACES: [u8; 128] = [b' '; 128];
impl<'a> Printer<'a> {
pub fn last_token(&mut self) -> Token {
self.buf[self.right].token.clone()
@ -497,10 +496,10 @@ impl<'a> Printer<'a> {
crate fn print_newline(&mut self, amount: isize) -> io::Result<()> {
debug!("NEWLINE {}", amount);
let ret = writeln!(self.out);
self.out.push('\n');
self.pending_indentation = 0;
self.indent(amount);
ret
Ok(())
}
crate fn indent(&mut self, amount: isize) {
@ -587,20 +586,14 @@ impl<'a> Printer<'a> {
//
// write!(self.out, "{: >n$}", "", n = self.pending_indentation as usize)?;
//
// But that is significantly slower than using `SPACES`. This code is
// sufficiently hot, and indents can get sufficiently large, that the
// difference is significant on some workloads.
let spaces_len = SPACES.len() as isize;
while self.pending_indentation >= spaces_len {
self.out.write_all(&SPACES)?;
self.pending_indentation -= spaces_len;
}
if self.pending_indentation > 0 {
self.out.write_all(&SPACES[0..self.pending_indentation as usize])?;
self.pending_indentation = 0;
}
// But that is significantly slower. This code is sufficiently hot, and indents can get
// sufficiently large, that the difference is significant on some workloads.
self.out.reserve(self.pending_indentation as usize);
self.out.extend(std::iter::repeat(' ').take(self.pending_indentation as usize));
self.pending_indentation = 0;
self.out.push_str(&s);
write!(self.out, "{}", s)
Ok(())
}
crate fn print(&mut self, token: Token, l: isize) -> io::Result<()> {

View File

@ -21,7 +21,7 @@ use syntax_pos::{self, BytePos};
use syntax_pos::{DUMMY_SP, FileName};
use std::borrow::Cow;
use std::io::{self, Write, Read};
use std::io::{self, Read};
use std::vec;
pub enum AnnNode<'a> {
@ -54,9 +54,9 @@ pub struct State<'a> {
is_expanded: bool
}
fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
fn rust_printer<'a>(writer: &'a mut String, ann: &'a dyn PpAnn) -> State<'a> {
State {
s: pp::mk_printer(writer, DEFAULT_COLUMNS),
s: pp::mk_printer(writer),
cm: None,
comments: None,
cur_cmnt: 0,
@ -68,8 +68,6 @@ fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a>
crate const INDENT_UNIT: usize = 4;
crate const DEFAULT_COLUMNS: usize = 78;
/// Requires you to pass an input filename and reader so that
/// it can scan the input text for comments to copy forward.
pub fn print_crate<'a>(cm: &'a SourceMap,
@ -77,7 +75,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
krate: &ast::Crate,
filename: FileName,
input: &mut dyn Read,
out: Box<dyn Write+'a>,
out: &mut String,
ann: &'a dyn PpAnn,
is_expanded: bool) -> io::Result<()> {
let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
@ -111,7 +109,7 @@ impl<'a> State<'a> {
sess: &ParseSess,
filename: FileName,
input: &mut dyn Read,
out: Box<dyn Write+'a>,
out: &'a mut String,
ann: &'a dyn PpAnn,
is_expanded: bool) -> State<'a> {
let comments = comments::gather_comments(sess, filename, input);
@ -119,12 +117,12 @@ impl<'a> State<'a> {
}
pub fn new(cm: &'a SourceMap,
out: Box<dyn Write+'a>,
out: &'a mut String,
ann: &'a dyn PpAnn,
comments: Option<Vec<comments::Comment>>,
is_expanded: bool) -> State<'a> {
State {
s: pp::mk_printer(out, DEFAULT_COLUMNS),
s: pp::mk_printer(out),
cm: Some(cm),
comments,
cur_cmnt: 0,
@ -138,14 +136,14 @@ impl<'a> State<'a> {
pub fn to_string<F>(f: F) -> String where
F: FnOnce(&mut State<'_>) -> io::Result<()>,
{
let mut wr = Vec::new();
let mut wr = String::new();
{
let ann = NoAnn;
let mut printer = rust_printer(Box::new(&mut wr), &ann);
let mut printer = rust_printer(&mut wr, &ann);
f(&mut printer).unwrap();
printer.s.eof().unwrap();
}
String::from_utf8(wr).unwrap()
wr
}
fn binop_to_string(op: BinOpToken) -> &'static str {