// FIXME: Random import to solve the mystery resolve bug import std; export fold; export fold_crate, fold_mod, fold_fn, fold_modlist, fold_fnlist; export default_seq_fold; export default_seq_fold_crate; export default_seq_fold_mod; export default_seq_fold_fn; export default_seq_fold_fnlist; enum fold = t; type fold_crate = fn~(fold: fold, doc: doc::cratedoc) -> doc::cratedoc; type fold_mod = fn~(fold: fold, doc: doc::moddoc) -> doc::moddoc; type fold_fn = fn~(fold: fold, doc: doc::fndoc) -> doc::fndoc; type fold_const = fn~(fold: fold, doc: doc::constdoc) -> doc::constdoc; type fold_modlist = fn~(fold: fold, list: doc::modlist) -> doc::modlist; type fold_fnlist = fn~(fold: fold, list: doc::fnlist) -> doc::fnlist; type fold_constlist = fn~( fold: fold, list: doc::constlist ) -> doc::constlist; type t = { ctxt: T, fold_crate: fold_crate, fold_mod: fold_mod, fold_fn: fold_fn, fold_const: fold_const, fold_modlist: fold_modlist, fold_fnlist: fold_fnlist, fold_constlist: fold_constlist }; // This exists because fn types don't infer correctly as record // initializers, but they do as function arguments fn mk_fold( ctxt: T, fold_crate: fold_crate, fold_mod: fold_mod, fold_fn: fold_fn, fold_const: fold_const, fold_modlist: fold_modlist, fold_fnlist: fold_fnlist, fold_constlist: fold_constlist ) -> fold { fold({ ctxt: ctxt, fold_crate: fold_crate, fold_mod: fold_mod, fold_fn: fold_fn, fold_const: fold_const, fold_modlist: fold_modlist, fold_fnlist: fold_fnlist, fold_constlist: fold_constlist }) } fn default_seq_fold(ctxt: T) -> fold { mk_fold( ctxt, {|f, d| default_seq_fold_crate(f, d)}, {|f, d| default_seq_fold_mod(f, d)}, {|f, d| default_seq_fold_fn(f, d)}, {|f, d| default_seq_fold_const(f, d)}, {|f, d| default_seq_fold_modlist(f, d)}, {|f, d| default_seq_fold_fnlist(f, d)}, {|f, d| default_seq_fold_constlist(f, d)} ) } fn default_seq_fold_crate( fold: fold, doc: doc::cratedoc ) -> doc::cratedoc { ~{ topmod: fold.fold_mod(fold, doc.topmod) } } fn default_seq_fold_mod( fold: fold, doc: doc::moddoc ) -> doc::moddoc { ~{ mods: fold.fold_modlist(fold, doc.mods), fns: fold.fold_fnlist(fold, doc.fns) with *doc } } fn default_seq_fold_fn( _fold: fold, doc: doc::fndoc ) -> doc::fndoc { doc } fn default_seq_fold_const( _fold: fold, doc: doc::constdoc ) -> doc::constdoc { doc } fn default_seq_fold_modlist( fold: fold, list: doc::modlist ) -> doc::modlist { doc::modlist(vec::map(*list) {|doc| fold.fold_mod(fold, doc) }) } fn default_seq_fold_fnlist( fold: fold, list: doc::fnlist ) -> doc::fnlist { doc::fnlist(vec::map(*list) {|doc| fold.fold_fn(fold, doc) }) } fn default_seq_fold_constlist( fold: fold, list: doc::constlist ) -> doc::constlist { doc::constlist(vec::map(*list) {|doc| fold.fold_const(fold, doc) }) } #[test] fn default_fold_should_produce_same_doc() { let source = "mod a { fn b() { } mod c { fn d() { } } }"; let ast = parse::from_str(source); let doc = extract::extract(ast, ""); let fld = default_seq_fold(()); let folded = fld.fold_crate(fld, doc); assert doc == folded; } #[test] fn default_fold_should_produce_same_consts() { let source = "const a: int = 0;"; let ast = parse::from_str(source); let doc = extract::extract(ast, ""); let fld = default_seq_fold(()); let folded = fld.fold_crate(fld, doc); assert doc == folded; }