1 | //! Items which do not have a correspondence to any API in the proc_macro crate, |
2 | //! but are necessary to include in proc-macro2. |
3 | |
4 | use crate::fallback; |
5 | use crate::imp; |
6 | use crate::marker::Marker; |
7 | use crate::Span; |
8 | use core::fmt::{self, Debug}; |
9 | |
10 | /// An object that holds a [`Group`]'s `span_open()` and `span_close()` together |
11 | /// (in a more compact representation than holding those 2 spans individually. |
12 | /// |
13 | /// [`Group`]: crate::Group |
14 | #[derive (Copy, Clone)] |
15 | pub struct DelimSpan { |
16 | inner: DelimSpanEnum, |
17 | _marker: Marker, |
18 | } |
19 | |
20 | #[derive (Copy, Clone)] |
21 | enum DelimSpanEnum { |
22 | #[cfg (wrap_proc_macro)] |
23 | Compiler { |
24 | join: proc_macro::Span, |
25 | #[cfg (not(no_group_open_close))] |
26 | open: proc_macro::Span, |
27 | #[cfg (not(no_group_open_close))] |
28 | close: proc_macro::Span, |
29 | }, |
30 | Fallback(fallback::Span), |
31 | } |
32 | |
33 | impl DelimSpan { |
34 | pub(crate) fn new(group: &imp::Group) -> Self { |
35 | #[cfg (wrap_proc_macro)] |
36 | let inner = match group { |
37 | imp::Group::Compiler(group) => DelimSpanEnum::Compiler { |
38 | join: group.span(), |
39 | #[cfg (not(no_group_open_close))] |
40 | open: group.span_open(), |
41 | #[cfg (not(no_group_open_close))] |
42 | close: group.span_close(), |
43 | }, |
44 | imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), |
45 | }; |
46 | |
47 | #[cfg (not(wrap_proc_macro))] |
48 | let inner = DelimSpanEnum::Fallback(group.span()); |
49 | |
50 | DelimSpan { |
51 | inner, |
52 | _marker: Marker, |
53 | } |
54 | } |
55 | |
56 | /// Returns a span covering the entire delimited group. |
57 | pub fn join(&self) -> Span { |
58 | match &self.inner { |
59 | #[cfg (wrap_proc_macro)] |
60 | DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), |
61 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), |
62 | } |
63 | } |
64 | |
65 | /// Returns a span for the opening punctuation of the group only. |
66 | pub fn open(&self) -> Span { |
67 | match &self.inner { |
68 | #[cfg (wrap_proc_macro)] |
69 | DelimSpanEnum::Compiler { |
70 | #[cfg (not(no_group_open_close))] |
71 | open, |
72 | #[cfg (no_group_open_close)] |
73 | join: open, |
74 | .. |
75 | } => Span::_new(imp::Span::Compiler(*open)), |
76 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), |
77 | } |
78 | } |
79 | |
80 | /// Returns a span for the closing punctuation of the group only. |
81 | pub fn close(&self) -> Span { |
82 | match &self.inner { |
83 | #[cfg (wrap_proc_macro)] |
84 | DelimSpanEnum::Compiler { |
85 | #[cfg (not(no_group_open_close))] |
86 | close, |
87 | #[cfg (no_group_open_close)] |
88 | join: close, |
89 | .. |
90 | } => Span::_new(imp::Span::Compiler(*close)), |
91 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), |
92 | } |
93 | } |
94 | } |
95 | |
96 | impl Debug for DelimSpan { |
97 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
98 | Debug::fmt(&self.join(), f) |
99 | } |
100 | } |
101 | |