(index<- )        ./libsyntax/fold.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 ast::*;
  12  use ast;
  13  use ast_util;
  14  use codemap::{respan, Span, Spanned};
  15  use parse::token;
  16  use owned_slice::OwnedSlice;
  17  use util::small_vector::SmallVector;
  18  
  19  use std::rc::Rc;
  20  
  21  // We may eventually want to be able to fold over type parameters, too.
  22  pub trait Folder {
  23      fn fold_crate(&mut self, cCrate) -> Crate {
  24          noop_fold_crate(c, self)
  25      }
  26  
  27      fn fold_meta_items(&mut self, meta_items&[@MetaItem]) -> Vec<@MetaItem> {
  28          meta_items.iter().map(|x| fold_meta_item_(*x, self)).collect()
  29      }
  30  
  31      fn fold_view_path(&mut self, view_path@ViewPath) -> @ViewPath {
  32          let inner_view_path = match view_path.node {
  33              ViewPathSimple(ref ident, ref path, node_id) => {
  34                  let id = self.new_id(node_id);
  35                  ViewPathSimple(ident.clone(),
  36                                 self.fold_path(path),
  37                                 id)
  38              }
  39              ViewPathGlob(ref path, node_id) => {
  40                  let id = self.new_id(node_id);
  41                  ViewPathGlob(self.fold_path(path), id)
  42              }
  43              ViewPathList(ref path, ref path_list_idents, node_id) => {
  44                  let id = self.new_id(node_id);
  45                  ViewPathList(self.fold_path(path),
  46                               path_list_idents.iter().map(|path_list_ident| {
  47                                  let id = self.new_id(path_list_ident.node
  48                                                                      .id);
  49                                  Spanned {
  50                                      node: PathListIdent_ {
  51                                          name: path_list_ident.node
  52                                                               .name
  53                                                               .clone(),
  54                                          id: id,
  55                                      },
  56                                      span: self.new_span(
  57                                          path_list_ident.span)
  58                                  }
  59                               }).collect(),
  60                               id)
  61              }
  62          };
  63          @Spanned {
  64              node: inner_view_path,
  65              span: self.new_span(view_path.span),
  66          }
  67      }
  68  
  69      fn fold_view_item(&mut self, vi&ViewItem) -> ViewItem {
  70          noop_fold_view_item(vi, self)
  71      }
  72  
  73      fn fold_foreign_item(&mut self, ni@ForeignItem) -> @ForeignItem {
  74          noop_fold_foreign_item(ni, self)
  75      }
  76  
  77      fn fold_item(&mut self, i@Item) -> SmallVector<@Item> {
  78          noop_fold_item(i, self)
  79      }
  80  
  81      fn fold_struct_field(&mut self, sf&StructField) -> StructField {
  82          let id = self.new_id(sf.node.id);
  83          Spanned {
  84              node: ast::StructField_ {
  85                  kind: sf.node.kind,
  86                  id: id,
  87                  ty: self.fold_ty(sf.node.ty),
  88                  attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect()
  89              },
  90              span: self.new_span(sf.span)
  91          }
  92      }
  93  
  94      fn fold_item_underscore(&mut self, i&Item_) -> Item_ {
  95          noop_fold_item_underscore(i, self)
  96      }
  97  
  98      fn fold_fn_decl(&mut self, d&FnDecl) -> P<FnDecl> {
  99          noop_fold_fn_decl(d, self)
 100      }
 101  
 102      fn fold_type_method(&mut self, m&TypeMethod) -> TypeMethod {
 103          noop_fold_type_method(m, self)
 104      }
 105  
 106      fn fold_method(&mut self, m@Method) -> @Method {
 107          noop_fold_method(m, self)
 108      }
 109  
 110      fn fold_block(&mut self, bP<Block>) -> P<Block> {
 111          noop_fold_block(b, self)
 112      }
 113  
 114      fn fold_stmt(&mut self, s&Stmt) -> SmallVector<@Stmt> {
 115          noop_fold_stmt(s, self)
 116      }
 117  
 118      fn fold_arm(&mut self, a&Arm) -> Arm {
 119          Arm {
 120              attrs: a.attrs.iter().map(|x| fold_attribute_(*x, self)).collect(),
 121              pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(),
 122              guard: a.guard.map(|x| self.fold_expr(x)),
 123              body: self.fold_expr(a.body),
 124          }
 125      }
 126  
 127      fn fold_pat(&mut self, p@Pat) -> @Pat {
 128          noop_fold_pat(p, self)
 129      }
 130  
 131      fn fold_decl(&mut self, d@Decl) -> SmallVector<@Decl> {
 132          let node = match d.node {
 133              DeclLocal(ref l) => SmallVector::one(DeclLocal(self.fold_local(*l))),
 134              DeclItem(it) => {
 135                  self.fold_item(it).move_iter().map(|i| DeclItem(i)).collect()
 136              }
 137          };
 138  
 139          node.move_iter().map(|node| {
 140              @Spanned {
 141                  node: node,
 142                  span: self.new_span(d.span),
 143              }
 144          }).collect()
 145      }
 146  
 147      fn fold_expr(&mut self, e@Expr) -> @Expr {
 148          noop_fold_expr(e, self)
 149      }
 150  
 151      fn fold_ty(&mut self, tP<Ty>) -> P<Ty> {
 152          let id = self.new_id(t.id);
 153          let node = match t.node {
 154              TyNil | TyBot | TyInfer => t.node.clone(),
 155              TyBox(ty) => TyBox(self.fold_ty(ty)),
 156              TyUniq(ty) => TyUniq(self.fold_ty(ty)),
 157              TyVec(ty) => TyVec(self.fold_ty(ty)),
 158              TyPtr(ref mt) => TyPtr(fold_mt(mt, self)),
 159              TyRptr(ref region, ref mt) => {
 160                  TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
 161              }
 162              TyClosure(ref f, ref region) => {
 163                  TyClosure(@ClosureTy {
 164                      fn_style: f.fn_style,
 165                      onceness: f.onceness,
 166                      bounds: fold_opt_bounds(&f.bounds, self),
 167                      decl: self.fold_fn_decl(f.decl),
 168                      lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
 169                  }, fold_opt_lifetime(region, self))
 170              }
 171              TyProc(ref f) => {
 172                  TyProc(@ClosureTy {
 173                      fn_style: f.fn_style,
 174                      onceness: f.onceness,
 175                      bounds: fold_opt_bounds(&f.bounds, self),
 176                      decl: self.fold_fn_decl(f.decl),
 177                      lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
 178                  })
 179              }
 180              TyBareFn(ref f) => {
 181                  TyBareFn(@BareFnTy {
 182                      lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
 183                      fn_style: f.fn_style,
 184                      abi: f.abi,
 185                      decl: self.fold_fn_decl(f.decl)
 186                  })
 187              }
 188              TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()),
 189              TyPath(ref path, ref bounds, id) => {
 190                  let id = self.new_id(id);
 191                  TyPath(self.fold_path(path),
 192                         fold_opt_bounds(bounds, self),
 193                         id)
 194              }
 195              TyFixedLengthVec(ty, e) => {
 196                  TyFixedLengthVec(self.fold_ty(ty), self.fold_expr(e))
 197              }
 198              TyTypeof(expr) => TyTypeof(self.fold_expr(expr)),
 199          };
 200          P(Ty {
 201              id: id,
 202              span: self.new_span(t.span),
 203              node: node,
 204          })
 205      }
 206  
 207      fn fold_mod(&mut self, m&Mod) -> Mod {
 208          noop_fold_mod(m, self)
 209      }
 210  
 211      fn fold_foreign_mod(&mut self, nm&ForeignMod) -> ForeignMod {
 212          ast::ForeignMod {
 213              abi: nm.abi,
 214              view_items: nm.view_items
 215                            .iter()
 216                            .map(|x| self.fold_view_item(x))
 217                            .collect(),
 218              items: nm.items
 219                       .iter()
 220                       .map(|x| self.fold_foreign_item(*x))
 221                       .collect(),
 222          }
 223      }
 224  
 225      fn fold_variant(&mut self, v&Variant) -> P<Variant> {
 226          let id = self.new_id(v.node.id);
 227          let kind;
 228          match v.node.kind {
 229              TupleVariantKind(ref variant_args) => {
 230                  kind = TupleVariantKind(variant_args.iter().map(|x|
 231                      fold_variant_arg_(x, self)).collect())
 232              }
 233              StructVariantKind(ref struct_def) => {
 234                  kind = StructVariantKind(@ast::StructDef {
 235                      fields: struct_def.fields.iter()
 236                          .map(|f| self.fold_struct_field(f)).collect(),
 237                      ctor_id: struct_def.ctor_id.map(|c| self.new_id(c)),
 238                      super_struct: match struct_def.super_struct {
 239                          Some(t) => Some(self.fold_ty(t)),
 240                          None => None
 241                      },
 242                      is_virtual: struct_def.is_virtual,
 243                  })
 244              }
 245          }
 246  
 247          let attrs = v.node.attrs.iter().map(|x| fold_attribute_(*x, self)).collect();
 248  
 249          let de = match v.node.disr_expr {
 250            Some(e) => Some(self.fold_expr(e)),
 251            None => None
 252          };
 253          let node = ast::Variant_ {
 254              name: v.node.name,
 255              attrs: attrs,
 256              kind: kind,
 257              id: id,
 258              disr_expr: de,
 259              vis: v.node.vis,
 260          };
 261          P(Spanned {
 262              node: node,
 263              span: self.new_span(v.span),
 264          })
 265      }
 266  
 267      fn fold_ident(&mut self, iIdent) -> Ident {
 268          i
 269      }
 270  
 271      fn fold_path(&mut self, p&Path) -> Path {
 272          ast::Path {
 273              span: self.new_span(p.span),
 274              global: p.global,
 275              segments: p.segments.iter().map(|segment| ast::PathSegment {
 276                  identifier: self.fold_ident(segment.identifier),
 277                  lifetimes: segment.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
 278                  types: segment.types.iter().map(|&typ| self.fold_ty(typ)).collect(),
 279              }).collect()
 280          }
 281      }
 282  
 283      fn fold_local(&mut self, l@Local) -> @Local {
 284          let id = self.new_id(l.id); // Needs to be first, for ast_map.
 285          @Local {
 286              id: id,
 287              ty: self.fold_ty(l.ty),
 288              pat: self.fold_pat(l.pat),
 289              init: l.init.map(|e| self.fold_expr(e)),
 290              span: self.new_span(l.span),
 291          }
 292      }
 293  
 294      fn fold_mac(&mut self, macro&Mac) -> Mac {
 295          Spanned {
 296              node: match macro.node {
 297                  MacInvocTT(ref p, ref tts, ctxt) => {
 298                      MacInvocTT(self.fold_path(p),
 299                                 fold_tts(tts.as_slice(), self),
 300                                 ctxt)
 301                  }
 302              },
 303              span: self.new_span(macro.span)
 304          }
 305      }
 306  
 307      fn map_exprs(&self, f|@Expr-> @Expr, es&[@Expr]) -> Vec<@Expr> {
 308          es.iter().map(|x| f(*x)).collect()
 309      }
 310  
 311      fn new_id(&mut self, iNodeId) -> NodeId {
 312          i
 313      }
 314  
 315      fn new_span(&mut self, spSpan) -> Span {
 316          sp
 317      }
 318  
 319      fn fold_explicit_self(&mut self, es&ExplicitSelf) -> ExplicitSelf {
 320          Spanned {
 321              span: self.new_span(es.span),
 322              node: self.fold_explicit_self_(&es.node)
 323          }
 324      }
 325  
 326      fn fold_explicit_self_(&mut self, es&ExplicitSelf_) -> ExplicitSelf_ {
 327          match *es {
 328              SelfStatic | SelfValue | SelfUniq => *es,
 329              SelfRegion(ref lifetime, m) => {
 330                  SelfRegion(fold_opt_lifetime(lifetime, self), m)
 331              }
 332          }
 333      }
 334  
 335      fn fold_lifetime(&mut self, l&Lifetime) -> Lifetime {
 336          noop_fold_lifetime(l, self)
 337      }
 338  }
 339  
 340  /* some little folds that probably aren't useful to have in Folder itself*/
 341  
 342  //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
 343  fn fold_meta_item_<T: Folder>(mi: @MetaItem, fld: &mut T) -> @MetaItem {
 344      @Spanned {
 345          node:
 346              match mi.node {
 347                  MetaWord(ref id) => MetaWord((*id).clone()),
 348                  MetaList(ref id, ref mis) => {
 349                      MetaList((*id).clone(), mis.iter().map(|e| fold_meta_item_(*e, fld)).collect())
 350                  }
 351                  MetaNameValue(ref id, ref s) => {
 352                      MetaNameValue((*id).clone(), (*s).clone())
 353                  }
 354              },
 355          span: fld.new_span(mi.span) }
 356  }
 357  
 358  //used in noop_fold_item and noop_fold_crate
 359  fn fold_attribute_<T: Folder>(atAttribute, fld: &mut T) -> Attribute {
 360      Spanned {
 361          span: fld.new_span(at.span),
 362          node: ast::Attribute_ {
 363              style: at.node.style,
 364              value: fold_meta_item_(at.node.value, fld),
 365              is_sugared_doc: at.node.is_sugared_doc
 366          }
 367      }
 368  }
 369  
 370  //used in noop_fold_foreign_item and noop_fold_fn_decl
 371  fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
 372      let id = fld.new_id(a.id); // Needs to be first, for ast_map.
 373      Arg {
 374          id: id,
 375          ty: fld.fold_ty(a.ty),
 376          pat: fld.fold_pat(a.pat),
 377      }
 378  }
 379  
 380  // build a new vector of tts by appling the Folder's fold_ident to
 381  // all of the identifiers in the token trees.
 382  //
 383  // This is part of hygiene magic. As far as hygiene is concerned, there
 384  // are three types of let pattern bindings or loop labels:
 385  //      - those defined and used in non-macro part of the program
 386  //      - those used as part of macro invocation arguments
 387  //      - those defined and used inside macro definitions
 388  // Lexically, type 1 and 2 are in one group and type 3 the other. If they
 389  // clash, in order for let and loop label to work hygienically, one group
 390  // or the other needs to be renamed. The problem is that type 2 and 3 are
 391  // parsed together (inside the macro expand function). After being parsed and
 392  // AST being constructed, they can no longer be distinguished from each other.
 393  //
 394  // For that reason, type 2 let bindings and loop labels are actually renamed
 395  // in the form of tokens instead of AST nodes, here. There are wasted effort
 396  // since many token::IDENT are not necessary part of let bindings and most
 397  // token::LIFETIME are certainly not loop labels. But we can't tell in their
 398  // token form. So this is less ideal and hacky but it works.
 399  pub fn fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
 400      tts.iter().map(|tt| {
 401          match *tt {
 402              TTTok(span, ref tok) =>
 403              TTTok(span,maybe_fold_ident(tok,fld)),
 404              TTDelim(ref tts) => TTDelim(Rc::new(fold_tts(tts.as_slice(), fld))),
 405              TTSeq(span, ref pattern, ref sep, is_optional) =>
 406              TTSeq(span,
 407                    Rc::new(fold_tts(pattern.as_slice(), fld)),
 408                    sep.as_ref().map(|tok|maybe_fold_ident(tok,fld)),
 409                    is_optional),
 410              TTNonterminal(sp,ref ident) =>
 411              TTNonterminal(sp,fld.fold_ident(*ident))
 412          }
 413      }).collect()
 414  }
 415  
 416  // apply ident folder if it's an ident, otherwise leave it alone
 417  fn maybe_fold_ident<T: Folder>(t: &token::Token, fld: &mut T) -> token::Token {
 418      match *t {
 419          token::IDENT(id, followed_by_colons) => {
 420              token::IDENT(fld.fold_ident(id), followed_by_colons)
 421          }
 422          token::LIFETIME(id) => token::LIFETIME(fld.fold_ident(id)),
 423          _ => (*t).clone()
 424      }
 425  }
 426  
 427  pub fn noop_fold_fn_decl<T: Folder>(decl: &FnDecl, fld: &mut T) -> P<FnDecl> {
 428      P(FnDecl {
 429          inputs: decl.inputs.iter().map(|x| fold_arg_(x, fld)).collect(), // bad copy
 430          output: fld.fold_ty(decl.output),
 431          cf: decl.cf,
 432          variadic: decl.variadic
 433      })
 434  }
 435  
 436  fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
 437                                      -> TyParamBound {
 438      match *tpb {
 439          TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
 440          StaticRegionTyParamBound => StaticRegionTyParamBound,
 441          OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s)
 442      }
 443  }
 444  
 445  pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
 446      let id = fld.new_id(tp.id);
 447      TyParam {
 448          ident: tp.ident,
 449          id: id,
 450          sized: tp.sized,
 451          bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
 452          default: tp.default.map(|x| fld.fold_ty(x)),
 453          span: tp.span
 454      }
 455  }
 456  
 457  pub fn fold_ty_params<T: Folder>(tps: &OwnedSlice<TyParam>, fld: &mut T)
 458                                     -> OwnedSlice<TyParam> {
 459      tps.map(|tp| fold_ty_param(tp, fld))
 460  }
 461  
 462  pub fn noop_fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
 463      let id = fld.new_id(l.id);
 464      Lifetime {
 465          id: id,
 466          span: fld.new_span(l.span),
 467          name: l.name
 468      }
 469  }
 470  
 471  pub fn fold_lifetimes<T: Folder>(lts: &Vec<Lifetime>, fld: &mut T)
 472                                     -> Vec<Lifetime> {
 473      lts.iter().map(|l| fld.fold_lifetime(l)).collect()
 474  }
 475  
 476  pub fn fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T)
 477                                        -> Option<Lifetime> {
 478      o_lt.as_ref().map(|lt| fld.fold_lifetime(lt))
 479  }
 480  
 481  pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
 482      Generics {ty_params: fold_ty_params(&generics.ty_params, fld),
 483                lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
 484  }
 485  
 486  fn fold_struct_def<T: Folder>(struct_def: @StructDef, fld: &mut T) -> @StructDef {
 487      @ast::StructDef {
 488          fields: struct_def.fields.iter().map(|f| fold_struct_field(f, fld)).collect(),
 489          ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)),
 490          super_struct: match struct_def.super_struct {
 491              Some(t) => Some(fld.fold_ty(t)),
 492              None => None
 493          },
 494          is_virtual: struct_def.is_virtual,
 495      }
 496  }
 497  
 498  fn fold_trait_ref<T: Folder>(p: &TraitRef, fld: &mut T) -> TraitRef {
 499      let id = fld.new_id(p.ref_id);
 500      ast::TraitRef {
 501          path: fld.fold_path(&p.path),
 502          ref_id: id,
 503      }
 504  }
 505  
 506  fn fold_struct_field<T: Folder>(f: &StructField, fld: &mut T) -> StructField {
 507      let id = fld.new_id(f.node.id);
 508      Spanned {
 509          node: ast::StructField_ {
 510              kind: f.node.kind,
 511              id: id,
 512              ty: fld.fold_ty(f.node.ty),
 513              attrs: f.node.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
 514          },
 515          span: fld.new_span(f.span),
 516      }
 517  }
 518  
 519  fn fold_field_<T: Folder>(fieldField, folder: &mut T) -> Field {
 520      ast::Field {
 521          ident: respan(field.ident.span, folder.fold_ident(field.ident.node)),
 522          expr: folder.fold_expr(field.expr),
 523          span: folder.new_span(field.span),
 524      }
 525  }
 526  
 527  fn fold_mt<T: Folder>(mt: &MutTy, folder: &mut T) -> MutTy {
 528      MutTy {
 529          ty: folder.fold_ty(mt.ty),
 530          mutbl: mt.mutbl,
 531      }
 532  }
 533  
 534  fn fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut T)
 535                                -> Option<OwnedSlice<TyParamBound>> {
 536      b.as_ref().map(|bounds| {
 537          bounds.map(|bound| {
 538              fold_ty_param_bound(bound, folder)
 539          })
 540      })
 541  }
 542  
 543  fn fold_variant_arg_<T: Folder>(va: &VariantArg, folder: &mut T) -> VariantArg {
 544      let id = folder.new_id(va.id);
 545      ast::VariantArg {
 546          ty: folder.fold_ty(va.ty),
 547          id: id,
 548      }
 549  }
 550  
 551  pub fn noop_fold_view_item<T: Folder>(vi: &ViewItem, folder: &mut T)
 552                                         -> ViewItem{
 553      let inner_view_item = match vi.node {
 554          ViewItemExternCrate(ref ident, ref string, node_id) => {
 555              ViewItemExternCrate(ident.clone(),
 556                                (*string).clone(),
 557                                folder.new_id(node_id))
 558          }
 559          ViewItemUse(ref view_path) => {
 560              ViewItemUse(folder.fold_view_path(*view_path))
 561          }
 562      };
 563      ViewItem {
 564          node: inner_view_item,
 565          attrs: vi.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
 566          vis: vi.vis,
 567          span: folder.new_span(vi.span),
 568      }
 569  }
 570  
 571  pub fn noop_fold_block<T: Folder>(bP<Block>, folder: &mut T) -> P<Block> {
 572      let id = folder.new_id(b.id); // Needs to be first, for ast_map.
 573      let view_items = b.view_items.iter().map(|x| folder.fold_view_item(x)).collect();
 574      let stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(*s).move_iter()).collect();
 575      P(Block {
 576          id: id,
 577          view_items: view_items,
 578          stmts: stmts,
 579          expr: b.expr.map(|x| folder.fold_expr(x)),
 580          rules: b.rules,
 581          span: folder.new_span(b.span),
 582      })
 583  }
 584  
 585  pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ {
 586      match *i {
 587          ItemStatic(t, m, e) => {
 588              ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e))
 589          }
 590          ItemFn(decl, fn_style, abi, ref generics, body) => {
 591              ItemFn(
 592                  folder.fold_fn_decl(decl),
 593                  fn_style,
 594                  abi,
 595                  fold_generics(generics, folder),
 596                  folder.fold_block(body)
 597              )
 598          }
 599          ItemMod(ref m) => ItemMod(folder.fold_mod(m)),
 600          ItemForeignMod(ref nm) => ItemForeignMod(folder.fold_foreign_mod(nm)),
 601          ItemTy(t, ref generics) => {
 602              ItemTy(folder.fold_ty(t), fold_generics(generics, folder))
 603          }
 604          ItemEnum(ref enum_definition, ref generics) => {
 605              ItemEnum(
 606                  ast::EnumDef {
 607                      variants: enum_definition.variants.iter().map(|&x| {
 608                          folder.fold_variant(x)
 609                      }).collect(),
 610                  },
 611                  fold_generics(generics, folder))
 612          }
 613          ItemStruct(ref struct_def, ref generics) => {
 614              let struct_def = fold_struct_def(*struct_def, folder);
 615              ItemStruct(struct_def, fold_generics(generics, folder))
 616          }
 617          ItemImpl(ref generics, ref ifce, ty, ref methods) => {
 618              ItemImpl(fold_generics(generics, folder),
 619                       ifce.as_ref().map(|p| fold_trait_ref(p, folder)),
 620                       folder.fold_ty(ty),
 621                       methods.iter().map(|x| folder.fold_method(*x)).collect()
 622              )
 623          }
 624          ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
 625              let methods = methods.iter().map(|method| {
 626                  match *method {
 627                      Required(ref m) => Required(folder.fold_type_method(m)),
 628                      Provided(method) => Provided(folder.fold_method(method))
 629                  }
 630              }).collect();
 631              ItemTrait(fold_generics(generics, folder),
 632                        *sized,
 633                        traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
 634                        methods)
 635          }
 636          ItemMac(ref m) => ItemMac(folder.fold_mac(m)),
 637      }
 638  }
 639  
 640  pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMethod {
 641      let id = fld.new_id(m.id); // Needs to be first, for ast_map.
 642      TypeMethod {
 643          id: id,
 644          ident: fld.fold_ident(m.ident),
 645          attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
 646          fn_style: m.fn_style,
 647          decl: fld.fold_fn_decl(m.decl),
 648          generics: fold_generics(&m.generics, fld),
 649          explicit_self: fld.fold_explicit_self(&m.explicit_self),
 650          span: fld.new_span(m.span),
 651      }
 652  }
 653  
 654  pub fn noop_fold_mod<T: Folder>(m: &Mod, folder: &mut T) -> Mod {
 655      ast::Mod {
 656          inner: folder.new_span(m.inner),
 657          view_items: m.view_items
 658                       .iter()
 659                       .map(|x| folder.fold_view_item(x)).collect(),
 660          items: m.items.iter().flat_map(|x| folder.fold_item(*x).move_iter()).collect(),
 661      }
 662  }
 663  
 664  pub fn noop_fold_crate<T: Folder>(cCrate, folder: &mut T) -> Crate {
 665      Crate {
 666          module: folder.fold_mod(&c.module),
 667          attrs: c.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
 668          config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
 669          span: folder.new_span(c.span),
 670      }
 671  }
 672  
 673  pub fn noop_fold_item<T: Folder>(i: &Item, folder: &mut T) -> SmallVector<@Item> {
 674      let id = folder.new_id(i.id); // Needs to be first, for ast_map.
 675      let node = folder.fold_item_underscore(&i.node);
 676      let ident = match node {
 677          // The node may have changed, recompute the "pretty" impl name.
 678          ItemImpl(_, ref maybe_trait, ty, _) => {
 679              ast_util::impl_pretty_name(maybe_trait, ty)
 680          }
 681          _ => i.ident
 682      };
 683  
 684      SmallVector::one(@Item {
 685          id: id,
 686          ident: folder.fold_ident(ident),
 687          attrs: i.attrs.iter().map(|e| fold_attribute_(*e, folder)).collect(),
 688          node: node,
 689          vis: i.vis,
 690          span: folder.new_span(i.span)
 691      })
 692  }
 693  
 694  pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem, folder: &mut T) -> @ForeignItem {
 695      let id = folder.new_id(ni.id); // Needs to be first, for ast_map.
 696      @ForeignItem {
 697          id: id,
 698          ident: folder.fold_ident(ni.ident),
 699          attrs: ni.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
 700          node: match ni.node {
 701              ForeignItemFn(ref fdec, ref generics) => {
 702                  ForeignItemFn(P(FnDecl {
 703                      inputs: fdec.inputs.iter().map(|a| fold_arg_(a, folder)).collect(),
 704                      output: folder.fold_ty(fdec.output),
 705                      cf: fdec.cf,
 706                      variadic: fdec.variadic
 707                  }), fold_generics(generics, folder))
 708              }
 709              ForeignItemStatic(t, m) => {
 710                  ForeignItemStatic(folder.fold_ty(t), m)
 711              }
 712          },
 713          span: folder.new_span(ni.span),
 714          vis: ni.vis,
 715      }
 716  }
 717  
 718  pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
 719      let id = folder.new_id(m.id); // Needs to be first, for ast_map.
 720      @Method {
 721          id: id,
 722          ident: folder.fold_ident(m.ident),
 723          attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
 724          generics: fold_generics(&m.generics, folder),
 725          explicit_self: folder.fold_explicit_self(&m.explicit_self),
 726          fn_style: m.fn_style,
 727          decl: folder.fold_fn_decl(m.decl),
 728          body: folder.fold_block(m.body),
 729          span: folder.new_span(m.span),
 730          vis: m.vis
 731      }
 732  }
 733  
 734  pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
 735      let id = folder.new_id(p.id);
 736      let node = match p.node {
 737          PatWild => PatWild,
 738          PatWildMulti => PatWildMulti,
 739          PatIdent(binding_mode, ref pth, ref sub) => {
 740              PatIdent(binding_mode,
 741                       folder.fold_path(pth),
 742                       sub.map(|x| folder.fold_pat(x)))
 743          }
 744          PatLit(e) => PatLit(folder.fold_expr(e)),
 745          PatEnum(ref pth, ref pats) => {
 746              PatEnum(folder.fold_path(pth),
 747                      pats.as_ref().map(|pats| pats.iter().map(|x| folder.fold_pat(*x)).collect()))
 748          }
 749          PatStruct(ref pth, ref fields, etc) => {
 750              let pth_ = folder.fold_path(pth);
 751              let fs = fields.iter().map(|f| {
 752                  ast::FieldPat {
 753                      ident: f.ident,
 754                      pat: folder.fold_pat(f.pat)
 755                  }
 756              }).collect();
 757              PatStruct(pth_, fs, etc)
 758          }
 759          PatTup(ref elts) => PatTup(elts.iter().map(|x| folder.fold_pat(*x)).collect()),
 760          PatUniq(inner) => PatUniq(folder.fold_pat(inner)),
 761          PatRegion(inner) => PatRegion(folder.fold_pat(inner)),
 762          PatRange(e1, e2) => {
 763              PatRange(folder.fold_expr(e1), folder.fold_expr(e2))
 764          },
 765          PatVec(ref before, ref slice, ref after) => {
 766              PatVec(before.iter().map(|x| folder.fold_pat(*x)).collect(),
 767                      slice.map(|x| folder.fold_pat(x)),
 768                      after.iter().map(|x| folder.fold_pat(*x)).collect())
 769          }
 770      };
 771  
 772      @Pat {
 773          id: id,
 774          span: folder.new_span(p.span),
 775          node: node,
 776      }
 777  }
 778  
 779  pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
 780      let id = folder.new_id(e.id);
 781      let node = match e.node {
 782          ExprVstore(e, v) => {
 783              ExprVstore(folder.fold_expr(e), v)
 784          }
 785          ExprBox(p, e) => {
 786              ExprBox(folder.fold_expr(p), folder.fold_expr(e))
 787          }
 788          ExprVec(ref exprs) => {
 789              ExprVec(exprs.iter().map(|&x| folder.fold_expr(x)).collect())
 790          }
 791          ExprRepeat(expr, count) => {
 792              ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count))
 793          }
 794          ExprTup(ref elts) => ExprTup(elts.iter().map(|x| folder.fold_expr(*x)).collect()),
 795          ExprCall(f, ref args) => {
 796              ExprCall(folder.fold_expr(f),
 797                       args.iter().map(|&x| folder.fold_expr(x)).collect())
 798          }
 799          ExprMethodCall(i, ref tps, ref args) => {
 800              ExprMethodCall(
 801                  respan(i.span, folder.fold_ident(i.node)),
 802                  tps.iter().map(|&x| folder.fold_ty(x)).collect(),
 803                  args.iter().map(|&x| folder.fold_expr(x)).collect())
 804          }
 805          ExprBinary(binop, lhs, rhs) => {
 806              ExprBinary(binop,
 807                         folder.fold_expr(lhs),
 808                         folder.fold_expr(rhs))
 809          }
 810          ExprUnary(binop, ohs) => {
 811              ExprUnary(binop, folder.fold_expr(ohs))
 812          }
 813          ExprLit(_) => e.node.clone(),
 814          ExprCast(expr, ty) => {
 815              ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
 816          }
 817          ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
 818          ExprIf(cond, tr, fl) => {
 819              ExprIf(folder.fold_expr(cond),
 820                     folder.fold_block(tr),
 821                     fl.map(|x| folder.fold_expr(x)))
 822          }
 823          ExprWhile(cond, body) => {
 824              ExprWhile(folder.fold_expr(cond), folder.fold_block(body))
 825          }
 826          ExprForLoop(pat, iter, body, ref maybe_ident) => {
 827              ExprForLoop(folder.fold_pat(pat),
 828                          folder.fold_expr(iter),
 829                          folder.fold_block(body),
 830                          maybe_ident.map(|i| folder.fold_ident(i)))
 831          }
 832          ExprLoop(body, opt_ident) => {
 833              ExprLoop(folder.fold_block(body),
 834                       opt_ident.map(|x| folder.fold_ident(x)))
 835          }
 836          ExprMatch(expr, ref arms) => {
 837              ExprMatch(folder.fold_expr(expr),
 838                        arms.iter().map(|x| folder.fold_arm(x)).collect())
 839          }
 840          ExprFnBlock(decl, body) => {
 841              ExprFnBlock(folder.fold_fn_decl(decl), folder.fold_block(body))
 842          }
 843          ExprProc(decl, body) => {
 844              ExprProc(folder.fold_fn_decl(decl), folder.fold_block(body))
 845          }
 846          ExprBlock(blk) => ExprBlock(folder.fold_block(blk)),
 847          ExprAssign(el, er) => {
 848              ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
 849          }
 850          ExprAssignOp(op, el, er) => {
 851              ExprAssignOp(op,
 852                           folder.fold_expr(el),
 853                           folder.fold_expr(er))
 854          }
 855          ExprField(el, id, ref tys) => {
 856              ExprField(folder.fold_expr(el),
 857                        folder.fold_ident(id),
 858                        tys.iter().map(|&x| folder.fold_ty(x)).collect())
 859          }
 860          ExprIndex(el, er) => {
 861              ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
 862          }
 863          ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
 864          ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
 865          ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
 866          ExprRet(ref e) => {
 867              ExprRet(e.map(|x| folder.fold_expr(x)))
 868          }
 869          ExprInlineAsm(ref a) => {
 870              ExprInlineAsm(InlineAsm {
 871                  inputs: a.inputs.iter().map(|&(ref c, input)| {
 872                      ((*c).clone(), folder.fold_expr(input))
 873                  }).collect(),
 874                  outputs: a.outputs.iter().map(|&(ref c, out)| {
 875                      ((*c).clone(), folder.fold_expr(out))
 876                  }).collect(),
 877                  .. (*a).clone()
 878              })
 879          }
 880          ExprMac(ref mac) => ExprMac(folder.fold_mac(mac)),
 881          ExprStruct(ref path, ref fields, maybe_expr) => {
 882              ExprStruct(folder.fold_path(path),
 883                         fields.iter().map(|x| fold_field_(*x, folder)).collect(),
 884                         maybe_expr.map(|x| folder.fold_expr(x)))
 885          },
 886          ExprParen(ex) => ExprParen(folder.fold_expr(ex))
 887      };
 888  
 889      @Expr {
 890          id: id,
 891          node: node,
 892          span: folder.new_span(e.span),
 893      }
 894  }
 895  
 896  pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> {
 897      let nodes = match s.node {
 898          StmtDecl(d, id) => {
 899              let id = folder.new_id(id);
 900              folder.fold_decl(d).move_iter()
 901                      .map(|d| StmtDecl(d, id))
 902                      .collect()
 903          }
 904          StmtExpr(e, id) => {
 905              let id = folder.new_id(id);
 906              SmallVector::one(StmtExpr(folder.fold_expr(e), id))
 907          }
 908          StmtSemi(e, id) => {
 909              let id = folder.new_id(id);
 910              SmallVector::one(StmtSemi(folder.fold_expr(e), id))
 911          }
 912          StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi))
 913      };
 914  
 915      nodes.move_iter().map(|node| @Spanned {
 916          node: node,
 917          span: folder.new_span(s.span),
 918      }).collect()
 919  }
 920  
 921  #[cfg(test)]
 922  mod test {
 923      use std::io;
 924      use ast;
 925      use util::parser_testing::{string_to_crate, matches_codepattern};
 926      use parse::token;
 927      use print::pprust;
 928      use super::*;
 929  
 930      // this version doesn't care about getting comments or docstrings in.
 931      fn fake_print_crate(s: &mut pprust::State,
 932                          krate: &ast::Crate) -> io::IoResult<(){
 933          s.print_mod(&krate.module, krate.attrs.as_slice())
 934      }
 935  
 936      // change every identifier to "zz"
 937      struct ToZzIdentFolder;
 938  
 939      impl Folder for ToZzIdentFolder {
 940          fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
 941              token::str_to_ident("zz")
 942          }
 943      }
 944  
 945      // maybe add to expand.rs...
 946      macro_rules! assert_pred (
 947          ($pred:expr, $predname:expr, $a:expr , $b:expr) => (
 948              {
 949                  let pred_val = $pred;
 950                  let a_val = $a;
 951                  let b_val = $b;
 952                  if !(pred_val(a_val.as_slice(),b_val.as_slice())) {
 953                      fail!("expected args satisfying {}, got {:?} and {:?}",
 954                            $predname, a_val, b_val);
 955                  }
 956              }
 957          )
 958      )
 959  
 960      // make sure idents get transformed everywhere
 961      #[test] fn ident_transformation () {
 962          let mut zz_fold = ToZzIdentFolder;
 963          let ast = string_to_crate(
 964              "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_strbuf());
 965          let folded_crate = zz_fold.fold_crate(ast);
 966          assert_pred!(
 967              matches_codepattern,
 968              "matches_codepattern",
 969              pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
 970              "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_strbuf());
 971      }
 972  
 973      // even inside macro defs....
 974      #[test] fn ident_transformation_in_defs () {
 975          let mut zz_fold = ToZzIdentFolder;
 976          let ast = string_to_crate(
 977              "macro_rules! a {(b $c:expr $(d $e:token)f+ => \
 978               (g $(d $d $e)+))} ".to_strbuf());
 979          let folded_crate = zz_fold.fold_crate(ast);
 980          assert_pred!(
 981              matches_codepattern,
 982              "matches_codepattern",
 983              pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
 984              "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_strbuf());
 985      }
 986  }


