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