Skip to main content

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