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 | Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, |
8 | ForeignItemType, ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, Item, |
9 | ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod, |
10 | ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, |
11 | Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro, |
12 | TraitItemType, Type, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic, |
13 | }; |
14 | |
15 | impl Printer { |
16 | pub fn item(&mut self, item: &Item) { |
17 | match item { |
18 | Item::Const(item) => self.item_const(item), |
19 | Item::Enum(item) => self.item_enum(item), |
20 | Item::ExternCrate(item) => self.item_extern_crate(item), |
21 | Item::Fn(item) => self.item_fn(item), |
22 | Item::ForeignMod(item) => self.item_foreign_mod(item), |
23 | Item::Impl(item) => self.item_impl(item), |
24 | Item::Macro(item) => self.item_macro(item), |
25 | Item::Mod(item) => self.item_mod(item), |
26 | Item::Static(item) => self.item_static(item), |
27 | Item::Struct(item) => self.item_struct(item), |
28 | Item::Trait(item) => self.item_trait(item), |
29 | Item::TraitAlias(item) => self.item_trait_alias(item), |
30 | Item::Type(item) => self.item_type(item), |
31 | Item::Union(item) => self.item_union(item), |
32 | Item::Use(item) => self.item_use(item), |
33 | Item::Verbatim(item) => self.item_verbatim(item), |
34 | #[cfg_attr (all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] |
35 | _ => unimplemented!("unknown Item" ), |
36 | } |
37 | } |
38 | |
39 | fn item_const(&mut self, item: &ItemConst) { |
40 | self.outer_attrs(&item.attrs); |
41 | self.cbox(0); |
42 | self.visibility(&item.vis); |
43 | self.word("const " ); |
44 | self.ident(&item.ident); |
45 | self.generics(&item.generics); |
46 | self.word(": " ); |
47 | self.ty(&item.ty); |
48 | self.word(" = " ); |
49 | self.neverbreak(); |
50 | self.expr(&item.expr); |
51 | self.word(";" ); |
52 | self.end(); |
53 | self.hardbreak(); |
54 | } |
55 | |
56 | fn item_enum(&mut self, item: &ItemEnum) { |
57 | self.outer_attrs(&item.attrs); |
58 | self.cbox(INDENT); |
59 | self.visibility(&item.vis); |
60 | self.word("enum " ); |
61 | self.ident(&item.ident); |
62 | self.generics(&item.generics); |
63 | self.where_clause_for_body(&item.generics.where_clause); |
64 | self.word("{" ); |
65 | self.hardbreak_if_nonempty(); |
66 | for variant in &item.variants { |
67 | self.variant(variant); |
68 | self.word("," ); |
69 | self.hardbreak(); |
70 | } |
71 | self.offset(-INDENT); |
72 | self.end(); |
73 | self.word("}" ); |
74 | self.hardbreak(); |
75 | } |
76 | |
77 | fn item_extern_crate(&mut self, item: &ItemExternCrate) { |
78 | self.outer_attrs(&item.attrs); |
79 | self.visibility(&item.vis); |
80 | self.word("extern crate " ); |
81 | self.ident(&item.ident); |
82 | if let Some((_as_token, rename)) = &item.rename { |
83 | self.word(" as " ); |
84 | self.ident(rename); |
85 | } |
86 | self.word(";" ); |
87 | self.hardbreak(); |
88 | } |
89 | |
90 | fn item_fn(&mut self, item: &ItemFn) { |
91 | self.outer_attrs(&item.attrs); |
92 | self.cbox(INDENT); |
93 | self.visibility(&item.vis); |
94 | self.signature(&item.sig); |
95 | self.where_clause_for_body(&item.sig.generics.where_clause); |
96 | self.word("{" ); |
97 | self.hardbreak_if_nonempty(); |
98 | self.inner_attrs(&item.attrs); |
99 | for stmt in &item.block.stmts { |
100 | self.stmt(stmt); |
101 | } |
102 | self.offset(-INDENT); |
103 | self.end(); |
104 | self.word("}" ); |
105 | self.hardbreak(); |
106 | } |
107 | |
108 | fn item_foreign_mod(&mut self, item: &ItemForeignMod) { |
109 | self.outer_attrs(&item.attrs); |
110 | self.cbox(INDENT); |
111 | if item.unsafety.is_some() { |
112 | self.word("unsafe " ); |
113 | } |
114 | self.abi(&item.abi); |
115 | self.word("{" ); |
116 | self.hardbreak_if_nonempty(); |
117 | self.inner_attrs(&item.attrs); |
118 | for foreign_item in &item.items { |
119 | self.foreign_item(foreign_item); |
120 | } |
121 | self.offset(-INDENT); |
122 | self.end(); |
123 | self.word("}" ); |
124 | self.hardbreak(); |
125 | } |
126 | |
127 | fn item_impl(&mut self, item: &ItemImpl) { |
128 | self.outer_attrs(&item.attrs); |
129 | self.cbox(INDENT); |
130 | self.ibox(-INDENT); |
131 | self.cbox(INDENT); |
132 | if item.defaultness.is_some() { |
133 | self.word("default " ); |
134 | } |
135 | if item.unsafety.is_some() { |
136 | self.word("unsafe " ); |
137 | } |
138 | self.word("impl" ); |
139 | self.generics(&item.generics); |
140 | self.end(); |
141 | self.nbsp(); |
142 | if let Some((negative_polarity, path, _for_token)) = &item.trait_ { |
143 | if negative_polarity.is_some() { |
144 | self.word("!" ); |
145 | } |
146 | self.path(path, PathKind::Type); |
147 | self.space(); |
148 | self.word("for " ); |
149 | } |
150 | self.ty(&item.self_ty); |
151 | self.end(); |
152 | self.where_clause_for_body(&item.generics.where_clause); |
153 | self.word("{" ); |
154 | self.hardbreak_if_nonempty(); |
155 | self.inner_attrs(&item.attrs); |
156 | for impl_item in &item.items { |
157 | self.impl_item(impl_item); |
158 | } |
159 | self.offset(-INDENT); |
160 | self.end(); |
161 | self.word("}" ); |
162 | self.hardbreak(); |
163 | } |
164 | |
165 | fn item_macro(&mut self, item: &ItemMacro) { |
166 | self.outer_attrs(&item.attrs); |
167 | let semicolon = true; |
168 | self.mac(&item.mac, item.ident.as_ref(), semicolon); |
169 | self.hardbreak(); |
170 | } |
171 | |
172 | fn item_mod(&mut self, item: &ItemMod) { |
173 | self.outer_attrs(&item.attrs); |
174 | self.cbox(INDENT); |
175 | self.visibility(&item.vis); |
176 | if item.unsafety.is_some() { |
177 | self.word("unsafe " ); |
178 | } |
179 | self.word("mod " ); |
180 | self.ident(&item.ident); |
181 | if let Some((_brace, items)) = &item.content { |
182 | self.word(" {" ); |
183 | self.hardbreak_if_nonempty(); |
184 | self.inner_attrs(&item.attrs); |
185 | for item in items { |
186 | self.item(item); |
187 | } |
188 | self.offset(-INDENT); |
189 | self.end(); |
190 | self.word("}" ); |
191 | } else { |
192 | self.word(";" ); |
193 | self.end(); |
194 | } |
195 | self.hardbreak(); |
196 | } |
197 | |
198 | fn item_static(&mut self, item: &ItemStatic) { |
199 | self.outer_attrs(&item.attrs); |
200 | self.cbox(0); |
201 | self.visibility(&item.vis); |
202 | self.word("static " ); |
203 | self.static_mutability(&item.mutability); |
204 | self.ident(&item.ident); |
205 | self.word(": " ); |
206 | self.ty(&item.ty); |
207 | self.word(" = " ); |
208 | self.neverbreak(); |
209 | self.expr(&item.expr); |
210 | self.word(";" ); |
211 | self.end(); |
212 | self.hardbreak(); |
213 | } |
214 | |
215 | fn item_struct(&mut self, item: &ItemStruct) { |
216 | self.outer_attrs(&item.attrs); |
217 | self.cbox(INDENT); |
218 | self.visibility(&item.vis); |
219 | self.word("struct " ); |
220 | self.ident(&item.ident); |
221 | self.generics(&item.generics); |
222 | match &item.fields { |
223 | Fields::Named(fields) => { |
224 | self.where_clause_for_body(&item.generics.where_clause); |
225 | self.word("{" ); |
226 | self.hardbreak_if_nonempty(); |
227 | for field in &fields.named { |
228 | self.field(field); |
229 | self.word("," ); |
230 | self.hardbreak(); |
231 | } |
232 | self.offset(-INDENT); |
233 | self.end(); |
234 | self.word("}" ); |
235 | } |
236 | Fields::Unnamed(fields) => { |
237 | self.fields_unnamed(fields); |
238 | self.where_clause_semi(&item.generics.where_clause); |
239 | self.end(); |
240 | } |
241 | Fields::Unit => { |
242 | self.where_clause_semi(&item.generics.where_clause); |
243 | self.end(); |
244 | } |
245 | } |
246 | self.hardbreak(); |
247 | } |
248 | |
249 | fn item_trait(&mut self, item: &ItemTrait) { |
250 | self.outer_attrs(&item.attrs); |
251 | self.cbox(INDENT); |
252 | self.visibility(&item.vis); |
253 | if item.unsafety.is_some() { |
254 | self.word("unsafe " ); |
255 | } |
256 | if item.auto_token.is_some() { |
257 | self.word("auto " ); |
258 | } |
259 | self.word("trait " ); |
260 | self.ident(&item.ident); |
261 | self.generics(&item.generics); |
262 | for supertrait in item.supertraits.iter().delimited() { |
263 | if supertrait.is_first { |
264 | self.word(": " ); |
265 | } else { |
266 | self.word(" + " ); |
267 | } |
268 | self.type_param_bound(&supertrait); |
269 | } |
270 | self.where_clause_for_body(&item.generics.where_clause); |
271 | self.word("{" ); |
272 | self.hardbreak_if_nonempty(); |
273 | self.inner_attrs(&item.attrs); |
274 | for trait_item in &item.items { |
275 | self.trait_item(trait_item); |
276 | } |
277 | self.offset(-INDENT); |
278 | self.end(); |
279 | self.word("}" ); |
280 | self.hardbreak(); |
281 | } |
282 | |
283 | fn item_trait_alias(&mut self, item: &ItemTraitAlias) { |
284 | self.outer_attrs(&item.attrs); |
285 | self.cbox(INDENT); |
286 | self.visibility(&item.vis); |
287 | self.word("trait " ); |
288 | self.ident(&item.ident); |
289 | self.generics(&item.generics); |
290 | self.word(" = " ); |
291 | self.neverbreak(); |
292 | for bound in item.bounds.iter().delimited() { |
293 | if !bound.is_first { |
294 | self.space(); |
295 | self.word("+ " ); |
296 | } |
297 | self.type_param_bound(&bound); |
298 | } |
299 | self.where_clause_semi(&item.generics.where_clause); |
300 | self.end(); |
301 | self.hardbreak(); |
302 | } |
303 | |
304 | fn item_type(&mut self, item: &ItemType) { |
305 | self.outer_attrs(&item.attrs); |
306 | self.cbox(INDENT); |
307 | self.visibility(&item.vis); |
308 | self.word("type " ); |
309 | self.ident(&item.ident); |
310 | self.generics(&item.generics); |
311 | self.where_clause_oneline(&item.generics.where_clause); |
312 | self.word("= " ); |
313 | self.neverbreak(); |
314 | self.ibox(-INDENT); |
315 | self.ty(&item.ty); |
316 | self.end(); |
317 | self.word(";" ); |
318 | self.end(); |
319 | self.hardbreak(); |
320 | } |
321 | |
322 | fn item_union(&mut self, item: &ItemUnion) { |
323 | self.outer_attrs(&item.attrs); |
324 | self.cbox(INDENT); |
325 | self.visibility(&item.vis); |
326 | self.word("union " ); |
327 | self.ident(&item.ident); |
328 | self.generics(&item.generics); |
329 | self.where_clause_for_body(&item.generics.where_clause); |
330 | self.word("{" ); |
331 | self.hardbreak_if_nonempty(); |
332 | for field in &item.fields.named { |
333 | self.field(field); |
334 | self.word("," ); |
335 | self.hardbreak(); |
336 | } |
337 | self.offset(-INDENT); |
338 | self.end(); |
339 | self.word("}" ); |
340 | self.hardbreak(); |
341 | } |
342 | |
343 | fn item_use(&mut self, item: &ItemUse) { |
344 | self.outer_attrs(&item.attrs); |
345 | self.visibility(&item.vis); |
346 | self.word("use " ); |
347 | if item.leading_colon.is_some() { |
348 | self.word("::" ); |
349 | } |
350 | self.use_tree(&item.tree); |
351 | self.word(";" ); |
352 | self.hardbreak(); |
353 | } |
354 | |
355 | #[cfg (not(feature = "verbatim" ))] |
356 | fn item_verbatim(&mut self, item: &TokenStream) { |
357 | if !item.is_empty() { |
358 | unimplemented!("Item::Verbatim ` {}`" , item); |
359 | } |
360 | self.hardbreak(); |
361 | } |
362 | |
363 | #[cfg (feature = "verbatim" )] |
364 | fn item_verbatim(&mut self, tokens: &TokenStream) { |
365 | use syn::parse::{Parse, ParseStream, Result}; |
366 | use syn::punctuated::Punctuated; |
367 | use syn::{ |
368 | braced, parenthesized, token, Attribute, Generics, Ident, Lifetime, Token, Visibility, |
369 | }; |
370 | use verbatim::{ |
371 | FlexibleItemConst, FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, |
372 | WhereClauseLocation, |
373 | }; |
374 | |
375 | enum ItemVerbatim { |
376 | Empty, |
377 | Ellipsis, |
378 | ConstFlexible(FlexibleItemConst), |
379 | FnFlexible(FlexibleItemFn), |
380 | ImplFlexible(ImplFlexible), |
381 | Macro2(Macro2), |
382 | StaticFlexible(FlexibleItemStatic), |
383 | TypeFlexible(FlexibleItemType), |
384 | UseBrace(UseBrace), |
385 | } |
386 | |
387 | struct ImplFlexible { |
388 | attrs: Vec<Attribute>, |
389 | vis: Visibility, |
390 | defaultness: bool, |
391 | unsafety: bool, |
392 | generics: Generics, |
393 | constness: ImplConstness, |
394 | negative_impl: bool, |
395 | trait_: Option<Type>, |
396 | self_ty: Type, |
397 | items: Vec<ImplItem>, |
398 | } |
399 | |
400 | enum ImplConstness { |
401 | None, |
402 | MaybeConst, |
403 | Const, |
404 | } |
405 | |
406 | struct Macro2 { |
407 | attrs: Vec<Attribute>, |
408 | vis: Visibility, |
409 | ident: Ident, |
410 | args: Option<TokenStream>, |
411 | body: TokenStream, |
412 | } |
413 | |
414 | struct UseBrace { |
415 | attrs: Vec<Attribute>, |
416 | vis: Visibility, |
417 | trees: Punctuated<RootUseTree, Token![,]>, |
418 | } |
419 | |
420 | struct RootUseTree { |
421 | leading_colon: Option<Token![::]>, |
422 | inner: UseTree, |
423 | } |
424 | |
425 | impl Parse for ImplConstness { |
426 | fn parse(input: ParseStream) -> Result<Self> { |
427 | if input.parse::<Option<Token![?]>>()?.is_some() { |
428 | input.parse::<Token![const]>()?; |
429 | Ok(ImplConstness::MaybeConst) |
430 | } else if input.parse::<Option<Token![const]>>()?.is_some() { |
431 | Ok(ImplConstness::Const) |
432 | } else { |
433 | Ok(ImplConstness::None) |
434 | } |
435 | } |
436 | } |
437 | |
438 | impl Parse for RootUseTree { |
439 | fn parse(input: ParseStream) -> Result<Self> { |
440 | Ok(RootUseTree { |
441 | leading_colon: input.parse()?, |
442 | inner: input.parse()?, |
443 | }) |
444 | } |
445 | } |
446 | |
447 | impl Parse for ItemVerbatim { |
448 | fn parse(input: ParseStream) -> Result<Self> { |
449 | if input.is_empty() { |
450 | return Ok(ItemVerbatim::Empty); |
451 | } else if input.peek(Token![...]) { |
452 | input.parse::<Token![...]>()?; |
453 | return Ok(ItemVerbatim::Ellipsis); |
454 | } |
455 | |
456 | let mut attrs = input.call(Attribute::parse_outer)?; |
457 | let vis: Visibility = input.parse()?; |
458 | |
459 | let lookahead = input.lookahead1(); |
460 | if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) { |
461 | let defaultness = false; |
462 | let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?; |
463 | Ok(ItemVerbatim::ConstFlexible(flexible_item)) |
464 | } else if input.peek(Token![const]) |
465 | || lookahead.peek(Token![async]) |
466 | || lookahead.peek(Token![unsafe]) && !input.peek2(Token![impl]) |
467 | || lookahead.peek(Token![extern]) |
468 | || lookahead.peek(Token![fn]) |
469 | { |
470 | let defaultness = false; |
471 | let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?; |
472 | Ok(ItemVerbatim::FnFlexible(flexible_item)) |
473 | } else if lookahead.peek(Token![default]) |
474 | || input.peek(Token![unsafe]) |
475 | || lookahead.peek(Token![impl]) |
476 | { |
477 | let defaultness = input.parse::<Option<Token![default]>>()?.is_some(); |
478 | let unsafety = input.parse::<Option<Token![unsafe]>>()?.is_some(); |
479 | input.parse::<Token![impl]>()?; |
480 | let has_generics = input.peek(Token![<]) |
481 | && (input.peek2(Token![>]) |
482 | || input.peek2(Token![#]) |
483 | || (input.peek2(Ident) || input.peek2(Lifetime)) |
484 | && (input.peek3(Token![:]) |
485 | || input.peek3(Token![,]) |
486 | || input.peek3(Token![>]) |
487 | || input.peek3(Token![=])) |
488 | || input.peek2(Token![const])); |
489 | let mut generics: Generics = if has_generics { |
490 | input.parse()? |
491 | } else { |
492 | Generics::default() |
493 | }; |
494 | let constness: ImplConstness = input.parse()?; |
495 | let negative_impl = |
496 | !input.peek2(token::Brace) && input.parse::<Option<Token![!]>>()?.is_some(); |
497 | let first_ty: Type = input.parse()?; |
498 | let (trait_, self_ty) = if input.parse::<Option<Token![for]>>()?.is_some() { |
499 | (Some(first_ty), input.parse()?) |
500 | } else { |
501 | (None, first_ty) |
502 | }; |
503 | generics.where_clause = input.parse()?; |
504 | let content; |
505 | braced!(content in input); |
506 | let inner_attrs = content.call(Attribute::parse_inner)?; |
507 | attrs.extend(inner_attrs); |
508 | let mut items = Vec::new(); |
509 | while !content.is_empty() { |
510 | items.push(content.parse()?); |
511 | } |
512 | Ok(ItemVerbatim::ImplFlexible(ImplFlexible { |
513 | attrs, |
514 | vis, |
515 | defaultness, |
516 | unsafety, |
517 | generics, |
518 | constness, |
519 | negative_impl, |
520 | trait_, |
521 | self_ty, |
522 | items, |
523 | })) |
524 | } else if lookahead.peek(Token![macro]) { |
525 | input.parse::<Token![macro]>()?; |
526 | let ident: Ident = input.parse()?; |
527 | let args = if input.peek(token::Paren) { |
528 | let paren_content; |
529 | parenthesized!(paren_content in input); |
530 | Some(paren_content.parse::<TokenStream>()?) |
531 | } else { |
532 | None |
533 | }; |
534 | let brace_content; |
535 | braced!(brace_content in input); |
536 | let body: TokenStream = brace_content.parse()?; |
537 | Ok(ItemVerbatim::Macro2(Macro2 { |
538 | attrs, |
539 | vis, |
540 | ident, |
541 | args, |
542 | body, |
543 | })) |
544 | } else if lookahead.peek(Token![static]) { |
545 | let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?; |
546 | Ok(ItemVerbatim::StaticFlexible(flexible_item)) |
547 | } else if lookahead.peek(Token![type]) { |
548 | let defaultness = false; |
549 | let flexible_item = FlexibleItemType::parse( |
550 | attrs, |
551 | vis, |
552 | defaultness, |
553 | input, |
554 | WhereClauseLocation::BeforeEq, |
555 | )?; |
556 | Ok(ItemVerbatim::TypeFlexible(flexible_item)) |
557 | } else if lookahead.peek(Token![use]) { |
558 | input.parse::<Token![use]>()?; |
559 | let content; |
560 | braced!(content in input); |
561 | let trees = content.parse_terminated(RootUseTree::parse, Token![,])?; |
562 | input.parse::<Token![;]>()?; |
563 | Ok(ItemVerbatim::UseBrace(UseBrace { attrs, vis, trees })) |
564 | } else { |
565 | Err(lookahead.error()) |
566 | } |
567 | } |
568 | } |
569 | |
570 | let item: ItemVerbatim = match syn::parse2(tokens.clone()) { |
571 | Ok(item) => item, |
572 | Err(_) => unimplemented!("Item::Verbatim ` {}`" , tokens), |
573 | }; |
574 | |
575 | match item { |
576 | ItemVerbatim::Empty => { |
577 | self.hardbreak(); |
578 | } |
579 | ItemVerbatim::Ellipsis => { |
580 | self.word("..." ); |
581 | self.hardbreak(); |
582 | } |
583 | ItemVerbatim::ConstFlexible(item) => { |
584 | self.flexible_item_const(&item); |
585 | } |
586 | ItemVerbatim::FnFlexible(item) => { |
587 | self.flexible_item_fn(&item); |
588 | } |
589 | ItemVerbatim::ImplFlexible(item) => { |
590 | self.outer_attrs(&item.attrs); |
591 | self.cbox(INDENT); |
592 | self.ibox(-INDENT); |
593 | self.cbox(INDENT); |
594 | self.visibility(&item.vis); |
595 | if item.defaultness { |
596 | self.word("default " ); |
597 | } |
598 | if item.unsafety { |
599 | self.word("unsafe " ); |
600 | } |
601 | self.word("impl" ); |
602 | self.generics(&item.generics); |
603 | self.end(); |
604 | self.nbsp(); |
605 | match item.constness { |
606 | ImplConstness::None => {} |
607 | ImplConstness::MaybeConst => self.word("?const " ), |
608 | ImplConstness::Const => self.word("const " ), |
609 | } |
610 | if item.negative_impl { |
611 | self.word("!" ); |
612 | } |
613 | if let Some(trait_) = &item.trait_ { |
614 | self.ty(trait_); |
615 | self.space(); |
616 | self.word("for " ); |
617 | } |
618 | self.ty(&item.self_ty); |
619 | self.end(); |
620 | self.where_clause_for_body(&item.generics.where_clause); |
621 | self.word("{" ); |
622 | self.hardbreak_if_nonempty(); |
623 | self.inner_attrs(&item.attrs); |
624 | for impl_item in &item.items { |
625 | self.impl_item(impl_item); |
626 | } |
627 | self.offset(-INDENT); |
628 | self.end(); |
629 | self.word("}" ); |
630 | self.hardbreak(); |
631 | } |
632 | ItemVerbatim::Macro2(item) => { |
633 | self.outer_attrs(&item.attrs); |
634 | self.visibility(&item.vis); |
635 | self.word("macro " ); |
636 | self.ident(&item.ident); |
637 | if let Some(args) = &item.args { |
638 | self.word("(" ); |
639 | self.cbox(INDENT); |
640 | self.zerobreak(); |
641 | self.ibox(0); |
642 | self.macro_rules_tokens(args.clone(), true); |
643 | self.end(); |
644 | self.zerobreak(); |
645 | self.offset(-INDENT); |
646 | self.end(); |
647 | self.word(")" ); |
648 | } |
649 | self.word(" {" ); |
650 | if !item.body.is_empty() { |
651 | self.neverbreak(); |
652 | self.cbox(INDENT); |
653 | self.hardbreak(); |
654 | self.ibox(0); |
655 | self.macro_rules_tokens(item.body.clone(), false); |
656 | self.end(); |
657 | self.hardbreak(); |
658 | self.offset(-INDENT); |
659 | self.end(); |
660 | } |
661 | self.word("}" ); |
662 | self.hardbreak(); |
663 | } |
664 | ItemVerbatim::StaticFlexible(item) => { |
665 | self.flexible_item_static(&item); |
666 | } |
667 | ItemVerbatim::TypeFlexible(item) => { |
668 | self.flexible_item_type(&item); |
669 | } |
670 | ItemVerbatim::UseBrace(item) => { |
671 | self.outer_attrs(&item.attrs); |
672 | self.visibility(&item.vis); |
673 | self.word("use " ); |
674 | if item.trees.len() == 1 { |
675 | self.word("::" ); |
676 | self.use_tree(&item.trees[0].inner); |
677 | } else { |
678 | self.cbox(INDENT); |
679 | self.word("{" ); |
680 | self.zerobreak(); |
681 | self.ibox(0); |
682 | for use_tree in item.trees.iter().delimited() { |
683 | if use_tree.leading_colon.is_some() { |
684 | self.word("::" ); |
685 | } |
686 | self.use_tree(&use_tree.inner); |
687 | if !use_tree.is_last { |
688 | self.word("," ); |
689 | let mut use_tree = &use_tree.inner; |
690 | while let UseTree::Path(use_path) = use_tree { |
691 | use_tree = &use_path.tree; |
692 | } |
693 | if let UseTree::Group(_) = use_tree { |
694 | self.hardbreak(); |
695 | } else { |
696 | self.space(); |
697 | } |
698 | } |
699 | } |
700 | self.end(); |
701 | self.trailing_comma(true); |
702 | self.offset(-INDENT); |
703 | self.word("}" ); |
704 | self.end(); |
705 | } |
706 | self.word(";" ); |
707 | self.hardbreak(); |
708 | } |
709 | } |
710 | } |
711 | |
712 | fn use_tree(&mut self, use_tree: &UseTree) { |
713 | match use_tree { |
714 | UseTree::Path(use_path) => self.use_path(use_path), |
715 | UseTree::Name(use_name) => self.use_name(use_name), |
716 | UseTree::Rename(use_rename) => self.use_rename(use_rename), |
717 | UseTree::Glob(use_glob) => self.use_glob(use_glob), |
718 | UseTree::Group(use_group) => self.use_group(use_group), |
719 | } |
720 | } |
721 | |
722 | fn use_path(&mut self, use_path: &UsePath) { |
723 | self.ident(&use_path.ident); |
724 | self.word("::" ); |
725 | self.use_tree(&use_path.tree); |
726 | } |
727 | |
728 | fn use_name(&mut self, use_name: &UseName) { |
729 | self.ident(&use_name.ident); |
730 | } |
731 | |
732 | fn use_rename(&mut self, use_rename: &UseRename) { |
733 | self.ident(&use_rename.ident); |
734 | self.word(" as " ); |
735 | self.ident(&use_rename.rename); |
736 | } |
737 | |
738 | fn use_glob(&mut self, use_glob: &UseGlob) { |
739 | let _ = use_glob; |
740 | self.word("*" ); |
741 | } |
742 | |
743 | fn use_group(&mut self, use_group: &UseGroup) { |
744 | if use_group.items.is_empty() { |
745 | self.word("{}" ); |
746 | } else if use_group.items.len() == 1 { |
747 | self.use_tree(&use_group.items[0]); |
748 | } else { |
749 | self.cbox(INDENT); |
750 | self.word("{" ); |
751 | self.zerobreak(); |
752 | self.ibox(0); |
753 | for use_tree in use_group.items.iter().delimited() { |
754 | self.use_tree(&use_tree); |
755 | if !use_tree.is_last { |
756 | self.word("," ); |
757 | let mut use_tree = *use_tree; |
758 | while let UseTree::Path(use_path) = use_tree { |
759 | use_tree = &use_path.tree; |
760 | } |
761 | if let UseTree::Group(_) = use_tree { |
762 | self.hardbreak(); |
763 | } else { |
764 | self.space(); |
765 | } |
766 | } |
767 | } |
768 | self.end(); |
769 | self.trailing_comma(true); |
770 | self.offset(-INDENT); |
771 | self.word("}" ); |
772 | self.end(); |
773 | } |
774 | } |
775 | |
776 | fn foreign_item(&mut self, foreign_item: &ForeignItem) { |
777 | match foreign_item { |
778 | ForeignItem::Fn(item) => self.foreign_item_fn(item), |
779 | ForeignItem::Static(item) => self.foreign_item_static(item), |
780 | ForeignItem::Type(item) => self.foreign_item_type(item), |
781 | ForeignItem::Macro(item) => self.foreign_item_macro(item), |
782 | ForeignItem::Verbatim(item) => self.foreign_item_verbatim(item), |
783 | #[cfg_attr (all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] |
784 | _ => unimplemented!("unknown ForeignItem" ), |
785 | } |
786 | } |
787 | |
788 | fn foreign_item_fn(&mut self, foreign_item: &ForeignItemFn) { |
789 | self.outer_attrs(&foreign_item.attrs); |
790 | self.cbox(INDENT); |
791 | self.visibility(&foreign_item.vis); |
792 | self.signature(&foreign_item.sig); |
793 | self.where_clause_semi(&foreign_item.sig.generics.where_clause); |
794 | self.end(); |
795 | self.hardbreak(); |
796 | } |
797 | |
798 | fn foreign_item_static(&mut self, foreign_item: &ForeignItemStatic) { |
799 | self.outer_attrs(&foreign_item.attrs); |
800 | self.cbox(0); |
801 | self.visibility(&foreign_item.vis); |
802 | self.word("static " ); |
803 | self.static_mutability(&foreign_item.mutability); |
804 | self.ident(&foreign_item.ident); |
805 | self.word(": " ); |
806 | self.ty(&foreign_item.ty); |
807 | self.word(";" ); |
808 | self.end(); |
809 | self.hardbreak(); |
810 | } |
811 | |
812 | fn foreign_item_type(&mut self, foreign_item: &ForeignItemType) { |
813 | self.outer_attrs(&foreign_item.attrs); |
814 | self.cbox(0); |
815 | self.visibility(&foreign_item.vis); |
816 | self.word("type " ); |
817 | self.ident(&foreign_item.ident); |
818 | self.generics(&foreign_item.generics); |
819 | self.word(";" ); |
820 | self.end(); |
821 | self.hardbreak(); |
822 | } |
823 | |
824 | fn foreign_item_macro(&mut self, foreign_item: &ForeignItemMacro) { |
825 | self.outer_attrs(&foreign_item.attrs); |
826 | let semicolon = true; |
827 | self.mac(&foreign_item.mac, None, semicolon); |
828 | self.hardbreak(); |
829 | } |
830 | |
831 | #[cfg (not(feature = "verbatim" ))] |
832 | fn foreign_item_verbatim(&mut self, foreign_item: &TokenStream) { |
833 | if !foreign_item.is_empty() { |
834 | unimplemented!("ForeignItem::Verbatim ` {}`" , foreign_item); |
835 | } |
836 | self.hardbreak(); |
837 | } |
838 | |
839 | #[cfg (feature = "verbatim" )] |
840 | fn foreign_item_verbatim(&mut self, tokens: &TokenStream) { |
841 | use syn::parse::{Parse, ParseStream, Result}; |
842 | use syn::{Attribute, Token, Visibility}; |
843 | use verbatim::{FlexibleItemFn, FlexibleItemStatic, FlexibleItemType, WhereClauseLocation}; |
844 | |
845 | enum ForeignItemVerbatim { |
846 | Empty, |
847 | Ellipsis, |
848 | FnFlexible(FlexibleItemFn), |
849 | StaticFlexible(FlexibleItemStatic), |
850 | TypeFlexible(FlexibleItemType), |
851 | } |
852 | |
853 | impl Parse for ForeignItemVerbatim { |
854 | fn parse(input: ParseStream) -> Result<Self> { |
855 | if input.is_empty() { |
856 | return Ok(ForeignItemVerbatim::Empty); |
857 | } else if input.peek(Token![...]) { |
858 | input.parse::<Token![...]>()?; |
859 | return Ok(ForeignItemVerbatim::Ellipsis); |
860 | } |
861 | |
862 | let attrs = input.call(Attribute::parse_outer)?; |
863 | let vis: Visibility = input.parse()?; |
864 | let defaultness = false; |
865 | |
866 | let lookahead = input.lookahead1(); |
867 | if lookahead.peek(Token![const]) |
868 | || lookahead.peek(Token![async]) |
869 | || lookahead.peek(Token![unsafe]) |
870 | || lookahead.peek(Token![extern]) |
871 | || lookahead.peek(Token![fn]) |
872 | { |
873 | let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?; |
874 | Ok(ForeignItemVerbatim::FnFlexible(flexible_item)) |
875 | } else if lookahead.peek(Token![static]) { |
876 | let flexible_item = FlexibleItemStatic::parse(attrs, vis, input)?; |
877 | Ok(ForeignItemVerbatim::StaticFlexible(flexible_item)) |
878 | } else if lookahead.peek(Token![type]) { |
879 | let flexible_item = FlexibleItemType::parse( |
880 | attrs, |
881 | vis, |
882 | defaultness, |
883 | input, |
884 | WhereClauseLocation::Both, |
885 | )?; |
886 | Ok(ForeignItemVerbatim::TypeFlexible(flexible_item)) |
887 | } else { |
888 | Err(lookahead.error()) |
889 | } |
890 | } |
891 | } |
892 | |
893 | let foreign_item: ForeignItemVerbatim = match syn::parse2(tokens.clone()) { |
894 | Ok(foreign_item) => foreign_item, |
895 | Err(_) => unimplemented!("ForeignItem::Verbatim ` {}`" , tokens), |
896 | }; |
897 | |
898 | match foreign_item { |
899 | ForeignItemVerbatim::Empty => { |
900 | self.hardbreak(); |
901 | } |
902 | ForeignItemVerbatim::Ellipsis => { |
903 | self.word("..." ); |
904 | self.hardbreak(); |
905 | } |
906 | ForeignItemVerbatim::FnFlexible(foreign_item) => { |
907 | self.flexible_item_fn(&foreign_item); |
908 | } |
909 | ForeignItemVerbatim::StaticFlexible(foreign_item) => { |
910 | self.flexible_item_static(&foreign_item); |
911 | } |
912 | ForeignItemVerbatim::TypeFlexible(foreign_item) => { |
913 | self.flexible_item_type(&foreign_item); |
914 | } |
915 | } |
916 | } |
917 | |
918 | fn trait_item(&mut self, trait_item: &TraitItem) { |
919 | match trait_item { |
920 | TraitItem::Const(item) => self.trait_item_const(item), |
921 | TraitItem::Fn(item) => self.trait_item_fn(item), |
922 | TraitItem::Type(item) => self.trait_item_type(item), |
923 | TraitItem::Macro(item) => self.trait_item_macro(item), |
924 | TraitItem::Verbatim(item) => self.trait_item_verbatim(item), |
925 | #[cfg_attr (all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] |
926 | _ => unimplemented!("unknown TraitItem" ), |
927 | } |
928 | } |
929 | |
930 | fn trait_item_const(&mut self, trait_item: &TraitItemConst) { |
931 | self.outer_attrs(&trait_item.attrs); |
932 | self.cbox(0); |
933 | self.word("const " ); |
934 | self.ident(&trait_item.ident); |
935 | self.generics(&trait_item.generics); |
936 | self.word(": " ); |
937 | self.ty(&trait_item.ty); |
938 | if let Some((_eq_token, default)) = &trait_item.default { |
939 | self.word(" = " ); |
940 | self.neverbreak(); |
941 | self.expr(default); |
942 | } |
943 | self.word(";" ); |
944 | self.end(); |
945 | self.hardbreak(); |
946 | } |
947 | |
948 | fn trait_item_fn(&mut self, trait_item: &TraitItemFn) { |
949 | self.outer_attrs(&trait_item.attrs); |
950 | self.cbox(INDENT); |
951 | self.signature(&trait_item.sig); |
952 | if let Some(block) = &trait_item.default { |
953 | self.where_clause_for_body(&trait_item.sig.generics.where_clause); |
954 | self.word("{" ); |
955 | self.hardbreak_if_nonempty(); |
956 | self.inner_attrs(&trait_item.attrs); |
957 | for stmt in &block.stmts { |
958 | self.stmt(stmt); |
959 | } |
960 | self.offset(-INDENT); |
961 | self.end(); |
962 | self.word("}" ); |
963 | } else { |
964 | self.where_clause_semi(&trait_item.sig.generics.where_clause); |
965 | self.end(); |
966 | } |
967 | self.hardbreak(); |
968 | } |
969 | |
970 | fn trait_item_type(&mut self, trait_item: &TraitItemType) { |
971 | self.outer_attrs(&trait_item.attrs); |
972 | self.cbox(INDENT); |
973 | self.word("type " ); |
974 | self.ident(&trait_item.ident); |
975 | self.generics(&trait_item.generics); |
976 | for bound in trait_item.bounds.iter().delimited() { |
977 | if bound.is_first { |
978 | self.word(": " ); |
979 | } else { |
980 | self.space(); |
981 | self.word("+ " ); |
982 | } |
983 | self.type_param_bound(&bound); |
984 | } |
985 | if let Some((_eq_token, default)) = &trait_item.default { |
986 | self.word(" = " ); |
987 | self.neverbreak(); |
988 | self.ibox(-INDENT); |
989 | self.ty(default); |
990 | self.end(); |
991 | } |
992 | self.where_clause_oneline_semi(&trait_item.generics.where_clause); |
993 | self.end(); |
994 | self.hardbreak(); |
995 | } |
996 | |
997 | fn trait_item_macro(&mut self, trait_item: &TraitItemMacro) { |
998 | self.outer_attrs(&trait_item.attrs); |
999 | let semicolon = true; |
1000 | self.mac(&trait_item.mac, None, semicolon); |
1001 | self.hardbreak(); |
1002 | } |
1003 | |
1004 | #[cfg (not(feature = "verbatim" ))] |
1005 | fn trait_item_verbatim(&mut self, trait_item: &TokenStream) { |
1006 | if !trait_item.is_empty() { |
1007 | unimplemented!("TraitItem::Verbatim ` {}`" , trait_item); |
1008 | } |
1009 | self.hardbreak(); |
1010 | } |
1011 | |
1012 | #[cfg (feature = "verbatim" )] |
1013 | fn trait_item_verbatim(&mut self, tokens: &TokenStream) { |
1014 | use syn::parse::{Parse, ParseStream, Result}; |
1015 | use syn::{Attribute, Ident, Token, Visibility}; |
1016 | use verbatim::{FlexibleItemConst, FlexibleItemType, WhereClauseLocation}; |
1017 | |
1018 | enum TraitItemVerbatim { |
1019 | Empty, |
1020 | Ellipsis, |
1021 | ConstFlexible(FlexibleItemConst), |
1022 | TypeFlexible(FlexibleItemType), |
1023 | PubOrDefault(PubOrDefaultTraitItem), |
1024 | } |
1025 | |
1026 | struct PubOrDefaultTraitItem { |
1027 | attrs: Vec<Attribute>, |
1028 | vis: Visibility, |
1029 | defaultness: bool, |
1030 | trait_item: TraitItem, |
1031 | } |
1032 | |
1033 | impl Parse for TraitItemVerbatim { |
1034 | fn parse(input: ParseStream) -> Result<Self> { |
1035 | if input.is_empty() { |
1036 | return Ok(TraitItemVerbatim::Empty); |
1037 | } else if input.peek(Token![...]) { |
1038 | input.parse::<Token![...]>()?; |
1039 | return Ok(TraitItemVerbatim::Ellipsis); |
1040 | } |
1041 | |
1042 | let attrs = input.call(Attribute::parse_outer)?; |
1043 | let vis: Visibility = input.parse()?; |
1044 | let defaultness = input.parse::<Option<Token![default]>>()?.is_some(); |
1045 | |
1046 | let lookahead = input.lookahead1(); |
1047 | if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) { |
1048 | let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?; |
1049 | Ok(TraitItemVerbatim::ConstFlexible(flexible_item)) |
1050 | } else if lookahead.peek(Token![type]) { |
1051 | let flexible_item = FlexibleItemType::parse( |
1052 | attrs, |
1053 | vis, |
1054 | defaultness, |
1055 | input, |
1056 | WhereClauseLocation::AfterEq, |
1057 | )?; |
1058 | Ok(TraitItemVerbatim::TypeFlexible(flexible_item)) |
1059 | } else if (input.peek(Token![const]) |
1060 | || lookahead.peek(Token![async]) |
1061 | || lookahead.peek(Token![unsafe]) |
1062 | || lookahead.peek(Token![extern]) |
1063 | || lookahead.peek(Token![fn])) |
1064 | && (!matches!(vis, Visibility::Inherited) || defaultness) |
1065 | { |
1066 | Ok(TraitItemVerbatim::PubOrDefault(PubOrDefaultTraitItem { |
1067 | attrs, |
1068 | vis, |
1069 | defaultness, |
1070 | trait_item: input.parse()?, |
1071 | })) |
1072 | } else { |
1073 | Err(lookahead.error()) |
1074 | } |
1075 | } |
1076 | } |
1077 | |
1078 | let impl_item: TraitItemVerbatim = match syn::parse2(tokens.clone()) { |
1079 | Ok(impl_item) => impl_item, |
1080 | Err(_) => unimplemented!("TraitItem::Verbatim ` {}`" , tokens), |
1081 | }; |
1082 | |
1083 | match impl_item { |
1084 | TraitItemVerbatim::Empty => { |
1085 | self.hardbreak(); |
1086 | } |
1087 | TraitItemVerbatim::Ellipsis => { |
1088 | self.word("..." ); |
1089 | self.hardbreak(); |
1090 | } |
1091 | TraitItemVerbatim::ConstFlexible(trait_item) => { |
1092 | self.flexible_item_const(&trait_item); |
1093 | } |
1094 | TraitItemVerbatim::TypeFlexible(trait_item) => { |
1095 | self.flexible_item_type(&trait_item); |
1096 | } |
1097 | TraitItemVerbatim::PubOrDefault(trait_item) => { |
1098 | self.outer_attrs(&trait_item.attrs); |
1099 | self.visibility(&trait_item.vis); |
1100 | if trait_item.defaultness { |
1101 | self.word("default " ); |
1102 | } |
1103 | self.trait_item(&trait_item.trait_item); |
1104 | } |
1105 | } |
1106 | } |
1107 | |
1108 | fn impl_item(&mut self, impl_item: &ImplItem) { |
1109 | match impl_item { |
1110 | ImplItem::Const(item) => self.impl_item_const(item), |
1111 | ImplItem::Fn(item) => self.impl_item_fn(item), |
1112 | ImplItem::Type(item) => self.impl_item_type(item), |
1113 | ImplItem::Macro(item) => self.impl_item_macro(item), |
1114 | ImplItem::Verbatim(item) => self.impl_item_verbatim(item), |
1115 | #[cfg_attr (all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] |
1116 | _ => unimplemented!("unknown ImplItem" ), |
1117 | } |
1118 | } |
1119 | |
1120 | fn impl_item_const(&mut self, impl_item: &ImplItemConst) { |
1121 | self.outer_attrs(&impl_item.attrs); |
1122 | self.cbox(0); |
1123 | self.visibility(&impl_item.vis); |
1124 | if impl_item.defaultness.is_some() { |
1125 | self.word("default " ); |
1126 | } |
1127 | self.word("const " ); |
1128 | self.ident(&impl_item.ident); |
1129 | self.generics(&impl_item.generics); |
1130 | self.word(": " ); |
1131 | self.ty(&impl_item.ty); |
1132 | self.word(" = " ); |
1133 | self.neverbreak(); |
1134 | self.expr(&impl_item.expr); |
1135 | self.word(";" ); |
1136 | self.end(); |
1137 | self.hardbreak(); |
1138 | } |
1139 | |
1140 | fn impl_item_fn(&mut self, impl_item: &ImplItemFn) { |
1141 | self.outer_attrs(&impl_item.attrs); |
1142 | self.cbox(INDENT); |
1143 | self.visibility(&impl_item.vis); |
1144 | if impl_item.defaultness.is_some() { |
1145 | self.word("default " ); |
1146 | } |
1147 | self.signature(&impl_item.sig); |
1148 | self.where_clause_for_body(&impl_item.sig.generics.where_clause); |
1149 | self.word("{" ); |
1150 | self.hardbreak_if_nonempty(); |
1151 | self.inner_attrs(&impl_item.attrs); |
1152 | for stmt in &impl_item.block.stmts { |
1153 | self.stmt(stmt); |
1154 | } |
1155 | self.offset(-INDENT); |
1156 | self.end(); |
1157 | self.word("}" ); |
1158 | self.hardbreak(); |
1159 | } |
1160 | |
1161 | fn impl_item_type(&mut self, impl_item: &ImplItemType) { |
1162 | self.outer_attrs(&impl_item.attrs); |
1163 | self.cbox(INDENT); |
1164 | self.visibility(&impl_item.vis); |
1165 | if impl_item.defaultness.is_some() { |
1166 | self.word("default " ); |
1167 | } |
1168 | self.word("type " ); |
1169 | self.ident(&impl_item.ident); |
1170 | self.generics(&impl_item.generics); |
1171 | self.word(" = " ); |
1172 | self.neverbreak(); |
1173 | self.ibox(-INDENT); |
1174 | self.ty(&impl_item.ty); |
1175 | self.end(); |
1176 | self.where_clause_oneline_semi(&impl_item.generics.where_clause); |
1177 | self.end(); |
1178 | self.hardbreak(); |
1179 | } |
1180 | |
1181 | fn impl_item_macro(&mut self, impl_item: &ImplItemMacro) { |
1182 | self.outer_attrs(&impl_item.attrs); |
1183 | let semicolon = true; |
1184 | self.mac(&impl_item.mac, None, semicolon); |
1185 | self.hardbreak(); |
1186 | } |
1187 | |
1188 | #[cfg (not(feature = "verbatim" ))] |
1189 | fn impl_item_verbatim(&mut self, impl_item: &TokenStream) { |
1190 | if !impl_item.is_empty() { |
1191 | unimplemented!("ImplItem::Verbatim ` {}`" , impl_item); |
1192 | } |
1193 | self.hardbreak(); |
1194 | } |
1195 | |
1196 | #[cfg (feature = "verbatim" )] |
1197 | fn impl_item_verbatim(&mut self, tokens: &TokenStream) { |
1198 | use syn::parse::{Parse, ParseStream, Result}; |
1199 | use syn::{Attribute, Ident, Token, Visibility}; |
1200 | use verbatim::{FlexibleItemConst, FlexibleItemFn, FlexibleItemType, WhereClauseLocation}; |
1201 | |
1202 | enum ImplItemVerbatim { |
1203 | Empty, |
1204 | Ellipsis, |
1205 | ConstFlexible(FlexibleItemConst), |
1206 | FnFlexible(FlexibleItemFn), |
1207 | TypeFlexible(FlexibleItemType), |
1208 | } |
1209 | |
1210 | impl Parse for ImplItemVerbatim { |
1211 | fn parse(input: ParseStream) -> Result<Self> { |
1212 | if input.is_empty() { |
1213 | return Ok(ImplItemVerbatim::Empty); |
1214 | } else if input.peek(Token![...]) { |
1215 | input.parse::<Token![...]>()?; |
1216 | return Ok(ImplItemVerbatim::Ellipsis); |
1217 | } |
1218 | |
1219 | let attrs = input.call(Attribute::parse_outer)?; |
1220 | let vis: Visibility = input.parse()?; |
1221 | let defaultness = input.parse::<Option<Token![default]>>()?.is_some(); |
1222 | |
1223 | let lookahead = input.lookahead1(); |
1224 | if lookahead.peek(Token![const]) && (input.peek2(Ident) || input.peek2(Token![_])) { |
1225 | let flexible_item = FlexibleItemConst::parse(attrs, vis, defaultness, input)?; |
1226 | Ok(ImplItemVerbatim::ConstFlexible(flexible_item)) |
1227 | } else if input.peek(Token![const]) |
1228 | || lookahead.peek(Token![async]) |
1229 | || lookahead.peek(Token![unsafe]) |
1230 | || lookahead.peek(Token![extern]) |
1231 | || lookahead.peek(Token![fn]) |
1232 | { |
1233 | let flexible_item = FlexibleItemFn::parse(attrs, vis, defaultness, input)?; |
1234 | Ok(ImplItemVerbatim::FnFlexible(flexible_item)) |
1235 | } else if lookahead.peek(Token![type]) { |
1236 | let flexible_item = FlexibleItemType::parse( |
1237 | attrs, |
1238 | vis, |
1239 | defaultness, |
1240 | input, |
1241 | WhereClauseLocation::AfterEq, |
1242 | )?; |
1243 | Ok(ImplItemVerbatim::TypeFlexible(flexible_item)) |
1244 | } else { |
1245 | Err(lookahead.error()) |
1246 | } |
1247 | } |
1248 | } |
1249 | |
1250 | let impl_item: ImplItemVerbatim = match syn::parse2(tokens.clone()) { |
1251 | Ok(impl_item) => impl_item, |
1252 | Err(_) => unimplemented!("ImplItem::Verbatim ` {}`" , tokens), |
1253 | }; |
1254 | |
1255 | match impl_item { |
1256 | ImplItemVerbatim::Empty => { |
1257 | self.hardbreak(); |
1258 | } |
1259 | ImplItemVerbatim::Ellipsis => { |
1260 | self.word("..." ); |
1261 | self.hardbreak(); |
1262 | } |
1263 | ImplItemVerbatim::ConstFlexible(impl_item) => { |
1264 | self.flexible_item_const(&impl_item); |
1265 | } |
1266 | ImplItemVerbatim::FnFlexible(impl_item) => { |
1267 | self.flexible_item_fn(&impl_item); |
1268 | } |
1269 | ImplItemVerbatim::TypeFlexible(impl_item) => { |
1270 | self.flexible_item_type(&impl_item); |
1271 | } |
1272 | } |
1273 | } |
1274 | |
1275 | fn signature(&mut self, signature: &Signature) { |
1276 | if signature.constness.is_some() { |
1277 | self.word("const " ); |
1278 | } |
1279 | if signature.asyncness.is_some() { |
1280 | self.word("async " ); |
1281 | } |
1282 | if signature.unsafety.is_some() { |
1283 | self.word("unsafe " ); |
1284 | } |
1285 | if let Some(abi) = &signature.abi { |
1286 | self.abi(abi); |
1287 | } |
1288 | self.word("fn " ); |
1289 | self.ident(&signature.ident); |
1290 | self.generics(&signature.generics); |
1291 | self.word("(" ); |
1292 | self.neverbreak(); |
1293 | self.cbox(0); |
1294 | self.zerobreak(); |
1295 | for input in signature.inputs.iter().delimited() { |
1296 | self.fn_arg(&input); |
1297 | let is_last = input.is_last && signature.variadic.is_none(); |
1298 | self.trailing_comma(is_last); |
1299 | } |
1300 | if let Some(variadic) = &signature.variadic { |
1301 | self.variadic(variadic); |
1302 | self.zerobreak(); |
1303 | } |
1304 | self.offset(-INDENT); |
1305 | self.end(); |
1306 | self.word(")" ); |
1307 | self.cbox(-INDENT); |
1308 | self.return_type(&signature.output); |
1309 | self.end(); |
1310 | } |
1311 | |
1312 | fn fn_arg(&mut self, fn_arg: &FnArg) { |
1313 | match fn_arg { |
1314 | FnArg::Receiver(receiver) => self.receiver(receiver), |
1315 | FnArg::Typed(pat_type) => self.pat_type(pat_type), |
1316 | } |
1317 | } |
1318 | |
1319 | fn receiver(&mut self, receiver: &Receiver) { |
1320 | self.outer_attrs(&receiver.attrs); |
1321 | if let Some((_ampersand, lifetime)) = &receiver.reference { |
1322 | self.word("&" ); |
1323 | if let Some(lifetime) = lifetime { |
1324 | self.lifetime(lifetime); |
1325 | self.nbsp(); |
1326 | } |
1327 | } |
1328 | if receiver.mutability.is_some() { |
1329 | self.word("mut " ); |
1330 | } |
1331 | self.word("self" ); |
1332 | if receiver.colon_token.is_some() { |
1333 | self.word(": " ); |
1334 | self.ty(&receiver.ty); |
1335 | } else { |
1336 | let consistent = match (&receiver.reference, &receiver.mutability, &*receiver.ty) { |
1337 | (Some(_), mutability, Type::Reference(ty)) => { |
1338 | mutability.is_some() == ty.mutability.is_some() |
1339 | && match &*ty.elem { |
1340 | Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self" ), |
1341 | _ => false, |
1342 | } |
1343 | } |
1344 | (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self" ), |
1345 | _ => false, |
1346 | }; |
1347 | if !consistent { |
1348 | self.word(": " ); |
1349 | self.ty(&receiver.ty); |
1350 | } |
1351 | } |
1352 | } |
1353 | |
1354 | fn variadic(&mut self, variadic: &Variadic) { |
1355 | self.outer_attrs(&variadic.attrs); |
1356 | if let Some((pat, _colon)) = &variadic.pat { |
1357 | self.pat(pat); |
1358 | self.word(": " ); |
1359 | } |
1360 | self.word("..." ); |
1361 | } |
1362 | |
1363 | fn static_mutability(&mut self, mutability: &StaticMutability) { |
1364 | match mutability { |
1365 | StaticMutability::Mut(_) => self.word("mut " ), |
1366 | StaticMutability::None => {} |
1367 | #[cfg_attr (all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] |
1368 | _ => unimplemented!("unknown StaticMutability" ), |
1369 | } |
1370 | } |
1371 | } |
1372 | |
1373 | #[cfg (feature = "verbatim" )] |
1374 | mod verbatim { |
1375 | use crate::algorithm::Printer; |
1376 | use crate::iter::IterDelimited; |
1377 | use crate::INDENT; |
1378 | use syn::ext::IdentExt; |
1379 | use syn::parse::{ParseStream, Result}; |
1380 | use syn::{ |
1381 | braced, token, Attribute, Block, Expr, Generics, Ident, Signature, StaticMutability, Stmt, |
1382 | Token, Type, TypeParamBound, Visibility, WhereClause, |
1383 | }; |
1384 | |
1385 | pub struct FlexibleItemConst { |
1386 | pub attrs: Vec<Attribute>, |
1387 | pub vis: Visibility, |
1388 | pub defaultness: bool, |
1389 | pub ident: Ident, |
1390 | pub generics: Generics, |
1391 | pub ty: Type, |
1392 | pub value: Option<Expr>, |
1393 | } |
1394 | |
1395 | pub struct FlexibleItemFn { |
1396 | pub attrs: Vec<Attribute>, |
1397 | pub vis: Visibility, |
1398 | pub defaultness: bool, |
1399 | pub sig: Signature, |
1400 | pub body: Option<Vec<Stmt>>, |
1401 | } |
1402 | |
1403 | pub struct FlexibleItemStatic { |
1404 | pub attrs: Vec<Attribute>, |
1405 | pub vis: Visibility, |
1406 | pub mutability: StaticMutability, |
1407 | pub ident: Ident, |
1408 | pub ty: Option<Type>, |
1409 | pub expr: Option<Expr>, |
1410 | } |
1411 | |
1412 | pub struct FlexibleItemType { |
1413 | pub attrs: Vec<Attribute>, |
1414 | pub vis: Visibility, |
1415 | pub defaultness: bool, |
1416 | pub ident: Ident, |
1417 | pub generics: Generics, |
1418 | pub bounds: Vec<TypeParamBound>, |
1419 | pub definition: Option<Type>, |
1420 | pub where_clause_after_eq: Option<WhereClause>, |
1421 | } |
1422 | |
1423 | pub enum WhereClauseLocation { |
1424 | // type Ty<T> where T: 'static = T; |
1425 | BeforeEq, |
1426 | // type Ty<T> = T where T: 'static; |
1427 | AfterEq, |
1428 | // TODO: goes away once the migration period on rust-lang/rust#89122 is over |
1429 | Both, |
1430 | } |
1431 | |
1432 | impl FlexibleItemConst { |
1433 | pub fn parse( |
1434 | attrs: Vec<Attribute>, |
1435 | vis: Visibility, |
1436 | defaultness: bool, |
1437 | input: ParseStream, |
1438 | ) -> Result<Self> { |
1439 | input.parse::<Token![const]>()?; |
1440 | let ident = input.call(Ident::parse_any)?; |
1441 | let mut generics: Generics = input.parse()?; |
1442 | input.parse::<Token![:]>()?; |
1443 | let ty: Type = input.parse()?; |
1444 | let value = if input.parse::<Option<Token![=]>>()?.is_some() { |
1445 | let expr: Expr = input.parse()?; |
1446 | Some(expr) |
1447 | } else { |
1448 | None |
1449 | }; |
1450 | generics.where_clause = input.parse()?; |
1451 | input.parse::<Token![;]>()?; |
1452 | |
1453 | Ok(FlexibleItemConst { |
1454 | attrs, |
1455 | vis, |
1456 | defaultness, |
1457 | ident, |
1458 | generics, |
1459 | ty, |
1460 | value, |
1461 | }) |
1462 | } |
1463 | } |
1464 | |
1465 | impl FlexibleItemFn { |
1466 | pub fn parse( |
1467 | mut attrs: Vec<Attribute>, |
1468 | vis: Visibility, |
1469 | defaultness: bool, |
1470 | input: ParseStream, |
1471 | ) -> Result<Self> { |
1472 | let sig: Signature = input.parse()?; |
1473 | |
1474 | let lookahead = input.lookahead1(); |
1475 | let body = if lookahead.peek(Token![;]) { |
1476 | input.parse::<Token![;]>()?; |
1477 | None |
1478 | } else if lookahead.peek(token::Brace) { |
1479 | let content; |
1480 | braced!(content in input); |
1481 | attrs.extend(content.call(Attribute::parse_inner)?); |
1482 | Some(content.call(Block::parse_within)?) |
1483 | } else { |
1484 | return Err(lookahead.error()); |
1485 | }; |
1486 | |
1487 | Ok(FlexibleItemFn { |
1488 | attrs, |
1489 | vis, |
1490 | defaultness, |
1491 | sig, |
1492 | body, |
1493 | }) |
1494 | } |
1495 | } |
1496 | |
1497 | impl FlexibleItemStatic { |
1498 | pub fn parse(attrs: Vec<Attribute>, vis: Visibility, input: ParseStream) -> Result<Self> { |
1499 | input.parse::<Token![static]>()?; |
1500 | let mutability: StaticMutability = input.parse()?; |
1501 | let ident = input.parse()?; |
1502 | |
1503 | let lookahead = input.lookahead1(); |
1504 | let has_type = lookahead.peek(Token![:]); |
1505 | let has_expr = lookahead.peek(Token![=]); |
1506 | if !has_type && !has_expr { |
1507 | return Err(lookahead.error()); |
1508 | } |
1509 | |
1510 | let ty: Option<Type> = if has_type { |
1511 | input.parse::<Token![:]>()?; |
1512 | input.parse().map(Some)? |
1513 | } else { |
1514 | None |
1515 | }; |
1516 | |
1517 | let expr: Option<Expr> = if input.parse::<Option<Token![=]>>()?.is_some() { |
1518 | input.parse().map(Some)? |
1519 | } else { |
1520 | None |
1521 | }; |
1522 | |
1523 | input.parse::<Token![;]>()?; |
1524 | |
1525 | Ok(FlexibleItemStatic { |
1526 | attrs, |
1527 | vis, |
1528 | mutability, |
1529 | ident, |
1530 | ty, |
1531 | expr, |
1532 | }) |
1533 | } |
1534 | } |
1535 | |
1536 | impl FlexibleItemType { |
1537 | pub fn parse( |
1538 | attrs: Vec<Attribute>, |
1539 | vis: Visibility, |
1540 | defaultness: bool, |
1541 | input: ParseStream, |
1542 | where_clause_location: WhereClauseLocation, |
1543 | ) -> Result<Self> { |
1544 | input.parse::<Token![type]>()?; |
1545 | let ident: Ident = input.parse()?; |
1546 | let mut generics: Generics = input.parse()?; |
1547 | |
1548 | let mut bounds = Vec::new(); |
1549 | if input.parse::<Option<Token![:]>>()?.is_some() { |
1550 | loop { |
1551 | if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { |
1552 | break; |
1553 | } |
1554 | bounds.push(input.parse::<TypeParamBound>()?); |
1555 | if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) { |
1556 | break; |
1557 | } |
1558 | input.parse::<Token![+]>()?; |
1559 | } |
1560 | } |
1561 | |
1562 | match where_clause_location { |
1563 | WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => { |
1564 | generics.where_clause = input.parse()?; |
1565 | } |
1566 | WhereClauseLocation::AfterEq => {} |
1567 | } |
1568 | |
1569 | let definition = if input.parse::<Option<Token![=]>>()?.is_some() { |
1570 | Some(input.parse()?) |
1571 | } else { |
1572 | None |
1573 | }; |
1574 | |
1575 | let where_clause_after_eq = match where_clause_location { |
1576 | WhereClauseLocation::AfterEq | WhereClauseLocation::Both |
1577 | if generics.where_clause.is_none() => |
1578 | { |
1579 | input.parse()? |
1580 | } |
1581 | _ => None, |
1582 | }; |
1583 | |
1584 | input.parse::<Token![;]>()?; |
1585 | |
1586 | Ok(FlexibleItemType { |
1587 | attrs, |
1588 | vis, |
1589 | defaultness, |
1590 | ident, |
1591 | generics, |
1592 | bounds, |
1593 | definition, |
1594 | where_clause_after_eq, |
1595 | }) |
1596 | } |
1597 | } |
1598 | |
1599 | impl Printer { |
1600 | pub fn flexible_item_const(&mut self, item: &FlexibleItemConst) { |
1601 | self.outer_attrs(&item.attrs); |
1602 | self.cbox(INDENT); |
1603 | self.visibility(&item.vis); |
1604 | if item.defaultness { |
1605 | self.word("default " ); |
1606 | } |
1607 | self.word("const " ); |
1608 | self.ident(&item.ident); |
1609 | self.generics(&item.generics); |
1610 | self.word(": " ); |
1611 | self.cbox(-INDENT); |
1612 | self.ty(&item.ty); |
1613 | self.end(); |
1614 | if let Some(value) = &item.value { |
1615 | self.word(" = " ); |
1616 | self.neverbreak(); |
1617 | self.ibox(-INDENT); |
1618 | self.expr(value); |
1619 | self.end(); |
1620 | } |
1621 | self.where_clause_oneline_semi(&item.generics.where_clause); |
1622 | self.end(); |
1623 | self.hardbreak(); |
1624 | } |
1625 | |
1626 | pub fn flexible_item_fn(&mut self, item: &FlexibleItemFn) { |
1627 | self.outer_attrs(&item.attrs); |
1628 | self.cbox(INDENT); |
1629 | self.visibility(&item.vis); |
1630 | if item.defaultness { |
1631 | self.word("default " ); |
1632 | } |
1633 | self.signature(&item.sig); |
1634 | if let Some(body) = &item.body { |
1635 | self.where_clause_for_body(&item.sig.generics.where_clause); |
1636 | self.word("{" ); |
1637 | self.hardbreak_if_nonempty(); |
1638 | self.inner_attrs(&item.attrs); |
1639 | for stmt in body { |
1640 | self.stmt(stmt); |
1641 | } |
1642 | self.offset(-INDENT); |
1643 | self.end(); |
1644 | self.word("}" ); |
1645 | } else { |
1646 | self.where_clause_semi(&item.sig.generics.where_clause); |
1647 | self.end(); |
1648 | } |
1649 | self.hardbreak(); |
1650 | } |
1651 | |
1652 | pub fn flexible_item_static(&mut self, item: &FlexibleItemStatic) { |
1653 | self.outer_attrs(&item.attrs); |
1654 | self.cbox(0); |
1655 | self.visibility(&item.vis); |
1656 | self.word("static " ); |
1657 | self.static_mutability(&item.mutability); |
1658 | self.ident(&item.ident); |
1659 | if let Some(ty) = &item.ty { |
1660 | self.word(": " ); |
1661 | self.ty(ty); |
1662 | } |
1663 | if let Some(expr) = &item.expr { |
1664 | self.word(" = " ); |
1665 | self.neverbreak(); |
1666 | self.expr(expr); |
1667 | } |
1668 | self.word(";" ); |
1669 | self.end(); |
1670 | self.hardbreak(); |
1671 | } |
1672 | |
1673 | pub fn flexible_item_type(&mut self, item: &FlexibleItemType) { |
1674 | self.outer_attrs(&item.attrs); |
1675 | self.cbox(INDENT); |
1676 | self.visibility(&item.vis); |
1677 | if item.defaultness { |
1678 | self.word("default " ); |
1679 | } |
1680 | self.word("type " ); |
1681 | self.ident(&item.ident); |
1682 | self.generics(&item.generics); |
1683 | for bound in item.bounds.iter().delimited() { |
1684 | if bound.is_first { |
1685 | self.word(": " ); |
1686 | } else { |
1687 | self.space(); |
1688 | self.word("+ " ); |
1689 | } |
1690 | self.type_param_bound(&bound); |
1691 | } |
1692 | if let Some(definition) = &item.definition { |
1693 | self.where_clause_oneline(&item.generics.where_clause); |
1694 | self.word("= " ); |
1695 | self.neverbreak(); |
1696 | self.ibox(-INDENT); |
1697 | self.ty(definition); |
1698 | self.end(); |
1699 | self.where_clause_oneline_semi(&item.where_clause_after_eq); |
1700 | } else { |
1701 | self.where_clause_oneline_semi(&item.generics.where_clause); |
1702 | } |
1703 | self.end(); |
1704 | self.hardbreak(); |
1705 | } |
1706 | } |
1707 | } |
1708 | |