123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536openImportopenLexingtypeloc=Lexing.position*Lexing.positionletdummy_loc=(Lexing.dummy_pos,Lexing.dummy_pos)exceptionAtd_errorofstringtypefull_module=module_head*module_bodyandmodule_head=loc*annotandmodule_body=module_itemlistandannot=annot_sectionlistandannot_section=string*(loc*annot_fieldlist)andannot_field=string*(loc*stringoption)andtype_def=loc*(string*type_param*annot)*type_exprandmodule_item=|Typeoftype_defandtype_param=stringlistandtype_expr=|Sumofloc*variantlist*annot|Recordofloc*fieldlist*annot|Tupleofloc*celllist*annot|Listofloc*type_expr*annot|Optionofloc*type_expr*annot|Nullableofloc*type_expr*annot|Sharedofloc*type_expr*annot|Wrapofloc*type_expr*annot|Nameofloc*type_inst*annot|Tvarofloc*string(* List, Option, Nullable, Shared and Wrap are
the only predefined types with a type
parameter (and no special syntax). *)andtype_inst=loc*string*type_exprlistandvariant=|Variantofloc*(string*annot)*type_exproption|Inheritofloc*type_exprandcell=loc*type_expr*annotandfield_kind=|Required|Optional|With_defaultandsimple_field=(loc*(string*field_kind*annot)*type_expr)andfield=[`Fieldofsimple_field|`Inheritof(loc*type_expr)]typeany=|Full_moduleoffull_module|Module_headofmodule_head|Module_bodyofmodule_body|Module_itemofmodule_item|Type_defoftype_def|Type_exproftype_expr|Variantofvariant|Cellofcell|Fieldoffieldletloc_of_type_expr=function|Sum(loc,_,_)|Record(loc,_,_)|Tuple(loc,_,_)|List(loc,_,_)|Option(loc,_,_)|Nullable(loc,_,_)|Shared(loc,_,_)|Wrap(loc,_,_)|Name(loc,_,_)|Tvar(loc,_)->locletrecamap_type_exprf=function|Sum(loc,vl,a)->Sum(loc,List.map(amap_variantf)vl,fa)|Record(loc,fl,a)->Record(loc,List.map(amap_fieldf)fl,fa)|Tuple(loc,tl,a)->Tuple(loc,List.map(amap_cellf)tl,fa)|List(loc,t,a)->List(loc,amap_type_exprft,fa)|Option(loc,t,a)->Option(loc,amap_type_exprft,fa)|Nullable(loc,t,a)->Nullable(loc,amap_type_exprft,fa)|Shared(loc,t,a)->Shared(loc,amap_type_exprft,fa)|Wrap(loc,t,a)->Wrap(loc,amap_type_exprft,fa)|Tvar_asx->x|Name(loc,(loc2,name,args),a)->Name(loc,(loc2,name,List.map(amap_type_exprf)args),fa)andamap_variantf=functionVariant(loc,(name,a),o)->leto=Option.map(amap_type_exprf)oinVariant(loc,(name,fa),o)|Inherit(loc,x)->Inherit(loc,amap_type_exprfx)andamap_fieldf=function`Field(loc,(name,kind,a),x)->`Field(loc,(name,kind,fa),amap_type_exprfx)|`Inherit(loc,x)->`Inherit(loc,amap_type_exprfx)andamap_cellf(loc,x,a)=(loc,amap_type_exprfx,fa)letamap_module_itemf(Type(loc,(name,param,a),x))=Type(loc,(name,param,fa),amap_type_exprfx)letamap_headf(loc,a)=(loc,fa)letamap_bodyfl=List.map(amap_module_itemf)lletmap_all_annotf((head,body):full_module)=(amap_headfhead,amap_bodyfbody)letset_type_expr_locloc=function|Sum(_,a,b)->Sum(loc,a,b)|Record(_,a,b)->Record(loc,a,b)|Tuple(_,a,b)->Tuple(loc,a,b)|List(_,a,b)->List(loc,a,b)|Option(_,a,b)->Option(loc,a,b)|Nullable(_,a,b)->Nullable(loc,a,b)|Shared(_,a,b)->Shared(loc,a,b)|Wrap(_,a,b)->Wrap(loc,a,b)|Name(_,a,b)->Name(loc,a,b)|Tvar(_,a)->Tvar(loc,a)letstring_of_loc(pos1,pos2)=letline1=pos1.pos_lnumandstart1=pos1.pos_bolinPrintf.sprintf"File %S, line %i, characters %i-%i"pos1.pos_fnameline1(pos1.pos_cnum-start1)(pos2.pos_cnum-start1)leterrors=raise(Atd_errors)leterror_atlocs=error(string_of_locloc^":\n"^s)letannot_of_type_expr=function|Sum(_,_,an)|Record(_,_,an)|Tuple(_,_,an)|List(_,_,an)|Option(_,_,an)|Nullable(_,_,an)|Shared(_,_,an)|Wrap(_,_,an)|Name(_,_,an)->an|Tvar(_,_)->[]letannot_of_variant(x:variant)=matchxwith|Variant(_,(_,an),_)->an|Inherit_->[]letannot_of_field(x:field)=matchxwith|`Field(_,(_,_,an),_)->an|`Inherit_->[]letmap_annotf=function|Sum(loc,vl,a)->Sum(loc,vl,fa)|Record(loc,fl,a)->Record(loc,fl,fa)|Tuple(loc,tl,a)->Tuple(loc,tl,fa)|List(loc,t,a)->List(loc,t,fa)|Option(loc,t,a)->Option(loc,t,fa)|Nullable(loc,t,a)->Nullable(loc,t,fa)|Shared(loc,t,a)->Shared(loc,t,fa)|Wrap(loc,t,a)->Wrap(loc,t,fa)|Tvar_asx->x|Name(loc,(loc2,name,args),a)->Name(loc,(loc2,name,args),fa)typevisitor_hooks={full_module:(full_module->unit)->full_module->unit;module_head:(module_head->unit)->module_head->unit;module_body:(module_body->unit)->module_body->unit;module_item:(module_item->unit)->module_item->unit;type_def:(type_def->unit)->type_def->unit;type_expr:(type_expr->unit)->type_expr->unit;variant:(variant->unit)->variant->unit;cell:(cell->unit)->cell->unit;field:(field->unit)->field->unit;}letrecvisit_type_exprhooksx=letcontx=matchxwith|Sum(loc,vl,a)->List.iter(visit_varianthooks)vl|Record(loc,fl,a)->List.iter(visit_fieldhooks)fl|Tuple(loc,tl,a)->List.iter(visit_cellhooks)tl|List(loc,t,a)->visit_type_exprhookst|Option(loc,t,a)->visit_type_exprhookst|Nullable(loc,t,a)->visit_type_exprhookst|Shared(loc,t,a)->visit_type_exprhookst|Wrap(loc,t,a)->visit_type_exprhookst|Tvar_->()|Name(loc,(loc2,name,args),a)->List.iter(visit_type_exprhooks)argsinhooks.type_exprcontxandvisit_varianthooksx=letcontx=match(x:variant)with|Variant(loc,(name,a),o)->(matchowith|None->()|Somex->visit_type_exprhooksx)|Inherit(loc,x)->visit_type_exprhooksxinhooks.variantcontxandvisit_fieldhooksx=letcontx=matchxwith|`Field(loc,(name,kind,a),x)->visit_type_exprhooksx|`Inherit(loc,x)->visit_type_exprhooksxinhooks.fieldcontxandvisit_cellhooksx=letcont(loc,x,a)=visit_type_exprhooksxinhooks.cellcontxletvisit_type_defhooksx=letcont(loc,(name,param,a),x)=visit_type_exprhooksxinhooks.type_defcontxletvisit_module_itemhooksx=letcont(Typex)=visit_type_defhooksxinhooks.module_itemcontxletvisit_module_headhooksx=letcontx=()inhooks.module_headcontxletvisit_module_bodyhooksx=letcontx=List.iter(visit_module_itemhooks)xinhooks.module_bodycontxletvisit_full_modulehooksx=letcont(head,body)=visit_module_headhookshead;visit_module_bodyhooksbodyinhooks.full_modulecontxletvisit?(full_module=funcontx->contx)?(module_head=funcontx->contx)?(module_body=funcontx->contx)?(module_item=funcontx->contx)?(type_def=funcontx->contx)?(type_expr=funcontx->contx)?(variant=funcontx->contx)?(cell=funcontx->contx)?(field=funcontx->contx)()=lethooks:visitor_hooks={full_module;module_head;module_body;module_item;type_def;type_expr;variant;cell;field;}inletvisit(any:any)=matchanywith|Full_modulex->visit_full_modulehooksx|Module_headx->visit_module_headhooksx|Module_bodyx->visit_module_bodyhooksx|Module_itemx->visit_module_itemhooksx|Type_defx->visit_type_defhooksx|Type_exprx->visit_type_exprhooksx|Variantx->visit_varianthooksx|Cellx->visit_cellhooksx|Fieldx->visit_fieldhooksxinvisitletfold_annot?module_head?type_def?type_expr?variant?cell?fieldanyinit=letacc=refinitinletfoldopt_folderget_annot=matchopt_folderwith|None->(funcontx->contx)|Somef->(funcontx->acc:=fx(get_annotx)!acc;contx)inletvisitor=visit~module_head:(foldmodule_head(fun(_,an)->an))~type_def:(foldtype_def(fun(_,(_,_,an),_)->an))~type_expr:(foldtype_exprannot_of_type_expr)~variant:(foldvariantannot_of_variant)~cell:(foldcell(fun(_,_,an)->an))~field:(foldfieldannot_of_field)()invisitorany;!acc(* TODO: rewrite this more compactly using the visitor machinery above *)letrecfold(f:type_expr->'a->'a)(x:type_expr)acc=letacc=fxaccinmatchxwithSum(_,variant_list,_annot)->List.fold_right(fold_variantf)variant_listacc|Record(_,field_list,_annot)->List.fold_right(fold_fieldf)field_listacc|Tuple(_,l,_annot)->List.fold_right(fun(_,x,_)acc->foldfxacc)lacc|List(_,type_expr,_annot)->foldftype_expracc|Option(_,type_expr,_annot)->foldftype_expracc|Nullable(_,type_expr,_annot)->foldftype_expracc|Shared(_,type_expr,_annot)->foldftype_expracc|Wrap(_,type_expr,_annot)->foldftype_expracc|Name(_,(_2,_name,type_expr_list),_annot)->List.fold_right(foldf)type_expr_listacc|Tvar(_,_string)->accandfold_variantfxacc=matchxwithVariant(_,_,Sometype_expr)->foldftype_expracc|Variant_->acc|Inherit(_,type_expr)->foldftype_expraccandfold_fieldfxacc=matchxwith`Field(_,_,type_expr)->foldftype_expracc|`Inherit(_,type_expr)->foldftype_expraccmoduleType_names=Set.Make(String)letextract_type_names?(ignorable=[])x=letigns=List.memsignorableinletaddsset=ifignsthensetelseType_names.addssetinletacc=fold(funxacc->matchxwithName(_,(_,name,_),_)->addnameacc|_->acc)xType_names.emptyinType_names.elementsaccletis_parametrizedx=fold(funxb->b||matchxwithTvar_->true|_->false)xfalseletis_required=function|Optional|With_default->false|Required->truemoduleMap=structtypemappers={(* TODO: support other node types *)type_expr:type_expr->type_expr;}letdefault_mappers={type_expr=(funx->x);}letrectype_exprm(x:type_expr):type_expr=matchm.type_exprxwith|Sum(loc,variant_list,an)->Sum(loc,List.map(variantm)variant_list,an)|Record(loc,field_list,an)->Record(loc,List.map(fieldm)field_list,an)|Tuple(loc,cells,an)->letcells=List.map(fun(loc,x,an)->(loc,type_exprmx,an))cellsinTuple(loc,cells,an)|List(loc,x,an)->List(loc,type_exprmx,an)|Option(loc,x,an)->Option(loc,type_exprmx,an)|Nullable(loc,x,an)->Nullable(loc,type_exprmx,an)|Shared(loc,x,an)->Shared(loc,type_exprmx,an)|Wrap(loc,x,an)->Wrap(loc,type_exprmx,an)|Name(loc,(loc2,name,args),an)->letargs=List.map(type_exprm)argsinName(loc,(loc2,name,args),an)|Tvar(_,_)asx->xandvariantmx=matchxwith|Variant(loc,name,Somex)->Variant(loc,name,Some(type_exprmx))|Variant_asx->x|Inherit(loc,x)->Inherit(loc,type_exprmx)andfieldmx=matchxwith|`Field(loc,k,x)->`Field(loc,k,type_exprmx)|`Inherit(loc,x)->`Inherit(loc,type_exprmx)lettype_defm(loc,(name,params,an),x)=(loc,(name,params,an),type_exprmx)letmodule_itemmx=matchxwith|Typex->Type(type_defmx)letmodule_bodymx=List.map(module_itemm)xletfull_modulem(head,body)=(head,module_bodymbody)endletuse_only_specific_variantsx=lettype_exprx=matchxwith|Name(loc,(loc2,name,[arg]),an)->(matchnamewith|"list"->List(loc,arg,an)|"option"->Option(loc,arg,an)|"nullable"->Nullable(loc,arg,an)|"shared"->Shared(loc,arg,an)|"wrap"->Wrap(loc,arg,an)|_->x)|Name(loc,(loc2,name,_),an)asx->x|Sum_|Record_|Tuple_|Tvar_|List_|Option_|Nullable_|Shared_|Wrap_asx->xinletmappers={Map.type_expr}inMap.full_modulemappersxletuse_only_name_variantx=lettype_exprx=matchxwith|List(loc,arg,an)->Name(loc,(loc,"list",[arg]),an)|Option(loc,arg,an)->Name(loc,(loc,"option",[arg]),an)|Nullable(loc,arg,an)->Name(loc,(loc,"nullable",[arg]),an)|Shared(loc,arg,an)->Name(loc,(loc,"shared",[arg]),an)|Name_|Sum_|Record_|Tuple_|Tvar_|Wrap_asx->xinletmappers={Map.type_expr}inMap.full_modulemappersx(*
Eliminate the 'Wrap' constructs.
The result is guaranteed to not be of the form 'Wrap ...' but it may
contain 'Wrap' constructs within its type arguments.
*)letrecshallow_unwrape=matchewith|Wrap(loc,e,an)->shallow_unwrape|Shared_|Tvar_|Sum_|Record_|Tuple_|List_|Option_|Nullable_|Name_->eletremove_wrap_constructsm=Map.full_module{type_expr=shallow_unwrap}m