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