]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
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 | ||
1a4d82fc JJ |
11 | //! A Folder represents an AST->AST fold; it accepts an AST piece, |
12 | //! and returns a piece of the same type. So, for instance, macro | |
13 | //! expansion is a Folder that walks over an AST and produces another | |
14 | //! AST. | |
15 | //! | |
16 | //! Note: using a Folder (other than the MacroExpander Folder) on | |
17 | //! an AST before macro expansion is probably a bad idea. For instance, | |
18 | //! a folder renaming item names in a module will miss all of those | |
19 | //! that are created by the expansion of a macro. | |
20 | ||
223e47cc LB |
21 | use ast::*; |
22 | use ast; | |
92a42be0 | 23 | use attr::{ThinAttributes, ThinAttributesExt}; |
1a4d82fc | 24 | use codemap::{respan, Span, Spanned}; |
970d7e83 | 25 | use parse::token; |
1a4d82fc | 26 | use ptr::P; |
1a4d82fc | 27 | use util::small_vector::SmallVector; |
92a42be0 | 28 | use util::move_map::MoveMap; |
1a4d82fc JJ |
29 | |
30 | use std::rc::Rc; | |
31 | ||
1a4d82fc JJ |
32 | pub trait Folder : Sized { |
33 | // Any additions to this trait should happen in form | |
34 | // of a call to a public `noop_*` function that only calls | |
35 | // out to the folder again, not other `noop_*` functions. | |
36 | // | |
37 | // This is a necessary API workaround to the problem of not | |
38 | // being able to call out to the super default method | |
39 | // in an overridden default method. | |
40 | ||
41 | fn fold_crate(&mut self, c: Crate) -> Crate { | |
42 | noop_fold_crate(c, self) | |
223e47cc | 43 | } |
223e47cc | 44 | |
1a4d82fc JJ |
45 | fn fold_meta_items(&mut self, meta_items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> { |
46 | noop_fold_meta_items(meta_items, self) | |
223e47cc | 47 | } |
223e47cc | 48 | |
1a4d82fc JJ |
49 | fn fold_meta_item(&mut self, meta_item: P<MetaItem>) -> P<MetaItem> { |
50 | noop_fold_meta_item(meta_item, self) | |
51 | } | |
52 | ||
53 | fn fold_view_path(&mut self, view_path: P<ViewPath>) -> P<ViewPath> { | |
54 | noop_fold_view_path(view_path, self) | |
55 | } | |
56 | ||
7453a54e | 57 | fn fold_foreign_item(&mut self, ni: ForeignItem) -> ForeignItem { |
1a4d82fc JJ |
58 | noop_fold_foreign_item(ni, self) |
59 | } | |
60 | ||
61 | fn fold_item(&mut self, i: P<Item>) -> SmallVector<P<Item>> { | |
62 | noop_fold_item(i, self) | |
63 | } | |
64 | ||
65 | fn fold_item_simple(&mut self, i: Item) -> Item { | |
66 | noop_fold_item_simple(i, self) | |
67 | } | |
68 | ||
69 | fn fold_struct_field(&mut self, sf: StructField) -> StructField { | |
70 | noop_fold_struct_field(sf, self) | |
71 | } | |
72 | ||
7453a54e SL |
73 | fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind { |
74 | noop_fold_item_kind(i, self) | |
1a4d82fc JJ |
75 | } |
76 | ||
7453a54e | 77 | fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> { |
85aaf69f SL |
78 | noop_fold_trait_item(i, self) |
79 | } | |
80 | ||
7453a54e | 81 | fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> { |
85aaf69f SL |
82 | noop_fold_impl_item(i, self) |
83 | } | |
84 | ||
1a4d82fc JJ |
85 | fn fold_fn_decl(&mut self, d: P<FnDecl>) -> P<FnDecl> { |
86 | noop_fold_fn_decl(d, self) | |
87 | } | |
88 | ||
1a4d82fc JJ |
89 | fn fold_block(&mut self, b: P<Block>) -> P<Block> { |
90 | noop_fold_block(b, self) | |
91 | } | |
92 | ||
7453a54e SL |
93 | fn fold_stmt(&mut self, s: Stmt) -> SmallVector<Stmt> { |
94 | noop_fold_stmt(s, self) | |
1a4d82fc JJ |
95 | } |
96 | ||
97 | fn fold_arm(&mut self, a: Arm) -> Arm { | |
98 | noop_fold_arm(a, self) | |
99 | } | |
100 | ||
101 | fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> { | |
102 | noop_fold_pat(p, self) | |
103 | } | |
104 | ||
105 | fn fold_decl(&mut self, d: P<Decl>) -> SmallVector<P<Decl>> { | |
106 | noop_fold_decl(d, self) | |
107 | } | |
108 | ||
109 | fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> { | |
110 | e.map(|e| noop_fold_expr(e, self)) | |
111 | } | |
112 | ||
92a42be0 SL |
113 | fn fold_opt_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { |
114 | noop_fold_opt_expr(e, self) | |
115 | } | |
116 | ||
117 | fn fold_exprs(&mut self, es: Vec<P<Expr>>) -> Vec<P<Expr>> { | |
118 | noop_fold_exprs(es, self) | |
119 | } | |
120 | ||
1a4d82fc JJ |
121 | fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> { |
122 | noop_fold_ty(t, self) | |
123 | } | |
124 | ||
7453a54e | 125 | fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding { |
1a4d82fc JJ |
126 | noop_fold_ty_binding(t, self) |
127 | } | |
128 | ||
129 | fn fold_mod(&mut self, m: Mod) -> Mod { | |
130 | noop_fold_mod(m, self) | |
131 | } | |
132 | ||
133 | fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod { | |
134 | noop_fold_foreign_mod(nm, self) | |
135 | } | |
136 | ||
7453a54e | 137 | fn fold_variant(&mut self, v: Variant) -> Variant { |
1a4d82fc JJ |
138 | noop_fold_variant(v, self) |
139 | } | |
140 | ||
141 | fn fold_ident(&mut self, i: Ident) -> Ident { | |
142 | noop_fold_ident(i, self) | |
143 | } | |
144 | ||
85aaf69f SL |
145 | fn fold_usize(&mut self, i: usize) -> usize { |
146 | noop_fold_usize(i, self) | |
1a4d82fc JJ |
147 | } |
148 | ||
149 | fn fold_path(&mut self, p: Path) -> Path { | |
150 | noop_fold_path(p, self) | |
151 | } | |
152 | ||
153 | fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters { | |
154 | noop_fold_path_parameters(p, self) | |
155 | } | |
156 | ||
157 | fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedParameterData) | |
158 | -> AngleBracketedParameterData | |
159 | { | |
160 | noop_fold_angle_bracketed_parameter_data(p, self) | |
161 | } | |
162 | ||
163 | fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedParameterData) | |
164 | -> ParenthesizedParameterData | |
165 | { | |
166 | noop_fold_parenthesized_parameter_data(p, self) | |
167 | } | |
168 | ||
169 | fn fold_local(&mut self, l: P<Local>) -> P<Local> { | |
170 | noop_fold_local(l, self) | |
171 | } | |
172 | ||
173 | fn fold_mac(&mut self, _mac: Mac) -> Mac { | |
174 | panic!("fold_mac disabled by default"); | |
175 | // NB: see note about macros above. | |
176 | // if you really want a folder that | |
177 | // works on macros, use this | |
178 | // definition in your trait impl: | |
179 | // fold::noop_fold_mac(_mac, self) | |
180 | } | |
181 | ||
182 | fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { | |
183 | noop_fold_explicit_self(es, self) | |
184 | } | |
185 | ||
7453a54e SL |
186 | fn fold_explicit_self_kind(&mut self, es: SelfKind) -> SelfKind { |
187 | noop_fold_explicit_self_kind(es, self) | |
1a4d82fc JJ |
188 | } |
189 | ||
190 | fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { | |
191 | noop_fold_lifetime(l, self) | |
192 | } | |
193 | ||
194 | fn fold_lifetime_def(&mut self, l: LifetimeDef) -> LifetimeDef { | |
195 | noop_fold_lifetime_def(l, self) | |
196 | } | |
197 | ||
85aaf69f | 198 | fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> { |
1a4d82fc JJ |
199 | noop_fold_attribute(at, self) |
200 | } | |
201 | ||
202 | fn fold_arg(&mut self, a: Arg) -> Arg { | |
203 | noop_fold_arg(a, self) | |
204 | } | |
205 | ||
206 | fn fold_generics(&mut self, generics: Generics) -> Generics { | |
207 | noop_fold_generics(generics, self) | |
208 | } | |
209 | ||
210 | fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef { | |
211 | noop_fold_trait_ref(p, self) | |
212 | } | |
213 | ||
214 | fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef { | |
215 | noop_fold_poly_trait_ref(p, self) | |
216 | } | |
217 | ||
b039eaaf SL |
218 | fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData { |
219 | noop_fold_variant_data(vdata, self) | |
1a4d82fc JJ |
220 | } |
221 | ||
222 | fn fold_lifetimes(&mut self, lts: Vec<Lifetime>) -> Vec<Lifetime> { | |
223 | noop_fold_lifetimes(lts, self) | |
224 | } | |
225 | ||
226 | fn fold_lifetime_defs(&mut self, lts: Vec<LifetimeDef>) -> Vec<LifetimeDef> { | |
227 | noop_fold_lifetime_defs(lts, self) | |
228 | } | |
229 | ||
230 | fn fold_ty_param(&mut self, tp: TyParam) -> TyParam { | |
231 | noop_fold_ty_param(tp, self) | |
232 | } | |
233 | ||
9cc50fc6 | 234 | fn fold_ty_params(&mut self, tps: P<[TyParam]>) -> P<[TyParam]> { |
1a4d82fc JJ |
235 | noop_fold_ty_params(tps, self) |
236 | } | |
237 | ||
238 | fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree { | |
239 | noop_fold_tt(tt, self) | |
240 | } | |
241 | ||
242 | fn fold_tts(&mut self, tts: &[TokenTree]) -> Vec<TokenTree> { | |
243 | noop_fold_tts(tts, self) | |
244 | } | |
245 | ||
246 | fn fold_token(&mut self, t: token::Token) -> token::Token { | |
247 | noop_fold_token(t, self) | |
248 | } | |
249 | ||
250 | fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal { | |
251 | noop_fold_interpolated(nt, self) | |
252 | } | |
253 | ||
254 | fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> { | |
255 | noop_fold_opt_lifetime(o_lt, self) | |
256 | } | |
257 | ||
9cc50fc6 SL |
258 | fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>) |
259 | -> Option<TyParamBounds> { | |
1a4d82fc JJ |
260 | noop_fold_opt_bounds(b, self) |
261 | } | |
262 | ||
9cc50fc6 SL |
263 | fn fold_bounds(&mut self, b: TyParamBounds) |
264 | -> TyParamBounds { | |
1a4d82fc JJ |
265 | noop_fold_bounds(b, self) |
266 | } | |
267 | ||
268 | fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound { | |
269 | noop_fold_ty_param_bound(tpb, self) | |
270 | } | |
271 | ||
272 | fn fold_mt(&mut self, mt: MutTy) -> MutTy { | |
273 | noop_fold_mt(mt, self) | |
274 | } | |
223e47cc | 275 | |
1a4d82fc JJ |
276 | fn fold_field(&mut self, field: Field) -> Field { |
277 | noop_fold_field(field, self) | |
278 | } | |
279 | ||
280 | fn fold_where_clause(&mut self, where_clause: WhereClause) | |
281 | -> WhereClause { | |
282 | noop_fold_where_clause(where_clause, self) | |
283 | } | |
284 | ||
285 | fn fold_where_predicate(&mut self, where_predicate: WherePredicate) | |
286 | -> WherePredicate { | |
287 | noop_fold_where_predicate(where_predicate, self) | |
288 | } | |
289 | ||
54a0048b SL |
290 | fn fold_vis(&mut self, vis: Visibility) -> Visibility { |
291 | noop_fold_vis(vis, self) | |
292 | } | |
293 | ||
1a4d82fc JJ |
294 | fn new_id(&mut self, i: NodeId) -> NodeId { |
295 | i | |
296 | } | |
297 | ||
298 | fn new_span(&mut self, sp: Span) -> Span { | |
299 | sp | |
300 | } | |
223e47cc LB |
301 | } |
302 | ||
1a4d82fc JJ |
303 | pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T) |
304 | -> Vec<P<MetaItem>> { | |
305 | meta_items.move_map(|x| fld.fold_meta_item(x)) | |
223e47cc LB |
306 | } |
307 | ||
1a4d82fc JJ |
308 | pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> { |
309 | view_path.map(|Spanned {node, span}| Spanned { | |
310 | node: match node { | |
85aaf69f SL |
311 | ViewPathSimple(ident, path) => { |
312 | ViewPathSimple(ident, fld.fold_path(path)) | |
1a4d82fc | 313 | } |
85aaf69f SL |
314 | ViewPathGlob(path) => { |
315 | ViewPathGlob(fld.fold_path(path)) | |
1a4d82fc | 316 | } |
85aaf69f | 317 | ViewPathList(path, path_list_idents) => { |
1a4d82fc JJ |
318 | ViewPathList(fld.fold_path(path), |
319 | path_list_idents.move_map(|path_list_ident| { | |
320 | Spanned { | |
321 | node: match path_list_ident.node { | |
7453a54e SL |
322 | PathListItemKind::Ident { id, name, rename } => |
323 | PathListItemKind::Ident { | |
1a4d82fc | 324 | id: fld.new_id(id), |
e9174d1e | 325 | rename: rename, |
1a4d82fc JJ |
326 | name: name |
327 | }, | |
7453a54e SL |
328 | PathListItemKind::Mod { id, rename } => |
329 | PathListItemKind::Mod { | |
e9174d1e SL |
330 | id: fld.new_id(id), |
331 | rename: rename | |
332 | } | |
1a4d82fc JJ |
333 | }, |
334 | span: fld.new_span(path_list_ident.span) | |
335 | } | |
85aaf69f | 336 | })) |
1a4d82fc JJ |
337 | } |
338 | }, | |
339 | span: fld.new_span(span) | |
340 | }) | |
223e47cc LB |
341 | } |
342 | ||
85aaf69f | 343 | pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> { |
92a42be0 SL |
344 | attrs.move_flat_map(|x| fld.fold_attribute(x)) |
345 | } | |
346 | ||
347 | pub fn fold_thin_attrs<T: Folder>(attrs: ThinAttributes, fld: &mut T) -> ThinAttributes { | |
348 | attrs.map_thin_attrs(|v| fold_attrs(v, fld)) | |
85aaf69f SL |
349 | } |
350 | ||
1a4d82fc JJ |
351 | pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm { |
352 | Arm { | |
85aaf69f | 353 | attrs: fold_attrs(attrs, fld), |
1a4d82fc JJ |
354 | pats: pats.move_map(|x| fld.fold_pat(x)), |
355 | guard: guard.map(|x| fld.fold_expr(x)), | |
356 | body: fld.fold_expr(body), | |
357 | } | |
223e47cc LB |
358 | } |
359 | ||
1a4d82fc JJ |
360 | pub fn noop_fold_decl<T: Folder>(d: P<Decl>, fld: &mut T) -> SmallVector<P<Decl>> { |
361 | d.and_then(|Spanned {node, span}| match node { | |
7453a54e SL |
362 | DeclKind::Local(l) => SmallVector::one(P(Spanned { |
363 | node: DeclKind::Local(fld.fold_local(l)), | |
1a4d82fc JJ |
364 | span: fld.new_span(span) |
365 | })), | |
7453a54e SL |
366 | DeclKind::Item(it) => fld.fold_item(it).into_iter().map(|i| P(Spanned { |
367 | node: DeclKind::Item(i), | |
1a4d82fc JJ |
368 | span: fld.new_span(span) |
369 | })).collect() | |
370 | }) | |
371 | } | |
223e47cc | 372 | |
7453a54e SL |
373 | pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding { |
374 | TypeBinding { | |
375 | id: fld.new_id(b.id), | |
376 | ident: b.ident, | |
377 | ty: fld.fold_ty(b.ty), | |
378 | span: fld.new_span(b.span), | |
379 | } | |
223e47cc LB |
380 | } |
381 | ||
1a4d82fc JJ |
382 | pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { |
383 | t.map(|Ty {id, node, span}| Ty { | |
384 | id: fld.new_id(id), | |
385 | node: match node { | |
7453a54e SL |
386 | TyKind::Infer => node, |
387 | TyKind::Vec(ty) => TyKind::Vec(fld.fold_ty(ty)), | |
388 | TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)), | |
389 | TyKind::Rptr(region, mt) => { | |
390 | TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) | |
1a4d82fc | 391 | } |
7453a54e SL |
392 | TyKind::BareFn(f) => { |
393 | TyKind::BareFn(f.map(|BareFnTy {lifetimes, unsafety, abi, decl}| BareFnTy { | |
1a4d82fc JJ |
394 | lifetimes: fld.fold_lifetime_defs(lifetimes), |
395 | unsafety: unsafety, | |
396 | abi: abi, | |
397 | decl: fld.fold_fn_decl(decl) | |
398 | })) | |
399 | } | |
7453a54e SL |
400 | TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))), |
401 | TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)), | |
402 | TyKind::Path(qself, path) => { | |
c34b1796 AL |
403 | let qself = qself.map(|QSelf { ty, position }| { |
404 | QSelf { | |
405 | ty: fld.fold_ty(ty), | |
406 | position: position | |
407 | } | |
408 | }); | |
7453a54e | 409 | TyKind::Path(qself, fld.fold_path(path)) |
1a4d82fc | 410 | } |
7453a54e SL |
411 | TyKind::ObjectSum(ty, bounds) => { |
412 | TyKind::ObjectSum(fld.fold_ty(ty), | |
1a4d82fc JJ |
413 | fld.fold_bounds(bounds)) |
414 | } | |
7453a54e SL |
415 | TyKind::FixedLengthVec(ty, e) => { |
416 | TyKind::FixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) | |
1a4d82fc | 417 | } |
7453a54e SL |
418 | TyKind::Typeof(expr) => { |
419 | TyKind::Typeof(fld.fold_expr(expr)) | |
1a4d82fc | 420 | } |
7453a54e SL |
421 | TyKind::PolyTraitRef(bounds) => { |
422 | TyKind::PolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b))) | |
1a4d82fc | 423 | } |
7453a54e SL |
424 | TyKind::Mac(mac) => { |
425 | TyKind::Mac(fld.fold_mac(mac)) | |
e9174d1e | 426 | } |
1a4d82fc JJ |
427 | }, |
428 | span: fld.new_span(span) | |
429 | }) | |
223e47cc LB |
430 | } |
431 | ||
85aaf69f | 432 | pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod, |
1a4d82fc JJ |
433 | fld: &mut T) -> ForeignMod { |
434 | ForeignMod { | |
435 | abi: abi, | |
1a4d82fc JJ |
436 | items: items.move_map(|x| fld.fold_foreign_item(x)), |
437 | } | |
438 | } | |
223e47cc | 439 | |
7453a54e SL |
440 | pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant { |
441 | Spanned { | |
1a4d82fc | 442 | node: Variant_ { |
7453a54e SL |
443 | name: v.node.name, |
444 | attrs: fold_attrs(v.node.attrs, fld), | |
445 | data: fld.fold_variant_data(v.node.data), | |
446 | disr_expr: v.node.disr_expr.map(|e| fld.fold_expr(e)), | |
1a4d82fc | 447 | }, |
7453a54e SL |
448 | span: fld.new_span(v.span), |
449 | } | |
1a4d82fc JJ |
450 | } |
451 | ||
452 | pub fn noop_fold_ident<T: Folder>(i: Ident, _: &mut T) -> Ident { | |
453 | i | |
454 | } | |
455 | ||
85aaf69f | 456 | pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize { |
1a4d82fc JJ |
457 | i |
458 | } | |
459 | ||
460 | pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut T) -> Path { | |
461 | Path { | |
462 | global: global, | |
463 | segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment { | |
464 | identifier: fld.fold_ident(identifier), | |
465 | parameters: fld.fold_path_parameters(parameters), | |
466 | }), | |
467 | span: fld.new_span(span) | |
223e47cc LB |
468 | } |
469 | } | |
470 | ||
1a4d82fc JJ |
471 | pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld: &mut T) |
472 | -> PathParameters | |
473 | { | |
474 | match path_parameters { | |
9cc50fc6 SL |
475 | PathParameters::AngleBracketed(data) => |
476 | PathParameters::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data)), | |
477 | PathParameters::Parenthesized(data) => | |
478 | PathParameters::Parenthesized(fld.fold_parenthesized_parameter_data(data)), | |
1a4d82fc JJ |
479 | } |
480 | } | |
223e47cc | 481 | |
1a4d82fc JJ |
482 | pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData, |
483 | fld: &mut T) | |
484 | -> AngleBracketedParameterData | |
485 | { | |
486 | let AngleBracketedParameterData { lifetimes, types, bindings } = data; | |
487 | AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes), | |
488 | types: types.move_map(|ty| fld.fold_ty(ty)), | |
489 | bindings: bindings.move_map(|b| fld.fold_ty_binding(b)) } | |
223e47cc LB |
490 | } |
491 | ||
1a4d82fc JJ |
492 | pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData, |
493 | fld: &mut T) | |
494 | -> ParenthesizedParameterData | |
495 | { | |
85aaf69f | 496 | let ParenthesizedParameterData { inputs, output, span } = data; |
1a4d82fc | 497 | ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)), |
85aaf69f SL |
498 | output: output.map(|ty| fld.fold_ty(ty)), |
499 | span: fld.new_span(span) } | |
1a4d82fc | 500 | } |
970d7e83 | 501 | |
1a4d82fc | 502 | pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { |
92a42be0 | 503 | l.map(|Local {id, pat, ty, init, span, attrs}| Local { |
1a4d82fc JJ |
504 | id: fld.new_id(id), |
505 | ty: ty.map(|t| fld.fold_ty(t)), | |
506 | pat: fld.fold_pat(pat), | |
507 | init: init.map(|e| fld.fold_expr(e)), | |
92a42be0 SL |
508 | span: fld.new_span(span), |
509 | attrs: attrs.map_thin_attrs(|v| fold_attrs(v, fld)), | |
1a4d82fc | 510 | }) |
223e47cc LB |
511 | } |
512 | ||
85aaf69f | 513 | pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> { |
1a4d82fc | 514 | let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at; |
85aaf69f | 515 | Some(Spanned { |
1a4d82fc JJ |
516 | node: Attribute_ { |
517 | id: id, | |
518 | style: style, | |
519 | value: fld.fold_meta_item(value), | |
520 | is_sugared_doc: is_sugared_doc | |
521 | }, | |
522 | span: fld.new_span(span) | |
85aaf69f | 523 | }) |
1a4d82fc JJ |
524 | } |
525 | ||
7453a54e SL |
526 | pub fn noop_fold_explicit_self_kind<T: Folder>(es: SelfKind, fld: &mut T) |
527 | -> SelfKind { | |
1a4d82fc | 528 | match es { |
7453a54e SL |
529 | SelfKind::Static | SelfKind::Value(_) => es, |
530 | SelfKind::Region(lifetime, m, ident) => { | |
531 | SelfKind::Region(fld.fold_opt_lifetime(lifetime), m, ident) | |
223e47cc | 532 | } |
7453a54e SL |
533 | SelfKind::Explicit(typ, ident) => { |
534 | SelfKind::Explicit(fld.fold_ty(typ), ident) | |
223e47cc LB |
535 | } |
536 | } | |
537 | } | |
538 | ||
1a4d82fc JJ |
539 | pub fn noop_fold_explicit_self<T: Folder>(Spanned {span, node}: ExplicitSelf, fld: &mut T) |
540 | -> ExplicitSelf { | |
541 | Spanned { | |
7453a54e | 542 | node: fld.fold_explicit_self_kind(node), |
1a4d82fc | 543 | span: fld.new_span(span) |
223e47cc LB |
544 | } |
545 | } | |
546 | ||
1a4d82fc JJ |
547 | |
548 | pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac { | |
549 | Spanned { | |
b039eaaf SL |
550 | node: Mac_ { |
551 | path: fld.fold_path(node.path), | |
552 | tts: fld.fold_tts(&node.tts), | |
553 | ctxt: node.ctxt, | |
1a4d82fc JJ |
554 | }, |
555 | span: fld.new_span(span) | |
223e47cc LB |
556 | } |
557 | } | |
558 | ||
1a4d82fc JJ |
559 | pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> { |
560 | mi.map(|Spanned {node, span}| Spanned { | |
561 | node: match node { | |
7453a54e SL |
562 | MetaItemKind::Word(id) => MetaItemKind::Word(id), |
563 | MetaItemKind::List(id, mis) => { | |
564 | MetaItemKind::List(id, mis.move_map(|e| fld.fold_meta_item(e))) | |
1a4d82fc | 565 | } |
7453a54e | 566 | MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s) |
223e47cc | 567 | }, |
1a4d82fc JJ |
568 | span: fld.new_span(span) |
569 | }) | |
223e47cc LB |
570 | } |
571 | ||
1a4d82fc JJ |
572 | pub fn noop_fold_arg<T: Folder>(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg { |
573 | Arg { | |
574 | id: fld.new_id(id), | |
575 | pat: fld.fold_pat(pat), | |
576 | ty: fld.fold_ty(ty) | |
223e47cc LB |
577 | } |
578 | } | |
579 | ||
1a4d82fc JJ |
580 | pub fn noop_fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree { |
581 | match *tt { | |
92a42be0 SL |
582 | TokenTree::Token(span, ref tok) => |
583 | TokenTree::Token(span, fld.fold_token(tok.clone())), | |
584 | TokenTree::Delimited(span, ref delimed) => { | |
585 | TokenTree::Delimited(span, Rc::new( | |
1a4d82fc JJ |
586 | Delimited { |
587 | delim: delimed.delim, | |
588 | open_span: delimed.open_span, | |
85aaf69f | 589 | tts: fld.fold_tts(&delimed.tts), |
1a4d82fc JJ |
590 | close_span: delimed.close_span, |
591 | } | |
592 | )) | |
593 | }, | |
92a42be0 SL |
594 | TokenTree::Sequence(span, ref seq) => |
595 | TokenTree::Sequence(span, | |
1a4d82fc | 596 | Rc::new(SequenceRepetition { |
85aaf69f | 597 | tts: fld.fold_tts(&seq.tts), |
1a4d82fc JJ |
598 | separator: seq.separator.clone().map(|tok| fld.fold_token(tok)), |
599 | ..**seq | |
600 | })), | |
223e47cc LB |
601 | } |
602 | } | |
603 | ||
1a4d82fc | 604 | pub fn noop_fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> { |
92a42be0 SL |
605 | // FIXME: Does this have to take a tts slice? |
606 | // Could use move_map otherwise... | |
1a4d82fc JJ |
607 | tts.iter().map(|tt| fld.fold_tt(tt)).collect() |
608 | } | |
609 | ||
610 | // apply ident folder if it's an ident, apply other folds to interpolated nodes | |
611 | pub fn noop_fold_token<T: Folder>(t: token::Token, fld: &mut T) -> token::Token { | |
612 | match t { | |
613 | token::Ident(id, followed_by_colons) => { | |
614 | token::Ident(fld.fold_ident(id), followed_by_colons) | |
970d7e83 | 615 | } |
1a4d82fc JJ |
616 | token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)), |
617 | token::Interpolated(nt) => token::Interpolated(fld.fold_interpolated(nt)), | |
618 | token::SubstNt(ident, namep) => { | |
619 | token::SubstNt(fld.fold_ident(ident), namep) | |
970d7e83 | 620 | } |
1a4d82fc JJ |
621 | token::MatchNt(name, kind, namep, kindp) => { |
622 | token::MatchNt(fld.fold_ident(name), fld.fold_ident(kind), namep, kindp) | |
970d7e83 | 623 | } |
1a4d82fc | 624 | _ => t |
223e47cc LB |
625 | } |
626 | } | |
627 | ||
1a4d82fc JJ |
628 | /// apply folder to elements of interpolated nodes |
629 | // | |
630 | // NB: this can occur only when applying a fold to partially expanded code, where | |
631 | // parsed pieces have gotten implanted ito *other* macro invocations. This is relevant | |
632 | // for macro hygiene, but possibly not elsewhere. | |
633 | // | |
634 | // One problem here occurs because the types for fold_item, fold_stmt, etc. allow the | |
635 | // folder to return *multiple* items; this is a problem for the nodes here, because | |
636 | // they insist on having exactly one piece. One solution would be to mangle the fold | |
637 | // trait to include one-to-many and one-to-one versions of these entry points, but that | |
638 | // would probably confuse a lot of people and help very few. Instead, I'm just going | |
639 | // to put in dynamic checks. I think the performance impact of this will be pretty much | |
640 | // nonexistent. The danger is that someone will apply a fold to a partially expanded | |
641 | // node, and will be confused by the fact that their "fold_item" or "fold_stmt" isn't | |
642 | // getting called on NtItem or NtStmt nodes. Hopefully they'll wind up reading this | |
643 | // comment, and doing something appropriate. | |
644 | // | |
645 | // BTW, design choice: I considered just changing the type of, e.g., NtItem to contain | |
646 | // multiple items, but decided against it when I looked at parse_item_or_view_item and | |
647 | // tried to figure out what I would do with multiple items there.... | |
648 | pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T) | |
649 | -> token::Nonterminal { | |
650 | match nt { | |
651 | token::NtItem(item) => | |
652 | token::NtItem(fld.fold_item(item) | |
653 | // this is probably okay, because the only folds likely | |
654 | // to peek inside interpolated nodes will be renamings/markings, | |
655 | // which map single items to single items | |
656 | .expect_one("expected fold to produce exactly one item")), | |
657 | token::NtBlock(block) => token::NtBlock(fld.fold_block(block)), | |
658 | token::NtStmt(stmt) => | |
7453a54e | 659 | token::NtStmt(stmt.map(|stmt| fld.fold_stmt(stmt) |
1a4d82fc JJ |
660 | // this is probably okay, because the only folds likely |
661 | // to peek inside interpolated nodes will be renamings/markings, | |
662 | // which map single items to single items | |
7453a54e | 663 | .expect_one("expected fold to produce exactly one statement"))), |
1a4d82fc JJ |
664 | token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), |
665 | token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), | |
666 | token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), | |
d9579d0f | 667 | token::NtIdent(id, is_mod_name) => |
9cc50fc6 SL |
668 | token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), .. *id}), |
669 | is_mod_name), | |
1a4d82fc | 670 | token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)), |
d9579d0f | 671 | token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))), |
92a42be0 | 672 | token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))), |
d9579d0f AL |
673 | token::NtArm(arm) => token::NtArm(fld.fold_arm(arm)), |
674 | token::NtImplItem(arm) => | |
7453a54e SL |
675 | token::NtImplItem(arm.map(|arm| fld.fold_impl_item(arm) |
676 | .expect_one("expected fold to produce exactly one item"))), | |
d9579d0f | 677 | token::NtTraitItem(arm) => |
7453a54e SL |
678 | token::NtTraitItem(arm.map(|arm| fld.fold_trait_item(arm) |
679 | .expect_one("expected fold to produce exactly one item"))), | |
d9579d0f AL |
680 | token::NtGenerics(generics) => token::NtGenerics(fld.fold_generics(generics)), |
681 | token::NtWhereClause(where_clause) => | |
682 | token::NtWhereClause(fld.fold_where_clause(where_clause)), | |
92a42be0 | 683 | token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)), |
223e47cc LB |
684 | } |
685 | } | |
686 | ||
1a4d82fc JJ |
687 | pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> { |
688 | decl.map(|FnDecl {inputs, output, variadic}| FnDecl { | |
689 | inputs: inputs.move_map(|x| fld.fold_arg(x)), | |
690 | output: match output { | |
7453a54e SL |
691 | FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(fld.fold_ty(ty)), |
692 | FunctionRetTy::Default(span) => FunctionRetTy::Default(span), | |
693 | FunctionRetTy::None(span) => FunctionRetTy::None(span), | |
223e47cc | 694 | }, |
1a4d82fc JJ |
695 | variadic: variadic |
696 | }) | |
697 | } | |
698 | ||
699 | pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) | |
700 | -> TyParamBound | |
701 | where T: Folder { | |
702 | match tpb { | |
703 | TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier), | |
704 | RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), | |
223e47cc LB |
705 | } |
706 | } | |
707 | ||
1a4d82fc JJ |
708 | pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam { |
709 | let TyParam {id, ident, bounds, default, span} = tp; | |
710 | TyParam { | |
711 | id: fld.new_id(id), | |
712 | ident: ident, | |
713 | bounds: fld.fold_bounds(bounds), | |
714 | default: default.map(|x| fld.fold_ty(x)), | |
715 | span: span | |
223e47cc LB |
716 | } |
717 | } | |
718 | ||
9cc50fc6 SL |
719 | pub fn noop_fold_ty_params<T: Folder>(tps: P<[TyParam]>, fld: &mut T) |
720 | -> P<[TyParam]> { | |
1a4d82fc | 721 | tps.move_map(|tp| fld.fold_ty_param(tp)) |
223e47cc LB |
722 | } |
723 | ||
1a4d82fc JJ |
724 | pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime { |
725 | Lifetime { | |
726 | id: fld.new_id(l.id), | |
727 | name: l.name, | |
728 | span: fld.new_span(l.span) | |
223e47cc | 729 | } |
1a4d82fc | 730 | } |
223e47cc | 731 | |
1a4d82fc JJ |
732 | pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T) |
733 | -> LifetimeDef { | |
734 | LifetimeDef { | |
735 | lifetime: fld.fold_lifetime(l.lifetime), | |
736 | bounds: fld.fold_lifetimes(l.bounds), | |
223e47cc LB |
737 | } |
738 | } | |
739 | ||
1a4d82fc JJ |
740 | pub fn noop_fold_lifetimes<T: Folder>(lts: Vec<Lifetime>, fld: &mut T) -> Vec<Lifetime> { |
741 | lts.move_map(|l| fld.fold_lifetime(l)) | |
742 | } | |
743 | ||
744 | pub fn noop_fold_lifetime_defs<T: Folder>(lts: Vec<LifetimeDef>, fld: &mut T) | |
745 | -> Vec<LifetimeDef> { | |
746 | lts.move_map(|l| fld.fold_lifetime_def(l)) | |
747 | } | |
748 | ||
749 | pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: Option<Lifetime>, fld: &mut T) | |
750 | -> Option<Lifetime> { | |
751 | o_lt.map(|lt| fld.fold_lifetime(lt)) | |
752 | } | |
753 | ||
754 | pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause}: Generics, | |
755 | fld: &mut T) -> Generics { | |
756 | Generics { | |
757 | ty_params: fld.fold_ty_params(ty_params), | |
758 | lifetimes: fld.fold_lifetime_defs(lifetimes), | |
759 | where_clause: fld.fold_where_clause(where_clause), | |
223e47cc | 760 | } |
1a4d82fc JJ |
761 | } |
762 | ||
763 | pub fn noop_fold_where_clause<T: Folder>( | |
764 | WhereClause {id, predicates}: WhereClause, | |
765 | fld: &mut T) | |
766 | -> WhereClause { | |
767 | WhereClause { | |
768 | id: fld.new_id(id), | |
769 | predicates: predicates.move_map(|predicate| { | |
770 | fld.fold_where_predicate(predicate) | |
771 | }) | |
970d7e83 | 772 | } |
1a4d82fc JJ |
773 | } |
774 | ||
775 | pub fn noop_fold_where_predicate<T: Folder>( | |
776 | pred: WherePredicate, | |
777 | fld: &mut T) | |
778 | -> WherePredicate { | |
779 | match pred { | |
85aaf69f SL |
780 | ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_lifetimes, |
781 | bounded_ty, | |
1a4d82fc JJ |
782 | bounds, |
783 | span}) => { | |
784 | ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { | |
85aaf69f | 785 | bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes), |
1a4d82fc JJ |
786 | bounded_ty: fld.fold_ty(bounded_ty), |
787 | bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)), | |
788 | span: fld.new_span(span) | |
223e47cc LB |
789 | }) |
790 | } | |
1a4d82fc JJ |
791 | ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{lifetime, |
792 | bounds, | |
793 | span}) => { | |
794 | ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { | |
795 | span: fld.new_span(span), | |
796 | lifetime: fld.fold_lifetime(lifetime), | |
797 | bounds: bounds.move_map(|bound| fld.fold_lifetime(bound)) | |
223e47cc LB |
798 | }) |
799 | } | |
1a4d82fc JJ |
800 | ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id, |
801 | path, | |
802 | ty, | |
803 | span}) => { | |
804 | ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ | |
805 | id: fld.new_id(id), | |
806 | path: fld.fold_path(path), | |
807 | ty:fld.fold_ty(ty), | |
808 | span: fld.new_span(span) | |
809 | }) | |
223e47cc | 810 | } |
223e47cc LB |
811 | } |
812 | } | |
813 | ||
b039eaaf SL |
814 | pub fn noop_fold_variant_data<T: Folder>(vdata: VariantData, fld: &mut T) -> VariantData { |
815 | match vdata { | |
816 | ast::VariantData::Struct(fields, id) => { | |
817 | ast::VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), | |
818 | fld.new_id(id)) | |
819 | } | |
820 | ast::VariantData::Tuple(fields, id) => { | |
821 | ast::VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), | |
822 | fld.new_id(id)) | |
823 | } | |
824 | ast::VariantData::Unit(id) => ast::VariantData::Unit(fld.new_id(id)) | |
825 | } | |
1a4d82fc JJ |
826 | } |
827 | ||
828 | pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef { | |
829 | let id = fld.new_id(p.ref_id); | |
830 | let TraitRef { | |
831 | path, | |
832 | ref_id: _, | |
833 | } = p; | |
834 | ast::TraitRef { | |
835 | path: fld.fold_path(path), | |
836 | ref_id: id, | |
223e47cc | 837 | } |
1a4d82fc | 838 | } |
223e47cc | 839 | |
1a4d82fc JJ |
840 | pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { |
841 | ast::PolyTraitRef { | |
842 | bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes), | |
85aaf69f SL |
843 | trait_ref: fld.fold_trait_ref(p.trait_ref), |
844 | span: fld.new_span(p.span), | |
1a4d82fc JJ |
845 | } |
846 | } | |
847 | ||
848 | pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField { | |
54a0048b SL |
849 | StructField { |
850 | span: fld.new_span(f.span), | |
851 | id: fld.new_id(f.id), | |
852 | ident: f.ident.map(|ident| fld.fold_ident(ident)), | |
853 | vis: f.vis, | |
854 | ty: fld.fold_ty(f.ty), | |
855 | attrs: fold_attrs(f.attrs, fld), | |
223e47cc | 856 | } |
1a4d82fc | 857 | } |
223e47cc | 858 | |
1a4d82fc JJ |
859 | pub fn noop_fold_field<T: Folder>(Field {ident, expr, span}: Field, folder: &mut T) -> Field { |
860 | Field { | |
861 | ident: respan(ident.span, folder.fold_ident(ident.node)), | |
862 | expr: folder.fold_expr(expr), | |
863 | span: folder.new_span(span) | |
864 | } | |
865 | } | |
223e47cc | 866 | |
1a4d82fc JJ |
867 | pub fn noop_fold_mt<T: Folder>(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutTy { |
868 | MutTy { | |
869 | ty: folder.fold_ty(ty), | |
870 | mutbl: mutbl, | |
223e47cc LB |
871 | } |
872 | } | |
873 | ||
9cc50fc6 SL |
874 | pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, folder: &mut T) |
875 | -> Option<TyParamBounds> { | |
1a4d82fc JJ |
876 | b.map(|bounds| folder.fold_bounds(bounds)) |
877 | } | |
878 | ||
879 | fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T) | |
880 | -> TyParamBounds { | |
881 | bounds.move_map(|bound| folder.fold_ty_param_bound(bound)) | |
223e47cc LB |
882 | } |
883 | ||
1a4d82fc | 884 | pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> { |
85aaf69f | 885 | b.map(|Block {id, stmts, expr, rules, span}| Block { |
1a4d82fc | 886 | id: folder.new_id(id), |
92a42be0 SL |
887 | stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()), |
888 | expr: expr.and_then(|x| folder.fold_opt_expr(x)), | |
1a4d82fc JJ |
889 | rules: rules, |
890 | span: folder.new_span(span), | |
891 | }) | |
892 | } | |
893 | ||
7453a54e | 894 | pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind { |
1a4d82fc | 895 | match i { |
7453a54e SL |
896 | ItemKind::ExternCrate(string) => ItemKind::ExternCrate(string), |
897 | ItemKind::Use(view_path) => { | |
898 | ItemKind::Use(folder.fold_view_path(view_path)) | |
85aaf69f | 899 | } |
7453a54e SL |
900 | ItemKind::Static(t, m, e) => { |
901 | ItemKind::Static(folder.fold_ty(t), m, folder.fold_expr(e)) | |
223e47cc | 902 | } |
7453a54e SL |
903 | ItemKind::Const(t, e) => { |
904 | ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e)) | |
223e47cc | 905 | } |
7453a54e SL |
906 | ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => { |
907 | ItemKind::Fn( | |
1a4d82fc JJ |
908 | folder.fold_fn_decl(decl), |
909 | unsafety, | |
62682a34 | 910 | constness, |
1a4d82fc JJ |
911 | abi, |
912 | folder.fold_generics(generics), | |
913 | folder.fold_block(body) | |
914 | ) | |
970d7e83 | 915 | } |
7453a54e SL |
916 | ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), |
917 | ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), | |
918 | ItemKind::Ty(t, generics) => { | |
919 | ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) | |
223e47cc | 920 | } |
7453a54e SL |
921 | ItemKind::Enum(enum_definition, generics) => { |
922 | ItemKind::Enum( | |
1a4d82fc JJ |
923 | ast::EnumDef { |
924 | variants: enum_definition.variants.move_map(|x| folder.fold_variant(x)), | |
925 | }, | |
926 | folder.fold_generics(generics)) | |
970d7e83 | 927 | } |
7453a54e | 928 | ItemKind::Struct(struct_def, generics) => { |
b039eaaf | 929 | let struct_def = folder.fold_variant_data(struct_def); |
7453a54e | 930 | ItemKind::Struct(struct_def, folder.fold_generics(generics)) |
223e47cc | 931 | } |
7453a54e SL |
932 | ItemKind::DefaultImpl(unsafety, ref trait_ref) => { |
933 | ItemKind::DefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone())) | |
c34b1796 | 934 | } |
7453a54e | 935 | ItemKind::Impl(unsafety, polarity, generics, ifce, ty, impl_items) => { |
92a42be0 SL |
936 | let new_impl_items = impl_items.move_flat_map(|item| { |
937 | folder.fold_impl_item(item) | |
938 | }); | |
1a4d82fc JJ |
939 | let ifce = match ifce { |
940 | None => None, | |
941 | Some(ref trait_ref) => { | |
942 | Some(folder.fold_trait_ref((*trait_ref).clone())) | |
943 | } | |
944 | }; | |
7453a54e | 945 | ItemKind::Impl(unsafety, |
1a4d82fc JJ |
946 | polarity, |
947 | folder.fold_generics(generics), | |
948 | ifce, | |
949 | folder.fold_ty(ty), | |
950 | new_impl_items) | |
223e47cc | 951 | } |
7453a54e | 952 | ItemKind::Trait(unsafety, generics, bounds, items) => { |
1a4d82fc | 953 | let bounds = folder.fold_bounds(bounds); |
92a42be0 SL |
954 | let items = items.move_flat_map(|item| { |
955 | folder.fold_trait_item(item) | |
956 | }); | |
7453a54e | 957 | ItemKind::Trait(unsafety, |
1a4d82fc JJ |
958 | folder.fold_generics(generics), |
959 | bounds, | |
85aaf69f | 960 | items) |
1a4d82fc | 961 | } |
7453a54e | 962 | ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)), |
223e47cc | 963 | } |
1a4d82fc JJ |
964 | } |
965 | ||
7453a54e SL |
966 | pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T) |
967 | -> SmallVector<TraitItem> { | |
968 | SmallVector::one(TraitItem { | |
969 | id: folder.new_id(i.id), | |
970 | ident: folder.fold_ident(i.ident), | |
971 | attrs: fold_attrs(i.attrs, folder), | |
972 | node: match i.node { | |
973 | TraitItemKind::Const(ty, default) => { | |
974 | TraitItemKind::Const(folder.fold_ty(ty), | |
d9579d0f AL |
975 | default.map(|x| folder.fold_expr(x))) |
976 | } | |
7453a54e SL |
977 | TraitItemKind::Method(sig, body) => { |
978 | TraitItemKind::Method(noop_fold_method_sig(sig, folder), | |
c34b1796 AL |
979 | body.map(|x| folder.fold_block(x))) |
980 | } | |
7453a54e SL |
981 | TraitItemKind::Type(bounds, default) => { |
982 | TraitItemKind::Type(folder.fold_bounds(bounds), | |
c34b1796 AL |
983 | default.map(|x| folder.fold_ty(x))) |
984 | } | |
985 | }, | |
7453a54e SL |
986 | span: folder.new_span(i.span) |
987 | }) | |
85aaf69f SL |
988 | } |
989 | ||
7453a54e SL |
990 | pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) |
991 | -> SmallVector<ImplItem> { | |
992 | SmallVector::one(ImplItem { | |
993 | id: folder.new_id(i.id), | |
994 | ident: folder.fold_ident(i.ident), | |
995 | attrs: fold_attrs(i.attrs, folder), | |
54a0048b SL |
996 | vis: folder.fold_vis(i.vis), |
997 | defaultness: i.defaultness, | |
7453a54e | 998 | node: match i.node { |
92a42be0 SL |
999 | ast::ImplItemKind::Const(ty, expr) => { |
1000 | ast::ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) | |
d9579d0f | 1001 | } |
92a42be0 SL |
1002 | ast::ImplItemKind::Method(sig, body) => { |
1003 | ast::ImplItemKind::Method(noop_fold_method_sig(sig, folder), | |
c34b1796 AL |
1004 | folder.fold_block(body)) |
1005 | } | |
92a42be0 SL |
1006 | ast::ImplItemKind::Type(ty) => ast::ImplItemKind::Type(folder.fold_ty(ty)), |
1007 | ast::ImplItemKind::Macro(mac) => ast::ImplItemKind::Macro(folder.fold_mac(mac)) | |
c34b1796 | 1008 | }, |
7453a54e SL |
1009 | span: folder.new_span(i.span) |
1010 | }) | |
1a4d82fc JJ |
1011 | } |
1012 | ||
85aaf69f | 1013 | pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod { |
1a4d82fc JJ |
1014 | Mod { |
1015 | inner: folder.new_span(inner), | |
92a42be0 | 1016 | items: items.move_flat_map(|x| folder.fold_item(x)), |
223e47cc | 1017 | } |
1a4d82fc JJ |
1018 | } |
1019 | ||
1020 | pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_macros, span}: Crate, | |
1021 | folder: &mut T) -> Crate { | |
1022 | let config = folder.fold_meta_items(config); | |
1023 | ||
1024 | let mut items = folder.fold_item(P(ast::Item { | |
1025 | ident: token::special_idents::invalid, | |
1026 | attrs: attrs, | |
1027 | id: ast::DUMMY_NODE_ID, | |
7453a54e | 1028 | vis: ast::Visibility::Public, |
1a4d82fc | 1029 | span: span, |
7453a54e | 1030 | node: ast::ItemKind::Mod(module), |
1a4d82fc JJ |
1031 | })).into_iter(); |
1032 | ||
1033 | let (module, attrs, span) = match items.next() { | |
1034 | Some(item) => { | |
1035 | assert!(items.next().is_none(), | |
1036 | "a crate cannot expand to more than one item"); | |
1037 | item.and_then(|ast::Item { attrs, span, node, .. }| { | |
1038 | match node { | |
7453a54e | 1039 | ast::ItemKind::Mod(m) => (m, attrs, span), |
1a4d82fc JJ |
1040 | _ => panic!("fold converted a module to not a module"), |
1041 | } | |
1042 | }) | |
1043 | } | |
1044 | None => (ast::Mod { | |
1045 | inner: span, | |
85aaf69f SL |
1046 | items: vec![], |
1047 | }, vec![], span) | |
1a4d82fc JJ |
1048 | }; |
1049 | ||
85aaf69f | 1050 | for def in &mut exported_macros { |
1a4d82fc | 1051 | def.id = folder.new_id(def.id); |
223e47cc | 1052 | } |
1a4d82fc JJ |
1053 | |
1054 | Crate { | |
1055 | module: module, | |
1056 | attrs: attrs, | |
1057 | config: config, | |
1058 | exported_macros: exported_macros, | |
1059 | span: span, | |
223e47cc | 1060 | } |
1a4d82fc JJ |
1061 | } |
1062 | ||
1063 | // fold one item into possibly many items | |
1064 | pub fn noop_fold_item<T: Folder>(i: P<Item>, folder: &mut T) -> SmallVector<P<Item>> { | |
1065 | SmallVector::one(i.map(|i| folder.fold_item_simple(i))) | |
1066 | } | |
1067 | ||
1068 | // fold one item into exactly one item | |
1069 | pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}: Item, | |
1070 | folder: &mut T) -> Item { | |
1071 | let id = folder.new_id(id); | |
7453a54e | 1072 | let node = folder.fold_item_kind(node); |
1a4d82fc JJ |
1073 | |
1074 | Item { | |
1075 | id: id, | |
1076 | ident: folder.fold_ident(ident), | |
85aaf69f | 1077 | attrs: fold_attrs(attrs, folder), |
1a4d82fc | 1078 | node: node, |
54a0048b | 1079 | vis: folder.fold_vis(vis), |
1a4d82fc | 1080 | span: folder.new_span(span) |
223e47cc LB |
1081 | } |
1082 | } | |
1083 | ||
7453a54e SL |
1084 | pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> ForeignItem { |
1085 | ForeignItem { | |
1086 | id: folder.new_id(ni.id), | |
1087 | ident: folder.fold_ident(ni.ident), | |
1088 | attrs: fold_attrs(ni.attrs, folder), | |
1089 | node: match ni.node { | |
1090 | ForeignItemKind::Fn(fdec, generics) => { | |
1091 | ForeignItemKind::Fn(folder.fold_fn_decl(fdec), folder.fold_generics(generics)) | |
1a4d82fc | 1092 | } |
7453a54e SL |
1093 | ForeignItemKind::Static(t, m) => { |
1094 | ForeignItemKind::Static(folder.fold_ty(t), m) | |
1a4d82fc JJ |
1095 | } |
1096 | }, | |
54a0048b | 1097 | vis: folder.fold_vis(ni.vis), |
7453a54e SL |
1098 | span: folder.new_span(ni.span) |
1099 | } | |
1a4d82fc JJ |
1100 | } |
1101 | ||
c34b1796 AL |
1102 | pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { |
1103 | MethodSig { | |
1104 | generics: folder.fold_generics(sig.generics), | |
1105 | abi: sig.abi, | |
1106 | explicit_self: folder.fold_explicit_self(sig.explicit_self), | |
1107 | unsafety: sig.unsafety, | |
62682a34 | 1108 | constness: sig.constness, |
c34b1796 AL |
1109 | decl: folder.fold_fn_decl(sig.decl) |
1110 | } | |
970d7e83 LB |
1111 | } |
1112 | ||
1a4d82fc JJ |
1113 | pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { |
1114 | p.map(|Pat {id, node, span}| Pat { | |
1115 | id: folder.new_id(id), | |
1116 | node: match node { | |
7453a54e SL |
1117 | PatKind::Wild => PatKind::Wild, |
1118 | PatKind::Ident(binding_mode, pth1, sub) => { | |
1119 | PatKind::Ident(binding_mode, | |
1a4d82fc JJ |
1120 | Spanned{span: folder.new_span(pth1.span), |
1121 | node: folder.fold_ident(pth1.node)}, | |
1122 | sub.map(|x| folder.fold_pat(x))) | |
1123 | } | |
7453a54e SL |
1124 | PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), |
1125 | PatKind::TupleStruct(pth, pats) => { | |
1126 | PatKind::TupleStruct(folder.fold_path(pth), | |
1a4d82fc JJ |
1127 | pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) |
1128 | } | |
7453a54e SL |
1129 | PatKind::Path(pth) => { |
1130 | PatKind::Path(folder.fold_path(pth)) | |
1131 | } | |
1132 | PatKind::QPath(qself, pth) => { | |
d9579d0f | 1133 | let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself}; |
7453a54e | 1134 | PatKind::QPath(qself, folder.fold_path(pth)) |
d9579d0f | 1135 | } |
7453a54e | 1136 | PatKind::Struct(pth, fields, etc) => { |
1a4d82fc JJ |
1137 | let pth = folder.fold_path(pth); |
1138 | let fs = fields.move_map(|f| { | |
1139 | Spanned { span: folder.new_span(f.span), | |
1140 | node: ast::FieldPat { | |
1141 | ident: f.node.ident, | |
1142 | pat: folder.fold_pat(f.node.pat), | |
1143 | is_shorthand: f.node.is_shorthand, | |
1144 | }} | |
1145 | }); | |
7453a54e | 1146 | PatKind::Struct(pth, fs, etc) |
1a4d82fc | 1147 | } |
7453a54e SL |
1148 | PatKind::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))), |
1149 | PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), | |
1150 | PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), | |
1151 | PatKind::Range(e1, e2) => { | |
1152 | PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2)) | |
1a4d82fc | 1153 | }, |
7453a54e SL |
1154 | PatKind::Vec(before, slice, after) => { |
1155 | PatKind::Vec(before.move_map(|x| folder.fold_pat(x)), | |
1a4d82fc JJ |
1156 | slice.map(|x| folder.fold_pat(x)), |
1157 | after.move_map(|x| folder.fold_pat(x))) | |
1158 | } | |
7453a54e | 1159 | PatKind::Mac(mac) => PatKind::Mac(folder.fold_mac(mac)) |
1a4d82fc JJ |
1160 | }, |
1161 | span: folder.new_span(span) | |
1162 | }) | |
1163 | } | |
1164 | ||
92a42be0 | 1165 | pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr { |
1a4d82fc JJ |
1166 | Expr { |
1167 | id: folder.new_id(id), | |
1168 | node: match node { | |
7453a54e SL |
1169 | ExprKind::Box(e) => { |
1170 | ExprKind::Box(folder.fold_expr(e)) | |
b039eaaf | 1171 | } |
7453a54e SL |
1172 | ExprKind::InPlace(p, e) => { |
1173 | ExprKind::InPlace(folder.fold_expr(p), folder.fold_expr(e)) | |
1a4d82fc | 1174 | } |
7453a54e SL |
1175 | ExprKind::Vec(exprs) => { |
1176 | ExprKind::Vec(folder.fold_exprs(exprs)) | |
1a4d82fc | 1177 | } |
7453a54e SL |
1178 | ExprKind::Repeat(expr, count) => { |
1179 | ExprKind::Repeat(folder.fold_expr(expr), folder.fold_expr(count)) | |
1a4d82fc | 1180 | } |
7453a54e SL |
1181 | ExprKind::Tup(exprs) => ExprKind::Tup(folder.fold_exprs(exprs)), |
1182 | ExprKind::Call(f, args) => { | |
1183 | ExprKind::Call(folder.fold_expr(f), | |
92a42be0 | 1184 | folder.fold_exprs(args)) |
1a4d82fc | 1185 | } |
7453a54e SL |
1186 | ExprKind::MethodCall(i, tps, args) => { |
1187 | ExprKind::MethodCall( | |
9346a6ac | 1188 | respan(folder.new_span(i.span), folder.fold_ident(i.node)), |
1a4d82fc | 1189 | tps.move_map(|x| folder.fold_ty(x)), |
92a42be0 | 1190 | folder.fold_exprs(args)) |
1a4d82fc | 1191 | } |
7453a54e SL |
1192 | ExprKind::Binary(binop, lhs, rhs) => { |
1193 | ExprKind::Binary(binop, | |
1a4d82fc JJ |
1194 | folder.fold_expr(lhs), |
1195 | folder.fold_expr(rhs)) | |
1196 | } | |
7453a54e SL |
1197 | ExprKind::Unary(binop, ohs) => { |
1198 | ExprKind::Unary(binop, folder.fold_expr(ohs)) | |
1a4d82fc | 1199 | } |
7453a54e SL |
1200 | ExprKind::Lit(l) => ExprKind::Lit(l), |
1201 | ExprKind::Cast(expr, ty) => { | |
1202 | ExprKind::Cast(folder.fold_expr(expr), folder.fold_ty(ty)) | |
1a4d82fc | 1203 | } |
7453a54e SL |
1204 | ExprKind::Type(expr, ty) => { |
1205 | ExprKind::Type(folder.fold_expr(expr), folder.fold_ty(ty)) | |
9cc50fc6 | 1206 | } |
7453a54e SL |
1207 | ExprKind::AddrOf(m, ohs) => ExprKind::AddrOf(m, folder.fold_expr(ohs)), |
1208 | ExprKind::If(cond, tr, fl) => { | |
1209 | ExprKind::If(folder.fold_expr(cond), | |
1a4d82fc JJ |
1210 | folder.fold_block(tr), |
1211 | fl.map(|x| folder.fold_expr(x))) | |
1212 | } | |
7453a54e SL |
1213 | ExprKind::IfLet(pat, expr, tr, fl) => { |
1214 | ExprKind::IfLet(folder.fold_pat(pat), | |
1a4d82fc JJ |
1215 | folder.fold_expr(expr), |
1216 | folder.fold_block(tr), | |
1217 | fl.map(|x| folder.fold_expr(x))) | |
1218 | } | |
7453a54e SL |
1219 | ExprKind::While(cond, body, opt_ident) => { |
1220 | ExprKind::While(folder.fold_expr(cond), | |
1a4d82fc JJ |
1221 | folder.fold_block(body), |
1222 | opt_ident.map(|i| folder.fold_ident(i))) | |
1223 | } | |
7453a54e SL |
1224 | ExprKind::WhileLet(pat, expr, body, opt_ident) => { |
1225 | ExprKind::WhileLet(folder.fold_pat(pat), | |
1a4d82fc JJ |
1226 | folder.fold_expr(expr), |
1227 | folder.fold_block(body), | |
1228 | opt_ident.map(|i| folder.fold_ident(i))) | |
1229 | } | |
7453a54e SL |
1230 | ExprKind::ForLoop(pat, iter, body, opt_ident) => { |
1231 | ExprKind::ForLoop(folder.fold_pat(pat), | |
1a4d82fc JJ |
1232 | folder.fold_expr(iter), |
1233 | folder.fold_block(body), | |
1234 | opt_ident.map(|i| folder.fold_ident(i))) | |
1235 | } | |
7453a54e SL |
1236 | ExprKind::Loop(body, opt_ident) => { |
1237 | ExprKind::Loop(folder.fold_block(body), | |
1a4d82fc JJ |
1238 | opt_ident.map(|i| folder.fold_ident(i))) |
1239 | } | |
7453a54e SL |
1240 | ExprKind::Match(expr, arms) => { |
1241 | ExprKind::Match(folder.fold_expr(expr), | |
b039eaaf | 1242 | arms.move_map(|x| folder.fold_arm(x))) |
1a4d82fc | 1243 | } |
7453a54e SL |
1244 | ExprKind::Closure(capture_clause, decl, body) => { |
1245 | ExprKind::Closure(capture_clause, | |
1a4d82fc JJ |
1246 | folder.fold_fn_decl(decl), |
1247 | folder.fold_block(body)) | |
1248 | } | |
7453a54e SL |
1249 | ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)), |
1250 | ExprKind::Assign(el, er) => { | |
1251 | ExprKind::Assign(folder.fold_expr(el), folder.fold_expr(er)) | |
1a4d82fc | 1252 | } |
7453a54e SL |
1253 | ExprKind::AssignOp(op, el, er) => { |
1254 | ExprKind::AssignOp(op, | |
1a4d82fc JJ |
1255 | folder.fold_expr(el), |
1256 | folder.fold_expr(er)) | |
1257 | } | |
7453a54e SL |
1258 | ExprKind::Field(el, ident) => { |
1259 | ExprKind::Field(folder.fold_expr(el), | |
9346a6ac AL |
1260 | respan(folder.new_span(ident.span), |
1261 | folder.fold_ident(ident.node))) | |
1a4d82fc | 1262 | } |
7453a54e SL |
1263 | ExprKind::TupField(el, ident) => { |
1264 | ExprKind::TupField(folder.fold_expr(el), | |
9346a6ac AL |
1265 | respan(folder.new_span(ident.span), |
1266 | folder.fold_usize(ident.node))) | |
1a4d82fc | 1267 | } |
7453a54e SL |
1268 | ExprKind::Index(el, er) => { |
1269 | ExprKind::Index(folder.fold_expr(el), folder.fold_expr(er)) | |
1a4d82fc | 1270 | } |
54a0048b | 1271 | ExprKind::Range(e1, e2, lim) => { |
7453a54e | 1272 | ExprKind::Range(e1.map(|x| folder.fold_expr(x)), |
54a0048b SL |
1273 | e2.map(|x| folder.fold_expr(x)), |
1274 | lim) | |
1a4d82fc | 1275 | } |
7453a54e | 1276 | ExprKind::Path(qself, path) => { |
c34b1796 AL |
1277 | let qself = qself.map(|QSelf { ty, position }| { |
1278 | QSelf { | |
1279 | ty: folder.fold_ty(ty), | |
1280 | position: position | |
1281 | } | |
1282 | }); | |
7453a54e | 1283 | ExprKind::Path(qself, folder.fold_path(path)) |
c34b1796 | 1284 | } |
7453a54e | 1285 | ExprKind::Break(opt_ident) => ExprKind::Break(opt_ident.map(|label| |
e9174d1e SL |
1286 | respan(folder.new_span(label.span), |
1287 | folder.fold_ident(label.node))) | |
1288 | ), | |
7453a54e | 1289 | ExprKind::Again(opt_ident) => ExprKind::Again(opt_ident.map(|label| |
e9174d1e SL |
1290 | respan(folder.new_span(label.span), |
1291 | folder.fold_ident(label.node))) | |
1292 | ), | |
7453a54e SL |
1293 | ExprKind::Ret(e) => ExprKind::Ret(e.map(|x| folder.fold_expr(x))), |
1294 | ExprKind::InlineAsm(InlineAsm { | |
1a4d82fc JJ |
1295 | inputs, |
1296 | outputs, | |
1297 | asm, | |
1298 | asm_str_style, | |
1299 | clobbers, | |
1300 | volatile, | |
1301 | alignstack, | |
1302 | dialect, | |
1303 | expn_id, | |
7453a54e | 1304 | }) => ExprKind::InlineAsm(InlineAsm { |
1a4d82fc JJ |
1305 | inputs: inputs.move_map(|(c, input)| { |
1306 | (c, folder.fold_expr(input)) | |
1307 | }), | |
9cc50fc6 SL |
1308 | outputs: outputs.move_map(|out| { |
1309 | InlineAsmOutput { | |
1310 | constraint: out.constraint, | |
1311 | expr: folder.fold_expr(out.expr), | |
1312 | is_rw: out.is_rw, | |
1313 | is_indirect: out.is_indirect, | |
1314 | } | |
1a4d82fc JJ |
1315 | }), |
1316 | asm: asm, | |
1317 | asm_str_style: asm_str_style, | |
1318 | clobbers: clobbers, | |
1319 | volatile: volatile, | |
1320 | alignstack: alignstack, | |
1321 | dialect: dialect, | |
1322 | expn_id: expn_id, | |
1323 | }), | |
7453a54e SL |
1324 | ExprKind::Mac(mac) => ExprKind::Mac(folder.fold_mac(mac)), |
1325 | ExprKind::Struct(path, fields, maybe_expr) => { | |
1326 | ExprKind::Struct(folder.fold_path(path), | |
1a4d82fc JJ |
1327 | fields.move_map(|x| folder.fold_field(x)), |
1328 | maybe_expr.map(|x| folder.fold_expr(x))) | |
1329 | }, | |
54a0048b SL |
1330 | ExprKind::Paren(ex) => ExprKind::Paren(folder.fold_expr(ex)), |
1331 | ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)), | |
1a4d82fc | 1332 | }, |
92a42be0 SL |
1333 | span: folder.new_span(span), |
1334 | attrs: attrs.map_thin_attrs(|v| fold_attrs(v, folder)), | |
223e47cc LB |
1335 | } |
1336 | } | |
1337 | ||
92a42be0 SL |
1338 | pub fn noop_fold_opt_expr<T: Folder>(e: P<Expr>, folder: &mut T) -> Option<P<Expr>> { |
1339 | Some(folder.fold_expr(e)) | |
1340 | } | |
1341 | ||
1342 | pub fn noop_fold_exprs<T: Folder>(es: Vec<P<Expr>>, folder: &mut T) -> Vec<P<Expr>> { | |
1343 | es.move_flat_map(|e| folder.fold_opt_expr(e)) | |
1344 | } | |
1345 | ||
1a4d82fc | 1346 | pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T) |
7453a54e | 1347 | -> SmallVector<Stmt> { |
1a4d82fc JJ |
1348 | let span = folder.new_span(span); |
1349 | match node { | |
7453a54e | 1350 | StmtKind::Decl(d, id) => { |
1a4d82fc | 1351 | let id = folder.new_id(id); |
7453a54e SL |
1352 | folder.fold_decl(d).into_iter().map(|d| Spanned { |
1353 | node: StmtKind::Decl(d, id), | |
1a4d82fc | 1354 | span: span |
7453a54e | 1355 | }).collect() |
1a4d82fc | 1356 | } |
7453a54e | 1357 | StmtKind::Expr(e, id) => { |
1a4d82fc | 1358 | let id = folder.new_id(id); |
92a42be0 | 1359 | if let Some(e) = folder.fold_opt_expr(e) { |
7453a54e SL |
1360 | SmallVector::one(Spanned { |
1361 | node: StmtKind::Expr(e, id), | |
92a42be0 | 1362 | span: span |
7453a54e | 1363 | }) |
92a42be0 SL |
1364 | } else { |
1365 | SmallVector::zero() | |
1366 | } | |
1a4d82fc | 1367 | } |
7453a54e | 1368 | StmtKind::Semi(e, id) => { |
1a4d82fc | 1369 | let id = folder.new_id(id); |
92a42be0 | 1370 | if let Some(e) = folder.fold_opt_expr(e) { |
7453a54e SL |
1371 | SmallVector::one(Spanned { |
1372 | node: StmtKind::Semi(e, id), | |
92a42be0 | 1373 | span: span |
7453a54e | 1374 | }) |
92a42be0 SL |
1375 | } else { |
1376 | SmallVector::zero() | |
1377 | } | |
1a4d82fc | 1378 | } |
7453a54e SL |
1379 | StmtKind::Mac(mac, semi, attrs) => SmallVector::one(Spanned { |
1380 | node: StmtKind::Mac(mac.map(|m| folder.fold_mac(m)), | |
1381 | semi, | |
1382 | attrs.map_thin_attrs(|v| fold_attrs(v, folder))), | |
1a4d82fc | 1383 | span: span |
7453a54e | 1384 | }) |
1a4d82fc | 1385 | } |
223e47cc LB |
1386 | } |
1387 | ||
54a0048b SL |
1388 | pub fn noop_fold_vis<T: Folder>(vis: Visibility, folder: &mut T) -> Visibility { |
1389 | match vis { | |
1390 | Visibility::Restricted { path, id } => Visibility::Restricted { | |
1391 | path: path.map(|path| folder.fold_path(path)), | |
1392 | id: folder.new_id(id) | |
1393 | }, | |
1394 | _ => vis, | |
1395 | } | |
1396 | } | |
1397 | ||
970d7e83 | 1398 | #[cfg(test)] |
d9579d0f | 1399 | mod tests { |
c34b1796 | 1400 | use std::io; |
970d7e83 LB |
1401 | use ast; |
1402 | use util::parser_testing::{string_to_crate, matches_codepattern}; | |
1403 | use parse::token; | |
1404 | use print::pprust; | |
1a4d82fc | 1405 | use fold; |
970d7e83 LB |
1406 | use super::*; |
1407 | ||
970d7e83 | 1408 | // this version doesn't care about getting comments or docstrings in. |
1a4d82fc | 1409 | fn fake_print_crate(s: &mut pprust::State, |
c34b1796 | 1410 | krate: &ast::Crate) -> io::Result<()> { |
85aaf69f | 1411 | s.print_mod(&krate.module, &krate.attrs) |
970d7e83 LB |
1412 | } |
1413 | ||
1414 | // change every identifier to "zz" | |
1a4d82fc JJ |
1415 | struct ToZzIdentFolder; |
1416 | ||
1417 | impl Folder for ToZzIdentFolder { | |
1418 | fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident { | |
1419 | token::str_to_ident("zz") | |
1420 | } | |
1421 | fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { | |
1422 | fold::noop_fold_mac(mac, self) | |
1423 | } | |
970d7e83 LB |
1424 | } |
1425 | ||
1426 | // maybe add to expand.rs... | |
1a4d82fc | 1427 | macro_rules! assert_pred { |
970d7e83 LB |
1428 | ($pred:expr, $predname:expr, $a:expr , $b:expr) => ( |
1429 | { | |
1430 | let pred_val = $pred; | |
1431 | let a_val = $a; | |
1432 | let b_val = $b; | |
85aaf69f | 1433 | if !(pred_val(&a_val, &b_val)) { |
1a4d82fc | 1434 | panic!("expected args satisfying {}, got {} and {}", |
970d7e83 LB |
1435 | $predname, a_val, b_val); |
1436 | } | |
1437 | } | |
1438 | ) | |
1a4d82fc | 1439 | } |
970d7e83 LB |
1440 | |
1441 | // make sure idents get transformed everywhere | |
1442 | #[test] fn ident_transformation () { | |
1a4d82fc JJ |
1443 | let mut zz_fold = ToZzIdentFolder; |
1444 | let ast = string_to_crate( | |
1445 | "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); | |
1446 | let folded_crate = zz_fold.fold_crate(ast); | |
1447 | assert_pred!( | |
1448 | matches_codepattern, | |
1449 | "matches_codepattern", | |
1450 | pprust::to_string(|s| fake_print_crate(s, &folded_crate)), | |
1451 | "#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); | |
970d7e83 LB |
1452 | } |
1453 | ||
1454 | // even inside macro defs.... | |
1455 | #[test] fn ident_transformation_in_defs () { | |
1a4d82fc JJ |
1456 | let mut zz_fold = ToZzIdentFolder; |
1457 | let ast = string_to_crate( | |
1458 | "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ | |
1459 | (g $(d $d $e)+))} ".to_string()); | |
1460 | let folded_crate = zz_fold.fold_crate(ast); | |
1461 | assert_pred!( | |
1462 | matches_codepattern, | |
1463 | "matches_codepattern", | |
1464 | pprust::to_string(|s| fake_print_crate(s, &folded_crate)), | |
1465 | "zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string()); | |
970d7e83 LB |
1466 | } |
1467 | } |