Provide Group::span_open and span_close
diff --git a/src/lib.rs b/src/lib.rs
index 59de17b..2b20683 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -502,9 +502,7 @@
/// `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.
@@ -527,6 +525,18 @@
}
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
@@ -534,15 +544,13 @@
/// 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`.
@@ -550,13 +558,40 @@
/// 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
@@ -566,7 +601,7 @@
/// 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)
}
}
@@ -574,30 +609,14 @@
/// 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)
}
}
diff --git a/src/stable.rs b/src/stable.rs
index 34df695..6c06fc4 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -12,7 +12,7 @@
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 {
@@ -432,6 +432,75 @@
}
#[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,
span: Span,
@@ -747,7 +816,7 @@
}
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
|
@@ -761,19 +830,19 @@
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> {
@@ -1288,7 +1357,8 @@
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);
}
diff --git a/src/unstable.rs b/src/unstable.rs
index e8e2e2e..433639d 100644
--- a/src/unstable.rs
+++ b/src/unstable.rs
@@ -8,7 +8,7 @@
use proc_macro;
use stable;
-use {Delimiter, Group, Punct, Spacing, TokenTree};
+use {Delimiter, Punct, Spacing, TokenTree};
#[derive(Clone)]
pub enum TokenStream {
@@ -161,18 +161,7 @@
return TokenStream::Stable(token.into());
}
let tt: proc_macro::TokenTree = match token {
- TokenTree::Group(tt) => {
- let delim = match tt.delimiter() {
- Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
- Delimiter::Bracket => proc_macro::Delimiter::Bracket,
- Delimiter::Brace => proc_macro::Delimiter::Brace,
- Delimiter::None => proc_macro::Delimiter::None,
- };
- let span = tt.span();
- let mut group = proc_macro::Group::new(delim, tt.stream.inner.unwrap_nightly());
- group.set_span(span.inner.unwrap_nightly());
- group.into()
- }
+ TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
Spacing::Joint => proc_macro::Spacing::Joint,
@@ -364,18 +353,7 @@
TokenTreeIter::Stable(iter) => return iter.next(),
};
Some(match token {
- proc_macro::TokenTree::Group(tt) => {
- let delim = match tt.delimiter() {
- proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
- proc_macro::Delimiter::Bracket => Delimiter::Bracket,
- proc_macro::Delimiter::Brace => Delimiter::Brace,
- proc_macro::Delimiter::None => Delimiter::None,
- };
- let stream = ::TokenStream::_new(TokenStream::Nightly(tt.stream()));
- let mut g = Group::new(delim, stream);
- g.set_span(::Span::_new(Span::Nightly(tt.span())));
- g.into()
- }
+ proc_macro::TokenTree::Group(tt) => ::Group::_new(Group::Nightly(tt)).into(),
proc_macro::TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
proc_macro::Spacing::Joint => Spacing::Joint,
@@ -594,6 +572,112 @@
}
#[derive(Clone)]
+pub enum Group {
+ Nightly(proc_macro::Group),
+ Stable(stable::Group),
+}
+
+impl Group {
+ pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
+ match stream {
+ TokenStream::Nightly(stream) => {
+ let delimiter = match delimiter {
+ Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
+ Delimiter::Bracket => proc_macro::Delimiter::Bracket,
+ Delimiter::Brace => proc_macro::Delimiter::Brace,
+ Delimiter::None => proc_macro::Delimiter::None,
+ };
+ Group::Nightly(proc_macro::Group::new(delimiter, stream))
+ }
+ TokenStream::Stable(stream) => {
+ Group::Stable(stable::Group::new(delimiter, stream))
+ }
+ }
+ }
+
+ pub fn delimiter(&self) -> Delimiter {
+ match self {
+ Group::Nightly(g) => match g.delimiter() {
+ proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
+ proc_macro::Delimiter::Bracket => Delimiter::Bracket,
+ proc_macro::Delimiter::Brace => Delimiter::Brace,
+ proc_macro::Delimiter::None => Delimiter::None,
+ }
+ Group::Stable(g) => g.delimiter(),
+ }
+ }
+
+ pub fn stream(&self) -> TokenStream {
+ match self {
+ Group::Nightly(g) => TokenStream::Nightly(g.stream()),
+ Group::Stable(g) => TokenStream::Stable(g.stream()),
+ }
+ }
+
+ pub fn span(&self) -> Span {
+ match self {
+ Group::Nightly(g) => Span::Nightly(g.span()),
+ Group::Stable(g) => Span::Stable(g.span()),
+ }
+ }
+
+ #[cfg(super_unstable)]
+ pub fn span_open(&self) -> Span {
+ match self {
+ Group::Nightly(g) => Span::Nightly(g.span_open()),
+ Group::Stable(g) => Span::Stable(g.span_open()),
+ }
+ }
+
+ #[cfg(super_unstable)]
+ pub fn span_close(&self) -> Span {
+ match self {
+ Group::Nightly(g) => Span::Nightly(g.span_close()),
+ Group::Stable(g) => Span::Stable(g.span_close()),
+ }
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ match (self, span) {
+ (Group::Nightly(g), Span::Nightly(s)) => g.set_span(s),
+ (Group::Stable(g), Span::Stable(s)) => g.set_span(s),
+ _ => mismatch(),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::Group {
+ match self {
+ Group::Nightly(g) => g,
+ Group::Stable(_) => mismatch(),
+ }
+ }
+}
+
+impl From<stable::Group> for Group {
+ fn from(g: stable::Group) -> Self {
+ Group::Stable(g)
+ }
+}
+
+impl fmt::Display for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Group::Nightly(group) => group.fmt(formatter),
+ Group::Stable(group) => group.fmt(formatter),
+ }
+ }
+}
+
+impl fmt::Debug for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Group::Nightly(group) => group.fmt(formatter),
+ Group::Stable(group) => group.fmt(formatter),
+ }
+ }
+}
+
+#[derive(Clone)]
pub enum Ident {
Nightly(proc_macro::Ident),
Stable(stable::Ident),