#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.17")]
#![cfg_attr(
super_unstable,
feature(proc_macro_raw_ident, proc_macro_span)
)]
#[cfg(use_proc_macro)]
extern crate proc_macro;
extern crate unicode_xid;
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::marker;
use std::rc::Rc;
use std::str::FromStr;
#[macro_use]
mod strnom;
mod stable;
#[cfg(not(wrap_proc_macro))]
use stable as imp;
#[path = "unstable.rs"]
#[cfg(wrap_proc_macro)]
mod imp;
#[derive(Clone)]
pub struct TokenStream {
inner: imp::TokenStream,
_marker: marker::PhantomData<Rc<()>>,
}
pub struct LexError {
inner: imp::LexError,
_marker: marker::PhantomData<Rc<()>>,
}
impl TokenStream {
fn _new(inner: imp::TokenStream) -> TokenStream {
TokenStream {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: stable::TokenStream) -> TokenStream {
TokenStream {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
pub fn new() -> TokenStream {
TokenStream::_new(imp::TokenStream::new())
}
#[deprecated(since = "0.4.4", note = "please use TokenStream::new")]
pub fn empty() -> TokenStream {
TokenStream::new()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
impl Default for TokenStream {
fn default() -> Self {
TokenStream::new()
}
}
impl FromStr for TokenStream {
type Err = LexError;
fn from_str(src: &str) -> Result<TokenStream, LexError> {
let e = src.parse().map_err(|e| LexError {
inner: e,
_marker: marker::PhantomData,
})?;
Ok(TokenStream::_new(e))
}
}
#[cfg(use_proc_macro)]
impl From<proc_macro::TokenStream> for TokenStream {
fn from(inner: proc_macro::TokenStream) -> TokenStream {
TokenStream::_new(inner.into())
}
}
#[cfg(use_proc_macro)]
impl From<TokenStream> for proc_macro::TokenStream {
fn from(inner: TokenStream) -> proc_macro::TokenStream {
inner.inner.into()
}
}
impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
self.inner.extend(streams)
}
}
impl Extend<TokenStream> for TokenStream {
fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
self.inner
.extend(streams.into_iter().map(|stream| stream.inner))
}
}
impl FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
TokenStream::_new(streams.into_iter().collect())
}
}
impl fmt::Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Debug for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Debug for LexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
#[cfg(procmacro2_semver_exempt)]
pub use imp::FileName;
#[cfg(procmacro2_semver_exempt)]
#[derive(Clone, PartialEq, Eq)]
pub struct SourceFile(imp::SourceFile);
#[cfg(procmacro2_semver_exempt)]
impl SourceFile {
pub fn path(&self) -> &FileName {
self.0.path()
}
pub fn is_real(&self) -> bool {
self.0.is_real()
}
}
#[cfg(procmacro2_semver_exempt)]
impl AsRef<FileName> for SourceFile {
fn as_ref(&self) -> &FileName {
self.0.path()
}
}
#[cfg(procmacro2_semver_exempt)]
impl fmt::Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
#[cfg(procmacro2_semver_exempt)]
pub struct LineColumn {
pub line: usize,
pub column: usize,
}
#[derive(Copy, Clone)]
pub struct Span {
inner: imp::Span,
_marker: marker::PhantomData<Rc<()>>,
}
impl Span {
fn _new(inner: imp::Span) -> Span {
Span {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: stable::Span) -> Span {
Span {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
pub fn call_site() -> Span {
Span::_new(imp::Span::call_site())
}
#[cfg(procmacro2_semver_exempt)]
pub fn def_site() -> Span {
Span::_new(imp::Span::def_site())
}
#[cfg(procmacro2_semver_exempt)]
pub fn resolved_at(&self, other: Span) -> Span {
Span::_new(self.inner.resolved_at(other.inner))
}
#[cfg(procmacro2_semver_exempt)]
pub fn located_at(&self, other: Span) -> Span {
Span::_new(self.inner.located_at(other.inner))
}
#[doc(hidden)]
#[cfg(any(feature = "nightly", super_unstable))]
pub fn unstable(self) -> proc_macro::Span {
self.inner.unstable()
}
#[cfg(procmacro2_semver_exempt)]
pub fn source_file(&self) -> SourceFile {
SourceFile(self.inner.source_file())
}
#[cfg(procmacro2_semver_exempt)]
pub fn start(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.start();
LineColumn {
line: line,
column: column,
}
}
#[cfg(procmacro2_semver_exempt)]
pub fn end(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.end();
LineColumn {
line: line,
column: column,
}
}
#[cfg(procmacro2_semver_exempt)]
pub fn join(&self, other: Span) -> Option<Span> {
self.inner.join(other.inner).map(Span::_new)
}
#[cfg(procmacro2_semver_exempt)]
pub fn eq(&self, other: &Span) -> bool {
self.inner.eq(&other.inner)
}
}
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Clone)]
pub enum TokenTree {
Group(Group),
Ident(Ident),
Punct(Punct),
Literal(Literal),
}
impl TokenTree {
pub fn span(&self) -> Span {
match *self {
TokenTree::Group(ref t) => t.span(),
TokenTree::Ident(ref t) => t.span(),
TokenTree::Punct(ref t) => t.span(),
TokenTree::Literal(ref t) => t.span(),
}
}
pub fn set_span(&mut self, span: Span) {
match *self {
TokenTree::Group(ref mut t) => t.set_span(span),
TokenTree::Ident(ref mut t) => t.set_span(span),
TokenTree::Punct(ref mut t) => t.set_span(span),
TokenTree::Literal(ref mut t) => t.set_span(span),
}
}
}
impl From<Group> for TokenTree {
fn from(g: Group) -> TokenTree {
TokenTree::Group(g)
}
}
impl From<Ident> for TokenTree {
fn from(g: Ident) -> TokenTree {
TokenTree::Ident(g)
}
}
impl From<Punct> for TokenTree {
fn from(g: Punct) -> TokenTree {
TokenTree::Punct(g)
}
}
impl From<Literal> for TokenTree {
fn from(g: Literal) -> TokenTree {
TokenTree::Literal(g)
}
}
impl fmt::Display for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TokenTree::Group(ref t) => t.fmt(f),
TokenTree::Ident(ref t) => t.fmt(f),
TokenTree::Punct(ref t) => t.fmt(f),
TokenTree::Literal(ref t) => t.fmt(f),
}
}
}
impl fmt::Debug for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TokenTree::Group(ref t) => t.fmt(f),
TokenTree::Ident(ref t) => {
let mut debug = f.debug_struct("Ident");
debug.field("sym", &format_args!("{}", t));
#[cfg(any(feature = "nightly", procmacro2_semver_exempt))]
debug.field("span", &t.span());
debug.finish()
}
TokenTree::Punct(ref t) => t.fmt(f),
TokenTree::Literal(ref t) => t.fmt(f),
}
}
}
#[derive(Clone)]
pub struct Group {
delimiter: Delimiter,
stream: TokenStream,
span: Span,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Delimiter {
Parenthesis,
Brace,
Bracket,
None,
}
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 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 Punct {
op: char,
spacing: Spacing,
span: Span,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Spacing {
Alone,
Joint,
}
impl Punct {
pub fn new(op: char, spacing: Spacing) -> Punct {
Punct {
op: op,
spacing: spacing,
span: Span::call_site(),
}
}
pub fn as_char(&self) -> char {
self.op
}
pub fn spacing(&self) -> Spacing {
self.spacing
}
pub fn span(&self) -> Span {
self.span
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
}
}
impl fmt::Display for Punct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.op.fmt(f)
}
}
impl fmt::Debug for Punct {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut debug = fmt.debug_struct("Punct");
debug.field("op", &self.op);
debug.field("spacing", &self.spacing);
#[cfg(procmacro2_semver_exempt)]
debug.field("span", &self.span);
debug.finish()
}
}
#[derive(Clone)]
pub struct Ident {
inner: imp::Ident,
_marker: marker::PhantomData<Rc<()>>,
}
impl Ident {
fn _new(inner: imp::Ident) -> Ident {
Ident {
inner: inner,
_marker: marker::PhantomData,
}
}
pub fn new(string: &str, span: Span) -> Ident {
Ident::_new(imp::Ident::new(string, span.inner))
}
#[cfg(procmacro2_semver_exempt)]
pub fn new_raw(string: &str, span: Span) -> Ident {
Ident::_new_raw(string, span)
}
fn _new_raw(string: &str, span: Span) -> Ident {
Ident::_new(imp::Ident::new_raw(string, span.inner))
}
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner);
}
}
impl PartialEq for Ident {
fn eq(&self, other: &Ident) -> bool {
self.inner == other.inner
}
}
impl<T> PartialEq<T> for Ident
where
T: ?Sized + AsRef<str>,
{
fn eq(&self, other: &T) -> bool {
self.inner == other
}
}
impl Eq for Ident {}
impl PartialOrd for Ident {
fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Ident {
fn cmp(&self, other: &Ident) -> Ordering {
self.to_string().cmp(&other.to_string())
}
}
impl Hash for Ident {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.to_string().hash(hasher)
}
}
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Clone)]
pub struct Literal {
inner: imp::Literal,
_marker: marker::PhantomData<Rc<()>>,
}
macro_rules! suffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
pub fn $name(n: $kind) -> Literal {
Literal::_new(imp::Literal::$name(n))
}
)*)
}
macro_rules! unsuffixed_int_literals {
($($name:ident => $kind:ident,)*) => ($(
pub fn $name(n: $kind) -> Literal {
Literal::_new(imp::Literal::$name(n))
}
)*)
}
impl Literal {
fn _new(inner: imp::Literal) -> Literal {
Literal {
inner: inner,
_marker: marker::PhantomData,
}
}
fn _new_stable(inner: stable::Literal) -> Literal {
Literal {
inner: inner.into(),
_marker: marker::PhantomData,
}
}
suffixed_int_literals! {
u8_suffixed => u8,
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
isize_suffixed => isize,
}
unsuffixed_int_literals! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
isize_unsuffixed => isize,
}
pub fn f64_unsuffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_unsuffixed(f))
}
pub fn f64_suffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_suffixed(f))
}
pub fn f32_unsuffixed(f: f32) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f32_unsuffixed(f))
}
pub fn f32_suffixed(f: f32) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f32_suffixed(f))
}
pub fn string(string: &str) -> Literal {
Literal::_new(imp::Literal::string(string))
}
pub fn character(ch: char) -> Literal {
Literal::_new(imp::Literal::character(ch))
}
pub fn byte_string(s: &[u8]) -> Literal {
Literal::_new(imp::Literal::byte_string(s))
}
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner);
}
}
impl fmt::Debug for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl fmt::Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
pub mod token_stream {
use std::fmt;
use std::marker;
use std::rc::Rc;
use imp;
pub use TokenStream;
use TokenTree;
pub struct IntoIter {
inner: imp::TokenTreeIter,
_marker: marker::PhantomData<Rc<()>>,
}
impl Iterator for IntoIter {
type Item = TokenTree;
fn next(&mut self) -> Option<TokenTree> {
self.inner.next()
}
}
impl fmt::Debug for IntoIter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter {
inner: self.inner.into_iter(),
_marker: marker::PhantomData,
}
}
}
}