123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768(*
* Generic Transformers: Camlp5 syntax extension.
* Copyright (C) 2016-2019
* Dmitrii Kosarev aka Kakadu
* St.Petersburg State University, JetBrains Research
*)(**
Implementation of the [GTHELPERS_sig.S] interface which
allows construction of Camlp5 parse tree
*)#load"q_MLast.cmo";;(* Camlp5 AST
https://github.com/camlp5/camlp5/blob/master/main/mLast.mli
Camlp5 doc
https://camlp5.github.io/doc/htmlc/ast_strict.html
*)openGTCommonopenPlocopenMLastmoduleLocated=structtypet=Ploc.tletmk~loclident=lidentendtypeloc=Located.tletloc_from_camlcamlloc=letopenPpxlib.Locationinlet{loc_start;loc_end}=camllocinPloc.make_locloc_start.pos_fnameloc_start.pos_lnumloc_start.pos_bol(loc_start.pos_bol,loc_start.pos_bol+loc_start.pos_cnum)""letnoloc=Ploc.dummytypetype_arg=MLast.type_varletnamed_type_arg~locs:type_arg=(Ploc.VaVal(Somes),None)typelab_decl=(loc*string*bool*ctyp)letlab_decl~locnameis_muttyp=(loc,name,is_mut,typ)typecase=patt*exproption*exprletcase~lhs~rhs:case=(lhs,None,rhs)letsep_lastl=matchList.revlwithlast::rev_pfx->(last,List.revrev_pfx)|[]->failwith"sep_last must be called with nonempty list"letcapitalizeds=assert(s<>"");letc1=String.gets0inChar.(equal(uppercase_asciic1)c1)moduleLongid=structtypet=MLast.longidletof_longident~loclid=letopenPpxlib.Longidentinletrectrec=functionLidentswhencapitalizeds-><:extended_longident<$uid:s$>>|Ldot(li,s)whencapitalizeds-><:extended_longident<$longid:trecli$.$uid:s$>>|Ldot(_,s)whennot(capitalizeds)->Ploc.raiseloc(Failure"Longid.of_longident: should not be called with lowercase ids(1)")|Lidentswhennot(capitalizeds)->Ploc.raiseloc(Failure"Longid.of_longident: should not be called with lowercase ids(2)")|Lapply_->Ploc.raiseloc(Failure"Longid.of_longident: should not be called with Lapply")|_->assertfalseintreclidendmodulePat=structtypet=MLast.pattletany~loc=<:patt<_>>letlid~locs=<:patt<$lid:s$>>letvar=lidletsprintf~locfmt=Printf.ksprintf(funs-><:patt<$lid:s$>>)fmtletof_longident~loclid=letis_lidents=not(capitalizeds)inmatchlidwithLongident.Lidentswhenis_lidents-><:patt<$lid:s$>>|Ldot(li,s)whenis_lidents->letli=Longid.of_longident~locliin<:patt<$longid:li$.$lid:s$>>|li->letli=Longid.of_longident~locliin<:patt<$longid:li$>>letaccess2~locmn=of_longident~loc(Ldot(Lidentm,n))letconstraint_~locpt=<:patt<($p$:$t$)>>letconstr_record~locuidps=failwith"Record constructors are not available for camlp5"letconstr~locuidps=assert(uid<>"");letc=<:patt<$uid:uid$>>inmatchpswith|[]->c|[x]-><:patt<$c$$x$>>|_->letargs=<:patt<($list:ps$)>>in<:patt<$c$$args$>>lettype_~loclident=<:patt<#$lilongid:Asttools.longident_lident_of_string_listloc(Longident.flattenlident)$>>letrecord~locfs=<:patt<{$list:List.map(fun(l,r)->(of_longident~locl,r))fs$}>>letrecord1~locident=record~loc[ident,of_longident~loc@@HelpersBase.lident_tailident]lettuple~locps=<:patt<($list:ps$)>>letvariant~locnameargs=letv=<:patt<`$name$>>inmatchargswith|[]->v|[x]-><:patt<$v$$x$>>|_->lettup=tuple~locargsin<:patt<$v$$tup$>>letalias~locp1name=letright=<:patt<$lid:name$>>in<:patt<(($p1$)as$right$)>>letoptional~locp1e=<:patt<?{$p1$=$e$}>>letunit~loc=<:patt<()>>endletuse_new_type~locnamee=letp=<:patt<(type$lid:name$)>>in<:expr<fun[$p$->$e$]>>moduleExp=structtypet=MLast.exprletident~locs=ifBase.Char.is_uppercases.[0]||Base.String.equals"[]"then<:expr<$uid:s$>>else<:expr<$lid:s$>>letlid=ident(* let uid ~loc s = <:expr< $uid:s$ >> *)letunit~loc=<:expr<()>>letsprintf~locfmt=Printf.ksprintf(funs-><:expr<$lid:s$>>)fmtletstring_const~locs=<:expr<$str:s$>>letint_const~locn=<:expr<$int:string_of_intn$>>letassert_false~loc=<:expr<assertFalse>>[@@ocaml.warning"-32"]letof_longident~locl=letrechelper=function(* | Longident.Lident s when Char.equal s.[0] (Char.uppercase_ascii s.[0]) -> uid ~loc s *)|Longident.Lidents->assert(s<>"");ident~locs|Ldot(l,r)->letu=helperlin<:expr<$u$.$ident~locr$>>|_->assertfalseinhelperlletacc~locel=<:expr<$e$.$of_longident~locl$>>letaccess~locmnameiname=letu=<:expr<$uid:mname$>>in<:expr<$u$.$ident~lociname$>>letapp~loclr=<:expr<$l$$r$>>letapp_lab~locllabr=letp=Pat.var~loclabinletarg=<:expr<~{$p$=$r$}>>in<:expr<$l$$arg$>>letapp_list~loclxs=List.fold_left(app~loc)lxsletmatch_~loce(xs:caselist)=letxs=List.map(fun(a,b,c)->(a,Ploc.VaValb,c))xsin<:expr<match$e$with[$list:xs$]>>letfun_~locpate=<:expr<fun[$list:[(pat,Ploc.VaValNone,e)]$]>>letfun_list~locpatsbody=List.fold_right(funxacc->fun_~locxacc)patsbodyletfun_list_l~locpatsbody=List.fold_right(fun(lab,opt)acc-><:expr<fun[$list:[(Pat.optional~loc(Pat.lid~loclab)opt,Ploc.VaValNone,acc)]$]>>)patsbodyletconstruct~loclidentargs=app_list~loc(of_longident~loclident)argsletvariant~locsargs=matchargswith|[]-><:expr<`$s$>>|[x]->app~loc<:expr<`$s$>>x|le-><:expr<`$s$($list:le$)>>lettuple~locle=matchlewith|[]->failwith"Exp.tuple: bad argument"|[x]->x|le-><:expr<($list:le$)>>letnew_~loclident=<:expr<new$lilongid:Asttools.longident_lident_of_string_listloc(Longident.flattenlident)$>>letobject_~loc(pat,fields)=<:expr<object($pat$)$list:fields$end>>letsend~loclefts=<:expr<$left$#$s$>>letrecord~loclpe=letlpe=List.map(fun(l,r)->Pat.of_longident~locl,r)lpein<:expr<{$list:lpe$}>>letrecord1~loclidentexpr=record~loc[lident,expr]letfield~locelident=acc~locelidentletlet_~loc?(rec_=false)lpeewhere=letlpe=List.map(fun(p,e)->(p,e,<:vala<[]>>))lpeinifrec_then<:expr<letrec$list:lpe$in$ewhere$>>else<:expr<let$list:lpe$in$ewhere$>>letlet_one~loc?(rec_=false)pate1ewhere=let_~loc~rec_[pat,e1]ewhereletfrom_camle=failwith"from_caml not implemented"letassert_false~loc=<:expr<assertFalse>>letfailwith_~locs=<:expr<failwith$str:s$>>letobjmagic_unit~loc=<:expr<Obj.magic()>>lettrue_~loc=<:expr<True>>letfalse_~loc=<:expr<False>>letlist~locxs=letrechelperacc=function|[]->acc|x::xs->helper(app_list~loc<:expr<$uid:"::"$>>[x;acc])xsinhelper<:expr<$uid:"[]"$>>(List.revxs)(* let new_type ~loc = failwith "Not implemented" *)letconstraint_~locet=<:expr<($e$:$t$)>>endmoduleTyp=structtypet=MLast.ctypletof_longident~loclid=letopenPpxlib.LongidentinmatchlidwithLidentswhennot(capitalizeds)-><:ctyp<$lid:s$>>|Ldot(li,s)whennot(capitalizeds)->letli=Longid.of_longident~locliin<:ctyp<$longid:li$.$lid:s$>>|Lapply_->failwith"Typ.of_longident: should not be called with Lapply"|_->assertfalseletsprintf~locfmt=Printf.ksprintf(funs-><:ctyp<$lid:s$>>)fmtletident~locs=<:ctyp<$lid:s$>>letstring~loc=<:ctyp<string>>letunit~loc=<:ctyp<unit>>letpair~loclr=<:ctyp<($list:[l;r]$)>>letaccess2~locmnametname=assert(Base.Char.is_uppercasemname.[0]);of_longident~loc(Ldot(Lidentmname,tname))letvar~locs=<:ctyp<'$s$>>letapp~loclr=<:ctyp<$l$$r$>>letany~loc=<:ctyp<_>>letalias~locts=letp=var~locsin<:ctyp<$t$as$p$>>lettuple~loclt=<:ctyp<($list:lt$)>>letconstr~loclident=letinit=of_longident~loclidentinfunction|[]->init|lt->List.fold_left(app~loc)initltletclass_~loclident=letinit=<:ctyp<#$lilongid:Asttools.longident_lident_of_string_listloc(Longident.flattenlident)$>>infunction|[]->init(* | [r] -> <:ctyp< $init$ $r$ >> *)|lt->List.fold_left(app~loc)initltletof_type_arg~loc(s,_)=matchswith|VaVal(Somes)->var~locs|VaAnt_->assertfalse|VaValNone->failwith"bad type arg"letobject_~locflglst=letlst=List.map(fun(s,t)->(Somes,t,<:vala<[]>>))lstin<:ctyp<<$list:lst$$flag:(matchflgwithPpxlib.Open->true|Ppxlib.Closed->false)$>>>letarrow~loct1t2=<:ctyp<$t1$->$t2$>>letchain_arrow~loc=function|[]->assertfalse|xs->letr=List.revxsinletinit=List.hdrinList.fold_left(funaccx->arrow~locxacc)init(List.tlr)letfrom_camlroot_typ=letrechelpertyp=letloc=loc_from_camltyp.Ppxlib.ptyp_locinmatchtyp.ptyp_descwith|Ptyp_any-><:ctyp<_>>|Ptyp_vars-><:ctyp<'$s$>>|Ptyp_arrow(lab,l,r)->arrow~loc(helperl)(helperr)|Ptyp_constr({txt;_},ts)->constr~loctxt(List.maphelperts)|Ptyp_tuplets-><:ctyp<($list:(List.maphelperts)$)>>|Ptyp_variant(_,_,_)|_->failwith"Not implemented: conversion from OCaml ast to Camlp5 Ast"inhelperroot_typ(* this might need to be changed *)letvariant~loc?(is_open=false)fs=letvs=fs|>List.map(funrf->matchrf.Ppxlib.prf_descwith|Ppxlib.Rinheritcore_typ->PvInh(loc,from_camlcore_typ)|Rtag(lb,is_open,args)->PvTag(loc,VaVallb.txt,VaValis_open,VaVal(List.mapfrom_camlargs),<:vala<[]>>))inifis_openthen<:ctyp<[>$list:vs$]>>else<:ctyp<[<$list:vs$]>>letvariant_of_t~loctyp=<:ctyp<[>$list:[PvInh(loc,typ)]$]>>letopenize~loc?as_t=letans=variant_of_t~loctinmatchas_with|Somename->alias~locansname|None->ansletuse_tdecltdecl=letloc=loc_from_camltdecl.Ppxlib.ptype_locinletc=ident~loctdecl.ptype_name.txtinList.fold_left(funacc(t,_)->matcht.Ppxlib.ptyp_descwith|Ptyp_vars->app~locacc(var~locs)|_->assertfalse)ctdecl.ptype_paramsletpoly~locnamest=<:ctyp<!$list:names$.$t$>>letmap~onvart=tletto_type_arg=function|<:ctyp<'$s$>>->Some(named_type_arg~loc:nolocs)|_->Noneletto_type_arg_exn=function|<:ctyp<'$s$>>->named_type_arg~loc:nolocs|_->failwith"bad argument of to_type_arg_exn"endtypetype_declaration=MLast.type_decltypeclass_declaration=class_exprclass_infosletclass_declaration~loc~name?(virt=false)?(wrap=(funx->x))~paramsfields=letc={ciLoc=loc;ciVir=Ploc.VaValvirt;ciPrm=(loc,Ploc.VaValparams);ciNam=Ploc.VaValname;ciExp=wrap@@CeStr(loc,Ploc.VaValNone,Ploc.VaValfields);ciAttributes=<:vala<[]>>}incmoduleStr=structtypet=MLast.str_itemletof_tdecls~loctd=letopenPpxlibinlettdPrm=HelpersBase.map_type_param_namestd.ptype_params~f:(funs->named_type_arg~locs)inlettdDef=matchtd.ptype_kindwith|Ptype_variantcds->letllslt=List.map(funcd->letargs=matchcd.pcd_argswith|Pcstr_record_->assertfalse|Pcstr_tuplets->List.mapTyp.from_camltsin<:constructor<$uid:cd.pcd_name.txt$of$list:args$>>)cdsin<:ctyp<[$list:llslt$]>>|_->assertfalseinlett=<:type_decl<$tp:(loc,VaValtd.ptype_name.txt)$$list:tdPrm$=$tdDef$>>in<:str_item<type$list:[t]$>>(* TODO *)letsingle_value~locpatbody=<:str_item<value$pat$=$body$>>letvalues~loc?(rec_flag=Ppxlib.Recursive)vbs=letvbs=List.map(fun(p,e)->(p,e,<:vala<[]>>))vbsinmatchrec_flagwith|Recursive-><:str_item<valuerec$list:vbs$>>|Nonrecursive-><:str_item<value$list:vbs$>>letof_vb~loc?(rec_flag=Ppxlib.Recursive)vb=values~loc~rec_flag[vb]letclass_single~loc~name?(virt=false)?(wrap=(funx->x))~paramsfields=letc={ciLoc=loc;ciVir=Ploc.VaValvirt;ciPrm=(loc,Ploc.VaValparams);ciNam=Ploc.VaValname;ciExp=wrap@@CeStr(loc,Ploc.VaValNone,Ploc.VaValfields);ciAttributes=<:vala<[]>>}in<:str_item<class$list:[c]$>>lettdecl~loc~name~paramsrhs=lettdPrm=List.map(funs->(VaVal(Somes),None))paramsinlett=<:type_decl<$tp:(loc,VaValname)$$list:tdPrm$=$rhs$>>in<:str_item<type$list:[t]$>>letof_class_declarations~loc(lcice:class_declarationlist)=<:str_item<class$list:lcice$>>lettdecl_record~loc~name~paramsllsbt=letllsbt=List.map(fun(a,b,c,d)->(a,b,c,d,<:vala<[]>>))llsbtinlett=<:ctyp<{$list:llsbt$}>>intdecl~loc~name~paramst(* let functor1 ~loc name ~param sigs strs = failwith "not_implemented" *)letsimple_gadt:loc:loc->name:string->params_count:int->(string*Typ.t)list->t=fun~loc~name~params_countts->letltv=List.initparams_count(funn->(VaVal(Some(Printf.sprintf"dummy%d"n)),None))inletls=(loc,VaValname)inletltt=[]inlett=letllslt=List.map(fun(name,typ)-><:constructor<$uid:name$:$typ$>>)tsin<:ctyp<[$list:llslt$]>>inletltd=<:type_decl<$tp:ls$$list:ltv$=$t$$list:ltt$>>in<:str_item<type$list:[ltd]$>>letmodule_~locnameme=<:str_item<module$uid:name$=$mexp:me$>>letmodtype~loc(_,name,topt)=matchtoptwith|Somemt-><:str_item<moduletype$name$=$mt$>>|None->failwith"Should not happen?"lettdecl_abstr~loc=assertfalseletinclude_~locme=<:str_item<include$me$>>endmoduleMe=structtypet=MLast.module_exprletstructure~loclsi=<:module_expr<struct$list:lsi$end>>letident~loclident=letrechelper=function|Ppxlib.Lidents-><:module_expr<$uid:s$>>|Ppxlib.Ldot(p,s)-><:module_expr<$helperp$.$uid:s$>>|_->failwith"Me.ident not_implemented"inhelperlidentletapply~locme1me2=<:module_expr<$me1$$me2$>>letfunctor_~locnametyp_optme=matchtyp_optwith|Somemt-><:module_expr<functor($name$:$mt$)->$me$>>|None->assertfalseendmoduleMt=structtypet=MLast.module_typeletident~loc(lid:Ppxlib.longident):MLast.module_type=letopenPpxlibinmatchlidwithLidents->ifcapitalizedsthen<:module_type<$uid:s$>>else<:module_type<$lid:s$>>|Ldot(li,s)->letli=Longid.of_longident~locliinifcapitalizedsthen<:module_type<$longid:li$.$uid:s$>>else<:module_type<$longid:li$.$lid:s$>>|Lapply_->failwith"Mt.ident: cannot call with an Lapply"letsignature~loclsi=<:module_type<sig$list:lsi$end>>letfunctor_~locnametyp_optme=matchtyp_optwith|Somemtl-><:module_type<functor($name$:$mtl$)->$me$>>|None->assertfalseletwith_~locmtlwc=<:module_type<$mt$with$list:lwc$>>endtypemodule_declaration=loc*string*Mt.tletmodule_declaration~loc~namet:module_declaration=(loc,name,t)typemodule_type_declaration=loc*string*Mt.toptionletmodule_type_declaration~loc~nametopt:module_type_declaration=(loc,name,topt)moduleSig=structtypet=MLast.sig_itemletof_tdecls~loctd=letopenPpxlibinlettdPrm=HelpersBase.map_type_param_namestd.ptype_params~f:(funs->named_type_arg~locs)inlettdDef=matchtd.ptype_kindwith|Ptype_variantcds->letllslt=List.map(funcd->letargs=matchcd.pcd_argswith|Pcstr_record_->assertfalse|Pcstr_tuplets->List.mapTyp.from_camltsin<:constructor<$uid:cd.pcd_name.txt$of$list:args$>>)cdsin<:ctyp<[$list:llslt$]>>|Ptype_abstract->beginmatchtd.ptype_manifestwith|None->assertfalse|Somet->Typ.from_camltend|_->assertfalseinlett=<:type_decl<$tp:(loc,VaValtd.ptype_name.txt)$$list:tdPrm$=$tdDef$>>in<:sig_item<type$list:[t]$>>letvalue~loc~nametyp=SgVal(loc,Ploc.VaValname,typ,<:vala<[]>>)(* let type_ ~loc recflg *)letclass_~loc~name~params?(virt=false)?(wrap=(funx->x))fields=(* TODO: wrap *)letc={ciLoc=loc;ciVir=Ploc.VaValvirt;ciPrm=(loc,Ploc.VaValparams);ciNam=Ploc.VaValname;ciExp=wrap@@CtSig(loc,Ploc.VaValNone,Ploc.VaValfields);ciAttributes=<:vala<[]>>}in<:sig_item<class$list:[c]$>>letfunctor1~locname~paramsigs_argsigs_r=letmt1=<:module_type<sig$list:sigs_arg$end>>inletmt2=<:module_type<sig$list:sigs_r$end>>inletmt=<:module_type<functor($param$:$mt1$)->$mt2$>>in<:sig_item<module$uid:name$:$mtyp:mt$>>letsimple_gadt(* : loc:loc -> name:string -> params_count:int -> (string * Typ.t) list -> t *)=fun~loc~name~params_countconstructors->lettdDef=(* TODO: error about gadts may be here *)letcs=List.map(fun(name,t)-><:constructor<$uid:name$:$t$>>)constructorsin<:ctyp<[$list:cs$]>>inlettdPrm=List.initparams_count(funn->(VaVal(Some(Printf.sprintf"dummy%d"n)),None))inlettd=<:type_decl<$tp:(loc,VaValname)$$list:tdPrm$=$tdDef$>>in<:sig_item<type$list:[td]$>>lettdecl_abstr:loc:loc->string->stringoptionlist->t=fun~locnameparams->lettdPrm=List.map(funs->(VaVals,None))paramsinlettd=<:type_decl<$tp:(loc,VaValname)$$list:tdPrm$='abstract>>in<:sig_item<type$list:[td]$>>letmodule_~loc(_,name,mtyp)=<:sig_item<module$uid:name$:$mtyp:mtyp$>>(* TODO: Kakadu, what is this? I don't recognize this. It doesn't seem to exist in Ocaml, and the construct appears to be something leftover in camlp5. *)letmodtype~loc(_loc,s,mt_opt)=letmt=matchmt_optwith|Somemt->mt|None-><:module_type<'abstract>>in<:sig_item<moduletype$s$=$mt$>>endmoduleWC=structtypet=MLast.with_constrlettyp~loc~paramsnamet=letls=(None,<:vala<name>>)inletltv=List.map(funs->named_type_arg~locs)paramsin<:with_constr<type$lilongid:ls$$list:ltv$=$t$>>endmoduleVb=structtypet=Pat.t*Exp.tendletvalue_binding~loc~pat~expr=(pat,expr)moduleCf=structtypet=MLast.class_str_itemletmethod_concrete~locnamebody_expr=<:class_str_item<method$lid:name$=$body_expr$>>letmethod_virtual~locnametyp=<:class_str_item<methodvirtual$lid:name$:$typ$>>letinherit_~loc?(as_=None)ce=<:class_str_item<inherit$ce$$opt:as_$>>letconstraint_~loct1t2=<:class_str_item<type$t1$=$t2$>>endmoduleCtf=structtypet=class_sig_itemletconstraint_~loct1t2=<:class_sig_item<type$t1$=$t2$>>letmethod_~loc?(virt=false)st=ifvirtthen<:class_sig_item<methodvirtual$lid:s$:$t$>>else<:class_sig_item<method$lid:s$:$t$>>letinherit_~loccty=<:class_sig_item<inherit$cty$>>endmoduleCty=structtypet=class_typeletof_longident~locl=letopenPpxlibinmatchlwithLidentswhennot(capitalizeds)-><:class_type<$lid:s$>>|Ldot(li,s)whencapitalizeds->failwith"class_type must end in uncapitalized ident"|Ldot(li,s)whennot(capitalizeds)->letli=Longid.of_longident~locliin<:class_type<$longid:li$.$lid:s$>>|Lapply_->failwith"Cty.of_longident: cannot call with an Lapply"|_->assertfalseletarrow~loctct=<:class_type<[$t$]->$ct$>>letconstr~loclongidentlt=letct=of_longident~loclongidentin<:class_type<$ct$[$list:lt$]>>endmoduleCl=structtypet=class_exprletconstr~loclidentargs=letls=Asttools.longident_lident_of_string_listloc(Longident.flattenlident)in<:class_expr<[$list:args$]$lilongid:ls$>>letapply~loclxs=List.fold_left(funaccr-><:class_expr<$acc$$r$>>)lxsletfun_~locpce=<:class_expr<fun$p$->$ce$>>letfun_list~locpsce=List.fold_right(fun_~loc)psceendletclass_structure~self~fields=(self,fields)typeclass_structure=Pat.t*Cf.tlistlettyp_arg_of_core_typet=matcht.Ppxlib.ptyp_descwith|Ptyp_any->failwith"wildcards are not supported"|Ptyp_vars->named_type_arg~loc:(loc_from_camlt.ptyp_loc)s|_->assertfalseletopenize_poly~loct=letlpv=[PvInh(loc,t)]in<:ctyp<[>$list:lpv$]>>(*
match t with
| MLast.TyVrn (loc, name, flg) -> begin
(*
let flg = match flg with
| None -> Some None
| Some None -> Some None
| Some (Some xs) -> Some None (* It could be a bug here *)
in
*)
let flg = Some None in
MLast.TyVrn (loc, name, flg)
end
| t -> t
*)letclosize_polyt=matchtwith|MLast.TyVrn(loc,name,flg)->(funflg->MLast.TyVrn(loc,name,flg))(matchflgwith|Some(Somexs)->Some(Somexs)|_->Some(Some(VaVal[])))|t->t(* Need to be synchronized with Expander.params_of_interface_class *)letprepare_param_triples~loc~extra?(inh=fun~loc:locs->Typ.var~loc@@"i"^s)?(syn=fun~loc:locs->Typ.var~loc@@"s"^s)?(default_inh=Typ.var~loc"syn")?(default_syn=Typ.var~loc"inh")names=letps=List.concat@@List.map(funs->[inh~locs;Typ.var~locs;syn~locs])namesinps@[default_inh;extra;default_syn]lettyp_vars_of_typt=letopenBaseinletrechelperacc=function|<:ctyp<$longid:_$.$lid:_$>>->acc|<:ctyp<$t1$as$t2$>>->helperacct1(* ??? *)|<:ctyp<_>>->acc|<:ctyp<$t1$$t2$>>->helper(helperacct1)t2|<:ctyp<$t1$->$t2$>>->helper(helperacct1)t2|<:ctyp<#$lilongid:_$>>->acc(* I'm not sure *)|<:ctyp<~$s$:$t$>>->helperacct|<:ctyp<$lid:s$>>->acc|<:ctyp<$t1$==private$t2$>>|<:ctyp<$t1$==$t2$>>->helper(helperacct1)t2|<:ctyp<<$list:lst$$flag:b$>>>->List.fold~init:acc~f:(funacc(_,t,_)->helperacct)lst|<:ctyp<?$s$:$t$>>->helperacct|<:ctyp<(module$mt$)>>->acc|<:ctyp<!$list:ls$.$t$>>->failwith"not implemented"|<:ctyp<'$s$>>->s::acc|<:ctyp<{$list:llsbt$}>>->List.fold~init:acc~f:(funacc(_,_,_,t,_)->helperacct)llsbt|<:ctyp<[$list:llslt$]>>->failwith"sum"|<:ctyp<($list:lt$)>>->List.fold~init:acc~f:helperlt|<:ctyp<[=$list:lpv$]>>->failwith"polyvariant"|_->acc(* This could be wrong *)inList.dedup_and_sort~compare:String.compare@@helper[]t