c2rust_ast_builder/
builder.rs

1//! Helpers for building AST nodes.  Normally used by calling `mk().some_node(args...)`.
2
3use std::str;
4
5use itertools::intersperse;
6use proc_macro2::{Literal, Punct, Spacing, Span, TokenStream, TokenTree};
7use std::default::Default;
8use std::iter::FromIterator;
9use syn::{__private::ToTokens, punctuated::Punctuated, *};
10
11pub mod properties {
12    use proc_macro2::Span;
13    use syn::{StaticMutability, Token};
14
15    pub trait ToToken {
16        type Token;
17        fn to_token(&self) -> Option<Self::Token>;
18    }
19
20    #[derive(Debug, Copy, Clone)]
21    pub enum Mutability {
22        Mutable,
23        Immutable,
24    }
25
26    impl ToToken for Mutability {
27        type Token = Token![mut];
28        fn to_token(&self) -> Option<Self::Token> {
29            match self {
30                Mutability::Mutable => Some(Default::default()),
31                Mutability::Immutable => None,
32            }
33        }
34    }
35
36    impl Mutability {
37        pub fn to_static_mutability(&self, span: Span) -> StaticMutability {
38            match self {
39                Mutability::Mutable => StaticMutability::Mut(Token![mut](span)),
40                Mutability::Immutable => StaticMutability::None,
41            }
42        }
43    }
44
45    #[derive(Debug, Clone)]
46    pub enum Unsafety {
47        Normal,
48        Unsafe,
49    }
50    impl ToToken for Unsafety {
51        type Token = Token![unsafe];
52        fn to_token(&self) -> Option<Self::Token> {
53            match self {
54                Unsafety::Normal => None,
55                Unsafety::Unsafe => Some(Default::default()),
56            }
57        }
58    }
59
60    #[derive(Debug, Clone)]
61    pub enum Constness {
62        Const,
63        NotConst,
64    }
65    impl ToToken for Constness {
66        type Token = Token![const];
67        fn to_token(&self) -> Option<Self::Token> {
68            match self {
69                Constness::NotConst => None,
70                Constness::Const => Some(Default::default()),
71            }
72        }
73    }
74
75    #[derive(Debug, Clone)]
76    pub enum Movability {
77        Movable,
78        Immovable,
79    }
80    impl ToToken for Movability {
81        type Token = Token![static];
82        fn to_token(&self) -> Option<Self::Token> {
83            match self {
84                Movability::Immovable => Some(Default::default()),
85                Movability::Movable => None,
86            }
87        }
88    }
89
90    #[derive(Debug, Clone)]
91    pub enum IsAsync {
92        Async,
93        NotAsync,
94    }
95    impl ToToken for IsAsync {
96        type Token = Token![async];
97        fn to_token(&self) -> Option<Self::Token> {
98            match self {
99                IsAsync::NotAsync => None,
100                IsAsync::Async => Some(Default::default()),
101            }
102        }
103    }
104
105    #[derive(Debug, Clone)]
106    pub enum Defaultness {
107        Final,
108        Default,
109    }
110    impl ToToken for Defaultness {
111        type Token = Token![default];
112        fn to_token(&self) -> Option<Self::Token> {
113            match self {
114                Defaultness::Final => None,
115                Defaultness::Default => Some(Default::default()),
116            }
117        }
118    }
119}
120
121use self::properties::*;
122
123pub type FnDecl = (Ident, Vec<FnArg>, Option<Variadic>, ReturnType);
124pub type BareFnTyParts = (Vec<BareFnArg>, Option<BareVariadic>, ReturnType);
125
126pub enum CaptureBy {
127    Value,
128    Ref,
129}
130
131#[derive(Debug, Clone)]
132pub enum Extern {
133    None,
134    Implicit,
135    Explicit(String),
136}
137
138//const Async : IsAsync = Some(Default::default());
139
140pub enum SelfKind {
141    Value(Mutability),
142    Region(Lifetime, Mutability),
143}
144
145fn use_tree_with_prefix(prefix: Path, leaf: UseTree) -> UseTree {
146    let mut out = leaf;
147    for seg in prefix.segments.into_iter().rev() {
148        out = UseTree::Path(UsePath {
149            ident: seg.ident,
150            colon2_token: Default::default(),
151            tree: Box::new(out),
152        });
153    }
154    out
155}
156
157fn punct<T, P: Default>(x: Vec<T>) -> Punctuated<T, P> {
158    Punctuated::from_iter(x)
159}
160
161fn punct_box<T, P: Default>(x: Vec<Box<T>>) -> Punctuated<T, P> {
162    Punctuated::from_iter(x.into_iter().map(|x| *x))
163}
164
165fn comma_separated<I, T>(items: I) -> TokenStream
166where
167    I: Iterator<Item = T>,
168    T: ToTokens + Clone,
169{
170    let items = items.map(|items| items.to_token_stream());
171    let comma = TokenTree::Punct(Punct::new(',', Spacing::Alone)).into_token_stream();
172    intersperse(items, comma).collect()
173}
174
175pub trait Make<T> {
176    fn make(self, mk: &Builder) -> T;
177}
178
179impl<T> Make<T> for T {
180    fn make(self, _mk: &Builder) -> T {
181        self
182    }
183}
184
185impl Make<Ident> for &str {
186    fn make(self, mk: &Builder) -> Ident {
187        Ident::new(self, mk.span)
188    }
189}
190
191impl Make<Ident> for String {
192    fn make(self, mk: &Builder) -> Ident {
193        Ident::new(&self, mk.span)
194    }
195}
196
197impl Make<Ident> for &String {
198    fn make(self, mk: &Builder) -> Ident {
199        Ident::new(self, mk.span)
200    }
201}
202
203impl<L: Make<Ident>> Make<Label> for L {
204    fn make(self, mk: &Builder) -> Label {
205        Label {
206            name: Lifetime {
207                apostrophe: mk.span,
208                ident: self.make(mk),
209            },
210            colon_token: Token![:](mk.span),
211        }
212    }
213}
214
215impl Make<Path> for &str {
216    fn make(self, mk: &Builder) -> Path {
217        let v = vec![self];
218        Make::<Path>::make(v, mk)
219    }
220}
221
222impl Make<Abi> for &str {
223    fn make(self, mk: &Builder) -> Abi {
224        Abi {
225            extern_token: Token![extern](mk.span),
226            name: Some(LitStr::new(self, mk.span)),
227        }
228        // TODO: validate string: format!("unrecognized string for Abi: {:?}", self))
229    }
230}
231
232impl Make<Extern> for &str {
233    fn make(self, _mk: &Builder) -> Extern {
234        Extern::Explicit(self.to_owned())
235    }
236}
237
238impl Make<Extern> for Abi {
239    fn make(self, _mk: &Builder) -> Extern {
240        Extern::Explicit(self.name.to_token_stream().to_string())
241    }
242}
243
244impl<I: Make<Ident>> Make<Lifetime> for I {
245    fn make(self, mk: &Builder) -> Lifetime {
246        Lifetime {
247            apostrophe: mk.span,
248            ident: self.make(mk),
249        }
250    }
251}
252
253impl<I: Make<Ident>> Make<PathSegment> for I {
254    fn make(self, mk: &Builder) -> PathSegment {
255        PathSegment {
256            ident: self.make(mk),
257            arguments: PathArguments::None,
258        }
259    }
260}
261
262impl<S: Make<PathSegment>> Make<Path> for Vec<S> {
263    fn make(self, mk: &Builder) -> Path {
264        let mut segments = Punctuated::new();
265        for s in self {
266            segments.push(s.make(mk));
267        }
268        Path {
269            leading_colon: None,
270            segments,
271        }
272    }
273}
274
275impl Make<TokenStream> for Vec<TokenTree> {
276    fn make(self, _mk: &Builder) -> TokenStream {
277        self.into_iter().collect::<TokenStream>()
278    }
279}
280
281impl Make<TokenStream> for Vec<&str> {
282    fn make(self, _mk: &Builder) -> TokenStream {
283        comma_separated(self.iter().map(|&s| Ident::new(s, Span::call_site())))
284    }
285}
286
287impl Make<TokenStream> for Vec<u64> {
288    fn make(self, _mk: &Builder) -> TokenStream {
289        comma_separated(self.iter().map(|&s| Literal::u64_unsuffixed(s)))
290    }
291}
292
293impl Make<TokenStream> for Vec<Meta> {
294    fn make(self, _mk: &Builder) -> TokenStream {
295        comma_separated(self.iter())
296    }
297}
298
299impl Make<PathArguments> for AngleBracketedGenericArguments {
300    fn make(self, _mk: &Builder) -> PathArguments {
301        PathArguments::AngleBracketed(self)
302    }
303}
304
305impl Make<GenericArgument> for Box<Type> {
306    fn make(self, _mk: &Builder) -> GenericArgument {
307        GenericArgument::Type(*self)
308    }
309}
310
311impl Make<GenericArgument> for Lifetime {
312    fn make(self, _mk: &Builder) -> GenericArgument {
313        GenericArgument::Lifetime(self)
314    }
315}
316
317impl Make<Lit> for String {
318    fn make(self, mk: &Builder) -> Lit {
319        Lit::Str(LitStr::new(&self, mk.span))
320    }
321}
322
323impl Make<Lit> for &String {
324    fn make(self, mk: &Builder) -> Lit {
325        Lit::Str(LitStr::new(self, mk.span))
326    }
327}
328
329impl Make<Lit> for &str {
330    fn make(self, mk: &Builder) -> Lit {
331        Lit::Str(LitStr::new(self, mk.span))
332    }
333}
334
335impl Make<Lit> for Vec<u8> {
336    fn make(self, mk: &Builder) -> Lit {
337        Lit::ByteStr(LitByteStr::new(&self, mk.span))
338    }
339}
340
341impl Make<Lit> for u8 {
342    fn make(self, mk: &Builder) -> Lit {
343        Lit::Byte(LitByte::new(self, mk.span))
344    }
345}
346
347impl Make<Lit> for char {
348    fn make(self, mk: &Builder) -> Lit {
349        Lit::Char(LitChar::new(self, mk.span))
350    }
351}
352
353impl Make<Lit> for u128 {
354    fn make(self, mk: &Builder) -> Lit {
355        Lit::Int(LitInt::new(&self.to_string(), mk.span))
356    }
357}
358
359impl Make<Signature> for Box<FnDecl> {
360    fn make(self, mk: &Builder) -> Signature {
361        let (name, inputs, variadic, output) = *self;
362        Signature {
363            unsafety: mk.unsafety.to_token(),
364            asyncness: IsAsync::NotAsync.to_token(),
365            constness: mk.constness.to_token(),
366            fn_token: Token![fn](mk.span),
367            paren_token: Default::default(),
368            generics: mk.generics.clone(),
369            abi: mk.get_abi_opt(),
370            ident: name,
371            inputs: punct(inputs),
372            variadic,
373            output,
374        }
375    }
376}
377
378impl Make<String> for i32 {
379    fn make(self, mk: &Builder) -> String {
380        (self as i128).make(mk)
381    }
382}
383
384impl Make<String> for i64 {
385    fn make(self, mk: &Builder) -> String {
386        (self as i128).make(mk)
387    }
388}
389
390impl Make<String> for u64 {
391    fn make(self, mk: &Builder) -> String {
392        (self as u128).make(mk)
393    }
394}
395
396impl Make<String> for i128 {
397    fn make(self, _mk: &Builder) -> String {
398        self.to_string()
399    }
400}
401
402impl Make<String> for u128 {
403    fn make(self, _mk: &Builder) -> String {
404        self.to_string()
405    }
406}
407
408#[derive(Clone, Debug)]
409pub struct Builder {
410    // The builder holds a set of "modifiers", such as visibility and mutability.  Functions for
411    // building AST nodes don't take arguments of these types, but instead use any applicable
412    // modifiers from the builder to set the node's visibility, mutability, etc.
413    vis: Visibility,
414    mutbl: Mutability,
415    generics: Generics,
416    unsafety: Unsafety,
417    constness: Constness,
418    ext: Extern,
419    attrs: Vec<Attribute>,
420    span: Span,
421}
422
423impl Default for Builder {
424    fn default() -> Self {
425        Builder {
426            vis: Visibility::Inherited,
427            mutbl: Mutability::Immutable,
428            generics: Generics::default(),
429            unsafety: Unsafety::Normal,
430            constness: Constness::NotConst,
431            ext: Extern::None,
432            attrs: Vec::new(),
433            span: Span::call_site(),
434        }
435    }
436}
437
438impl Builder {
439    pub fn new() -> Builder {
440        Builder::default()
441    }
442
443    // Modifier updates.
444
445    pub fn vis<V: Make<Visibility>>(self, vis: V) -> Self {
446        let vis = vis.make(&self);
447        Builder { vis, ..self }
448    }
449
450    pub fn pub_(self) -> Self {
451        let pub_token = Token![pub](self.span);
452        self.vis(Visibility::Public(pub_token))
453    }
454
455    pub fn set_mutbl<M: Make<Mutability>>(self, mutbl: M) -> Self {
456        let mutbl = mutbl.make(&self);
457        Builder { mutbl, ..self }
458    }
459
460    pub fn mutbl(self) -> Self {
461        self.set_mutbl(Mutability::Mutable)
462    }
463
464    pub fn unsafety<U: Make<Unsafety>>(self, unsafety: U) -> Self {
465        let unsafety = unsafety.make(&self);
466        Builder { unsafety, ..self }
467    }
468
469    pub fn unsafe_(self) -> Self {
470        self.unsafety(Unsafety::Unsafe)
471    }
472
473    pub fn constness<C: Make<Constness>>(self, constness: C) -> Self {
474        let constness = constness.make(&self);
475        Builder { constness, ..self }
476    }
477
478    pub fn const_(self) -> Self {
479        self.constness(Constness::Const)
480    }
481
482    pub fn extern_<A: Make<Extern>>(self, ext: A) -> Self {
483        let ext = ext.make(&self);
484        Builder { ext, ..self }
485    }
486
487    pub fn span<S: Make<Span>>(self, span: S) -> Self {
488        let span = span.make(&self);
489        Builder { span, ..self }
490    }
491
492    pub fn generic_over(mut self, param: GenericParam) -> Self {
493        self.generics.params.push(param);
494        self
495    }
496
497    pub fn prepared_attr(self, meta: Meta) -> Self {
498        let attr = self.clone().attribute(AttrStyle::Outer, meta);
499        let mut attrs = self.attrs;
500        attrs.push(attr);
501        Builder { attrs, ..self }
502    }
503
504    pub fn str_attr<K, V>(self, key: K, value: V) -> Self
505    where
506        K: Make<Path>,
507        V: Make<Lit>,
508    {
509        let meta = mk().meta_namevalue(key, value);
510        self.prepared_attr(meta)
511    }
512
513    pub fn single_attr<K>(self, key: K) -> Self
514    where
515        K: Make<Path>,
516    {
517        let meta = mk().meta_path(key);
518        self.prepared_attr(meta)
519    }
520
521    pub fn call_attr<K, V>(self, func: K, arguments: V) -> Self
522    where
523        K: Make<Path>,
524        V: Make<TokenStream>,
525    {
526        let meta = mk().meta_list(func, arguments);
527        self.prepared_attr(meta)
528    }
529
530    // Path segments with parameters
531
532    pub fn path_segment_with_args<I, P>(self, identifier: I, args: P) -> PathSegment
533    where
534        I: Make<Ident>,
535        P: Make<PathArguments>,
536    {
537        let identifier = identifier.make(&self);
538        let args = args.make(&self);
539        PathSegment {
540            ident: identifier,
541            arguments: args,
542        }
543    }
544
545    pub fn angle_bracketed_args<A>(self, args: Vec<A>) -> AngleBracketedGenericArguments
546    where
547        A: Make<GenericArgument>,
548    {
549        let args = args.into_iter().map(|arg| arg.make(&self)).collect();
550        AngleBracketedGenericArguments {
551            colon2_token: Some(Token![::](self.span)), // Always include a colon2 for turbofish
552            lt_token: Token![<](self.span),
553            args,
554            gt_token: Token![>](self.span),
555        }
556    }
557
558    pub fn generic_arg<A>(self, arg: A) -> GenericArgument
559    where
560        A: Make<GenericArgument>,
561    {
562        arg.make(&self)
563    }
564
565    // Simple nodes
566
567    pub fn ident<I>(self, name: I) -> Ident
568    where
569        I: Make<Ident>,
570    {
571        name.make(&self)
572    }
573
574    pub fn path_segment<S>(self, seg: S) -> PathSegment
575    where
576        S: Make<PathSegment>,
577    {
578        seg.make(&self)
579    }
580
581    pub fn path<Pa>(self, path: Pa) -> Path
582    where
583        Pa: Make<Path>,
584    {
585        path.make(&self)
586    }
587
588    pub fn use_tree<Pa>(self, prefix: Pa, mut tree: UseTree) -> UseTree
589    where
590        Pa: Make<Path>,
591    {
592        let path: Path = prefix.make(&self);
593        for seg in path.segments {
594            tree = UseTree::Path(UsePath {
595                ident: seg.ident,
596                colon2_token: Token![::](self.span),
597                tree: Box::new(tree),
598            });
599        }
600        tree
601    }
602
603    pub fn abs_path<Pa>(self, path: Pa) -> Path
604    where
605        Pa: Make<Path>,
606    {
607        let mut path = path.make(&self);
608        path.leading_colon = Some(Token![::](self.span));
609        path
610    }
611
612    // Exprs
613    // These are sorted in the same order as the corresponding ExprKind variants, with additional
614    // variant-specific details following each variant.
615
616    pub fn array_expr(self, args: Vec<Box<Expr>>) -> Box<Expr> {
617        let args = args.into_iter().map(|a| *a).collect();
618        Box::new(Expr::Array(ExprArray {
619            attrs: self.attrs,
620            bracket_token: token::Bracket(self.span),
621            elems: args,
622        }))
623    }
624
625    pub fn call_expr(self, func: Box<Expr>, args: Vec<Box<Expr>>) -> Box<Expr> {
626        let args = args.into_iter().map(|a| *a).collect();
627        Box::new(parenthesize_if_necessary(Expr::Call(ExprCall {
628            attrs: self.attrs,
629            paren_token: token::Paren(self.span),
630            func,
631            args,
632        })))
633    }
634
635    pub fn method_call_expr<S>(self, expr: Box<Expr>, seg: S, args: Vec<Box<Expr>>) -> Box<Expr>
636    where
637        S: Make<PathSegment>,
638    {
639        let seg = seg.make(&self);
640        let args = args
641            .into_iter()
642            .map(|arg| *arg)
643            .map(|arg| arg.make(&self))
644            .collect();
645
646        let turbofish = match seg.arguments {
647            PathArguments::None => None,
648            PathArguments::AngleBracketed(ab) => Some(ab),
649            PathArguments::Parenthesized(_) => {
650                panic!("Found parenthesized arguments on path segment for method call")
651            }
652        };
653
654        Box::new(parenthesize_if_necessary(Expr::MethodCall(
655            ExprMethodCall {
656                attrs: self.attrs,
657                dot_token: Token![.](self.span),
658                paren_token: token::Paren(self.span),
659                turbofish,
660                receiver: expr,
661                method: seg.ident,
662                args,
663            },
664        )))
665    }
666
667    pub fn tuple_expr(self, exprs: Vec<Box<Expr>>) -> Box<Expr> {
668        Box::new(Expr::Tuple(ExprTuple {
669            attrs: self.attrs,
670            paren_token: token::Paren(self.span),
671            elems: punct_box(exprs),
672        }))
673    }
674
675    pub fn binary_expr(self, op: BinOp, mut lhs: Box<Expr>, rhs: Box<Expr>) -> Box<Expr> {
676        match op {
677            BinOp::Lt(_) | BinOp::Shl(_) if has_rightmost_cast(&lhs) => lhs = mk().paren_expr(lhs),
678            _ => {}
679        }
680
681        Box::new(parenthesize_if_necessary(Expr::Binary(ExprBinary {
682            attrs: self.attrs,
683            left: lhs,
684            op,
685            right: rhs,
686        })))
687    }
688
689    pub fn unary_expr<O>(self, op: O, a: Box<Expr>) -> Box<Expr>
690    where
691        O: Make<UnOp>,
692    {
693        let op = op.make(&self);
694        // FIXME: set span for op
695        Box::new(parenthesize_if_necessary(Expr::Unary(ExprUnary {
696            attrs: self.attrs,
697            op,
698            expr: a,
699        })))
700    }
701
702    pub fn lit_expr<L>(self, lit: L) -> Box<Expr>
703    where
704        L: Make<Lit>,
705    {
706        let mut lit = lit.make(&self);
707        lit.set_span(self.span);
708        Box::new(Expr::Lit(ExprLit {
709            attrs: self.attrs,
710            lit,
711        }))
712    }
713
714    pub fn cast_expr(self, e: Box<Expr>, t: Box<Type>) -> Box<Expr> {
715        Box::new(parenthesize_if_necessary(Expr::Cast(ExprCast {
716            attrs: self.attrs,
717            as_token: Token![as](self.span),
718            expr: e,
719            ty: t,
720        })))
721    }
722
723    pub fn unsafe_block_expr(self, unsafe_blk: ExprUnsafe) -> Box<Expr> {
724        Box::new(Expr::Unsafe(unsafe_blk))
725    }
726
727    pub fn block_expr(self, block: Block) -> Box<Expr> {
728        Box::new(Expr::Block(ExprBlock {
729            attrs: self.attrs,
730            block,
731            label: None,
732        }))
733    }
734
735    pub fn labelled_block_expr<L>(self, block: Block, lbl: L) -> Box<Expr>
736    where
737        L: Make<Label>,
738    {
739        let lbl = lbl.make(&self);
740        Box::new(Expr::Block(ExprBlock {
741            attrs: self.attrs,
742            block,
743            label: Some(lbl),
744        }))
745    }
746
747    pub fn assign_expr(self, lhs: Box<Expr>, rhs: Box<Expr>) -> Box<Expr> {
748        Box::new(Expr::Assign(ExprAssign {
749            attrs: self.attrs,
750            eq_token: Token![=](self.span),
751            left: lhs,
752            right: rhs,
753        }))
754    }
755
756    pub fn assign_op_expr(self, op: BinOp, lhs: Box<Expr>, rhs: Box<Expr>) -> Box<Expr> {
757        Box::new(Expr::Binary(ExprBinary {
758            attrs: self.attrs,
759            op,
760            left: lhs,
761            right: rhs,
762        }))
763    }
764
765    pub fn index_expr(self, lhs: Box<Expr>, rhs: Box<Expr>) -> Box<Expr> {
766        Box::new(parenthesize_if_necessary(Expr::Index(ExprIndex {
767            attrs: self.attrs,
768            bracket_token: token::Bracket(self.span),
769            expr: lhs,
770            index: rhs,
771        })))
772    }
773
774    pub fn abs_path_expr<Pa>(self, path: Pa) -> Box<Expr>
775    where
776        Pa: Make<Path>,
777    {
778        let path = mk().abs_path(path);
779        self.path_expr(path)
780    }
781
782    pub fn path_expr<Pa>(self, path: Pa) -> Box<Expr>
783    where
784        Pa: Make<Path>,
785    {
786        self.qpath_expr(None, path)
787    }
788
789    pub fn qpath_expr<Pa>(self, qself: Option<QSelf>, path: Pa) -> Box<Expr>
790    where
791        Pa: Make<Path>,
792    {
793        let path = path.make(&self);
794        Box::new(Expr::Path(ExprPath {
795            attrs: self.attrs,
796            qself,
797            path,
798        }))
799    }
800
801    /// An array literal constructed from one repeated element.
802    /// `[expr; n]`
803    pub fn repeat_expr(self, expr: Box<Expr>, n: Box<Expr>) -> Box<Expr> {
804        Box::new(Expr::Repeat(ExprRepeat {
805            attrs: self.attrs,
806            bracket_token: token::Bracket(self.span),
807            semi_token: Token![;](self.span),
808            expr,
809            len: n,
810        }))
811    }
812
813    pub fn paren_expr(self, e: Box<Expr>) -> Box<Expr> {
814        Box::new(Expr::Paren(ExprParen {
815            attrs: self.attrs,
816            paren_token: token::Paren(self.span),
817            expr: e,
818        }))
819    }
820
821    // Special case of path_expr
822    pub fn ident_expr<I>(self, name: I) -> Box<Expr>
823    where
824        I: Make<Ident>,
825    {
826        self.path_expr(vec![name])
827    }
828
829    pub fn addr_of_expr(self, e: Box<Expr>) -> Box<Expr> {
830        Box::new(parenthesize_if_necessary(Expr::Reference(ExprReference {
831            attrs: self.attrs,
832            and_token: Token![&](self.span),
833            mutability: self.mutbl.to_token(),
834            expr: e,
835        })))
836    }
837
838    pub fn mac_expr(self, mac: Macro) -> Box<Expr> {
839        Box::new(Expr::Macro(ExprMacro {
840            attrs: self.attrs,
841            mac,
842        }))
843    }
844
845    pub fn struct_expr<Pa>(self, path: Pa, fields: Vec<FieldValue>) -> Box<Expr>
846    where
847        Pa: Make<Path>,
848    {
849        let path = path.make(&self);
850        Box::new(Expr::Struct(ExprStruct {
851            attrs: self.attrs,
852            qself: None,
853            brace_token: token::Brace(self.span),
854            dot2_token: None,
855            path,
856            fields: punct(fields),
857            rest: None,
858        }))
859    }
860
861    // struct_expr, but with optional base expression
862    pub fn struct_expr_base<Pa>(
863        self,
864        path: Pa,
865        fields: Vec<FieldValue>,
866        base: Option<Box<Expr>>,
867    ) -> Box<Expr>
868    where
869        Pa: Make<Path>,
870    {
871        let path = path.make(&self);
872        Box::new(Expr::Struct(ExprStruct {
873            attrs: self.attrs,
874            qself: None,
875            brace_token: token::Brace(self.span),
876            dot2_token: Some(Token![..](self.span)),
877            path,
878            fields: punct(fields),
879            rest: base,
880        }))
881    }
882
883    pub fn field_expr<F>(self, val: Box<Expr>, field: F) -> Box<Expr>
884    where
885        F: Make<Ident>,
886    {
887        let field = field.make(&self);
888        Box::new(parenthesize_if_necessary(Expr::Field(ExprField {
889            attrs: self.attrs,
890            dot_token: Token![.](self.span),
891            base: val,
892            member: Member::Named(field),
893        })))
894    }
895
896    pub fn anon_field_expr(self, val: Box<Expr>, field: u32) -> Box<Expr> {
897        Box::new(parenthesize_if_necessary(Expr::Field(ExprField {
898            attrs: self.attrs,
899            dot_token: Token![.](self.span),
900            base: val,
901            member: Member::Unnamed(Index {
902                index: field,
903                span: self.span,
904            }),
905        })))
906    }
907
908    pub fn field<I>(self, ident: I, expr: Box<Expr>) -> FieldValue
909    where
910        I: Make<Ident>,
911    {
912        let ident = ident.make(&self);
913        FieldValue {
914            member: Member::Named(ident),
915            expr: *expr,
916            colon_token: Some(Token![:](self.span)),
917            attrs: self.attrs,
918        }
919    }
920
921    pub fn match_expr(self, cond: Box<Expr>, arms: Vec<Arm>) -> Box<Expr> {
922        let arms = arms.into_iter().collect();
923        Box::new(Expr::Match(ExprMatch {
924            attrs: self.attrs,
925            match_token: Token![match](self.span),
926            brace_token: token::Brace(self.span),
927            expr: cond,
928            arms,
929        }))
930    }
931
932    pub fn arm(self, pat: Pat, guard: Option<Box<Expr>>, body: Box<Expr>) -> Arm {
933        let guard = guard.map(|g| (Token![if](self.span), g));
934        Arm {
935            attrs: self.attrs,
936            pat,
937            guard,
938            body,
939            fat_arrow_token: Token![=>](self.span),
940            comma: Some(Token![,](self.span)),
941        }
942    }
943
944    // Literals
945
946    pub fn int_lit(self, i: u128, ty: &str) -> Lit {
947        Lit::Int(LitInt::new(&format!("{}{}", i, ty), self.span))
948    }
949
950    pub fn int_unsuffixed_lit<S>(self, s: S) -> Lit
951    where
952        S: Make<String>,
953    {
954        let s = s.make(&self);
955        Lit::Int(LitInt::new(&s, self.span))
956    }
957
958    pub fn float_lit(self, s: &str, ty: &str) -> Lit {
959        Lit::Float(LitFloat::new(&format!("{}{}", s, ty), self.span))
960    }
961
962    pub fn float_unsuffixed_lit(self, s: &str) -> Lit {
963        Lit::Float(LitFloat::new(s, self.span))
964    }
965
966    pub fn bool_lit(self, b: bool) -> Lit {
967        Lit::Bool(LitBool {
968            value: b,
969            span: self.span,
970        })
971    }
972
973    pub fn str_lit(self, s: &str) -> Lit {
974        Lit::Str(LitStr::new(s, self.span))
975    }
976
977    pub fn ifte_expr(
978        self,
979        cond: Box<Expr>,
980        then_branch: Block,
981        else_branch: Option<Box<Expr>>,
982    ) -> Box<Expr> {
983        let else_branch = else_branch.map(|e| {
984            // The else branch in libsyntax must be one of these three cases,
985            // otherwise we have to manually add the block around the else expression
986            (
987                Token![else](self.span),
988                match &*e {
989                    Expr::If(..)
990                    | Expr::Block(ExprBlock {
991                        attrs: _,
992                        label: None,
993                        block: _,
994                    }) => e,
995                    _ => mk().block_expr(mk().block(vec![mk().expr_stmt(e)])),
996                },
997            )
998        });
999
1000        Box::new(Expr::If(ExprIf {
1001            attrs: self.attrs,
1002            if_token: Token![if](self.span),
1003            cond,
1004            then_branch,
1005            else_branch,
1006        }))
1007    }
1008
1009    pub fn while_expr<I>(self, cond: Box<Expr>, body: Block, label: Option<I>) -> Box<Expr>
1010    where
1011        I: Make<Ident>,
1012    {
1013        let label = label.map(|l| Label {
1014            name: Lifetime {
1015                ident: l.make(&self),
1016                apostrophe: self.span,
1017            },
1018            colon_token: Token![:](self.span),
1019        });
1020
1021        Box::new(Expr::While(ExprWhile {
1022            attrs: self.attrs,
1023            while_token: Token![while](self.span),
1024            cond,
1025            body,
1026            label,
1027        }))
1028    }
1029
1030    pub fn loop_expr<I>(self, body: Block, label: Option<I>) -> Box<Expr>
1031    where
1032        I: Make<Ident>,
1033    {
1034        let label = label.map(|l| Label {
1035            name: Lifetime {
1036                ident: l.make(&self),
1037                apostrophe: self.span,
1038            },
1039            colon_token: Token![:](self.span),
1040        });
1041
1042        Box::new(Expr::Loop(ExprLoop {
1043            attrs: self.attrs,
1044            loop_token: Token![loop](self.span),
1045            body,
1046            label,
1047        }))
1048    }
1049
1050    pub fn for_expr<I>(self, pat: Pat, expr: Box<Expr>, body: Block, label: Option<I>) -> Box<Expr>
1051    where
1052        I: Make<Ident>,
1053    {
1054        let label = label.map(|l| Label {
1055            name: Lifetime {
1056                ident: l.make(&self),
1057                apostrophe: self.span,
1058            },
1059            colon_token: Token![:](self.span),
1060        });
1061
1062        Box::new(Expr::ForLoop(ExprForLoop {
1063            attrs: self.attrs,
1064            for_token: Token![for](self.span),
1065            in_token: Token![in](self.span),
1066            pat: Box::new(pat),
1067            expr,
1068            body,
1069            label,
1070        }))
1071    }
1072
1073    // Patterns
1074
1075    pub fn ident_pat<I>(self, name: I) -> Pat
1076    where
1077        I: Make<Ident>,
1078    {
1079        let name = name.make(&self);
1080        Pat::Ident(PatIdent {
1081            attrs: self.attrs,
1082            mutability: self.mutbl.to_token(),
1083            by_ref: None,
1084            ident: name,
1085            subpat: None,
1086        })
1087    }
1088
1089    pub fn tuple_pat(self, pats: Vec<Pat>) -> Pat {
1090        Pat::Tuple(PatTuple {
1091            attrs: self.attrs,
1092            paren_token: token::Paren(self.span),
1093            elems: punct(pats),
1094        })
1095    }
1096
1097    pub fn qpath_pat<Pa>(self, qself: Option<QSelf>, path: Pa) -> Box<Pat>
1098    where
1099        Pa: Make<Path>,
1100    {
1101        let path = path.make(&self);
1102        Box::new(Pat::Path(PatPath {
1103            attrs: self.attrs,
1104            qself,
1105            path,
1106        }))
1107    }
1108
1109    pub fn wild_pat(self) -> Pat {
1110        Pat::Wild(PatWild {
1111            attrs: self.attrs,
1112            underscore_token: Token![_](self.span),
1113        })
1114    }
1115
1116    pub fn lit_pat(self, lit: Lit) -> Pat {
1117        Pat::Lit(PatLit {
1118            attrs: self.attrs,
1119            lit,
1120        })
1121    }
1122
1123    pub fn path_pat(self, path: Path, qself: Option<QSelf>) -> Pat {
1124        Pat::Path(PatPath {
1125            attrs: self.attrs,
1126            qself,
1127            path,
1128        })
1129    }
1130
1131    pub fn mac_pat(self, mac: Macro) -> Pat {
1132        Pat::Macro(PatMacro {
1133            attrs: self.attrs,
1134            mac,
1135        })
1136    }
1137
1138    pub fn ident_ref_pat<I>(self, name: I) -> Pat
1139    where
1140        I: Make<Ident>,
1141    {
1142        let name = name.make(&self);
1143        Pat::Ident(PatIdent {
1144            attrs: self.attrs,
1145            by_ref: Some(Token![ref](self.span)),
1146            mutability: self.mutbl.to_token(),
1147            ident: name,
1148            subpat: None,
1149        })
1150    }
1151
1152    pub fn or_pat(self, pats: Vec<Pat>) -> Pat {
1153        Pat::Or(PatOr {
1154            attrs: self.attrs,
1155            leading_vert: None, // Untested
1156            cases: punct(pats),
1157        })
1158    }
1159
1160    // Types
1161
1162    pub fn barefn_ty(self, decl: BareFnTyParts) -> Box<Type> {
1163        let (inputs, variadic, output) = decl;
1164        let abi = self.get_abi_opt();
1165
1166        let barefn = TypeBareFn {
1167            fn_token: Token![fn](self.span),
1168            paren_token: token::Paren(self.span),
1169            unsafety: self.unsafety.to_token(),
1170            abi,
1171            inputs: punct(inputs),
1172            output,
1173            variadic,
1174            lifetimes: None,
1175        };
1176
1177        Box::new(Type::BareFn(barefn))
1178    }
1179
1180    pub fn array_ty(self, ty: Box<Type>, len: Box<Expr>) -> Box<Type> {
1181        Box::new(Type::Array(TypeArray {
1182            bracket_token: token::Bracket(self.span),
1183            semi_token: Token![;](self.span),
1184            elem: ty,
1185            len: *len,
1186        }))
1187    }
1188
1189    pub fn slice_ty(self, ty: Box<Type>) -> Box<Type> {
1190        Box::new(Type::Slice(TypeSlice {
1191            elem: ty,
1192            bracket_token: token::Bracket(self.span),
1193        }))
1194    }
1195
1196    pub fn ptr_ty(self, ty: Box<Type>) -> Box<Type> {
1197        let const_token = if self.mutbl.to_token().is_none() {
1198            Some(Token![const](self.span))
1199        } else {
1200            None
1201        };
1202        Box::new(Type::Ptr(TypePtr {
1203            elem: ty,
1204            mutability: self.mutbl.to_token(),
1205            const_token,
1206            star_token: Token![*](self.span),
1207        }))
1208    }
1209
1210    pub fn ref_ty(self, ty: Box<Type>) -> Box<Type> {
1211        Box::new(Type::Reference(TypeReference {
1212            lifetime: None,
1213            elem: ty,
1214            mutability: self.mutbl.to_token(),
1215            and_token: Token![&](self.span),
1216        }))
1217    }
1218
1219    pub fn ref_lt_ty<L>(self, lt: L, ty: Box<Type>) -> Box<Type>
1220    where
1221        L: Make<Lifetime>,
1222    {
1223        let lt = lt.make(&self);
1224        Box::new(Type::Reference(TypeReference {
1225            and_token: Token![&](self.span),
1226            lifetime: Some(lt),
1227            mutability: self.mutbl.to_token(),
1228            elem: ty,
1229        }))
1230    }
1231
1232    pub fn never_ty(self) -> Box<Type> {
1233        Box::new(Type::Never(TypeNever {
1234            bang_token: Token![!](self.span),
1235        }))
1236    }
1237
1238    pub fn tuple_ty(self, elem_tys: Vec<Box<Type>>) -> Box<Type> {
1239        let elem_tys = elem_tys.into_iter().map(|ty| *ty).collect();
1240        Box::new(Type::Tuple(TypeTuple {
1241            paren_token: token::Paren(self.span),
1242            elems: elem_tys,
1243        }))
1244    }
1245
1246    pub fn path_ty<Pa>(self, path: Pa) -> Box<Type>
1247    where
1248        Pa: Make<Path>,
1249    {
1250        self.qpath_ty(None, path)
1251    }
1252
1253    pub fn qpath_ty<Pa>(self, qself: Option<QSelf>, path: Pa) -> Box<Type>
1254    where
1255        Pa: Make<Path>,
1256    {
1257        let path = path.make(&self);
1258        Box::new(Type::Path(TypePath { qself, path }))
1259    }
1260
1261    pub fn ident_ty<I>(self, name: I) -> Box<Type>
1262    where
1263        I: Make<Ident>,
1264    {
1265        self.path_ty(vec![name])
1266    }
1267
1268    pub fn infer_ty(self) -> Box<Type> {
1269        Box::new(Type::Infer(TypeInfer {
1270            underscore_token: Token![_](self.span),
1271        }))
1272    }
1273
1274    pub fn mac_ty(self, mac: Macro) -> Box<Type> {
1275        Box::new(Type::Macro(TypeMacro { mac }))
1276    }
1277
1278    // Stmts
1279
1280    pub fn local_stmt(self, local: Box<Local>) -> Stmt {
1281        Stmt::Local(*local)
1282    }
1283
1284    pub fn expr_stmt(self, expr: Box<Expr>) -> Stmt {
1285        Stmt::Expr(*expr, None)
1286    }
1287
1288    pub fn semi_stmt(self, expr: Box<Expr>) -> Stmt {
1289        Stmt::Expr(*expr, Some(Token![;](self.span)))
1290    }
1291
1292    pub fn item_stmt(self, item: Box<Item>) -> Stmt {
1293        Stmt::Item(*item)
1294    }
1295
1296    pub fn mac_stmt(self, mac: Macro) -> Stmt {
1297        self.semi_stmt(mk().mac_expr(mac))
1298    }
1299
1300    // Items
1301
1302    pub fn static_item<I>(self, name: I, ty: Box<Type>, init: Box<Expr>) -> Box<Item>
1303    where
1304        I: Make<Ident>,
1305    {
1306        let name = name.make(&self);
1307        Box::new(Item::Static(ItemStatic {
1308            attrs: self.attrs,
1309            vis: self.vis,
1310            mutability: self.mutbl.to_static_mutability(self.span),
1311            ident: name,
1312            static_token: Token![static](self.span),
1313            colon_token: Token![:](self.span),
1314            eq_token: Token![=](self.span),
1315            semi_token: Token![;](self.span),
1316            expr: init,
1317            ty,
1318        }))
1319    }
1320
1321    pub fn const_item<I>(self, name: I, ty: Box<Type>, init: Box<Expr>) -> Box<Item>
1322    where
1323        I: Make<Ident>,
1324    {
1325        let name = name.make(&self);
1326        Box::new(Item::Const(ItemConst {
1327            attrs: self.attrs,
1328            vis: self.vis,
1329            const_token: Token![const](self.span),
1330            generics: self.generics,
1331            colon_token: Token![:](self.span),
1332            eq_token: Token![=](self.span),
1333            semi_token: Token![;](self.span),
1334            ident: name,
1335            ty,
1336            expr: init,
1337        }))
1338    }
1339
1340    pub fn fn_item<S>(self, sig: S, block: Block) -> Box<Item>
1341    where
1342        S: Make<Signature>,
1343    {
1344        let sig = sig.make(&self);
1345        Box::new(Item::Fn(ItemFn {
1346            attrs: self.attrs,
1347            vis: self.vis,
1348            sig,
1349            block: Box::new(block),
1350        }))
1351    }
1352
1353    pub fn variadic_arg(self, name: Option<String>) -> Variadic {
1354        let pat = if let Some(name) = name {
1355            let pat = Box::new(self.clone().ident_pat(name));
1356            Some((pat, Token![:](self.span)))
1357        } else {
1358            None
1359        };
1360
1361        Variadic {
1362            dots: Token![...](self.span),
1363            attrs: self.attrs,
1364            pat,
1365            comma: None,
1366        }
1367    }
1368
1369    pub fn bare_variadic_arg(self) -> BareVariadic {
1370        BareVariadic {
1371            attrs: self.attrs,
1372            name: None,
1373            dots: Token![...](self.span),
1374            comma: None,
1375        }
1376    }
1377
1378    pub fn fn_decl<I>(
1379        self,
1380        name: I,
1381        inputs: Vec<FnArg>,
1382        variadic: Option<Variadic>,
1383        output: ReturnType,
1384    ) -> Box<FnDecl>
1385    where
1386        I: Make<Ident>,
1387    {
1388        let name = name.make(&self);
1389        Box::new((name, inputs, variadic, output))
1390    }
1391
1392    pub fn struct_item<I>(self, name: I, fields: Vec<Field>, is_tuple: bool) -> Box<Item>
1393    where
1394        I: Make<Ident>,
1395    {
1396        let name = name.make(&self);
1397        let fields = if is_tuple {
1398            Fields::Unnamed(FieldsUnnamed {
1399                paren_token: token::Paren(self.span),
1400                unnamed: fields.into_iter().collect(),
1401            })
1402        } else {
1403            Fields::Named(FieldsNamed {
1404                brace_token: token::Brace(self.span),
1405                named: fields.into_iter().collect(),
1406            })
1407        };
1408        Box::new(Item::Struct(ItemStruct {
1409            attrs: self.attrs,
1410            vis: self.vis,
1411            struct_token: Token![struct](self.span),
1412            semi_token: None,
1413            ident: name,
1414            generics: self.generics,
1415            fields,
1416        }))
1417    }
1418
1419    pub fn union_item<I>(self, name: I, fields: Vec<Field>) -> Box<Item>
1420    where
1421        I: Make<Ident>,
1422    {
1423        let name = name.make(&self);
1424        let fields = FieldsNamed {
1425            brace_token: token::Brace(self.span),
1426            named: punct(fields),
1427        };
1428        Box::new(Item::Union(ItemUnion {
1429            attrs: self.attrs,
1430            vis: self.vis,
1431            ident: name,
1432            fields,
1433            union_token: Token![union](self.span),
1434            generics: self.generics,
1435        }))
1436    }
1437
1438    pub fn enum_item<I>(self, name: I, fields: Vec<Variant>) -> Box<Item>
1439    where
1440        I: Make<Ident>,
1441    {
1442        let name = name.make(&self);
1443        Box::new(Item::Enum(ItemEnum {
1444            attrs: self.attrs,
1445            vis: self.vis,
1446            ident: name,
1447            enum_token: Token![enum](self.span),
1448            brace_token: token::Brace(self.span),
1449            variants: punct(fields),
1450            generics: self.generics,
1451        }))
1452    }
1453
1454    pub fn type_item<I>(self, name: I, ty: Box<Type>) -> Box<Item>
1455    where
1456        I: Make<Ident>,
1457    {
1458        let name = name.make(&self);
1459        Box::new(Item::Type(ItemType {
1460            attrs: self.attrs,
1461            vis: self.vis,
1462            ident: name,
1463            generics: self.generics,
1464            type_token: Token![type](self.span),
1465            eq_token: Token![=](self.span),
1466            semi_token: Token![;](self.span),
1467            ty,
1468        }))
1469    }
1470
1471    pub fn mod_item<I>(self, name: I, items: Option<Vec<Item>>) -> Box<Item>
1472    where
1473        I: Make<Ident>,
1474    {
1475        let items = items.map(|i| (token::Brace(self.span), i));
1476        let name = name.make(&self);
1477        Box::new(Item::Mod(ItemMod {
1478            attrs: self.attrs,
1479            vis: self.vis,
1480            unsafety: self.unsafety.to_token(),
1481            ident: name,
1482            mod_token: Token![mod](self.span),
1483            semi: None,
1484            content: items,
1485        }))
1486    }
1487
1488    pub fn mod_(self, items: Vec<Box<Item>>) -> Vec<Item> {
1489        items.into_iter().map(|i| *i).collect()
1490    }
1491
1492    pub fn mac_item(self, mac: Macro) -> Box<Item> {
1493        Box::new(Item::Macro(ItemMacro {
1494            attrs: self.attrs,
1495            semi_token: Some(Token![;](self.span)), // Untested
1496            ident: None,
1497            mac,
1498        }))
1499    }
1500
1501    pub fn variant<I>(self, name: I, fields: Fields) -> Variant
1502    where
1503        I: Make<Ident>,
1504    {
1505        let name = name.make(&self);
1506        Variant {
1507            ident: name,
1508            attrs: self.attrs,
1509            fields,
1510            discriminant: None,
1511        }
1512    }
1513
1514    pub fn unit_variant<I>(self, name: I, disc: Option<Box<Expr>>) -> Variant
1515    where
1516        I: Make<Ident>,
1517    {
1518        let name = name.make(&self);
1519        Variant {
1520            ident: name,
1521            fields: Fields::Unit,
1522            discriminant: disc.map(|e| (Token![=](self.span), *e)),
1523            attrs: self.attrs,
1524        }
1525    }
1526
1527    pub fn impl_item(self, ty: Box<Type>, items: Vec<ImplItem>) -> Box<Item> {
1528        Box::new(Item::Impl(ItemImpl {
1529            attrs: self.attrs,
1530            unsafety: self.unsafety.to_token(),
1531            defaultness: Defaultness::Final.to_token(),
1532            generics: self.generics,
1533            trait_: None, // not a trait implementation, no ! on said trait name
1534            self_ty: ty,
1535            impl_token: Token![impl](self.span),
1536            brace_token: token::Brace(self.span),
1537            items,
1538        }))
1539    }
1540
1541    pub fn extern_crate_item<I>(self, name: I, rename: Option<I>) -> Box<Item>
1542    where
1543        I: Make<Ident>,
1544    {
1545        let name = name.make(&self);
1546        let rename = rename.map(|n| (Token![as](self.span), n.make(&self)));
1547        Box::new(Item::ExternCrate(ItemExternCrate {
1548            attrs: self.attrs,
1549            vis: self.vis,
1550            crate_token: Token![crate](self.span),
1551            extern_token: Token![extern](self.span),
1552            semi_token: Token![;](self.span),
1553            ident: name,
1554            rename,
1555        }))
1556    }
1557
1558    pub fn use_item(self, tree: UseTree) -> Box<Item> {
1559        Box::new(Item::Use(ItemUse {
1560            attrs: self.attrs,
1561            vis: self.vis,
1562            use_token: Token![use](self.span),
1563            leading_colon: None,
1564            semi_token: Token![;](self.span),
1565            tree,
1566        }))
1567    }
1568
1569    // `use <path>;` item
1570    pub fn use_simple_item<Pa, I>(self, path: Pa, rename: Option<I>) -> Box<Item>
1571    where
1572        Pa: Make<Path>,
1573        I: Make<Ident>,
1574    {
1575        let path = path.make(&self);
1576        let rename = rename.map(|n| n.make(&self));
1577
1578        fn split_path(mut p: Path) -> (Path, Option<Ident>) {
1579            if let Some(punct) = p.segments.pop() {
1580                (p, Some(punct.into_value().ident))
1581            } else {
1582                (p, None)
1583            }
1584        }
1585        let leading_colon = path.leading_colon;
1586        let (prefix, ident) = split_path(path);
1587        let ident = ident.expect("use_simple_item called with path `::`");
1588        let tree = if let Some(rename) = rename {
1589            use_tree_with_prefix(
1590                prefix,
1591                UseTree::Rename(UseRename {
1592                    ident,
1593                    as_token: Token![as](self.span),
1594                    rename,
1595                }),
1596            )
1597        } else {
1598            use_tree_with_prefix(prefix, UseTree::Name(UseName { ident }))
1599        };
1600        Box::new(Item::Use(ItemUse {
1601            attrs: self.attrs,
1602            vis: self.vis,
1603            use_token: Token![use](self.span),
1604            leading_colon,
1605            semi_token: Token![;](self.span),
1606            tree,
1607        }))
1608    }
1609
1610    pub fn use_multiple_item<Pa, I, It>(self, path: Pa, inner: It) -> Box<Item>
1611    where
1612        Pa: Make<Path>,
1613        I: Make<Ident>,
1614        It: Iterator<Item = I>,
1615    {
1616        let path = path.make(&self);
1617        let inner_trees = inner
1618            .map(|i| {
1619                UseTree::Name(UseName {
1620                    ident: i.make(&self),
1621                })
1622            })
1623            .collect();
1624        let leading_colon = path.leading_colon;
1625        let tree = use_tree_with_prefix(
1626            path,
1627            UseTree::Group(UseGroup {
1628                brace_token: token::Brace(self.span),
1629                items: inner_trees,
1630            }),
1631        );
1632        Box::new(Item::Use(ItemUse {
1633            attrs: self.attrs,
1634            vis: self.vis,
1635            use_token: Token![use](self.span),
1636            leading_colon,
1637            semi_token: Token![;](self.span),
1638            tree,
1639        }))
1640    }
1641
1642    pub fn use_glob_item<Pa>(self, path: Pa) -> Box<Item>
1643    where
1644        Pa: Make<Path>,
1645    {
1646        let path = path.make(&self);
1647        let leading_colon = path.leading_colon;
1648        let tree = use_tree_with_prefix(
1649            path,
1650            UseTree::Glob(UseGlob {
1651                star_token: Token![*](self.span),
1652            }),
1653        );
1654        Box::new(Item::Use(ItemUse {
1655            attrs: self.attrs,
1656            vis: self.vis,
1657            use_token: Token![use](self.span),
1658            leading_colon,
1659            semi_token: Token![;](self.span),
1660            tree,
1661        }))
1662    }
1663
1664    pub fn foreign_items(self, items: Vec<ForeignItem>) -> Box<Item> {
1665        let abi = self.get_abi();
1666
1667        Box::new(Item::ForeignMod(ItemForeignMod {
1668            attrs: self.attrs,
1669            unsafety: None,
1670            brace_token: token::Brace(self.span),
1671            items,
1672            abi,
1673        }))
1674    }
1675
1676    pub fn get_abi(&self) -> Abi {
1677        Abi {
1678            extern_token: Token![extern](self.span),
1679            name: match self.ext {
1680                Extern::None | Extern::Implicit => None,
1681                Extern::Explicit(ref s) => Some(LitStr::new(s, self.span)),
1682            },
1683        }
1684    }
1685
1686    pub fn get_abi_opt(&self) -> Option<Abi> {
1687        let name: Option<LitStr> = match self.ext {
1688            Extern::None => return None,
1689            Extern::Implicit => None,
1690            Extern::Explicit(ref s) => Some(LitStr::new(s, self.span)),
1691        };
1692        Some(Abi {
1693            extern_token: Token![extern](self.span),
1694            name,
1695        })
1696    }
1697
1698    // Impl Items
1699
1700    pub fn mac_impl_item(self, mac: Macro) -> ImplItem {
1701        ImplItem::Macro(ImplItemMacro {
1702            attrs: self.attrs,
1703            semi_token: None,
1704            mac,
1705        })
1706    }
1707
1708    // Trait Items
1709
1710    pub fn mac_trait_item(self, mac: Macro) -> TraitItem {
1711        TraitItem::Macro(TraitItemMacro {
1712            attrs: self.attrs,
1713            semi_token: None,
1714            mac,
1715        })
1716    }
1717
1718    // Foreign Items
1719
1720    /// [`ForeignItem`] is large (472 bytes), so [`Box`] it.
1721    pub fn fn_foreign_item(self, decl: Box<FnDecl>) -> Box<ForeignItem> {
1722        let sig = Signature {
1723            constness: None,
1724            asyncness: None,
1725            generics: self.generics.clone(),
1726            ..decl.make(&self)
1727        };
1728        Box::new(ForeignItem::Fn(ForeignItemFn {
1729            attrs: self.attrs,
1730            vis: self.vis,
1731            sig,
1732            semi_token: Token![;](self.span),
1733        }))
1734    }
1735
1736    /// [`ForeignItem`] is large (472 bytes), so [`Box`] it.
1737    pub fn static_foreign_item<I>(self, name: I, ty: Box<Type>) -> Box<ForeignItem>
1738    where
1739        I: Make<Ident>,
1740    {
1741        let name = name.make(&self);
1742        Box::new(ForeignItem::Static(ForeignItemStatic {
1743            attrs: self.attrs,
1744            vis: self.vis,
1745            mutability: self.mutbl.to_static_mutability(self.span),
1746            ident: name,
1747            ty,
1748            static_token: Token![static](self.span),
1749            colon_token: Token![:](self.span),
1750            semi_token: Token![;](self.span),
1751        }))
1752    }
1753
1754    /// [`ForeignItem`] is large (472 bytes), so [`Box`] it.
1755    pub fn ty_foreign_item<I>(self, name: I) -> Box<ForeignItem>
1756    where
1757        I: Make<Ident>,
1758    {
1759        let name = name.make(&self);
1760        Box::new(ForeignItem::Type(ForeignItemType {
1761            attrs: self.attrs,
1762            vis: self.vis,
1763            generics: self.generics,
1764            ident: name,
1765            type_token: Token![type](self.span),
1766            semi_token: Token![;](self.span),
1767        }))
1768    }
1769
1770    pub fn mac_foreign_item(self, mac: Macro) -> ForeignItem {
1771        ForeignItem::Macro(ForeignItemMacro {
1772            attrs: self.attrs,
1773            mac,
1774            semi_token: None,
1775        })
1776    }
1777
1778    // struct fields
1779
1780    pub fn struct_field<I>(self, ident: I, ty: Box<Type>) -> Field
1781    where
1782        I: Make<Ident>,
1783    {
1784        let ident = ident.make(&self);
1785        Field {
1786            ident: Some(ident),
1787            vis: self.vis,
1788            mutability: FieldMutability::None,
1789            attrs: self.attrs,
1790            ty: *ty,
1791            colon_token: Some(Token![:](self.span)),
1792        }
1793    }
1794
1795    pub fn enum_field(self, ty: Box<Type>) -> Field {
1796        Field {
1797            ident: None,
1798            vis: self.vis,
1799            mutability: FieldMutability::None,
1800            ty: *ty,
1801            attrs: self.attrs,
1802            colon_token: None,
1803        }
1804    }
1805
1806    // Misc nodes
1807
1808    pub fn unsafe_block(self, stmts: Vec<Stmt>) -> ExprUnsafe {
1809        let blk = Block {
1810            stmts,
1811            brace_token: token::Brace(self.span),
1812        };
1813        ExprUnsafe {
1814            attrs: self.attrs,
1815            unsafe_token: Token![unsafe](self.span),
1816            block: blk,
1817        }
1818    }
1819
1820    pub fn block(self, stmts: Vec<Stmt>) -> Block {
1821        Block {
1822            stmts,
1823            brace_token: token::Brace(self.span),
1824        }
1825    }
1826
1827    pub fn label<L>(self, lbl: L) -> Label
1828    where
1829        L: Make<Label>,
1830    {
1831        lbl.make(&self)
1832    }
1833
1834    pub fn break_expr_value<L>(self, label: Option<L>, value: Option<Box<Expr>>) -> Box<Expr>
1835    where
1836        L: Make<Label>,
1837    {
1838        let label = label.map(|l| l.make(&self).name);
1839        Box::new(Expr::Break(ExprBreak {
1840            attrs: self.attrs,
1841            break_token: Token![break](self.span),
1842            label,
1843            expr: value,
1844        }))
1845    }
1846
1847    pub fn bare_arg<I>(self, ty: Box<Type>, name: Option<I>) -> BareFnArg
1848    where
1849        I: Make<Box<Ident>>,
1850    {
1851        let name = name.map(|n| (*n.make(&self), Token![:](self.span)));
1852        BareFnArg {
1853            attrs: Vec::new(),
1854            name,
1855            ty: *ty,
1856        }
1857    }
1858
1859    pub fn arg(self, ty: Box<Type>, pat: Pat) -> FnArg {
1860        FnArg::Typed(PatType {
1861            attrs: Vec::new(),
1862            ty,
1863            pat: Box::new(pat),
1864            colon_token: Token![:](self.span),
1865        })
1866    }
1867
1868    pub fn self_arg(self, kind: SelfKind) -> FnArg {
1869        let (reference, mutability) = match kind {
1870            SelfKind::Value(mutability) => (None, mutability),
1871            SelfKind::Region(lt, mutability) => {
1872                (Some((Token![&](self.span), Some(lt))), mutability)
1873            }
1874        };
1875        let ty = mk().path_ty("Self");
1876        let attrs = Vec::new();
1877        FnArg::Receiver(Receiver {
1878            attrs,
1879            reference,
1880            mutability: mutability.to_token(),
1881            self_token: Token![self](self.span),
1882            colon_token: None,
1883            ty,
1884        })
1885    }
1886
1887    pub fn ty_param<I>(self, ident: I) -> GenericParam
1888    where
1889        I: Make<Ident>,
1890    {
1891        let ident = ident.make(&self);
1892        GenericParam::Type(TypeParam {
1893            attrs: self.attrs,
1894            ident,
1895            bounds: punct(vec![]),
1896            colon_token: None,
1897            eq_token: None,
1898            default: None,
1899        })
1900    }
1901
1902    pub fn ty<T>(self, kind: Type) -> Type {
1903        kind
1904    }
1905
1906    pub fn lt_param<L>(self, lifetime: L) -> GenericParam
1907    where
1908        L: Make<Lifetime>,
1909    {
1910        let lifetime = lifetime.make(&self);
1911        GenericParam::Lifetime(LifetimeParam {
1912            attrs: self.attrs,
1913            lifetime,
1914            colon_token: None,
1915            bounds: punct(vec![]),
1916        })
1917    }
1918
1919    pub fn lifetime<L: Make<Lifetime>>(self, lt: L) -> Lifetime {
1920        lt.make(&self)
1921    }
1922
1923    pub fn attribute(self, style: AttrStyle, meta: Meta) -> Attribute {
1924        Attribute {
1925            style,
1926            pound_token: Token![#](self.span),
1927            bracket_token: token::Bracket(self.span),
1928            meta,
1929        }
1930    }
1931
1932    /// makes a meta item with just a path
1933    /// # Examples
1934    ///
1935    /// mk().meta_path("C") // ->  `C`
1936    pub fn meta_path<Pa>(self, path: Pa) -> Meta
1937    where
1938        Pa: Make<Path>,
1939    {
1940        let path = path.make(&self);
1941        Meta::Path(path)
1942    }
1943
1944    /// makes a meta item with the given path and some arguments
1945    /// # Examples
1946    ///
1947    /// mk().meta_list("derive", vec!["Clone", "Copy"]) // ->  `derive(Clone, Copy)`
1948    pub fn meta_list<I, N>(self, path: I, args: N) -> Meta
1949    where
1950        I: Make<Path>,
1951        N: Make<TokenStream>,
1952    {
1953        let path = path.make(&self);
1954        let args = args.make(&self);
1955        Meta::List(MetaList {
1956            path,
1957            delimiter: MacroDelimiter::Paren(token::Paren(self.span)),
1958            tokens: args,
1959        })
1960    }
1961
1962    /// makes a meta item with key value argument
1963    /// # Examples
1964    ///
1965    /// mk().meta_namevalue("target_os", "linux") // ->  `target_os = "linux"`
1966    pub fn meta_namevalue<K, V>(self, key: K, value: V) -> Meta
1967    where
1968        K: Make<Path>,
1969        V: Make<Lit>,
1970    {
1971        let key = key.make(&self);
1972        let lit = value.make(&self);
1973        let value = Expr::Lit(ExprLit {
1974            attrs: self.attrs,
1975            lit,
1976        });
1977
1978        Meta::NameValue(MetaNameValue {
1979            path: key,
1980            eq_token: Token![=](self.span),
1981            value,
1982        })
1983    }
1984
1985    pub fn empty_mac<Pa>(self, path: Pa, delim: MacroDelimiter) -> Macro
1986    where
1987        Pa: Make<Path>,
1988    {
1989        let path = path.make(&self);
1990        Macro {
1991            path,
1992            tokens: TokenStream::new(),
1993            bang_token: Token![!](self.span),
1994            delimiter: delim,
1995        }
1996    }
1997
1998    pub fn mac<Ts>(self, func: Path, arguments: Ts, delim: MacroDelimiter) -> Macro
1999    where
2000        Ts: Make<TokenStream>,
2001    {
2002        let tokens = arguments.make(&self);
2003        Macro {
2004            path: func,
2005            tokens,
2006            bang_token: Token![!](self.span),
2007            delimiter: delim,
2008        }
2009    }
2010
2011    /// Create a local variable
2012    pub fn local(self, pat: Pat, ty: Option<Box<Type>>, init: Option<Box<Expr>>) -> Local {
2013        let init = init.map(|x| LocalInit {
2014            eq_token: Token![=](self.span),
2015            expr: x,
2016            diverge: None,
2017        });
2018
2019        let pat = if let Some(ty) = ty {
2020            Pat::Type(PatType {
2021                attrs: vec![],
2022                pat: Box::new(pat),
2023                colon_token: Token![:](self.span),
2024                ty,
2025            })
2026        } else {
2027            pat
2028        };
2029        Local {
2030            attrs: self.attrs,
2031            let_token: Token![let](self.span),
2032            semi_token: Token![;](self.span),
2033            pat,
2034            init,
2035        }
2036    }
2037
2038    pub fn return_expr(self, val: Option<Box<Expr>>) -> Box<Expr> {
2039        Box::new(Expr::Return(ExprReturn {
2040            attrs: self.attrs,
2041            return_token: Token![return](self.span),
2042            expr: val,
2043        }))
2044    }
2045
2046    pub fn continue_expr<I>(self, label: Option<I>) -> Box<Expr>
2047    where
2048        I: Make<Ident>,
2049    {
2050        let label = label.map(|l| Lifetime {
2051            ident: l.make(&self),
2052            apostrophe: self.span,
2053        });
2054
2055        Box::new(Expr::Continue(ExprContinue {
2056            attrs: self.attrs,
2057            continue_token: Token![continue](self.span),
2058            label,
2059        }))
2060    }
2061
2062    pub fn break_expr<I>(self, label: Option<I>) -> Box<Expr>
2063    where
2064        I: Make<Ident>,
2065    {
2066        let label = label.map(|l| Lifetime {
2067            ident: l.make(&self),
2068            apostrophe: self.span,
2069        });
2070
2071        Box::new(Expr::Break(ExprBreak {
2072            attrs: self.attrs,
2073            break_token: Token![break](self.span),
2074            label,
2075            expr: None,
2076        }))
2077    }
2078
2079    pub fn closure_expr(
2080        self,
2081        capture: CaptureBy,
2082        mov: Movability,
2083        decl: FnDecl,
2084        body: Box<Expr>,
2085    ) -> Box<Expr> {
2086        let (_name, inputs, _variadic, output) = decl;
2087        let inputs = inputs
2088            .into_iter()
2089            .map(|e| match e {
2090                FnArg::Receiver(_s) => panic!("found 'self' in closure arguments"),
2091                FnArg::Typed(PatType { pat, .. }) => *pat,
2092            })
2093            .collect();
2094        let capture = match capture {
2095            CaptureBy::Ref => None,
2096            CaptureBy::Value => Some(Default::default()),
2097        };
2098        Box::new(Expr::Closure(ExprClosure {
2099            attrs: self.attrs,
2100            lifetimes: None,
2101            constness: None,
2102            or1_token: Token![|](self.span),
2103            or2_token: Token![|](self.span),
2104            capture,
2105            asyncness: IsAsync::NotAsync.to_token(),
2106            movability: mov.to_token(),
2107            body,
2108            inputs,
2109            output,
2110        }))
2111    }
2112}
2113
2114pub fn mk() -> Builder {
2115    Builder::new()
2116}
2117
2118/// Detect a cast that would create a syntax error when it was the left
2119/// argument to a less-than operator. This is a work-around for an upstream
2120/// libsyntax bug.
2121fn has_rightmost_cast(expr: &Expr) -> bool {
2122    match expr {
2123        Expr::Cast(..) => true,
2124        Expr::Unary(ExprUnary {
2125            attrs: _,
2126            op: _,
2127            ref expr,
2128        }) => has_rightmost_cast(expr),
2129        Expr::Binary(ExprBinary {
2130            attrs: _,
2131            left: _,
2132            op: _,
2133            ref right,
2134        }) => has_rightmost_cast(right),
2135        _ => false,
2136    }
2137}
2138
2139fn expr_precedence(e: &Expr) -> u8 {
2140    match e {
2141        Expr::Path(_ep) => 18,
2142        Expr::MethodCall(_emc) => 17,
2143        Expr::Field(_ef) => 16,
2144        Expr::Call(_) | Expr::Index(_) => 15,
2145        Expr::Try(_et) => 14,
2146        Expr::Unary(_) | Expr::Reference(_) => 13,
2147        Expr::Cast(_ec) => 12,
2148        Expr::Binary(eb) => 2 + binop_precedence(&eb.op),
2149        Expr::Assign(_) => 1,
2150        Expr::Return(_) | Expr::Closure(_) => 0,
2151        _ => 255,
2152    }
2153}
2154
2155/// See <https://doc.rust-lang.org/reference/expressions.html>
2156fn binop_precedence(b: &BinOp) -> u8 {
2157    match b {
2158        BinOp::Add(_) => 8,
2159        BinOp::Sub(_) => 8,
2160        BinOp::Mul(_) => 9,
2161        BinOp::Div(_) => 9,
2162        BinOp::Rem(_) => 9,
2163        BinOp::And(_) => 2,
2164        BinOp::Or(_) => 1,
2165        BinOp::BitXor(_) => 5,
2166        BinOp::BitAnd(_) => 6,
2167        BinOp::BitOr(_) => 4,
2168        BinOp::Shl(_) => 7,
2169        BinOp::Shr(_) => 7,
2170        BinOp::Eq(_) => 3,
2171        BinOp::Lt(_) => 3,
2172        BinOp::Le(_) => 3,
2173        BinOp::Ne(_) => 3,
2174        BinOp::Ge(_) => 3,
2175        BinOp::Gt(_) => 3,
2176        BinOp::AddAssign(_) => 0,
2177        BinOp::SubAssign(_) => 0,
2178        BinOp::MulAssign(_) => 0,
2179        BinOp::DivAssign(_) => 0,
2180        BinOp::RemAssign(_) => 0,
2181        BinOp::BitXorAssign(_) => 0,
2182        BinOp::BitAndAssign(_) => 0,
2183        BinOp::BitOrAssign(_) => 0,
2184        BinOp::ShlAssign(_) => 0,
2185        BinOp::ShrAssign(_) => 0,
2186        _ => panic!("mising binop"),
2187    }
2188}
2189
2190/// Wrap an expression in parentheses
2191fn parenthesize_mut(e: &mut Box<Expr>) {
2192    let mut temp = mk().tuple_expr(Vec::new());
2193    std::mem::swap(e, &mut temp);
2194    *e = Box::new(Expr::Paren(ExprParen {
2195        attrs: vec![],
2196        paren_token: Default::default(),
2197        expr: temp,
2198    }))
2199}
2200
2201/// Wrap an expression's subexpressions in an explicit ExprParen if the
2202/// pretty-printed form of the expression would otherwise reparse differently
2203fn parenthesize_if_necessary(mut outer: Expr) -> Expr {
2204    // If outer operation has higher precedence, parenthesize inner operation
2205    let outer_precedence = expr_precedence(&outer);
2206    let parenthesize_if_gte = |inner: &mut Box<Expr>| {
2207        if expr_precedence(&*inner) <= outer_precedence {
2208            parenthesize_mut(inner);
2209        }
2210    };
2211    let parenthesize_if_gt = |inner: &mut Box<Expr>| {
2212        if expr_precedence(&*inner) < outer_precedence {
2213            parenthesize_mut(inner);
2214        }
2215    };
2216    match outer {
2217        Expr::Field(ref mut ef) => {
2218            if let Expr::Index(_) = *ef.base {
2219                /* we do not need to parenthesize the indexing in a[b].c */
2220            } else {
2221                /*if let Expr::Unary(_) = *ef.base {
2222                    parenthesize_mut(&mut ef.base);
2223                } else { */
2224                parenthesize_if_gt(&mut ef.base);
2225            }
2226        }
2227        Expr::MethodCall(ref mut emc) => {
2228            parenthesize_if_gt(&mut emc.receiver);
2229        }
2230        Expr::Call(ref mut ec) => {
2231            parenthesize_if_gt(&mut ec.func);
2232        }
2233        Expr::Cast(ref mut ec) => {
2234            if let Expr::If(_) = *ec.expr {
2235                parenthesize_mut(&mut ec.expr);
2236            } else {
2237                parenthesize_if_gt(&mut ec.expr);
2238            }
2239        }
2240        Expr::Unary(ref mut eu) => {
2241            parenthesize_if_gt(&mut eu.expr);
2242        }
2243        Expr::Reference(ref mut er) => {
2244            parenthesize_if_gt(&mut er.expr);
2245        }
2246        Expr::Binary(ref mut eb) => {
2247            parenthesize_if_gt(&mut eb.left);
2248            // Because binops associate right, parenthesize same-precedence RHS
2249            // (e.g. `5 - (6 - 7)`).
2250            parenthesize_if_gte(&mut eb.right);
2251        }
2252        Expr::Index(ref mut ei) => {
2253            parenthesize_if_gt(&mut ei.expr);
2254        }
2255        _ => (),
2256    };
2257    outer
2258}