1 use crate::syntax::atom::Atom::*;
2 use crate::syntax::{
3     Array, Atom, Derive, Enum, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr, Receiver,
4     Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
5 };
6 use proc_macro2::{Ident, Span, TokenStream};
7 use quote::{quote_spanned, ToTokens};
8 use syn::{token, Token};
9 
10 impl ToTokens for Type {
to_tokens(&self, tokens: &mut TokenStream)11     fn to_tokens(&self, tokens: &mut TokenStream) {
12         match self {
13             Type::Ident(ident) => {
14                 if ident.rust == Char {
15                     let span = ident.rust.span();
16                     tokens.extend(quote_spanned!(span=> ::std::os::raw::));
17                 } else if ident.rust == CxxString {
18                     let span = ident.rust.span();
19                     tokens.extend(quote_spanned!(span=> ::cxx::));
20                 }
21                 ident.to_tokens(tokens);
22             }
23             Type::RustBox(ty)
24             | Type::UniquePtr(ty)
25             | Type::SharedPtr(ty)
26             | Type::WeakPtr(ty)
27             | Type::CxxVector(ty)
28             | Type::RustVec(ty) => ty.to_tokens(tokens),
29             Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
30             Type::Ptr(p) => p.to_tokens(tokens),
31             Type::Array(a) => a.to_tokens(tokens),
32             Type::Fn(f) => f.to_tokens(tokens),
33             Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
34             Type::SliceRef(r) => r.to_tokens(tokens),
35         }
36     }
37 }
38 
39 impl ToTokens for Var {
to_tokens(&self, tokens: &mut TokenStream)40     fn to_tokens(&self, tokens: &mut TokenStream) {
41         let Var {
42             doc: _,
43             attrs: _,
44             visibility: _,
45             name,
46             ty,
47         } = self;
48         name.rust.to_tokens(tokens);
49         Token![:](name.rust.span()).to_tokens(tokens);
50         ty.to_tokens(tokens);
51     }
52 }
53 
54 impl ToTokens for Ty1 {
to_tokens(&self, tokens: &mut TokenStream)55     fn to_tokens(&self, tokens: &mut TokenStream) {
56         let Ty1 {
57             name,
58             langle,
59             inner,
60             rangle,
61         } = self;
62         let span = name.span();
63         match name.to_string().as_str() {
64             "UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" => {
65                 tokens.extend(quote_spanned!(span=> ::cxx::));
66             }
67             "Vec" => {
68                 tokens.extend(quote_spanned!(span=> ::std::vec::));
69             }
70             _ => {}
71         }
72         name.to_tokens(tokens);
73         langle.to_tokens(tokens);
74         inner.to_tokens(tokens);
75         rangle.to_tokens(tokens);
76     }
77 }
78 
79 impl ToTokens for Ref {
to_tokens(&self, tokens: &mut TokenStream)80     fn to_tokens(&self, tokens: &mut TokenStream) {
81         let Ref {
82             pinned: _,
83             ampersand,
84             lifetime,
85             mutable: _,
86             inner,
87             pin_tokens,
88             mutability,
89         } = self;
90         if let Some((pin, langle, _rangle)) = pin_tokens {
91             tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
92             langle.to_tokens(tokens);
93         }
94         ampersand.to_tokens(tokens);
95         lifetime.to_tokens(tokens);
96         mutability.to_tokens(tokens);
97         inner.to_tokens(tokens);
98         if let Some((_pin, _langle, rangle)) = pin_tokens {
99             rangle.to_tokens(tokens);
100         }
101     }
102 }
103 
104 impl ToTokens for Ptr {
to_tokens(&self, tokens: &mut TokenStream)105     fn to_tokens(&self, tokens: &mut TokenStream) {
106         let Ptr {
107             star,
108             mutable: _,
109             inner,
110             mutability,
111             constness,
112         } = self;
113         star.to_tokens(tokens);
114         mutability.to_tokens(tokens);
115         constness.to_tokens(tokens);
116         inner.to_tokens(tokens);
117     }
118 }
119 
120 impl ToTokens for SliceRef {
to_tokens(&self, tokens: &mut TokenStream)121     fn to_tokens(&self, tokens: &mut TokenStream) {
122         let SliceRef {
123             ampersand,
124             lifetime,
125             mutable: _,
126             bracket,
127             inner,
128             mutability,
129         } = self;
130         ampersand.to_tokens(tokens);
131         lifetime.to_tokens(tokens);
132         mutability.to_tokens(tokens);
133         bracket.surround(tokens, |tokens| {
134             inner.to_tokens(tokens);
135         });
136     }
137 }
138 
139 impl ToTokens for Array {
to_tokens(&self, tokens: &mut TokenStream)140     fn to_tokens(&self, tokens: &mut TokenStream) {
141         let Array {
142             bracket,
143             inner,
144             semi_token,
145             len: _,
146             len_token,
147         } = self;
148         bracket.surround(tokens, |tokens| {
149             inner.to_tokens(tokens);
150             semi_token.to_tokens(tokens);
151             len_token.to_tokens(tokens);
152         });
153     }
154 }
155 
156 impl ToTokens for Atom {
to_tokens(&self, tokens: &mut TokenStream)157     fn to_tokens(&self, tokens: &mut TokenStream) {
158         Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
159     }
160 }
161 
162 impl ToTokens for Derive {
to_tokens(&self, tokens: &mut TokenStream)163     fn to_tokens(&self, tokens: &mut TokenStream) {
164         Ident::new(self.what.as_ref(), self.span).to_tokens(tokens);
165     }
166 }
167 
168 impl ToTokens for ExternType {
to_tokens(&self, tokens: &mut TokenStream)169     fn to_tokens(&self, tokens: &mut TokenStream) {
170         // Notional token range for error reporting purposes.
171         self.type_token.to_tokens(tokens);
172         self.name.rust.to_tokens(tokens);
173         self.generics.to_tokens(tokens);
174     }
175 }
176 
177 impl ToTokens for TypeAlias {
to_tokens(&self, tokens: &mut TokenStream)178     fn to_tokens(&self, tokens: &mut TokenStream) {
179         // Notional token range for error reporting purposes.
180         self.type_token.to_tokens(tokens);
181         self.name.rust.to_tokens(tokens);
182         self.generics.to_tokens(tokens);
183     }
184 }
185 
186 impl ToTokens for Struct {
to_tokens(&self, tokens: &mut TokenStream)187     fn to_tokens(&self, tokens: &mut TokenStream) {
188         // Notional token range for error reporting purposes.
189         self.struct_token.to_tokens(tokens);
190         self.name.rust.to_tokens(tokens);
191         self.generics.to_tokens(tokens);
192     }
193 }
194 
195 impl ToTokens for Enum {
to_tokens(&self, tokens: &mut TokenStream)196     fn to_tokens(&self, tokens: &mut TokenStream) {
197         // Notional token range for error reporting purposes.
198         self.enum_token.to_tokens(tokens);
199         self.name.rust.to_tokens(tokens);
200         self.generics.to_tokens(tokens);
201     }
202 }
203 
204 impl ToTokens for ExternFn {
to_tokens(&self, tokens: &mut TokenStream)205     fn to_tokens(&self, tokens: &mut TokenStream) {
206         // Notional token range for error reporting purposes.
207         self.unsafety.to_tokens(tokens);
208         self.sig.fn_token.to_tokens(tokens);
209         self.semi_token.to_tokens(tokens);
210     }
211 }
212 
213 impl ToTokens for Impl {
to_tokens(&self, tokens: &mut TokenStream)214     fn to_tokens(&self, tokens: &mut TokenStream) {
215         let Impl {
216             impl_token,
217             impl_generics,
218             negative: _,
219             ty,
220             ty_generics: _,
221             brace_token,
222             negative_token,
223         } = self;
224         impl_token.to_tokens(tokens);
225         impl_generics.to_tokens(tokens);
226         negative_token.to_tokens(tokens);
227         ty.to_tokens(tokens);
228         brace_token.surround(tokens, |_tokens| {});
229     }
230 }
231 
232 impl ToTokens for Lifetimes {
to_tokens(&self, tokens: &mut TokenStream)233     fn to_tokens(&self, tokens: &mut TokenStream) {
234         let Lifetimes {
235             lt_token,
236             lifetimes,
237             gt_token,
238         } = self;
239         lt_token.to_tokens(tokens);
240         lifetimes.to_tokens(tokens);
241         gt_token.to_tokens(tokens);
242     }
243 }
244 
245 impl ToTokens for Signature {
to_tokens(&self, tokens: &mut TokenStream)246     fn to_tokens(&self, tokens: &mut TokenStream) {
247         let Signature {
248             unsafety: _,
249             fn_token,
250             generics: _,
251             receiver: _,
252             args,
253             ret,
254             throws: _,
255             paren_token,
256             throws_tokens,
257         } = self;
258         fn_token.to_tokens(tokens);
259         paren_token.surround(tokens, |tokens| {
260             args.to_tokens(tokens);
261         });
262         if let Some(ret) = ret {
263             Token![->](paren_token.span).to_tokens(tokens);
264             if let Some((result, langle, rangle)) = throws_tokens {
265                 result.to_tokens(tokens);
266                 langle.to_tokens(tokens);
267                 ret.to_tokens(tokens);
268                 rangle.to_tokens(tokens);
269             } else {
270                 ret.to_tokens(tokens);
271             }
272         } else if let Some((result, langle, rangle)) = throws_tokens {
273             Token![->](paren_token.span).to_tokens(tokens);
274             result.to_tokens(tokens);
275             langle.to_tokens(tokens);
276             token::Paren(langle.span).surround(tokens, |_| ());
277             rangle.to_tokens(tokens);
278         }
279     }
280 }
281 
282 impl ToTokens for NamedType {
to_tokens(&self, tokens: &mut TokenStream)283     fn to_tokens(&self, tokens: &mut TokenStream) {
284         let NamedType { rust, generics } = self;
285         rust.to_tokens(tokens);
286         generics.to_tokens(tokens);
287     }
288 }
289 
290 pub struct ReceiverType<'a>(&'a Receiver);
291 pub struct ReceiverTypeSelf<'a>(&'a Receiver);
292 
293 impl Receiver {
294     // &TheType
ty(&self) -> ReceiverType295     pub fn ty(&self) -> ReceiverType {
296         ReceiverType(self)
297     }
298 
299     // &Self
ty_self(&self) -> ReceiverTypeSelf300     pub fn ty_self(&self) -> ReceiverTypeSelf {
301         ReceiverTypeSelf(self)
302     }
303 }
304 
305 impl ToTokens for ReceiverType<'_> {
to_tokens(&self, tokens: &mut TokenStream)306     fn to_tokens(&self, tokens: &mut TokenStream) {
307         let Receiver {
308             pinned: _,
309             ampersand,
310             lifetime,
311             mutable: _,
312             var: _,
313             ty,
314             shorthand: _,
315             pin_tokens,
316             mutability,
317         } = &self.0;
318         if let Some((pin, langle, _rangle)) = pin_tokens {
319             tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
320             langle.to_tokens(tokens);
321         }
322         ampersand.to_tokens(tokens);
323         lifetime.to_tokens(tokens);
324         mutability.to_tokens(tokens);
325         ty.to_tokens(tokens);
326         if let Some((_pin, _langle, rangle)) = pin_tokens {
327             rangle.to_tokens(tokens);
328         }
329     }
330 }
331 
332 impl ToTokens for ReceiverTypeSelf<'_> {
to_tokens(&self, tokens: &mut TokenStream)333     fn to_tokens(&self, tokens: &mut TokenStream) {
334         let Receiver {
335             pinned: _,
336             ampersand,
337             lifetime,
338             mutable: _,
339             var: _,
340             ty,
341             shorthand: _,
342             pin_tokens,
343             mutability,
344         } = &self.0;
345         if let Some((pin, langle, _rangle)) = pin_tokens {
346             tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
347             langle.to_tokens(tokens);
348         }
349         ampersand.to_tokens(tokens);
350         lifetime.to_tokens(tokens);
351         mutability.to_tokens(tokens);
352         Token![Self](ty.rust.span()).to_tokens(tokens);
353         if let Some((_pin, _langle, rangle)) = pin_tokens {
354             rangle.to_tokens(tokens);
355         }
356     }
357 }
358