X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Ftt%2Fsrc%2Flib.rs;h=b2841370ec59d9b676622959ee58010964e90f91;hb=f1222e80850dca050e4f9a150514aeab9b27ac08;hp=20c3f5eabfb8dfe54e2e6e75ff3f51882239c737;hpb=550d7fbe3cbf2af4a47fca6c9bbefaf798cd7b7b;p=rust.git diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index 20c3f5eabfb..b2841370ec5 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs @@ -1,10 +1,7 @@ //! `tt` crate defines a `TokenTree` data structure: this is the interface (both //! input and output) of macros. It closely mirrors `proc_macro` crate's //! `TokenTree`. -use std::{ - fmt::{self, Debug}, - panic::RefUnwindSafe, -}; +use std::fmt; use stdx::impl_from; @@ -91,7 +88,7 @@ pub struct Ident { } fn print_debug_subtree(f: &mut fmt::Formatter<'_>, subtree: &Subtree, level: usize) -> fmt::Result { - let align = std::iter::repeat(" ").take(level).collect::(); + let align = " ".repeat(level); let aux = match subtree.delimiter.map(|it| (it.kind, it.id.0)) { None => "$".to_string(), @@ -116,7 +113,7 @@ fn print_debug_subtree(f: &mut fmt::Formatter<'_>, subtree: &Subtree, level: usi } fn print_debug_token(f: &mut fmt::Formatter<'_>, tkn: &TokenTree, level: usize) -> fmt::Result { - let align = std::iter::repeat(" ").take(level).collect::(); + let align = " ".repeat(level); match tkn { TokenTree::Leaf(leaf) => match leaf { @@ -139,7 +136,7 @@ fn print_debug_token(f: &mut fmt::Formatter<'_>, tkn: &TokenTree, level: usize) Ok(()) } -impl Debug for Subtree { +impl fmt::Debug for Subtree { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { print_debug_subtree(f, self, 0) } @@ -230,17 +227,65 @@ pub fn delimiter_kind(&self) -> Option { } } +impl Subtree { + /// A simple line string used for debugging + pub fn as_debug_string(&self) -> String { + let delim = match self.delimiter_kind() { + Some(DelimiterKind::Brace) => ("{", "}"), + Some(DelimiterKind::Bracket) => ("[", "]"), + Some(DelimiterKind::Parenthesis) => ("(", ")"), + None => (" ", " "), + }; + + let mut res = String::new(); + res.push_str(delim.0); + let mut last = None; + for child in &self.token_trees { + let s = match child { + TokenTree::Leaf(it) => { + let s = match it { + Leaf::Literal(it) => it.text.to_string(), + Leaf::Punct(it) => it.char.to_string(), + Leaf::Ident(it) => it.text.to_string(), + }; + match (it, last) { + (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { + " ".to_string() + &s + } + (Leaf::Punct(_), Some(&TokenTree::Leaf(Leaf::Punct(punct)))) => { + if punct.spacing == Spacing::Alone { + " ".to_string() + &s + } else { + s + } + } + _ => s, + } + } + TokenTree::Subtree(it) => it.as_debug_string(), + }; + res.push_str(&s); + last = Some(child); + } + + res.push_str(delim.1); + res + } +} + pub mod buffer; #[derive(Debug, PartialEq, Eq, Clone)] pub enum ExpansionError { - IOError(String), - JsonError(String), Unknown(String), ExpansionError(String), } -pub trait TokenExpander: Debug + Send + Sync + RefUnwindSafe { - fn expand(&self, subtree: &Subtree, attrs: Option<&Subtree>) - -> Result; +impl fmt::Display for ExpansionError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ExpansionError::Unknown(e) => e.fmt(f), + ExpansionError::ExpansionError(e) => write!(f, "proc macro returned error: {}", e), + } + } }