libsyntax/fold.rs:733:1-733:1 -fn- definition:
pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
    let id = folder.new_id(p.id);
    let node = match p.node {
references:- 2
127:     fn fold_pat(&mut self, p: @Pat) -> @Pat {
128:         noop_fold_pat(p, self)
129:     }
libsyntax/ast_map.rs:
509:     fn fold_pat(&mut self, pat: @Pat) -> @Pat {
510:         let pat = fold::noop_fold_pat(pat, self);
511:         match pat.node {


libsyntax/fold.rs:416:65-416:65 -fn- definition:
// apply ident folder if it's an ident, otherwise leave it alone
fn maybe_fold_ident<T: Folder>(t: &token::Token, fld: &mut T) -> token::Token {
    match *t {
references:- 2
407:                   Rc::new(fold_tts(pattern.as_slice(), fld)),
408:                   sep.as_ref().map(|tok|maybe_fold_ident(tok,fld)),
409:                   is_optional),


libsyntax/fold.rs:672:1-672:1 -fn- definition:
pub fn noop_fold_item<T: Folder>(i: &Item, folder: &mut T) -> SmallVector<@Item> {
    let id = folder.new_id(i.id); // Needs to be first, for ast_map.
    let node = folder.fold_item_underscore(&i.node);
references:- 4
77:     fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
78:         noop_fold_item(i, self)
79:     }
libsyntax/ext/expand.rs:
299:                                           macro_escape,
300:                                           noop_fold_item(it, fld));
301:             fld.cx.mod_pop();
libsyntax/ast_map.rs:
453:         let i = fold::noop_fold_item(i, self).expect_one("expected one item");
454:         assert_eq!(self.parent, i.id);
libsyntax/ext/expand.rs:
303:         },
304:         _ => noop_fold_item(it, fld)
305:     };


libsyntax/fold.rs:480:1-480:1 -fn- definition:
pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
    Generics {ty_params: fold_ty_params(&generics.ty_params, fld),
              lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
references:- 9
723:         attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
724:         generics: fold_generics(&m.generics, folder),
725:         explicit_self: folder.fold_explicit_self(&m.explicit_self),


libsyntax/fold.rs:550:1-550:1 -fn- definition:
pub fn noop_fold_view_item<T: Folder>(vi: &ViewItem, folder: &mut T)
                                       -> ViewItem{
    let inner_view_item = match vi.node {
references:- 2
69:     fn fold_view_item(&mut self, vi: &ViewItem) -> ViewItem {
70:         noop_fold_view_item(vi, self)
71:     }
libsyntax/ext/expand.rs:
484:     noop_fold_view_item(vi, fld)
485: }


libsyntax/fold.rs:778:1-778:1 -fn- definition:
pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
    let id = folder.new_id(e.id);
    let node = match e.node {
references:- 3
147:     fn fold_expr(&mut self, e: @Expr) -> @Expr {
148:         noop_fold_expr(e, self)
149:     }
libsyntax/ast_map.rs:
522:     fn fold_expr(&mut self, expr: @Expr) -> @Expr {
523:         let expr = fold::noop_fold_expr(expr, self);
libsyntax/ext/expand.rs:
209:         _ => noop_fold_expr(e, fld)
210:     }


libsyntax/fold.rs:461:1-461:1 -fn- definition:
pub fn noop_fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
    let id = fld.new_id(l.id);
    Lifetime {
references:- 2
335:     fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime {
336:         noop_fold_lifetime(l, self)
337:     }
libsyntax/ast_map.rs:
568:     fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
569:         let lifetime = fold::noop_fold_lifetime(lifetime, self);
570:         self.insert(lifetime.id, EntryLifetime(self.parent, @lifetime));


libsyntax/fold.rs:895:1-895:1 -fn- definition:
pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> {
    let nodes = match s.node {
        StmtDecl(d, id) => {
references:- 4
libsyntax/ext/expand.rs:
704:         },
705:         _ => noop_fold_stmt(s, fld),
706:     }
libsyntax/ast_map.rs:
530:     fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<@Stmt> {
531:         let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
532:         self.insert(ast_util::stmt_id(stmt), EntryStmt(self.parent, stmt));
libsyntax/fold.rs:
114:     fn fold_stmt(&mut self, s: &Stmt) -> SmallVector<@Stmt> {
115:         noop_fold_stmt(s, self)
116:     }


libsyntax/fold.rs:533:1-533:1 -fn- definition:
fn fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut T)
                              -> Option<OwnedSlice<TyParamBound>> {
    b.as_ref().map(|bounds| {
references:- 3
174:                     onceness: f.onceness,
175:                     bounds: fold_opt_bounds(&f.bounds, self),
176:                     decl: self.fold_fn_decl(f.decl),
--
191:                 TyPath(self.fold_path(path),
192:                        fold_opt_bounds(bounds, self),
193:                        id)


libsyntax/fold.rs:21:72-21:72 -trait- definition:
// We may eventually want to be able to fold over type parameters, too.
pub trait Folder {
    fn fold_crate(&mut self, c: Crate) -> Crate {
references:- 37
libsyntax/ext/expand.rs:
libsyntax/ext/build.rs:
libsyntax/ast_map.rs:
libsyntax/fold.rs:


libsyntax/fold.rs:342:75-342:75 -fn- definition:
//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
fn fold_meta_item_<T: Folder>(mi: @MetaItem, fld: &mut T) -> @MetaItem {
    @Spanned {
references:- 4
27:     fn fold_meta_items(&mut self, meta_items: &[@MetaItem]) -> Vec<@MetaItem> {
28:         meta_items.iter().map(|x| fold_meta_item_(*x, self)).collect()
29:     }
--
348:                 MetaList(ref id, ref mis) => {
349:                     MetaList((*id).clone(), mis.iter().map(|e| fold_meta_item_(*e, fld)).collect())
350:                 }
--
363:             style: at.node.style,
364:             value: fold_meta_item_(at.node.value, fld),
365:             is_sugared_doc: at.node.is_sugared_doc
--
667:         attrs: c.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
668:         config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
669:         span: folder.new_span(c.span),


libsyntax/fold.rs:475:1-475:1 -fn- definition:
pub fn fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T)
                                      -> Option<Lifetime> {
    o_lt.as_ref().map(|lt| fld.fold_lifetime(lt))
references:- 3
159:             TyRptr(ref region, ref mt) => {
160:                 TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
161:             }
--
329:             SelfRegion(ref lifetime, m) => {
330:                 SelfRegion(fold_opt_lifetime(lifetime, self), m)
331:             }


libsyntax/fold.rs:570:1-570:1 -fn- definition:
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
    let id = folder.new_id(b.id); // Needs to be first, for ast_map.
    let view_items = b.view_items.iter().map(|x| folder.fold_view_item(x)).collect();
references:- 2
110:     fn fold_block(&mut self, b: P<Block>) -> P<Block> {
111:         noop_fold_block(b, self)
112:     }
libsyntax/ast_map.rs:
562:     fn fold_block(&mut self, block: P<Block>) -> P<Block> {
563:         let block = fold::noop_fold_block(block, self);
564:         self.insert(block.id, EntryBlock(self.parent, block));


libsyntax/fold.rs:426:1-426:1 -fn- definition:
pub fn noop_fold_fn_decl<T: Folder>(decl: &FnDecl, fld: &mut T) -> P<FnDecl> {
    P(FnDecl {
        inputs: decl.inputs.iter().map(|x| fold_arg_(x, fld)).collect(), // bad copy
references:- 2
98:     fn fold_fn_decl(&mut self, d: &FnDecl) -> P<FnDecl> {
99:         noop_fold_fn_decl(d, self)
100:     }
libsyntax/ast_map.rs:
554:     fn fold_fn_decl(&mut self, decl: &FnDecl) -> P<FnDecl> {
555:         let decl = fold::noop_fold_fn_decl(decl, self);
556:         for a in decl.inputs.iter() {


libsyntax/fold.rs:526:1-526:1 -fn- definition:
fn fold_mt<T: Folder>(mt: &MutTy, folder: &mut T) -> MutTy {
    MutTy {
        ty: folder.fold_ty(mt.ty),
references:- 2
159:             TyRptr(ref region, ref mt) => {
160:                 TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
161:             }


libsyntax/fold.rs:358:45-358:45 -fn- definition:
//used in noop_fold_item and noop_fold_crate
fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
    Spanned {
references:- 10
87:                 ty: self.fold_ty(sf.node.ty),
88:                 attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect()
89:             },
--
564:         node: inner_view_item,
565:         attrs: vi.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
566:         vis: vi.vis,
--
644:         ident: fld.fold_ident(m.ident),
645:         attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
646:         fn_style: m.fn_style,
--
666:         module: folder.fold_mod(&c.module),
667:         attrs: c.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
668:         config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
--
686:         ident: folder.fold_ident(ident),
687:         attrs: i.attrs.iter().map(|e| fold_attribute_(*e, folder)).collect(),
688:         node: node,
--
722:         ident: folder.fold_ident(m.ident),
723:         attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
724:         generics: fold_generics(&m.generics, folder),


libsyntax/fold.rs:639:1-639:1 -fn- definition:
pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMethod {
    let id = fld.new_id(m.id); // Needs to be first, for ast_map.
    TypeMethod {
references:- 2
libsyntax/ast_map.rs:
538:         self.parent = DUMMY_NODE_ID;
539:         let m = fold::noop_fold_type_method(m, self);
540:         assert_eq!(self.parent, m.id);
libsyntax/fold.rs:
102:     fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
103:         noop_fold_type_method(m, self)
104:     }


libsyntax/fold.rs:717:1-717:1 -fn- definition:
pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
    let id = folder.new_id(m.id); // Needs to be first, for ast_map.
    @Method {
references:- 2
106:     fn fold_method(&mut self, m: @Method) -> @Method {
107:         noop_fold_method(m, self)
108:     }
libsyntax/ast_map.rs:
547:         self.parent = DUMMY_NODE_ID;
548:         let m = fold::noop_fold_method(m, self);
549:         assert_eq!(self.parent, m.id);


libsyntax/fold.rs:435:1-435:1 -fn- definition:
fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
                                    -> TyParamBound {
    match *tpb {
references:- 2
537:         bounds.map(|bound| {
538:             fold_ty_param_bound(bound, folder)
539:         })


libsyntax/fold.rs:370:55-370:55 -fn- definition:
//used in noop_fold_foreign_item and noop_fold_fn_decl
fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
    let id = fld.new_id(a.id); // Needs to be first, for ast_map.
references:- 2
702:                 ForeignItemFn(P(FnDecl {
703:                     inputs: fdec.inputs.iter().map(|a| fold_arg_(a, folder)).collect(),
704:                     output: folder.fold_ty(fdec.output),


libsyntax/fold.rs:398:61-398:61 -fn- definition:
// token form. So this is less ideal and hacky but it works.
pub fn fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
    tts.iter().map(|tt| {
references:- 5
298:                     MacInvocTT(self.fold_path(p),
299:                                fold_tts(tts.as_slice(), self),
300:                                ctxt)
--
406:             TTSeq(span,
407:                   Rc::new(fold_tts(pattern.as_slice(), fld)),
408:                   sep.as_ref().map(|tok|maybe_fold_ident(tok,fld)),
libsyntax/ext/expand.rs:
906:                 MacInvocTT(self.fold_path(path),
907:                            fold_tts(tts.as_slice(), self),
908:                            mtwt::new_mark(self.mark, ctxt))
--
924: fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
925:     fold_tts(tts, &mut new_mark_folder(m))
926: }
libsyntax/fold.rs:
403:             TTTok(span,maybe_fold_ident(tok,fld)),
404:             TTDelim(ref tts) => TTDelim(Rc::new(fold_tts(tts.as_slice(), fld))),
405:             TTSeq(span, ref pattern, ref sep, is_optional) =>


libsyntax/fold.rs:497:1-497:1 -fn- definition:
fn fold_trait_ref<T: Folder>(p: &TraitRef, fld: &mut T) -> TraitRef {
    let id = fld.new_id(p.ref_id);
    ast::TraitRef {
references:- 3
438:     match *tpb {
439:         TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)),
440:         StaticRegionTyParamBound => StaticRegionTyParamBound,
--
632:                       *sized,
633:                       traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
634:                       methods)