moxy_token/bridge/
proc_macro.rs1use crate::span::fallback;
2use crate::{Delim, Group, Ident, Keyword, LexError, Lit, Spacing, Span, ToTokens, TokenStream, TokenTree, TryIntoTokenStream};
3
4impl From<proc_macro::Span> for fallback::Span {
7 fn from(#[allow(unused)] value: proc_macro::Span) -> Self {
8 #[cfg(nightly)]
9 {
10 let r = value.byte_range();
11 Self::new(r.start as u32, r.end as u32)
12 }
13
14 #[cfg(not(nightly))]
15 {
16 Self::default()
17 }
18 }
19}
20
21impl From<fallback::Span> for proc_macro::Span {
22 fn from(_value: fallback::Span) -> Self {
23 Self::call_site()
24 }
25}
26
27impl From<proc_macro::Span> for Span {
30 #[inline]
31 fn from(value: proc_macro::Span) -> Self {
32 Self::Compiler(value)
33 }
34}
35
36impl From<Span> for proc_macro::Span {
37 fn from(value: Span) -> Self {
38 match value {
39 Span::Compiler(s) => s,
40 Span::Fallback(_) => Self::call_site(),
41 }
42 }
43}
44
45#[cfg(nightly)]
46impl proc_macro::MultiSpan for Span {
47 fn into_spans(self) -> Vec<proc_macro::Span> {
48 match self {
49 Self::Compiler(s) => vec![s],
50 Self::Fallback(_) => vec![proc_macro::Span::call_site()],
51 }
52 }
53}
54
55impl From<proc_macro::Delimiter> for Delim {
58 #[inline]
59 fn from(value: proc_macro::Delimiter) -> Self {
60 match value {
61 proc_macro::Delimiter::Parenthesis => Self::Paren,
62 proc_macro::Delimiter::Brace => Self::Brace,
63 proc_macro::Delimiter::Bracket => Self::Bracket,
64 proc_macro::Delimiter::None => Self::None,
65 }
66 }
67}
68
69impl From<Delim> for proc_macro::Delimiter {
70 #[inline]
71 fn from(value: Delim) -> Self {
72 match value {
73 Delim::Paren => Self::Parenthesis,
74 Delim::Brace => Self::Brace,
75 Delim::Bracket => Self::Bracket,
76 Delim::None => Self::None,
77 }
78 }
79}
80
81impl From<proc_macro::Spacing> for Spacing {
84 #[inline]
85 fn from(value: proc_macro::Spacing) -> Self {
86 match value {
87 proc_macro::Spacing::Alone => Self::Alone,
88 proc_macro::Spacing::Joint => Self::Joint,
89 }
90 }
91}
92
93impl From<Spacing> for proc_macro::Spacing {
94 #[inline]
95 fn from(value: Spacing) -> Self {
96 match value {
97 Spacing::Alone => Self::Alone,
98 Spacing::Joint => Self::Joint,
99 }
100 }
101}
102
103impl From<proc_macro::Ident> for Ident {
106 #[inline]
107 fn from(value: proc_macro::Ident) -> Self {
108 Self::new(value.to_string()).with_span(value.span().into())
109 }
110}
111
112impl From<Ident> for proc_macro::Ident {
113 fn from(value: Ident) -> Self {
114 let span: proc_macro::Span = value.span().into();
115
116 if value.is_raw() {
117 Self::new_raw(value.text(), span)
118 } else {
119 Self::new(value.text(), span)
120 }
121 }
122}
123
124impl From<proc_macro::Literal> for Lit {
127 fn from(value: proc_macro::Literal) -> Self {
128 Self::from_repr(&value.to_string(), value.span().into())
129 }
130}
131
132impl From<Lit> for proc_macro::Literal {
133 fn from(value: Lit) -> Self {
134 let repr = value.repr();
135 let mut lit = repr.parse().unwrap_or_else(|_| Self::string(repr));
136
137 lit.set_span(value.span().into());
138 lit
139 }
140}
141
142impl From<proc_macro::Group> for Group {
145 #[inline]
146 fn from(value: proc_macro::Group) -> Self {
147 use crate::span::DelimSpan;
148 let mut group = Self::new(value.delimiter().into(), value.stream().into());
149 group.span = DelimSpan::new(value.span_open().into(), value.span_close().into());
150 group
151 }
152}
153
154impl From<Group> for proc_macro::Group {
155 #[inline]
156 fn from(value: Group) -> Self {
157 let span = value.span.span().into();
158 let mut group = Self::new(value.delim.into(), value.tokens.into());
159 group.set_span(span);
160 group
161 }
162}
163
164impl ToTokens<TokenStream> for proc_macro::TokenTree {
167 fn to_tokens(&self, tokens: &mut TokenStream) {
168 match self {
169 Self::Ident(v) => {
170 let span = v.span().into();
171 let text = v.to_string();
172 let tt = match text.as_str() {
173 "true" => TokenTree::Literal(Lit::Bool(crate::LitBool::new(true, span))),
174 "false" => TokenTree::Literal(Lit::Bool(crate::LitBool::new(false, span))),
175 _ => match Keyword::from_str(&text, span) {
176 Some(kw) => TokenTree::Keyword(kw),
177 None => TokenTree::Ident(v.clone().into()),
178 },
179 };
180 tokens.extend_one(tt)
181 }
182 Self::Literal(v) => tokens.extend_one(TokenTree::Literal(v.clone().into())),
183 Self::Group(v) => tokens.extend_one(TokenTree::Group(v.clone().into())),
184 Self::Punct(p) => crate::scan_puncts_spanned(&[(p.as_char(), p.span().into(), p.spacing().into())], tokens),
185 }
186 }
187}
188
189impl ToTokens<TokenStream> for proc_macro::TokenStream {
190 fn to_tokens(&self, tokens: &mut TokenStream) {
191 let mut punct_run: Vec<(char, Span, Spacing)> = Vec::new();
192
193 for tt in self.clone() {
194 match tt {
195 proc_macro::TokenTree::Punct(p) => punct_run.push((p.as_char(), p.span().into(), p.spacing().into())),
196 other => {
197 if !punct_run.is_empty() {
198 crate::scan_puncts_spanned(&punct_run, tokens);
199 punct_run.clear();
200 }
201 other.to_tokens(tokens);
202 }
203 }
204 }
205
206 if !punct_run.is_empty() {
207 crate::scan_puncts_spanned(&punct_run, tokens);
208 }
209 }
210}
211
212impl ToTokens<proc_macro::TokenStream> for TokenTree {
213 fn to_tokens(&self, out: &mut proc_macro::TokenStream) {
214 match self {
215 Self::Group(g) => out.extend(vec![proc_macro::TokenTree::Group(g.clone().into())]),
216 Self::Ident(v) => out.extend(vec![proc_macro::TokenTree::Ident(v.clone().into())]),
217 Self::Keyword(kw) => {
218 let id = proc_macro::Ident::new(kw.as_str(), kw.span().into());
219 out.extend(vec![proc_macro::TokenTree::Ident(id)])
220 }
221 Self::Literal(Lit::Bool(v)) => {
223 let id = proc_macro::Ident::new(v.repr(), v.span().into());
224 out.extend(vec![proc_macro::TokenTree::Ident(id)])
225 }
226 Self::Literal(v) => out.extend(vec![proc_macro::TokenTree::Literal(v.clone().into())]),
227 Self::Punct(op) => {
228 let text = op.as_str();
229 let span: proc_macro::Span = op.span().into();
230 let last = text.chars().count() - 1;
231
232 for (i, ch) in text.chars().enumerate() {
233 let spacing = if i == last {
234 op.spacing().into()
235 } else {
236 proc_macro::Spacing::Joint
237 };
238
239 let mut p = proc_macro::Punct::new(ch, spacing);
240 p.set_span(span);
241 out.extend(vec![proc_macro::TokenTree::Punct(p)]);
242 }
243 }
244 }
245 }
246}
247
248impl ToTokens<proc_macro::TokenStream> for TokenStream {
249 fn to_tokens(&self, out: &mut proc_macro::TokenStream) {
250 for t in self.iter() {
251 t.to_tokens(out);
252 }
253 }
254}
255
256impl From<proc_macro::TokenStream> for TokenStream {
257 fn from(value: proc_macro::TokenStream) -> Self {
258 let mut out = Self::new();
259 value.to_tokens(&mut out);
260 out
261 }
262}
263
264impl From<TokenStream> for proc_macro::TokenStream {
265 fn from(value: TokenStream) -> Self {
266 let mut out = Self::new();
267
268 for t in value.iter() {
269 t.to_tokens(&mut out);
270 }
271
272 out
273 }
274}
275
276impl TryIntoTokenStream for proc_macro::TokenStream {
277 fn try_into_token_stream(self) -> Result<TokenStream, LexError> {
278 Ok(self.into())
279 }
280}
281
282impl TryIntoTokenStream for &proc_macro::TokenStream {
283 fn try_into_token_stream(self) -> Result<TokenStream, LexError> {
284 Ok(self.clone().into())
285 }
286}