Skip to content

Commit 0f453a5

Browse files
Refactor to keep up with changes to proc_macro
Instead of a `kind` field containting a `TokenNode` variant, a TokenTree is now an enum with variants of different types (Literal, Op, Term, etc). Note that a TokenTree could be a sequence of TokenTrees if it is a Group variant. Other notes: I'm unsure about the set_span call in Builder::emit_if, but I did not want to throw away the passed in Span. Parsing relies on destructuring references to the values associated with TokenTree enum variants It doesn't seem as easy to compose/chain TokenStreams as it is to collect a Vec<TokenTree> into a TokenStream. There is probably some iterator API I could use instead. See `match_arms` and build.rs Refs #121
1 parent 3d22f90 commit 0f453a5

File tree

3 files changed

+139
-127
lines changed

3 files changed

+139
-127
lines changed

maud_macros/src/build.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use proc_macro::{Delimiter, Literal, Span, TokenNode, TokenStream, TokenTree};
1+
use proc_macro::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
22
use proc_macro::quote;
3-
43
use maud_htmlescape::Escaper;
54

65
pub struct Builder {
@@ -24,7 +23,7 @@ impl Builder {
2423
if !self.tail.is_empty() {
2524
let expr = {
2625
let output_ident = self.output_ident.clone();
27-
let string = TokenNode::Literal(Literal::string(&self.tail));
26+
let string = TokenTree::Literal(Literal::string(&self.tail));
2827
quote!($output_ident.push_str($string);)
2928
};
3029
self.stmts.push(expr);
@@ -35,7 +34,15 @@ impl Builder {
3534
/// Reifies the `Builder` into a raw list of statements.
3635
pub fn build(mut self) -> TokenStream {
3736
let Builder { stmts, .. } = { self.flush(); self };
38-
stmts.into_iter().collect()
37+
38+
// use a Group here?
39+
let mut tts: Vec<TokenTree> = Vec::new();
40+
for s in stmts.into_iter() {
41+
let i = s.into_iter();
42+
tts.extend(i);
43+
}
44+
45+
tts.into_iter().collect()
3946
}
4047

4148
/// Pushes a statement, flushing the tail buffer in the process.
@@ -111,14 +118,20 @@ impl Builder {
111118
) {
112119
// If the condition contains an opening brace `{`,
113120
// wrap it in parentheses to avoid parse errors
114-
if cond.clone().into_iter().any(|token| match token.kind {
115-
TokenNode::Group(Delimiter::Brace, _) => true,
121+
if cond.clone().into_iter().any(|token| match token {
122+
TokenTree::Group(grp) => {
123+
if grp.delimiter() == Delimiter::Brace {
124+
true
125+
} else {
126+
false
127+
}
128+
},
116129
_ => false,
117130
}) {
118-
cond = TokenStream::from(TokenTree {
119-
kind: TokenNode::Group(Delimiter::Parenthesis, cond),
120-
span: cond_span,
121-
});
131+
let mut g = Group::new(Delimiter::Parenthesis, cond);
132+
// NOTE: Do we need to do this?
133+
g.set_span(cond_span);
134+
cond = TokenStream::from(TokenTree::Group(g));
122135
}
123136
self.push(quote!(if $cond { $body }));
124137
}

maud_macros/src/lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(proc_macro)]
2+
#![feature(pattern_parentheses)]
23

34
#![doc(html_root_url = "https://docs.rs/maud_macros/0.17.2")]
45

@@ -9,7 +10,7 @@ extern crate proc_macro;
910
mod parse;
1011
mod build;
1112

12-
use proc_macro::{Literal, Span, Term, TokenNode, TokenStream, TokenTree};
13+
use proc_macro::{Span, Term, TokenStream, TokenTree};
1314
use proc_macro::quote;
1415

1516
type ParseResult<T> = Result<T, String>;
@@ -27,21 +28,21 @@ pub fn html_debug(input: TokenStream) -> TokenStream {
2728
}
2829

2930
fn expand(input: TokenStream) -> TokenStream {
30-
let output_ident = TokenTree {
31-
kind: TokenNode::Term(Term::intern("__maud_output")),
32-
span: Span::def_site(),
33-
};
31+
32+
let output_ident = TokenTree::Term(Term::new("__maud_output", Span::def_site()));
3433
// Heuristic: the size of the resulting markup tends to correlate with the
3534
// code size of the template itself
36-
let size_hint = input.to_string().len();
37-
let size_hint = TokenNode::Literal(Literal::u64(size_hint as u64));
35+
//
36+
// NOTE: can't get this to compile inside quote!
37+
//let size_hint = Literal::u64_unsuffixed(size_hint as u64);
3838
let stmts = match parse::parse(input, output_ident.clone()) {
3939
Ok(stmts) => stmts,
4040
Err(e) => panic!(e),
4141
};
4242
quote!({
4343
extern crate maud;
44-
let mut $output_ident = String::with_capacity($size_hint as usize);
44+
//let mut $output_ident = String::with_capacity($size_hint as usize);
45+
let mut $output_ident = String::new();
4546
$stmts
4647
maud::PreEscaped($output_ident)
4748
})

0 commit comments

Comments
 (0)