123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916openPpxlibopenAst_helpermoduleAst_builder_default_loc=structincludePpx_deriving.Ast_convenienceletgen_def_locfx=letloc=!Ast_helper.default_locinf~locxletlid=gen_def_locAst_builder.Default.Located.lidentletlist=gen_def_locAst_builder.Default.elistletpstr=gen_def_locAst_builder.Default.pstringletplist=gen_def_locAst_builder.Default.plistletlam=gen_def_locAst_builder.Default.pexp_funNolabelNoneendopenAst_builder_default_locletdisable_warning_39()=letloc=!Ast_helper.default_locinletname={txt="ocaml.warning";loc}inAst_helper.Attr.mk~locname(PStr[%str"-39"])letmod_mknolocx=mknolocxletderiver="yojson"letraise_errorf=Ppx_deriving.raise_errorfletargn=Printf.sprintf"arg%d"letattr_int_encodingattrs=matchPpx_deriving.attr~deriver"encoding"attrs|>Ppx_deriving.Arg.(get_attr~deriver(enum["string";"number"]))with|Some"string"->`String|Some"number"|None->`Int|_->assertfalseletattr_stringnamedefaultattrs=matchPpx_deriving.attr~derivernameattrs|>Ppx_deriving.Arg.(get_attr~deriverstring)with|Somex->x|None->defaultletattr_key=attr_string"key"letattr_name=attr_string"name"letattr_serattrs=Ppx_deriving.(attrs|>attr~deriver"to_yojson"|>Arg.(get_attr~deriverexpr))letattr_desuattrs=Ppx_deriving.(attrs|>attr~deriver"of_yojson"|>Arg.(get_attr~deriverexpr))letattr_defaultattrs=Ppx_deriving.attr~deriver"default"attrs|>Ppx_deriving.Arg.(get_attr~deriverexpr)typeoptions={is_strict:bool;want_meta:bool;want_exn:bool;}letparse_optionsoptions=letstrict=reftrueinletmeta=reffalseinletexn=reffalseinletget_bool=Ppx_deriving.Arg.(get_expr~deriverbool)inoptions|>List.iter(fun(name,expr)->matchnamewith|"strict"->strict:=get_boolexpr|"meta"->meta:=get_boolexpr|"exn"->exn:=get_boolexpr|_->raise_errorf~loc:expr.pexp_loc"%s does not support option %s"derivername);{is_strict=!strict;want_meta=!meta;want_exn=!exn;}letpoly_funnamesexpr=List.fold_right(funnameexpr->letloc=name.Location.locinletname=name.Location.txtin[%exprfun[%ppvar("poly_"^name)]->[%eexpr]])namesexprlettype_add_attrstypattributes={typwithptyp_attributes=typ.ptyp_attributes@attributes}letrecser_expr_of_typtyp=matchattr_sertyp.ptyp_attributeswith|Somee->e|None->ser_expr_of_only_typtypandser_expr_of_only_typtyp=letloc=typ.ptyp_locinletattr_int_encodingtyp=matchattr_int_encodingtypwith`String->"String"|`Int->"Intlit"inmatchtypwith|[%type:unit]->[%exprfun(x:Ppx_deriving_runtime.unit)->`Null]|[%type:int]->[%exprfun(x:Ppx_deriving_runtime.int)->`Intx]|[%type:float]->[%exprfun(x:Ppx_deriving_runtime.float)->`Floatx]|[%type:bool]->[%exprfun(x:Ppx_deriving_runtime.bool)->`Boolx]|[%type:string]->[%exprfun(x:Ppx_deriving_runtime.string)->`Stringx]|[%type:bytes]->[%exprfunx->`String(Bytes.to_stringx)]|[%type:char]->[%exprfunx->`String(String.make1x)]|[%type:[%t?typ]ref]->[%exprfunx->[%eser_expr_of_typtyp]!x]|[%type:[%t?typ]list]->[%exprfunx->`List(safe_map[%eser_expr_of_typtyp]x)]|[%type:int32]|[%type:Int32.t]->[%exprfunx->`Intlit(Int32.to_stringx)]|[%type:int64]|[%type:Int64.t]->[%exprfunx->[%eExp.variant(attr_int_encodingtyp.ptyp_attributes)(Some[%expr(Int64.to_stringx)])]]|[%type:nativeint]|[%type:Nativeint.t]->[%exprfunx->[%eExp.variant(attr_int_encodingtyp.ptyp_attributes)(Some[%expr(Nativeint.to_stringx)])]]|[%type:[%t?typ]array]->[%exprfunx->`List(Array.to_list(Array.map[%eser_expr_of_typtyp]x))]|[%type:[%t?typ]option]->[%exprfunctionNone->`Null|Somex->[%eser_expr_of_typtyp]x]|[%type:Yojson.Safe.json]|[%type:Yojson.Safe.t]->[%exprfunx->x]|{ptyp_desc=Ptyp_constr({txt=lid},args)}->letfwd=app(Exp.ident(mknoloc(Ppx_deriving.mangle_lid(`Suffix"to_yojson")lid)))(List.mapser_expr_of_typargs)in(* eta-expansion is necessary for let-rec *)[%exprfunx->[%efwd]x]|{ptyp_desc=Ptyp_tupletyps}->[%exprfun[%pptuple(List.mapi(funi_->pvar(argni))typs)]->`List([%elist(List.mapi(funityp->app(ser_expr_of_typtyp)[evar(argni)])typs)])];|{ptyp_desc=Ptyp_variant(fields,_,_);ptyp_loc}->letcases=fields|>List.map(fun(field:row_field)->matchfield.prf_descwith|Rtag(label,true(*empty*),[])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case(Pat.variantlabelNone)[%expr`List[`String[%estr(attr_namelabelattrs)]]]|Rtag(label,false,[{ptyp_desc=Ptyp_tupletyps}])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case(Pat.variantlabel(Some(ptuple(List.mapi(funi_->pvar(argni))typs))))[%expr`List((`String[%estr(attr_namelabelattrs)])::[%elist(List.mapi(funityp->app(ser_expr_of_typtyp)[evar(argni)])typs)])]|Rtag(label,false,[typ])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case(Pat.variantlabel(Some[%pat?x]))[%expr`List[`String[%estr(attr_namelabelattrs)];[%eser_expr_of_typtyp]x]]|Rinherit({ptyp_desc=Ptyp_constr(tname,_)}astyp)->Exp.case[%pat?[%pPat.type_tname]asx][%expr[%eser_expr_of_typtyp]x]|_->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp))inExp.function_cases|{ptyp_desc=Ptyp_varname}->[%expr([%eevar("poly_"^name)]:_->Yojson.Safe.t)]|{ptyp_desc=Ptyp_alias(typ,name)}->[%exprfunx->[%eevar("poly_"^name)]x;[%eser_expr_of_typtyp]x]|{ptyp_desc=Ptyp_poly(names,typ)}->poly_funnames(ser_expr_of_typtyp)|{ptyp_loc}->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp)(* http://desuchan.net/desu/src/1284751839295.jpg *)letrecdesu_fold~loc~pathftyps=typs|>List.mapi(funityp->i,app(desu_expr_of_typ~pathtyp)[evar(argni)])|>List.fold_left(funx(i,y)->letloc=x.pexp_locin[%expr[%ey]>>=fun[%ppvar(argni)]->[%ex]])[%exprResult.Ok[%ef(List.mapi(funi_->evar(argni))typs)]]anddesu_expr_of_typ~pathtyp=matchattr_desutyp.ptyp_attributeswith|Somee->e|None->desu_expr_of_only_typ~pathtypanddesu_expr_of_only_typ~pathtyp=letloc=typ.ptyp_locinleterror=[%exprResult.Error[%estr(String.concat"."path)]]inletdecode'cases=Exp.function_(List.map(fun(pat,exp)->Exp.casepatexp)cases@[Exp.case[%pat?_]error])inletdecodepatexp=decode'[pat,exp]inmatchtypwith|[%type:unit]->decode[%pat?`Null][%exprResult.Ok()]|[%type:int]->decode[%pat?`Intx][%exprResult.Okx]|[%type:float]->decode'[[%pat?`Intx],[%exprResult.Ok(float_of_intx)];[%pat?`Intlitx],[%exprResult.Ok(float_of_stringx)];[%pat?`Floatx],[%exprResult.Okx]]|[%type:bool]->decode[%pat?`Boolx][%exprResult.Okx]|[%type:string]->decode[%pat?`Stringx][%exprResult.Okx]|[%type:bytes]->decode[%pat?`Stringx][%exprResult.Ok(Bytes.of_stringx)]|[%type:char]->decode[%pat?`Stringx][%exprifString.lengthx=1thenResult.Okx.[0]else[%eerror]]|[%type:int32]|[%type:Int32.t]->decode'[[%pat?`Intx],[%exprResult.Ok(Int32.of_intx)];[%pat?`Intlitx],[%exprResult.Ok(Int32.of_stringx)]]|[%type:int64]|[%type:Int64.t]->beginmatchattr_int_encodingtyp.ptyp_attributeswith|`String->decode[%pat?`Stringx][%exprResult.Ok(Int64.of_stringx)]|`Int->decode'[[%pat?`Intx],[%exprResult.Ok(Int64.of_intx)];[%pat?`Intlitx],[%exprResult.Ok(Int64.of_stringx)]]end|[%type:nativeint]|[%type:Nativeint.t]->beginmatchattr_int_encodingtyp.ptyp_attributeswith|`String->decode[%pat?`Stringx][%exprResult.Ok(Nativeint.of_stringx)]|`Int->decode'[[%pat?`Intx],[%exprResult.Ok(Nativeint.of_intx)];[%pat?`Intlitx],[%exprResult.Ok(Nativeint.of_stringx)]]end|[%type:[%t?typ]ref]->[%exprfunx->[%edesu_expr_of_typ~path:(path@["contents"])typ]x>|=ref]|[%type:[%t?typ]option]->[%exprfunction|`Null->Result.OkNone|x->[%edesu_expr_of_typ~pathtyp]x>>=funx->Result.Ok(Somex)]|[%type:[%t?typ]list]->decode[%pat?`Listxs][%exprmap_bind[%edesu_expr_of_typ~pathtyp][]xs]|[%type:[%t?typ]array]->decode[%pat?`Listxs][%exprmap_bind[%edesu_expr_of_typ~pathtyp][]xs>|=Array.of_list]|[%type:Yojson.Safe.t]|[%type:Yojson.Safe.json]->[%exprfunx->Result.Okx]|{ptyp_desc=Ptyp_tupletyps}->decode[%pat?`List[%pplist(List.mapi(funi_->pvar(argni))typs)]](desu_fold~loc~pathtupletyps)|{ptyp_desc=Ptyp_variant(fields,_,_);ptyp_loc}->letinherits,tags=List.partition(funfield->matchfield.prf_descwithRinherit_->true|_->false)fieldsinlettag_cases=tags|>List.map(funfield->matchfield.prf_descwith|Rtag(label,true(*empty*),[])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case[%pat?`List[`String[%ppstr(attr_namelabelattrs)]]][%exprResult.Ok[%eExp.variantlabelNone]]|Rtag(label,false,[{ptyp_desc=Ptyp_tupletyps}])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case[%pat?`List((`String[%ppstr(attr_namelabelattrs)])::[%pplist(List.mapi(funi_->pvar(argni))typs)])](desu_fold~loc~path(funx->(Exp.variantlabel(Some(tuplex))))typs)|Rtag(label,false,[typ])->letlabel=label.txtinletattrs=field.prf_attributesinExp.case[%pat?`List[`String[%ppstr(attr_namelabelattrs)];x]][%expr[%edesu_expr_of_typ~pathtyp]x>>=funx->Result.Ok[%eExp.variantlabel(Some[%exprx])]]|Rinherit({ptyp_desc=Ptyp_constr(tname,_)}astyp)->Exp.case[%pat?[%pPat.type_tname]asx][%expr[%edesu_expr_of_typ~pathtyp]x]|_->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp))andinherits_case=lettoplevel_typ=typininherits|>List.map(funfield->matchfield.prf_descwith|Rinherittyp->typ|_->assertfalse)|>List.fold_left(funexprtyp->[%exprmatch[%edesu_expr_of_typ~pathtyp]jsonwith|(Result.Okresult)->Result.Ok(result:>[%ttoplevel_typ])|Result.Error_->[%eexpr]])error|>Exp.case[%pat?_]in[%exprfun(json:Yojson.Safe.t)->[%eExp.match_[%exprjson](tag_cases@[inherits_case])]]|{ptyp_desc=Ptyp_constr({txt=lid},args)}->letfwd=app(Exp.ident(mknoloc(Ppx_deriving.mangle_lid(`Suffix"of_yojson")lid)))(List.map(desu_expr_of_typ~path)args)in(* eta-expansion is necessary for recursive groups *)[%exprfunx->[%efwd]x]|{ptyp_desc=Ptyp_varname}->[%expr([%eevar("poly_"^name)]:Yojson.Safe.t->_error_or)]|{ptyp_desc=Ptyp_alias(typ,name)}->[%exprfunx->[%eevar("poly_"^name)]x;[%edesu_expr_of_typ~pathtyp]x]|{ptyp_desc=Ptyp_poly(names,typ)}->poly_funnames(desu_expr_of_typ~pathtyp)|{ptyp_loc}->raise_errorf~loc:ptyp_loc"%s cannot be derived for %s"deriver(Ppx_deriving.string_of_core_typetyp)(* TODO: Do not wrap runtime around [@default ...].
We do currently and for instance the following doesn't currently work:
module List = struct let x = [1; 2] end
type t = {field : int list [@default List.x]} [@@deriving to_yojson]
*)letwrap_runtimedecls=Ppx_deriving.sanitize~module_:(Lident"Ppx_deriving_yojson_runtime")declsletser_type_of_decl~options~path:_type_decl=ignore(parse_optionsoptions);letloc=type_decl.ptype_locinlettyp=Ppx_deriving.core_type_of_type_decltype_declinletpolymorphize=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:[%tvar]->Yojson.Safe.t])type_declinpolymorphize[%type:[%ttyp]->Yojson.Safe.t]letser_str_of_record~locvarnamelabels=letfields=labels|>List.mapi(fun_i{pld_loc=loc;pld_name={txt=name};pld_type;pld_attributes}->letfield=Exp.field(evarvarname)(mknoloc(Lidentname))inletresult=[%expr[%estr(attr_keynamepld_attributes)],[%eser_expr_of_typ@@type_add_attrspld_typepld_attributes][%efield]]inmatchattr_default(pld_type.ptyp_attributes@pld_attributes)with|None->[%expr[%eresult]::fields]|Somedefault->[%exprif[%efield]=[%edefault]thenfieldselse[%eresult]::fields])inletassoc=List.fold_left(funexprfield->letloc=expr.pexp_locin[%exprletfields=[%efield]in[%eexpr]])[%expr`Assocfields]fieldsin[%exprletfields=[]in[%eassoc]]letser_str_of_type~options~path({ptype_loc=loc}astype_decl)=ignore(parse_optionsoptions);letpolymorphize=Ppx_deriving.poly_fun_of_type_decltype_declinlettyp=Ppx_deriving.core_type_of_type_decltype_declinmatchtype_decl.ptype_kindwith|Ptype_open->beginletto_yojson_name=Ppx_deriving.mangle_type_decl(`Suffix"to_yojson")type_declinletmod_name=Ppx_deriving.mangle_type_decl(`PrefixSuffix("M","to_yojson"))type_declinmatchtype_decl.ptype_manifestwith|Some({ptyp_desc=Ptyp_constr({txt=lid},_args)}asmanifest)->letser=ser_expr_of_typmanifestinletlid=Ppx_deriving.mangle_lid(`PrefixSuffix("M","to_yojson"))lidinletorig_mod=Mod.ident(mknoloclid)in([Str.module_(Mb.mk(mod_mknolocmod_name)orig_mod)],[Vb.mk(pvarto_yojson_name)(polymorphize[%expr([%eser]:[%ttyp]->Yojson.Safe.t)])],[])|Some_->raise_errorf~loc"%s: extensible type manifest should be a type name"deriver|None->letpoly_vars=List.rev(Ppx_deriving.fold_left_type_decl(funaccname->name::acc)[]type_decl)inletpolymorphize_ser=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:[%tvar]->Yojson.Safe.t])type_declinletty=Typ.polypoly_vars(polymorphize_ser[%type:[%ttyp]->Yojson.Safe.t])inletdefault_fun=lettype_path=String.concat"."(path@[type_decl.ptype_name.txt])inlete_type_path=Exp.constant(Pconst_string(type_path,None))in[%exprfun_->invalid_arg("to_yojson: Maybe a [@@deriving yojson] is missing when extending the type "^[%ee_type_path])]inletpoly_fun=polymorphizedefault_funinletpoly_fun=(Ppx_deriving.fold_left_type_decl(funexpname->Exp.newtypenameexp)poly_funtype_decl)inletmod_name="M_"^to_yojson_nameinlettyp=Type.mk~kind:(Ptype_record[Type.field~mut:Mutable(mknoloc"f")ty])(mknoloc"t_to_yojson")inletrecord=Vb.mk(pvar"f")(Exp.record[lid"f",poly_fun]None)inletflid=lid(Printf.sprintf"%s.f"mod_name)inletfield=Exp.field(Exp.identflid)(flid)inletmod_=Str.module_(Mb.mk(mod_mknolocmod_name)(Mod.structure[Str.type_Nonrecursive[typ];Str.valueNonrecursive[record];]))in([mod_],[Vb.mk(pvarto_yojson_name)[%exprfunx->[%efield]x]],[])end|kind->letserializer=matchkind,type_decl.ptype_manifestwith|Ptype_open,_->assertfalse|Ptype_abstract,Somemanifest->ser_expr_of_typmanifest|Ptype_variantconstrs,_->constrs|>List.map(fun{pcd_name={txt=name'};pcd_args;pcd_attributes}->letjson_name=attr_namename'pcd_attributesinmatchpcd_argswith|Pcstr_tuple([])->Exp.case(pconstrname'[])[%expr`List[`String[%estrjson_name]]]|Pcstr_tuple(args)->letarg_exprs=List.mapi(funityp->app(ser_expr_of_typtyp)[evar(argni)])argsinExp.case(pconstrname'(List.mapi(funi_->pvar(argni))args))[%expr`List((`String[%estrjson_name])::[%elistarg_exprs])]|Pcstr_recordlabels->letarg_expr=ser_str_of_record~loc(argn0)labelsinExp.case(pconstrname'[pvar(argn0)])[%expr`List((`String[%estrjson_name])::[%elist[arg_expr]])])|>Exp.function_|Ptype_recordlabels,_->[%exprfunx->[%eser_str_of_record~loc"x"labels]]|Ptype_abstract,None->raise_errorf~loc"%s cannot be derived for fully abstract types"deriverinletty=ser_type_of_decl~options~pathtype_declinletfv=Ppx_deriving.free_vars_in_core_typetyinletpoly_type=Typ.force_poly@@Typ.polyfv@@tyinletvar_s=Ppx_deriving.mangle_type_decl(`Suffix"to_yojson")type_declinletvar=pvarvar_sin([],[Vb.mk~attrs:[disable_warning_39()](Pat.constraint_varpoly_type)(polymorphize[%expr([%ewrap_runtimeserializer])])],[Str.valueNonrecursive[Vb.mk[%expr[%epvar"_"]][%expr[%eevarvar_s]]]])letser_str_of_type_ext~options~path:_({ptyext_path={loc}}astype_ext)=ignore(parse_optionsoptions);letserializer=letpats=List.fold_right(fun{pext_name={txt=name'};pext_kind;pext_attributes}acc_cases->matchpext_kindwith|Pext_rebind_->(* nothing to do, since the constructor must be handled in original
constructor declaration *)acc_cases|Pext_decl(pext_args,_)->letjson_name=attr_namename'pext_attributesinletcase=matchpext_argswith|Pcstr_tuple([])->Exp.case(pconstrname'[])[%expr`List[`String[%estrjson_name]]]|Pcstr_tuple(args)->letarg_exprs=List.mapi(funityp->app(ser_expr_of_typtyp)[evar(argni)])argsinExp.case(pconstrname'(List.mapi(funi_->pvar(argni))args))[%expr`List((`String[%estrjson_name])::[%elistarg_exprs])]|Pcstr_record_->raise_errorf~loc"%s: record variants are not supported in extensible types"deriverincase::acc_cases)type_ext.ptyext_constructors[]inletfallback_case=Exp.case[%pat?x][%expr[%ePpx_deriving.poly_apply_of_type_exttype_ext[%exprfallback]]x]inExp.function_(pats@[fallback_case])inletmod_name=letmod_lid=Ppx_deriving.mangle_lid(`PrefixSuffix("M","to_yojson"))type_ext.ptyext_path.txtinLongident.namemod_lidinletpolymorphize=Ppx_deriving.poly_fun_of_type_exttype_extinletserializer=polymorphize(wrap_runtimeserializer)inletflid=lid(Printf.sprintf"%s.f"mod_name)inletset_field=Exp.setfield(Exp.identflid)flidserializerinletfield=Exp.field(Exp.identflid)(flid)inletbody=[%exprletfallback=[%efield]in[%eset_field]]in[Str.value?loc:NoneNonrecursive[Vb.mk(Pat.construct(lid"()")None)body]]leterror_ortyp=letloc=typ.ptyp_locin[%type:[%ttyp]Ppx_deriving_yojson_runtime.error_or]letdesu_type_of_decl_poly~options~path:_type_decltype_=ignore(parse_optionsoptions);letloc=type_decl.ptype_locinletpolymorphize=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:Yojson.Safe.t->[%terror_orvar]])type_declinpolymorphizetype_letdesu_type_of_decl~options~pathtype_decl=letloc=type_decl.ptype_locinlettyp=Ppx_deriving.core_type_of_type_decltype_declindesu_type_of_decl_poly~options~pathtype_decl[%type:Yojson.Safe.t->[%terror_ortyp]]letdesu_str_of_record~loc~is_strict~error~pathwrap_recordlabels=lettop_error=errorpathinletrecord=List.fold_left(funexpri->letloc=expr.pexp_locin[%expr[%eevar(argni)]>>=fun[%ppvar(argni)]->[%eexpr]])(letr=Exp.record(labels|>List.mapi(funi{pld_name={txt=name}}->mknoloc(Lidentname),evar(argni)))Nonein[%exprResult.Ok[%ewrap_recordr]])(labels|>List.mapi(funi_->i))inletdefault_case=ifis_strictthentop_errorelse[%exprloopxs_state]inletcases=(labels|>List.mapi(funi{pld_loc=loc;pld_name={txt=name};pld_type;pld_attributes}->letpath=path@[name]inletthunks=labels|>List.mapi(funj_->ifi=jthenapp(desu_expr_of_typ~path@@type_add_attrspld_typepld_attributes)[evar"x"]elseevar(argnj))inExp.case[%pat?([%ppstr(attr_keynamepld_attributes)],x)::xs][%exprloopxs[%etuplethunks]]))@[Exp.case[%pat?[]]record;Exp.case[%pat?_::xs]default_case]andthunks=labels|>List.map(fun{pld_name={txt=name};pld_type;pld_attributes}->matchattr_default(pld_type.ptyp_attributes@pld_attributes)with|None->error(path@[name])|Somex->[%exprResult.Ok[%ex]])in[%exprfunction|`Assocxs->letrecloopxs([%pptuple(List.mapi(funi_->pvar(argni))labels)]as_state)=[%eExp.match_[%exprxs]cases]inloopxs[%etuplethunks]|_->[%etop_error]]letdesu_str_of_type~options~path({ptype_loc=loc}astype_decl)=let{is_strict;want_exn;_}=parse_optionsoptionsinletpath=path@[type_decl.ptype_name.txt]inleterrorpath=[%exprResult.Error[%estr(String.concat"."path)]]inlettop_error=errorpathinletpolymorphize=Ppx_deriving.poly_fun_of_type_decltype_declinlettyp=Ppx_deriving.core_type_of_type_decltype_declinmatchtype_decl.ptype_kindwith|Ptype_open->beginletof_yojson_name=Ppx_deriving.mangle_type_decl(`Suffix"of_yojson")type_declinletmod_name=Ppx_deriving.mangle_type_decl(`PrefixSuffix("M","of_yojson"))type_declinmatchtype_decl.ptype_manifestwith|Some({ptyp_desc=Ptyp_constr({txt=lid},_args)}asmanifest)->letdesu=desu_expr_of_typ~pathmanifestinletlid=Ppx_deriving.mangle_lid(`PrefixSuffix("M","of_yojson"))lidinletorig_mod=Mod.ident(mknoloclid)inletpoly_desu=polymorphize[%expr([%ewrap_runtimedesu]:Yojson.Safe.t->_)]in([Str.module_(Mb.mk(mod_mknolocmod_name)orig_mod)],[Vb.mk(pvarof_yojson_name)poly_desu],[])|Some_->raise_errorf~loc"%s: extensible type manifest should be a type name"deriver|None->letpoly_vars=List.rev(Ppx_deriving.fold_left_type_decl(funaccname->name::acc)[]type_decl)inletpolymorphize_desu=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:Yojson.Safe.t->[%terror_orvar]])type_declinletty=Typ.polypoly_vars(polymorphize_desu[%type:Yojson.Safe.t->[%terror_ortyp]])inletdefault_fun=Exp.function_[Exp.case[%pat?_]top_error]inletpoly_fun=polymorphizedefault_funinletpoly_fun=(Ppx_deriving.fold_left_type_decl(funexpname->Exp.newtypenameexp)poly_funtype_decl)inletmod_name="M_"^of_yojson_nameinlettyp=Type.mk~kind:(Ptype_record[Type.field~mut:Mutable(mknoloc"f")ty])(mknoloc"t_of_yojson")inletrecord=Vb.mk(pvar"f")(Exp.record[lid"f",poly_fun]None)inletflid=lid(Printf.sprintf"%s.f"mod_name)inletfield=Exp.field(Exp.identflid)flidinletmod_=Str.module_(Mb.mk(mod_mknolocmod_name)(Mod.structure[Str.type_Nonrecursive[typ];Str.valueNonrecursive[record];]))in([mod_],[Vb.mk(pvarof_yojson_name)[%exprfunx->[%efield]x]],[])end|kind->letdesurializer=matchkind,type_decl.ptype_manifestwith|Ptype_open,_->assertfalse|Ptype_abstract,Somemanifest->desu_expr_of_typ~pathmanifest|Ptype_variantconstrs,_->letcases=List.map(fun{pcd_loc=loc;pcd_name={txt=name'};pcd_args;pcd_attributes}->matchpcd_argswith|Pcstr_tuple(args)->Exp.case[%pat?`List((`String[%ppstr(attr_namename'pcd_attributes)])::[%pplist(List.mapi(funi_->pvar(argni))args)])](desu_fold~loc~path(funx->constrname'x)args)|Pcstr_recordlabels->letwrap_recordr=constrname'[r]inletsub=desu_str_of_record~loc~is_strict~error~pathwrap_recordlabelsinExp.case[%pat?`List((`String[%ppstr(attr_namename'pcd_attributes)])::[%pplist[pvar(argn0)]])][%expr[%esub][%eevar(argn0)]])constrsinExp.function_(cases@[Exp.case[%pat?_]top_error])|Ptype_recordlabels,_->desu_str_of_record~loc~is_strict~error~path(funr->r)labels|Ptype_abstract,None->raise_errorf~loc"%s cannot be derived for fully abstract types"deriverinletty=desu_type_of_decl~options~pathtype_declinletfv=Ppx_deriving.free_vars_in_core_typetyinletpoly_type=Typ.force_poly@@Typ.polyfv@@tyinletvar_s=Ppx_deriving.mangle_type_decl(`Suffix"of_yojson")type_declinletvar=pvarvar_sinletvar_s_exn=var_s^"_exn"inlet{ptype_params;_}=type_declinletvar_s_exn_args=List.mapi(funi_->argni|>evar)ptype_paramsinletvar_s_exn_args=var_s_exn_args@[evar"x"]inletvar_s_exn_fun=letrecloop=function|[]->wrap_runtime([%exprmatch[%eapp(evarvar_s)var_s_exn_args]withResult.Okx->x|Result.Errorerr->raise(Failureerr)])|hd::tl->lam(pvarhd)(looptl)inloop((List.mapi(funi_->argni)ptype_params)@["x"])in([],[Vb.mk~attrs:[disable_warning_39()](Pat.constraint_varpoly_type)(polymorphize[%expr([%ewrap_runtimedesurializer])])],[Str.valueNonrecursive[Vb.mk[%expr[%epvar"_"]][%expr[%eevarvar_s]]]]@(ifnotwant_exnthen[]else[Str.valueNonrecursive[Vb.mk[%expr[%epvarvar_s_exn]]var_s_exn_fun];Str.valueNonrecursive[Vb.mk[%expr[%epvar"_"]][%expr[%eevarvar_s_exn]]]]))letdesu_str_of_type_ext~options~path({ptyext_path={loc}}astype_ext)=ignore(parse_optionsoptions);letdesurializer=letpats=List.fold_right(fun{pext_name={txt=name'};pext_kind;pext_attributes}acc_cases->matchpext_kindwith|Pext_rebind_->(* nothing to do since it must have been handled in the original
constructor declaration *)acc_cases|Pext_decl(pext_args,_)->letcase=matchpext_argswith|Pcstr_tuple(args)->Exp.case[%pat?`List((`String[%ppstr(attr_namename'pext_attributes)])::[%pplist(List.mapi(funi_->pvar(argni))args)])](desu_fold~loc~path(funx->constrname'x)args)|Pcstr_record_->raise_errorf~loc"%s: record variants are not supported in extensible types"deriverincase::acc_cases)type_ext.ptyext_constructors[]inletany_case=Exp.case(Pat.var(mknoloc"x"))(app(Ppx_deriving.poly_apply_of_type_exttype_ext[%exprfallback])[[%exprx]])in(pats@[any_case])|>Exp.function_inletmod_name=letmod_lid=Ppx_deriving.mangle_lid(`PrefixSuffix("M","of_yojson"))type_ext.ptyext_path.txtinLongident.namemod_lidinletpolymorphize=Ppx_deriving.poly_fun_of_type_exttype_extinletdesurializer=wrap_runtime(polymorphizedesurializer)inletflid=lid(Printf.sprintf"%s.f"mod_name)inletset_field=Exp.setfield(Exp.identflid)fliddesurializerinletfield=Exp.field(Exp.identflid)flidinletbody=[%exprletfallback=[%efield]in[%eset_field]]in[Str.value?loc:NoneNonrecursive[Vb.mk(Pat.construct(lid"()")None)body]]letser_sig_of_type~options~pathtype_decl=letto_yojson=Sig.value(Val.mk(mknoloc(Ppx_deriving.mangle_type_decl(`Suffix"to_yojson")type_decl))(ser_type_of_decl~options~pathtype_decl))inmatchtype_decl.ptype_kindwith|Ptype_open->letmod_name=Ppx_deriving.mangle_type_decl(`PrefixSuffix("M","to_yojson"))type_declinletpoly_vars=List.rev(Ppx_deriving.fold_left_type_decl(funaccname->name::acc)[]type_decl)inlettyp=Ppx_deriving.core_type_of_type_decltype_declinletloc=typ.ptyp_locinletpolymorphize_ser=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:[%tvar]->Yojson.Safe.t])type_declinletty=Typ.polypoly_vars(polymorphize_ser[%type:[%ttyp]->Yojson.Safe.t])inlettyp=Type.mk~kind:(Ptype_record[Type.field~mut:Mutable(mknoloc"f")ty])(mknoloc"t_to_yojson")inletrecord=Val.mk(mknoloc"f")(Typ.constr(lid"t_to_yojson")[])inletmod_=Sig.module_(Md.mk(mod_mknolocmod_name)(Mty.signature[Sig.type_Nonrecursive[typ];Sig.valuerecord;]))in[mod_;to_yojson]|_->[to_yojson]letser_sig_of_type_ext~options:_~path:__type_ext=[]letdesu_sig_of_type~options~pathtype_decl=let{want_exn;_}=parse_optionsoptionsinletof_yojson=Sig.value(Val.mk(mknoloc(Ppx_deriving.mangle_type_decl(`Suffix"of_yojson")type_decl))(desu_type_of_decl~options~pathtype_decl))inlettyp=Ppx_deriving.core_type_of_type_decltype_declinletloc=typ.ptyp_locinletof_yojson_exn=Sig.value(Val.mk(mknoloc(Ppx_deriving.mangle_type_decl(`Suffix"of_yojson_exn")type_decl))(desu_type_of_decl_poly~options~pathtype_decl[%type:Yojson.Safe.t->[%ttyp]]))inmatchtype_decl.ptype_kindwith|Ptype_open->letmod_name=Ppx_deriving.mangle_type_decl(`PrefixSuffix("M","of_yojson"))type_declinletpoly_vars=List.rev(Ppx_deriving.fold_left_type_decl(funaccname->name::acc)[]type_decl)inlettyp=Ppx_deriving.core_type_of_type_decltype_declinletpolymorphize_desu=Ppx_deriving.poly_arrow_of_type_decl(funvar->[%type:Yojson.Safe.t->[%terror_orvar]])type_declinletty=Typ.polypoly_vars(polymorphize_desu[%type:Yojson.Safe.t->[%terror_ortyp]])inlettyp=Type.mk~kind:(Ptype_record[Type.field~mut:Mutable(mknoloc"f")ty])(mknoloc"t_of_yojson")inletrecord=Val.mk(mknoloc"f")(Typ.constr(lid"t_of_yojson")[])inletmod_=Sig.module_(Md.mk(mod_mknolocmod_name)(Mty.signature[Sig.type_Nonrecursive[typ];Sig.valuerecord;]))in[mod_;of_yojson]|_->[of_yojson]@(ifnotwant_exnthen[]else[of_yojson_exn])letdesu_sig_of_type_ext~options:_~path:__type_ext=[]letyojson_str_fields~options~path:_type_decl=let{want_meta;_}=parse_optionsoptionsinmatchwant_meta,type_decl.ptype_kindwith|false,_|true,Ptype_open->[]|true,kind->matchkind,type_decl.ptype_manifestwith|Ptype_recordlabels,_->letloc=!Ast_helper.default_locinletfields=labels|>List.map(fun{pld_name={txt=name};pld_attributes}->[%expr[%estr(attr_keynamepld_attributes)]])inletflist=List.fold_right(funnacc->[%expr[%en]::[%eacc]])fields[%expr[]]in[Str.module_(Mb.mk(mod_mknoloc(Ppx_deriving.mangle_type_decl(`Prefix"Yojson_meta")type_decl))(Mod.structure[Str.valueNonrecursive[Vb.mk[%expr[%epvar"keys"]][%expr[%eflist]]];Str.valueNonrecursive[Vb.mk[%expr[%epvar"_"]][%expr[%eevar"keys"]]]]))]|_->[]letyojson_sig_fields~options~path:_type_decl=let{want_meta;_}=parse_optionsoptionsinmatchwant_meta,type_decl.ptype_kindwith|false,_|true,Ptype_open->[]|true,kind->matchkind,type_decl.ptype_manifestwith|Ptype_record_,_->letloc=!Ast_helper.default_locin[Sig.module_(Md.mk(mod_mknoloc(Ppx_deriving.mangle_type_decl(`Prefix"Yojson_meta")type_decl))(Mty.signature[Sig.value(Val.mk(mknoloc"keys")[%type:stringlist])]))]|_->[]letstr_of_type~options~pathtype_decl=let(ser_pre,ser_vals,ser_post)=ser_str_of_type~options~pathtype_declinlet(desu_pre,desu_vals,desu_post)=desu_str_of_type~options~pathtype_declinletfields_post=yojson_str_fields~options~pathtype_declin(ser_pre@desu_pre,ser_vals@desu_vals,ser_post@desu_post@fields_post)letstr_of_type_to_yojson~options~pathtype_decl=let(ser_pre,ser_vals,ser_post)=ser_str_of_type~options~pathtype_declinletfields_post=yojson_str_fields~options~pathtype_declin(ser_pre,ser_vals,ser_post@fields_post)letstr_of_type_of_yojson~options~pathtype_decl=let(desu_pre,desu_vals,desu_post)=desu_str_of_type~options~pathtype_declinletfields_post=yojson_str_fields~options~pathtype_declin(desu_pre,desu_vals,desu_post@fields_post)letstr_of_type_ext~options~pathtype_ext=letser_vals=ser_str_of_type_ext~options~pathtype_extinletdesu_vals=desu_str_of_type_ext~options~pathtype_extinser_vals@desu_valsletsig_of_type~options~pathtype_decl=(ser_sig_of_type~options~pathtype_decl)@(desu_sig_of_type~options~pathtype_decl)@(yojson_sig_fields~options~pathtype_decl)letsig_of_type_to_yojson~options~pathtype_decl=(ser_sig_of_type~options~pathtype_decl)@(yojson_sig_fields~options~pathtype_decl)letsig_of_type_of_yojson~options~pathtype_decl=(desu_sig_of_type~options~pathtype_decl)@(yojson_sig_fields~options~pathtype_decl)letsig_of_type_ext~options~pathtype_ext=(ser_sig_of_type_ext~options~pathtype_ext)@(desu_sig_of_type_ext~options~pathtype_ext)letstructuref~options~pathtype_=let(pre,vals,post)=f~options~pathtype_inmatchvalswith|[]->pre@post|_->pre@[Str.value?loc:NoneRecursivevals]@postleton_str_declsf~options~pathtype_decls=letunzip3l=List.fold_right(fun(v1,v2,v3)(a1,a2,a3)->(v1::a1,v2::a2,v3::a3))l([],[],[])inlet(pre,vals,post)=unzip3(List.map(f~options~path)type_decls)in(List.concatpre,List.concatvals,List.concatpost)leton_sig_declsf~options~pathtype_decls=List.concat(List.map(f~options~path)type_decls)let()=Ppx_deriving.(register(create"yojson"~type_decl_str:(structure(on_str_declsstr_of_type))~type_ext_str:str_of_type_ext~type_decl_sig:(on_sig_declssig_of_type)~type_ext_sig:sig_of_type_ext()));Ppx_deriving.(register(create"to_yojson"~core_type:(funtyp->lettyp=Ppx_deriving.strong_type_of_typetypinwrap_runtime(ser_expr_of_typtyp))~type_decl_str:(structure(on_str_declsstr_of_type_to_yojson))~type_ext_str:ser_str_of_type_ext~type_decl_sig:(on_sig_declssig_of_type_to_yojson)~type_ext_sig:ser_sig_of_type_ext()));Ppx_deriving.(register(create"of_yojson"~core_type:(funtyp->lettyp=Ppx_deriving.strong_type_of_typetypinwrap_runtime(desu_expr_of_typ~path:[]typ))~type_decl_str:(structure(on_str_declsstr_of_type_of_yojson))~type_ext_str:desu_str_of_type_ext~type_decl_sig:(on_sig_declssig_of_type_of_yojson)~type_ext_sig:desu_sig_of_type_ext()))