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