Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_eliom_client.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267openPpxlibopenAst_helperopenPpx_eliom_utilsletattribute_of_warninglocs=Attr.mk{loc;txt="ocaml.ppwarning"}(PStr[Str.eval~loc(Exp.constant(Const.strings))])modulePass=struct(** {2 Auxiliaries} *)(* Replace every escaped identifier [v] with
[Eliom_client_core.Syntax_helpers.get_escaped_value v] *)letmap_get_escaped_valuesexpr=(objectinheritPpxlib.Ast_traverse.mapassupermethod!expressione=matche.pexp_descwith|Pexp_ident{txt;_}whenMli.is_escaped_ident@@Longident.last_exntxt->letloc=e.pexp_locin[%exprEliom_client_core.Syntax_helpers.get_escaped_value[%ee]]|_->super#expressioneend)#expressionexprletpush_escaped_binding,flush_escaped_bindings=letserver_arg_ids=ref[]inletpushgen_id(expr:expression)get_type=matchList.find_opt(fun(gen_id',_,_)->gen_id.txt=gen_id'.txt)!server_arg_idswith|Some(_,_,typ)->typ|None->lettyp=get_type()inserver_arg_ids:=(gen_id,expr,typ)::!server_arg_ids;typinletflush()=letres=List.rev!server_arg_idsinserver_arg_ids:=[];resinpush,flushletmark_injection,flush_injection=lethas_injection=reffalseinletmark()=has_injection:=trueinletflush()=letx=!has_injectioninhas_injection:=false;xinmark,flushletpush_client_value_data,flush_client_value_datas=letclient_value_datas=ref[]inletpushlocgen_numgen_idexpr(args:stringLocation.loclist)=client_value_datas:=(loc,gen_num,gen_id,expr,args)::!client_value_datasinletflush()=letres=List.rev!client_value_datasinclient_value_datas:=[];resinpush,flushletfind_escaped_identlocid=ifMli.exists()thenMli.find_escaped_identidelseifCmo.exists()thenCmo.find_escaped_identlocelse[%type:_]letfind_injected_identlocid=ifMli.exists()thenMli.find_injected_identidelseifCmo.exists()thenCmo.find_injected_identlocelse[%type:_]letfind_fragmentlocid=ifMli.exists()thenMli.find_fragmentidelseifCmo.exists()thenCmo.find_fragmentlocelse[%type:_]letregister_client_closuresclient_value_datas=letregistrations=List.map(fun(loc,num,id,expr,args)->lettyp=find_fragmentlocidinletargs=List.mapPat.varargsinletloc=expr.pexp_locin[%exprEliom_client_core.Syntax_helpers.register_client_closure[%estrnum](fun[%ppat_argsargs]:[%ttyp]->[%emap_get_escaped_valuesexpr])])client_value_datasinmatchregistrationswith|[]->[]|_->[Str.eval(sequenceregistrations)](* We hoist the body of client fragments to enforce the correct scoping:
Identifiers declared earlier in the client section should not be
visible inside the client fragment (unless via escaped value). *)letdefine_client_functions~locclient_value_datas=matchclient_value_dataswith|[]->[]|_->letbindings=List.map(fun(loc,_num,id,expr,args)->letpatt=Pat.varidinlettyp=find_fragmentlocidinletargs=List.mapPat.varargsinletexpr=[%exprfun[%ppat_argsargs]:[%ttyp]->[%eexpr]]inVb.mk~locpattexpr)client_value_datasin[Str.value~locNonrecursivebindings](* For injections *)letclose_server_sectionloc=[%strilet()=Eliom_client_core.Syntax_helpers.close_server_section[%eeid@@id_file_hashloc]]letmay_close_server_section~no_fragmentitem=ifno_fragmentthen[]else[close_server_sectionitem.pstr_loc]letopen_client_sectionloc=[%strilet()=Eliom_client_core.Syntax_helpers.open_client_section[%eeid@@id_file_hashloc]]letmay_open_client_sectionloc=ifflush_injection()then[open_client_sectionloc]else[](** Syntax extension *)letclient_stritem=letloc=item.pstr_locinmay_open_client_sectionloc@[item]letserver_strno_fragmentitem=register_client_closures(flush_client_value_datas())@may_close_server_section~no_fragmentitemletshared_strno_fragmentitem=letloc=item.pstr_locinletclient_expr_data=flush_client_value_datas()inletop=may_open_client_sectionlocinop@register_client_closuresclient_expr_data@define_client_functions~locclient_expr_data@[item]@may_close_server_section~no_fragment:(no_fragment||op<>[])itemletfragment~loc?typ~context~num~id~unsafeexpr=letfrag_eid=eididinletescaped_bindings=flush_escaped_bindings()in(matchtypwith|Some_->()|Nonewhennot(Mli.exists()||Cmo.exists())->()|None->(matchfind_fragmentlocidwith|{ptyp_desc=Ptyp_var_;_}whennotunsafe->Location.raise_errorf~loc"The types of client values must be monomorphic from its usage or from its type annotation"|_->()));push_client_value_datalocnumidexpr(List.map(fun(gen_id,_,_)->gen_id)escaped_bindings);matchcontext,escaped_bindingswith|`Server,_->(* We are in a server fragment, this code should always be discarded. *)Exp.extension@@Location.Error.to_extension@@Location.Error.make~loc~sub:[]"Eliom: ICE"|`Shared,[]->[%expr[%efrag_eid]()]|`Shared,_->letbindings=List.map(fun(gen_id,expr,_)->Vb.mk~loc:expr.pexp_loc(Pat.vargen_id)expr)escaped_bindingsinletargs=format_args@@List.map(fun(id,_,_)->eidid)escaped_bindingsinExp.let_~locNonrecursivebindings[%expr[%efrag_eid][%eargs]]letcheck_no_variable=(objectinheritPpxlib.Ast_traverse.mapassupermethod!core_typetyp=matchtypwith|{ptyp_desc=Ptyp_var_;ptyp_loc=loc;_}->letattr=attribute_of_warningloc"The type of this injected value contains a type variable that could be wrongly inferred."in{typwithptyp_attributes=attr::typ.ptyp_attributes;ptyp_loc=loc}|_->super#core_typetypend)#core_typeletescape_inject~loc:loc0?ident~(context:Context.escape_inject)~id~unsafeexpr=letloc=expr.pexp_locinletfrag_eid=eididinletassert_no_variablest=ifunsafethentelsecheck_no_variabletinmatchcontextwith(* [%%server [%client ~%( ... ) ] ] *)|`Escaped_value_section->lettyp=push_escaped_bindingidexpr(fun()->lettyp=find_escaped_identloc0idinlettyp=assert_no_variablestypintyp)in[%expr([%efrag_eid]:[%ttyp])](* [%%server ... %x ... ] *)|`Injection_section->mark_injection();lettyp=find_injected_identloc0idinlettyp=assert_no_variablestypinletident=matchidentwith|None->[%exprNone]|Somei->[%exprSome[%estri]]inletu,d=Mli.get_injected_ident_infoid.txtinletes=str~loc:id.loc(Printf.sprintf"%s%d"ud)in[%expr(Eliom_client_core.Syntax_helpers.get_injection?ident:[%eident]~pos:[%epositionloc][%ees]:[%ttyp])]letshared_sigitem=[item]letserver_sig_=[]letclient_sigitem=[item]letprelude_=[]letpostlude_=[]endincludeMake(Pass)let()=Ppxlib.Driver.register_transformation~impl:mapper#structure~intf:mapper#signature"ppx_eliom_client"