blob: 49d1d2c4a1e010be91f662cce3a115382ff2c41f [file] [log] [blame]
Alex Crichtonaf5bad42018-03-27 14:45:10 -07001#![allow(dead_code)]
2
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07003use std::ascii;
4use std::fmt;
5use std::iter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07006use std::str::FromStr;
7
8use proc_macro;
9
David Tolnayb28f38a2018-03-31 22:02:29 +020010use {Delimiter, Group, Op, Spacing, TokenTree};
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070011
12#[derive(Clone)]
13pub struct TokenStream(proc_macro::TokenStream);
14
15pub struct LexError(proc_macro::LexError);
16
17impl TokenStream {
18 pub fn empty() -> TokenStream {
19 TokenStream(proc_macro::TokenStream::empty())
20 }
21
22 pub fn is_empty(&self) -> bool {
23 self.0.is_empty()
24 }
25}
26
27impl FromStr for TokenStream {
28 type Err = LexError;
29
30 fn from_str(src: &str) -> Result<TokenStream, LexError> {
31 Ok(TokenStream(src.parse().map_err(LexError)?))
32 }
33}
34
35impl fmt::Display for TokenStream {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 self.0.fmt(f)
38 }
39}
40
41impl From<proc_macro::TokenStream> for TokenStream {
42 fn from(inner: proc_macro::TokenStream) -> TokenStream {
43 TokenStream(inner)
44 }
45}
46
47impl From<TokenStream> for proc_macro::TokenStream {
48 fn from(inner: TokenStream) -> proc_macro::TokenStream {
49 inner.0
50 }
51}
52
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070053impl From<TokenTree> for TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -070054 fn from(token: TokenTree) -> TokenStream {
55 let (span, kind) = match token {
56 TokenTree::Group(tt) => {
57 let delim = match tt.delimiter() {
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 };
63 let span = tt.span();
64 let group = proc_macro::TokenNode::Group(delim, tt.stream.inner.0);
65 (span, group)
66 }
67 TokenTree::Op(tt) => {
68 let kind = match tt.spacing() {
69 Spacing::Joint => proc_macro::Spacing::Joint,
70 Spacing::Alone => proc_macro::Spacing::Alone,
71 };
72 (tt.span(), proc_macro::TokenNode::Op(tt.op(), kind))
73 }
David Tolnayb28f38a2018-03-31 22:02:29 +020074 TokenTree::Term(tt) => (tt.span(), proc_macro::TokenNode::Term(tt.inner.0)),
75 TokenTree::Literal(tt) => (tt.span(), proc_macro::TokenNode::Literal(tt.inner.0)),
Alex Crichtonaf5bad42018-03-27 14:45:10 -070076 };
David Tolnayb28f38a2018-03-31 22:02:29 +020077 TokenStream(
78 proc_macro::TokenTree {
79 span: span.inner.0,
80 kind,
81 }.into(),
82 )
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070083 }
84}
85
Alex Crichtonaf5bad42018-03-27 14:45:10 -070086impl iter::FromIterator<TokenTree> for TokenStream {
David Tolnayb28f38a2018-03-31 22:02:29 +020087 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
Alex Crichtonaf5bad42018-03-27 14:45:10 -070088 let streams = streams.into_iter().map(TokenStream::from);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070089 TokenStream(streams.collect::<proc_macro::TokenStream>())
90 }
91}
92
93impl fmt::Debug for TokenStream {
94 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -070095 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070096 }
97}
98
99impl fmt::Debug for LexError {
100 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700101 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700102 }
103}
104
Alex Crichton1a7f7622017-07-05 17:47:15 -0700105pub struct TokenTreeIter(proc_macro::TokenTreeIter);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700106
107impl IntoIterator for TokenStream {
108 type Item = TokenTree;
Alex Crichton1a7f7622017-07-05 17:47:15 -0700109 type IntoIter = TokenTreeIter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700110
Alex Crichton1a7f7622017-07-05 17:47:15 -0700111 fn into_iter(self) -> TokenTreeIter {
112 TokenTreeIter(self.0.into_iter())
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700113 }
114}
115
Alex Crichton1a7f7622017-07-05 17:47:15 -0700116impl Iterator for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700117 type Item = TokenTree;
118
119 fn next(&mut self) -> Option<TokenTree> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700120 let token = self.0.next()?;
121 let span = ::Span::_new(Span(token.span));
122 Some(match token.kind {
123 proc_macro::TokenNode::Group(delim, s) => {
124 let delim = match delim {
125 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
126 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
127 proc_macro::Delimiter::Brace => Delimiter::Brace,
128 proc_macro::Delimiter::None => Delimiter::None,
129 };
130 let stream = ::TokenStream::_new(TokenStream(s));
131 let mut g = Group::new(delim, stream);
132 g.set_span(span);
133 g.into()
134 }
135 proc_macro::TokenNode::Op(ch, kind) => {
136 let kind = match kind {
137 proc_macro::Spacing::Joint => Spacing::Joint,
138 proc_macro::Spacing::Alone => Spacing::Alone,
139 };
140 let mut o = Op::new(ch, kind);
141 o.span = span;
142 o.into()
143 }
David Tolnayb28f38a2018-03-31 22:02:29 +0200144 proc_macro::TokenNode::Term(s) => ::Term::_new(Term(s), span).into(),
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700145 proc_macro::TokenNode::Literal(l) => {
146 let mut l = ::Literal::_new(Literal(l));
147 l.span = span;
148 l.into()
149 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700150 })
151 }
152
153 fn size_hint(&self) -> (usize, Option<usize>) {
154 self.0.size_hint()
155 }
156}
157
Alex Crichton1a7f7622017-07-05 17:47:15 -0700158impl fmt::Debug for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700160 f.debug_struct("TokenTreeIter").finish()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700161 }
162}
163
Nika Layzellf8d5f212017-12-11 14:07:02 -0500164#[derive(Clone, PartialEq, Eq)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500165pub struct FileName(String);
166
167impl fmt::Display for FileName {
168 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169 self.0.fmt(f)
170 }
171}
172
173// NOTE: We have to generate our own filename object here because we can't wrap
174// the one provided by proc_macro.
175#[derive(Clone, PartialEq, Eq)]
176pub struct SourceFile(proc_macro::SourceFile, FileName);
Nika Layzellf8d5f212017-12-11 14:07:02 -0500177
178impl SourceFile {
Nika Layzellb35a9a32017-12-30 14:34:35 -0500179 fn new(sf: proc_macro::SourceFile) -> Self {
180 let filename = FileName(sf.path().to_string());
181 SourceFile(sf, filename)
182 }
183
Nika Layzellf8d5f212017-12-11 14:07:02 -0500184 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500185 pub fn path(&self) -> &FileName {
186 &self.1
Nika Layzellf8d5f212017-12-11 14:07:02 -0500187 }
188
189 pub fn is_real(&self) -> bool {
190 self.0.is_real()
191 }
192}
193
Nika Layzellb35a9a32017-12-30 14:34:35 -0500194impl AsRef<FileName> for SourceFile {
195 fn as_ref(&self) -> &FileName {
196 self.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500197 }
198}
199
200impl fmt::Debug for SourceFile {
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 self.0.fmt(f)
203 }
204}
205
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500206pub struct LineColumn {
207 pub line: usize,
208 pub column: usize,
209}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500210
Nika Layzell99737982018-03-11 18:51:27 -0400211#[derive(Copy, Clone, PartialEq, Eq)]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700212pub struct Span(proc_macro::Span);
213
Sergio Benitez13805082018-01-04 01:25:45 -0800214impl From<proc_macro::Span> for ::Span {
215 fn from(proc_span: proc_macro::Span) -> ::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700216 ::Span::_new(Span(proc_span))
Sergio Benitez13805082018-01-04 01:25:45 -0800217 }
218}
219
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700220impl Span {
221 pub fn call_site() -> Span {
222 Span(proc_macro::Span::call_site())
223 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700224
Alex Crichtone6085b72017-11-21 07:24:25 -0800225 pub fn def_site() -> Span {
Alex Crichton998f6422017-11-19 08:06:27 -0800226 Span(proc_macro::Span::def_site())
227 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500228
David Tolnay4e8e3972018-01-05 18:10:22 -0800229 pub fn resolved_at(&self, other: Span) -> Span {
230 Span(self.0.resolved_at(other.0))
231 }
232
233 pub fn located_at(&self, other: Span) -> Span {
234 Span(self.0.located_at(other.0))
235 }
236
David Tolnay16a17202017-12-31 10:47:24 -0500237 pub fn unstable(self) -> proc_macro::Span {
238 self.0
239 }
240
Nika Layzellf8d5f212017-12-11 14:07:02 -0500241 pub fn source_file(&self) -> SourceFile {
Nika Layzellb35a9a32017-12-30 14:34:35 -0500242 SourceFile::new(self.0.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500243 }
244
245 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200246 let proc_macro::LineColumn { line, column } = self.0.start();
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500247 LineColumn { line, column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500248 }
249
250 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200251 let proc_macro::LineColumn { line, column } = self.0.end();
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500252 LineColumn { line, column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500253 }
254
255 pub fn join(&self, other: Span) -> Option<Span> {
256 self.0.join(other.0).map(Span)
257 }
Alex Crichton998f6422017-11-19 08:06:27 -0800258}
259
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700260impl fmt::Debug for Span {
261 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700262 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700263 }
264}
265
266#[derive(Copy, Clone)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700267pub struct Term(proc_macro::Term);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700268
David Tolnay10effeb2018-01-06 11:07:49 -0800269impl Term {
270 pub fn intern(string: &str) -> Term {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700271 Term(proc_macro::Term::intern(string))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700272 }
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700273
David Tolnay10effeb2018-01-06 11:07:49 -0800274 pub fn as_str(&self) -> &str {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700275 self.0.as_str()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700276 }
277}
278
Alex Crichton1a7f7622017-07-05 17:47:15 -0700279impl fmt::Debug for Term {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700280 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700281 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700282 }
283}
284
285#[derive(Clone)]
286pub struct Literal(proc_macro::Literal);
287
288impl Literal {
289 pub fn byte_char(byte: u8) -> Literal {
290 match byte {
291 0 => Literal(to_literal("b'\\0'")),
292 b'\"' => Literal(to_literal("b'\"'")),
293 n => {
294 let mut escaped = "b'".to_string();
295 escaped.extend(ascii::escape_default(n).map(|c| c as char));
296 escaped.push('\'');
297 Literal(to_literal(&escaped))
298 }
299 }
300 }
301
302 pub fn byte_string(bytes: &[u8]) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700303 Literal(proc_macro::Literal::byte_string(bytes))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700304 }
305
306 pub fn doccomment(s: &str) -> Literal {
307 Literal(to_literal(s))
308 }
309
Alex Crichton1a7f7622017-07-05 17:47:15 -0700310 pub fn float(s: f64) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700311 Literal(proc_macro::Literal::float(s))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700312 }
313
Alex Crichton1a7f7622017-07-05 17:47:15 -0700314 pub fn integer(s: i64) -> Literal {
Alex Crichton040be632017-07-05 17:56:48 -0700315 Literal(proc_macro::Literal::integer(s.into()))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700316 }
317
318 pub fn raw_string(s: &str, pounds: usize) -> Literal {
319 let mut ret = format!("r");
320 ret.extend((0..pounds).map(|_| "#"));
321 ret.push('"');
322 ret.push_str(s);
323 ret.push('"');
324 ret.extend((0..pounds).map(|_| "#"));
325 Literal(to_literal(&ret))
326 }
327
328 pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
329 let mut ret = format!("br");
330 ret.extend((0..pounds).map(|_| "#"));
331 ret.push('"');
332 ret.push_str(s);
333 ret.push('"');
334 ret.extend((0..pounds).map(|_| "#"));
335 Literal(to_literal(&ret))
336 }
337}
338
339impl fmt::Display for Literal {
340 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 self.0.fmt(f)
342 }
343}
344
345impl fmt::Debug for Literal {
346 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton040be632017-07-05 17:56:48 -0700347 self.0.fmt(f)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700348 }
349}
350
351fn to_literal(s: &str) -> proc_macro::Literal {
352 let stream = s.parse::<proc_macro::TokenStream>().unwrap();
353 match stream.into_iter().next().unwrap().kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700354 proc_macro::TokenNode::Literal(l) => l,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700355 _ => unreachable!(),
356 }
357}
358
359macro_rules! ints {
Alex Crichton040be632017-07-05 17:56:48 -0700360 ($($t:ident,)*) => {$(
361 impl From<$t> for Literal {
362 fn from(t: $t) -> Literal {
363 Literal(proc_macro::Literal::$t(t))
364 }
365 }
366 )*}
367}
368
369ints! {
Alex Crichton6e81d762017-07-14 06:09:31 -0700370 u8, u16, u32, u64, usize,
371 i8, i16, i32, i64, isize,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700372}
373
374macro_rules! floats {
375 ($($t:ident,)*) => {$(
376 impl From<$t> for Literal {
377 fn from(t: $t) -> Literal {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700378 Literal(proc_macro::Literal::$t(t))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700379 }
380 }
381 )*}
382}
383
384floats! {
385 f32, f64,
386}
387
388impl<'a> From<&'a str> for Literal {
389 fn from(t: &'a str) -> Literal {
390 Literal(proc_macro::Literal::string(t))
391 }
392}
393
394impl From<char> for Literal {
395 fn from(t: char) -> Literal {
396 Literal(proc_macro::Literal::character(t))
397 }
398}