(***********************************************************************) (* *) (* OCaml *) (* *) (* Alain Frisch, LexiFi *) (* *) (* Copyright 2012 Institut National de Recherche en Informatique et *) (* en Automatique. All rights reserved. This file is distributed *) (* under the terms of the Q Public License version 1.0. *) (* *) (***********************************************************************) open Asttypes open Typedtree let opt f = function None -> () | Some x -> f x let structure sub str = List.iter (sub # structure_item) str.str_items let structure_item sub x = match x.str_desc with | Tstr_eval exp -> sub # expression exp | Tstr_value (rec_flag, list) -> sub # bindings (rec_flag, list) | Tstr_primitive (_id, _, v) -> sub # value_description v | Tstr_type list -> List.iter (fun (_id, _, decl) -> sub # type_declaration decl) list | Tstr_exception (_id, _, decl) -> sub # exception_declaration decl | Tstr_exn_rebind (_id, _, _p, _) -> () | Tstr_module (_id, _, mexpr) -> sub # module_expr mexpr | Tstr_recmodule list -> List.iter (fun (_id, _, mtype, mexpr) -> sub # module_type mtype; sub # module_expr mexpr ) list | Tstr_modtype (_id, _, mtype) -> sub # module_type mtype | Tstr_open _ -> () | Tstr_class list -> List.iter (fun (ci, _, _) -> sub # class_expr ci.ci_expr) list | Tstr_class_type list -> List.iter (fun (_id, _, ct) -> sub # class_type ct.ci_expr) list | Tstr_include (mexpr, _) -> sub # module_expr mexpr let value_description sub x = sub # core_type x.val_desc let type_declaration sub decl = List.iter (fun (ct1, ct2, _loc) -> sub # core_type ct1; sub # core_type ct2) decl.typ_cstrs; begin match decl.typ_kind with | Ttype_abstract -> () | Ttype_variant list -> List.iter (fun (_s, _, cts, _loc) -> List.iter (sub # core_type) cts) list | Ttype_record list -> List.iter (fun (_s, _, _mut, ct, _loc) -> sub # core_type ct) list end; opt (sub # core_type) decl.typ_manifest let exception_declaration sub decl = List.iter (sub # core_type) decl.exn_params let pattern sub pat = let extra = function | Tpat_type _ | Tpat_unpack -> () | Tpat_constraint ct -> sub # core_type ct in List.iter (fun (c, _) -> extra c) pat.pat_extra; match pat.pat_desc with | Tpat_any | Tpat_var _ | Tpat_constant _ -> () | Tpat_tuple l | Tpat_construct (_, _, l, _) -> List.iter (sub # pattern) l | Tpat_variant (_, po, _) -> opt (sub # pattern) po | Tpat_record (l, _) -> List.iter (fun (_, _, pat) -> sub # pattern pat) l | Tpat_array l -> List.iter (sub # pattern) l | Tpat_or (p1, p2, _) -> sub # pattern p1; sub # pattern p2 | Tpat_alias (p, _, _) | Tpat_lazy p -> sub # pattern p let expression sub exp = let extra = function | Texp_constraint (cty1, cty2) -> opt (sub # core_type) cty1; opt (sub # core_type) cty2 | Texp_open _ | Texp_newtype _ -> () | Texp_poly cto -> opt (sub # core_type) cto in List.iter (function (c, _) -> extra c) exp.exp_extra; match exp.exp_desc with | Texp_ident _ | Texp_constant _ -> () | Texp_let (rec_flag, list, exp) -> sub # bindings (rec_flag, list); sub # expression exp | Texp_function (_, cases, _) -> sub # bindings (Nonrecursive, cases) | Texp_apply (exp, list) -> sub # expression exp; List.iter (fun (_, expo, _) -> opt (sub # expression) expo) list | Texp_match (exp, list, _) -> sub # expression exp; sub # bindings (Nonrecursive, list) | Texp_try (exp, list) -> sub # expression exp; sub # bindings (Nonrecursive, list) | Texp_tuple list -> List.iter (sub # expression) list | Texp_construct (_, _, args, _) -> List.iter (sub # expression) args | Texp_variant (_, expo) -> opt (sub # expression) expo | Texp_record (list, expo) -> List.iter (fun (_, _, exp) -> sub # expression exp) list; opt (sub # expression) expo | Texp_field (exp, _, _label) -> sub # expression exp | Texp_setfield (exp1, _, _label, exp2) -> sub # expression exp1; sub # expression exp2 | Texp_array list -> List.iter (sub # expression) list | Texp_ifthenelse (exp1, exp2, expo) -> sub # expression exp1; sub # expression exp2; opt (sub # expression) expo | Texp_sequence (exp1, exp2) -> sub # expression exp1; sub # expression exp2 | Texp_while (exp1, exp2) -> sub # expression exp1; sub # expression exp2 | Texp_for (_id, _, exp1, exp2, _dir, exp3) -> sub # expression exp1; sub # expression exp2; sub # expression exp3 | Texp_when (exp1, exp2) -> sub # expression exp1; sub # expression exp2 | Texp_send (exp, _meth, expo) -> sub # expression exp; opt (sub # expression) expo | Texp_new (_path, _, _) -> () | Texp_instvar (_, _path, _) -> () | Texp_setinstvar (_, _, _, exp) -> sub # expression exp | Texp_override (_, list) -> List.iter (fun (_path, _, exp) -> sub # expression exp) list | Texp_letmodule (_id, _, mexpr, exp) -> sub # module_expr mexpr; sub # expression exp | Texp_assert exp -> sub # expression exp | Texp_assertfalse -> () | Texp_lazy exp -> sub # expression exp | Texp_object (cl, _) -> sub # class_structure cl | Texp_pack (mexpr) -> sub # module_expr mexpr let package_type sub pack = List.iter (fun (_s, ct) -> sub # core_type ct) pack.pack_fields let signature sub sg = List.iter (sub # signature_item) sg.sig_items let signature_item sub item = match item.sig_desc with | Tsig_value (_id, _, v) -> sub # value_description v | Tsig_type list -> List.iter (fun (_id, _, decl) -> sub # type_declaration decl) list | Tsig_exception (_id, _, decl) -> sub # exception_declaration decl | Tsig_module (_id, _, mtype) -> sub # module_type mtype | Tsig_recmodule list -> List.iter (fun (_id, _, mtype) -> sub # module_type mtype) list | Tsig_modtype (_id, _, mdecl) -> sub # modtype_declaration mdecl | Tsig_open _ -> () | Tsig_include (mty,_) -> sub # module_type mty | Tsig_class list -> List.iter (sub # class_description) list | Tsig_class_type list -> List.iter (sub # class_type_declaration) list let modtype_declaration sub mdecl = match mdecl with | Tmodtype_abstract -> () | Tmodtype_manifest mtype -> sub # module_type mtype let class_description sub cd = sub # class_type cd.ci_expr let class_type_declaration sub cd = sub # class_type cd.ci_expr let module_type sub mty = match mty.mty_desc with | Tmty_ident (_path, _) -> () | Tmty_signature sg -> sub # signature sg | Tmty_functor (_id, _, mtype1, mtype2) -> sub # module_type mtype1; sub # module_type mtype2 | Tmty_with (mtype, list) -> sub # module_type mtype; List.iter (fun (_, _, withc) -> sub # with_constraint withc) list | Tmty_typeof mexpr -> sub # module_expr mexpr let with_constraint sub cstr = match cstr with | Twith_type decl -> sub # type_declaration decl | Twith_module _ -> () | Twith_typesubst decl -> sub # type_declaration decl | Twith_modsubst _ -> () let module_expr sub mexpr = match mexpr.mod_desc with | Tmod_ident (_p, _) -> () | Tmod_structure st -> sub # structure st | Tmod_functor (_id, _, mtype, mexpr) -> sub # module_type mtype; sub # module_expr mexpr | Tmod_apply (mexp1, mexp2, _) -> sub # module_expr mexp1; sub # module_expr mexp2 | Tmod_constraint (mexpr, _, Tmodtype_implicit, _ ) -> sub # module_expr mexpr | Tmod_constraint (mexpr, _, Tmodtype_explicit mtype, _) -> sub # module_expr mexpr; sub # module_type mtype | Tmod_unpack (exp, _mty) -> sub # expression exp (* sub # module_type mty *) let class_expr sub cexpr = match cexpr.cl_desc with | Tcl_constraint (cl, None, _, _, _ ) -> sub # class_expr cl; | Tcl_structure clstr -> sub # class_structure clstr | Tcl_fun (_label, pat, priv, cl, _partial) -> sub # pattern pat; List.iter (fun (_id, _, exp) -> sub # expression exp) priv; sub # class_expr cl | Tcl_apply (cl, args) -> sub # class_expr cl; List.iter (fun (_label, expo, _) -> opt (sub # expression) expo) args | Tcl_let (rec_flat, bindings, ivars, cl) -> sub # bindings (rec_flat, bindings); List.iter (fun (_id, _, exp) -> sub # expression exp) ivars; sub # class_expr cl | Tcl_constraint (cl, Some clty, _vals, _meths, _concrs) -> sub # class_expr cl; sub # class_type clty | Tcl_ident (_, _, tyl) -> List.iter (sub # core_type) tyl let class_type sub ct = match ct.cltyp_desc with | Tcty_signature csg -> sub # class_signature csg | Tcty_constr (_path, _, list) -> List.iter (sub # core_type) list | Tcty_fun (_label, ct, cl) -> sub # core_type ct; sub # class_type cl let class_signature sub cs = sub # core_type cs.csig_self; List.iter (sub # class_type_field) cs.csig_fields let class_type_field sub ctf = match ctf.ctf_desc with | Tctf_inher ct -> sub # class_type ct | Tctf_val (_s, _mut, _virt, ct) -> sub # core_type ct | Tctf_virt (_s, _priv, ct) -> sub # core_type ct | Tctf_meth (_s, _priv, ct) -> sub # core_type ct | Tctf_cstr (ct1, ct2) -> sub # core_type ct1; sub # core_type ct2 let core_type sub ct = match ct.ctyp_desc with | Ttyp_any -> () | Ttyp_var _s -> () | Ttyp_arrow (_label, ct1, ct2) -> sub # core_type ct1; sub # core_type ct2 | Ttyp_tuple list -> List.iter (sub # core_type) list | Ttyp_constr (_path, _, list) -> List.iter (sub # core_type) list | Ttyp_object list -> List.iter (sub # core_field_type) list | Ttyp_class (_path, _, list, _labels) -> List.iter (sub # core_type) list | Ttyp_alias (ct, _s) -> sub # core_type ct | Ttyp_variant (list, _bool, _labels) -> List.iter (sub # row_field) list | Ttyp_poly (_list, ct) -> sub # core_type ct | Ttyp_package pack -> sub # package_type pack let core_field_type sub cft = match cft.field_desc with | Tcfield_var -> () | Tcfield (_s, ct) -> sub # core_type ct let class_structure sub cs = sub # pattern cs.cstr_pat; List.iter (sub # class_field) cs.cstr_fields let row_field sub rf = match rf with | Ttag (_label, _bool, list) -> List.iter (sub # core_type) list | Tinherit ct -> sub # core_type ct let class_field sub cf = match cf.cf_desc with | Tcf_inher (_ovf, cl, _super, _vals, _meths) -> sub # class_expr cl | Tcf_constr (cty, cty') -> sub # core_type cty; sub # core_type cty' | Tcf_val (_lab, _, _, _mut, Tcfk_virtual cty, _override) -> sub # core_type cty | Tcf_val (_lab, _, _, _mut, Tcfk_concrete exp, _override) -> sub # expression exp | Tcf_meth (_lab, _, _priv, Tcfk_virtual cty, _override) -> sub # core_type cty | Tcf_meth (_lab, _, _priv, Tcfk_concrete exp, _override) -> sub # expression exp | Tcf_init exp -> sub # expression exp let bindings sub (_rec_flag, list) = List.iter (sub # binding) list let binding sub (pat, exp) = sub # pattern pat; sub # expression exp class iter = object(this) method binding = binding this method bindings = bindings this method class_description = class_description this method class_expr = class_expr this method class_field = class_field this method class_signature = class_signature this method class_structure = class_structure this method class_type = class_type this method class_type_declaration = class_type_declaration this method class_type_field = class_type_field this method core_field_type = core_field_type this method core_type = core_type this method exception_declaration = exception_declaration this method expression = expression this method modtype_declaration = modtype_declaration this method module_expr = module_expr this method module_type = module_type this method package_type = package_type this method pattern = pattern this method row_field = row_field this method signature = signature this method signature_item = signature_item this method structure = structure this method structure_item = structure_item this method type_declaration = type_declaration this method value_description = value_description this method with_constraint = with_constraint this end