Move pprust code to a 'state' submodule

This commit is contained in:
Aaron Hill 2020-09-26 12:41:53 -04:00
parent bc74dd711f
commit a20ae8901c
No known key found for this signature in database
GPG Key ID: B4087E510E98B164
2 changed files with 299 additions and 179 deletions

View File

@ -0,0 +1,99 @@
#[cfg(test)]
mod tests;
pub mod state;
pub use state::{print_crate, AnnNode, Comments, PpAnn, PrintState, State};
use rustc_ast as ast;
use rustc_ast::token::{Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
State::new().nonterminal_to_string(nt)
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
pub fn token_kind_to_string(tok: &TokenKind) -> String {
State::new().token_kind_to_string(tok)
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
pub fn token_to_string(token: &Token) -> String {
State::new().token_to_string(token)
}
pub fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
State::new().token_to_string_ext(token, convert_dollar_crate)
}
pub fn ty_to_string(ty: &ast::Ty) -> String {
State::new().ty_to_string(ty)
}
pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
State::new().bounds_to_string(bounds)
}
pub fn pat_to_string(pat: &ast::Pat) -> String {
State::new().pat_to_string(pat)
}
pub fn expr_to_string(e: &ast::Expr) -> String {
State::new().expr_to_string(e)
}
pub fn tt_to_string(tt: &TokenTree) -> String {
State::new().tt_to_string(tt)
}
pub fn tts_to_string(tokens: &TokenStream) -> String {
State::new().tts_to_string(tokens)
}
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
State::new().stmt_to_string(stmt)
}
pub fn item_to_string(i: &ast::Item) -> String {
State::new().item_to_string(i)
}
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
State::new().generic_params_to_string(generic_params)
}
pub fn path_to_string(p: &ast::Path) -> String {
State::new().path_to_string(p)
}
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
State::new().path_segment_to_string(p)
}
pub fn vis_to_string(v: &ast::Visibility) -> String {
State::new().vis_to_string(v)
}
pub fn block_to_string(blk: &ast::Block) -> String {
State::new().block_to_string(blk)
}
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
State::new().meta_list_item_to_string(li)
}
pub fn attr_item_to_string(ai: &ast::AttrItem) -> String {
State::new().attr_item_to_string(ai)
}
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
State::new().attribute_to_string(attr)
}
pub fn param_to_string(arg: &ast::Param) -> String {
State::new().param_to_string(arg)
}
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
State::new().to_string(f)
}

View File

