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