• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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