@ -142,13 +142,6 @@ pub fn print_crate<'a>(
s.s.eof()
}
pub fn to_string(f: impl FnOnce(&mut State<'_>)) -> String {
let mut printer =
State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false };
f(&mut printer);
printer.s.eof()
}
// This makes printed token streams look slightly nicer,
// and also addresses some specific regressions described in #63896 and #73345.
fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool {
@ -231,173 +224,8 @@ pub fn literal_to_string(lit: token::Lit) -> String {
out
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
pub fn token_kind_to_string(tok: &TokenKind) -> String {
token_kind_to_string_ext(tok, None)
}
fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>) -> String {
match *tok {
token::Eq => "=".to_string(),
token::Lt => "<".to_string(),
token::Le => "<=".to_string(),
token::EqEq => "==".to_string(),
token::Ne => "!=".to_string(),
token::Ge => ">=".to_string(),
token::Gt => ">".to_string(),
token::Not => "!".to_string(),
token::Tilde => "~".to_string(),
token::OrOr => "||".to_string(),
token::AndAnd => "&&".to_string(),
token::BinOp(op) => binop_to_string(op).to_string(),
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
/* Structural symbols */
token::At => "@".to_string(),
token::Dot => ".".to_string(),
token::DotDot => "..".to_string(),
token::DotDotDot => "...".to_string(),
token::DotDotEq => "..=".to_string(),
token::Comma => ",".to_string(),
token::Semi => ";".to_string(),
token::Colon => ":".to_string(),
token::ModSep => "::".to_string(),
token::RArrow => "->".to_string(),
token::LArrow => "<-".to_string(),
token::FatArrow => "=>".to_string(),
token::OpenDelim(token::Paren) => "(".to_string(),
token::CloseDelim(token::Paren) => ")".to_string(),
token::OpenDelim(token::Bracket) => "[".to_string(),
token::CloseDelim(token::Bracket) => "]".to_string(),
token::OpenDelim(token::Brace) => "{".to_string(),
token::CloseDelim(token::Brace) => "}".to_string(),
token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".to_string(),
token::Pound => "#".to_string(),
token::Dollar => "$".to_string(),
token::Question => "?".to_string(),
token::SingleQuote => "'".to_string(),
/* Literals */
token::Literal(lit) => literal_to_string(lit),
/* Name components */
token::Ident(s, is_raw) => IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string(),
token::Lifetime(s) => s.to_string(),
/* Other */
token::DocComment(comment_kind, attr_style, data) => {
doc_comment_to_string(comment_kind, attr_style, data)
}
token::Eof => "<eof>".to_string(),
token::Interpolated(ref nt) => nonterminal_to_string(nt),
}
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
pub fn token_to_string(token: &Token) -> String {
token_to_string_ext(token, false)
}
fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
let convert_dollar_crate = convert_dollar_crate.then_some(token.span);
token_kind_to_string_ext(&token.kind, convert_dollar_crate)
}
pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => expr_to_string(e),
token::NtMeta(ref e) => attr_item_to_string(e),
token::NtTy(ref e) => ty_to_string(e),
token::NtPath(ref e) => path_to_string(e),
token::NtItem(ref e) => item_to_string(e),
token::NtBlock(ref e) => block_to_string(e),
token::NtStmt(ref e) => stmt_to_string(e),
token::NtPat(ref e) => pat_to_string(e),
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => expr_to_string(e),
token::NtTT(ref tree) => tt_to_string(tree),
token::NtVis(ref e) => vis_to_string(e),
}
}
pub fn ty_to_string(ty: &ast::Ty) -> String {
to_string(|s| s.print_type(ty))
}
pub fn bounds_to_string(bounds: &[ast::GenericBound]) -> String {
to_string(|s| s.print_type_bounds("", bounds))
}
pub fn pat_to_string(pat: &ast::Pat) -> String {
to_string(|s| s.print_pat(pat))
}
pub fn expr_to_string(e: &ast::Expr) -> String {
to_string(|s| s.print_expr(e))
}
pub fn tt_to_string(tt: &TokenTree) -> String {
to_string(|s| s.print_tt(tt, false))
}
pub fn tts_to_string(tokens: &TokenStream) -> String {
to_string(|s| s.print_tts(tokens, false))
}
pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
to_string(|s| s.print_stmt(stmt))
}
pub fn item_to_string(i: &ast::Item) -> String {
to_string(|s| s.print_item(i))
}
pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String {
to_string(|s| s.print_generic_params(generic_params))
}
pub fn path_to_string(p: &ast::Path) -> String {
to_string(|s| s.print_path(p, false, 0))
}
pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
to_string(|s| s.print_path_segment(p, false))
}
pub fn vis_to_string(v: &ast::Visibility) -> String {
to_string(|s| s.print_visibility(v))
}
fn block_to_string(blk: &ast::Block) -> String {
to_string(|s| {
// Containing cbox, will be closed by `print_block` at `}`.
s.cbox(INDENT_UNIT);
// Head-ibox, will be closed by `print_block` after `{`.
s.ibox(0);
s.print_block(blk)
})
}
pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
to_string(|s| s.print_meta_list_item(li))
}
fn attr_item_to_string(ai: &ast::AttrItem) -> String {
to_string(|s| s.print_attr_item(ai, ai.path.span))
}
pub fn attribute_to_string(attr: &ast::Attribute) -> String {
to_string(|s| s.print_attribute(attr))
}
pub fn param_to_string(arg: &ast::Param) -> String {
to_string(|s| s.print_param(arg, false))
}
fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
format!("{}{}", to_string(|s| s.print_visibility(vis)), s)
format!("{}{}", State::new().to_string(|s| s.print_visibility(vis)), s)
}
impl std::ops::Deref for State<'_> {
@ -679,7 +507,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
match tt {
TokenTree::Token(token) => {
self.word(token_to_string_ext(&token, convert_dollar_crate));
let token_str = self.token_to_string_ext(&token, convert_dollar_crate);
self.word(token_str);
if let token::DocComment(..) = token.kind {
self.hardbreak()
}
@ -745,14 +574,20 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
self.space();
}
}
_ => self.word(token_kind_to_string(&token::OpenDelim(delim))),
_ => {
let token_str = self.token_kind_to_string(&token::OpenDelim(delim));
self.word(token_str)
}
}
self.ibox(0);
self.print_tts(tts, convert_dollar_crate);
self.end();
match delim {
DelimToken::Brace => self.bclose(span),
_ => self.word(token_kind_to_string(&token::CloseDelim(delim))),
_ => {
let token_str = self.token_kind_to_string(&token::CloseDelim(delim));
self.word(token_str)
}
}
}
@ -818,6 +653,183 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}
}
}
fn nonterminal_to_string(&self, nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => self.expr_to_string(e),
token::NtMeta(ref e) => self.attr_item_to_string(e),
token::NtTy(ref e) => self.ty_to_string(e),
token::NtPath(ref e) => self.path_to_string(e),
token::NtItem(ref e) => self.item_to_string(e),
token::NtBlock(ref e) => self.block_to_string(e),
token::NtStmt(ref e) => self.stmt_to_string(e),
token::NtPat(ref e) => self.pat_to_string(e),
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => self.expr_to_string(e),
token::NtTT(ref tree) => self.tt_to_string(tree),
token::NtVis(ref e) => self.vis_to_string(e),
}
}
/// Print the token kind precisely, without converting `$crate` into its respective crate name.
fn token_kind_to_string(&self, tok: &TokenKind) -> String {
self.token_kind_to_string_ext(tok, None)
}
fn token_kind_to_string_ext(
&self,
tok: &TokenKind,
convert_dollar_crate: Option<Span>,
) -> String {
match *tok {
token::Eq => "=".to_string(),
token::Lt => "<".to_string(),
token::Le => "<=".to_string(),
token::EqEq => "==".to_string(),
token::Ne => "!=".to_string(),
token::Ge => ">=".to_string(),
token::Gt => ">".to_string(),
token::Not => "!".to_string(),
token::Tilde => "~".to_string(),
token::OrOr => "||".to_string(),
token::AndAnd => "&&".to_string(),
token::BinOp(op) => binop_to_string(op).to_string(),
token::BinOpEq(op) => format!("{}=", binop_to_string(op)),
/* Structural symbols */
token::At => "@".to_string(),
token::Dot => ".".to_string(),
token::DotDot => "..".to_string(),
token::DotDotDot => "...".to_string(),
token::DotDotEq => "..=".to_string(),
token::Comma => ",".to_string(),
token::Semi => ";".to_string(),
token::Colon => ":".to_string(),
token::ModSep => "::".to_string(),
token::RArrow => "->".to_string(),
token::LArrow => "<-".to_string(),
token::FatArrow => "=>".to_string(),
token::OpenDelim(token::Paren) => "(".to_string(),
token::CloseDelim(token::Paren) => ")".to_string(),
token::OpenDelim(token::Bracket) => "[".to_string(),
token::CloseDelim(token::Bracket) => "]".to_string(),
token::OpenDelim(token::Brace) => "{".to_string(),
token::CloseDelim(token::Brace) => "}".to_string(),
token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".to_string(),
token::Pound => "#".to_string(),
token::Dollar => "$".to_string(),
token::Question => "?".to_string(),
token::SingleQuote => "'".to_string(),
/* Literals */
token::Literal(lit) => literal_to_string(lit),
/* Name components */
token::Ident(s, is_raw) => {
IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string()
}
token::Lifetime(s) => s.to_string(),
/* Other */
token::DocComment(comment_kind, attr_style, data) => {
doc_comment_to_string(comment_kind, attr_style, data)
}
token::Eof => "<eof>".to_string(),
token::Interpolated(ref nt) => self.nonterminal_to_string(nt),
}
}
/// Print the token precisely, without converting `$crate` into its respective crate name.
fn token_to_string(&self, token: &Token) -> String {
self.token_to_string_ext(token, false)
}
fn token_to_string_ext(&self, token: &Token, convert_dollar_crate: bool) -> String {
let convert_dollar_crate = convert_dollar_crate.then_some(token.span);
self.token_kind_to_string_ext(&token.kind, convert_dollar_crate)
}
fn ty_to_string(&self, ty: &ast::Ty) -> String {
self.to_string(|s| s.print_type(ty))
}
fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String {
self.to_string(|s| s.print_type_bounds("", bounds))
}
fn pat_to_string(&self, pat: &ast::Pat) -> String {
self.to_string(|s| s.print_pat(pat))
}
fn expr_to_string(&self, e: &ast::Expr) -> String {
self.to_string(|s| s.print_expr(e))
}
fn tt_to_string(&self, tt: &TokenTree) -> String {
self.to_string(|s| s.print_tt(tt, false))
}
fn tts_to_string(&self, tokens: &TokenStream) -> String {
self.to_string(|s| s.print_tts(tokens, false))
}
fn stmt_to_string(&self, stmt: &ast::Stmt) -> String {
self.to_string(|s| s.print_stmt(stmt))
}
fn item_to_string(&self, i: &ast::Item) -> String {
self.to_string(|s| s.print_item(i))
}
fn generic_params_to_string(&self, generic_params: &[ast::GenericParam]) -> String {
self.to_string(|s| s.print_generic_params(generic_params))
}
fn path_to_string(&self, p: &ast::Path) -> String {
self.to_string(|s| s.print_path(p, false, 0))
}
fn path_segment_to_string(&self, p: &ast::PathSegment) -> String {
self.to_string(|s| s.print_path_segment(p, false))
}
fn vis_to_string(&self, v: &ast::Visibility) -> String {
self.to_string(|s| s.print_visibility(v))
}
fn block_to_string(&self, blk: &ast::Block) -> String {
self.to_string(|s| {
// Containing cbox, will be closed by `print_block` at `}`.
s.cbox(INDENT_UNIT);
// Head-ibox, will be closed by `print_block` after `{`.
s.ibox(0);
s.print_block(blk)
})
}
fn meta_list_item_to_string(&self, li: &ast::NestedMetaItem) -> String {
self.to_string(|s| s.print_meta_list_item(li))
}
fn attr_item_to_string(&self, ai: &ast::AttrItem) -> String {
self.to_string(|s| s.print_attr_item(ai, ai.path.span))
}
fn attribute_to_string(&self, attr: &ast::Attribute) -> String {
self.to_string(|s| s.print_attribute(attr))
}
fn param_to_string(&self, arg: &ast::Param) -> String {
self.to_string(|s| s.print_param(arg, false))
}
fn to_string(&self, f: impl FnOnce(&mut State<'_>)) -> String {
let mut printer = State::new();
f(&mut printer);
printer.s.eof()
}
}
impl<'a> PrintState<'a> for State<'a> {
@ -856,6 +868,15 @@ impl<'a> PrintState<'a> for State<'a> {
}
impl<'a> State<'a> {
pub fn new() -> State<'a> {
State {
s: pp::mk_printer(),
comments: None,
ann: &NoAnn,
is_expanded: false,
}
}
// Synthesizes a comment that was not textually present in the original source
// file.
pub fn synth_comment(&mut self, text: String) {
@ -1139,7 +1160,7 @@ impl<'a> State<'a> {
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
self.head(to_string(|s| {
self.head(self.to_string(|s| {
s.print_visibility(&item.vis);
s.print_unsafety(_mod.unsafety);
s.word("mod");
@ -1158,7 +1179,7 @@ impl<'a> State<'a> {
}
}
ast::ItemKind::ForeignMod(ref nmod) => {
self.head(to_string(|s| {
self.head(self.to_string(|s| {
s.print_unsafety(nmod.unsafety);
s.word("extern");
}));
@ -1366,7 +1387,7 @@ impl<'a> State<'a> {
ast::CrateSugar::JustCrate => self.word_nbsp("crate"),
},
ast::VisibilityKind::Restricted { ref path, .. } => {
let path = to_string(|s| s.print_path(path, false, 0));
let path = self.to_string(|s| s.print_path(path, false, 0));
if path == "self" || path == "super" {
self.word_nbsp(format!("pub({})", path))
} else {