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.
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.
15 use codemap::{Span, respan, DUMMY_SP};
16 use ext::base::ExtCtxt;
17 use ext::quote::rt::*;
19 use owned_slice::OwnedSlice;
20 use parse::token::special_idents;
28 // Transitional reexports so qquote can find the paths it is looking for
34 pub trait AstBuilder {
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,
41 idents: Vec<ast::Ident> ,
42 lifetimes: Vec<ast::Lifetime>,
43 types: Vec<P<ast::Ty>> )
47 fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
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>;
53 fn ty_rptr(&self, span: Span,
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>;
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>;
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;
70 bounds: OwnedSlice<ast::TyParamBound>,
71 default: Option<P<ast::Ty>>) -> ast::TyParam;
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;
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,
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>;
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;
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;
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;
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;
125 fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr;
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;
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;
139 fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr;
140 fn expr_none(&self, sp: Span) -> @ast::Expr;
142 fn expr_fail(&self, span: Span, msg: InternedString) -> @ast::Expr;
143 fn expr_unreachable(&self, span: Span) -> @ast::Expr;
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;
150 fn pat_ident_binding_mode(&self,
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;
158 fn arm(&self, span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm;
159 fn arm_unreachable(&self, span: Span) -> ast::Arm;
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;
165 fn lambda_fn_decl(&self, span: Span,
166 fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> @ast::Expr;
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;
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;
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;
181 fn item(&self, span: Span,
182 name: Ident, attrs: Vec<ast::Attribute> , node: ast::Item_) -> @ast::Item;
184 fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
186 fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl>;
188 fn item_fn_poly(&self,
191 inputs: Vec<ast::Arg> ,
194 body: P<ast::Block>) -> @ast::Item;
198 inputs: Vec<ast::Arg> ,
200 body: P<ast::Block>) -> @ast::Item;
202 fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant;
203 fn item_enum_poly(&self,
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;
210 fn item_struct_poly(&self,
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;
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;
221 fn item_ty_poly(&self,
225 generics: Generics) -> @ast::Item;
226 fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item;
228 fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
230 fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem;
233 name: InternedString,
234 mis: Vec<@ast::MetaItem> )
236 fn meta_name_value(&self,
238 name: InternedString,
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;
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())
257 fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
258 self.path(span, vec!(id))
260 fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
261 self.path_all(span, true, strs, Vec::new(), Vec::new())
266 mut idents: Vec<ast::Ident> ,
267 lifetimes: Vec<ast::Lifetime>,
268 types: Vec<P<ast::Ty>> )
270 let last_identifier = idents.pop().unwrap();
271 let mut segments: Vec<ast::PathSegment> = idents.move_iter()
275 lifetimes: Vec::new(),
276 types: OwnedSlice::empty(),
279 segments.push(ast::PathSegment {
280 identifier: last_identifier,
281 lifetimes: lifetimes,
282 types: OwnedSlice::from_vec(types),
291 fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
298 fn ty(&self, span: Span, ty: ast::Ty_) -> P<ast::Ty> {
300 id: ast::DUMMY_NODE_ID,
306 fn ty_path(&self, path: ast::Path, bounds: Option<OwnedSlice<ast::TyParamBound>>)
309 ast::TyPath(path, bounds, ast::DUMMY_NODE_ID))
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)
316 self.ty_path(self.path_ident(span, ident), None)
322 lifetime: Option<ast::Lifetime>,
323 mutbl: ast::Mutability)
326 ast::TyRptr(lifetime, self.ty_mt(ty, mutbl)))
329 fn ty_uniq(&self, span: Span, ty: P<ast::Ty>) -> P<ast::Ty> {
330 self.ty(span, ast::TyUniq(ty))
333 fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
335 self.path_all(DUMMY_SP,
338 self.ident_of("std"),
339 self.ident_of("option"),
340 self.ident_of("Option")
346 fn ty_field_imm(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::TypeField {
349 mt: ast::MutTy { ty: ty, mutbl: ast::MutImmutable },
354 fn ty_infer(&self, span: Span) -> P<ast::Ty> {
355 self.ty(span, ast::TyInfer)
358 fn ty_nil(&self) -> P<ast::Ty> {
360 id: ast::DUMMY_NODE_ID,
368 bounds: OwnedSlice<ast::TyParamBound>,
369 default: Option<P<ast::Ty>>) -> ast::TyParam {
372 id: ast::DUMMY_NODE_ID,
378 // these are strange, and probably shouldn't be used outside of
379 // pipes. Specifically, the global version possible generates
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()
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()
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 }
395 ty_params: new_params,
396 .. (*generics).clone()
400 fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
403 ref_id: ast::DUMMY_NODE_ID
407 fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
408 ast::TraitTyParamBound(self.trait_ref(path))
411 fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
412 ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
415 fn stmt_expr(&self, expr: @ast::Expr) -> @ast::Stmt {
416 @respan(expr.span, ast::StmtSemi(expr, ast::DUMMY_NODE_ID))
419 fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: @ast::Expr) -> @ast::Stmt {
421 self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
423 self.pat_ident(sp, ident)
425 let local = @ast::Local {
426 ty: self.ty_infer(sp),
429 id: ast::DUMMY_NODE_ID,
432 let decl = respan(sp, ast::DeclLocal(local));
433 @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))
436 fn stmt_let_typed(&self,
444 self.pat_ident_binding_mode(sp, ident, ast::BindByValue(ast::MutMutable))
446 self.pat_ident(sp, ident)
448 let local = @ast::Local {
452 id: ast::DUMMY_NODE_ID,
455 let decl = respan(sp, ast::DeclLocal(local));
456 @respan(sp, ast::StmtDecl(@decl, ast::DUMMY_NODE_ID))
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)
463 fn block_expr(&self, expr: @ast::Expr) -> P<ast::Block> {
464 self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
468 view_items: Vec<ast::ViewItem> ,
469 stmts: Vec<@ast::Stmt> ,
470 expr: Option<@ast::Expr>) -> P<ast::Block> {
472 view_items: view_items,
475 id: ast::DUMMY_NODE_ID,
476 rules: ast::DefaultBlock,
481 fn expr(&self, span: Span, node: ast::Expr_) -> @ast::Expr {
483 id: ast::DUMMY_NODE_ID,
489 fn expr_path(&self, path: ast::Path) -> @ast::Expr {
490 self.expr(path.span, ast::ExprPath(path))
493 fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr {
494 self.expr_path(self.path_ident(span, id))
496 fn expr_self(&self, span: Span) -> @ast::Expr {
497 self.expr_ident(span, special_idents::self_)
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))
505 fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
506 self.expr_unary(sp, ast::UnDeref, e)
508 fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr {
509 self.expr(sp, ast::ExprUnary(op, e))
512 fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
513 self.expr_unary(sp, ast::UnBox, e)
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()))
519 fn expr_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
520 self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
522 fn expr_mut_addr_of(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
523 self.expr(sp, ast::ExprAddrOf(ast::MutMutable, e))
526 fn expr_call(&self, span: Span, expr: @ast::Expr, args: Vec<@ast::Expr> ) -> @ast::Expr {
527 self.expr(span, ast::ExprCall(expr, args))
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))
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)
537 fn expr_method_call(&self, span: Span,
540 mut args: Vec<@ast::Expr> ) -> @ast::Expr {
542 self.expr(span, ast::ExprMethodCall(ident, Vec::new(), args))
544 fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
545 self.expr(b.span, ast::ExprBlock(b))
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 }
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))
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)
558 fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> @ast::Expr {
559 self.expr(sp, ast::ExprLit(@respan(sp, lit)))
561 fn expr_uint(&self, span: Span, i: uint) -> @ast::Expr {
562 self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
564 fn expr_int(&self, sp: Span, i: int) -> @ast::Expr {
565 self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
567 fn expr_u8(&self, sp: Span, u: u8) -> @ast::Expr {
568 self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
570 fn expr_bool(&self, sp: Span, value: bool) -> @ast::Expr {
571 self.expr_lit(sp, ast::LitBool(value))
574 fn expr_vstore(&self, sp: Span, expr: @ast::Expr, vst: ast::ExprVstore) -> @ast::Expr {
575 self.expr(sp, ast::ExprVstore(expr, vst))
577 fn expr_vec(&self, sp: Span, exprs: Vec<@ast::Expr> ) -> @ast::Expr {
578 self.expr(sp, ast::ExprVec(exprs, ast::MutImmutable))
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")),
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)
591 fn expr_str(&self, sp: Span, s: InternedString) -> @ast::Expr {
592 self.expr_lit(sp, ast::LitStr(s, ast::CookedStr))
594 fn expr_str_uniq(&self, sp: Span, s: InternedString) -> @ast::Expr {
595 self.expr_vstore(sp, self.expr_str(sp, s), ast::ExprVstoreUniq)
599 fn expr_cast(&self, sp: Span, expr: @ast::Expr, ty: P<ast::Ty>) -> @ast::Expr {
600 self.expr(sp, ast::ExprCast(expr, ty))
604 fn expr_some(&self, sp: Span, expr: @ast::Expr) -> @ast::Expr {
606 self.ident_of("std"),
607 self.ident_of("option"),
608 self.ident_of("Some"));
609 self.expr_call_global(sp, some, vec!(expr))
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")));
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(
625 self.ident_of("std"),
627 self.ident_of("begin_unwind")),
629 self.expr_str(span, msg),
631 token::intern_and_get_ident(loc.file.name)),
632 self.expr_uint(span, loc.line)))
635 fn expr_unreachable(&self, span: Span) -> @ast::Expr {
638 "internal error: entered unreachable code"))
642 fn pat(&self, span: Span, pat: ast::Pat_) -> @ast::Pat {
643 @ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span }
645 fn pat_wild(&self, span: Span) -> @ast::Pat {
646 self.pat(span, ast::PatWild)
648 fn pat_lit(&self, span: Span, expr: @ast::Expr) -> @ast::Pat {
649 self.pat(span, ast::PatLit(expr))
651 fn pat_ident(&self, span: Span, ident: ast::Ident) -> @ast::Pat {
652 self.pat_ident_binding_mode(span, ident, ast::BindByValue(ast::MutImmutable))
655 fn pat_ident_binding_mode(&self,
658 bm: ast::BindingMode) -> @ast::Pat {
659 let path = self.path_ident(span, ident);
660 let pat = ast::PatIdent(bm, path, None);
663 fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<@ast::Pat> ) -> @ast::Pat {
664 let pat = ast::PatEnum(path, Some(subpats));
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);
673 fn arm(&self, _span: Span, pats: Vec<@ast::Pat> , expr: @ast::Expr) -> ast::Arm {
681 fn arm_unreachable(&self, span: Span) -> ast::Arm {
682 self.arm(span, vec!(self.pat_wild(span)), self.expr_unreachable(span))
685 fn expr_match(&self, span: Span, arg: @ast::Expr, arms: Vec<ast::Arm> ) -> @Expr {
686 self.expr(span, ast::ExprMatch(arg, arms))
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))
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))
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));
704 self.expr(span, ast::ExprFnBlock(fn_decl, blk))
706 fn lambda0(&self, span: Span, blk: P<ast::Block>) -> @ast::Expr {
707 self.lambda(span, Vec::new(), blk)
710 fn lambda1(&self, span: Span, blk: P<ast::Block>, ident: ast::Ident) -> @ast::Expr {
711 self.lambda(span, vec!(ident), blk)
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))
717 fn lambda_expr_0(&self, span: Span, expr: @ast::Expr) -> @ast::Expr {
718 self.lambda0(span, self.block_expr(expr))
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)
724 fn lambda_stmts(&self,
726 ids: Vec<ast::Ident>,
727 stmts: Vec<@ast::Stmt>)
729 self.lambda(span, ids, self.block(span, stmts, None))
731 fn lambda_stmts_0(&self, span: Span, stmts: Vec<@ast::Stmt> ) -> @ast::Expr {
732 self.lambda0(span, self.block(span, stmts, None))
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)
738 fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
739 let arg_pat = self.pat_ident(span, ident);
743 id: ast::DUMMY_NODE_ID
748 fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl> {
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,
763 id: ast::DUMMY_NODE_ID,
769 fn item_fn_poly(&self,
772 inputs: Vec<ast::Arg> ,
775 body: P<ast::Block>) -> @ast::Item {
779 ast::ItemFn(self.fn_decl(inputs, output),
789 inputs: Vec<ast::Arg> ,
798 ast_util::empty_generics(),
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 }
811 kind: ast::TupleVariantKind(args),
812 id: ast::DUMMY_NODE_ID,
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))
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())
830 fn item_struct(&self, span: Span, name: Ident,
831 struct_def: ast::StructDef) -> @ast::Item {
832 self.item_struct_poly(
836 ast_util::empty_generics()
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))
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 {
853 ast::ItemMod(ast::Mod {
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))
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())
869 fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute {
870 respan(sp, ast::Attribute_ {
871 style: ast::AttrOuter,
873 is_sugared_doc: false,
877 fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem {
878 @respan(sp, ast::MetaWord(w))
882 name: InternedString,
883 mis: Vec<@ast::MetaItem> )
885 @respan(sp, ast::MetaList(name, mis))
887 fn meta_name_value(&self,
889 name: InternedString,
892 @respan(sp, ast::MetaNameValue(name, respan(sp, value)))
895 fn view_use(&self, sp: Span,
896 vis: ast::Visibility, vp: Vec<@ast::ViewPath> ) -> ast::ViewItem {
898 node: ast::ViewItemUse(vp),
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)
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,
914 ast::ViewPathSimple(ident,
916 ast::DUMMY_NODE_ID))))
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 })
925 self.view_use(sp, vis,
927 ast::ViewPathList(self.path(sp, path),
931 ast::DUMMY_NODE_ID))))
934 fn view_use_glob(&self, sp: Span,
935 vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
936 self.view_use(sp, vis,
938 ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))))
942 struct Duplicator<'a> {
946 impl<'a> Folder for Duplicator<'a> {
947 fn new_id(&mut self, _: NodeId) -> NodeId {
952 pub trait Duplicate {
954 // Duplication functions
956 // These functions just duplicate AST nodes.
959 fn duplicate(&self, cx: &ExtCtxt) -> Self;
962 impl Duplicate for @ast::Expr {
963 fn duplicate(&self, cx: &ExtCtxt) -> @ast::Expr {
964 let mut folder = Duplicator {
967 folder.fold_expr(*self)