Skip to content

Commit

Permalink
Merge pull request #134 from dtolnay/group
Browse files Browse the repository at this point in the history
Provide Group::span_open and span_close
  • Loading branch information
alexcrichton authored Sep 17, 2018
2 parents 262c957 + f14813f commit 79e40a1
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 61 deletions.
79 changes: 49 additions & 30 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,7 @@ impl fmt::Debug for TokenTree {
/// `Delimiter`s.
#[derive(Clone)]
pub struct Group {
delimiter: Delimiter,
stream: TokenStream,
span: Span,
inner: imp::Group,
}

/// Describes how a sequence of token trees is delimited.
Expand All @@ -527,36 +525,73 @@ pub enum Delimiter {
}

impl Group {
fn _new(inner: imp::Group) -> Self {
Group {
inner: inner,
}
}

fn _new_stable(inner: stable::Group) -> Self {
Group {
inner: inner.into(),
}
}

/// Creates a new `Group` with the given delimiter and token stream.
///
/// This constructor will set the span for this group to
/// `Span::call_site()`. To change the span you can use the `set_span`
/// method below.
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group {
delimiter: delimiter,
stream: stream,
span: Span::call_site(),
inner: imp::Group::new(delimiter, stream.inner),
}
}

/// Returns the delimiter of this `Group`
pub fn delimiter(&self) -> Delimiter {
self.delimiter
self.inner.delimiter()
}

/// Returns the `TokenStream` of tokens that are delimited in this `Group`.
///
/// Note that the returned token stream does not include the delimiter
/// returned above.
pub fn stream(&self) -> TokenStream {
self.stream.clone()
TokenStream::_new(self.inner.stream())
}

/// Returns the span for the delimiters of this token stream, spanning the
/// entire `Group`.
///
/// ```text
/// pub fn span(&self) -> Span {
/// ^^^^^^^
/// ```
pub fn span(&self) -> Span {
self.span
Span::_new(self.inner.span())
}

/// Returns the span pointing to the opening delimiter of this group.
///
/// ```text
/// pub fn span_open(&self) -> Span {
/// ^
/// ```
#[cfg(procmacro2_semver_exempt)]
pub fn span_open(&self) -> Span {
Span::_new(self.inner.span_open())
}

/// Returns the span pointing to the closing delimiter of this group.
///
/// ```text
/// pub fn span_close(&self) -> Span {
/// ^
/// ```
#[cfg(procmacro2_semver_exempt)]
pub fn span_close(&self) -> Span {
Span::_new(self.inner.span_close())
}

/// Configures the span for this `Group`'s delimiters, but not its internal
Expand All @@ -566,38 +601,22 @@ impl Group {
/// by this group, but rather it will only set the span of the delimiter
/// tokens at the level of the `Group`.
pub fn set_span(&mut self, span: Span) {
self.span = span;
self.inner.set_span(span.inner)
}
}

/// Prints the group as a string that should be losslessly convertible back
/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
/// with `Delimiter::None` delimiters.
impl fmt::Display for Group {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (left, right) = match self.delimiter {
Delimiter::Parenthesis => ("(", ")"),
Delimiter::Brace => ("{", "}"),
Delimiter::Bracket => ("[", "]"),
Delimiter::None => ("", ""),
};

f.write_str(left)?;
self.stream.fmt(f)?;
f.write_str(right)?;

Ok(())
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.inner, formatter)
}
}

impl fmt::Debug for Group {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut debug = fmt.debug_struct("Group");
debug.field("delimiter", &self.delimiter);
debug.field("stream", &self.stream);
#[cfg(procmacro2_semver_exempt)]
debug.field("span", &self.span);
debug.finish()
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.inner, formatter)
}
}

Expand Down
82 changes: 76 additions & 6 deletions src/stable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::vec;
use strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
use unicode_xid::UnicodeXID;

use {Delimiter, Group, Punct, Spacing, TokenTree};
use {Delimiter, Punct, Spacing, TokenTree};

#[derive(Clone)]
pub struct TokenStream {
Expand Down Expand Up @@ -431,6 +431,75 @@ impl fmt::Debug for Span {
}
}

#[derive(Clone)]
pub struct Group {
delimiter: Delimiter,
stream: TokenStream,
span: Span,
}

impl Group {
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group {
delimiter: delimiter,
stream: stream,
span: Span::call_site(),
}
}

pub fn delimiter(&self) -> Delimiter {
self.delimiter
}

pub fn stream(&self) -> TokenStream {
self.stream.clone()
}

pub fn span(&self) -> Span {
self.span
}

pub fn span_open(&self) -> Span {
self.span
}

pub fn span_close(&self) -> Span {
self.span
}

pub fn set_span(&mut self, span: Span) {
self.span = span;
}
}

impl fmt::Display for Group {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (left, right) = match self.delimiter {
Delimiter::Parenthesis => ("(", ")"),
Delimiter::Brace => ("{", "}"),
Delimiter::Bracket => ("[", "]"),
Delimiter::None => ("", ""),
};

f.write_str(left)?;
self.stream.fmt(f)?;
f.write_str(right)?;

Ok(())
}
}

impl fmt::Debug for Group {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut debug = fmt.debug_struct("Group");
debug.field("delimiter", &self.delimiter);
debug.field("stream", &self.stream);
#[cfg(procmacro2_semver_exempt)]
debug.field("span", &self.span);
debug.finish()
}
}

#[derive(Clone)]
pub struct Ident {
sym: String,
Expand Down Expand Up @@ -747,7 +816,7 @@ fn token_tree(input: Cursor) -> PResult<TokenTree> {
}

named!(token_kind -> TokenTree, alt!(
map!(group, TokenTree::Group)
map!(group, |g| TokenTree::Group(::Group::_new_stable(g)))
|
map!(literal, |l| TokenTree::Literal(::Literal::_new_stable(l))) // must be before symbol
|
Expand All @@ -761,19 +830,19 @@ named!(group -> Group, alt!(
punct!("("),
token_stream,
punct!(")")
) => { |ts| Group::new(Delimiter::Parenthesis, ::TokenStream::_new_stable(ts)) }
) => { |ts| Group::new(Delimiter::Parenthesis, ts) }
|
delimited!(
punct!("["),
token_stream,
punct!("]")
) => { |ts| Group::new(Delimiter::Bracket, ::TokenStream::_new_stable(ts)) }
) => { |ts| Group::new(Delimiter::Bracket, ts) }
|
delimited!(
punct!("{"),
token_stream,
punct!("}")
) => { |ts| Group::new(Delimiter::Brace, ::TokenStream::_new_stable(ts)) }
) => { |ts| Group::new(Delimiter::Brace, ts) }
));

fn symbol_leading_ws(input: Cursor) -> PResult<TokenTree> {
Expand Down Expand Up @@ -1288,7 +1357,8 @@ fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
for tt in stream.iter_mut() {
tt.set_span(span);
}
trees.push(Group::new(Delimiter::Bracket, stream.into_iter().collect()).into());
let group = Group::new(Delimiter::Bracket, stream.into_iter().collect());
trees.push(::Group::_new_stable(group).into());
for tt in trees.iter_mut() {
tt.set_span(span);
}
Expand Down
Loading

0 comments on commit 79e40a1

Please sign in to comment.