1 use crate::algorithm::Printer; 2 use crate::iter::IterDelimited; 3 use crate::path::PathKind; 4 use crate::INDENT; 5 use proc_macro2::TokenStream; 6 use syn::{ 7 Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup, 8 TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, 9 TypeSlice, TypeTraitObject, TypeTuple, 10 }; 11 12 impl Printer { ty(&mut self, ty: &Type)13 pub fn ty(&mut self, ty: &Type) { 14 match ty { 15 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 16 Type::Array(ty) => self.type_array(ty), 17 Type::BareFn(ty) => self.type_bare_fn(ty), 18 Type::Group(ty) => self.type_group(ty), 19 Type::ImplTrait(ty) => self.type_impl_trait(ty), 20 Type::Infer(ty) => self.type_infer(ty), 21 Type::Macro(ty) => self.type_macro(ty), 22 Type::Never(ty) => self.type_never(ty), 23 Type::Paren(ty) => self.type_paren(ty), 24 Type::Path(ty) => self.type_path(ty), 25 Type::Ptr(ty) => self.type_ptr(ty), 26 Type::Reference(ty) => self.type_reference(ty), 27 Type::Slice(ty) => self.type_slice(ty), 28 Type::TraitObject(ty) => self.type_trait_object(ty), 29 Type::Tuple(ty) => self.type_tuple(ty), 30 Type::Verbatim(ty) => self.type_verbatim(ty), 31 _ => unimplemented!("unknown Type"), 32 } 33 } 34 type_array(&mut self, ty: &TypeArray)35 fn type_array(&mut self, ty: &TypeArray) { 36 self.word("["); 37 self.ty(&ty.elem); 38 self.word("; "); 39 self.expr(&ty.len); 40 self.word("]"); 41 } 42 type_bare_fn(&mut self, ty: &TypeBareFn)43 fn type_bare_fn(&mut self, ty: &TypeBareFn) { 44 if let Some(bound_lifetimes) = &ty.lifetimes { 45 self.bound_lifetimes(bound_lifetimes); 46 } 47 if ty.unsafety.is_some() { 48 self.word("unsafe "); 49 } 50 if let Some(abi) = &ty.abi { 51 self.abi(abi); 52 } 53 self.word("fn("); 54 self.cbox(INDENT); 55 self.zerobreak(); 56 for bare_fn_arg in ty.inputs.iter().delimited() { 57 self.bare_fn_arg(&bare_fn_arg); 58 self.trailing_comma(bare_fn_arg.is_last && ty.variadic.is_none()); 59 } 60 if let Some(variadic) = &ty.variadic { 61 self.bare_variadic(variadic); 62 self.zerobreak(); 63 } 64 self.offset(-INDENT); 65 self.end(); 66 self.word(")"); 67 self.return_type(&ty.output); 68 } 69 type_group(&mut self, ty: &TypeGroup)70 fn type_group(&mut self, ty: &TypeGroup) { 71 self.ty(&ty.elem); 72 } 73 type_impl_trait(&mut self, ty: &TypeImplTrait)74 fn type_impl_trait(&mut self, ty: &TypeImplTrait) { 75 self.word("impl "); 76 for type_param_bound in ty.bounds.iter().delimited() { 77 if !type_param_bound.is_first { 78 self.word(" + "); 79 } 80 self.type_param_bound(&type_param_bound); 81 } 82 } 83 type_infer(&mut self, ty: &TypeInfer)84 fn type_infer(&mut self, ty: &TypeInfer) { 85 let _ = ty; 86 self.word("_"); 87 } 88 type_macro(&mut self, ty: &TypeMacro)89 fn type_macro(&mut self, ty: &TypeMacro) { 90 let semicolon = false; 91 self.mac(&ty.mac, None, semicolon); 92 } 93 type_never(&mut self, ty: &TypeNever)94 fn type_never(&mut self, ty: &TypeNever) { 95 let _ = ty; 96 self.word("!"); 97 } 98 type_paren(&mut self, ty: &TypeParen)99 fn type_paren(&mut self, ty: &TypeParen) { 100 self.word("("); 101 self.ty(&ty.elem); 102 self.word(")"); 103 } 104 type_path(&mut self, ty: &TypePath)105 fn type_path(&mut self, ty: &TypePath) { 106 self.qpath(&ty.qself, &ty.path, PathKind::Type); 107 } 108 type_ptr(&mut self, ty: &TypePtr)109 fn type_ptr(&mut self, ty: &TypePtr) { 110 self.word("*"); 111 if ty.mutability.is_some() { 112 self.word("mut "); 113 } else { 114 self.word("const "); 115 } 116 self.ty(&ty.elem); 117 } 118 type_reference(&mut self, ty: &TypeReference)119 fn type_reference(&mut self, ty: &TypeReference) { 120 self.word("&"); 121 if let Some(lifetime) = &ty.lifetime { 122 self.lifetime(lifetime); 123 self.nbsp(); 124 } 125 if ty.mutability.is_some() { 126 self.word("mut "); 127 } 128 self.ty(&ty.elem); 129 } 130 type_slice(&mut self, ty: &TypeSlice)131 fn type_slice(&mut self, ty: &TypeSlice) { 132 self.word("["); 133 self.ty(&ty.elem); 134 self.word("]"); 135 } 136 type_trait_object(&mut self, ty: &TypeTraitObject)137 fn type_trait_object(&mut self, ty: &TypeTraitObject) { 138 self.word("dyn "); 139 for type_param_bound in ty.bounds.iter().delimited() { 140 if !type_param_bound.is_first { 141 self.word(" + "); 142 } 143 self.type_param_bound(&type_param_bound); 144 } 145 } 146 type_tuple(&mut self, ty: &TypeTuple)147 fn type_tuple(&mut self, ty: &TypeTuple) { 148 self.word("("); 149 self.cbox(INDENT); 150 self.zerobreak(); 151 for elem in ty.elems.iter().delimited() { 152 self.ty(&elem); 153 if ty.elems.len() == 1 { 154 self.word(","); 155 self.zerobreak(); 156 } else { 157 self.trailing_comma(elem.is_last); 158 } 159 } 160 self.offset(-INDENT); 161 self.end(); 162 self.word(")"); 163 } 164 165 #[cfg(not(feature = "verbatim"))] type_verbatim(&mut self, ty: &TokenStream)166 fn type_verbatim(&mut self, ty: &TokenStream) { 167 unimplemented!("Type::Verbatim `{}`", ty); 168 } 169 170 #[cfg(feature = "verbatim")] type_verbatim(&mut self, tokens: &TokenStream)171 fn type_verbatim(&mut self, tokens: &TokenStream) { 172 use syn::parse::{Parse, ParseStream, Result}; 173 use syn::punctuated::Punctuated; 174 use syn::{token, FieldsNamed, Token, TypeParamBound}; 175 176 enum TypeVerbatim { 177 Ellipsis, 178 AnonStruct(AnonStruct), 179 AnonUnion(AnonUnion), 180 DynStar(DynStar), 181 MutSelf(MutSelf), 182 NotType(NotType), 183 } 184 185 struct AnonStruct { 186 fields: FieldsNamed, 187 } 188 189 struct AnonUnion { 190 fields: FieldsNamed, 191 } 192 193 struct DynStar { 194 bounds: Punctuated<TypeParamBound, Token![+]>, 195 } 196 197 struct MutSelf { 198 ty: Option<Type>, 199 } 200 201 struct NotType { 202 inner: Type, 203 } 204 205 impl Parse for TypeVerbatim { 206 fn parse(input: ParseStream) -> Result<Self> { 207 let lookahead = input.lookahead1(); 208 if lookahead.peek(Token![struct]) { 209 input.parse::<Token![struct]>()?; 210 let fields: FieldsNamed = input.parse()?; 211 Ok(TypeVerbatim::AnonStruct(AnonStruct { fields })) 212 } else if lookahead.peek(Token![union]) && input.peek2(token::Brace) { 213 input.parse::<Token![union]>()?; 214 let fields: FieldsNamed = input.parse()?; 215 Ok(TypeVerbatim::AnonUnion(AnonUnion { fields })) 216 } else if lookahead.peek(Token![dyn]) { 217 input.parse::<Token![dyn]>()?; 218 input.parse::<Token![*]>()?; 219 let bounds = input.parse_terminated(TypeParamBound::parse, Token![+])?; 220 Ok(TypeVerbatim::DynStar(DynStar { bounds })) 221 } else if lookahead.peek(Token![mut]) { 222 input.parse::<Token![mut]>()?; 223 input.parse::<Token![self]>()?; 224 let ty = if input.is_empty() { 225 None 226 } else { 227 input.parse::<Token![:]>()?; 228 let ty: Type = input.parse()?; 229 Some(ty) 230 }; 231 Ok(TypeVerbatim::MutSelf(MutSelf { ty })) 232 } else if lookahead.peek(Token![!]) { 233 input.parse::<Token![!]>()?; 234 let inner: Type = input.parse()?; 235 Ok(TypeVerbatim::NotType(NotType { inner })) 236 } else if lookahead.peek(Token![...]) { 237 input.parse::<Token![...]>()?; 238 Ok(TypeVerbatim::Ellipsis) 239 } else { 240 Err(lookahead.error()) 241 } 242 } 243 } 244 245 let ty: TypeVerbatim = match syn::parse2(tokens.clone()) { 246 Ok(ty) => ty, 247 Err(_) => unimplemented!("Type::Verbatim `{}`", tokens), 248 }; 249 250 match ty { 251 TypeVerbatim::Ellipsis => { 252 self.word("..."); 253 } 254 TypeVerbatim::AnonStruct(ty) => { 255 self.cbox(INDENT); 256 self.word("struct {"); 257 self.hardbreak_if_nonempty(); 258 for field in &ty.fields.named { 259 self.field(field); 260 self.word(","); 261 self.hardbreak(); 262 } 263 self.offset(-INDENT); 264 self.end(); 265 self.word("}"); 266 } 267 TypeVerbatim::AnonUnion(ty) => { 268 self.cbox(INDENT); 269 self.word("union {"); 270 self.hardbreak_if_nonempty(); 271 for field in &ty.fields.named { 272 self.field(field); 273 self.word(","); 274 self.hardbreak(); 275 } 276 self.offset(-INDENT); 277 self.end(); 278 self.word("}"); 279 } 280 TypeVerbatim::DynStar(ty) => { 281 self.word("dyn* "); 282 for type_param_bound in ty.bounds.iter().delimited() { 283 if !type_param_bound.is_first { 284 self.word(" + "); 285 } 286 self.type_param_bound(&type_param_bound); 287 } 288 } 289 TypeVerbatim::MutSelf(bare_fn_arg) => { 290 self.word("mut self"); 291 if let Some(ty) = &bare_fn_arg.ty { 292 self.word(": "); 293 self.ty(ty); 294 } 295 } 296 TypeVerbatim::NotType(ty) => { 297 self.word("!"); 298 self.ty(&ty.inner); 299 } 300 } 301 } 302 return_type(&mut self, ty: &ReturnType)303 pub fn return_type(&mut self, ty: &ReturnType) { 304 match ty { 305 ReturnType::Default => {} 306 ReturnType::Type(_arrow, ty) => { 307 self.word(" -> "); 308 self.ty(ty); 309 } 310 } 311 } 312 bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg)313 fn bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg) { 314 self.outer_attrs(&bare_fn_arg.attrs); 315 if let Some((name, _colon)) = &bare_fn_arg.name { 316 self.ident(name); 317 self.word(": "); 318 } 319 self.ty(&bare_fn_arg.ty); 320 } 321 bare_variadic(&mut self, variadic: &BareVariadic)322 fn bare_variadic(&mut self, variadic: &BareVariadic) { 323 self.outer_attrs(&variadic.attrs); 324 if let Some((name, _colon)) = &variadic.name { 325 self.ident(name); 326 self.word(": "); 327 } 328 self.word("..."); 329 } 330 abi(&mut self, abi: &Abi)331 pub fn abi(&mut self, abi: &Abi) { 332 self.word("extern "); 333 if let Some(name) = &abi.name { 334 self.lit_str(name); 335 self.nbsp(); 336 } 337 } 338 } 339