blob: 6f9719778c2a26354453f2a94b1fcd1dcdf5e0a1 [file] [log] [blame]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07001use std::ascii;
2use std::fmt;
3use std::iter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07004use std::str::FromStr;
5
6use proc_macro;
7
Alex Crichton1a7f7622017-07-05 17:47:15 -07008use {TokenTree, TokenNode, Delimiter, Spacing};
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07009
10#[derive(Clone)]
11pub struct TokenStream(proc_macro::TokenStream);
12
13pub struct LexError(proc_macro::LexError);
14
15impl TokenStream {
16 pub fn empty() -> TokenStream {
17 TokenStream(proc_macro::TokenStream::empty())
18 }
19
20 pub fn is_empty(&self) -> bool {
21 self.0.is_empty()
22 }
23}
24
25impl FromStr for TokenStream {
26 type Err = LexError;
27
28 fn from_str(src: &str) -> Result<TokenStream, LexError> {
29 Ok(TokenStream(src.parse().map_err(LexError)?))
30 }
31}
32
33impl fmt::Display for TokenStream {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 self.0.fmt(f)
36 }
37}
38
39impl From<proc_macro::TokenStream> for TokenStream {
40 fn from(inner: proc_macro::TokenStream) -> TokenStream {
41 TokenStream(inner)
42 }
43}
44
45impl From<TokenStream> for proc_macro::TokenStream {
46 fn from(inner: TokenStream) -> proc_macro::TokenStream {
47 inner.0
48 }
49}
50
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070051impl From<TokenTree> for TokenStream {
52 fn from(tree: TokenTree) -> TokenStream {
53 TokenStream(proc_macro::TokenTree {
54 span: (tree.span.0).0,
55 kind: match tree.kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -070056 TokenNode::Group(delim, s) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070057 let delim = match delim {
58 Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
59 Delimiter::Bracket => proc_macro::Delimiter::Bracket,
60 Delimiter::Brace => proc_macro::Delimiter::Brace,
61 Delimiter::None => proc_macro::Delimiter::None,
62 };
Alex Crichton1a7f7622017-07-05 17:47:15 -070063 proc_macro::TokenNode::Group(delim, (s.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070064 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070065 TokenNode::Op(ch, kind) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070066 let kind = match kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -070067 Spacing::Joint => proc_macro::Spacing::Joint,
68 Spacing::Alone => proc_macro::Spacing::Alone,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070069 };
Alex Crichton1a7f7622017-07-05 17:47:15 -070070 proc_macro::TokenNode::Op(ch, kind)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070071 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070072 TokenNode::Term(s) => {
73 proc_macro::TokenNode::Term((s.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070074 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070075 TokenNode::Literal(l) => {
76 proc_macro::TokenNode::Literal((l.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070077 }
78 },
79 }.into())
80 }
81}
82
83impl iter::FromIterator<TokenStream> for TokenStream {
84 fn from_iter<I: IntoIterator<Item=TokenStream>>(streams: I) -> Self {
85 let streams = streams.into_iter().map(|s| s.0);
86 TokenStream(streams.collect::<proc_macro::TokenStream>())
87 }
88}
89
90impl fmt::Debug for TokenStream {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -070092 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070093 }
94}
95
96impl fmt::Debug for LexError {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -070098 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070099 }
100}
101
Alex Crichton1a7f7622017-07-05 17:47:15 -0700102pub struct TokenTreeIter(proc_macro::TokenTreeIter);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700103
104impl IntoIterator for TokenStream {
105 type Item = TokenTree;
Alex Crichton1a7f7622017-07-05 17:47:15 -0700106 type IntoIter = TokenTreeIter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700107
Alex Crichton1a7f7622017-07-05 17:47:15 -0700108 fn into_iter(self) -> TokenTreeIter {
109 TokenTreeIter(self.0.into_iter())
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700110 }
111}
112
Alex Crichton1a7f7622017-07-05 17:47:15 -0700113impl Iterator for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700114 type Item = TokenTree;
115
116 fn next(&mut self) -> Option<TokenTree> {
117 let token = match self.0.next() {
118 Some(n) => n,
119 None => return None,
120 };
121 Some(TokenTree {
122 span: ::Span(Span(token.span)),
123 kind: match token.kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700124 proc_macro::TokenNode::Group(delim, s) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700125 let delim = match delim {
126 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
127 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
128 proc_macro::Delimiter::Brace => Delimiter::Brace,
129 proc_macro::Delimiter::None => Delimiter::None,
130 };
Alex Crichton1a7f7622017-07-05 17:47:15 -0700131 TokenNode::Group(delim, ::TokenStream(TokenStream(s)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700132 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700133 proc_macro::TokenNode::Op(ch, kind) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700134 let kind = match kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700135 proc_macro::Spacing::Joint => Spacing::Joint,
136 proc_macro::Spacing::Alone => Spacing::Alone,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700137 };
Alex Crichton1a7f7622017-07-05 17:47:15 -0700138 TokenNode::Op(ch, kind)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700139 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700140 proc_macro::TokenNode::Term(s) => {
141 TokenNode::Term(::Term(Term(s)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700142 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700143 proc_macro::TokenNode::Literal(l) => {
144 TokenNode::Literal(::Literal(Literal(l)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700145 }
146 },
147 })
148 }
149
150 fn size_hint(&self) -> (usize, Option<usize>) {
151 self.0.size_hint()
152 }
153}
154
Alex Crichton1a7f7622017-07-05 17:47:15 -0700155impl fmt::Debug for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700157 f.debug_struct("TokenTreeIter").finish()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700158 }
159}
160
David Tolnay1ebe3972018-01-02 20:14:20 -0800161#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500162#[derive(Clone, PartialEq, Eq)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500163pub struct FileName(String);
164
David Tolnay1ebe3972018-01-02 20:14:20 -0800165#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500166impl fmt::Display for FileName {
167 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
168 self.0.fmt(f)
169 }
170}
171
172// NOTE: We have to generate our own filename object here because we can't wrap
173// the one provided by proc_macro.
David Tolnay1ebe3972018-01-02 20:14:20 -0800174#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500175#[derive(Clone, PartialEq, Eq)]
176pub struct SourceFile(proc_macro::SourceFile, FileName);
Nika Layzellf8d5f212017-12-11 14:07:02 -0500177
David Tolnay1ebe3972018-01-02 20:14:20 -0800178#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500179impl SourceFile {
Nika Layzellb35a9a32017-12-30 14:34:35 -0500180 fn new(sf: proc_macro::SourceFile) -> Self {
181 let filename = FileName(sf.path().to_string());
182 SourceFile(sf, filename)
183 }
184
Nika Layzellf8d5f212017-12-11 14:07:02 -0500185 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500186 pub fn path(&self) -> &FileName {
187 &self.1
Nika Layzellf8d5f212017-12-11 14:07:02 -0500188 }
189
190 pub fn is_real(&self) -> bool {
191 self.0.is_real()
192 }
193}
194
David Tolnay1ebe3972018-01-02 20:14:20 -0800195#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500196impl AsRef<FileName> for SourceFile {
197 fn as_ref(&self) -> &FileName {
198 self.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500199 }
200}
201
David Tolnay1ebe3972018-01-02 20:14:20 -0800202#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500203impl fmt::Debug for SourceFile {
204 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
205 self.0.fmt(f)
206 }
207}
208
David Tolnay1ebe3972018-01-02 20:14:20 -0800209#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500210pub struct LineColumn {
211 pub line: usize,
212 pub column: usize,
213}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500214
Nika Layzell99737982018-03-11 18:51:27 -0400215#[derive(Copy, Clone, PartialEq, Eq)]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700216pub struct Span(proc_macro::Span);
217
Sergio Benitez13805082018-01-04 01:25:45 -0800218impl From<proc_macro::Span> for ::Span {
219 fn from(proc_span: proc_macro::Span) -> ::Span {
220 ::Span(Span(proc_span))
221 }
222}
223
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700224impl Span {
225 pub fn call_site() -> Span {
226 Span(proc_macro::Span::call_site())
227 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700228
Alex Crichtone6085b72017-11-21 07:24:25 -0800229 pub fn def_site() -> Span {
Alex Crichton998f6422017-11-19 08:06:27 -0800230 Span(proc_macro::Span::def_site())
231 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500232
David Tolnay4e8e3972018-01-05 18:10:22 -0800233 pub fn resolved_at(&self, other: Span) -> Span {
234 Span(self.0.resolved_at(other.0))
235 }
236
237 pub fn located_at(&self, other: Span) -> Span {
238 Span(self.0.located_at(other.0))
239 }
240
David Tolnay16a17202017-12-31 10:47:24 -0500241 pub fn unstable(self) -> proc_macro::Span {
242 self.0
243 }
244
David Tolnay1ebe3972018-01-02 20:14:20 -0800245 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500246 pub fn source_file(&self) -> SourceFile {
Nika Layzellb35a9a32017-12-30 14:34:35 -0500247 SourceFile::new(self.0.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500248 }
249
David Tolnay1ebe3972018-01-02 20:14:20 -0800250 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500251 pub fn start(&self) -> LineColumn {
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500252 let proc_macro::LineColumn{ line, column } = self.0.start();
253 LineColumn { line, column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500254 }
255
David Tolnay1ebe3972018-01-02 20:14:20 -0800256 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500257 pub fn end(&self) -> LineColumn {
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500258 let proc_macro::LineColumn{ line, column } = self.0.end();
259 LineColumn { line, column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500260 }
261
David Tolnay1ebe3972018-01-02 20:14:20 -0800262 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500263 pub fn join(&self, other: Span) -> Option<Span> {
264 self.0.join(other.0).map(Span)
265 }
Alex Crichton998f6422017-11-19 08:06:27 -0800266}
267
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700268impl fmt::Debug for Span {
269 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700270 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700271 }
272}
273
274#[derive(Copy, Clone)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700275pub struct Term(proc_macro::Term);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700276
David Tolnay10effeb2018-01-06 11:07:49 -0800277impl Term {
278 pub fn intern(string: &str) -> Term {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700279 Term(proc_macro::Term::intern(string))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700280 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700281
David Tolnay10effeb2018-01-06 11:07:49 -0800282 pub fn as_str(&self) -> &str {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700283 self.0.as_str()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700284 }
285}
286
Alex Crichton1a7f7622017-07-05 17:47:15 -0700287impl fmt::Debug for Term {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700288 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700289 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700290 }
291}
292
293#[derive(Clone)]
294pub struct Literal(proc_macro::Literal);
295
296impl Literal {
297 pub fn byte_char(byte: u8) -> Literal {
298 match byte {
299 0 => Literal(to_literal("b'\\0'")),
300 b'\"' => Literal(to_literal("b'\"'")),
301 n => {
302 let mut escaped = "b'".to_string();
303 escaped.extend(ascii::escape_default(n).map(|c| c as char));
304 escaped.push('\'');
305 Literal(to_literal(&escaped))
306 }
307 }
308 }
309
310 pub fn byte_string(bytes: &[u8]) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700311 Literal(proc_macro::Literal::byte_string(bytes))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700312 }
313
314 pub fn doccomment(s: &str) -> Literal {
315 Literal(to_literal(s))
316 }
317
Alex Crichton1a7f7622017-07-05 17:47:15 -0700318 pub fn float(s: f64) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700319 Literal(proc_macro::Literal::float(s))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700320 }
321
Alex Crichton1a7f7622017-07-05 17:47:15 -0700322 pub fn integer(s: i64) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700323 Literal(proc_macro::Literal::integer(s.into()))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700324 }
325
326 pub fn raw_string(s: &str, pounds: usize) -> Literal {
327 let mut ret = format!("r");
328 ret.extend((0..pounds).map(|_| "#"));
329 ret.push('"');
330 ret.push_str(s);
331 ret.push('"');
332 ret.extend((0..pounds).map(|_| "#"));
333 Literal(to_literal(&ret))
334 }
335
336 pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
337 let mut ret = format!("br");
338 ret.extend((0..pounds).map(|_| "#"));
339 ret.push('"');
340 ret.push_str(s);
341 ret.push('"');
342 ret.extend((0..pounds).map(|_| "#"));
343 Literal(to_literal(&ret))
344 }
345}
346
347impl fmt::Display for Literal {
348 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
349 self.0.fmt(f)
350 }
351}
352
353impl fmt::Debug for Literal {
354 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700355 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700356 }
357}
358
359fn to_literal(s: &str) -> proc_macro::Literal {
360 let stream = s.parse::<proc_macro::TokenStream>().unwrap();
361 match stream.into_iter().next().unwrap().kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700362 proc_macro::TokenNode::Literal(l) => l,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700363 _ => unreachable!(),
364 }
365}
366
367macro_rules! ints {
Alex Crichton040be632017-07-05 17:56:48 -0700368 ($($t:ident,)*) => {$(
369 impl From<$t> for Literal {
370 fn from(t: $t) -> Literal {
371 Literal(proc_macro::Literal::$t(t))
372 }
373 }
374 )*}
375}
376
377ints! {
Alex Crichton6e81d762017-07-14 06:09:31 -0700378 u8, u16, u32, u64, usize,
379 i8, i16, i32, i64, isize,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700380}
381
382macro_rules! floats {
383 ($($t:ident,)*) => {$(
384 impl From<$t> for Literal {
385 fn from(t: $t) -> Literal {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700386 Literal(proc_macro::Literal::$t(t))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700387 }
388 }
389 )*}
390}
391
392floats! {
393 f32, f64,
394}
395
396impl<'a> From<&'a str> for Literal {
397 fn from(t: &'a str) -> Literal {
398 Literal(proc_macro::Literal::string(t))
399 }
400}
401
402impl From<char> for Literal {
403 fn from(t: char) -> Literal {
404 Literal(proc_macro::Literal::character(t))
405 }
406}