(index<- )        ./libsyntax/ext/build.rs

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