1
Fork 0

Remove lifetime parameter from syntax::tokenstream::Cursor.

This commit is contained in:
Jeffrey Seyfried 2017-02-18 06:18:29 +00:00
parent c0b7112ba2
commit 0143774cb5
4 changed files with 40 additions and 34 deletions

View file

@ -51,7 +51,7 @@ macro_rules! quote_tree {
fn delimit(delim: token::DelimToken, stream: TokenStream) -> TokenStream { fn delimit(delim: token::DelimToken, stream: TokenStream) -> TokenStream {
TokenTree::Delimited(DUMMY_SP, Rc::new(Delimited { TokenTree::Delimited(DUMMY_SP, Rc::new(Delimited {
delim: delim, delim: delim,
tts: stream.trees().cloned().collect(), tts: stream.into_trees().collect(),
})).into() })).into()
} }
@ -75,21 +75,21 @@ impl Quote for TokenStream {
return quote!(::syntax::tokenstream::TokenStream::empty()); return quote!(::syntax::tokenstream::TokenStream::empty());
} }
struct Quote<'a>(tokenstream::Cursor<'a>); struct Quote(tokenstream::Cursor);
impl<'a> Iterator for Quote<'a> { impl Iterator for Quote {
type Item = TokenStream; type Item = TokenStream;
fn next(&mut self) -> Option<TokenStream> { fn next(&mut self) -> Option<TokenStream> {
let is_unquote = match self.0.peek() { let is_unquote = match self.0.peek() {
Some(&TokenTree::Token(_, Token::Ident(ident))) if ident.name == "unquote" => { Some(TokenTree::Token(_, Token::Ident(ident))) if ident.name == "unquote" => {
self.0.next(); self.0.next();
true true
} }
_ => false, _ => false,
}; };
self.0.next().cloned().map(|tree| { self.0.next().map(|tree| {
let quoted_tree = if is_unquote { tree.into() } else { tree.quote() }; let quoted_tree = if is_unquote { tree.into() } else { tree.quote() };
quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),) quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),)
}) })
@ -104,7 +104,7 @@ impl Quote for TokenStream {
impl Quote for Vec<TokenTree> { impl Quote for Vec<TokenTree> {
fn quote(&self) -> TokenStream { fn quote(&self) -> TokenStream {
let stream = self.iter().cloned().collect::<TokenStream>(); let stream = self.iter().cloned().collect::<TokenStream>();
quote!((quote stream).trees().cloned().collect::<::std::vec::Vec<_> >()) quote!((quote stream).into_trees().collect::<::std::vec::Vec<_> >())
} }
} }

View file

@ -647,7 +647,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span) fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span)
-> Expansion { -> Expansion {
let mut parser = self.cx.new_parser_from_tts(&toks.trees().cloned().collect::<Vec<_>>()); let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
let expansion = match parser.parse_expansion(kind, false) { let expansion = match parser.parse_expansion(kind, false) {
Ok(expansion) => expansion, Ok(expansion) => expansion,
Err(mut err) => { Err(mut err) => {

View file

@ -192,7 +192,7 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenT
} }
pub fn new_parser_from_ts<'a>(sess: &'a ParseSess, ts: tokenstream::TokenStream) -> Parser<'a> { pub fn new_parser_from_ts<'a>(sess: &'a ParseSess, ts: tokenstream::TokenStream) -> Parser<'a> {
tts_to_parser(sess, ts.trees().cloned().collect()) tts_to_parser(sess, ts.into_trees().collect())
} }

View file

@ -35,7 +35,7 @@ use serialize::{Decoder, Decodable, Encoder, Encodable};
use symbol::Symbol; use symbol::Symbol;
use util::RcSlice; use util::RcSlice;
use std::{fmt, iter}; use std::{fmt, iter, mem};
use std::rc::Rc; use std::rc::Rc;
/// A delimited sequence of token trees /// A delimited sequence of token trees
@ -338,14 +338,18 @@ impl TokenStream {
TokenStream { kind: TokenStreamKind::Stream(RcSlice::new(vec)) } TokenStream { kind: TokenStreamKind::Stream(RcSlice::new(vec)) }
} }
pub fn trees<'a>(&'a self) -> Cursor { pub fn trees(&self) -> Cursor {
self.clone().into_trees()
}
pub fn into_trees(self) -> Cursor {
Cursor::new(self) Cursor::new(self)
} }
/// Compares two TokenStreams, checking equality without regarding span information. /// Compares two TokenStreams, checking equality without regarding span information.
pub fn eq_unspanned(&self, other: &TokenStream) -> bool { pub fn eq_unspanned(&self, other: &TokenStream) -> bool {
for (t1, t2) in self.trees().zip(other.trees()) { for (t1, t2) in self.trees().zip(other.trees()) {
if !t1.eq_unspanned(t2) { if !t1.eq_unspanned(&t2) {
return false; return false;
} }
} }
@ -353,58 +357,60 @@ impl TokenStream {
} }
} }
pub struct Cursor<'a> { pub struct Cursor {
current_frame: CursorFrame<'a>, current_frame: CursorFrame,
stack: Vec<CursorFrame<'a>>, stack: Vec<CursorFrame>,
} }
impl<'a> Iterator for Cursor<'a> { impl Iterator for Cursor {
type Item = &'a TokenTree; type Item = TokenTree;
fn next(&mut self) -> Option<&'a TokenTree> { fn next(&mut self) -> Option<TokenTree> {
let tree = self.peek(); let tree = self.peek();
self.current_frame = self.stack.pop().unwrap_or(CursorFrame::Empty); self.current_frame = self.stack.pop().unwrap_or(CursorFrame::Empty);
tree tree
} }
} }
enum CursorFrame<'a> { enum CursorFrame {
Empty, Empty,
Tree(&'a TokenTree), Tree(TokenTree),
Stream(&'a RcSlice<TokenStream>, usize), Stream(RcSlice<TokenStream>, usize),
} }
impl<'a> CursorFrame<'a> { impl CursorFrame {
fn new(stream: &'a TokenStream) -> Self { fn new(stream: TokenStream) -> Self {
match stream.kind { match stream.kind {
TokenStreamKind::Empty => CursorFrame::Empty, TokenStreamKind::Empty => CursorFrame::Empty,
TokenStreamKind::Tree(ref tree) => CursorFrame::Tree(tree), TokenStreamKind::Tree(tree) => CursorFrame::Tree(tree),
TokenStreamKind::Stream(ref stream) => CursorFrame::Stream(stream, 0), TokenStreamKind::Stream(stream) => CursorFrame::Stream(stream, 0),
} }
} }
} }
impl<'a> Cursor<'a> { impl Cursor {
fn new(stream: &'a TokenStream) -> Self { fn new(stream: TokenStream) -> Self {
Cursor { Cursor {
current_frame: CursorFrame::new(stream), current_frame: CursorFrame::new(stream),
stack: Vec::new(), stack: Vec::new(),
} }
} }
pub fn peek(&mut self) -> Option<&'a TokenTree> { pub fn peek(&mut self) -> Option<TokenTree> {
while let CursorFrame::Stream(stream, index) = self.current_frame { while let CursorFrame::Stream(stream, index) =
mem::replace(&mut self.current_frame, CursorFrame::Empty) {
self.current_frame = if index == stream.len() { self.current_frame = if index == stream.len() {
self.stack.pop().unwrap_or(CursorFrame::Empty) self.stack.pop().unwrap_or(CursorFrame::Empty)
} else { } else {
let frame = CursorFrame::new(stream[index].clone());
self.stack.push(CursorFrame::Stream(stream, index + 1)); self.stack.push(CursorFrame::Stream(stream, index + 1));
CursorFrame::new(&stream[index]) frame
}; };
} }
match self.current_frame { match self.current_frame {
CursorFrame::Empty => None, CursorFrame::Empty => None,
CursorFrame::Tree(tree) => Some(tree), CursorFrame::Tree(ref tree) => Some(tree.clone()),
CursorFrame::Stream(..) => unreachable!(), CursorFrame::Stream(..) => unreachable!(),
} }
} }
@ -412,13 +418,13 @@ impl<'a> Cursor<'a> {
impl fmt::Display for TokenStream { impl fmt::Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&pprust::tts_to_string(&self.trees().cloned().collect::<Vec<_>>())) f.write_str(&pprust::tts_to_string(&self.trees().collect::<Vec<_>>()))
} }
} }
impl Encodable for TokenStream { impl Encodable for TokenStream {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> { fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.trees().cloned().collect::<Vec<_>>().encode(encoder) self.trees().collect::<Vec<_>>().encode(encoder)
} }
} }
@ -464,14 +470,14 @@ mod tests {
fn test_from_to_bijection() { fn test_from_to_bijection() {
let test_start = string_to_tts("foo::bar(baz)".to_string()); let test_start = string_to_tts("foo::bar(baz)".to_string());
let ts = test_start.iter().cloned().collect::<TokenStream>(); let ts = test_start.iter().cloned().collect::<TokenStream>();
let test_end: Vec<TokenTree> = ts.trees().cloned().collect(); let test_end: Vec<TokenTree> = ts.trees().collect();
assert_eq!(test_start, test_end) assert_eq!(test_start, test_end)
} }
#[test] #[test]
fn test_to_from_bijection() { fn test_to_from_bijection() {
let test_start = string_to_ts("foo::bar(baz)"); let test_start = string_to_ts("foo::bar(baz)");
let test_end = test_start.trees().cloned().collect(); let test_end = test_start.trees().collect();
assert_eq!(test_start, test_end) assert_eq!(test_start, test_end)
} }