#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.27")]
#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))]
#![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![allow(clippy::needless_doctest_main, clippy::vec_init_then_push)]
#[cfg(use_proc_macro)]
extern crate proc_macro;
mod marker;
mod parse;
#[cfg(wrap_proc_macro)]
mod detection;
#[doc(hidden)]
pub mod fallback;
#[cfg(not(wrap_proc_macro))]
use crate::fallback as imp;
#[path = "wrapper.rs"]
#[cfg(wrap_proc_macro)]
mod imp;
use crate::marker::Marker;
use std::cmp::Ordering;
use std::error::Error;
use std::fmt::{self, Debug, Display};
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::ops::RangeBounds;
#[cfg(procmacro2_semver_exempt)]
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Clone)]
pub struct TokenStream {
inner: imp::TokenStream,
_marker: Marker,
}
pub struct LexError {
inner: imp::LexError,
_marker: Marker,
}
impl TokenStream {
fn _new(inner: imp::TokenStream) -> TokenStream {
TokenStream {
inner,
_marker: Marker,
}
}
fn _new_stable(inner: fallback::TokenStream) -> TokenStream {
TokenStream {
inner: inner.into(),
_marker: Marker,
}
}
pub fn new() -> TokenStream {
TokenStream::_new(imp::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,
})?;
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 From<TokenTree> for TokenStream {
fn from(token: TokenTree) -> Self {
TokenStream::_new(imp::TokenStream::from(token))
}
}
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 FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
TokenStream::_new(streams.into_iter().map(|i| i.inner).collect())
}
}
impl Display for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Debug for TokenStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
impl LexError {
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
}
impl Debug for LexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
impl Display for LexError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Error for LexError {}
#[cfg(procmacro2_semver_exempt)]
#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))]
#[derive(Clone, PartialEq, Eq)]
pub struct SourceFile {
inner: imp::SourceFile,
_marker: Marker,
}
#[cfg(procmacro2_semver_exempt)]
impl SourceFile {
fn _new(inner: imp::SourceFile) -> Self {
SourceFile {
inner,
_marker: Marker,
}
}
pub fn path(&self) -> PathBuf {
self.inner.path()
}
pub fn is_real(&self) -> bool {
self.inner.is_real()
}
}
#[cfg(procmacro2_semver_exempt)]
impl Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
#[cfg(span_locations)]
#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct LineColumn {
pub line: usize,
pub column: usize,
}
#[cfg(span_locations)]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line
.cmp(&other.line)
.then(self.column.cmp(&other.column))
}
}
#[cfg(span_locations)]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[derive(Copy, Clone)]
pub struct Span {
inner: imp::Span,
_marker: Marker,
}
impl Span {
fn _new(inner: imp::Span) -> Span {
Span {
inner,
_marker: Marker,
}
}
fn _new_stable(inner: fallback::Span) -> Span {
Span {
inner: inner.into(),
_marker: Marker,
}
}
pub fn call_site() -> Span {
Span::_new(imp::Span::call_site())
}
#[cfg(hygiene)]
pub fn mixed_site() -> Span {
Span::_new(imp::Span::mixed_site())
}
#[cfg(procmacro2_semver_exempt)]
#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))]
pub fn def_site() -> Span {
Span::_new(imp::Span::def_site())
}
pub fn resolved_at(&self, other: Span) -> Span {
Span::_new(self.inner.resolved_at(other.inner))
}
pub fn located_at(&self, other: Span) -> Span {
Span::_new(self.inner.located_at(other.inner))
}
#[cfg(wrap_proc_macro)]
pub fn unwrap(self) -> proc_macro::Span {
self.inner.unwrap()
}
#[cfg(wrap_proc_macro)]
#[doc(hidden)]
pub fn unstable(self) -> proc_macro::Span {
self.unwrap()
}
#[cfg(procmacro2_semver_exempt)]
#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))]
pub fn source_file(&self) -> SourceFile {
SourceFile::_new(self.inner.source_file())
}
#[cfg(span_locations)]
#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))]
pub fn start(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.start();
LineColumn { line, column }
}
#[cfg(span_locations)]
#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))]
pub fn end(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.end();
LineColumn { line, column }
}
pub fn join(&self, other: Span) -> Option<Span> {
self.inner.join(other.inner).map(Span::_new)
}
#[cfg(procmacro2_semver_exempt)]
#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))]
pub fn eq(&self, other: &Span) -> bool {
self.inner.eq(&other.inner)
}
}
impl Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, 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(t) => t.span(),
TokenTree::Ident(t) => t.span(),
TokenTree::Punct(t) => t.span(),
TokenTree::Literal(t) => t.span(),
}
}
pub fn set_span(&mut self, span: Span) {
match self {
TokenTree::Group(t) => t.set_span(span),
TokenTree::Ident(t) => t.set_span(span),
TokenTree::Punct(t) => t.set_span(span),
TokenTree::Literal(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 Display for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TokenTree::Group(t) => Display::fmt(t, f),
TokenTree::Ident(t) => Display::fmt(t, f),
TokenTree::Punct(t) => Display::fmt(t, f),
TokenTree::Literal(t) => Display::fmt(t, f),
}
}
}
impl Debug for TokenTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TokenTree::Group(t) => Debug::fmt(t, f),
TokenTree::Ident(t) => {
let mut debug = f.debug_struct("Ident");
debug.field("sym", &format_args!("{}", t));
imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner);
debug.finish()
}
TokenTree::Punct(t) => Debug::fmt(t, f),
TokenTree::Literal(t) => Debug::fmt(t, f),
}
}
}
#[derive(Clone)]
pub struct Group {
inner: imp::Group,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Delimiter {
Parenthesis,
Brace,
Bracket,
None,
}
impl Group {
fn _new(inner: imp::Group) -> Self {
Group { inner }
}
fn _new_stable(inner: fallback::Group) -> Self {
Group {
inner: inner.into(),
}
}
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group {
inner: imp::Group::new(delimiter, stream.inner),
}
}
pub fn delimiter(&self) -> Delimiter {
self.inner.delimiter()
}
pub fn stream(&self) -> TokenStream {
TokenStream::_new(self.inner.stream())
}
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
pub fn span_open(&self) -> Span {
Span::_new(self.inner.span_open())
}
pub fn span_close(&self) -> Span {
Span::_new(self.inner.span_close())
}
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner)
}
}
impl Display for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, formatter)
}
}
impl Debug for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, formatter)
}
}
#[derive(Clone)]
pub struct Punct {
ch: char,
spacing: Spacing,
span: Span,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Spacing {
Alone,
Joint,
}
impl Punct {
pub fn new(ch: char, spacing: Spacing) -> Punct {
Punct {
ch,
spacing,
span: Span::call_site(),
}
}
pub fn as_char(&self) -> char {
self.ch
}
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 Display for Punct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.ch, f)
}
}
impl Debug for Punct {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut debug = fmt.debug_struct("Punct");
debug.field("char", &self.ch);
debug.field("spacing", &self.spacing);
imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner);
debug.finish()
}
}
#[derive(Clone)]
pub struct Ident {
inner: imp::Ident,
_marker: Marker,
}
impl Ident {
fn _new(inner: imp::Ident) -> Ident {
Ident {
inner,
_marker: Marker,
}
}
pub fn new(string: &str, span: Span) -> Ident {
Ident::_new(imp::Ident::new(string, span.inner))
}
#[cfg(procmacro2_semver_exempt)]
#[cfg_attr(doc_cfg, doc(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 Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
impl Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
#[derive(Clone)]
pub struct Literal {
inner: imp::Literal,
_marker: Marker,
}
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,
_marker: Marker,
}
}
fn _new_stable(inner: fallback::Literal) -> Literal {
Literal {
inner: inner.into(),
_marker: Marker,
}
}
suffixed_int_literals! {
u8_suffixed => u8,
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
u128_suffixed => u128,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
i128_suffixed => i128,
isize_suffixed => isize,
}
unsuffixed_int_literals! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
u128_unsuffixed => u128,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
i128_unsuffixed => i128,
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);
}
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
self.inner.subspan(range).map(Span::_new)
}
}
impl FromStr for Literal {
type Err = LexError;
fn from_str(repr: &str) -> Result<Self, LexError> {
repr.parse().map(Literal::_new).map_err(|inner| LexError {
inner,
_marker: Marker,
})
}
}
impl Debug for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
impl Display for Literal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.inner, f)
}
}
pub mod token_stream {
use crate::marker::Marker;
use crate::{imp, TokenTree};
use std::fmt::{self, Debug};
pub use crate::TokenStream;
#[derive(Clone)]
pub struct IntoIter {
inner: imp::TokenTreeIter,
_marker: Marker,
}
impl Iterator for IntoIter {
type Item = TokenTree;
fn next(&mut self) -> Option<TokenTree> {
self.inner.next()
}
}
impl Debug for IntoIter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter {
inner: self.inner.into_iter(),
_marker: Marker,
}
}
}
}