From 26a39f23ce09b64c9718f3ee6535f7ca4e84c7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Fri, 25 Jul 2014 21:00:33 +0200 Subject: [PATCH 1/2] Refactored syntax::fold. Prior to this, the code there had a few issues: - Default implementations inconsistently either had the prefix `noop_` or not. - Some default methods where implemented in terms of a public noop function for user code to call, others where implemented directly on the trait and did not allow users of the trait to reuse the code. - Some of the default implementations where private, and thus not reusable for other implementors. - There where some bugs where default implementations called other default implementations directly, rather than to the underlying Folder, with the result of some AST nodes never being visited even if the user implemented that method. (For example, the current Folder never folded struct fields) This commit solves this situation somewhat radically by making _all_ `fold_...` functions in the module into Folder methods, and implementing them all in terms of public `noop_...` functions for other implementors to call out to. Some public functions had to be renamed to fit the new system, so this is a breaking change. [breaking-change] --- src/librustc/front/config.rs | 2 +- src/libsyntax/ast.rs | 4 +- src/libsyntax/ast_map/mod.rs | 2 +- src/libsyntax/ext/expand.rs | 12 +- src/libsyntax/fold.rs | 695 +++++++++++++++++++++-------------- 5 files changed, 420 insertions(+), 295 deletions(-) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 0c39cf350a613..ab363a88db2d9 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -44,7 +44,7 @@ impl<'a> fold::Folder for Context<'a> { fold_expr(self, expr) } fn fold_mac(&mut self, mac: &ast::Mac) -> ast::Mac { - fold::fold_mac(mac, self) + fold::noop_fold_mac(mac, self) } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f05d17569f68d..34de81008711e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -961,7 +961,7 @@ pub enum ExplicitSelf_ { pub type ExplicitSelf = Spanned; -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Method { pub attrs: Vec, pub id: NodeId, @@ -969,7 +969,7 @@ pub struct Method { pub node: Method_, } -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Method_ { /// Represents a method declaration MethDecl(Ident, diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index c77f7db1c6da0..67de8e7aba102 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -606,7 +606,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> { } fn fold_mac(&mut self, mac: &Mac) -> Mac { - fold::fold_mac(mac, self) + fold::noop_fold_mac(mac, self) } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f82796b480a4e..3b098ea8a3dfd 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -341,7 +341,7 @@ fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::It ast::ItemFn(decl, fn_style, abi, ref generics, body) => { let (rewritten_fn_decl, rewritten_body) = expand_and_rename_fn_decl_and_block(&*decl, body, fld); - let expanded_generics = fold::fold_generics(generics,fld); + let expanded_generics = fold::noop_fold_generics(generics,fld); ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body) } _ => noop_fold_item_underscore(&*item, fld) @@ -792,7 +792,7 @@ impl<'a> Folder for IdentRenamer<'a> { } } fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac { - fold::fold_mac(macro, self) + fold::noop_fold_mac(macro, self) } } @@ -824,7 +824,7 @@ impl<'a> Folder for PatIdentRenamer<'a> { } } fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac { - fold::fold_mac(macro, self) + fold::noop_fold_mac(macro, self) } } @@ -847,7 +847,7 @@ fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector { MacInvocTT(self.fold_path(path), - fold_tts(tts.as_slice(), self), + self.fold_tts(tts.as_slice()), mtwt::apply_mark(self.mark, ctxt)) } }; @@ -1027,7 +1027,7 @@ impl Folder for Marker { // apply a given mark to the given token trees. Used prior to expansion of a macro. fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec { - fold_tts(tts, &mut Marker{mark:m}) + noop_fold_tts(tts, &mut Marker{mark:m}) } // apply a given mark to the given expr. Used following the expansion of a macro. diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index f48306bc6ee2f..f3e6cf77e7972 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -29,52 +29,29 @@ use util::small_vector::SmallVector; use std::rc::Rc; use std::gc::{Gc, GC}; -// We may eventually want to be able to fold over type parameters, too. pub trait Folder { + // Any additions to this trait should happen in form + // of a call to a public `noop_*` function that only calls + // out to the folder again, not other `noop_*` functions. + // + // This is a necessary API workaround to the problem of not + // being able to call out to the super default method + // in an overridden default method. + fn fold_crate(&mut self, c: Crate) -> Crate { noop_fold_crate(c, self) } fn fold_meta_items(&mut self, meta_items: &[Gc]) -> Vec> { - meta_items.iter().map(|x| fold_meta_item_(*x, self)).collect() + noop_fold_meta_items(meta_items, self) + } + + fn fold_meta_item(&mut self, meta_item: &MetaItem) -> MetaItem { + noop_fold_meta_item(meta_item, self) } fn fold_view_path(&mut self, view_path: Gc) -> Gc { - let inner_view_path = match view_path.node { - ViewPathSimple(ref ident, ref path, node_id) => { - let id = self.new_id(node_id); - ViewPathSimple(ident.clone(), - self.fold_path(path), - id) - } - ViewPathGlob(ref path, node_id) => { - let id = self.new_id(node_id); - ViewPathGlob(self.fold_path(path), id) - } - ViewPathList(ref path, ref path_list_idents, node_id) => { - let id = self.new_id(node_id); - ViewPathList(self.fold_path(path), - path_list_idents.iter().map(|path_list_ident| { - Spanned { - node: match path_list_ident.node { - PathListIdent { id, name } => - PathListIdent { - id: self.new_id(id), - name: name.clone() - }, - PathListMod { id } => - PathListMod { id: self.new_id(id) } - }, - span: self.new_span(path_list_ident.span) - } - }).collect(), - id) - } - }; - box(GC) Spanned { - node: inner_view_path, - span: self.new_span(view_path.span), - } + noop_fold_view_path(view_path, self) } fn fold_view_item(&mut self, vi: &ViewItem) -> ViewItem { @@ -89,17 +66,12 @@ pub trait Folder { noop_fold_item(&*i, self) } + fn fold_item_simple(&mut self, i: &Item) -> Item { + noop_fold_item_simple(i, self) + } + fn fold_struct_field(&mut self, sf: &StructField) -> StructField { - let id = self.new_id(sf.node.id); - Spanned { - node: ast::StructField_ { - kind: sf.node.kind, - id: id, - ty: self.fold_ty(sf.node.ty), - attrs: sf.node.attrs.iter().map(|e| self.fold_attribute(*e)).collect() - }, - span: self.new_span(sf.span) - } + noop_fold_struct_field(sf, self) } fn fold_item_underscore(&mut self, i: &Item_) -> Item_ { @@ -127,12 +99,7 @@ pub trait Folder { } fn fold_arm(&mut self, a: &Arm) -> Arm { - Arm { - attrs: a.attrs.iter().map(|x| self.fold_attribute(*x)).collect(), - pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(), - guard: a.guard.map(|x| self.fold_expr(x)), - body: self.fold_expr(a.body), - } + noop_fold_arm(a, self) } fn fold_pat(&mut self, p: Gc) -> Gc { @@ -140,19 +107,7 @@ pub trait Folder { } fn fold_decl(&mut self, d: Gc) -> SmallVector> { - let node = match d.node { - DeclLocal(ref l) => SmallVector::one(DeclLocal(self.fold_local(*l))), - DeclItem(it) => { - self.fold_item(it).move_iter().map(|i| DeclItem(i)).collect() - } - }; - - node.move_iter().map(|node| { - box(GC) Spanned { - node: node, - span: self.new_span(d.span), - } - }).collect() + noop_fold_decl(d, self) } fn fold_expr(&mut self, e: Gc) -> Gc { @@ -160,65 +115,7 @@ pub trait Folder { } fn fold_ty(&mut self, t: P) -> P { - let id = self.new_id(t.id); - let node = match t.node { - TyNil | TyBot | TyInfer => t.node.clone(), - TyBox(ty) => TyBox(self.fold_ty(ty)), - TyUniq(ty) => TyUniq(self.fold_ty(ty)), - TyVec(ty) => TyVec(self.fold_ty(ty)), - TyPtr(ref mt) => TyPtr(fold_mt(mt, self)), - TyRptr(ref region, ref mt) => { - TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self)) - } - TyClosure(ref f, ref region) => { - TyClosure(box(GC) ClosureTy { - fn_style: f.fn_style, - onceness: f.onceness, - bounds: fold_opt_bounds(&f.bounds, self), - decl: self.fold_fn_decl(&*f.decl), - lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), - }, fold_opt_lifetime(region, self)) - } - TyProc(ref f) => { - TyProc(box(GC) ClosureTy { - fn_style: f.fn_style, - onceness: f.onceness, - bounds: fold_opt_bounds(&f.bounds, self), - decl: self.fold_fn_decl(&*f.decl), - lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), - }) - } - TyBareFn(ref f) => { - TyBareFn(box(GC) BareFnTy { - lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), - fn_style: f.fn_style, - abi: f.abi, - decl: self.fold_fn_decl(&*f.decl) - }) - } - TyUnboxedFn(ref f) => { - TyUnboxedFn(box(GC) UnboxedFnTy { - decl: self.fold_fn_decl(&*f.decl), - }) - } - TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()), - TyParen(ref ty) => TyParen(self.fold_ty(*ty)), - TyPath(ref path, ref bounds, id) => { - let id = self.new_id(id); - TyPath(self.fold_path(path), - fold_opt_bounds(bounds, self), - id) - } - TyFixedLengthVec(ty, e) => { - TyFixedLengthVec(self.fold_ty(ty), self.fold_expr(e)) - } - TyTypeof(expr) => TyTypeof(self.fold_expr(expr)), - }; - P(Ty { - id: id, - span: self.new_span(t.span), - node: node, - }) + noop_fold_ty(t, self) } fn fold_mod(&mut self, m: &Mod) -> Mod { @@ -226,87 +123,23 @@ pub trait Folder { } fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod { - ast::ForeignMod { - abi: nm.abi, - view_items: nm.view_items - .iter() - .map(|x| self.fold_view_item(x)) - .collect(), - items: nm.items - .iter() - .map(|x| self.fold_foreign_item(*x)) - .collect(), - } + noop_fold_foreign_mod(nm, self) } fn fold_variant(&mut self, v: &Variant) -> P { - let id = self.new_id(v.node.id); - let kind; - match v.node.kind { - TupleVariantKind(ref variant_args) => { - kind = TupleVariantKind(variant_args.iter().map(|x| - fold_variant_arg_(x, self)).collect()) - } - StructVariantKind(ref struct_def) => { - kind = StructVariantKind(box(GC) ast::StructDef { - fields: struct_def.fields.iter() - .map(|f| self.fold_struct_field(f)).collect(), - ctor_id: struct_def.ctor_id.map(|c| self.new_id(c)), - super_struct: match struct_def.super_struct { - Some(t) => Some(self.fold_ty(t)), - None => None - }, - is_virtual: struct_def.is_virtual, - }) - } - } - - let attrs = v.node.attrs.iter().map(|x| self.fold_attribute(*x)).collect(); - - let de = match v.node.disr_expr { - Some(e) => Some(self.fold_expr(e)), - None => None - }; - let node = ast::Variant_ { - name: v.node.name, - attrs: attrs, - kind: kind, - id: id, - disr_expr: de, - vis: v.node.vis, - }; - P(Spanned { - node: node, - span: self.new_span(v.span), - }) + noop_fold_variant(v, self) } fn fold_ident(&mut self, i: Ident) -> Ident { - i + noop_fold_ident(i, self) } fn fold_path(&mut self, p: &Path) -> Path { - ast::Path { - span: self.new_span(p.span), - global: p.global, - segments: p.segments.iter().map(|segment| ast::PathSegment { - identifier: self.fold_ident(segment.identifier), - lifetimes: segment.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(), - types: segment.types.iter().map(|&typ| self.fold_ty(typ)).collect(), - }).collect() - } + noop_fold_path(p, self) } fn fold_local(&mut self, l: Gc) -> Gc { - let id = self.new_id(l.id); // Needs to be first, for ast_map. - box(GC) Local { - id: id, - ty: self.fold_ty(l.ty), - pat: self.fold_pat(l.pat), - init: l.init.map(|e| self.fold_expr(e)), - span: self.new_span(l.span), - source: l.source, - } + noop_fold_local(l, self) } fn fold_mac(&mut self, _macro: &Mac) -> Mac { @@ -315,9 +148,96 @@ pub trait Folder { // if you really want a folder that // works on macros, use this // definition in your trait impl: - // fold::fold_mac(_macro, self) + // fold::noop_fold_mac(_macro, self) + } + + fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf { + noop_fold_explicit_self(es, self) + } + + fn fold_explicit_self_underscore(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ { + noop_fold_explicit_self_underscore(es, self) + } + + fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime { + noop_fold_lifetime(l, self) + } + + fn fold_attribute(&mut self, at: Attribute) -> Attribute { + noop_fold_attribute(at, self) + } + + fn fold_arg(&mut self, a: &Arg) -> Arg { + noop_fold_arg(a, self) + } + + fn fold_generics(&mut self, generics: &Generics) -> Generics { + noop_fold_generics(generics, self) + } + + fn fold_trait_ref(&mut self, p: &TraitRef) -> TraitRef { + noop_fold_trait_ref(p, self) + } + + fn fold_struct_def(&mut self, struct_def: Gc) -> Gc { + noop_fold_struct_def(struct_def, self) + } + + fn fold_lifetimes(&mut self, lts: &[Lifetime]) -> Vec { + noop_fold_lifetimes(lts, self) + } + + fn fold_ty_param(&mut self, tp: &TyParam) -> TyParam { + noop_fold_ty_param(tp, self) + } + + fn fold_ty_params(&mut self, tps: &[TyParam]) -> OwnedSlice { + noop_fold_ty_params(tps, self) + } + + fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree { + noop_fold_tt(tt, self) + } + + fn fold_tts(&mut self, tts: &[TokenTree]) -> Vec { + noop_fold_tts(tts, self) + } + + fn fold_token(&mut self, t: &token::Token) -> token::Token { + noop_fold_token(t, self) + } + + fn fold_interpolated(&mut self, nt : &token::Nonterminal) -> token::Nonterminal { + noop_fold_interpolated(nt, self) + } + + fn fold_opt_lifetime(&mut self, o_lt: &Option) -> Option { + noop_fold_opt_lifetime(o_lt, self) + } + + fn fold_variant_arg(&mut self, va: &VariantArg) -> VariantArg { + noop_fold_variant_arg(va, self) + } + + fn fold_ty_param_bound(&mut self, tpb: &TyParamBound) -> TyParamBound { + noop_fold_ty_param_bound(tpb, self) + } + + fn fold_opt_bounds(&mut self, b: &Option>) + -> Option> { + noop_fold_opt_bounds(b, self) + } + + fn fold_mt(&mut self, mt: &MutTy) -> MutTy { + noop_fold_mt(mt, self) } + fn fold_field(&mut self, field: Field) -> Field { + noop_fold_field(field, self) + } + +// Helper methods: + fn map_exprs(&self, f: |Gc| -> Gc, es: &[Gc]) -> Vec> { es.iter().map(|x| f(*x)).collect() @@ -330,51 +250,259 @@ pub trait Folder { fn new_span(&mut self, sp: Span) -> Span { sp } +} - fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf { - Spanned { - span: self.new_span(es.span), - node: self.fold_explicit_self_(&es.node) +pub fn noop_fold_meta_items(meta_items: &[Gc], fld: &mut T) + -> Vec> { + meta_items.iter().map(|x| box (GC) fld.fold_meta_item(&**x)).collect() +} + +pub fn noop_fold_view_path(view_path: Gc, fld: &mut T) -> Gc { + let inner_view_path = match view_path.node { + ViewPathSimple(ref ident, ref path, node_id) => { + let id = fld.new_id(node_id); + ViewPathSimple(ident.clone(), + fld.fold_path(path), + id) + } + ViewPathGlob(ref path, node_id) => { + let id = fld.new_id(node_id); + ViewPathGlob(fld.fold_path(path), id) } + ViewPathList(ref path, ref path_list_idents, node_id) => { + let id = fld.new_id(node_id); + ViewPathList(fld.fold_path(path), + path_list_idents.iter().map(|path_list_ident| { + Spanned { + node: match path_list_ident.node { + PathListIdent { id, name } => + PathListIdent { + id: fld.new_id(id), + name: name.clone() + }, + PathListMod { id } => + PathListMod { id: fld.new_id(id) } + }, + span: fld.new_span(path_list_ident.span) + } + }).collect(), + id) + } + }; + box(GC) Spanned { + node: inner_view_path, + span: fld.new_span(view_path.span), } +} - fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ { - match *es { - SelfStatic | SelfValue(_) => *es, - SelfRegion(ref lifetime, m, id) => { - SelfRegion(fold_opt_lifetime(lifetime, self), m, id) - } - SelfExplicit(ref typ, id) => SelfExplicit(self.fold_ty(*typ), id), +pub fn noop_fold_arm(a: &Arm, fld: &mut T) -> Arm { + Arm { + attrs: a.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(), + pats: a.pats.iter().map(|x| fld.fold_pat(*x)).collect(), + guard: a.guard.map(|x| fld.fold_expr(x)), + body: fld.fold_expr(a.body), + } +} + +pub fn noop_fold_decl(d: Gc, fld: &mut T) -> SmallVector> { + let node = match d.node { + DeclLocal(ref l) => SmallVector::one(DeclLocal(fld.fold_local(*l))), + DeclItem(it) => { + fld.fold_item(it).move_iter().map(|i| DeclItem(i)).collect() + } + }; + + node.move_iter().map(|node| { + box(GC) Spanned { + node: node, + span: fld.new_span(d.span), + } + }).collect() +} + +pub fn noop_fold_ty(t: P, fld: &mut T) -> P { + let id = fld.new_id(t.id); + let node = match t.node { + TyNil | TyBot | TyInfer => t.node.clone(), + TyBox(ty) => TyBox(fld.fold_ty(ty)), + TyUniq(ty) => TyUniq(fld.fold_ty(ty)), + TyVec(ty) => TyVec(fld.fold_ty(ty)), + TyPtr(ref mt) => TyPtr(fld.fold_mt(mt)), + TyRptr(ref region, ref mt) => { + TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) + } + TyClosure(ref f, ref region) => { + TyClosure(box(GC) ClosureTy { + fn_style: f.fn_style, + onceness: f.onceness, + bounds: fld.fold_opt_bounds(&f.bounds), + decl: fld.fold_fn_decl(&*f.decl), + lifetimes: f.lifetimes.iter().map(|l| fld.fold_lifetime(l)).collect(), + }, fld.fold_opt_lifetime(region)) + } + TyProc(ref f) => { + TyProc(box(GC) ClosureTy { + fn_style: f.fn_style, + onceness: f.onceness, + bounds: fld.fold_opt_bounds(&f.bounds), + decl: fld.fold_fn_decl(&*f.decl), + lifetimes: f.lifetimes.iter().map(|l| fld.fold_lifetime(l)).collect(), + }) + } + TyBareFn(ref f) => { + TyBareFn(box(GC) BareFnTy { + lifetimes: f.lifetimes.iter().map(|l| fld.fold_lifetime(l)).collect(), + fn_style: f.fn_style, + abi: f.abi, + decl: fld.fold_fn_decl(&*f.decl) + }) + } + TyUnboxedFn(ref f) => { + TyUnboxedFn(box(GC) UnboxedFnTy { + decl: fld.fold_fn_decl(&*f.decl), + }) + } + TyTup(ref tys) => TyTup(tys.iter().map(|&ty| fld.fold_ty(ty)).collect()), + TyParen(ref ty) => TyParen(fld.fold_ty(*ty)), + TyPath(ref path, ref bounds, id) => { + let id = fld.new_id(id); + TyPath(fld.fold_path(path), + fld.fold_opt_bounds(bounds), + id) + } + TyFixedLengthVec(ty, e) => { + TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) + } + TyTypeof(expr) => TyTypeof(fld.fold_expr(expr)), + }; + P(Ty { + id: id, + span: fld.new_span(t.span), + node: node, + }) +} + +pub fn noop_fold_foreign_mod(nm: &ForeignMod, fld: &mut T) -> ForeignMod { + ast::ForeignMod { + abi: nm.abi, + view_items: nm.view_items + .iter() + .map(|x| fld.fold_view_item(x)) + .collect(), + items: nm.items + .iter() + .map(|x| fld.fold_foreign_item(*x)) + .collect(), + } +} + +pub fn noop_fold_variant(v: &Variant, fld: &mut T) -> P { + let id = fld.new_id(v.node.id); + let kind; + match v.node.kind { + TupleVariantKind(ref variant_args) => { + kind = TupleVariantKind(variant_args.iter().map(|x| + fld.fold_variant_arg(x)).collect()) + } + StructVariantKind(ref struct_def) => { + kind = StructVariantKind(box(GC) ast::StructDef { + fields: struct_def.fields.iter() + .map(|f| fld.fold_struct_field(f)).collect(), + ctor_id: struct_def.ctor_id.map(|c| fld.new_id(c)), + super_struct: match struct_def.super_struct { + Some(t) => Some(fld.fold_ty(t)), + None => None + }, + is_virtual: struct_def.is_virtual, + }) } } - fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime { - noop_fold_lifetime(l, self) + let attrs = v.node.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(); + + let de = match v.node.disr_expr { + Some(e) => Some(fld.fold_expr(e)), + None => None + }; + let node = ast::Variant_ { + name: v.node.name, + attrs: attrs, + kind: kind, + id: id, + disr_expr: de, + vis: v.node.vis, + }; + P(Spanned { + node: node, + span: fld.new_span(v.span), + }) +} + +pub fn noop_fold_ident(i: Ident, _: &mut T) -> Ident { + i +} + +pub fn noop_fold_path(p: &Path, fld: &mut T) -> Path { + ast::Path { + span: fld.new_span(p.span), + global: p.global, + segments: p.segments.iter().map(|segment| ast::PathSegment { + identifier: fld.fold_ident(segment.identifier), + lifetimes: segment.lifetimes.iter().map(|l| fld.fold_lifetime(l)).collect(), + types: segment.types.iter().map(|&typ| fld.fold_ty(typ)).collect(), + }).collect() } +} - //used in noop_fold_item and noop_fold_crate - fn fold_attribute(&mut self, at: Attribute) -> Attribute { - Spanned { - span: self.new_span(at.span), - node: ast::Attribute_ { - id: at.node.id, - style: at.node.style, - value: fold_meta_item_(at.node.value, self), - is_sugared_doc: at.node.is_sugared_doc - } +pub fn noop_fold_local(l: Gc, fld: &mut T) -> Gc { + let id = fld.new_id(l.id); // Needs to be first, for ast_map. + box(GC) Local { + id: id, + ty: fld.fold_ty(l.ty), + pat: fld.fold_pat(l.pat), + init: l.init.map(|e| fld.fold_expr(e)), + span: fld.new_span(l.span), + source: l.source, + } +} + +pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Attribute { + Spanned { + span: fld.new_span(at.span), + node: ast::Attribute_ { + id: at.node.id, + style: at.node.style, + value: box (GC) fld.fold_meta_item(&*at.node.value), + is_sugared_doc: at.node.is_sugared_doc } } +} +pub fn noop_fold_explicit_self_underscore(es: &ExplicitSelf_, fld: &mut T) + -> ExplicitSelf_ { + match *es { + SelfStatic | SelfValue(_) => *es, + SelfRegion(ref lifetime, m, id) => { + SelfRegion(fld.fold_opt_lifetime(lifetime), m, id) + } + SelfExplicit(ref typ, id) => SelfExplicit(fld.fold_ty(*typ), id), + } +} +pub fn noop_fold_explicit_self(es: &ExplicitSelf, fld: &mut T) -> ExplicitSelf { + Spanned { + span: fld.new_span(es.span), + node: fld.fold_explicit_self_underscore(&es.node) + } } -pub fn fold_mac(macro: &Mac, fld: &mut T) -> Mac { +pub fn noop_fold_mac(macro: &Mac, fld: &mut T) -> Mac { Spanned { node: match macro.node { MacInvocTT(ref p, ref tts, ctxt) => { MacInvocTT(fld.fold_path(p), - fold_tts(tts.as_slice(), fld), + fld.fold_tts(tts.as_slice()), ctxt) } }, @@ -382,16 +510,15 @@ pub fn fold_mac(macro: &Mac, fld: &mut T) -> Mac { } } -/* some little folds that probably aren't useful to have in Folder itself*/ - -//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive -fn fold_meta_item_(mi: Gc, fld: &mut T) -> Gc { - box(GC) Spanned { +pub fn noop_fold_meta_item(mi: &MetaItem, fld: &mut T) -> MetaItem { + Spanned { node: match mi.node { MetaWord(ref id) => MetaWord((*id).clone()), MetaList(ref id, ref mis) => { - MetaList((*id).clone(), mis.iter().map(|e| fold_meta_item_(*e, fld)).collect()) + MetaList((*id).clone(), + mis.iter() + .map(|e| box (GC) fld.fold_meta_item(&**e)).collect()) } MetaNameValue(ref id, ref s) => { MetaNameValue((*id).clone(), (*s).clone()) @@ -400,8 +527,7 @@ fn fold_meta_item_(mi: Gc, fld: &mut T) -> Gc { span: fld.new_span(mi.span) } } -//used in noop_fold_foreign_item and noop_fold_fn_decl -fn fold_arg_(a: &Arg, fld: &mut T) -> Arg { +pub fn noop_fold_arg(a: &Arg, fld: &mut T) -> Arg { let id = fld.new_id(a.id); // Needs to be first, for ast_map. Arg { id: id, @@ -410,39 +536,38 @@ fn fold_arg_(a: &Arg, fld: &mut T) -> Arg { } } -pub fn fold_tt(tt: &TokenTree, fld: &mut T) -> TokenTree { +pub fn noop_fold_tt(tt: &TokenTree, fld: &mut T) -> TokenTree { match *tt { TTTok(span, ref tok) => - TTTok(span, fold_token(tok,fld)), - TTDelim(ref tts) => TTDelim(Rc::new(fold_tts(tts.as_slice(), fld))), + TTTok(span, fld.fold_token(tok)), + TTDelim(ref tts) => TTDelim(Rc::new(fld.fold_tts(tts.as_slice()))), TTSeq(span, ref pattern, ref sep, is_optional) => TTSeq(span, - Rc::new(fold_tts(pattern.as_slice(), fld)), - sep.as_ref().map(|tok| fold_token(tok,fld)), + Rc::new(fld.fold_tts(pattern.as_slice())), + sep.as_ref().map(|tok| fld.fold_token(tok)), is_optional), TTNonterminal(sp,ref ident) => TTNonterminal(sp,fld.fold_ident(*ident)) } } -pub fn fold_tts(tts: &[TokenTree], fld: &mut T) -> Vec { - tts.iter().map(|tt| fold_tt(tt,fld)).collect() +pub fn noop_fold_tts(tts: &[TokenTree], fld: &mut T) -> Vec { + tts.iter().map(|tt| fld.fold_tt(tt)).collect() } - // apply ident folder if it's an ident, apply other folds to interpolated nodes -fn fold_token(t: &token::Token, fld: &mut T) -> token::Token { +pub fn noop_fold_token(t: &token::Token, fld: &mut T) -> token::Token { match *t { token::IDENT(id, followed_by_colons) => { token::IDENT(fld.fold_ident(id), followed_by_colons) } token::LIFETIME(id) => token::LIFETIME(fld.fold_ident(id)), - token::INTERPOLATED(ref nt) => token::INTERPOLATED(fold_interpolated(nt,fld)), + token::INTERPOLATED(ref nt) => token::INTERPOLATED(fld.fold_interpolated(nt)), _ => (*t).clone() } } -// apply folder to elements of interpolated nodes +/// apply folder to elements of interpolated nodes // // NB: this can occur only when applying a fold to partially expanded code, where // parsed pieces have gotten implanted ito *other* macro invocations. This is relevant @@ -462,7 +587,8 @@ fn fold_token(t: &token::Token, fld: &mut T) -> token::Token { // BTW, design choice: I considered just changing the type of, e.g., NtItem to contain // multiple items, but decided against it when I looked at parse_item_or_view_item and // tried to figure out what I would do with multiple items there.... -fn fold_interpolated(nt : &token::Nonterminal, fld: &mut T) -> token::Nonterminal { +pub fn noop_fold_interpolated(nt : &token::Nonterminal, fld: &mut T) + -> token::Nonterminal { match *nt { token::NtItem(item) => token::NtItem(fld.fold_item(item) @@ -482,9 +608,9 @@ fn fold_interpolated(nt : &token::Nonterminal, fld: &mut T) -> token: token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), token::NtIdent(ref id, is_mod_name) => token::NtIdent(box fld.fold_ident(**id),is_mod_name), - token::NtMeta(meta_item) => token::NtMeta(fold_meta_item_(meta_item,fld)), + token::NtMeta(meta_item) => token::NtMeta(box (GC) fld.fold_meta_item(&*meta_item)), token::NtPath(ref path) => token::NtPath(box fld.fold_path(&**path)), - token::NtTT(tt) => token::NtTT(box (GC) fold_tt(&*tt,fld)), + token::NtTT(tt) => token::NtTT(box (GC) fld.fold_tt(&*tt)), // it looks to me like we can leave out the matchers: token::NtMatchers(matchers) _ => (*nt).clone() } @@ -492,17 +618,17 @@ fn fold_interpolated(nt : &token::Nonterminal, fld: &mut T) -> token: pub fn noop_fold_fn_decl(decl: &FnDecl, fld: &mut T) -> P { P(FnDecl { - inputs: decl.inputs.iter().map(|x| fold_arg_(x, fld)).collect(), // bad copy + inputs: decl.inputs.iter().map(|x| fld.fold_arg(x)).collect(), // bad copy output: fld.fold_ty(decl.output), cf: decl.cf, variadic: decl.variadic }) } -fn fold_ty_param_bound(tpb: &TyParamBound, fld: &mut T) - -> TyParamBound { +pub fn noop_fold_ty_param_bound(tpb: &TyParamBound, fld: &mut T) + -> TyParamBound { match *tpb { - TraitTyParamBound(ref ty) => TraitTyParamBound(fold_trait_ref(ty, fld)), + TraitTyParamBound(ref ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), StaticRegionTyParamBound => StaticRegionTyParamBound, UnboxedFnTyParamBound(ref unboxed_function_type) => { UnboxedFnTyParamBound(UnboxedFnTy { @@ -513,21 +639,21 @@ fn fold_ty_param_bound(tpb: &TyParamBound, fld: &mut T) } } -pub fn fold_ty_param(tp: &TyParam, fld: &mut T) -> TyParam { +pub fn noop_fold_ty_param(tp: &TyParam, fld: &mut T) -> TyParam { let id = fld.new_id(tp.id); TyParam { ident: tp.ident, id: id, - bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)), - unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)), + bounds: tp.bounds.map(|x| fld.fold_ty_param_bound(x)), + unbound: tp.unbound.as_ref().map(|x| fld.fold_ty_param_bound(x)), default: tp.default.map(|x| fld.fold_ty(x)), span: tp.span } } -pub fn fold_ty_params(tps: &OwnedSlice, fld: &mut T) - -> OwnedSlice { - tps.map(|tp| fold_ty_param(tp, fld)) +pub fn noop_fold_ty_params(tps: &[TyParam], fld: &mut T) + -> OwnedSlice { + tps.iter().map(|tp| fld.fold_ty_param(tp)).collect() } pub fn noop_fold_lifetime(l: &Lifetime, fld: &mut T) -> Lifetime { @@ -539,25 +665,24 @@ pub fn noop_fold_lifetime(l: &Lifetime, fld: &mut T) -> Lifetime { } } -pub fn fold_lifetimes(lts: &Vec, fld: &mut T) - -> Vec { +pub fn noop_fold_lifetimes(lts: &[Lifetime], fld: &mut T) -> Vec { lts.iter().map(|l| fld.fold_lifetime(l)).collect() } -pub fn fold_opt_lifetime(o_lt: &Option, fld: &mut T) +pub fn noop_fold_opt_lifetime(o_lt: &Option, fld: &mut T) -> Option { o_lt.as_ref().map(|lt| fld.fold_lifetime(lt)) } -pub fn fold_generics(generics: &Generics, fld: &mut T) -> Generics { - Generics {ty_params: fold_ty_params(&generics.ty_params, fld), - lifetimes: fold_lifetimes(&generics.lifetimes, fld)} +pub fn noop_fold_generics(generics: &Generics, fld: &mut T) -> Generics { + Generics {ty_params: fld.fold_ty_params(generics.ty_params.as_slice()), + lifetimes: fld.fold_lifetimes(generics.lifetimes.as_slice())} } -fn fold_struct_def(struct_def: Gc, +pub fn noop_fold_struct_def(struct_def: Gc, fld: &mut T) -> Gc { box(GC) ast::StructDef { - fields: struct_def.fields.iter().map(|f| fold_struct_field(f, fld)).collect(), + fields: struct_def.fields.iter().map(|f| fld.fold_struct_field(f)).collect(), ctor_id: struct_def.ctor_id.map(|cid| fld.new_id(cid)), super_struct: match struct_def.super_struct { Some(t) => Some(fld.fold_ty(t)), @@ -567,7 +692,7 @@ fn fold_struct_def(struct_def: Gc, } } -fn fold_trait_ref(p: &TraitRef, fld: &mut T) -> TraitRef { +pub fn noop_fold_trait_ref(p: &TraitRef, fld: &mut T) -> TraitRef { let id = fld.new_id(p.ref_id); ast::TraitRef { path: fld.fold_path(&p.path), @@ -575,7 +700,7 @@ fn fold_trait_ref(p: &TraitRef, fld: &mut T) -> TraitRef { } } -fn fold_struct_field(f: &StructField, fld: &mut T) -> StructField { +pub fn noop_fold_struct_field(f: &StructField, fld: &mut T) -> StructField { let id = fld.new_id(f.node.id); Spanned { node: ast::StructField_ { @@ -588,7 +713,7 @@ fn fold_struct_field(f: &StructField, fld: &mut T) -> StructField { } } -fn fold_field_(field: Field, folder: &mut T) -> Field { +pub fn noop_fold_field(field: Field, folder: &mut T) -> Field { ast::Field { ident: respan(field.ident.span, folder.fold_ident(field.ident.node)), expr: folder.fold_expr(field.expr), @@ -596,23 +721,23 @@ fn fold_field_(field: Field, folder: &mut T) -> Field { } } -fn fold_mt(mt: &MutTy, folder: &mut T) -> MutTy { +pub fn noop_fold_mt(mt: &MutTy, folder: &mut T) -> MutTy { MutTy { ty: folder.fold_ty(mt.ty), mutbl: mt.mutbl, } } -fn fold_opt_bounds(b: &Option>, folder: &mut T) +pub fn noop_fold_opt_bounds(b: &Option>, folder: &mut T) -> Option> { b.as_ref().map(|bounds| { bounds.map(|bound| { - fold_ty_param_bound(bound, folder) + folder.fold_ty_param_bound(bound) }) }) } -fn fold_variant_arg_(va: &VariantArg, folder: &mut T) -> VariantArg { +pub fn noop_fold_variant_arg(va: &VariantArg, folder: &mut T) -> VariantArg { let id = folder.new_id(va.id); ast::VariantArg { ty: folder.fold_ty(va.ty), @@ -664,14 +789,14 @@ pub fn noop_fold_item_underscore(i: &Item_, folder: &mut T) -> Item_ folder.fold_fn_decl(&*decl), fn_style, abi, - fold_generics(generics, folder), + folder.fold_generics(generics), folder.fold_block(body) ) } ItemMod(ref m) => ItemMod(folder.fold_mod(m)), ItemForeignMod(ref nm) => ItemForeignMod(folder.fold_foreign_mod(nm)), ItemTy(t, ref generics) => { - ItemTy(folder.fold_ty(t), fold_generics(generics, folder)) + ItemTy(folder.fold_ty(t), folder.fold_generics(generics)) } ItemEnum(ref enum_definition, ref generics) => { ItemEnum( @@ -680,15 +805,15 @@ pub fn noop_fold_item_underscore(i: &Item_, folder: &mut T) -> Item_ folder.fold_variant(&*x) }).collect(), }, - fold_generics(generics, folder)) + folder.fold_generics(generics)) } ItemStruct(ref struct_def, ref generics) => { - let struct_def = fold_struct_def(*struct_def, folder); - ItemStruct(struct_def, fold_generics(generics, folder)) + let struct_def = folder.fold_struct_def(*struct_def); + ItemStruct(struct_def, folder.fold_generics(generics)) } ItemImpl(ref generics, ref ifce, ty, ref methods) => { - ItemImpl(fold_generics(generics, folder), - ifce.as_ref().map(|p| fold_trait_ref(p, folder)), + ItemImpl(folder.fold_generics(generics), + ifce.as_ref().map(|p| folder.fold_trait_ref(p)), folder.fold_ty(ty), methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect() ) @@ -711,9 +836,9 @@ pub fn noop_fold_item_underscore(i: &Item_, folder: &mut T) -> Item_ }; r }).collect(); - ItemTrait(fold_generics(generics, folder), + ItemTrait(folder.fold_generics(generics), unbound.clone(), - traits.iter().map(|p| fold_trait_ref(p, folder)).collect(), + traits.iter().map(|p| folder.fold_trait_ref(p)).collect(), methods) } ItemMac(ref m) => ItemMac(folder.fold_mac(m)), @@ -729,7 +854,7 @@ pub fn noop_fold_type_method(m: &TypeMethod, fld: &mut T) -> TypeMeth fn_style: m.fn_style, abi: m.abi, decl: fld.fold_fn_decl(&*m.decl), - generics: fold_generics(&m.generics, fld), + generics: fld.fold_generics(&m.generics), explicit_self: fld.fold_explicit_self(&m.explicit_self), span: fld.new_span(m.span), vis: m.vis, @@ -750,7 +875,7 @@ pub fn noop_fold_crate(c: Crate, folder: &mut T) -> Crate { Crate { module: folder.fold_mod(&c.module), attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(), - config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(), + config: c.config.iter().map(|x| box (GC) folder.fold_meta_item(&**x)).collect(), span: folder.new_span(c.span), exported_macros: c.exported_macros } @@ -759,12 +884,12 @@ pub fn noop_fold_crate(c: Crate, folder: &mut T) -> Crate { // fold one item into possibly many items pub fn noop_fold_item(i: &Item, folder: &mut T) -> SmallVector> { - SmallVector::one(box(GC) noop_fold_item_(i,folder)) + SmallVector::one(box(GC) folder.fold_item_simple(i)) } // fold one item into exactly one item -pub fn noop_fold_item_(i: &Item, folder: &mut T) -> Item { +pub fn noop_fold_item_simple(i: &Item, folder: &mut T) -> Item { let id = folder.new_id(i.id); // Needs to be first, for ast_map. let node = folder.fold_item_underscore(&i.node); let ident = match node { @@ -795,11 +920,11 @@ pub fn noop_fold_foreign_item(ni: &ForeignItem, node: match ni.node { ForeignItemFn(ref fdec, ref generics) => { ForeignItemFn(P(FnDecl { - inputs: fdec.inputs.iter().map(|a| fold_arg_(a, folder)).collect(), + inputs: fdec.inputs.iter().map(|a| folder.fold_arg(a)).collect(), output: folder.fold_ty(fdec.output), cf: fdec.cf, variadic: fdec.variadic - }), fold_generics(generics, folder)) + }), folder.fold_generics(generics)) } ForeignItemStatic(t, m) => { ForeignItemStatic(folder.fold_ty(t), m) @@ -828,7 +953,7 @@ pub fn noop_fold_method(m: &Method, folder: &mut T) -> SmallVector { MethDecl(folder.fold_ident(ident), - fold_generics(generics, folder), + folder.fold_generics(generics), abi, folder.fold_explicit_self(explicit_self), fn_style, @@ -998,7 +1123,7 @@ pub fn noop_fold_expr(e: Gc, folder: &mut T) -> Gc { ExprMac(ref mac) => ExprMac(folder.fold_mac(mac)), ExprStruct(ref path, ref fields, maybe_expr) => { ExprStruct(folder.fold_path(path), - fields.iter().map(|x| fold_field_(*x, folder)).collect(), + fields.iter().map(|x| folder.fold_field(*x)).collect(), maybe_expr.map(|x| folder.fold_expr(x))) }, ExprParen(ex) => ExprParen(folder.fold_expr(ex)) @@ -1061,7 +1186,7 @@ mod test { token::str_to_ident("zz") } fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac { - fold::fold_mac(macro, self) + fold::noop_fold_mac(macro, self) } } From da6070dbef81c1028ce3e87fd0102b2abbbc181e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Sat, 26 Jul 2014 03:58:48 +0200 Subject: [PATCH 2/2] Add a few more derivings to AST types --- src/libsyntax/ast.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 34de81008711e..8159aee99d12c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -261,7 +261,7 @@ pub struct Crate { pub type MetaItem = Spanned; -#[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)] +#[deriving(Clone, Eq, Encodable, Decodable, Hash, Show)] pub enum MetaItem_ { MetaWord(InternedString), MetaList(InternedString, Vec>), @@ -423,7 +423,7 @@ pub enum LocalSource { // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. /// Local represents a `let` statement, e.g., `let : = ;` -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Local { pub ty: P, pub pat: Gc, @@ -435,7 +435,7 @@ pub struct Local { pub type Decl = Spanned; -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Decl_ { /// A local (let) binding: DeclLocal(Gc), @@ -677,7 +677,7 @@ pub struct MutTy { pub mutbl: Mutability, } -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TypeField { pub ident: Ident, pub mt: MutTy, @@ -1048,7 +1048,7 @@ pub type PathListItem = Spanned; pub type ViewPath = Spanned; -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum ViewPath_ { /// `quux = foo::bar::baz` @@ -1113,7 +1113,7 @@ pub struct Attribute_ { /// that the ref_id is for. The impl_id maps to the "self type" of this impl. /// If this impl is an ItemImpl, the impl_id is redundant (it could be the /// same as the impl's node id). -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TraitRef { pub path: Path, pub ref_id: NodeId, @@ -1169,7 +1169,7 @@ impl StructFieldKind { } } -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct StructDef { /// Fields, not including ctor pub fields: Vec, @@ -1219,7 +1219,7 @@ pub enum Item_ { ItemMac(Mac), } -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct ForeignItem { pub ident: Ident, pub attrs: Vec, @@ -1229,7 +1229,7 @@ pub struct ForeignItem { pub vis: Visibility, } -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum ForeignItem_ { ForeignItemFn(P, Generics), ForeignItemStatic(P, /* is_mutbl */ bool), @@ -1238,7 +1238,7 @@ pub enum ForeignItem_ { /// The data we save and restore about an inlined item or method. This is not /// part of the AST that we parse from a file, but it becomes part of the tree /// that we trans. -#[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum InlinedItem { IIItem(Gc), IIMethod(DefId /* impl id */, bool /* is provided */, Gc),