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