123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294moduleParsetree=Ppxlib.ParsetreemoduleAsttypes=Ppxlib.AsttypesmoduleLongident=Ppxlib.LongidentmoduleLocation=Ppxlib.LocationopenPpxlib.AstopenPpxlib.Ast_helperletmkloctxtloc={txt;loc}letmkloc_opt?(loc=!default_loc)x=mklocxlocletstr?loc?attrss=Exp.constant?loc?attrs(Const.strings)letpvar?locname=Pat.var?loc(mkloc_opt?locname)letidentx=Exp.ident(mkloc_opt(Longident.Lidentx))letunit?loc?attrs()=Exp.construct?loc?attrs(mkloc_opt?loc(Longident.Lident"()"))Nonelettunit?loc()=Typ.constr(mkloc_opt?loc(Longident.Lident"unit"))[]typeerror=|No_parameter|Missing_parameter_type|Missing_parameter_name|Reserved_parameterofstring|Duplicated_parameterofstring|No_return_typeletprint_error~loc(e:error)=leterror_str=matchewith|No_parameter->"The function must have at least one parameter"|Missing_parameter_type->"Missing parameter type anotation"|Missing_parameter_name->"The parameter should be a variable"|Reserved_parameternm->Printf.sprintf"Parameter '%s' has a reserved name"nm|Duplicated_parameternm->Printf.sprintf"Two parameters have name '%s'"nm|No_return_type->"An Lwt.t return type is mandatory"inLocation.raise_errorf~loc"%s"error_strletrpc_namefun_name=letfilename=Filename.(!Ocaml_common.Location.input_name|>chop_extension|>basename)inFormat.sprintf"%s.%s"filenamefun_nameletexpr_tuplel=matchlwith|[]->unit()|[(_,x,_)]->identx|_->Exp.tuple(List.map(fun(_,x,_)->identx)l)letpat_tuplel=matchlwith|[]->Pat.any()|[(_,x,_)]->pvarx|_->Pat.tuple(List.map(fun(_,x,_)->pvarx)l)lettyp_tuplel=matchlwith|[]->tunit()|[(_,_,ty)]->ty|_->Typ.tuple(List.map(fun(_,_,ty)->ty)l)letexpr_typee=matchewith[%expr([%e?_]:[%t?ty]Lwt.t)]->Somety|_->Noneletreccollect_paramslexpr=matchexprwith|{pexp_desc=Pexp_fun(((Labelledname|Optionalname)aslabel),def,{ppat_desc=Ppat_constraint(_,ty)},expr')}|{pexp_desc=Pexp_fun((Nolabelaslabel),def,{ppat_desc=Ppat_constraint({ppat_desc=Ppat_var{txt=name}},ty)},expr')}|{pexp_desc=Pexp_fun(((Labelledname|Optionalname)aslabel),(Some{pexp_desc=Pexp_constraint(_,ty)}asdef),_,expr')}|{pexp_desc=Pexp_fun((Nolabelaslabel),(Some{pexp_desc=Pexp_constraint(_,ty)}asdef),{ppat_desc=Ppat_var{txt=name}},expr')}->letty=matchlabel,defwith|Optional_,Some_->letloc=ty.ptyp_locin[%type:[%tty]option]|_->tyincollect_params((label,name,ty)::l)expr'|[%exprfun()->[%e?expr']]->(List.revl,true),expr_typeexpr'|{pexp_desc=Pexp_fun(_,_,({ppat_desc=Ppat_constraint(_,_)}asp),_)}->print_error~loc:p.ppat_locMissing_parameter_name|{pexp_desc=Pexp_fun(_,_,p,_)}->print_error~loc:p.ppat_locMissing_parameter_type|_->(List.revl,false),expr_typeexprletparametrizeloc(params,has_unit)expr=List.fold_right(fun(label,x,_)expr->Exp.fun_labelNone(pvarx)expr)params(ifhas_unitthen[%exprfun()->[%eexpr]]elseexpr)letbuild_paramsloc(params,has_unit)=List.map(fun(label,x,_)->label,identx)params@ifhas_unitthen[Nolabel,[%expr()]]else[]letapplyargsexpr=Exp.applyexprargsletserver_function~loc~kind~fun_varexpr'=letexpr=matchkindwith|`Connected->[%exprfun(myid:Os_types.User.id)->[%eexpr']]|`Any->[%exprfun(myid_o:Os_types.User.idoption)->[%eexpr']]|`None->expr'in[%strilet%server[%pfun_var]=[%eexpr]]letserver_cacher~loc~kind~cache~fun_name~fun_var~params=matchcachewith|None->[%strilet%server_=()]|Somereturn_typ->letid_param=matchkindwith|`Connected->[Nolabel,[%exprmyid]]|`Any->[Nolabel,[%exprmyid_o]]|`None->[]inletcacheexpr=[%exprlet%lwtx=[%eexpr]inBs_proxy.cache[%derive.caching:[%treturn_typ]]x]inletparametrize_idexpr=matchkindwith|`Connected->[%exprfunmyid->[%eexpr]]|`Any->[%exprfunmyid_o->[%eexpr]]|`None->exprinletexpr=fun_name|>ident|>apply(id_param@build_paramslocparams)|>cache|>parametrizelocparams|>parametrize_idin[%strilet%server[%pfun_var]=[%eexpr][@@ocaml.warning"-16"]]letserver_wrapper~loc~kind~raw~cache~fun_name~fun_var~params=ifrawthen[%strilet%server_=()]elseletid_param=matchkindwith|`Connected->[Nolabel,[%exprOs_current_user.get_current_userid()]]|`Any->[Nolabel,[%exprOs_current_user.Opt.get_current_userid()]]|`None->[]inletuncacheexpr=ifcache<>Nonethen[%exprBs_proxy.extract[%eexpr]]elseexprinletexpr=fun_name|>ident|>apply(id_param@build_paramslocparams)|>uncache|>parametrizelocparamsin[%strilet%server[%pfun_var]=[%eexpr][@@ocaml.warning"-16-32"]]letclient_wrapper~loc~kind~raw~cache~fun_name~fun_var~params=letid_param=matchkindwith|`Connected->[Nolabel,[%exprmyid]]|`Any->[Nolabel,[%exprmyid_o]]|`None->[]inletuncacheexpr=ifcache<>Nonethen[%exprBs_proxy.extract[%eexpr]]elseexprinletparametrize'expr=[%exprfun[%ppat_tuple(fstparams)]->[%eexpr]]inletparametrize_idexpr=matchkindwith|`Connected->[%exprfunmyid->[%eexpr]]|`Any->[%exprfunmyid_o->[%eexpr]]|`None->exprinletwrapexpr=ifrawthenexprelsematchkindwith|`Connected->[%exprOs_session.connected_rpc[%eexpr]]|`Any->[%exprOs_session.Opt.connected_rpc[%eexpr]]|`None->[%exprOs_session.connected_wrapper[%eexpr]]inletexpr=fun_name|>ident|>apply(id_param@build_paramslocparams)|>uncache|>parametrize'|>parametrize_id|>wrapinletexpr=[%expr~%(Eliom_client.server_function~name:[%estr(rpc_namefun_name)][%json:[%ttyp_tuple(fstparams)]][%eexpr])[%eexpr_tuple(fstparams)]]in[%strilet%client[%pfun_var]=[%eparametrizelocparamsexpr][@@ocaml.warning"-16"]]letraw=reffalseletcache=reffalseletextension~legacy~loc~path:_fun_nameexpr=letraw=!raw&¬!cacheinletcache=(notlegacy)&&!cacheinletfun_var=pvar~loc:fun_name.locfun_name.txtinletfun_name=fun_name.txtinletkind,expr'=ifrawthen`None,exprelsematchexprwith|[%exprfunmyid->[%e?expr']]->`Connected,expr'|[%exprfunmyid_o->[%e?expr']]->`Any,expr'|_->`None,exprinletparams,return_typ=collect_params[]expr'in(matchparamswith|[],false->print_error~locNo_parameter|l,_->ignore(List.fold_left(funacc(_,nm,_)->ifList.memnmaccthenprint_error~loc(Duplicated_parameternm);ifnm="myid"||nm="myid_o"thenprint_error~loc(Reserved_parameternm);nm::acc)[]l));ifcache&&return_typ=Nonethenprint_error~locNo_return_type;letcache=ifcachethenreturn_typelseNoneinStr.include_~loc(Incl.mk~loc(Mod.structure~loc[server_function~loc~kind~fun_varexpr';server_cacher~loc~kind~cache~fun_name~fun_var~params;client_wrapper~loc~kind~raw~cache~fun_name~fun_var~params;server_wrapper~loc~kind~raw~cache~fun_name~fun_var~params]))letextensions=letopenPpxlibinList.concat@@List.map(fun(legacy,exts)->List.map(funext->Extension.declareextExtension.Context.structure_item(letopenAst_patterninpstr(pstr_valuenonrecursive(value_binding~pat:(ppat_var__')~expr:__^::nil)^::nil))(extension~legacy))exts)[true,["cw_rpc";"crpc";"crpc_opt"];false,["rpc"]]letdriver_args=[("--rpc-raw",Arg.Unit(fun()->raw:=true)," Do not insert any ocsigen-start session wrapper.");("--rpc-cache",Arg.Unit(fun()->cache:=true)," Insert caching directives (for internal use at Be Sport).")]let()=List.iter(fun(key,spec,doc)->Ppxlib.Driver.add_argkeyspec~doc)driver_argsletrules=List.mapPpxlib.Context_free.Rule.extensionextensionslet()=Ppxlib.Driver.register_transformation~rules"rpc"