123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032(*
* Copyright (c) 2014 Leo White <lpw25@cl.cam.ac.uk>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openAsttypesopenTypesmoduleOCamlPath=PathopenOdoc_model.PathsopenOdoc_model.LangopenOdoc_model.NamesmoduleEnv=Odoc_model.Ident_envmodulePaths=Odoc_model.PathsmoduleIdent_env=Odoc_model.Ident_envletopt_mapf=function|None->None|Somex->Some(fx)letopt_iterf=function|None->()|Somex->fxletparenthesisename=matchnamewith|"asr"|"land"|"lnot"|"lor"|"lsl"|"lsr"|"lxor"|"mod"->"("^name^")"|_->if(String.lengthname>0)thenmatchname.[0]with|'a'..'z'|'\223'..'\246'|'\248'..'\255'|'_'|'A'..'Z'|'\192'..'\214'|'\216'..'\222'->name|_->"("^name^")"elsenameletread_labellbl=letopenTypeExprin#ifOCAML_MAJOR=4&&OCAML_MINOR=02(* NOTE(@ostera): 4.02 does not have an Asttypes variant for whether the
* label exists, and is an optional label or not, so I went back to string
* manipulation *)ifString.lengthlbl==0thenNoneelsematchString.getlbl0with|'?'->Some(Optional(String.sublbl1(String.lengthlbl-1)))|_->Some(Labellbl)#elsematchlblwith|Asttypes.Nolabel->None|Asttypes.Labelleds->Some(Labels)|Asttypes.Optionals->Some(Optionals)#endif(* Handle type variable names *)letused_names=ref[]letname_counter=ref0letreserved_names=ref[]letreset_names()=used_names:=[];name_counter:=0;reserved_names:=[]letreserve_name=function|Somename->ifnot(List.memname!reserved_names)thenreserved_names:=name::!reserved_names|None->()letrecnext_name()=letname=if!name_counter<26thenString.make1(Char.chr(97+!name_counter))elseString.make1(Char.chr(97+!name_countermod26))^string_of_int(!name_counter/26)inincrname_counter;ifList.memname!reserved_namesthennext_name()elsenameletfresh_namebase=letcurrent_name=refbaseinleti=ref0inwhileList.exists(fun(_,name')->!current_name=name')!used_namesdocurrent_name:=base^(string_of_int!i);i:=!i+1;done;!current_nameletname_of_type(ty:Types.type_expr)=tryList.assqty!used_nameswithNot_found->letbase=matchty.descwith|Tvar(Somename)|Tunivar(Somename)->name|_->next_name()inletname=fresh_namebaseinifname<>"_"thenused_names:=(ty,name)::!used_names;nameletremove_namestyl=used_names:=List.filter(fun(ty,_)->not(List.memqtytyl))!used_names(* Handle recursive types and shared row variables *)letaliased=ref[]letused_aliases=ref[]letreset_aliased()=aliased:=[];used_aliases:=[]letis_aliasedpx=List.memqpx!aliasedletaliasable(ty:Types.type_expr)=matchty.descwith|Tvar_|Tunivar_|Tpoly_->false|_->trueletadd_aliasty=letpx=Btype.proxytyinifnot(List.memqpx!aliased)thenbeginaliased:=px::!aliased;matchpx.descwith|Tvarname|Tunivarname->reserve_namename|_->()endletused_alias(px:Types.type_expr)=List.memqpx!used_aliasesletuse_alias(px:Types.type_expr)=used_aliases:=px::!used_aliasesletvisited_rows=ref[]letreset_visited_rows()=visited_rows:=[]letis_row_visitedpx=List.memqpx!visited_rowsletvisit_rowpx=visited_rows:=px::!visited_rowsletvisit_objecttypx=ifCtype.opened_objecttythenvisited_rows:=px::!visited_rowsletnamable_rowrow=row.row_name<>None&&List.for_all(fun(_,f)->matchBtype.row_field_reprfwith|Reither(c,l,_,_)->row.row_closed&&ifcthenl=[]elseList.lengthl=1|_->true)row.row_fieldsletmark_typety=letrecloopvisitedty=letty=Btype.reprtyinletpx=Btype.proxytyinifList.memqpxvisited&&aliasabletythenadd_aliaspxelseletvisited=px::visitedinmatchty.descwith|Tvarname->reserve_namename|Tarrow(_,ty1,ty2,_)->loopvisitedty1;loopvisitedty2|Ttupletyl->List.iter(loopvisited)tyl|Tconstr(_,tyl,_)->List.iter(loopvisited)tyl|Tvariantrow->ifis_row_visitedpxthenadd_aliaspxelsebeginletrow=Btype.row_reprrowinifnot(Btype.static_rowrow)thenvisit_rowpx;matchrow.row_namewith|Some(_,tyl)whennamable_rowrow->List.iter(loopvisited)tyl|_->Btype.iter_row(loopvisited)rowend|Tobject(fi,nm)->ifis_row_visitedpxthenadd_aliaspxelsebeginvisit_objecttypx;match!nmwith|None->letfields,_=Ctype.flatten_fieldsfiinList.iter(fun(_,kind,ty)->ifBtype.field_kind_reprkind=Fpresentthenloopvisitedty)fields|Some(_,l)->List.iter(loopvisited)(List.tll)end|Tfield(_,kind,ty1,ty2)whenBtype.field_kind_reprkind=Fpresent->loopvisitedty1;loopvisitedty2|Tfield(_,_,_,ty2)->loopvisitedty2|Tnil->()|Tpoly(ty,tyl)->List.iter(funt->add_aliast)tyl;loopvisitedty|Tunivarname->reserve_namename#ifOCAML_VERSION>=(4,13,0)|Tpackage(_,tyl)->List.iter(fun(_,x)->loopvisitedx)tyl#else|Tpackage(_,_,tyl)->List.iter(loopvisited)tyl#endif#ifOCAML_VERSION<(4,13,0)|Tsubstty->loopvisitedty#else|Tsubst(ty,_)->loopvisitedty#endif|Tlink_->assertfalseinloop[]tyletreset_context()=reset_names();reset_aliased();reset_visited_rows()letmark_type_exprt=reset_context();mark_typetletmark_value_descriptionvd=reset_context();mark_typevd.val_typeletmark_type_parameterparam=add_aliasparam;mark_typeparam;ifaliasableparamthenuse_alias(Btype.proxyparam)#ifOCAML_VERSION<(4,13,0)lettsubstx=Tsubstxlettvar_nonety=ty.desc<-TvarNone#elselettsubstx=Tsubst(x,None)lettvar_nonety=Types.Private_type_expr.set_descty(TvarNone)#endifletprepare_type_parametersparamsmanifest=letparams=List.fold_left(funparamsparam->letparam=Btype.reprparaminifList.memqparamparamsthenBtype.newgenty(tsubstparam)::paramselseparam::params)[]paramsinletparams=List.revparamsinbeginmatchmanifestwith|Somety->letvars=Ctype.free_variablestyinList.iter(function{desc=Tvar(Some"_");_}asty->ifList.memqtyvarsthentvar_nonety|_->())params|None->()end;params(* NOTE(@ostera): constructor with inlined records were introduced post 4.02 *)letmark_constructor_args=#ifOCAML_MAJOR=4&&OCAML_MINOR=02List.itermark_type#elsefunction|Cstr_tupleargs->List.itermark_typeargs|Cstr_recordlds->List.iter(funld->mark_typeld.ld_type)lds#endifletmark_type_kind=function|Type_abstract->()#ifOCAML_VERSION>=(4,13,0)|Type_variant(cds,_)->#else|Type_variantcds->#endifList.iter(funcd->mark_constructor_argscd.cd_args;opt_itermark_typecd.cd_res)cds|Type_record(lds,_)->List.iter(funld->mark_typeld.ld_type)lds|Type_open->()letmark_type_declarationdecl=letparams=prepare_type_parametersdecl.type_paramsdecl.type_manifestinreset_context();List.itermark_type_parameterparams;opt_itermark_typedecl.type_manifest;mark_type_kinddecl.type_kind;paramsletmark_extension_constructorext=mark_constructor_argsext.ext_args;opt_itermark_typeext.ext_ret_typeletmark_type_extensiontype_paramsexts=lettype_params=prepare_type_parameterstype_paramsNoneinreset_context();List.itermark_type_parametertype_params;List.itermark_extension_constructorexts;type_paramsletmark_type_extension'extrest=lettype_params=ext.ext_type_paramsinletexts=ext::(List.mapsndrest)inmark_type_extensiontype_paramsextsletmark_exceptionext=reset_context();mark_extension_constructorextletrecmark_class_typeparams=function|Cty_constr(_,tyl,cty)->letsty=Ctype.self_typectyinifis_row_visited(Btype.proxysty)||List.existsaliasableparams||List.exists(Ctype.deep_occursty)tylthenmark_class_typeparamsctyelseList.itermark_typetyl|Cty_signaturesign->letsty=Btype.reprsign.csig_selfinletpx=Btype.proxystyinifis_row_visitedpxthenadd_aliasstyelsevisit_rowpx;let(fields,_)=Ctype.flatten_fields(Ctype.object_fieldssign.csig_self)inList.iter(fun(_,_,ty)->mark_typety)fields;Vars.iter(fun_(_,_,ty)->mark_typety)sign.csig_vars;ifis_aliasedsty&&aliasablestythenuse_aliaspx|Cty_arrow(_,ty,cty)->mark_typety;mark_class_typeparamsctyletmark_class_type_declarationcltd=reset_context();List.itermark_type_parametercltd.clty_params;mark_class_typecltd.clty_paramscltd.clty_typeletmark_class_declarationcld=reset_context();List.itermark_type_parametercld.cty_params;mark_class_typecld.cty_paramscld.cty_typeletrecread_type_exprenvtyp=letopenTypeExprinlettyp=Btype.reprtypinletpx=Btype.proxytypinifused_aliaspxthenVar(name_of_typetyp)elsebeginletalias=ifnot(is_aliasedpx&&aliasabletyp)thenNoneelsebeginuse_aliaspx;Some(name_of_typetyp)endinlettyp=matchtyp.descwith|Tvar_->letname=name_of_typetypinifname="_"thenAnyelseVarname|Tarrow(lbl,arg,res,_)->letarg=ifBtype.is_optionallblthenmatch(Btype.reprarg).descwith|Tconstr(_option,[arg],_)->read_type_exprenvarg|_->assertfalseelseread_type_exprenvarginletlbl=read_labellblinletres=read_type_exprenvresinArrow(lbl,arg,res)|Ttupletyps->lettyps=List.map(read_type_exprenv)typsinTupletyps|Tconstr(p,params,_)->letp=Env.Path.read_typeenvpinletparams=List.map(read_type_exprenv)paramsinConstr(p,params)|Tvariantrow->read_rowenvpxrow|Tobject(fi,nm)->read_objectenvfi!nm|Tnil|Tfield_->read_objectenvtypNone|Tpoly(typ,[])->read_type_exprenvtyp|Tpoly(typ,tyl)->lettyl=List.mapBtype.reprtylinletvars=List.mapname_of_typetylinlettyp=read_type_exprenvtypinremove_namestyl;Poly(vars,typ)|Tunivar_->Var(name_of_typetyp)#ifOCAML_VERSION>=(4,13,0)|Tpackage(p,eqs)->#else|Tpackage(p,frags,tyl)->leteqs=List.combinefragstylin#endifletopenTypeExpr.Packageinletpath=Env.Path.read_module_typeenvpinletsubstitutions=List.map(fun(frag,typ)->letfrag=Env.Fragment.read_typefraginlettyp=read_type_exprenvtypin(frag,typ))eqsinPackage{path;substitutions}#ifOCAML_VERSION<(4,13,0)|Tsubsttyp->read_type_exprenvtyp#else|Tsubst(typ,_)->read_type_exprenvtyp#endif|Tlink_->assertfalseinmatchaliaswith|None->typ|Somename->Alias(typ,name)endandread_rowenv_pxrow=letopenTypeExprinletopenTypeExpr.Polymorphic_variantinletrow=Btype.row_reprrowinletfields=ifrow.row_closedthenList.filter(fun(_,f)->Btype.row_field_reprf<>Rabsent)row.row_fieldselserow.row_fieldsinletsorted_fields=List.sort(fun(p,_)(q,_)->comparepq)fieldsinletpresent=List.filter(fun(_,f)->matchBtype.row_field_reprfwith|Rpresent_->true|_->false)sorted_fieldsinletall_present=List.lengthpresent=List.lengthsorted_fieldsinmatchrow.row_namewith|Some(p,params)whennamable_rowrow->letp=Env.Path.read_typeenvpinletparams=List.map(read_type_exprenv)paramsinifrow.row_closed&&all_presentthenConstr(p,params)elseletkind=ifall_presentthenOpenelseClosed(List.mapfstpresent)inPolymorphic_variant{kind;elements=[Type(Constr(p,params))]}|_->letelements=List.map(fun(name,f)->matchBtype.row_field_reprfwith|RpresentNone->Constructor{name;constant=true;arguments=[];doc=[]}|Rpresent(Sometyp)->Constructor{name;constant=false;arguments=[read_type_exprenvtyp];doc=[];}|Reither(constant,typs,_,_)->letarguments=List.map(read_type_exprenv)typsinConstructor{name;constant;arguments;doc=[]}|Rabsent->assertfalse)sorted_fieldsinletkind=ifall_presentthenifrow.row_closedthenFixedelseOpenelseClosed(List.mapfstpresent)inPolymorphic_variant{kind;elements}andread_objectenvfinm=letopenTypeExprinletopenTypeExpr.Objectinmatchnmwith|None->let(fields,rest)=Ctype.flatten_fieldsfiinletpresent_fields=List.fold_right(fun(n,k,t)l->matchBtype.field_kind_reprkwith|Fpresent->(n,t)::l|_->l)fields[]inletsorted_fields=List.sort(fun(n,_)(n',_)->comparenn')present_fieldsinletmethods=List.map(fun(name,typ)->Method{name;type_=read_type_exprenvtyp})sorted_fieldsinletopen_=matchrest.descwith|Tvar_|Tunivar_->true|Tconstr_->true|Tnil->false|_->assertfalseinObject{fields=methods;open_}|Some(p,_::params)->letp=Env.Path.read_class_typeenvpinletparams=List.map(read_type_exprenv)paramsinClass(p,params)|_->assertfalseletread_value_descriptionenvparentidvd=letopenSignatureinletname=parenthesise(Ident.nameid)inletid=`Value(parent,Odoc_model.Names.ValueName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainervd.val_attributesinmark_value_descriptionvd;lettype_=read_type_exprenvvd.val_typeinmatchvd.val_kindwith|Val_reg->Value{Value.id;doc;type_}|Val_primdesc->letprimitives=letopenPrimitiveindesc.prim_name::(matchdesc.prim_native_namewith|""->[]|name->[name])inExternal{External.id;doc;type_;primitives}|_->assertfalseletread_label_declarationenvparentld=letopenTypeDecl.Fieldinletname=parenthesise(Ident.nameld.ld_id)inletid=`Field(parent,Odoc_model.Names.FieldName.of_stringname)inletdoc=Doc_attr.attached(parent:>Identifier.LabelParent.t)ld.ld_attributesinletmutable_=(ld.ld_mutable=Mutable)inlettype_=read_type_exprenvld.ld_typein{id;doc;mutable_;type_}letread_constructor_declaration_argumentsenvparentarg=#ifOCAML_MAJOR=4&&OCAML_MINOR=02(* NOTE(@ostera): constructor with inlined records were introduced post 4.02
so it's safe to use Tuple here *)ignoreparent;TypeDecl.Constructor.Tuple(List.map(read_type_exprenv)arg)#elseletopenTypeDecl.Constructorinmatchargwith|Cstr_tupleargs->Tuple(List.map(read_type_exprenv)args)|Cstr_recordlds->Record(List.map(read_label_declarationenvparent)lds)#endifletread_constructor_declarationenvparentcd=letopenTypeDecl.Constructorinletname=parenthesise(Ident.namecd.cd_id)inletid=`Constructor(parent,Odoc_model.Names.ConstructorName.of_stringname)inletcontainer=(parent:Identifier.DataType.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainercd.cd_attributesinletargs=read_constructor_declaration_argumentsenv(parent:>Identifier.Parent.t)cd.cd_argsinletres=opt_map(read_type_exprenv)cd.cd_resin{id;doc;args;res}letread_type_kindenvparent=letopenTypeDecl.Representationinfunction|Type_abstract->None#ifOCAML_VERSION>=(4,13,0)|Type_variant(cstrs,_)->#else|Type_variantcstrs->#endifletcstrs=List.map(read_constructor_declarationenvparent)cstrsinSome(Variantcstrs)|Type_record(lbls,_)->letlbls=List.map(read_label_declarationenv(parent:>Identifier.Parent.t))lblsinSome(Recordlbls)|Type_open->SomeExtensibleletread_type_parameterabstrvarparam=letopenTypeDeclinletname=name_of_typeparaminletdesc=ifname="_"thenAnyelseVarnameinletvariance=ifnot(abstr||aliasableparam)thenNoneelsebeginletco,cn=Variance.get_uppervarinifnotcnthenSomePoselseifnotcothenSomeNegelseNoneendinletinjectivity=let_,_,_,inj=Variance.get_lowervarininjin{desc;variance;injectivity}letread_type_constraintsenvparams=List.fold_right(funtyp1acc->lettyp2=Ctype.unaliastyp1inifBtype.proxytyp1!=Btype.proxytyp2thenlettyp1=read_type_exprenvtyp1inlettyp2=read_type_exprenvtyp2in(typ1,typ2)::accelseacc)params[]letread_type_declarationenvparentiddecl=letopenTypeDeclinletname=parenthesise(Ident.nameid)inletid=`Type(parent,Odoc_model.Names.TypeName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainerdecl.type_attributesinletparams=mark_type_declarationdeclinletmanifest=opt_map(read_type_exprenv)decl.type_manifestinletconstraints=read_type_constraintsenvparamsinletrepresentation=read_type_kindenviddecl.type_kindinletabstr=matchdecl.type_kindwithType_abstract->decl.type_manifest=None||decl.type_private=Private|Type_record_->decl.type_private=Private#ifOCAML_VERSION>=(4,13,0)|Type_variant(tll,_)->#else|Type_varianttll->#endifdecl.type_private=Private||List.exists(funcd->cd.cd_res<>None)tll|Type_open->decl.type_manifest=Noneinletparams=List.map2(read_type_parameterabstr)decl.type_varianceparamsinletprivate_=(decl.type_private=Private)inletequation=Equation.{params;manifest;constraints;private_}in{id;doc;equation;representation}letread_extension_constructorenvparentidext=letopenExtension.Constructorinletname=parenthesise(Ident.nameid)inletid=`Extension(parent,Odoc_model.Names.ExtensionName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainerext.ext_attributesinletargs=read_constructor_declaration_argumentsenv(parent:Identifier.Signature.t:>Identifier.Parent.t)ext.ext_argsinletres=opt_map(read_type_exprenv)ext.ext_ret_typein{id;doc;args;res}letread_type_extensionenvparentidextrest=letopenExtensioninlettype_path=Env.Path.read_typeenvext.ext_type_pathinletdoc=Doc_attr.emptyinlettype_params=mark_type_extension'extrestinletfirst=read_extension_constructorenvparentidextinletrest=List.map(fun(id,ext)->read_extension_constructorenvparentidext)restinletconstructors=first::restinlettype_params=List.map(read_type_parameterfalseVariance.null)type_paramsinletprivate_=(ext.ext_private=Private)in{type_path;type_params;doc;private_;constructors;}letread_exceptionenvparentidext=letopenExceptioninletname=parenthesise(Ident.nameid)inletid=`Exception(parent,Odoc_model.Names.ExceptionName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainerext.ext_attributesinmark_exceptionext;letargs=read_constructor_declaration_argumentsenv(parent:Identifier.Signature.t:>Identifier.Parent.t)ext.ext_argsinletres=opt_map(read_type_exprenv)ext.ext_ret_typein{id;doc;args;res}letread_methodenvparentconcrete(name,kind,typ)=letopenMethodinletname=parenthesisenameinletid=`Method(parent,Odoc_model.Names.MethodName.of_stringname)inletdoc=Doc_attr.emptyinletprivate_=(Btype.field_kind_reprkind)<>Fpresentinletvirtual_=not(Concr.memnameconcrete)inlettype_=read_type_exprenvtypinClassSignature.Method{id;doc;private_;virtual_;type_}letread_instance_variableenvparent(name,mutable_,virtual_,typ)=letopenInstanceVariableinletname=parenthesisenameinletid=`InstanceVariable(parent,Odoc_model.Names.InstanceVariableName.of_stringname)inletdoc=Doc_attr.emptyinletmutable_=(mutable_=Mutable)inletvirtual_=(virtual_=Virtual)inlettype_=read_type_exprenvtypinClassSignature.InstanceVariable{id;doc;mutable_;virtual_;type_}letread_self_typesty=letsty=Btype.reprstyinifnot(is_aliasedsty)thenNoneelseSome(TypeExpr.Var(name_of_type(Btype.proxysty)))letrecread_class_signatureenvparentparams=letopenClassTypeinfunction|Cty_constr(p,_,cty)->ifis_row_visited(Btype.proxy(Ctype.self_typecty))||List.existsaliasableparamsthenread_class_signatureenvparentparamsctyelsebeginletp=Env.Path.read_class_typeenvpinletparams=List.map(read_type_exprenv)paramsinConstr(p,params)end|Cty_signaturecsig->letopenClassSignatureinletself=read_self_typecsig.csig_selfinletconstraints=read_type_constraintsenvparamsinletconstraints=List.map(fun(typ1,typ2)->Constraint(typ1,typ2))constraintsinletinstance_variables=Vars.fold(funname(mutable_,virtual_,typ)acc->(name,mutable_,virtual_,typ)::acc)csig.csig_vars[]inletmethods,_=Ctype.flatten_fields(Ctype.object_fieldscsig.csig_self)inletmethods=List.filter(fun(name,_,_)->name<>Btype.dummy_method)methodsinletinstance_variables=List.map(read_instance_variableenvparent)instance_variablesinletmethods=List.map(read_methodenvparentcsig.csig_concr)methodsinletitems=constraints@instance_variables@methodsinSignature{self;items}|Cty_arrow_->assertfalseletrecread_virtual=function|Cty_constr(_,_,cty)|Cty_arrow(_,_,cty)->read_virtualcty|Cty_signaturecsig->letmethods,_=Ctype.flatten_fields(Ctype.object_fieldscsig.csig_self)inletvirtual_method=List.exists(fun(name,_,_)->not(name=Btype.dummy_method||Concr.memnamecsig.csig_concr))methodsinletvirtual_instance_variable=Vars.exists(fun_(_,virtual_,_)->virtual_=Virtual)csig.csig_varsinvirtual_method||virtual_instance_variableletread_class_type_declarationenvparentidcltd=letopenClassTypeinletname=parenthesise(Ident.nameid)inletid=`ClassType(parent,Odoc_model.Names.ClassTypeName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainercltd.clty_attributesinmark_class_type_declarationcltd;letparams=List.map2(read_type_parameterfalse)cltd.clty_variancecltd.clty_paramsinletexpr=read_class_signatureenvidcltd.clty_paramscltd.clty_typeinletvirtual_=read_virtualcltd.clty_typein{id;doc;virtual_;params;expr;expansion=None}letrecread_class_typeenvparentparams=letopenClassinfunction|Cty_constr_|Cty_signature_ascty->ClassType(read_class_signatureenvparentparamscty)|Cty_arrow(lbl,arg,cty)->letarg=ifBtype.is_optionallblthenmatch(Btype.reprarg).descwith|Tconstr(path,[arg],_)whenOCamlPath.samepathPredef.path_option->read_type_exprenvarg|_->assertfalseelseread_type_exprenvarginletlbl=read_labellblinletcty=read_class_typeenvparentparamsctyinArrow(lbl,arg,cty)letread_class_declarationenvparentidcld=letopenClassinletname=parenthesise(Ident.nameid)inletid=`Class(parent,Odoc_model.Names.ClassName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainercld.cty_attributesinmark_class_declarationcld;letparams=List.map2(read_type_parameterfalse)cld.cty_variancecld.cty_paramsinlettype_=read_class_typeenvidcld.cty_paramscld.cty_typeinletvirtual_=cld.cty_new=Nonein{id;doc;virtual_;params;type_;expansion=None}letrecread_module_typeenvparentpos(mty:Odoc_model.Compat.module_type)=letopenModuleTypeinmatchmtywith|Mty_identp->Path(Env.Path.read_module_typeenvp)|Mty_signaturesg->Signature(read_signatureenvparentsg)|Mty_functor(parameter,res)->letparameter,env=matchparameterwith|Unit->Odoc_model.Lang.FunctorParameter.Unit,env|Named(id_opt,arg)->letname,env=matchid_optwith|Someid->parenthesise(Ident.nameid),Env.add_argumentparentposid(ArgumentName.of_identid)env|None->"_",envinletid=`Argument(parent,pos,Odoc_model.Names.ArgumentName.of_stringname)inletarg=read_module_typeenvid1arginletexpansion=matchargwith|Signature_->SomeModule.AlreadyASig|_->NoneinOdoc_model.Lang.FunctorParameter.Named({FunctorParameter.id;expr=arg;expansion}),envinletres=read_module_typeenvparent(pos+1)resinFunctor(parameter,res)|Mty_alias_->assertfalseandread_module_type_declarationenvparentid(mtd:Odoc_model.Compat.modtype_declaration)=letopenModuleTypeinletname=parenthesise(Ident.nameid)inletid=`ModuleType(parent,Odoc_model.Names.ModuleTypeName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainermtd.mtd_attributesinletexpr=opt_map(read_module_typeenvid1)mtd.mtd_typeinletexpansion=matchexprwith|Some(Signature_)->SomeModule.AlreadyASig|_->Nonein{id;doc;expr;expansion}andread_module_declarationenvparentident(md:Odoc_model.Compat.module_declaration)=letopenModuleinletname=parenthesise(Ident.nameident)inletid=`Module(parent,Odoc_model.Names.ModuleName.of_stringname)inletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attachedcontainermd.md_attributesinletcanonical=letdoc=List.mapOdoc_model.Location_.valuedocinmatchList.find(function`Tag(`Canonical_)->true|_->false)docwith|exceptionNot_found->None|`Tag(`Canonical(p,r))->Some(p,r)|_->Noneinlettype_=matchmd.md_typewith|Mty_aliasp->Alias(Env.Path.read_moduleenvp)|_->ModuleType(read_module_typeenvid1md.md_type)inlethidden=matchcanonicalwith|Some_->false|None->Odoc_model.Root.contains_double_underscore(Ident.nameident)inletexpansion=matchtype_with|ModuleType(ModuleType.Signature_)->SomeAlreadyASig|_->Nonein{id;doc;type_;expansion;canonical;hidden;display_type=None}andread_type_rec_statusrec_status=letopenSignatureinmatchrec_statuswith|Trec_first->Ordinary|Trec_next->And|Trec_not->Nonrecandread_module_rec_statusrec_status=letopenSignatureinmatchrec_statuswith|Trec_not->Ordinary|Trec_first->Rec|Trec_next->Andandread_signatureenvparent(items:Odoc_model.Compat.signature)=letenv=Env.add_signature_type_itemsparentitemsenvinletrecloopaccitems=letopenSignatureinletopenOdoc_model.Compatinmatchitemswith|Sig_value(id,v,Exported)::rest->letvd=read_value_descriptionenvparentidvinloop(vd::acc)rest|Sig_type(id,_,_,Exported)::restwhenBtype.is_row_name(Ident.nameid)->loopaccrest|Sig_type(id,decl,rec_status,Exported)::rest->letdecl=read_type_declarationenvparentiddeclinloop(Type(read_type_rec_statusrec_status,decl)::acc)rest|Sig_typext(id,ext,Text_first,Exported)::rest->letrecinner_loopinner_acc=function|Sig_typext(id,ext,Text_next,_)::rest->inner_loop((id,ext)::inner_acc)rest|rest->letext=read_type_extensionenvparentidext(List.revinner_acc)inloop(TypExtext::acc)restininner_loop[]rest|Sig_typext(id,ext,Text_next,Exported)::rest->letext=read_type_extensionenvparentidext[]inloop(TypExtext::acc)rest|Sig_typext(id,ext,Text_exception,Exported)::rest->letexn=read_exceptionenvparentidextinloop(Exceptionexn::acc)rest|Sig_module(id,_,md,rec_status,Exported)::rest->letmd=read_module_declarationenvparentidmdinloop(Module(read_module_rec_statusrec_status,md)::acc)rest|Sig_modtype(id,mtd,Exported)::rest->letmtd=read_module_type_declarationenvparentidmtdinloop(ModuleTypemtd::acc)rest|Sig_class(id,cl,rec_status,Exported)::Sig_class_type_::Sig_type_::Sig_type_::rest->letcl=read_class_declarationenvparentidclinloop(Class(read_type_rec_statusrec_status,cl)::acc)rest|Sig_class_type(id,cltyp,rec_status,Exported)::Sig_type_::Sig_type_::rest->letcltyp=read_class_type_declarationenvparentidcltypinloop(ClassType(read_type_rec_statusrec_status,cltyp)::acc)rest(* Skip all of the hidden sig items *)|Sig_class_type(_,_,_,Hidden)::Sig_type_::Sig_type_::rest|Sig_class(_,_,_,Hidden)::Sig_class_type_::Sig_type_::Sig_type_::rest|Sig_modtype(_,_,Hidden)::rest|Sig_module(_,_,_,_,Hidden)::rest|Sig_typext(_,_,Text_exception,Hidden)::rest|Sig_typext(_,_,_,Hidden)::rest|Sig_type(_,_,_,Hidden)::rest|Sig_value(_,_,Hidden)::rest->loopaccrest(* Bad - we expect Sig_class and Sig_class_type to be matched above
with subsequent Sig_type items *)|Sig_class_type_::_|Sig_class_::_->assertfalse|[]->List.revaccinloop[]itemsletread_interfacerootnameintf=letid=`Root(root,Odoc_model.Names.UnitName.of_stringname)inletdoc=Doc_attr.emptyinletitems=read_signatureEnv.emptyidintfin(id,doc,items)