1 | use crate::detection::inside_proc_macro; |
2 | #[cfg (span_locations)] |
3 | use crate::location::LineColumn; |
4 | use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; |
5 | use core::fmt::{self, Debug, Display}; |
6 | use core::iter::FromIterator; |
7 | use core::ops::RangeBounds; |
8 | use core::str::FromStr; |
9 | use std::panic; |
10 | #[cfg (super_unstable)] |
11 | use std::path::PathBuf; |
12 | |
13 | #[derive (Clone)] |
14 | pub(crate) enum TokenStream { |
15 | Compiler(DeferredTokenStream), |
16 | Fallback(fallback::TokenStream), |
17 | } |
18 | |
19 | // Work around https://github.com/rust-lang/rust/issues/65080. |
20 | // In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote, |
21 | // we hold on to the appended tokens and do proc_macro::TokenStream::extend as |
22 | // late as possible to batch together consecutive uses of the Extend impl. |
23 | #[derive (Clone)] |
24 | pub(crate) struct DeferredTokenStream { |
25 | stream: proc_macro::TokenStream, |
26 | extra: Vec<proc_macro::TokenTree>, |
27 | } |
28 | |
29 | pub(crate) enum LexError { |
30 | Compiler(proc_macro::LexError), |
31 | Fallback(fallback::LexError), |
32 | } |
33 | |
34 | impl LexError { |
35 | fn call_site() -> Self { |
36 | LexError::Fallback(fallback::LexError { |
37 | span: fallback::Span::call_site(), |
38 | }) |
39 | } |
40 | } |
41 | |
42 | fn mismatch() -> ! { |
43 | panic!("compiler/fallback mismatch" ) |
44 | } |
45 | |
46 | impl DeferredTokenStream { |
47 | fn new(stream: proc_macro::TokenStream) -> Self { |
48 | DeferredTokenStream { |
49 | stream, |
50 | extra: Vec::new(), |
51 | } |
52 | } |
53 | |
54 | fn is_empty(&self) -> bool { |
55 | self.stream.is_empty() && self.extra.is_empty() |
56 | } |
57 | |
58 | fn evaluate_now(&mut self) { |
59 | // If-check provides a fast short circuit for the common case of `extra` |
60 | // being empty, which saves a round trip over the proc macro bridge. |
61 | // Improves macro expansion time in winrt by 6% in debug mode. |
62 | if !self.extra.is_empty() { |
63 | self.stream.extend(self.extra.drain(..)); |
64 | } |
65 | } |
66 | |
67 | fn into_token_stream(mut self) -> proc_macro::TokenStream { |
68 | self.evaluate_now(); |
69 | self.stream |
70 | } |
71 | } |
72 | |
73 | impl TokenStream { |
74 | pub fn new() -> Self { |
75 | if inside_proc_macro() { |
76 | TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) |
77 | } else { |
78 | TokenStream::Fallback(fallback::TokenStream::new()) |
79 | } |
80 | } |
81 | |
82 | pub fn is_empty(&self) -> bool { |
83 | match self { |
84 | TokenStream::Compiler(tts) => tts.is_empty(), |
85 | TokenStream::Fallback(tts) => tts.is_empty(), |
86 | } |
87 | } |
88 | |
89 | fn unwrap_nightly(self) -> proc_macro::TokenStream { |
90 | match self { |
91 | TokenStream::Compiler(s) => s.into_token_stream(), |
92 | TokenStream::Fallback(_) => mismatch(), |
93 | } |
94 | } |
95 | |
96 | fn unwrap_stable(self) -> fallback::TokenStream { |
97 | match self { |
98 | TokenStream::Compiler(_) => mismatch(), |
99 | TokenStream::Fallback(s) => s, |
100 | } |
101 | } |
102 | } |
103 | |
104 | impl FromStr for TokenStream { |
105 | type Err = LexError; |
106 | |
107 | fn from_str(src: &str) -> Result<TokenStream, LexError> { |
108 | if inside_proc_macro() { |
109 | Ok(TokenStream::Compiler(DeferredTokenStream::new( |
110 | stream:proc_macro_parse(src)?, |
111 | ))) |
112 | } else { |
113 | Ok(TokenStream::Fallback(src.parse()?)) |
114 | } |
115 | } |
116 | } |
117 | |
118 | // Work around https://github.com/rust-lang/rust/issues/58736. |
119 | fn proc_macro_parse(src: &str) -> Result<proc_macro::TokenStream, LexError> { |
120 | let result: Result, …> = panic::catch_unwind(|| src.parse().map_err(op:LexError::Compiler)); |
121 | result.unwrap_or_else(|_| Err(LexError::call_site())) |
122 | } |
123 | |
124 | impl Display for TokenStream { |
125 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
126 | match self { |
127 | TokenStream::Compiler(tts: &DeferredTokenStream) => Display::fmt(&tts.clone().into_token_stream(), f), |
128 | TokenStream::Fallback(tts: &TokenStream) => Display::fmt(self:tts, f), |
129 | } |
130 | } |
131 | } |
132 | |
133 | impl From<proc_macro::TokenStream> for TokenStream { |
134 | fn from(inner: proc_macro::TokenStream) -> Self { |
135 | TokenStream::Compiler(DeferredTokenStream::new(stream:inner)) |
136 | } |
137 | } |
138 | |
139 | impl From<TokenStream> for proc_macro::TokenStream { |
140 | fn from(inner: TokenStream) -> Self { |
141 | match inner { |
142 | TokenStream::Compiler(inner: DeferredTokenStream) => inner.into_token_stream(), |
143 | TokenStream::Fallback(inner: TokenStream) => inner.to_string().parse().unwrap(), |
144 | } |
145 | } |
146 | } |
147 | |
148 | impl From<fallback::TokenStream> for TokenStream { |
149 | fn from(inner: fallback::TokenStream) -> Self { |
150 | TokenStream::Fallback(inner) |
151 | } |
152 | } |
153 | |
154 | // Assumes inside_proc_macro(). |
155 | fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { |
156 | match token { |
157 | TokenTree::Group(tt: Group) => tt.inner.unwrap_nightly().into(), |
158 | TokenTree::Punct(tt: Punct) => { |
159 | let spacing: Spacing = match tt.spacing() { |
160 | Spacing::Joint => proc_macro::Spacing::Joint, |
161 | Spacing::Alone => proc_macro::Spacing::Alone, |
162 | }; |
163 | let mut punct: Punct = proc_macro::Punct::new(ch:tt.as_char(), spacing); |
164 | punct.set_span(tt.span().inner.unwrap_nightly()); |
165 | punct.into() |
166 | } |
167 | TokenTree::Ident(tt: Ident) => tt.inner.unwrap_nightly().into(), |
168 | TokenTree::Literal(tt: Literal) => tt.inner.unwrap_nightly().into(), |
169 | } |
170 | } |
171 | |
172 | impl From<TokenTree> for TokenStream { |
173 | fn from(token: TokenTree) -> Self { |
174 | if inside_proc_macro() { |
175 | TokenStream::Compiler(DeferredTokenStream::new(stream:into_compiler_token(token).into())) |
176 | } else { |
177 | TokenStream::Fallback(token.into()) |
178 | } |
179 | } |
180 | } |
181 | |
182 | impl FromIterator<TokenTree> for TokenStream { |
183 | fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self { |
184 | if inside_proc_macro() { |
185 | TokenStream::Compiler(DeferredTokenStream::new( |
186 | stream:trees.into_iter().map(into_compiler_token).collect(), |
187 | )) |
188 | } else { |
189 | TokenStream::Fallback(trees.into_iter().collect()) |
190 | } |
191 | } |
192 | } |
193 | |
194 | impl FromIterator<TokenStream> for TokenStream { |
195 | fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { |
196 | let mut streams: ::IntoIter = streams.into_iter(); |
197 | match streams.next() { |
198 | Some(TokenStream::Compiler(mut first: DeferredTokenStream)) => { |
199 | first.evaluate_now(); |
200 | first.stream.extend(iter:streams.map(|s: TokenStream| match s { |
201 | TokenStream::Compiler(s: DeferredTokenStream) => s.into_token_stream(), |
202 | TokenStream::Fallback(_) => mismatch(), |
203 | })); |
204 | TokenStream::Compiler(first) |
205 | } |
206 | Some(TokenStream::Fallback(mut first: TokenStream)) => { |
207 | first.extend(iter:streams.map(|s: TokenStream| match s { |
208 | TokenStream::Fallback(s: TokenStream) => s, |
209 | TokenStream::Compiler(_) => mismatch(), |
210 | })); |
211 | TokenStream::Fallback(first) |
212 | } |
213 | None => TokenStream::new(), |
214 | } |
215 | } |
216 | } |
217 | |
218 | impl Extend<TokenTree> for TokenStream { |
219 | fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, stream: I) { |
220 | match self { |
221 | TokenStream::Compiler(tts: &mut DeferredTokenStream) => { |
222 | // Here is the reason for DeferredTokenStream. |
223 | for token: TokenTree in stream { |
224 | tts.extra.push(into_compiler_token(token)); |
225 | } |
226 | } |
227 | TokenStream::Fallback(tts: &mut TokenStream) => tts.extend(iter:stream), |
228 | } |
229 | } |
230 | } |
231 | |
232 | impl Extend<TokenStream> for TokenStream { |
233 | fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { |
234 | match self { |
235 | TokenStream::Compiler(tts: &mut DeferredTokenStream) => { |
236 | tts.evaluate_now(); |
237 | tts.stream |
238 | .extend(iter:streams.into_iter().map(TokenStream::unwrap_nightly)); |
239 | } |
240 | TokenStream::Fallback(tts: &mut TokenStream) => { |
241 | tts.extend(iter:streams.into_iter().map(TokenStream::unwrap_stable)); |
242 | } |
243 | } |
244 | } |
245 | } |
246 | |
247 | impl Debug for TokenStream { |
248 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
249 | match self { |
250 | TokenStream::Compiler(tts: &DeferredTokenStream) => Debug::fmt(&tts.clone().into_token_stream(), f), |
251 | TokenStream::Fallback(tts: &TokenStream) => Debug::fmt(self:tts, f), |
252 | } |
253 | } |
254 | } |
255 | |
256 | impl LexError { |
257 | pub(crate) fn span(&self) -> Span { |
258 | match self { |
259 | LexError::Compiler(_) => Span::call_site(), |
260 | LexError::Fallback(e: &LexError) => Span::Fallback(e.span()), |
261 | } |
262 | } |
263 | } |
264 | |
265 | impl From<proc_macro::LexError> for LexError { |
266 | fn from(e: proc_macro::LexError) -> Self { |
267 | LexError::Compiler(e) |
268 | } |
269 | } |
270 | |
271 | impl From<fallback::LexError> for LexError { |
272 | fn from(e: fallback::LexError) -> Self { |
273 | LexError::Fallback(e) |
274 | } |
275 | } |
276 | |
277 | impl Debug for LexError { |
278 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
279 | match self { |
280 | LexError::Compiler(e: &LexError) => Debug::fmt(self:e, f), |
281 | LexError::Fallback(e: &LexError) => Debug::fmt(self:e, f), |
282 | } |
283 | } |
284 | } |
285 | |
286 | impl Display for LexError { |
287 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
288 | match self { |
289 | #[cfg (not(no_lexerror_display))] |
290 | LexError::Compiler(e: &LexError) => Display::fmt(self:e, f), |
291 | #[cfg (no_lexerror_display)] |
292 | LexError::Compiler(_e) => Display::fmt( |
293 | &fallback::LexError { |
294 | span: fallback::Span::call_site(), |
295 | }, |
296 | f, |
297 | ), |
298 | LexError::Fallback(e: &LexError) => Display::fmt(self:e, f), |
299 | } |
300 | } |
301 | } |
302 | |
303 | #[derive (Clone)] |
304 | pub(crate) enum TokenTreeIter { |
305 | Compiler(proc_macro::token_stream::IntoIter), |
306 | Fallback(fallback::TokenTreeIter), |
307 | } |
308 | |
309 | impl IntoIterator for TokenStream { |
310 | type Item = TokenTree; |
311 | type IntoIter = TokenTreeIter; |
312 | |
313 | fn into_iter(self) -> TokenTreeIter { |
314 | match self { |
315 | TokenStream::Compiler(tts: DeferredTokenStream) => { |
316 | TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) |
317 | } |
318 | TokenStream::Fallback(tts: TokenStream) => TokenTreeIter::Fallback(tts.into_iter()), |
319 | } |
320 | } |
321 | } |
322 | |
323 | impl Iterator for TokenTreeIter { |
324 | type Item = TokenTree; |
325 | |
326 | fn next(&mut self) -> Option<TokenTree> { |
327 | let token = match self { |
328 | TokenTreeIter::Compiler(iter) => iter.next()?, |
329 | TokenTreeIter::Fallback(iter) => return iter.next(), |
330 | }; |
331 | Some(match token { |
332 | proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), |
333 | proc_macro::TokenTree::Punct(tt) => { |
334 | let spacing = match tt.spacing() { |
335 | proc_macro::Spacing::Joint => Spacing::Joint, |
336 | proc_macro::Spacing::Alone => Spacing::Alone, |
337 | }; |
338 | let mut o = Punct::new(tt.as_char(), spacing); |
339 | o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); |
340 | o.into() |
341 | } |
342 | proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), |
343 | proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), |
344 | }) |
345 | } |
346 | |
347 | fn size_hint(&self) -> (usize, Option<usize>) { |
348 | match self { |
349 | TokenTreeIter::Compiler(tts) => tts.size_hint(), |
350 | TokenTreeIter::Fallback(tts) => tts.size_hint(), |
351 | } |
352 | } |
353 | } |
354 | |
355 | #[derive (Clone, PartialEq, Eq)] |
356 | #[cfg (super_unstable)] |
357 | pub(crate) enum SourceFile { |
358 | Compiler(proc_macro::SourceFile), |
359 | Fallback(fallback::SourceFile), |
360 | } |
361 | |
362 | #[cfg (super_unstable)] |
363 | impl SourceFile { |
364 | fn nightly(sf: proc_macro::SourceFile) -> Self { |
365 | SourceFile::Compiler(sf) |
366 | } |
367 | |
368 | /// Get the path to this source file as a string. |
369 | pub fn path(&self) -> PathBuf { |
370 | match self { |
371 | SourceFile::Compiler(a) => a.path(), |
372 | SourceFile::Fallback(a) => a.path(), |
373 | } |
374 | } |
375 | |
376 | pub fn is_real(&self) -> bool { |
377 | match self { |
378 | SourceFile::Compiler(a) => a.is_real(), |
379 | SourceFile::Fallback(a) => a.is_real(), |
380 | } |
381 | } |
382 | } |
383 | |
384 | #[cfg (super_unstable)] |
385 | impl Debug for SourceFile { |
386 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
387 | match self { |
388 | SourceFile::Compiler(a) => Debug::fmt(a, f), |
389 | SourceFile::Fallback(a) => Debug::fmt(a, f), |
390 | } |
391 | } |
392 | } |
393 | |
394 | #[derive (Copy, Clone)] |
395 | pub(crate) enum Span { |
396 | Compiler(proc_macro::Span), |
397 | Fallback(fallback::Span), |
398 | } |
399 | |
400 | impl Span { |
401 | pub fn call_site() -> Self { |
402 | if inside_proc_macro() { |
403 | Span::Compiler(proc_macro::Span::call_site()) |
404 | } else { |
405 | Span::Fallback(fallback::Span::call_site()) |
406 | } |
407 | } |
408 | |
409 | #[cfg (not(no_hygiene))] |
410 | pub fn mixed_site() -> Self { |
411 | if inside_proc_macro() { |
412 | Span::Compiler(proc_macro::Span::mixed_site()) |
413 | } else { |
414 | Span::Fallback(fallback::Span::mixed_site()) |
415 | } |
416 | } |
417 | |
418 | #[cfg (super_unstable)] |
419 | pub fn def_site() -> Self { |
420 | if inside_proc_macro() { |
421 | Span::Compiler(proc_macro::Span::def_site()) |
422 | } else { |
423 | Span::Fallback(fallback::Span::def_site()) |
424 | } |
425 | } |
426 | |
427 | pub fn resolved_at(&self, other: Span) -> Span { |
428 | match (self, other) { |
429 | #[cfg (not(no_hygiene))] |
430 | (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), |
431 | |
432 | // Name resolution affects semantics, but location is only cosmetic |
433 | #[cfg (no_hygiene)] |
434 | (Span::Compiler(_), Span::Compiler(_)) => other, |
435 | |
436 | (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), |
437 | _ => mismatch(), |
438 | } |
439 | } |
440 | |
441 | pub fn located_at(&self, other: Span) -> Span { |
442 | match (self, other) { |
443 | #[cfg (not(no_hygiene))] |
444 | (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), |
445 | |
446 | // Name resolution affects semantics, but location is only cosmetic |
447 | #[cfg (no_hygiene)] |
448 | (Span::Compiler(_), Span::Compiler(_)) => *self, |
449 | |
450 | (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), |
451 | _ => mismatch(), |
452 | } |
453 | } |
454 | |
455 | pub fn unwrap(self) -> proc_macro::Span { |
456 | match self { |
457 | Span::Compiler(s) => s, |
458 | Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros" ), |
459 | } |
460 | } |
461 | |
462 | #[cfg (super_unstable)] |
463 | pub fn source_file(&self) -> SourceFile { |
464 | match self { |
465 | Span::Compiler(s) => SourceFile::nightly(s.source_file()), |
466 | Span::Fallback(s) => SourceFile::Fallback(s.source_file()), |
467 | } |
468 | } |
469 | |
470 | #[cfg (span_locations)] |
471 | pub fn start(&self) -> LineColumn { |
472 | match self { |
473 | Span::Compiler(_) => LineColumn { line: 0, column: 0 }, |
474 | Span::Fallback(s) => s.start(), |
475 | } |
476 | } |
477 | |
478 | #[cfg (span_locations)] |
479 | pub fn end(&self) -> LineColumn { |
480 | match self { |
481 | Span::Compiler(_) => LineColumn { line: 0, column: 0 }, |
482 | Span::Fallback(s) => s.end(), |
483 | } |
484 | } |
485 | |
486 | pub fn join(&self, other: Span) -> Option<Span> { |
487 | let ret = match (self, other) { |
488 | #[cfg (proc_macro_span)] |
489 | (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), |
490 | (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), |
491 | _ => return None, |
492 | }; |
493 | Some(ret) |
494 | } |
495 | |
496 | #[cfg (super_unstable)] |
497 | pub fn eq(&self, other: &Span) -> bool { |
498 | match (self, other) { |
499 | (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), |
500 | (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), |
501 | _ => false, |
502 | } |
503 | } |
504 | |
505 | pub fn source_text(&self) -> Option<String> { |
506 | match self { |
507 | #[cfg (not(no_source_text))] |
508 | Span::Compiler(s) => s.source_text(), |
509 | #[cfg (no_source_text)] |
510 | Span::Compiler(_) => None, |
511 | Span::Fallback(s) => s.source_text(), |
512 | } |
513 | } |
514 | |
515 | fn unwrap_nightly(self) -> proc_macro::Span { |
516 | match self { |
517 | Span::Compiler(s) => s, |
518 | Span::Fallback(_) => mismatch(), |
519 | } |
520 | } |
521 | } |
522 | |
523 | impl From<proc_macro::Span> for crate::Span { |
524 | fn from(proc_span: proc_macro::Span) -> Self { |
525 | crate::Span::_new(inner:Span::Compiler(proc_span)) |
526 | } |
527 | } |
528 | |
529 | impl From<fallback::Span> for Span { |
530 | fn from(inner: fallback::Span) -> Self { |
531 | Span::Fallback(inner) |
532 | } |
533 | } |
534 | |
535 | impl Debug for Span { |
536 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
537 | match self { |
538 | Span::Compiler(s: &Span) => Debug::fmt(self:s, f), |
539 | Span::Fallback(s: &Span) => Debug::fmt(self:s, f), |
540 | } |
541 | } |
542 | } |
543 | |
544 | pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { |
545 | match span { |
546 | Span::Compiler(s: Span) => { |
547 | debug.field(name:"span" , &s); |
548 | } |
549 | Span::Fallback(s: Span) => fallback::debug_span_field_if_nontrivial(debug, span:s), |
550 | } |
551 | } |
552 | |
553 | #[derive (Clone)] |
554 | pub(crate) enum Group { |
555 | Compiler(proc_macro::Group), |
556 | Fallback(fallback::Group), |
557 | } |
558 | |
559 | impl Group { |
560 | pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { |
561 | match stream { |
562 | TokenStream::Compiler(tts) => { |
563 | let delimiter = match delimiter { |
564 | Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, |
565 | Delimiter::Bracket => proc_macro::Delimiter::Bracket, |
566 | Delimiter::Brace => proc_macro::Delimiter::Brace, |
567 | Delimiter::None => proc_macro::Delimiter::None, |
568 | }; |
569 | Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) |
570 | } |
571 | TokenStream::Fallback(stream) => { |
572 | Group::Fallback(fallback::Group::new(delimiter, stream)) |
573 | } |
574 | } |
575 | } |
576 | |
577 | pub fn delimiter(&self) -> Delimiter { |
578 | match self { |
579 | Group::Compiler(g) => match g.delimiter() { |
580 | proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, |
581 | proc_macro::Delimiter::Bracket => Delimiter::Bracket, |
582 | proc_macro::Delimiter::Brace => Delimiter::Brace, |
583 | proc_macro::Delimiter::None => Delimiter::None, |
584 | }, |
585 | Group::Fallback(g) => g.delimiter(), |
586 | } |
587 | } |
588 | |
589 | pub fn stream(&self) -> TokenStream { |
590 | match self { |
591 | Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), |
592 | Group::Fallback(g) => TokenStream::Fallback(g.stream()), |
593 | } |
594 | } |
595 | |
596 | pub fn span(&self) -> Span { |
597 | match self { |
598 | Group::Compiler(g) => Span::Compiler(g.span()), |
599 | Group::Fallback(g) => Span::Fallback(g.span()), |
600 | } |
601 | } |
602 | |
603 | pub fn span_open(&self) -> Span { |
604 | match self { |
605 | #[cfg (not(no_group_open_close))] |
606 | Group::Compiler(g) => Span::Compiler(g.span_open()), |
607 | #[cfg (no_group_open_close)] |
608 | Group::Compiler(g) => Span::Compiler(g.span()), |
609 | Group::Fallback(g) => Span::Fallback(g.span_open()), |
610 | } |
611 | } |
612 | |
613 | pub fn span_close(&self) -> Span { |
614 | match self { |
615 | #[cfg (not(no_group_open_close))] |
616 | Group::Compiler(g) => Span::Compiler(g.span_close()), |
617 | #[cfg (no_group_open_close)] |
618 | Group::Compiler(g) => Span::Compiler(g.span()), |
619 | Group::Fallback(g) => Span::Fallback(g.span_close()), |
620 | } |
621 | } |
622 | |
623 | pub fn set_span(&mut self, span: Span) { |
624 | match (self, span) { |
625 | (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), |
626 | (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), |
627 | _ => mismatch(), |
628 | } |
629 | } |
630 | |
631 | fn unwrap_nightly(self) -> proc_macro::Group { |
632 | match self { |
633 | Group::Compiler(g) => g, |
634 | Group::Fallback(_) => mismatch(), |
635 | } |
636 | } |
637 | } |
638 | |
639 | impl From<fallback::Group> for Group { |
640 | fn from(g: fallback::Group) -> Self { |
641 | Group::Fallback(g) |
642 | } |
643 | } |
644 | |
645 | impl Display for Group { |
646 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
647 | match self { |
648 | Group::Compiler(group: &Group) => Display::fmt(self:group, f:formatter), |
649 | Group::Fallback(group: &Group) => Display::fmt(self:group, f:formatter), |
650 | } |
651 | } |
652 | } |
653 | |
654 | impl Debug for Group { |
655 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
656 | match self { |
657 | Group::Compiler(group: &Group) => Debug::fmt(self:group, f:formatter), |
658 | Group::Fallback(group: &Group) => Debug::fmt(self:group, f:formatter), |
659 | } |
660 | } |
661 | } |
662 | |
663 | #[derive (Clone)] |
664 | pub(crate) enum Ident { |
665 | Compiler(proc_macro::Ident), |
666 | Fallback(fallback::Ident), |
667 | } |
668 | |
669 | impl Ident { |
670 | pub fn new(string: &str, span: Span) -> Self { |
671 | match span { |
672 | Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), |
673 | Span::Fallback(s) => Ident::Fallback(fallback::Ident::new(string, s)), |
674 | } |
675 | } |
676 | |
677 | pub fn new_raw(string: &str, span: Span) -> Self { |
678 | match span { |
679 | #[cfg (not(no_ident_new_raw))] |
680 | Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), |
681 | #[cfg (no_ident_new_raw)] |
682 | Span::Compiler(s) => { |
683 | let _ = proc_macro::Ident::new(string, s); |
684 | // At this point the un-r#-prefixed string is known to be a |
685 | // valid identifier. Try to produce a valid raw identifier by |
686 | // running the `TokenStream` parser, and unwrapping the first |
687 | // token as an `Ident`. |
688 | let raw_prefixed = format!("r# {}" , string); |
689 | if let Ok(ts) = raw_prefixed.parse::<proc_macro::TokenStream>() { |
690 | let mut iter = ts.into_iter(); |
691 | if let (Some(proc_macro::TokenTree::Ident(mut id)), None) = |
692 | (iter.next(), iter.next()) |
693 | { |
694 | id.set_span(s); |
695 | return Ident::Compiler(id); |
696 | } |
697 | } |
698 | panic!("not allowed as a raw identifier: ` {}`" , raw_prefixed) |
699 | } |
700 | Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw(string, s)), |
701 | } |
702 | } |
703 | |
704 | pub fn span(&self) -> Span { |
705 | match self { |
706 | Ident::Compiler(t) => Span::Compiler(t.span()), |
707 | Ident::Fallback(t) => Span::Fallback(t.span()), |
708 | } |
709 | } |
710 | |
711 | pub fn set_span(&mut self, span: Span) { |
712 | match (self, span) { |
713 | (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), |
714 | (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), |
715 | _ => mismatch(), |
716 | } |
717 | } |
718 | |
719 | fn unwrap_nightly(self) -> proc_macro::Ident { |
720 | match self { |
721 | Ident::Compiler(s) => s, |
722 | Ident::Fallback(_) => mismatch(), |
723 | } |
724 | } |
725 | } |
726 | |
727 | impl PartialEq for Ident { |
728 | fn eq(&self, other: &Ident) -> bool { |
729 | match (self, other) { |
730 | (Ident::Compiler(t: &Ident), Ident::Compiler(o: &Ident)) => t.to_string() == o.to_string(), |
731 | (Ident::Fallback(t: &Ident), Ident::Fallback(o: &Ident)) => t == o, |
732 | _ => mismatch(), |
733 | } |
734 | } |
735 | } |
736 | |
737 | impl<T> PartialEq<T> for Ident |
738 | where |
739 | T: ?Sized + AsRef<str>, |
740 | { |
741 | fn eq(&self, other: &T) -> bool { |
742 | let other: &str = other.as_ref(); |
743 | match self { |
744 | Ident::Compiler(t: &Ident) => t.to_string() == other, |
745 | Ident::Fallback(t: &Ident) => t == other, |
746 | } |
747 | } |
748 | } |
749 | |
750 | impl Display for Ident { |
751 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
752 | match self { |
753 | Ident::Compiler(t: &Ident) => Display::fmt(self:t, f), |
754 | Ident::Fallback(t: &Ident) => Display::fmt(self:t, f), |
755 | } |
756 | } |
757 | } |
758 | |
759 | impl Debug for Ident { |
760 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
761 | match self { |
762 | Ident::Compiler(t: &Ident) => Debug::fmt(self:t, f), |
763 | Ident::Fallback(t: &Ident) => Debug::fmt(self:t, f), |
764 | } |
765 | } |
766 | } |
767 | |
768 | #[derive (Clone)] |
769 | pub(crate) enum Literal { |
770 | Compiler(proc_macro::Literal), |
771 | Fallback(fallback::Literal), |
772 | } |
773 | |
774 | macro_rules! suffixed_numbers { |
775 | ($($name:ident => $kind:ident,)*) => ($( |
776 | pub fn $name(n: $kind) -> Literal { |
777 | if inside_proc_macro() { |
778 | Literal::Compiler(proc_macro::Literal::$name(n)) |
779 | } else { |
780 | Literal::Fallback(fallback::Literal::$name(n)) |
781 | } |
782 | } |
783 | )*) |
784 | } |
785 | |
786 | macro_rules! unsuffixed_integers { |
787 | ($($name:ident => $kind:ident,)*) => ($( |
788 | pub fn $name(n: $kind) -> Literal { |
789 | if inside_proc_macro() { |
790 | Literal::Compiler(proc_macro::Literal::$name(n)) |
791 | } else { |
792 | Literal::Fallback(fallback::Literal::$name(n)) |
793 | } |
794 | } |
795 | )*) |
796 | } |
797 | |
798 | impl Literal { |
799 | pub unsafe fn from_str_unchecked(repr: &str) -> Self { |
800 | if inside_proc_macro() { |
801 | Literal::Compiler(compiler_literal_from_str(repr).expect("invalid literal" )) |
802 | } else { |
803 | Literal::Fallback(fallback::Literal::from_str_unchecked(repr)) |
804 | } |
805 | } |
806 | |
807 | suffixed_numbers! { |
808 | u8_suffixed => u8, |
809 | u16_suffixed => u16, |
810 | u32_suffixed => u32, |
811 | u64_suffixed => u64, |
812 | u128_suffixed => u128, |
813 | usize_suffixed => usize, |
814 | i8_suffixed => i8, |
815 | i16_suffixed => i16, |
816 | i32_suffixed => i32, |
817 | i64_suffixed => i64, |
818 | i128_suffixed => i128, |
819 | isize_suffixed => isize, |
820 | |
821 | f32_suffixed => f32, |
822 | f64_suffixed => f64, |
823 | } |
824 | |
825 | unsuffixed_integers! { |
826 | u8_unsuffixed => u8, |
827 | u16_unsuffixed => u16, |
828 | u32_unsuffixed => u32, |
829 | u64_unsuffixed => u64, |
830 | u128_unsuffixed => u128, |
831 | usize_unsuffixed => usize, |
832 | i8_unsuffixed => i8, |
833 | i16_unsuffixed => i16, |
834 | i32_unsuffixed => i32, |
835 | i64_unsuffixed => i64, |
836 | i128_unsuffixed => i128, |
837 | isize_unsuffixed => isize, |
838 | } |
839 | |
840 | pub fn f32_unsuffixed(f: f32) -> Literal { |
841 | if inside_proc_macro() { |
842 | Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) |
843 | } else { |
844 | Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) |
845 | } |
846 | } |
847 | |
848 | pub fn f64_unsuffixed(f: f64) -> Literal { |
849 | if inside_proc_macro() { |
850 | Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) |
851 | } else { |
852 | Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) |
853 | } |
854 | } |
855 | |
856 | pub fn string(t: &str) -> Literal { |
857 | if inside_proc_macro() { |
858 | Literal::Compiler(proc_macro::Literal::string(t)) |
859 | } else { |
860 | Literal::Fallback(fallback::Literal::string(t)) |
861 | } |
862 | } |
863 | |
864 | pub fn character(t: char) -> Literal { |
865 | if inside_proc_macro() { |
866 | Literal::Compiler(proc_macro::Literal::character(t)) |
867 | } else { |
868 | Literal::Fallback(fallback::Literal::character(t)) |
869 | } |
870 | } |
871 | |
872 | pub fn byte_string(bytes: &[u8]) -> Literal { |
873 | if inside_proc_macro() { |
874 | Literal::Compiler(proc_macro::Literal::byte_string(bytes)) |
875 | } else { |
876 | Literal::Fallback(fallback::Literal::byte_string(bytes)) |
877 | } |
878 | } |
879 | |
880 | pub fn span(&self) -> Span { |
881 | match self { |
882 | Literal::Compiler(lit) => Span::Compiler(lit.span()), |
883 | Literal::Fallback(lit) => Span::Fallback(lit.span()), |
884 | } |
885 | } |
886 | |
887 | pub fn set_span(&mut self, span: Span) { |
888 | match (self, span) { |
889 | (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), |
890 | (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), |
891 | _ => mismatch(), |
892 | } |
893 | } |
894 | |
895 | pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { |
896 | match self { |
897 | #[cfg (proc_macro_span)] |
898 | Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), |
899 | #[cfg (not(proc_macro_span))] |
900 | Literal::Compiler(_lit) => None, |
901 | Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), |
902 | } |
903 | } |
904 | |
905 | fn unwrap_nightly(self) -> proc_macro::Literal { |
906 | match self { |
907 | Literal::Compiler(s) => s, |
908 | Literal::Fallback(_) => mismatch(), |
909 | } |
910 | } |
911 | } |
912 | |
913 | impl From<fallback::Literal> for Literal { |
914 | fn from(s: fallback::Literal) -> Self { |
915 | Literal::Fallback(s) |
916 | } |
917 | } |
918 | |
919 | impl FromStr for Literal { |
920 | type Err = LexError; |
921 | |
922 | fn from_str(repr: &str) -> Result<Self, Self::Err> { |
923 | if inside_proc_macro() { |
924 | compiler_literal_from_str(repr).map(op:Literal::Compiler) |
925 | } else { |
926 | let literal: Literal = fallback::Literal::from_str(repr)?; |
927 | Ok(Literal::Fallback(literal)) |
928 | } |
929 | } |
930 | } |
931 | |
932 | fn compiler_literal_from_str(repr: &str) -> Result<proc_macro::Literal, LexError> { |
933 | #[cfg (not(no_literal_from_str))] |
934 | { |
935 | proc_macro::Literal::from_str(repr).map_err(op:LexError::Compiler) |
936 | } |
937 | #[cfg (no_literal_from_str)] |
938 | { |
939 | let tokens = proc_macro_parse(repr)?; |
940 | let mut iter = tokens.into_iter(); |
941 | if let (Some(proc_macro::TokenTree::Literal(literal)), None) = (iter.next(), iter.next()) { |
942 | if literal.to_string().len() == repr.len() { |
943 | return Ok(literal); |
944 | } |
945 | } |
946 | Err(LexError::call_site()) |
947 | } |
948 | } |
949 | |
950 | impl Display for Literal { |
951 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
952 | match self { |
953 | Literal::Compiler(t: &Literal) => Display::fmt(self:t, f), |
954 | Literal::Fallback(t: &Literal) => Display::fmt(self:t, f), |
955 | } |
956 | } |
957 | } |
958 | |
959 | impl Debug for Literal { |
960 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
961 | match self { |
962 | Literal::Compiler(t: &Literal) => Debug::fmt(self:t, f), |
963 | Literal::Fallback(t: &Literal) => Debug::fmt(self:t, f), |
964 | } |
965 | } |
966 | } |
967 | |