blob: 00c1aafc8a1f3ad65debb3ef256a83fc87230073 [file] [log] [blame]
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08001//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
2//! Rust.
Alex Crichtonbabc99e2017-07-05 18:00:29 -07003//!
4//! Procedural macros in Rust operate over the upstream
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08005//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
6//! conservative and exposed no internal implementation details. Nightly
7//! compilers, however, contain a much richer interface. This richer interface
8//! allows fine-grained inspection of the token stream which avoids
9//! stringification/re-lexing and also preserves span information.
Alex Crichtonbabc99e2017-07-05 18:00:29 -070010//!
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080011//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
Alex Crichtonbabc99e2017-07-05 18:00:29 -070012//! productive procedural macros in the ecosystem. To help prepare the ecosystem
13//! for using them this crate serves to both compile on stable and nightly and
14//! mirrors the API-to-be. The intention is that procedural macros which switch
15//! to use this crate will be trivially able to switch to the upstream
16//! `proc_macro` crate once its API stabilizes.
17//!
David Tolnayd66ecf62018-01-02 20:05:42 -080018//! In the meantime this crate also has a `nightly` Cargo feature which
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080019//! enables it to reimplement itself with the unstable API of [`proc_macro`].
Alex Crichtonbabc99e2017-07-05 18:00:29 -070020//! This'll allow immediate usage of the beneficial upstream API, particularly
21//! around preserving span information.
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080022//!
David Tolnay6b46deb2018-04-25 21:22:46 -070023//! # Unstable Features
24//!
25//! `proc-macro2` supports exporting some methods from `proc_macro` which are
26//! currently highly unstable, and may not be stabilized in the first pass of
27//! `proc_macro` stabilizations. These features are not exported by default.
28//! Minor versions of `proc-macro2` may make breaking changes to them at any
29//! time.
30//!
31//! To enable these features, the `procmacro2_semver_exempt` config flag must be
32//! passed to rustc.
33//!
34//! ```sh
35//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
36//! ```
37//!
38//! Note that this must not only be done for your crate, but for any crate that
39//! depends on your crate. This infectious nature is intentional, as it serves
40//! as a reminder that you are outside of the normal semver guarantees.
41//!
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080042//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
43//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
Alex Crichtonbabc99e2017-07-05 18:00:29 -070044
David Tolnay15cc4982018-01-08 08:03:27 -080045// Proc-macro2 types in rustdoc of other crates get linked to here.
David Tolnay2c8e9172018-05-18 20:54:57 -070046#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.2")]
David Tolnayd66ecf62018-01-02 20:05:42 -080047#![cfg_attr(feature = "nightly", feature(proc_macro))]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070048
Alex Crichton0e8e7f42018-02-22 06:15:13 -080049#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070050extern crate proc_macro;
David Tolnayb1032662017-05-31 15:52:28 -070051extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070052
Alex Crichtonf3888432018-05-16 09:11:05 -070053use std::cmp::Ordering;
Alex Crichton44bffbc2017-05-19 17:51:59 -070054use std::fmt;
Alex Crichtonf3888432018-05-16 09:11:05 -070055use std::hash::{Hash, Hasher};
Alex Crichton44bffbc2017-05-19 17:51:59 -070056use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070057use std::marker;
58use std::rc::Rc;
59use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070060
David Tolnayb1032662017-05-31 15:52:28 -070061#[macro_use]
David Tolnayb1032662017-05-31 15:52:28 -070062mod strnom;
Alex Crichton30a4e9e2018-04-27 17:02:19 -070063mod stable;
David Tolnayb1032662017-05-31 15:52:28 -070064
David Tolnayd66ecf62018-01-02 20:05:42 -080065#[cfg(not(feature = "nightly"))]
Alex Crichton30a4e9e2018-04-27 17:02:19 -070066use stable as imp;
Alex Crichtonb15c6352017-05-19 19:36:36 -070067#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080068#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070069mod imp;
70
David Tolnaycb1b85f2017-06-03 16:40:35 -070071#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070072pub struct TokenStream {
73 inner: imp::TokenStream,
74 _marker: marker::PhantomData<Rc<()>>,
75}
Alex Crichton44bffbc2017-05-19 17:51:59 -070076
Alex Crichtonaf5bad42018-03-27 14:45:10 -070077pub struct LexError {
78 inner: imp::LexError,
79 _marker: marker::PhantomData<Rc<()>>,
80}
81
82impl TokenStream {
83 fn _new(inner: imp::TokenStream) -> TokenStream {
84 TokenStream {
85 inner: inner,
86 _marker: marker::PhantomData,
87 }
88 }
89
Alex Crichton30a4e9e2018-04-27 17:02:19 -070090 fn _new_stable(inner: stable::TokenStream) -> TokenStream {
91 TokenStream {
92 inner: inner.into(),
93 _marker: marker::PhantomData,
94 }
95 }
96
Alex Crichtonaf5bad42018-03-27 14:45:10 -070097 pub fn empty() -> TokenStream {
98 TokenStream::_new(imp::TokenStream::empty())
99 }
100
101 pub fn is_empty(&self) -> bool {
102 self.inner.is_empty()
103 }
104}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700105
106impl FromStr for TokenStream {
107 type Err = LexError;
108
109 fn from_str(src: &str) -> Result<TokenStream, LexError> {
David Tolnayb28f38a2018-03-31 22:02:29 +0200110 let e = src.parse().map_err(|e| LexError {
111 inner: e,
112 _marker: marker::PhantomData,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700113 })?;
114 Ok(TokenStream::_new(e))
Alex Crichton44bffbc2017-05-19 17:51:59 -0700115 }
116}
117
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800118#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700119impl From<proc_macro::TokenStream> for TokenStream {
120 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700121 TokenStream::_new(inner.into())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700122 }
123}
124
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800125#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700126impl From<TokenStream> for proc_macro::TokenStream {
127 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700128 inner.inner.into()
Alex Crichton44bffbc2017-05-19 17:51:59 -0700129 }
130}
131
Alex Crichtonf3888432018-05-16 09:11:05 -0700132impl Extend<TokenTree> for TokenStream {
133 fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
134 self.inner.extend(streams)
135 }
136}
137
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700138impl FromIterator<TokenTree> for TokenStream {
139 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
140 TokenStream::_new(streams.into_iter().collect())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700141 }
142}
143
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700144impl fmt::Display for TokenStream {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700147 }
148}
149
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700150impl fmt::Debug for TokenStream {
151 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700153 }
154}
155
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700156impl fmt::Debug for LexError {
157 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
158 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700159 }
160}
161
Nika Layzellb35a9a32017-12-30 14:34:35 -0500162// Returned by reference, so we can't easily wrap it.
David Tolnay1ebe3972018-01-02 20:14:20 -0800163#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500164pub use imp::FileName;
165
David Tolnay1ebe3972018-01-02 20:14:20 -0800166#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500167#[derive(Clone, PartialEq, Eq)]
168pub struct SourceFile(imp::SourceFile);
169
David Tolnay1ebe3972018-01-02 20:14:20 -0800170#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500171impl SourceFile {
172 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500173 pub fn path(&self) -> &FileName {
174 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500175 }
176
177 pub fn is_real(&self) -> bool {
178 self.0.is_real()
179 }
180}
181
David Tolnay1ebe3972018-01-02 20:14:20 -0800182#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500183impl AsRef<FileName> for SourceFile {
184 fn as_ref(&self) -> &FileName {
185 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500186 }
187}
188
David Tolnay1ebe3972018-01-02 20:14:20 -0800189#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500190impl fmt::Debug for SourceFile {
191 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192 self.0.fmt(f)
193 }
194}
195
David Tolnay1ebe3972018-01-02 20:14:20 -0800196#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500197pub struct LineColumn {
198 pub line: usize,
199 pub column: usize,
200}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500201
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700202#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700203pub struct Span {
204 inner: imp::Span,
205 _marker: marker::PhantomData<Rc<()>>,
206}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700207
Alex Crichton44bffbc2017-05-19 17:51:59 -0700208impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700209 fn _new(inner: imp::Span) -> Span {
210 Span {
211 inner: inner,
212 _marker: marker::PhantomData,
213 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700214 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800215
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700216 fn _new_stable(inner: stable::Span) -> Span {
217 Span {
218 inner: inner.into(),
219 _marker: marker::PhantomData,
220 }
221 }
222
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700223 pub fn call_site() -> Span {
224 Span::_new(imp::Span::call_site())
225 }
226
227 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800228 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700229 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800230 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500231
David Tolnay4e8e3972018-01-05 18:10:22 -0800232 /// Creates a new span with the same line/column information as `self` but
233 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700234 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800235 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700236 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800237 }
238
239 /// Creates a new span with the same name resolution behavior as `self` but
240 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700241 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800242 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700243 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800244 }
245
David Tolnayd66ecf62018-01-02 20:05:42 -0800246 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800247 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500248 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700249 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500250 }
251
David Tolnay1ebe3972018-01-02 20:14:20 -0800252 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500253 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700254 SourceFile(self.inner.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500255 }
256
David Tolnay1ebe3972018-01-02 20:14:20 -0800257 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500258 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200259 let imp::LineColumn { line, column } = self.inner.start();
260 LineColumn {
261 line: line,
262 column: column,
263 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500264 }
265
David Tolnay1ebe3972018-01-02 20:14:20 -0800266 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500267 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200268 let imp::LineColumn { line, column } = self.inner.end();
269 LineColumn {
270 line: line,
271 column: column,
272 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500273 }
274
David Tolnay1ebe3972018-01-02 20:14:20 -0800275 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500276 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700277 self.inner.join(other.inner).map(Span::_new)
278 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700279
280 #[cfg(procmacro2_semver_exempt)]
281 pub fn eq(&self, other: &Span) -> bool {
282 self.inner.eq(&other.inner)
283 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700284}
285
286impl fmt::Debug for Span {
287 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500289 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700290}
291
David Tolnay034205f2018-04-22 16:45:28 -0700292#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700293pub enum TokenTree {
294 Group(Group),
Alex Crichtonf3888432018-05-16 09:11:05 -0700295 Ident(Ident),
296 Punct(Punct),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700297 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700298}
299
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700300impl TokenTree {
301 pub fn span(&self) -> Span {
302 match *self {
303 TokenTree::Group(ref t) => t.span(),
Alex Crichtonf3888432018-05-16 09:11:05 -0700304 TokenTree::Ident(ref t) => t.span(),
305 TokenTree::Punct(ref t) => t.span(),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700306 TokenTree::Literal(ref t) => t.span(),
307 }
308 }
309
310 pub fn set_span(&mut self, span: Span) {
311 match *self {
312 TokenTree::Group(ref mut t) => t.set_span(span),
Alex Crichtonf3888432018-05-16 09:11:05 -0700313 TokenTree::Ident(ref mut t) => t.set_span(span),
314 TokenTree::Punct(ref mut t) => t.set_span(span),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700315 TokenTree::Literal(ref mut t) => t.set_span(span),
316 }
317 }
318}
319
320impl From<Group> for TokenTree {
321 fn from(g: Group) -> TokenTree {
322 TokenTree::Group(g)
323 }
324}
325
Alex Crichtonf3888432018-05-16 09:11:05 -0700326impl From<Ident> for TokenTree {
327 fn from(g: Ident) -> TokenTree {
328 TokenTree::Ident(g)
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700329 }
330}
331
Alex Crichtonf3888432018-05-16 09:11:05 -0700332impl From<Punct> for TokenTree {
333 fn from(g: Punct) -> TokenTree {
334 TokenTree::Punct(g)
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700335 }
336}
337
338impl From<Literal> for TokenTree {
339 fn from(g: Literal) -> TokenTree {
340 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700341 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700342}
343
Alex Crichton44bffbc2017-05-19 17:51:59 -0700344impl fmt::Display for TokenTree {
345 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700346 match *self {
347 TokenTree::Group(ref t) => t.fmt(f),
Alex Crichtonf3888432018-05-16 09:11:05 -0700348 TokenTree::Ident(ref t) => t.fmt(f),
349 TokenTree::Punct(ref t) => t.fmt(f),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700350 TokenTree::Literal(ref t) => t.fmt(f),
351 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700352 }
353}
354
David Tolnay034205f2018-04-22 16:45:28 -0700355impl fmt::Debug for TokenTree {
356 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
357 // Each of these has the name in the struct type in the derived debug,
358 // so don't bother with an extra layer of indirection
359 match *self {
360 TokenTree::Group(ref t) => t.fmt(f),
Alex Crichtonf3888432018-05-16 09:11:05 -0700361 TokenTree::Ident(ref t) => t.fmt(f),
362 TokenTree::Punct(ref t) => t.fmt(f),
David Tolnay034205f2018-04-22 16:45:28 -0700363 TokenTree::Literal(ref t) => t.fmt(f),
364 }
365 }
366}
367
368#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700369pub struct Group {
370 delimiter: Delimiter,
371 stream: TokenStream,
372 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700373}
374
Michael Layzell5372f4b2017-06-02 10:29:31 -0400375#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700376pub enum Delimiter {
377 Parenthesis,
378 Brace,
379 Bracket,
380 None,
381}
382
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700383impl Group {
384 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
385 Group {
386 delimiter: delimiter,
387 stream: stream,
388 span: Span::call_site(),
389 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700390 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700391
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700392 pub fn delimiter(&self) -> Delimiter {
393 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700394 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700395
396 pub fn stream(&self) -> TokenStream {
397 self.stream.clone()
398 }
399
400 pub fn span(&self) -> Span {
401 self.span
402 }
403
404 pub fn set_span(&mut self, span: Span) {
405 self.span = span;
406 }
407}
408
409impl fmt::Display for Group {
410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411 self.stream.fmt(f)
412 }
413}
414
David Tolnay034205f2018-04-22 16:45:28 -0700415impl fmt::Debug for Group {
416 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
417 let mut debug = fmt.debug_struct("Group");
418 debug.field("delimiter", &self.delimiter);
419 debug.field("stream", &self.stream);
420 #[cfg(procmacro2_semver_exempt)]
421 debug.field("span", &self.span);
422 debug.finish()
423 }
424}
425
Alex Crichtonf3888432018-05-16 09:11:05 -0700426#[derive(Clone)]
427pub struct Punct {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700428 op: char,
429 spacing: Spacing,
430 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700431}
432
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200433#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700434pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700435 Alone,
436 Joint,
437}
438
Alex Crichtonf3888432018-05-16 09:11:05 -0700439impl Punct {
440 pub fn new(op: char, spacing: Spacing) -> Punct {
441 Punct {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700442 op: op,
443 spacing: spacing,
444 span: Span::call_site(),
445 }
446 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700447
Alex Crichtonf3888432018-05-16 09:11:05 -0700448 pub fn as_char(&self) -> char {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700449 self.op
450 }
451
452 pub fn spacing(&self) -> Spacing {
453 self.spacing
454 }
455
456 pub fn span(&self) -> Span {
457 self.span
458 }
459
460 pub fn set_span(&mut self, span: Span) {
461 self.span = span;
462 }
463}
464
Alex Crichtonf3888432018-05-16 09:11:05 -0700465impl fmt::Display for Punct {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700466 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
467 self.op.fmt(f)
468 }
469}
470
Alex Crichtonf3888432018-05-16 09:11:05 -0700471impl fmt::Debug for Punct {
David Tolnay034205f2018-04-22 16:45:28 -0700472 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonf3888432018-05-16 09:11:05 -0700473 let mut debug = fmt.debug_struct("Punct");
David Tolnay034205f2018-04-22 16:45:28 -0700474 debug.field("op", &self.op);
475 debug.field("spacing", &self.spacing);
476 #[cfg(procmacro2_semver_exempt)]
477 debug.field("span", &self.span);
478 debug.finish()
479 }
480}
481
Alex Crichtonf3888432018-05-16 09:11:05 -0700482#[derive(Clone)]
483pub struct Ident {
484 inner: imp::Ident,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700485 _marker: marker::PhantomData<Rc<()>>,
486}
487
Alex Crichtonf3888432018-05-16 09:11:05 -0700488impl Ident {
489 fn _new(inner: imp::Ident) -> Ident {
490 Ident {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700491 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700492 _marker: marker::PhantomData,
493 }
494 }
495
Alex Crichtonf3888432018-05-16 09:11:05 -0700496 pub fn new(string: &str, span: Span) -> Ident {
497 Ident::_new(imp::Ident::new(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700498 }
499
Alex Crichtonf3888432018-05-16 09:11:05 -0700500 #[cfg(procmacro2_semver_exempt)]
501 pub fn new_raw(string: &str, span: Span) -> Ident {
502 Ident::_new_raw(string, span)
503 }
504
505 fn _new_raw(string: &str, span: Span) -> Ident {
506 Ident::_new(imp::Ident::new_raw(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700507 }
508
509 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700510 Span::_new(self.inner.span())
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700511 }
512
513 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700514 self.inner.set_span(span.inner);
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700515 }
516}
517
Alex Crichtonf3888432018-05-16 09:11:05 -0700518impl PartialEq for Ident {
David Tolnay3d9d6ad2018-05-18 10:51:55 -0700519 fn eq(&self, other: &Ident) -> bool {
Alex Crichtonf3888432018-05-16 09:11:05 -0700520 self.to_string() == other.to_string()
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700521 }
522}
523
David Tolnayc0bbcc52018-05-18 10:51:04 -0700524impl<T> PartialEq<T> for Ident
525where
526 T: ?Sized + AsRef<str>,
527{
528 fn eq(&self, other: &T) -> bool {
529 self.to_string() == other.as_ref()
530 }
531}
532
David Tolnay3d9d6ad2018-05-18 10:51:55 -0700533impl Eq for Ident {}
Alex Crichtonf3888432018-05-16 09:11:05 -0700534
535impl PartialOrd for Ident {
536 fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
537 Some(self.cmp(other))
538 }
539}
540
541impl Ord for Ident {
542 fn cmp(&self, other: &Ident) -> Ordering {
543 self.to_string().cmp(&other.to_string())
544 }
545}
546
547impl Hash for Ident {
548 fn hash<H: Hasher>(&self, hasher: &mut H) {
549 self.to_string().hash(hasher)
550 }
551}
552
553impl fmt::Display for Ident {
554 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
555 self.inner.fmt(f)
556 }
557}
558
559impl fmt::Debug for Ident {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700560 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
561 self.inner.fmt(f)
562 }
563}
564
565#[derive(Clone)]
566pub struct Literal {
567 inner: imp::Literal,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700568 _marker: marker::PhantomData<Rc<()>>,
569}
570
Alex Crichtona914a612018-04-04 07:48:44 -0700571macro_rules! int_literals {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700572 ($($name:ident => $kind:ident,)*) => ($(
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700573 pub fn $name(n: $kind) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700574 Literal::_new(imp::Literal::$name(n))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700575 }
576 )*)
577}
578
Alex Crichton852d53d2017-05-19 19:25:08 -0700579impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700580 fn _new(inner: imp::Literal) -> Literal {
581 Literal {
582 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700583 _marker: marker::PhantomData,
584 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700585 }
586
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700587 fn _new_stable(inner: stable::Literal) -> Literal {
588 Literal {
589 inner: inner.into(),
590 _marker: marker::PhantomData,
591 }
592 }
593
Alex Crichtona914a612018-04-04 07:48:44 -0700594 int_literals! {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700595 u8_suffixed => u8,
596 u16_suffixed => u16,
597 u32_suffixed => u32,
598 u64_suffixed => u64,
599 usize_suffixed => usize,
600 i8_suffixed => i8,
601 i16_suffixed => i16,
602 i32_suffixed => i32,
603 i64_suffixed => i64,
604 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700605
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700606 u8_unsuffixed => u8,
607 u16_unsuffixed => u16,
608 u32_unsuffixed => u32,
609 u64_unsuffixed => u64,
610 usize_unsuffixed => usize,
611 i8_unsuffixed => i8,
612 i16_unsuffixed => i16,
613 i32_unsuffixed => i32,
614 i64_unsuffixed => i64,
615 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700616 }
617
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700618 pub fn f64_unsuffixed(f: f64) -> Literal {
619 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700620 Literal::_new(imp::Literal::f64_unsuffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700621 }
622
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700623 pub fn f64_suffixed(f: f64) -> Literal {
624 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700625 Literal::_new(imp::Literal::f64_suffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700626 }
627
628 pub fn f32_unsuffixed(f: f32) -> Literal {
629 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700630 Literal::_new(imp::Literal::f32_unsuffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700631 }
632
633 pub fn f32_suffixed(f: f32) -> Literal {
634 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700635 Literal::_new(imp::Literal::f32_suffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700636 }
637
638 pub fn string(string: &str) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700639 Literal::_new(imp::Literal::string(string))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700640 }
641
642 pub fn character(ch: char) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700643 Literal::_new(imp::Literal::character(ch))
Alex Crichton76a5cc82017-05-23 07:01:44 -0700644 }
645
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700646 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700647 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700648 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700649
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700650 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700651 Span::_new(self.inner.span())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700652 }
653
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700654 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700655 self.inner.set_span(span.inner);
Alex Crichton31316622017-05-26 12:54:47 -0700656 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700657}
658
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700659impl fmt::Debug for Literal {
660 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
661 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700662 }
663}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700664
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700665impl fmt::Display for Literal {
666 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
667 self.inner.fmt(f)
668 }
669}
670
671pub mod token_stream {
672 use std::fmt;
673 use std::marker;
674 use std::rc::Rc;
675
David Tolnay48ea5042018-04-23 19:17:35 -0700676 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700677 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200678 use TokenTree;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700679
680 pub struct IntoIter {
681 inner: imp::TokenTreeIter,
682 _marker: marker::PhantomData<Rc<()>>,
683 }
684
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700685 impl Iterator for IntoIter {
686 type Item = TokenTree;
687
688 fn next(&mut self) -> Option<TokenTree> {
689 self.inner.next()
690 }
691 }
692
693 impl fmt::Debug for IntoIter {
694 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
695 self.inner.fmt(f)
696 }
697 }
698
699 impl IntoIterator for TokenStream {
700 type Item = TokenTree;
701 type IntoIter = IntoIter;
702
703 fn into_iter(self) -> IntoIter {
704 IntoIter {
705 inner: self.inner.into_iter(),
706 _marker: marker::PhantomData,
707 }
708 }
709 }
710}