]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/build.rs
rand: Use fill() instead of read()
[rust.git] / src / libsyntax / ext / build.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use abi::AbiSet;
12 use ast::{P, Ident};
13 use ast;
14 use ast_util;
15 use codemap::{Span, respan, DUMMY_SP};
16 use ext::base::ExtCtxt;
17 use ext::quote::rt::*;
18 use fold::Folder;
19 use owned_slice::OwnedSlice;
20 use parse::token::special_idents;
21 use parse::token;
22
23 pub struct Field {
24     ident: ast::Ident,
25     ex: @ast::Expr
26 }
27
28 // Transitional reexports so qquote can find the paths it is looking for
29 mod syntax {
30     pub use ext;
31     pub use parse;
32 }
33
34 pub trait AstBuilder {
35     // paths
36     fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
37     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path;
38     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
39     fn path_all(&self, sp: Span,
40                 global: bool,
41                 idents: Vec<ast::Ident> ,
42                 lifetimes: Vec<ast::Lifetime>,
43                 types: Vec<P<ast::Ty>> )
44         -> ast::Path;
45
46     // types
47     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
48
49     fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty>;
50     fn ty_path(&self, ast::Path, Option<OwnedSlice<ast::TyParamBound>>) -> P<ast::Ty>;
51     fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
52
53     fn ty_rptr(&self, span: Span,
54                ty: P<ast::Ty>,
55                lifetime: Option<ast::Lifetime>,
56                mutbl: ast::Mutability) -> P<ast::Ty>;
57     fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty>;
58
59     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
60     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
61     fn ty_nil(&self) -> P<ast::Ty>;
62
63     fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
64     fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> ;
65     fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField;
66     fn strip_bounds(&self, bounds: &Generics) -> Generics;
67
68     fn typaram(&self,
69                id: ast::Ident,
70                bounds: OwnedSlice<ast::TyParamBound>,
71                default: Option<P<ast::Ty>>) -> ast::TyParam;
72
73     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
74     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
75     fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
76
77     // statements
78     fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt;
79     fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt;
80     fn stmt_let_typed(&self,
81                       sp: Span,
82                       mutbl: bool,
83                       ident: ast::Ident,
84                       typ: P<ast::Ty>,
85                       ex: @ast::Expr)
86                       -> @ast::Stmt;
87
88     // blocks
89     fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@ast::Expr>) -> P<ast::Block>;
90     fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block>;
91     fn block_all(&self, span: Span,
92                  view_items: Vec<ast::ViewItem> ,
93                  stmts: Vec<@ast::Stmt> ,
94                  expr: Option<@ast::Expr>) -> P<ast::Block>;
95
96     // expressions
97     fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr;
98     fn expr_path(&self, path: ast::Path) -> @ast::Expr;
99     fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr;
100
101     fn expr_self(&self, span: Span) -> @ast::Expr;
102     fn expr_binary(&self, sp: Span, op: ast::BinOp,
103                    lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr;
104     fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
105     fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr;
106
107     fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
108     fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
109     fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr;
110     fn expr_field_access(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr;
111     fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr;
112     fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr;
113     fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
114                         args: Vec<@ast::Expr> ) -> @ast::Expr;
115     fn expr_method_call(&self, span: Span,
116                         expr: @ast::Expr, ident: ast::Ident,
117                         args: Vec<@ast::Expr> ) -> @ast::Expr;
118     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr;
119     fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr;
120
121     fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field;
122     fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr;
123     fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr;
124
125     fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr;
126
127     fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr;
128     fn expr_int(&self, sp: Span, i: int) -> @ast::Expr;
129     fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr;
130     fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr;
131
132     fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr;
133     fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr;
134     fn expr_vec_ng(&self, sp: Span) -> @ast::Expr;
135     fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr;
136     fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr;
137     fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr;
138
139     fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr;
140     fn expr_none(&self, sp: Span) -> @ast::Expr;
141
142     fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr;
143     fn expr_unreachable(&self, span: Span) -> @ast::Expr;
144
145     fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat;
146     fn pat_wild(&self, span: Span) -> @ast::Pat;
147     fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat;
148     fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat;
149
150     fn pat_ident_binding_mode(&self,
151                               span: Span,
152                               ident: ast::Ident,
153                               bm: ast::BindingMode) -> @ast::Pat;
154     fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat;
155     fn pat_struct(&self, span: Span,
156                   path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat;
157
158     fn arm(&self, span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm;
159     fn arm_unreachable(&self, span: Span) -> ast::Arm;
160
161     fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @ast::Expr;
162     fn expr_if(&self, span: Span,
163                cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr;
164
165     fn lambda_fn_decl(&self, span: Span,
166                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr;
167
168     fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr;
169     fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr;
170     fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr;
171
172     fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , blk: @ast::Expr) -> @ast::Expr;
173     fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr;
174     fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr;
175
176     fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident> , blk: Vec<@ast::Stmt> ) -> @ast::Expr;
177     fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr;
178     fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr;
179
180     // items
181     fn item(&self, span: Span,
182             name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item;
183
184     fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
185     // FIXME unused self
186     fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl>;
187
188     fn item_fn_poly(&self,
189                     span: Span,
190                     name: Ident,
191                     inputs: Vec<ast::Arg> ,
192                     output: P<ast::Ty>,
193                     generics: Generics,
194                     body: P<ast::Block>) -> @ast::Item;
195     fn item_fn(&self,
196                span: Span,
197                name: Ident,
198                inputs: Vec<ast::Arg> ,
199                output: P<ast::Ty>,
200                body: P<ast::Block>) -> @ast::Item;
201
202     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant;
203     fn item_enum_poly(&self,
204                       span: Span,
205                       name: Ident,
206                       enum_definition: ast::EnumDef,
207                       generics: Generics) -> @ast::Item;
208     fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> @ast::Item;
209
210     fn item_struct_poly(&self,
211                         span: Span,
212                         name: Ident,
213                         struct_def: ast::StructDef,
214                         generics: Generics) -> @ast::Item;
215     fn item_struct(&self, span: Span, name: Ident, struct_def: ast::StructDef) -> @ast::Item;
216
217     fn item_mod(&self, span: Span,
218                 name: Ident, attrs: Vec<ast::Attribute> ,
219                 vi: Vec<ast::ViewItem> , items: Vec<@ast::Item> ) -> @ast::Item;
220
221     fn item_ty_poly(&self,
222                     span: Span,
223                     name: Ident,
224                     ty: P<ast::Ty>,
225                     generics: Generics) -> @ast::Item;
226     fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item;
227
228     fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
229
230     fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem;
231     fn meta_list(&self,
232                  sp: Span,
233                  name: InternedString,
234                  mis: Vec<@ast::MetaItem> )
235                  -> @ast::MetaItem;
236     fn meta_name_value(&self,
237                        sp: Span,
238                        name: InternedString,
239                        value: ast::Lit_)
240                        -> @ast::MetaItem;
241
242     fn view_use(&self, sp: Span,
243                 vis: ast::Visibility, vp: Vec<@ast::ViewPath> ) -> ast::ViewItem;
244     fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
245     fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
246                         ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
247     fn view_use_list(&self, sp: Span, vis: ast::Visibility,
248                      path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem;
249     fn view_use_glob(&self, sp: Span,
250                      vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem;
251 }
252
253 impl<'a> AstBuilder for ExtCtxt<'a> {
254     fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
255         self.path_all(span, false, strs, Vec::new(), Vec::new())
256     }
257     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
258         self.path(span, vec!(id))
259     }
260     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
261         self.path_all(span, true, strs, Vec::new(), Vec::new())
262     }
263     fn path_all(&self,
264                 sp: Span,
265                 global: bool,
266                 mut idents: Vec<ast::Ident> ,
267                 lifetimes: Vec<ast::Lifetime>,
268                 types: Vec<P<ast::Ty>> )
269                 -> ast::Path {
270         let last_identifier = idents.pop().unwrap();
271         let mut segments: Vec<ast::PathSegment> = idents.move_iter()
272                                                       .map(|ident| {
273             ast::PathSegment {
274                 identifier: ident,
275                 lifetimes: Vec::new(),
276                 types: OwnedSlice::empty(),
277             }
278         }).collect();
279         segments.push(ast::PathSegment {
280             identifier: last_identifier,
281             lifetimes: lifetimes,
282             types: OwnedSlice::from_vec(types),
283         });
284         ast::Path {
285             span: sp,
286             global: global,
287             segments: segments,
288         }
289     }
290
291     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
292         ast::MutTy {
293             ty: ty,
294             mutbl: mutbl
295         }
296     }
297
298     fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty> {
299         P(ast::Ty {
300             id: ast::DUMMY_NODE_ID,
301             span: span,
302             node: ty
303         })
304     }
305
306     fn ty_path(&self, path: ast::Path, bounds: Option<OwnedSlice<ast::TyParamBound>>)
307               -> P<ast::Ty> {
308         self.ty(path.span,
309                 ast::TyPath(path, bounds, ast::DUMMY_NODE_ID))
310     }
311
312     // Might need to take bounds as an argument in the future, if you ever want
313     // to generate a bounded existential trait type.
314     fn ty_ident(&self, span: Span, ident: ast::Ident)
315         -> P<ast::Ty> {
316         self.ty_path(self.path_ident(span, ident), None)
317     }
318
319     fn ty_rptr(&self,
320                span: Span,
321                ty: P<ast::Ty>,
322                lifetime: Option<ast::Lifetime>,
323                mutbl: ast::Mutability)
324         -> P<ast::Ty> {
325         self.ty(span,
326                 ast::TyRptr(lifetime, self.ty_mt(ty, mutbl)))
327     }
328
329     fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
330         self.ty(span, ast::TyUniq(ty))
331     }
332
333     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
334         self.ty_path(
335             self.path_all(DUMMY_SP,
336                           true,
337                           vec!(
338                               self.ident_of("std"),
339                               self.ident_of("option"),
340                               self.ident_of("Option")
341                           ),
342                           Vec::new(),
343                           vec!( ty )), None)
344     }
345
346     fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField {
347         ast::TypeField {
348             ident: name,
349             mt: ast::MutTy { ty: ty, mutbl: ast::MutImmutable },
350             span: span,
351         }
352     }
353
354     fn ty_infer(&self, span: Span) -> P<ast::Ty> {
355         self.ty(span, ast::TyInfer)
356     }
357
358     fn ty_nil(&self) -> P<ast::Ty> {
359         P(ast::Ty {
360             id: ast::DUMMY_NODE_ID,
361             node: ast::TyNil,
362             span: DUMMY_SP,
363         })
364     }
365
366     fn typaram(&self,
367                id: ast::Ident,
368                bounds: OwnedSlice<ast::TyParamBound>,
369                default: Option<P<ast::Ty>>) -> ast::TyParam {
370         ast::TyParam {
371             ident: id,
372             id: ast::DUMMY_NODE_ID,
373             bounds: bounds,
374             default: default
375         }
376     }
377
378     // these are strange, and probably shouldn't be used outside of
379     // pipes. Specifically, the global version possible generates
380     // incorrect code.
381     fn ty_vars(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
382         ty_params.iter().map(|p| self.ty_ident(DUMMY_SP, p.ident)).collect()
383     }
384
385     fn ty_vars_global(&self, ty_params: &OwnedSlice<ast::TyParam>) -> Vec<P<ast::Ty>> {
386         ty_params.iter().map(|p| self.ty_path(
387                 self.path_global(DUMMY_SP, vec!(p.ident)), None)).collect()
388     }
389
390     fn strip_bounds(&self, generics: &Generics) -> Generics {
391         let new_params = generics.ty_params.map(|ty_param| {
392             ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
393         });
394         Generics {
395             ty_params: new_params,
396             .. (*generics).clone()
397         }
398     }
399
400     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
401         ast::TraitRef {
402             path: path,
403             ref_id: ast::DUMMY_NODE_ID
404         }
405     }
406
407     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
408         ast::TraitTyParamBound(self.trait_ref(path))
409     }
410
411     fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
412         ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
413     }
414
415     fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt {
416         @respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))
417     }
418
419     fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt {
420         let pat = if mutbl {
421             self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
422         } else {
423             self.pat_ident(sp, ident)
424         };
425         let local = @ast::Local {
426             ty: self.ty_infer(sp),
427             pat: pat,
428             init: Some(ex),
429             id: ast::DUMMY_NODE_ID,
430             span: sp,
431         };
432         let decl = respan(sp, ast::DeclLocal(local));
433         @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))
434     }
435
436     fn stmt_let_typed(&self,
437                       sp: Span,
438                       mutbl: bool,
439                       ident: ast::Ident,
440                       typ: P<ast::Ty>,
441                       ex: @ast::Expr)
442                       -> @ast::Stmt {
443         let pat = if mutbl {
444             self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
445         } else {
446             self.pat_ident(sp, ident)
447         };
448         let local = @ast::Local {
449             ty: typ,
450             pat: pat,
451             init: Some(ex),
452             id: ast::DUMMY_NODE_ID,
453             span: sp,
454         };
455         let decl = respan(sp, ast::DeclLocal(local));
456         @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))
457     }
458
459     fn block(&self, span: Span, stmts: Vec<@ast::Stmt> , expr: Option<@Expr>) -> P<ast::Block> {
460         self.block_all(span, Vec::new(), stmts, expr)
461     }
462
463     fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block> {
464         self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
465     }
466     fn block_all(&self,
467                  span: Span,
468                  view_items: Vec<ast::ViewItem> ,
469                  stmts: Vec<@ast::Stmt> ,
470                  expr: Option<@ast::Expr>) -> P<ast::Block> {
471             P(ast::Block {
472                view_items: view_items,
473                stmts: stmts,
474                expr: expr,
475                id: ast::DUMMY_NODE_ID,
476                rules: ast::DefaultBlock,
477                span: span,
478             })
479     }
480
481     fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr {
482         @ast::Expr {
483             id: ast::DUMMY_NODE_ID,
484             node: node,
485             span: span,
486         }
487     }
488
489     fn expr_path(&self, path: ast::Path) -> @ast::Expr {
490         self.expr(path.span, ast::ExprPath(path))
491     }
492
493     fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr {
494         self.expr_path(self.path_ident(span, id))
495     }
496     fn expr_self(&self, span: Span) -> @ast::Expr {
497         self.expr_ident(span, special_idents::self_)
498     }
499
500     fn expr_binary(&self, sp: Span, op: ast::BinOp,
501                    lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr {
502         self.expr(sp, ast::ExprBinary(op, lhs, rhs))
503     }
504
505     fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
506         self.expr_unary(sp, ast::UnDeref, e)
507     }
508     fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr {
509         self.expr(sp, ast::ExprUnary(op, e))
510     }
511
512     fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
513         self.expr_unary(sp, ast::UnBox, e)
514     }
515
516     fn expr_field_access(&self, sp: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr {
517         self.expr(sp, ast::ExprField(expr, ident, Vec::new()))
518     }
519     fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
520         self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
521     }
522     fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
523         self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e))
524     }
525
526     fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr {
527         self.expr(span, ast::ExprCall(expr, args))
528     }
529     fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<@ast::Expr> ) -> @ast::Expr {
530         self.expr(span, ast::ExprCall(self.expr_ident(span, id), args))
531     }
532     fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
533                       args: Vec<@ast::Expr> ) -> @ast::Expr {
534         let pathexpr = self.expr_path(self.path_global(sp, fn_path));
535         self.expr_call(sp, pathexpr, args)
536     }
537     fn expr_method_call(&self, span: Span,
538                         expr: @ast::Expr,
539                         ident: ast::Ident,
540                         mut args: Vec<@ast::Expr> ) -> @ast::Expr {
541         args.unshift(expr);
542         self.expr(span, ast::ExprMethodCall(ident, Vec::new(), args))
543     }
544     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
545         self.expr(b.span, ast::ExprBlock(b))
546     }
547     fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field {
548         ast::Field { ident: respan(span, name), expr: e, span: span }
549     }
550     fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field> ) -> @ast::Expr {
551         self.expr(span, ast::ExprStruct(path, fields, None))
552     }
553     fn expr_struct_ident(&self, span: Span,
554                          id: ast::Ident, fields: Vec<ast::Field> ) -> @ast::Expr {
555         self.expr_struct(span, self.path_ident(span, id), fields)
556     }
557
558     fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr {
559         self.expr(sp, ast::ExprLit(@respan(sp, lit)))
560     }
561     fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr {
562         self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
563     }
564     fn expr_int(&self, sp: Span, i: int) -> @ast::Expr {
565         self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
566     }
567     fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr {
568         self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
569     }
570     fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr {
571         self.expr_lit(sp, ast::LitBool(value))
572     }
573
574     fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr {
575         self.expr(sp, ast::ExprVstore(expr, vst))
576     }
577     fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr {
578         self.expr(sp, ast::ExprVec(exprs, ast::MutImmutable))
579     }
580     fn expr_vec_ng(&self, sp: Span) -> @ast::Expr {
581         self.expr_call_global(sp,
582                               vec!(self.ident_of("std"),
583                                    self.ident_of("vec"),
584                                    self.ident_of("Vec"),
585                                    self.ident_of("new")),
586                               Vec::new())
587     }
588     fn expr_vec_slice(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr {
589         self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::ExprVstoreSlice)
590     }
591     fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr {
592         self.expr_lit(sp, ast::LitStr(s, ast::CookedStr))
593     }
594     fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr {
595         self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq)
596     }
597
598
599     fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr {
600         self.expr(sp, ast::ExprCast(expr, ty))
601     }
602
603
604     fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr {
605         let some = vec!(
606             self.ident_of("std"),
607             self.ident_of("option"),
608             self.ident_of("Some"));
609         self.expr_call_global(sp, some, vec!(expr))
610     }
611
612     fn expr_none(&self, sp: Span) -> @ast::Expr {
613         let none = self.path_global(sp, vec!(
614             self.ident_of("std"),
615             self.ident_of("option"),
616             self.ident_of("None")));
617         self.expr_path(none)
618     }
619
620     fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr {
621         let loc = self.codemap().lookup_char_pos(span.lo);
622         self.expr_call_global(
623             span,
624             vec!(
625                 self.ident_of("std"),
626                 self.ident_of("rt"),
627                 self.ident_of("begin_unwind")),
628             vec!(
629                 self.expr_str(span, msg),
630                 self.expr_str(span,
631                               token::intern_and_get_ident(loc.file.deref().name)),
632                 self.expr_uint(span, loc.line)))
633     }
634
635     fn expr_unreachable(&self, span: Span) -> @ast::Expr {
636         self.expr_fail(span,
637                        InternedString::new(
638                            "internal error: entered unreachable code"))
639     }
640
641
642     fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat {
643         @ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
644     }
645     fn pat_wild(&self, span: Span) -> @ast::Pat {
646         self.pat(span, ast::PatWild)
647     }
648     fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat {
649         self.pat(span, ast::PatLit(expr))
650     }
651     fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat {
652         self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable))
653     }
654
655     fn pat_ident_binding_mode(&self,
656                               span: Span,
657                               ident: ast::Ident,
658                               bm: ast::BindingMode) -> @ast::Pat {
659         let path = self.path_ident(span, ident);
660         let pat = ast::PatIdent(bm, path, None);
661         self.pat(span, pat)
662     }
663     fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat {
664         let pat = ast::PatEnum(path, Some(subpats));
665         self.pat(span, pat)
666     }
667     fn pat_struct(&self, span: Span,
668                   path: ast::Path, field_pats: Vec<ast::FieldPat> ) -> @ast::Pat {
669         let pat = ast::PatStruct(path, field_pats, false);
670         self.pat(span, pat)
671     }
672
673     fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm {
674         ast::Arm {
675             pats: pats,
676             guard: None,
677             body: expr
678         }
679     }
680
681     fn arm_unreachable(&self, span: Span) -> ast::Arm {
682         self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span))
683     }
684
685     fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @Expr {
686         self.expr(span, ast::ExprMatch(arg, arms))
687     }
688
689     fn expr_if(&self, span: Span,
690                cond: @ast::Expr, then: @ast::Expr, els: Option<@ast::Expr>) -> @ast::Expr {
691         let els = els.map(|x| self.expr_block(self.block_expr(x)));
692         self.expr(span, ast::ExprIf(cond, self.block_expr(then), els))
693     }
694
695     fn lambda_fn_decl(&self, span: Span,
696                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr {
697         self.expr(span, ast::ExprFnBlock(fn_decl, blk))
698     }
699     fn lambda(&self, span: Span, ids: Vec<ast::Ident> , blk: P<ast::Block>) -> @ast::Expr {
700         let fn_decl = self.fn_decl(
701             ids.map(|id| self.arg(span, *id, self.ty_infer(span))),
702             self.ty_infer(span));
703
704         self.expr(span, ast::ExprFnBlock(fn_decl, blk))
705     }
706     fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr {
707         self.lambda(span, Vec::new(), blk)
708     }
709
710     fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr {
711         self.lambda(span, vec!(ident), blk)
712     }
713
714     fn lambda_expr(&self, span: Span, ids: Vec<ast::Ident> , expr: @ast::Expr) -> @ast::Expr {
715         self.lambda(span, ids, self.block_expr(expr))
716     }
717     fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr {
718         self.lambda0(span, self.block_expr(expr))
719     }
720     fn lambda_expr_1(&self, span: Span, expr: @ast::Expr, ident: ast::Ident) -> @ast::Expr {
721         self.lambda1(span, self.block_expr(expr), ident)
722     }
723
724     fn lambda_stmts(&self,
725                     span: Span,
726                     ids: Vec<ast::Ident>,
727                     stmts: Vec<@ast::Stmt>)
728                     -> @ast::Expr {
729         self.lambda(span, ids, self.block(span, stmts, None))
730     }
731     fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr {
732         self.lambda0(span, self.block(span, stmts, None))
733     }
734     fn lambda_stmts_1(&self, span: Span, stmts: Vec<@ast::Stmt> , ident: ast::Ident) -> @ast::Expr {
735         self.lambda1(span, self.block(span, stmts, None), ident)
736     }
737
738     fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
739         let arg_pat = self.pat_ident(span, ident);
740         ast::Arg {
741             ty: ty,
742             pat: arg_pat,
743             id: ast::DUMMY_NODE_ID
744         }
745     }
746
747     // FIXME unused self
748     fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl> {
749         P(ast::FnDecl {
750             inputs: inputs,
751             output: output,
752             cf: ast::Return,
753             variadic: false
754         })
755     }
756
757     fn item(&self, span: Span,
758             name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item {
759         // FIXME: Would be nice if our generated code didn't violate
760         // Rust coding conventions
761         @ast::Item { ident: name,
762                     attrs: attrs,
763                     id: ast::DUMMY_NODE_ID,
764                     node: node,
765                     vis: ast::Inherited,
766                     span: span }
767     }
768
769     fn item_fn_poly(&self,
770                     span: Span,
771                     name: Ident,
772                     inputs: Vec<ast::Arg> ,
773                     output: P<ast::Ty>,
774                     generics: Generics,
775                     body: P<ast::Block>) -> @ast::Item {
776         self.item(span,
777                   name,
778                   Vec::new(),
779                   ast::ItemFn(self.fn_decl(inputs, output),
780                               ast::ImpureFn,
781                               AbiSet::Rust(),
782                               generics,
783                               body))
784     }
785
786     fn item_fn(&self,
787                span: Span,
788                name: Ident,
789                inputs: Vec<ast::Arg> ,
790                output: P<ast::Ty>,
791                body: P<ast::Block>
792               ) -> @ast::Item {
793         self.item_fn_poly(
794             span,
795             name,
796             inputs,
797             output,
798             ast_util::empty_generics(),
799             body)
800     }
801
802     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
803         let args = tys.move_iter().map(|ty| {
804             ast::VariantArg { ty: ty, id: ast::DUMMY_NODE_ID }
805         }).collect();
806
807         respan(span,
808                ast::Variant_ {
809                    name: name,
810                    attrs: Vec::new(),
811                    kind: ast::TupleVariantKind(args),
812                    id: ast::DUMMY_NODE_ID,
813                    disr_expr: None,
814                    vis: ast::Public
815                })
816     }
817
818     fn item_enum_poly(&self, span: Span, name: Ident,
819                       enum_definition: ast::EnumDef,
820                       generics: Generics) -> @ast::Item {
821         self.item(span, name, Vec::new(), ast::ItemEnum(enum_definition, generics))
822     }
823
824     fn item_enum(&self, span: Span, name: Ident,
825                  enum_definition: ast::EnumDef) -> @ast::Item {
826         self.item_enum_poly(span, name, enum_definition,
827                             ast_util::empty_generics())
828     }
829
830     fn item_struct(&self, span: Span, name: Ident,
831                    struct_def: ast::StructDef) -> @ast::Item {
832         self.item_struct_poly(
833             span,
834             name,
835             struct_def,
836             ast_util::empty_generics()
837         )
838     }
839
840     fn item_struct_poly(&self, span: Span, name: Ident,
841         struct_def: ast::StructDef, generics: Generics) -> @ast::Item {
842         self.item(span, name, Vec::new(), ast::ItemStruct(@struct_def, generics))
843     }
844
845     fn item_mod(&self, span: Span, name: Ident,
846                 attrs: Vec<ast::Attribute> ,
847                 vi: Vec<ast::ViewItem> ,
848                 items: Vec<@ast::Item> ) -> @ast::Item {
849         self.item(
850             span,
851             name,
852             attrs,
853             ast::ItemMod(ast::Mod {
854                 view_items: vi,
855                 items: items,
856             })
857         )
858     }
859
860     fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
861                     generics: Generics) -> @ast::Item {
862         self.item(span, name, Vec::new(), ast::ItemTy(ty, generics))
863     }
864
865     fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item {
866         self.item_ty_poly(span, name, ty, ast_util::empty_generics())
867     }
868
869     fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute {
870         respan(sp, ast::Attribute_ {
871             style: ast::AttrOuter,
872             value: mi,
873             is_sugared_doc: false,
874         })
875     }
876
877     fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem {
878         @respan(sp, ast::MetaWord(w))
879     }
880     fn meta_list(&self,
881                  sp: Span,
882                  name: InternedString,
883                  mis: Vec<@ast::MetaItem> )
884                  -> @ast::MetaItem {
885         @respan(sp, ast::MetaList(name, mis))
886     }
887     fn meta_name_value(&self,
888                        sp: Span,
889                        name: InternedString,
890                        value: ast::Lit_)
891                        -> @ast::MetaItem {
892         @respan(sp, ast::MetaNameValue(name, respan(sp, value)))
893     }
894
895     fn view_use(&self, sp: Span,
896                 vis: ast::Visibility, vp: Vec<@ast::ViewPath> ) -> ast::ViewItem {
897         ast::ViewItem {
898             node: ast::ViewItemUse(vp),
899             attrs: Vec::new(),
900             vis: vis,
901             span: sp
902         }
903     }
904
905     fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem {
906         let last = path.segments.last().unwrap().identifier;
907         self.view_use_simple_(sp, vis, last, path)
908     }
909
910     fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
911                         ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
912         self.view_use(sp, vis,
913                       vec!(@respan(sp,
914                                 ast::ViewPathSimple(ident,
915                                                     path,
916                                                     ast::DUMMY_NODE_ID))))
917     }
918
919     fn view_use_list(&self, sp: Span, vis: ast::Visibility,
920                      path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem {
921         let imports = imports.map(|id| {
922             respan(sp, ast::PathListIdent_ { name: *id, id: ast::DUMMY_NODE_ID })
923         });
924
925         self.view_use(sp, vis,
926                       vec!(@respan(sp,
927                                 ast::ViewPathList(self.path(sp, path),
928                                                   imports.iter()
929                                                          .map(|x| *x)
930                                                          .collect(),
931                                                   ast::DUMMY_NODE_ID))))
932     }
933
934     fn view_use_glob(&self, sp: Span,
935                      vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
936         self.view_use(sp, vis,
937                       vec!(@respan(sp,
938                                 ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))))
939     }
940 }
941
942 struct Duplicator<'a> {
943     cx: &'a ExtCtxt<'a>,
944 }
945
946 impl<'a> Folder for Duplicator<'a> {
947     fn new_id(&mut self, _: NodeId) -> NodeId {
948         ast::DUMMY_NODE_ID
949     }
950 }
951
952 pub trait Duplicate {
953     //
954     // Duplication functions
955     //
956     // These functions just duplicate AST nodes.
957     //
958
959     fn duplicate(&self, cx: &ExtCtxt) -> Self;
960 }
961
962 impl Duplicate for @ast::Expr {
963     fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr {
964         let mut folder = Duplicator {
965             cx: cx,
966         };
967         folder.fold_expr(*self)
968     }
969 }