123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785openImportopenAst_builder.Default(* [do_insert_unused_warning_attribute] -- If true, generated code
contains compiler attribute to disable unused warnings, instead of
inserting [let _ = ... ]. *)letdo_insert_unused_warning_attribute=reffalseletkeep_w32_impl=reffalseletkeep_w32_intf=reffalselet()=letkeep_w32_spec=Caml.Arg.Symbol(["impl";"intf";"both"],function|"impl"->keep_w32_impl:=true|"intf"->keep_w32_intf:=true|"both"->keep_w32_impl:=true;keep_w32_intf:=true|_->assertfalse)inletconv_w32_spec=Caml.Arg.Symbol(["code";"attribute"],function|"code"->do_insert_unused_warning_attribute:=false|"attribute"->do_insert_unused_warning_attribute:=true|_->assertfalse)inDriver.add_arg"-deriving-keep-w32"keep_w32_spec~doc:" Do not try to disable warning 32 for the generated code";Driver.add_arg"-deriving-disable-w32-method"conv_w32_spec~doc:" How to disable warning 32 for the generated code";Driver.add_arg"-type-conv-keep-w32"keep_w32_spec~doc:" Deprecated, use -deriving-keep-w32";Driver.add_arg"-type-conv-w32"conv_w32_spec~doc:" Deprecated, use -deriving-disable-w32-method"letkeep_w32_impl()=!keep_w32_impl||Driver.pretty()letkeep_w32_intf()=!keep_w32_intf||Driver.pretty()letkeep_w60_impl=reffalseletkeep_w60_intf=reffalselet()=letkeep_w60_spec=Caml.Arg.Symbol(["impl";"intf";"both"],function|"impl"->keep_w60_impl:=true|"intf"->keep_w60_intf:=true|"both"->keep_w60_impl:=true;keep_w60_intf:=true|_->assertfalse)inDriver.add_arg"-deriving-keep-w60"keep_w60_spec~doc:" Do not try to disable warning 60 for the generated code"letkeep_w60_impl()=!keep_w60_impl||Driver.pretty()letkeep_w60_intf()=!keep_w60_intf||Driver.pretty()moduleArgs=structinclude(Ast_pattern:moduletypeofstructincludeAst_patternendwithtype('a,'b,'c)t:=('a,'b,'c)Ast_pattern.t)type'aparam={name:string;pattern:(expression,'a)Ast_pattern.Packed.t;default:'a;}letargnamepattern={name;default=None;pattern=Ast_pattern.Packed.createpattern(funx->Somex);}letflagname=letpattern=pexp_ident(lident(stringname))in{name;default=false;pattern=Ast_pattern.Packed.createpatterntrue}type(_,_)t=|Nil:('m,'m)t|Cons:('m1,'a->'m2)t*'aparam->('m1,'m2)tletempty=Nillet(+>)ab=Cons(a,b)letrecnames:typeab.(a,b)t->stringlist=function|Nil->[]|Cons(t,p)->p.name::namestmoduleInstance=structtype(_,_)instance=|I_nil:('m,'m)instance|I_cons:('m1,'a->'m2)instance*'a->('m1,'m2)instanceletreccreate:typeab.(a,b)t->(string*expression)list->(a,b)instance=funspecargs->matchspecwith|Nil->I_nil|Cons(t,p)->letvalue=matchList.assoc_optp.nameargswith|None->p.default|Someexpr->Ast_pattern.Packed.parsep.patternexpr.pexp_locexprinI_cons(createtargs,value)letrecapply:typeab.(a,b)instance->a->b=funtf->matchtwithI_nil->f|I_cons(t,x)->applytfxendletapplytargsf=Instance.apply(Instance.createtargs)fend(* +-----------------------------------------------------------------+
| Generators |
+-----------------------------------------------------------------+ *)typet=stringletignore(_:t)=()typeparsed_args=|Argsof(string*expression)list|Unknown_syntaxofLocation.t*stringmoduleGenerator=structtypederiver=ttype('a,'b)t=|T:{spec:('c,'a)Args.t;gen:ctxt:Expansion_context.Deriver.t->'b->'c;arg_names:String.Set.t;attributes:Attribute.packedlist;deps:deriverlist;}->('a,'b)tletdeps(Tt)=t.depsmoduleV2=structletmake?(attributes=[])?(deps=[])specgen=letarg_names=String.Set.of_list(Args.namesspec)inT{spec;gen;arg_names;attributes;deps}letmake_noarg?attributes?depsgen=make?attributes?depsArgs.emptygenendletmake?attributes?depsspecgen=V2.make?attributes?depsspec(Expansion_context.Deriver.with_loc_and_pathgen)letmake_noarg?attributes?depsgen=make?attributes?depsArgs.emptygenletmerge_accepted_argsl=letrecloopacc=function|[]->acc|Tt::rest->loop(String.Set.unionacct.arg_names)restinloopString.Set.emptylletcheck_argumentsnamegenerators(args:(string*expression)list)=List.iterargs~f:(fun(label,e)->ifString.is_emptylabelthenLocation.raise_errorf~loc:e.pexp_loc"Ppxlib.Deriving: generator arguments must be labelled");Option.iter(List.find_a_dupargs~compare:(fun(a,_)(b,_)->String.compareab))~f:(fun(label,e)->Location.raise_errorf~loc:e.pexp_loc"Ppxlib.Deriving: argument labelled '%s' appears more than once"label);letaccepted_args=merge_accepted_argsgeneratorsinList.iterargs~f:(fun(label,e)->ifnot(String.Set.memlabelaccepted_args)thenletspellcheck_msg=matchSpellcheck.spellcheck(String.Set.elementsaccepted_args)labelwith|None->""|Somes->".\n"^sinLocation.raise_errorf~loc:e.pexp_loc"Ppxlib.Deriving: generator '%s' doesn't accept argument '%s'%s"namelabelspellcheck_msg)letapply(Tt)~name:_~ctxtxargs=Args.applyt.specargs(t.gen~ctxtx)letapply_all~ctxtentry(name,generators,args)=check_argumentsname.txtgeneratorsargs;List.concat_mapgenerators~f:(funt->applyt~name:name.txt~ctxtentryargs)letapply_all~ctxtentrygenerators=List.concat_mapgenerators~f:(apply_all~ctxtentry)endmoduleDeriver=structmoduleActual_deriver=structtypet={name:string;str_type_decl:(structure,rec_flag*type_declarationlist)Generator.toption;str_type_ext:(structure,type_extension)Generator.toption;str_exception:(structure,type_exception)Generator.toption;str_module_type_decl:(structure,module_type_declaration)Generator.toption;sig_type_decl:(signature,rec_flag*type_declarationlist)Generator.toption;sig_type_ext:(signature,type_extension)Generator.toption;sig_exception:(signature,type_exception)Generator.toption;sig_module_type_decl:(signature,module_type_declaration)Generator.toption;extension:(loc:Location.t->path:string->core_type->expression)option;}endmoduleAlias=structtypet={str_type_decl:stringlist;str_type_ext:stringlist;str_exception:stringlist;str_module_type_decl:stringlist;sig_type_decl:stringlist;sig_type_ext:stringlist;sig_exception:stringlist;sig_module_type_decl:stringlist;}endmoduleField=structtypekind=Str|Sigtype('a,'b)t={name:string;kind:kind;get:Actual_deriver.t->('a,'b)Generator.toption;get_set:Alias.t->stringlist;}letstr_type_decl={kind=Str;name="type";get=(funt->t.str_type_decl);get_set=(funt->t.str_type_decl);}letstr_type_ext={kind=Str;name="type extension";get=(funt->t.str_type_ext);get_set=(funt->t.str_type_ext);}letstr_exception={kind=Str;name="exception";get=(funt->t.str_exception);get_set=(funt->t.str_exception);}letstr_module_type_decl={kind=Str;name="module type";get=(funt->t.str_module_type_decl);get_set=(funt->t.str_module_type_decl);}letsig_type_decl={kind=Sig;name="signature type";get=(funt->t.sig_type_decl);get_set=(funt->t.sig_type_decl);}letsig_type_ext={kind=Sig;name="signature type extension";get=(funt->t.sig_type_ext);get_set=(funt->t.sig_type_ext);}letsig_exception={kind=Sig;name="signature exception";get=(funt->t.sig_exception);get_set=(funt->t.sig_exception);}letsig_module_type_decl={kind=Sig;name="signature module type";get=(funt->t.sig_module_type_decl);get_set=(funt->t.sig_module_type_decl);}endtypet=Actual_deriverofActual_deriver.t|AliasofAlias.ttypePpx_derivers.deriver+=Toftletderivers()=List.filter_map(Ppx_derivers.derivers())~f:(function|name,Tt->Some(name,t)|_->None)exceptionNot_supportedofstringletresolve_actual_derivers(field:(_,_)Field.t)name=letrecloopnamecollected=ifList.existscollected~f:(fun(d:Actual_deriver.t)->String.equald.namename)thencollectedelsematchPpx_derivers.lookupnamewith|Some(T(Actual_deriverdrv))->drv::collected|Some(T(Aliasalias))->letset=field.get_setaliasinList.fold_rightset~init:collected~f:loop|_->raise(Not_supportedname)inList.rev(loopname[])letresolve_internal(field:(_,_)Field.t)name=List.map(resolve_actual_deriversfieldname)~f:(fundrv->matchfield.getdrvwith|None->raise(Not_supportedname)|Someg->(drv.name,g))letsupported_forfield=List.fold_left(derivers())~init:String.Set.empty~f:(funacc(name,_)->matchresolve_internalfieldnamewith|_->String.Set.addnameacc|exceptionNot_supported_->acc)|>String.Set.elementsletnot_supported(field:(_,_)Field.t)?(spellcheck=true)name=letspellcheck_msg=ifspellcheckthenmatchSpellcheck.spellcheck(supported_forfield)name.txtwith|None->""|Somes->".\n"^selse""inLocation.raise_errorf~loc:name.loc"Ppxlib.Deriving: '%s' is not a supported %s deriving generator%s"name.txtfield.namespellcheck_msgletresolvefieldname=tryresolve_internalfieldname.txtwithNot_supportedname'->not_supportedfield~spellcheck:(String.equalname.txtname')nameletresolve_allfieldderivers=letderivers_and_args=List.filter_mapderivers~f:(fun(name,args)->matchPpx_derivers.lookupname.txtwith|None->not_supportedfieldname|Some(T_)->(* It's one of ours, parse the arguments now. We can't do it before since
ppx_deriving uses a different syntax for arguments. *)Some(name,matchargswith|Argsl->l|Unknown_syntax(loc,msg)->Location.raise_errorf~loc"Ppxlib.Deriving: %s"msg)|Some_->(* It's not one of ours, ignore it. *)None)in(* Set of actual deriver names *)letseen=Hashtbl.create16inList.mapderivers_and_args~f:(fun(name,args)->letnamed_generators=resolvefieldnameinList.iternamed_generators~f:(fun(actual_deriver_name,gen)->ifOptions.fail_on_duplicate_derivers&&Hashtbl.memseenactual_deriver_namethenLocation.raise_errorf~loc:name.loc"Deriver %s appears twice"actual_deriver_name;List.iter(Generator.depsgen)~f:(fundep->List.iter(resolve_actual_deriversfielddep)~f:(fundrv->letdep_name=drv.nameinifnot(Hashtbl.memseendep_name)thenLocation.raise_errorf~loc:name.loc"Deriver %s is needed for %s, you need to add it \
before in the list"dep_namename.txt));Hashtbl.setseen~key:actual_deriver_name~data:());(name,List.mapnamed_generators~f:snd,args))letadd?str_type_decl?str_type_ext?str_exception?str_module_type_decl?sig_type_decl?sig_type_ext?sig_exception?sig_module_type_decl?extensionname=letactual_deriver:Actual_deriver.t={name;str_type_decl;str_type_ext;str_exception;str_module_type_decl;sig_type_decl;sig_type_ext;sig_exception;sig_module_type_decl;extension;}inPpx_derivers.registername(T(Actual_deriveractual_deriver));(matchextensionwith|None->()|Somef->letextension=Extension.declarenameExpressionAst_pattern.(ptyp__)finDriver.register_transformation("Ppxlib.Deriving."^name)~rules:[Context_free.Rule.extensionextension]);nameletadd_aliasname?str_type_decl?str_type_ext?str_exception?str_module_type_decl?sig_type_decl?sig_type_ext?sig_exception?sig_module_type_declset=letalias:Alias.t=letget=functionNone->set|Someset->setin{str_type_decl=getstr_type_decl;str_type_ext=getstr_type_ext;str_exception=getstr_exception;str_module_type_decl=getstr_module_type_decl;sig_type_decl=getsig_type_decl;sig_type_ext=getsig_type_ext;sig_exception=getsig_exception;sig_module_type_decl=getsig_module_type_decl;}inPpx_derivers.registername(T(Aliasalias));nameendletadd=Deriver.addletadd_alias=Deriver.add_alias(* +-----------------------------------------------------------------+
| [@@deriving ] parsing |
+-----------------------------------------------------------------+ *)letinvalid_with~loc=Location.raise_errorf~loc"invalid [@@deriving ] attribute syntax"letgenerator_name_of_idlocid=matchLongident.flatten_exnidwith|l->{loc;txt=String.concat~sep:"."l}|exception_->invalid_with~locexceptionUnknown_syntaxofLocation.t*stringletparse_argumentsl=tryArgs(matchlwith|[(Nolabel,e)]->(matche.pexp_descwith|Pexp_record(fields,None)->List.mapfields~f:(fun(id,expr)->letname=matchid.txtwith|Lidents->s|_->raise_notrace(Unknown_syntax(id.loc,"simple identifier expected"))in(name,expr))|_->raise_notrace(Unknown_syntax(e.pexp_loc,"non-optional labelled argument or record expected")))|l->List.mapl~f:(fun(label,expr)->matchlabelwith|Labelleds->(s,expr)|_->raise_notrace(Unknown_syntax(expr.pexp_loc,"non-optional labelled argument expected"))))withUnknown_syntax(loc,msg)->Unknown_syntax(loc,msg)letmk_deriving_attrcontext~prefix~suffix=Attribute.declare(prefix^"deriving"^suffix)contextAst_pattern.(letgenerator_name()=map'(pexp_ident__)~f:(funlocfid->f(generator_name_of_idlocid))inletgenerator()=map(generator_name())~f:(funfx->f(x,Args[]))|||pack2(pexp_apply(generator_name())(map1(many__)~f:parse_arguments))inletgenerators=pexp_tuple(many(generator()))|||map(generator())~f:(funfx->f[x])inpstr(pstr_evalgeneratorsnil^::nil))(funx->x)(* +-----------------------------------------------------------------+
| Unused warning stuff + locations check silencing |
+-----------------------------------------------------------------+ *)letdisable_warnings_attributewarnings=letloc=Location.noneinletstring=List.sortwarnings~cmp:Int.compare|>List.map~f:(funwarning->"-"^Int.to_stringwarning)|>String.concat~sep:""in{attr_name={txt="ocaml.warning";loc};attr_payload=PStr[pstr_eval~loc(estring~locstring)[]];attr_loc=loc;}letinline_doc_attr=letloc=Location.nonein{attr_name={txt="ocaml.doc";loc};attr_payload=PStr[pstr_eval~loc(estring~loc"@inline")[]];attr_loc=loc;}letwrap_str~loc~hidest=letinclude_infos=include_infos~loc(pmod_structure~locst)inletpincl_attributes=ifhidethen[inline_doc_attr;Merlin_helpers.hide_attribute]else[inline_doc_attr]in[pstr_include~loc{include_infoswithpincl_attributes}]letwrap_str~loc~hidest=letloc={locwithloc_ghost=true}inletwarnings,st=ifkeep_w32_impl()then([],st)elseifnot!do_insert_unused_warning_attributethen([],Ignore_unused_warning.add_dummy_user_for_values#structurest)else([32],st)inletwarnings,st=ifkeep_w60_impl()||not(Ignore_unused_warning.binds_module_names#structurestfalse)then(warnings,st)else(60::warnings,st)inletwrap,st=ifList.is_emptywarningsthen(hide,st)else(true,pstr_attribute~loc(disable_warnings_attributewarnings)::st)inifwrapthenwrap_str~loc~hidestelsestletwrap_sig~loc~hidest=letinclude_infos=include_infos~loc(pmty_signature~locst)inletpincl_attributes=ifhidethen[inline_doc_attr;Merlin_helpers.hide_attribute]else[inline_doc_attr]in[psig_include~loc{include_infoswithpincl_attributes}]letwrap_sig~loc~hidesg=letloc={locwithloc_ghost=true}inletwarnings=ifkeep_w32_intf()then[]else[32]inletwarnings=ifkeep_w60_intf()||not(Ignore_unused_warning.binds_module_names#signaturesgfalse)thenwarningselse60::warningsinletwrap,sg=ifList.is_emptywarningsthen(hide,sg)else(true,psig_attribute~loc(disable_warnings_attributewarnings)::sg)inifwrapthenwrap_sig~loc~hidesgelsesg(* +-----------------------------------------------------------------+
| Remove attributes used by syntax extensions |
+-----------------------------------------------------------------+ *)(*
let remove generators =
let attributes =
List.concat_map generators ~f:(fun (_, actual_generators, _) ->
List.concat_map actual_generators ~f:(fun (Generator.T g) -> g.attributes))
in
object
inherit Ast_traverse.map
(* Don't recurse through attributes and extensions *)
method! attribute x = x
method! extension x = x
method! label_declaration ld =
Attribute.remove_seen Attribute.Context.label_declaration attributes ld
method! constructor_declaration cd =
Attribute.remove_seen Attribute.Context.constructor_declaration attributes cd
end
*)(* +-----------------------------------------------------------------+
| Main expansion |
+-----------------------------------------------------------------+ *)lettypes_used_by_deriving(tds:type_declarationlist):structure_itemlist=ifkeep_w32_impl()then[]elseList.maptds~f:(funtd->lettyp=Common.core_type_of_type_declarationtdinletloc=td.ptype_locinpstr_value~locNonrecursive[value_binding~loc~pat:(ppat_any~loc)~expr:(pexp_fun~locNolabelNone(ppat_constraint~loc(ppat_any~loc)typ)(eunit~loc));])letmerge_generatorsfieldl=List.filter_mapl~f:(funx->x)|>List.concat|>Deriver.resolve_allfieldletexpand_str_type_decls~ctxtrec_flagtdsvalues=letgenerators=merge_generatorsDeriver.Field.str_type_declvaluesin(* TODO: instead of disabling the unused warning for types themselves, we
should add a tag [@@unused]. *)letgenerated=types_used_by_derivingtds@Generator.apply_all~ctxt(rec_flag,tds)generatorsinwrap_str~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_sig_type_decls~ctxtrec_flagtdsvalues=letgenerators=merge_generatorsDeriver.Field.sig_type_declvaluesinletgenerated=Generator.apply_all~ctxt(rec_flag,tds)generatorsinwrap_sig~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_str_module_type_decl~ctxtmtdgenerators=letgenerators=Deriver.resolve_allDeriver.Field.str_module_type_declgeneratorsinletgenerated=Generator.apply_all~ctxtmtdgeneratorsinwrap_str~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_sig_module_type_decl~ctxtmtdgenerators=letgenerators=Deriver.resolve_allDeriver.Field.sig_module_type_declgeneratorsinletgenerated=Generator.apply_all~ctxtmtdgeneratorsinwrap_sig~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_str_exception~ctxtecgenerators=letgenerators=Deriver.resolve_allDeriver.Field.str_exceptiongeneratorsinletgenerated=Generator.apply_all~ctxtecgeneratorsinwrap_str~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_sig_exception~ctxtecgenerators=letgenerators=Deriver.resolve_allDeriver.Field.sig_exceptiongeneratorsinletgenerated=Generator.apply_all~ctxtecgeneratorsinwrap_sig~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_str_type_ext~ctxttegenerators=letgenerators=Deriver.resolve_allDeriver.Field.str_type_extgeneratorsinletgenerated=Generator.apply_all~ctxttegeneratorsinwrap_str~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletexpand_sig_type_ext~ctxttegenerators=letgenerators=Deriver.resolve_allDeriver.Field.sig_type_extgeneratorsinletgenerated=Generator.apply_all~ctxttegeneratorsinwrap_sig~loc:(Expansion_context.Deriver.derived_item_locctxt)~hide:(not@@Expansion_context.Deriver.inlinectxt)generatedletrules~typ~expand_sig~expand_str~rule_str~rule_sig~rule_str_expect~rule_sig_expect=letprefix="ppxlib."inletderiving_attr=mk_deriving_attr~suffix:""~prefixtypinletderiving_attr_expect=mk_deriving_attr~suffix:"_inline"~prefixtypin[rule_sigderiving_attrexpand_sig;rule_strderiving_attrexpand_str;rule_str_expectderiving_attr_expectexpand_str;rule_sig_expectderiving_attr_expectexpand_sig;]letrules_type_decl=rules~typ:Type_declaration~expand_str:expand_str_type_decls~expand_sig:expand_sig_type_decls~rule_str:Context_free.Rule.attr_str_type_decl~rule_sig:Context_free.Rule.attr_sig_type_decl~rule_str_expect:Context_free.Rule.attr_str_type_decl_expect~rule_sig_expect:Context_free.Rule.attr_sig_type_decl_expectletrules_type_ext=rules~typ:Type_extension~expand_str:expand_str_type_ext~expand_sig:expand_sig_type_ext~rule_str:Context_free.Rule.attr_str_type_ext~rule_sig:Context_free.Rule.attr_sig_type_ext~rule_str_expect:Context_free.Rule.attr_str_type_ext_expect~rule_sig_expect:Context_free.Rule.attr_sig_type_ext_expectletrules_exception=rules~typ:Type_exception~expand_str:expand_str_exception~expand_sig:expand_sig_exception~rule_str:Context_free.Rule.attr_str_exception~rule_sig:Context_free.Rule.attr_sig_exception~rule_str_expect:Context_free.Rule.attr_str_exception_expect~rule_sig_expect:Context_free.Rule.attr_sig_exception_expectletrules_module_type_decl=rules~typ:Module_type_declaration~expand_str:expand_str_module_type_decl~expand_sig:expand_sig_module_type_decl~rule_str:Context_free.Rule.attr_str_module_type_decl~rule_sig:Context_free.Rule.attr_sig_module_type_decl~rule_str_expect:Context_free.Rule.attr_str_module_type_decl_expect~rule_sig_expect:Context_free.Rule.attr_sig_module_type_decl_expectlet()=letrules=[rules_type_decl;rules_type_ext;rules_exception;rules_module_type_decl]|>List.concatinDriver.register_transformation"deriving"~aliases:["type_conv"]~rules