blob: df0b7020118c78c8884088461bc9da8224d7afec [file] [log] [blame]
David Tolnaya52602b2020-03-06 10:24:34 -08001use crate::syntax::atom::Atom::*;
David Tolnay83496eb2020-05-04 00:36:53 -07002use crate::syntax::{
David Tolnay77a5e752021-01-01 14:15:18 -08003 Array, Atom, Derive, Enum, ExternFn, ExternType, Impl, Lifetimes, NamedType, Receiver, Ref,
David Tolnay8c80de72020-12-28 22:13:34 -08004 Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
David Tolnay83496eb2020-05-04 00:36:53 -07005};
David Tolnay7db73692019-10-20 14:51:12 -04006use proc_macro2::{Ident, Span, TokenStream};
David Tolnayc071b892020-03-18 16:59:53 -07007use quote::{quote_spanned, ToTokens};
David Tolnay57c166d2020-11-14 23:38:31 -08008use syn::{token, Token};
David Tolnay7db73692019-10-20 14:51:12 -04009
10impl ToTokens for Type {
11 fn to_tokens(&self, tokens: &mut TokenStream) {
12 match self {
13 Type::Ident(ident) => {
David Tolnayb3873dc2020-11-25 19:47:49 -080014 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 {
Adrian Taylorc8713432020-10-21 18:20:55 -070018 let span = ident.rust.span();
David Tolnay7db73692019-10-20 14:51:12 -040019 tokens.extend(quote_spanned!(span=> ::cxx::));
20 }
David Tolnay89fd09b2020-12-31 02:01:31 -080021 ident.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -040022 }
David Tolnayb3b24a12020-12-01 15:27:43 -080023 Type::RustBox(ty)
24 | Type::UniquePtr(ty)
25 | Type::SharedPtr(ty)
David Tolnay215e77f2020-12-28 17:09:48 -080026 | Type::WeakPtr(ty)
David Tolnayb3b24a12020-12-01 15:27:43 -080027 | Type::CxxVector(ty)
28 | Type::RustVec(ty) => ty.to_tokens(tokens),
David Tolnaye0dca7b2020-11-25 17:18:57 -080029 Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
Xiangpeng Hao78762352020-11-12 10:24:18 +080030 Type::Array(a) => a.to_tokens(tokens),
David Tolnayc071b892020-03-18 16:59:53 -070031 Type::Fn(f) => f.to_tokens(tokens),
David Tolnayd0bb3642020-03-15 23:27:11 -070032 Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
David Tolnay73b72642020-11-25 17:44:05 -080033 Type::SliceRef(r) => r.to_tokens(tokens),
David Tolnay7db73692019-10-20 14:51:12 -040034 }
35 }
36}
37
38impl ToTokens for Var {
39 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -080040 let Var {
41 doc: _,
42 attrs: _,
43 visibility: _,
44 ident,
45 ty,
46 } = self;
47 ident.to_tokens(tokens);
48 Token![:](ident.span()).to_tokens(tokens);
49 ty.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -040050 }
51}
52
53impl ToTokens for Ty1 {
54 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -080055 let Ty1 {
56 name,
57 langle,
58 inner,
59 rangle,
60 } = self;
61 let span = name.span();
62 match name.to_string().as_str() {
63 "UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" => {
64 tokens.extend(quote_spanned!(span=> ::cxx::));
65 }
66 "Vec" => {
67 tokens.extend(quote_spanned!(span=> ::std::vec::));
68 }
69 _ => {}
David Tolnay7db73692019-10-20 14:51:12 -040070 }
David Tolnay444f2dc2020-12-30 19:52:56 -080071 name.to_tokens(tokens);
72 langle.to_tokens(tokens);
73 inner.to_tokens(tokens);
74 rangle.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -040075 }
76}
77
78impl ToTokens for Ref {
79 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -080080 let Ref {
81 pinned: _,
82 ampersand,
83 lifetime,
84 mutable: _,
85 inner,
86 pin_tokens,
87 mutability,
88 } = self;
89 if let Some((pin, langle, _rangle)) = pin_tokens {
David Tolnayc9673842020-11-15 16:26:10 -080090 tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
91 langle.to_tokens(tokens);
92 }
David Tolnay444f2dc2020-12-30 19:52:56 -080093 ampersand.to_tokens(tokens);
94 lifetime.to_tokens(tokens);
95 mutability.to_tokens(tokens);
96 inner.to_tokens(tokens);
97 if let Some((_pin, _langle, rangle)) = pin_tokens {
David Tolnayc9673842020-11-15 16:26:10 -080098 rangle.to_tokens(tokens);
99 }
David Tolnay7db73692019-10-20 14:51:12 -0400100 }
101}
102
David Tolnaye0dca7b2020-11-25 17:18:57 -0800103impl ToTokens for SliceRef {
104 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800105 let SliceRef {
106 ampersand,
107 lifetime,
108 mutable: _,
109 bracket,
110 inner,
111 mutability,
112 } = self;
113 ampersand.to_tokens(tokens);
114 lifetime.to_tokens(tokens);
115 mutability.to_tokens(tokens);
116 bracket.surround(tokens, |tokens| {
117 inner.to_tokens(tokens);
David Tolnaye0dca7b2020-11-25 17:18:57 -0800118 });
119 }
120}
121
Xiangpeng Hao78762352020-11-12 10:24:18 +0800122impl ToTokens for Array {
123 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800124 let Array {
125 bracket,
126 inner,
127 semi_token,
128 len: _,
129 len_token,
130 } = self;
131 bracket.surround(tokens, |tokens| {
132 inner.to_tokens(tokens);
133 semi_token.to_tokens(tokens);
134 len_token.to_tokens(tokens);
Xiangpeng Hao78762352020-11-12 10:24:18 +0800135 });
136 }
137}
138
David Tolnayc605e6f2020-05-10 23:37:12 -0700139impl ToTokens for Atom {
140 fn to_tokens(&self, tokens: &mut TokenStream) {
141 Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);
142 }
143}
144
David Tolnayb600e4f2020-11-27 17:26:49 -0800145impl ToTokens for Derive {
146 fn to_tokens(&self, tokens: &mut TokenStream) {
147 Ident::new(self.what.as_ref(), self.span).to_tokens(tokens);
148 }
149}
150
David Tolnay83496eb2020-05-04 00:36:53 -0700151impl ToTokens for ExternType {
152 fn to_tokens(&self, tokens: &mut TokenStream) {
153 // Notional token range for error reporting purposes.
154 self.type_token.to_tokens(tokens);
David Tolnay9bb232b2020-11-02 00:55:18 -0800155 self.name.rust.to_tokens(tokens);
David Tolnay83496eb2020-05-04 00:36:53 -0700156 }
157}
158
David Tolnay99383812020-05-04 02:34:33 -0700159impl ToTokens for TypeAlias {
160 fn to_tokens(&self, tokens: &mut TokenStream) {
161 // Notional token range for error reporting purposes.
162 self.type_token.to_tokens(tokens);
David Tolnay9bb232b2020-11-02 00:55:18 -0800163 self.name.rust.to_tokens(tokens);
David Tolnay99383812020-05-04 02:34:33 -0700164 }
165}
166
David Tolnay83496eb2020-05-04 00:36:53 -0700167impl ToTokens for Struct {
168 fn to_tokens(&self, tokens: &mut TokenStream) {
169 // Notional token range for error reporting purposes.
170 self.struct_token.to_tokens(tokens);
David Tolnay9bb232b2020-11-02 00:55:18 -0800171 self.name.rust.to_tokens(tokens);
David Tolnay83496eb2020-05-04 00:36:53 -0700172 }
173}
174
175impl ToTokens for Enum {
176 fn to_tokens(&self, tokens: &mut TokenStream) {
177 // Notional token range for error reporting purposes.
178 self.enum_token.to_tokens(tokens);
David Tolnay9bb232b2020-11-02 00:55:18 -0800179 self.name.rust.to_tokens(tokens);
David Tolnay83496eb2020-05-04 00:36:53 -0700180 }
181}
182
David Tolnay7db73692019-10-20 14:51:12 -0400183impl ToTokens for ExternFn {
184 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnaye3a48152020-04-08 19:38:05 -0700185 // Notional token range for error reporting purposes.
186 self.sig.fn_token.to_tokens(tokens);
187 self.semi_token.to_tokens(tokens);
David Tolnay7db73692019-10-20 14:51:12 -0400188 }
189}
David Tolnayc071b892020-03-18 16:59:53 -0700190
David Tolnay7e69f892020-10-03 22:20:22 -0700191impl ToTokens for Impl {
192 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800193 let Impl {
194 impl_token,
David Tolnayc455e972020-12-31 14:40:23 -0800195 generics,
David Tolnay444f2dc2020-12-30 19:52:56 -0800196 negative: _,
197 ty,
198 brace_token,
199 negative_token,
200 } = self;
201 impl_token.to_tokens(tokens);
David Tolnayc455e972020-12-31 14:40:23 -0800202 generics.to_tokens(tokens);
David Tolnay444f2dc2020-12-30 19:52:56 -0800203 negative_token.to_tokens(tokens);
204 ty.to_tokens(tokens);
205 brace_token.surround(tokens, |_tokens| {});
David Tolnay7e69f892020-10-03 22:20:22 -0700206 }
207}
208
David Tolnay8c80de72020-12-28 22:13:34 -0800209impl ToTokens for Lifetimes {
210 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800211 let Lifetimes {
212 lt_token,
213 lifetimes,
214 gt_token,
215 } = self;
216 lt_token.to_tokens(tokens);
217 lifetimes.to_tokens(tokens);
218 gt_token.to_tokens(tokens);
David Tolnay8c80de72020-12-28 22:13:34 -0800219 }
220}
221
David Tolnayc071b892020-03-18 16:59:53 -0700222impl ToTokens for Signature {
223 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800224 let Signature {
225 unsafety: _,
226 fn_token,
227 generics: _,
228 receiver: _,
229 args,
230 ret,
231 throws: _,
232 paren_token,
233 throws_tokens,
234 } = self;
235 fn_token.to_tokens(tokens);
236 paren_token.surround(tokens, |tokens| {
237 args.to_tokens(tokens);
David Tolnaye3a48152020-04-08 19:38:05 -0700238 });
David Tolnay444f2dc2020-12-30 19:52:56 -0800239 if let Some(ret) = ret {
240 Token![->](paren_token.span).to_tokens(tokens);
241 if let Some((result, langle, rangle)) = throws_tokens {
David Tolnaye3a48152020-04-08 19:38:05 -0700242 result.to_tokens(tokens);
243 langle.to_tokens(tokens);
244 ret.to_tokens(tokens);
245 rangle.to_tokens(tokens);
246 } else {
247 ret.to_tokens(tokens);
248 }
David Tolnay444f2dc2020-12-30 19:52:56 -0800249 } else if let Some((result, langle, rangle)) = throws_tokens {
250 Token![->](paren_token.span).to_tokens(tokens);
David Tolnay57c166d2020-11-14 23:38:31 -0800251 result.to_tokens(tokens);
252 langle.to_tokens(tokens);
253 token::Paren(langle.span).surround(tokens, |_| ());
254 rangle.to_tokens(tokens);
David Tolnaye3a48152020-04-08 19:38:05 -0700255 }
David Tolnayc071b892020-03-18 16:59:53 -0700256 }
257}
David Tolnayfb6e3862020-04-20 01:33:23 -0700258
David Tolnay77a5e752021-01-01 14:15:18 -0800259impl ToTokens for NamedType {
Adrian Taylorc8713432020-10-21 18:20:55 -0700260 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay77a5e752021-01-01 14:15:18 -0800261 let NamedType { rust, generics } = self;
David Tolnay444f2dc2020-12-30 19:52:56 -0800262 rust.to_tokens(tokens);
David Tolnay679b15d2020-12-30 20:39:06 -0800263 generics.to_tokens(tokens);
Adrian Taylorc8713432020-10-21 18:20:55 -0700264 }
265}
266
David Tolnay18ba92c2020-04-22 16:17:30 -0700267pub struct ReceiverType<'a>(&'a Receiver);
268
269impl Receiver {
270 // &TheType
271 pub fn ty(&self) -> ReceiverType {
272 ReceiverType(self)
273 }
274}
275
276impl ToTokens for ReceiverType<'_> {
David Tolnayfb6e3862020-04-20 01:33:23 -0700277 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay444f2dc2020-12-30 19:52:56 -0800278 let Receiver {
279 pinned: _,
280 ampersand,
281 lifetime,
282 mutable: _,
283 var: _,
284 ty,
285 shorthand: _,
286 pin_tokens,
287 mutability,
288 } = &self.0;
289 if let Some((pin, langle, _rangle)) = pin_tokens {
David Tolnayc9673842020-11-15 16:26:10 -0800290 tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
291 langle.to_tokens(tokens);
292 }
David Tolnay444f2dc2020-12-30 19:52:56 -0800293 ampersand.to_tokens(tokens);
294 lifetime.to_tokens(tokens);
295 mutability.to_tokens(tokens);
296 ty.to_tokens(tokens);
297 if let Some((_pin, _langle, rangle)) = pin_tokens {
David Tolnayc9673842020-11-15 16:26:10 -0800298 rangle.to_tokens(tokens);
299 }
David Tolnayfb6e3862020-04-20 01:33:23 -0700300 }
301}