123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121(*
* Generic transformers: plugins.
* Copyright (C) 2016-2019
* Dmitrii Kosarev aka Kakadu
* St.Petersburg State University, JetBrains Research
*)(** {i Foldl} plugin: fold all values in a type.
Essentially is a stub that chains inherited attribute thorough all values
in the value
For type declaration [type ('a,'b,...) typ = ...] it will create a transformation
function with type
[('s -> 'a -> 's) ->
('s -> 'b -> 's) ->
... ->
's -> ('a,'b,...) typ -> 's ]
*)openPpxlibopenPrintfopenGTCommonopenHelpersBaselettrait_name="foldl"moduleMake(AstHelpers:GTHELPERS_sig.S)=structopenAstHelpersmoduleP=Plugin.Make(AstHelpers)lettrait_name=trait_nameletmake_dest_param_namesps=map_type_param_namesps~f:(Printf.sprintf"%s_2")classginitial_argstdecls=object(self:'self)inheritP.with_inherited_attrinitial_argstdeclsmethodtrait_name=trait_namemethodsyn_of_param~locs=Typ.var~loc"syn"methodinh_of_main~loctdecl=self#syn_of_main~loctdeclmethodsyn_of_main~loc?in_classtdecl=self#syn_of_param~loc"dummy"methodinh_of_param~loctdecl_=self#syn_of_param~loc"dummy"methodplugin_class_params~loctyps~typname=List.maptyps~f:Typ.from_caml@[Typ.var~loc"syn";Typ.var~loc@@Naming.make_extra_paramtypname](* new type of trasfomation function is 'syn -> old_type *)method!make_typ_of_class_argument:'a.loc:loc->type_declaration->(Typ.t->'a->'a)->string->(('a->'a)->'a->'a)->'a->'a=fun~loctdeclchainnamek->letsubj_t=Typ.var~locnameinletsyn_t=self#syn_of_param~locnameinletinh_t=self#inh_of_param~loctdeclnameink@@chain(Typ.arrow~locinh_t@@Typ.arrow~locsubj_tsyn_t)methodjoin_args~locdo_typ~init(xs:(string*core_type)list)=List.fold_left~f:(funacc(name,typ)->Exp.app_list~loc(do_typtyp)[acc;Exp.sprintf~loc"%s"name])~initxsmethodon_tuple_constr~loc~is_self_rec~mutual_decls~inhetdeclconstr_infoargs=self#join_args~loc~init:inhe(self#do_typ_gen~loc~is_self_rec~mutual_declstdecl)argsmethodon_record_declaration~loc~is_self_rec~mutual_declstdecllabs=(* TODO: introduce fresh pattern names here *)letpat=Pat.record~loc@@List.maplabs~f:(funl->Lidentl.pld_name.txt,Pat.var~locl.pld_name.txt)inletmethname=sprintf"do_%s"tdecl.ptype_name.txtin[Cf.method_concrete~locmethname@@Exp.fun_list~loc[Pat.sprintf~loc"inh";pat]@@self#join_args~loc~init:(Exp.ident~loc"inh")(self#do_typ_gen~loc~is_self_rec~mutual_declstdecl)(List.maplabs~f:(funl->l.pld_name.txt,l.pld_type))]method!on_record_constr~loc~is_self_rec~mutual_decls~inhetdecl_infobindingslabs=assert(List.lengthlabs>0);Exp.fun_list~loc(List.mapbindings~f:(fun(s,_,_)->Pat.sprintf~loc"%s"s))@@self#join_args~loc~init:inhe(self#do_typ_gen~loc~is_self_rec~mutual_declstdecl)(List.mapbindings~f:(fun(name,_,typ)->name,typ))endletcreate=(newg:>P.plugin_constructor)endletregister()=Expander.register_plugintrait_name(moduleMake:Plugin_intf.MAKE)let()=register()