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