use rust;
use rust::Token as rtok;
use rust::TokenAndSpan;
pub struct TokenFlattener<'a>
{
rp: rust::Parser<'a>,
tokens: Vec<TokenAndSpan>
}
impl<'a> TokenFlattener<'a>
{
pub fn flatten(cx: &'a rust::ExtCtxt, tts: Vec<rust::TokenTree>)
-> Vec<TokenAndSpan>
{
let mut flattener = TokenFlattener::new(cx, tts);
flattener.flatten_tokens();
flattener.tokens
}
fn new(cx: &'a rust::ExtCtxt, tts: Vec<rust::TokenTree>)
-> TokenFlattener<'a>
{
TokenFlattener {
rp: rust::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts),
tokens: vec![]
}
}
fn flatten_tokens(&mut self) {
self.push_open_brace();
loop {
if self.rp.token == rtok::Eof {
self.push_close_brace();
self.push_current_tok();
break;
}
self.push_current_tok();
self.rp.bump();
}
}
fn push_open_brace(&mut self) {
self.push_tok(rtok::OpenDelim(rust::DelimToken::Brace));
}
fn push_close_brace(&mut self) {
self.push_tok(rtok::CloseDelim(rust::DelimToken::Brace));
}
fn push_current_tok(&mut self) {
let cur = self.token_and_span();
self.tokens.push(cur);
}
fn token_and_span(&mut self) -> TokenAndSpan {
TokenAndSpan {
tok: self.rp.token.clone(),
sp: self.rp.span
}
}
fn push_tok(&mut self, tok: rtok) {
self.tokens.push(TokenAndSpan {
tok: tok,
sp: self.rp.span
})
}
}