• 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     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=> ::cxx::private::));
17                 } else if ident.rust == CxxString {
18                     let span = ident.rust.span();
19                     tokens.extend(quote_spanned!(span=> ::cxx::));
20                 } else if ident.rust == RustString {
21                     let span = ident.rust.span();
22                     tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::));
23                 }
24                 ident.to_tokens(tokens);
25             }
26             Type::RustBox(ty)
27             | Type::UniquePtr(ty)
28             | Type::SharedPtr(ty)
29             | Type::WeakPtr(ty)
30             | Type::CxxVector(ty)
31             | Type::RustVec(ty) => ty.to_tokens(tokens),
32             Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
33             Type::Ptr(p) => p.to_tokens(tokens),
34             Type::Array(a) => a.to_tokens(tokens),
35             Type::Fn(f) => f.to_tokens(tokens),
36             Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
37             Type::SliceRef(r) => r.to_tokens(tokens),
38         }
39     }
40 }
41 
42 impl ToTokens for Var {
to_tokens(&self, tokens: &mut TokenStream)43     fn to_tokens(&self, tokens: &mut TokenStream) {
44         let Var {
45             cfg: _,
46             doc: _,
47             attrs: _,
48             visibility: _,
49             name,
50             colon_token: _,
51             ty,
52         } = self;
53         name.rust.to_tokens(tokens);
54         Token![:](name.rust.span()).to_tokens(tokens);
55         ty.to_tokens(tokens);
56     }
57 }
58 
59 impl ToTokens for Ty1 {
to_tokens(&self, tokens: &mut TokenStream)60     fn to_tokens(&self, tokens: &mut TokenStream) {
61         let Ty1 {
62             name,
63             langle,
64             inner,
65             rangle,
66         } = self;
67         let span = name.span();
68         match name.to_string().as_str() {
69             "UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" => {
70                 tokens.extend(quote_spanned!(span=> ::cxx::));
71             }
72             "Box" => {
73                 tokens.extend(quote_spanned!(span=> ::cxx::alloc::boxed::));
74             }
75             "Vec" => {
76                 tokens.extend(quote_spanned!(span=> ::cxx::alloc::vec::));
77             }
78             _ => {}
79         }
80         name.to_tokens(tokens);
81         langle.to_tokens(tokens);
82         inner.to_tokens(tokens);
83         rangle.to_tokens(tokens);
84     }
85 }
86 
87 impl ToTokens for Ref {
to_tokens(&self, tokens: &mut TokenStream)88     fn to_tokens(&self, tokens: &mut TokenStream) {
89         let Ref {
90             pinned: _,
91             ampersand,
92             lifetime,
93             mutable: _,
94             inner,
95             pin_tokens,
96             mutability,
97         } = self;
98         if let Some((pin, langle, _rangle)) = pin_tokens {
99             tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));
100             langle.to_tokens(tokens);
101         }
102         ampersand.to_tokens(tokens);
103         lifetime.to_tokens(tokens);
104         mutability.to_tokens(tokens);
105         inner.to_tokens(tokens);
106         if let Some((_pin, _langle, rangle)) = pin_tokens {
107             rangle.to_tokens(tokens);
108         }
109     }
110 }
111 
112 impl ToTokens for Ptr {
to_tokens(&self, tokens: &mut TokenStream)113     fn to_tokens(&self, tokens: &mut TokenStream) {
114         let Ptr {
115             star,
116             mutable: _,
117             inner,
118             mutability,
119             constness,
120         } = self;
121         star.to_tokens(tokens);
122         mutability.to_tokens(tokens);
123         constness.to_tokens(tokens);
124         inner.to_tokens(tokens);
125     }
126 }
127 
128 impl ToTokens for SliceRef {
to_tokens(&self, tokens: &mut TokenStream)129     fn to_tokens(&self, tokens: &mut TokenStream) {
130         let SliceRef {
131             ampersand,
132             lifetime,
133             mutable: _,
134             bracket,
135             inner,
136             mutability,
137         } = self;
138         ampersand.to_tokens(tokens);
139         lifetime.to_tokens(tokens);
140         mutability.to_tokens(tokens);
141         bracket.surround(tokens, |tokens| {
142             inner.to_tokens(tokens);
143         });
144     }
145 }
146 
147 impl ToTokens for Array {
to_tokens(&self, tokens: &mut TokenStream)148     fn to_tokens(&self, tokens: &mut TokenStream) {
149         let Array {
150             bracket,
151             inner,
152             semi_token,
153             len: _,
154             len_token,
155         } = self;
156         bracket.surround(tokens, |tokens| {
157             inner.to_tokens(tokens);
158             semi_token.to_tokens(tokens);
159             len_token.to_tokens(tokens);
160         });
161     }
162 }
163 
164 impl ToTokens for Atom {
to_tokens(&self, tokens: &mut TokenStream)165     fn to_tokens(&self, tokens: &mut TokenStream) {
166         Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
167     }
168 }
169 
170 impl ToTokens for Derive {
to_tokens(&self, tokens: &mut TokenStream)171     fn to_tokens(&self, tokens: &mut TokenStream) {
172         Ident::new(self.what.as_ref(), self.span).to_tokens(tokens);
173     }
174 }
175 
176 impl ToTokens for ExternType {
to_tokens(&self, tokens: &mut TokenStream)177     fn to_tokens(&self, tokens: &mut TokenStream) {
178         // Notional token range for error reporting purposes.
179         self.type_token.to_tokens(tokens);
180         self.name.rust.to_tokens(tokens);
181         self.generics.to_tokens(tokens);
182     }
183 }
184 
185 impl ToTokens for TypeAlias {
to_tokens(&self, tokens: &mut TokenStream)186     fn to_tokens(&self, tokens: &mut TokenStream) {
187         // Notional token range for error reporting purposes.
188         self.type_token.to_tokens(tokens);
189         self.name.rust.to_tokens(tokens);
190         self.generics.to_tokens(tokens);
191     }
192 }
193 
194 impl ToTokens for Struct {
to_tokens(&self, tokens: &mut TokenStream)195     fn to_tokens(&self, tokens: &mut TokenStream) {
196         // Notional token range for error reporting purposes.
197         self.struct_token.to_tokens(tokens);
198         self.name.rust.to_tokens(tokens);
199         self.generics.to_tokens(tokens);
200     }
201 }
202 
203 impl ToTokens for Enum {
to_tokens(&self, tokens: &mut TokenStream)204     fn to_tokens(&self, tokens: &mut TokenStream) {
205         // Notional token range for error reporting purposes.
206         self.enum_token.to_tokens(tokens);
207         self.name.rust.to_tokens(tokens);
208         self.generics.to_tokens(tokens);
209     }
210 }
211 
212 impl ToTokens for ExternFn {
to_tokens(&self, tokens: &mut TokenStream)213     fn to_tokens(&self, tokens: &mut TokenStream) {
214         // Notional token range for error reporting purposes.
215         self.unsafety.to_tokens(tokens);
216         self.sig.fn_token.to_tokens(tokens);
217         self.semi_token.to_tokens(tokens);
218     }
219 }
220 
221 impl ToTokens for Impl {
to_tokens(&self, tokens: &mut TokenStream)222     fn to_tokens(&self, tokens: &mut TokenStream) {
223         let Impl {
224             cfg: _,
225             impl_token,
226             impl_generics,
227             negative: _,
228             ty,
229             ty_generics: _,
230             brace_token,
231             negative_token,
232         } = self;
233         impl_token.to_tokens(tokens);
234         impl_generics.to_tokens(tokens);
235         negative_token.to_tokens(tokens);
236         ty.to_tokens(tokens);
237         brace_token.surround(tokens, |_tokens| {});
238     }
239 }
240 
241 impl ToTokens for Lifetimes {
to_tokens(&self, tokens: &mut TokenStream)242     fn to_tokens(&self, tokens: &mut TokenStream) {
243         let Lifetimes {
244             lt_token,
245             lifetimes,
246             gt_token,
247         } = self;
248         lt_token.to_tokens(tokens);
249         lifetimes.to_tokens(tokens);
250         gt_token.to_tokens(tokens);
251     }
252 }
253 
254 impl ToTokens for Signature {
to_tokens(&self, tokens: &mut TokenStream)255     fn to_tokens(&self, tokens: &mut TokenStream) {
256         let Signature {
257             asyncness: _,
258             unsafety: _,
259             fn_token,
260             generics: _,
261             receiver: _,
262             args,
263             ret,
264             throws: _,
265             paren_token,
266             throws_tokens,
267         } = self;
268         fn_token.to_tokens(tokens);
269         paren_token.surround(tokens, |tokens| {
270             args.to_tokens(tokens);
271         });
272         if let Some(ret) = ret {
273             Token![->](paren_token.span).to_tokens(tokens);
274             if let Some((result, langle, rangle)) = throws_tokens {
275                 result.to_tokens(tokens);
276                 langle.to_tokens(tokens);
277                 ret.to_tokens(tokens);
278                 rangle.to_tokens(tokens);
279             } else {
280                 ret.to_tokens(tokens);
281             }
282         } else if let Some((result, langle, rangle)) = throws_tokens {
283             Token![->](paren_token.span).to_tokens(tokens);
284             result.to_tokens(tokens);
285             langle.to_tokens(tokens);
286             token::Paren(langle.span).surround(tokens, |_| ());
287             rangle.to_tokens(tokens);
288         }
289     }
290 }
291 
292 impl ToTokens for EnumRepr {
to_tokens(&self, tokens: &mut TokenStream)293     fn to_tokens(&self, tokens: &mut TokenStream) {
294         match self {
295             EnumRepr::Native { atom, repr_type: _ } => atom.to_tokens(tokens),
296             #[cfg(feature = "experimental-enum-variants-from-header")]
297             EnumRepr::Foreign { rust_type } => rust_type.to_tokens(tokens),
298         }
299     }
300 }
301 
302 impl ToTokens for NamedType {
to_tokens(&self, tokens: &mut TokenStream)303     fn to_tokens(&self, tokens: &mut TokenStream) {
304         let NamedType { rust, generics } = self;
305         rust.to_tokens(tokens);
306         generics.to_tokens(tokens);
307     }
308 }
309