(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, c: Crate) -> 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, b: P<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, t: P<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, i: Ident) -> 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, i: NodeId) -> NodeId {
312 i
313 }
314
315 fn new_span(&mut self, sp: Span) -> 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>(at: Attribute, 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>(field: Field, 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>(b: P<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>(c: Crate, 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:- 2127: 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:- 2407: 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:- 477: 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:- 9723: 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:- 269: 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:- 3147: 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:- 2335: 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:- 4libsyntax/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:- 3174: 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:- 37libsyntax/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:- 427: 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:- 3159: 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:- 2110: 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:- 298: 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:- 2159: 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:- 1087: 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:- 2libsyntax/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:- 2106: 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:- 2537: 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:- 2702: 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:- 5298: 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:- 3438: 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)