Skip to content

Commit

Permalink
Remove lifetime parameter from syntax::tokenstream::Cursor.
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed Mar 3, 2017
1 parent c0b7112 commit 0143774
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 34 deletions.
12 changes: 6 additions & 6 deletions src/libproc_macro_plugin/qquote.rs
Expand Up @@ -51,7 +51,7 @@ macro_rules! quote_tree {
fn delimit(delim: token::DelimToken, stream: TokenStream) -> TokenStream {
TokenTree::Delimited(DUMMY_SP, Rc::new(Delimited {
delim: delim,
tts: stream.trees().cloned().collect(),
tts: stream.into_trees().collect(),
})).into()
}

Expand All @@ -75,21 +75,21 @@ impl Quote for TokenStream {
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;

fn next(&mut self) -> Option<TokenStream> {
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();
true
}
_ => false,
};

self.0.next().cloned().map(|tree| {
self.0.next().map(|tree| {
let quoted_tree = if is_unquote { tree.into() } else { tree.quote() };
quote!(::syntax::tokenstream::TokenStream::from((unquote quoted_tree)),)
})
Expand All @@ -104,7 +104,7 @@ impl Quote for TokenStream {
impl Quote for Vec<TokenTree> {
fn quote(&self) -> 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<_> >())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/expand.rs
Expand Up @@ -647,7 +647,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {

fn parse_expansion(&mut self, toks: TokenStream, kind: ExpansionKind, name: Name, span: Span)
-> 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) {
Ok(expansion) => expansion,
Err(mut err) => {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/mod.rs
Expand Up @@ -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> {
tts_to_parser(sess, ts.trees().cloned().collect())
tts_to_parser(sess, ts.into_trees().collect())
}


Expand Down
58 changes: 32 additions & 26 deletions src/libsyntax/tokenstream.rs
Expand Up @@ -35,7 +35,7 @@ use serialize::{Decoder, Decodable, Encoder, Encodable};
use symbol::Symbol;
use util::RcSlice;

use std::{fmt, iter};
use std::{fmt, iter, mem};
use std::rc::Rc;

/// A delimited sequence of token trees
Expand Down Expand Up @@ -338,87 +338,93 @@ impl TokenStream {
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)
}

/// Compares two TokenStreams, checking equality without regarding span information.
pub fn eq_unspanned(&self, other: &TokenStream) -> bool {
for (t1, t2) in self.trees().zip(other.trees()) {
if !t1.eq_unspanned(t2) {
if !t1.eq_unspanned(&t2) {
return false;
}
}
true
}
}

pub struct Cursor<'a> {
current_frame: CursorFrame<'a>,
stack: Vec<CursorFrame<'a>>,
pub struct Cursor {
current_frame: CursorFrame,
stack: Vec<CursorFrame>,
}

impl<'a> Iterator for Cursor<'a> {
type Item = &'a TokenTree;
impl Iterator for Cursor {
type Item = TokenTree;

fn next(&mut self) -> Option<&'a TokenTree> {
fn next(&mut self) -> Option<TokenTree> {
let tree = self.peek();
self.current_frame = self.stack.pop().unwrap_or(CursorFrame::Empty);
tree
}
}

enum CursorFrame<'a> {
enum CursorFrame {
Empty,
Tree(&'a TokenTree),
Stream(&'a RcSlice<TokenStream>, usize),
Tree(TokenTree),
Stream(RcSlice<TokenStream>, usize),
}

impl<'a> CursorFrame<'a> {
fn new(stream: &'a TokenStream) -> Self {
impl CursorFrame {
fn new(stream: TokenStream) -> Self {
match stream.kind {
TokenStreamKind::Empty => CursorFrame::Empty,
TokenStreamKind::Tree(ref tree) => CursorFrame::Tree(tree),
TokenStreamKind::Stream(ref stream) => CursorFrame::Stream(stream, 0),
TokenStreamKind::Tree(tree) => CursorFrame::Tree(tree),
TokenStreamKind::Stream(stream) => CursorFrame::Stream(stream, 0),
}
}
}

impl<'a> Cursor<'a> {
fn new(stream: &'a TokenStream) -> Self {
impl Cursor {
fn new(stream: TokenStream) -> Self {
Cursor {
current_frame: CursorFrame::new(stream),
stack: Vec::new(),
}
}

pub fn peek(&mut self) -> Option<&'a TokenTree> {
while let CursorFrame::Stream(stream, index) = self.current_frame {
pub fn peek(&mut self) -> Option<TokenTree> {
while let CursorFrame::Stream(stream, index) =
mem::replace(&mut self.current_frame, CursorFrame::Empty) {
self.current_frame = if index == stream.len() {
self.stack.pop().unwrap_or(CursorFrame::Empty)
} else {
let frame = CursorFrame::new(stream[index].clone());
self.stack.push(CursorFrame::Stream(stream, index + 1));
CursorFrame::new(&stream[index])
frame
};
}

match self.current_frame {
CursorFrame::Empty => None,
CursorFrame::Tree(tree) => Some(tree),
CursorFrame::Tree(ref tree) => Some(tree.clone()),
CursorFrame::Stream(..) => unreachable!(),
}
}
}

impl fmt::Display for TokenStream {
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 {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.trees().cloned().collect::<Vec<_>>().encode(encoder)
self.trees().collect::<Vec<_>>().encode(encoder)
}
}

Expand Down Expand Up @@ -464,14 +470,14 @@ mod tests {
fn test_from_to_bijection() {
let test_start = string_to_tts("foo::bar(baz)".to_string());
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)
}

#[test]
fn test_to_from_bijection() {
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)
}

Expand Down

0 comments on commit 0143774

Please sign in to comment.