1use crate::syntax::atom::Atom::*; 2use crate::syntax::{ 3 Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr, 4 Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, 5}; 6use proc_macro2::{Ident, Span, TokenStream}; 7use quote::{quote_spanned, ToTokens}; 8use syn::{token, Token}; 9 10impl ToTokens for Type { 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 42impl ToTokens for Var { 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).to_tokens(tokens); 55 ty.to_tokens(tokens); 56 } 57} 58 59impl ToTokens for Ty1 { 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 87impl ToTokens for Ref { 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 112impl ToTokens for Ptr { 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 128impl ToTokens for SliceRef { 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 147impl ToTokens for Array { 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 164impl ToTokens for Atom { 165 fn to_tokens(&self, tokens: &mut TokenStream) { 166 Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens); 167 } 168} 169 170impl ToTokens for Derive { 171 fn to_tokens(&self, tokens: &mut TokenStream) { 172 Ident::new(self.what.as_ref(), self.span).to_tokens(tokens); 173 } 174} 175 176impl ToTokens for ExternType { 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 185impl ToTokens for TypeAlias { 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 194impl ToTokens for Struct { 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 203impl ToTokens for Enum { 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 212impl ToTokens for ExternFn { 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 221impl ToTokens for Impl { 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 241impl ToTokens for Lifetimes { 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 254impl ToTokens for Signature { 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).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).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 292impl ToTokens for EnumRepr { 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 302impl ToTokens for NamedType { 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