123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068(*
* 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.
*)openOdoc_modelopenPathsopenOdoc_model.LangopenNamestypepartial_expansion=|SignatureofSignature.t|FunctorofFunctorParameter.t*Identifier.Signature.t*int*ModuleType.exprletsubst_signaturesub=function|None->None|Somesg->Some(Subst.signaturesubsg)letsubst_argsubarg=letopenFunctorParameterinmatchargwith|Unit->Unit|Named{id;expr;expansion}->letid'=Subst.identifier_modulesubidinletexpr'=Subst.module_type_exprsubexprinletexpansion'=Maps.option_map(Subst.module_expansionsub)expansioninNamed{id=id';expr=expr';expansion=expansion'}letsubst_expansionsub=function|None->None|Some(Signaturesg)->letsg'=Subst.signaturesubsginSome(Signaturesg')|Some(Functor(arg,id,offset,expr))->letarg'=subst_argsubarginletid',offset'=Subst.offset_identifier_signaturesub(id,offset)inletexpr'=Subst.module_type_exprsubexprinSome(Functor(arg',id',offset',expr'))letsubst_class_expansionsub=function|None->None|Somesg->Some(Subst.class_signaturesubsg)letmap_modulenameexf=letrecloopnameitemsfacc=letopenSignatureinletopenModuleinmatchitemswith|[]->List.revacc(* raise Not_found *)|Module(recursive,md)::restwhenIdentifier.namemd.id=name->letmd'=fmdinList.rev_appendacc((Module(recursive,md'))::rest)|item::rest->loopnamerestf(item::acc)inmatchexwith|None->raiseNot_found|Some(Signatureitems)->Some(Signature(loopnameitemsf[]))|Some(Functor_)->raiseNot_foundletmap_typenameexf=letrecloopnameitemsfacc=letopenSignatureinletopenTypeDeclinmatchitemswith|[]->List.revacc(* raise Not_found *)|Type(recursive,decl)::restwhenIdentifier.namedecl.id=name->letdecl'=fdeclinList.rev_appendacc((Type(recursive,decl'))::rest)|item::rest->loopnamerestf(item::acc)inmatchexwith|None->raiseNot_found|Some(Signatureitems)->Some(Signature(loopnameitemsf[]))|Some(Functor_)->raiseNot_foundletadd_module_withsubstmd=letopenModuleinletopenModuleTypeinlettype_=matchmd.type_with|Alias_asdecl->ModuleType(With(TypeOfdecl,[subst]))|ModuleType(With(expr,substs))->ModuleType(With(expr,substs@[subst]))|ModuleTypeexpr->ModuleType(With(expr,[subst]))in{mdwithtype_;expansion=None}letrefine_typeex(frag:Fragment.Type.t)equation=letopenFragmentinmatchfragwith|`Dot_->None|`Resolvedfrag->letopenResolvedinletname,rest=Type.splitfraginmatchrestwith|None->begintrymap_typenameex(fundecl->TypeDecl.{declwithequation})withNot_found->None(* TODO should be an error *)end|Somefrag->beginletsubst=ModuleType.TypeEq(`Resolvedfrag,equation)intrymap_modulenameex(add_module_withsubst)withNot_found->None(* TODO should be an error *)endletrefine_moduleex(frag:Fragment.Module.t)equation=letopenFragmentinmatchfragwith|`Dot_->None|`Resolvedfrag->letopenResolvedinletname,rest=Module.splitfraginmatchrestwith|None->begintrymap_modulenameex(funmd->{mdwithtype_=equation;expansion=None})(* TODO Fix this to not produce an alias (needs strengthening)
or fix OCaml to do the correct thing. *)withNot_found->None(* TODO should be an error *)end|Somefrag->beginletsubst=ModuleType.ModuleEq(`Resolvedfrag,equation)intrymap_modulenameex(add_module_withsubst)withNot_found->None(* TODO should be an error *)endtypeintermediate_module_expansion=Identifier.Module.t*Odoc_model.Comment.docs*(Path.Module.t*Reference.Module.t)option*partial_expansionoption*Subst.tlisttypeintermediate_module_type_expansion=Identifier.ModuleType.t*Odoc_model.Comment.docs*partial_expansionoption*Subst.tlisttypeintermediate_class_type_expansion=Identifier.ClassType.t*Odoc_model.Comment.docs*ClassSignature.toption*Subst.tlisttypeexpander={equal:Root.t->Root.t->bool;hash:Root.t->int;expand_root:root:Root.t->Root.t->intermediate_module_expansion;expand_forward_ref:root:Root.t->string->intermediate_module_expansion;expand_module_identifier:root:Root.t->Identifier.Module.t->intermediate_module_expansion;expand_module_type_identifier:root:Root.t->Identifier.ModuleType.t->intermediate_module_type_expansion;expand_class_signature_identifier:root:Root.t->Identifier.ClassSignature.t->intermediate_class_type_expansion;expand_signature_identifier:root:Root.t->Identifier.Signature.t->partial_expansionoption;expand_module_resolved_path:root:Root.t->Path.Resolved.Module.t->intermediate_module_expansion;expand_module_path:root:Root.t->Path.Module.t->intermediate_module_expansion;expand_module_type_resolved_path:root:Root.t->Path.Resolved.ModuleType.t->intermediate_module_type_expansion;expand_class_type_path:root:Root.t->Path.ClassType.t->intermediate_class_type_expansion;expand_class_type_resolved_path:root:Root.t->Path.Resolved.ClassType.t->intermediate_class_type_expansion;fetch_unit_from_ref:Reference.Module.t->Compilation_unit.toption;}letadd_doc_to_class_expansion_optdoc=letopenClassSignatureinfunction|Some({items;_}assg)->letdoc=Comment(`Docsdoc)inSome{sgwithitems=doc::items}|otherwise->otherwiseletadd_doc_to_expansion_optdoc=function|Some(Signaturesg)->letdoc=Signature.Comment(`Docsdoc)inSome(Signature(doc::sg))|otherwise->otherwiseletrecexpand_class_decltrootdestdecl=letopenClassinmatchdeclwith|Arrow(_,_,decl)->expand_class_decltrootdestdecl|ClassTypeexpr->expand_class_type_exprtrootdestexprandexpand_class_type_expr({equal;_}ast)rootdestexpr=letopenClassTypeinmatchexprwith|Constr(`Resolvedp,_)->beginmatcht.expand_class_type_resolved_path~rootpwith|src,doc,ex,subs->letex=add_doc_to_class_expansion_optdocexinletex=List.fold_left(funaccsub->subst_class_expansionsubacc)exsubsinletsrc=(src:Identifier.ClassType.t:>Identifier.ClassSignature.t)inletsub=Subst.rename_class_signature~equalsrcdestinsubst_class_expansionsubex|exceptionNot_found->Noneend|Constr(p,_)->beginmatcht.expand_class_type_path~rootpwith|src,doc,ex,subs->letex=add_doc_to_class_expansion_optdocexinletex=List.fold_left(funaccsub->subst_class_expansionsubacc)exsubsinletsrc=(src:Identifier.ClassType.t:>Identifier.ClassSignature.t)inletsub=Subst.rename_class_signature~equalsrcdestinsubst_class_expansionsubex|exceptionNot_found->Noneend|Signaturecsig->Somecsigletrecexpand_module_decl({equal;_}ast)rootdestoffsetdecl=letopenModuleinmatchdeclwith|Alias(`Resolvedp)->begin(* TODO Should have strengthening *)matcht.expand_module_resolved_path~rootpwith|src,doc,_,ex,subs->letex=add_doc_to_expansion_optdocexinletex=List.fold_left(funaccsub->subst_expansionsubacc)exsubsinletsrc=(src:Identifier.Module.t:>Identifier.Signature.t)inletsub1=Subst.rename_signature~equalsrcdestoffsetinletex=subst_expansionsub1exinletsub2=Subst.strengthenpinsubst_expansionsub2ex|exceptionNot_found->None(* TODO: Should be an error *)end|Aliasp->beginmatcht.expand_module_path~rootpwith|src,doc,_,ex,subs->letex=add_doc_to_expansion_optdocexinletex=List.fold_left(funaccsub->subst_expansionsubacc)exsubsinletsrc=(src:Identifier.Module.t:>Identifier.Signature.t)inletsub=Subst.rename_signature~equalsrcdestoffsetinsubst_expansionsubex|exceptionNot_found->None(* TODO: Should be an error *)end|ModuleTypeexpr->expand_module_type_exprtrootdestoffsetexprandexpand_module_type_expr({equal;_}ast)rootdestoffsetexpr=letopenModuleTypeinmatchexprwith|Path(`Resolvedp)->beginmatcht.expand_module_type_resolved_path~rootpwith|src,_,ex,subs->letex=List.fold_left(funaccsub->subst_expansionsubacc)exsubsinletsrc=(src:Identifier.ModuleType.t:>Identifier.Signature.t)inletsub=Subst.rename_signature~equalsrcdestoffsetinsubst_expansionsubex|exceptionNot_found->None(* TODO: Should be an error *)end|Path_->None|Signaturesg->Some(Signaturesg)|Functor(arg,expr)->Some(Functor(arg,dest,(offset+1),expr))|With(expr,substs)->letex=expand_module_type_exprtrootdestoffsetexprinList.fold_left(funexsubst->matchsubstwith|TypeEq(frag,eq)->refine_typeexfrageq|ModuleEq(frag,eq)->refine_moduleexfrageq|TypeSubst_->ex(* TODO perform substitution *)|ModuleSubst_->ex(* TODO perform substitution *))exsubsts|TypeOfdecl->expand_module_decltrootdestoffsetdecl(* TODO perform weakening *)letexpand_moduletrootmd=letopenModuleinletid=(md.id:Identifier.Module.t:>Identifier.Signature.t)inexpand_module_decltrootid0md.type_letexpand_classtrootc=letopenClassinletid=(c.id:Identifier.Class.t:>Identifier.ClassSignature.t)inexpand_class_decltrootidc.type_letexpand_class_typetrootc=letopenClassTypeinletid=(c.id:Identifier.ClassType.t:>Identifier.ClassSignature.t)inexpand_class_type_exprtrootidc.exprletexpand_module_typetrootmty=letopenModuleTypeinmatchmty.exprwith|Someexpr->letid=(mty.id:Identifier.ModuleType.t:>Identifier.Signature.t)inexpand_module_type_exprtrootid0expr|None->Some(Signature[])typeinclude_expansion_result=|FailedofSignature.t|ExpandedofSignature.t|To_functorletexpand_includetrootincl=letopenIncludeinifincl.expansion.resolvedthenExpandedincl.expansion.contentelsebeginmatchexpand_module_decltrootincl.parent0incl.declwith|None->Failedincl.expansion.content|Some(Signaturesg)->Expandedsg|Some(Functor_)->To_functor(* TODO: Should be an error *)endletexpand_argument_troot{FunctorParameter.id;expr;expansion}=matchexpansionwith|None->letid=(id:Identifier.Module.t:>Identifier.Signature.t)inexpand_module_type_exprtrootid0expr|SomeModule.AlreadyASig->beginmatchexprwith|ModuleType.Signaturesg->Some(Signaturesg)|_->assertfalseend|Some(Module.Signaturesg)->Some(Signaturesg)|Some(Module.Functor_)->(* TODO: This is for cases where the module argument is itself a functor.
It *should* be handled, but latter. *)Noneletfind_moduletrootnameex=letrecinner_loopnameitems=letopenSignatureinletopenModuleinmatchitemswith|[]->raiseNot_found|Module(_,md)::_whenIdentifier.namemd.id=name->md|Includeincl::rest->beginmatchexpand_includetrootinclwith|To_functor->inner_loopnamerest|Failedsg|Expandedsg->inner_loopname(sg@rest)end|_::rest->inner_loopnamerestinletreclooptrootnameex=matchexwith|None->raiseNot_found|Some(Signatureitems)->inner_loopnameitems|Some(Functor(_,dest,offset,expr))->looptrootname(expand_module_type_exprtrootdestoffsetexpr)inlooptrootnameexletfind_class_typetrootnameex=letrecinner_loopnameitems=letopenSignatureinletopenClassTypeinmatchitemswith|[]->raiseNot_found|ClassType(_,cd)::_whenIdentifier.namecd.id=name->cd|Includeincl::rest->beginmatchexpand_includetrootinclwith|To_functor->inner_loopnamerest|Failedsg|Expandedsg->inner_loopname(sg@rest)end|_::rest->inner_loopnamerestinletreclooptrootnameex=matchexwith|None->raiseNot_found|Some(Signatureitems)->inner_loopnameitems|Some(Functor(_,dest,offset,expr))->looptrootname(expand_module_type_exprtrootdestoffsetexpr)inlooptrootnameexletfind_argumenttrootposex=letreclooptrootposex=matchexwith|None->raiseNot_found|Some(Signature_)->raiseNot_found|Some(Functor(Unit,_,_,_))whenpos=1->raiseNot_found|Some(Functor(Namedarg,_,_,_))whenpos=1->arg|Some(Functor(_,dest,offset,expr))->looptroot(pos-1)(expand_module_type_exprtrootdestoffsetexpr)inlooptrootposexletfind_module_typetrootnameex=letrecinner_loopnameitems=letopenSignatureinletopenModuleTypeinmatchitemswith|[]->raiseNot_found|ModuleTypemty::_whenIdentifier.namemty.id=name->mty|Includeincl::rest->beginmatchexpand_includetrootinclwith|To_functor->inner_loopnamerest|Failedsg|Expandedsg->inner_loopname(sg@rest)end|_::rest->inner_loopnamerestinletreclooptrootnameex=matchexwith|None->raiseNot_found|Some(Signatureitems)->inner_loopnameitems|Some(Functor(_,dest,offset,expr))->looptrootname(expand_module_type_exprtrootdestoffsetexpr)inlooptrootnameexletexpand_signature_identifier'troot(id:Identifier.Signature.t)=matchidwith|`Root(root',_name)->let_,_,_,ex,subs=t.expand_root~rootroot'inletex=List.fold_left(funaccsub->subst_expansionsubacc)exsubsinex|`Module(parent,name)->letex=t.expand_signature_identifier~rootparentinletmd=find_moduletroot(ModuleName.to_string_unsafename)exinexpand_moduletrootmd|`Argument(parent,pos,_name)->letex=t.expand_signature_identifier~rootparentinletarg=find_argumenttrootposexinexpand_argument_trootarg|`ModuleType(parent,name)->letex=t.expand_signature_identifier~rootparentinletmty=find_module_typetroot(ModuleTypeName.to_stringname)exinexpand_module_typetrootmtyandexpand_module_identifier'troot(id:Identifier.Module.t)=matchidwith|`Root(root',_name)->t.expand_root~rootroot'|`Module(parent,name)->letopenModuleinletex=t.expand_signature_identifier~rootparentinletmd=find_moduletroot(ModuleName.to_string_unsafename)exinmd.id,md.doc,md.canonical,expand_moduletrootmd,[]|`Argument(parent,pos,_name)->letex=t.expand_signature_identifier~rootparentinlet{FunctorParameter.id;_}asarg=find_argumenttrootposexinletdoc=[]inid,doc,None,expand_argument_trootarg,[]andexpand_module_type_identifier'troot(id:Identifier.ModuleType.t)=matchidwith|`ModuleType(parent,name)->letopenModuleTypeinletex=t.expand_signature_identifier~rootparentinletmty=find_module_typetroot(ModuleTypeName.to_stringname)exinmty.id,mty.doc,expand_module_typetrootmty,[]andexpand_class_signature_identifier'troot(id:Identifier.ClassSignature.t)=matchidwith|`Class(parent,name)->letex=t.expand_signature_identifier~rootparentinletct=find_class_typetroot(ClassName.to_stringname)exinct.id,ct.doc,expand_class_typetrootct,[]|`ClassType(parent,name)->letex=t.expand_signature_identifier~rootparentinletct=find_class_typetroot(ClassTypeName.to_stringname)exinct.id,ct.doc,expand_class_typetrootct,[]andexpand_module_resolved_path'({equal=eq;_}ast)root(p:Path.Resolved.Module.t)=matchpwith|`Identifierid->t.expand_module_identifier~rootid|`Subst(_,p)->t.expand_module_resolved_path~rootp|`SubstAlias(_,p)->t.expand_module_resolved_path~rootp|`Hiddenp->t.expand_module_resolved_path~rootp|`Module(parent,name)->letopenModuleinletid,_,canonical,ex,subs=t.expand_module_resolved_path~rootparentinletmd=find_moduletroot(ModuleName.to_stringname)exinletsub=Subst.prefix~equal:eq~canonicalidinmd.id,md.doc,md.canonical,expand_moduletrootmd,sub::subs|`Canonical(p,_)->t.expand_module_resolved_path~rootp|`Apply_->raiseNot_found(* TODO support functor application *)andexpand_module_path'({equal=eq;_}ast)root(p:Path.Module.t)=matchpwith|`Forwards->t.expand_forward_ref~roots|`Dot(parent,name)->letopenModuleinletid,_,canonical,ex,subs=t.expand_module_path~rootparentinletmd=find_moduletrootnameexinletsub=Subst.prefix~equal:eq~canonicalidinmd.id,md.doc,md.canonical,expand_moduletrootmd,sub::subs|`Root_|`Apply_|`Resolved_->raiseNot_found(* TODO: assert false? *)andexpand_class_type_path'({equal=eq;_}ast)root(p:Path.ClassType.t)=matchpwith|`Resolved_->raiseNot_found(* TODO: assert false? *)|`Dot(parent,name)->letopenClassTypeinletid,_,canonical,ex,subs=t.expand_module_path~rootparentinletc=find_class_typetrootnameexinletsub=Subst.prefix~equal:eq~canonicalidinc.id,c.doc,expand_class_typetrootc,sub::subsandexpand_class_type_resolved_path'({equal=eq;_}ast)root(p:Path.Resolved.ClassType.t)=matchpwith|`Identifierid->t.expand_class_signature_identifier~rootid|`Class(parent,name)->letopenClassTypeinletid,_,canonical,ex,subs=t.expand_module_resolved_path~rootparentinletc=find_class_typetroot(ClassName.to_stringname)exinletsub=Subst.prefix~equal:eq~canonicalidinc.id,c.doc,expand_class_typetrootc,sub::subs|`ClassType(parent,name)->letopenClassTypeinletid,_,canonical,ex,subs=t.expand_module_resolved_path~rootparentinletc=find_class_typetroot(ClassTypeName.to_stringname)exinletsub=Subst.prefix~equal:eq~canonicalidinc.id,c.doc,expand_class_typetrootc,sub::subsandexpand_module_type_resolved_path'({equal=eq;_}ast)root(p:Path.Resolved.ModuleType.t)=matchpwith|`Identifierid->t.expand_module_type_identifier~rootid|`ModuleType(parent,name)->letopenModuleTypeinletid,_,canonical,ex,subs=t.expand_module_resolved_path~rootparentinletmty=find_module_typetroot(ModuleTypeName.to_stringname)exinletsub=Subst.prefix~equal:eq~canonicalidinmty.id,mty.doc,expand_module_typetrootmty,sub::subsandexpand_unit({equal;hash;_}ast)rootunit=letopenCompilation_unitinmatchunit.expansionwith|Someex->Someex|None->matchunit.contentwith|Packitems->letopenPackedinletrecloopidsmds=function|[]->letopenSignatureinletsg=List.rev_map(funmd->Module(Ordinary,md))mdsinids,Somesg|item::rest->matchitem.pathwith|`Resolvedp->beginmatcht.expand_module_resolved_path~rootpwith|src,doc,_,ex,subs->beginmatchexwith|None->[],None|Some(Functor_)->[],None(* TODO should be an error *)|Some(Signaturesg)->letsg=List.fold_left(funaccsub->Subst.signaturesubacc)sgsubsinletdoc=List.fold_left(funaccsub->Subst.documentationsubacc)docsubsinletopenModuleinletid=item.idinlettype_=ModuleType(ModuleType.Signaturesg)inletcanonical=Noneinletmd={id;doc;type_;canonical;expansion=Some(Signaturesg);display_type=None;hidden=false}inloop((src,item.id)::ids)(md::mds)restend|exceptionNot_found->[],None(* TODO: Should be an error *)end|_->[],Noneinletids,sg=loop[][]itemsinletsub=Subst.pack~equal~hashidsinsubst_signaturesubsg|Modulesg->Somesgletcreate?equal?hash(lookup:string->Component_table.lookup_unit_result)(fetch:root:Root.t->Root.t->Compilation_unit.t)=letequal=matchequalwith|None->(=)|Someeq->eqinlethash=matchhashwith|None->Hashtbl.hash|Someh->hinletmoduleRootHash=structtypet=Root.t*Root.tletequal(a1,b1)(a2,b2)=equala1a2&&equalb1b2lethash(a,b)=Hashtbl.hash(hasha,hashb)endinletmoduleRootTbl=Hashtbl.Make(RootHash)inletexpand_root_tbl=RootTbl.create13inletmoduleIdentifierHash=structtypet=Root.t*Identifier.tletequal(root1,id1)(root2,id2)=equalroot1root2&&Identifier.equalid1id2lethash(root,id)=Hashtbl.hash(hashroot,Identifier.hashid)endinletmoduleIdentifierTbl=Hashtbl.Make(IdentifierHash)inletexpand_module_identifier_tbl=IdentifierTbl.create13inletexpand_module_type_identifier_tbl=IdentifierTbl.create13inletexpand_signature_identifier_tbl=IdentifierTbl.create13inletexpand_class_signature_identifier_tbl=IdentifierTbl.create13inletmoduleRPathHash=structtypet=Root.t*Path.Resolved.tletequal(root1,p1)(root2,p2)=equalroot1root2&&Path.Resolved.equalp1p2lethash(root,_p)=Hashtbl.hash(hashroot,Path.Resolved.hash)endinletmoduleRPathTbl=Hashtbl.Make(RPathHash)inletmodulePathHash=structtypet=Root.t*Path.tletequal(root1,p1)(root2,p2)=equalroot1root2&&Path.equalp1p2lethash(root,_p)=Hashtbl.hash(hashroot,Path.hash)endinletmodulePathTbl=Hashtbl.Make(PathHash)inletexpand_module_resolved_path_tbl=RPathTbl.create13inletexpand_module_path_tbl=PathTbl.create13inletexpand_module_type_resolved_path_tbl=RPathTbl.create13inletexpand_class_type_path_tbl=PathTbl.create13inletexpand_class_type_resolved_path_tbl=RPathTbl.create13inletrecexpand_root~rootroot'=letkey=(root,root')intryRootTbl.findexpand_root_tblkeywithNot_found->letopenCompilation_unitinletunit=fetch~rootroot'inletsg=expand_unittrootunitinletex=matchsgwith|None->None|Somesg->Some(Signaturesg)inletres=(unit.id,unit.doc,None,ex,[])inRootTbl.addexpand_root_tblkeyres;resandfetch_unit_from_refref=(* FIXME: this function is not really necessary is it? *)matchrefwith|`Resolved(`Identifier(`Root(_,unit_name)))->beginmatchlookup(UnitName.to_stringunit_name)with|Component_table.Found{root;_}->letunit=fetch~rootrootinSomeunit|_->Noneend|_->Noneandexpand_forward_ref~rootstr=matchlookupstrwith|Component_table.Found{root=a;_}->expand_root~roota|_->raiseNot_foundandexpand_module_identifier~root(id:Identifier.Module.t)=letkey=(root,(id:>Identifier.t))intryIdentifierTbl.findexpand_module_identifier_tblkeywithNot_found->letres=expand_module_identifier'trootidinIdentifierTbl.addexpand_module_identifier_tblkeyres;resandexpand_module_type_identifier~root(id:Identifier.ModuleType.t)=letkey=(root,(id:>Identifier.t))intryIdentifierTbl.findexpand_module_type_identifier_tblkeywithNot_found->letres=expand_module_type_identifier'trootidinIdentifierTbl.addexpand_module_type_identifier_tblkeyres;resandexpand_signature_identifier~root(id:Identifier.Signature.t)=letkey=(root,(id:>Identifier.t))intryIdentifierTbl.findexpand_signature_identifier_tblkeywithNot_found->letres=expand_signature_identifier'trootidinIdentifierTbl.addexpand_signature_identifier_tblkeyres;resandexpand_class_signature_identifier~root(id:Identifier.ClassSignature.t)=letkey=(root,(id:>Identifier.t))intryIdentifierTbl.findexpand_class_signature_identifier_tblkeywithNot_found->letres=expand_class_signature_identifier'trootidinIdentifierTbl.addexpand_class_signature_identifier_tblkeyres;resandexpand_module_resolved_path~root(p:Path.Resolved.Module.t)=letkey=(root,(p:>Path.Resolved.t))intryRPathTbl.findexpand_module_resolved_path_tblkeywithNot_found->letres=expand_module_resolved_path'trootpinRPathTbl.addexpand_module_resolved_path_tblkeyres;resandexpand_module_path~root(p:Path.Module.t)=letkey=(root,(p:>Path.t))intryPathTbl.findexpand_module_path_tblkeywithNot_found->letres=expand_module_path'trootpinPathTbl.addexpand_module_path_tblkeyres;resandexpand_module_type_resolved_path~root(p:Path.Resolved.ModuleType.t)=letkey=(root,(p:>Path.Resolved.t))intryRPathTbl.findexpand_module_type_resolved_path_tblkeywithNot_found->letres=expand_module_type_resolved_path'trootpinRPathTbl.addexpand_module_type_resolved_path_tblkeyres;resandexpand_class_type_path~root(p:Path.ClassType.t)=letkey=(root,(p:>Path.t))intryPathTbl.findexpand_class_type_path_tblkeywithNot_found->letres=expand_class_type_path'trootpinPathTbl.addexpand_class_type_path_tblkeyres;resandexpand_class_type_resolved_path~root(p:Path.Resolved.ClassType.t)=letkey=(root,(p:>Path.Resolved.t))intryRPathTbl.findexpand_class_type_resolved_path_tblkeywithNot_found->letres=expand_class_type_resolved_path'trootpinRPathTbl.addexpand_class_type_resolved_path_tblkeyres;resandt={equal;hash;expand_root;expand_forward_ref;expand_module_path;expand_module_identifier;expand_module_type_identifier;expand_signature_identifier;expand_class_signature_identifier;expand_module_resolved_path;expand_module_type_resolved_path;expand_class_type_path;expand_class_type_resolved_path;fetch_unit_from_ref;}intletrecforce_expansiontroot(ex:partial_expansionoption)=matchexwith|None->None|Some(Signaturesg)->Some(Module.Signaturesg)|Some(Functor(arg,dest,offset,expr))->letarg=expand_argumenttarginletex=expand_module_type_exprtrootdestoffsetexprinmatchforce_expansiontrootexwith|None->None|SomeModule.AlreadyASig->(* we are never returning it, so we cannot receive it. *)assertfalse|Some(Module.Signaturesg)->Some(Module.Functor([arg],sg))|Some(Module.Functor(args,sg))->Some(Module.Functor(arg::args,sg))andexpand_argumenttarg=matchargwith|Unit->arg|Named({FunctorParameter.id;expr;expansion}asa)->matchexpansionwith|Some_->arg|None->letroot=Identifier.Module.rootidinletexpansion=force_expansiontroot(expand_argument_troota)inNamed{FunctorParameter.id;expr;expansion}(** We will always expand modules which are not aliases. For aliases we only
expand when the thing they point to should be hidden. *)letshould_expand_t_iddecl=matchdeclwith|Module.Aliasp->Path.is_hidden(p:>Path.t)|_->trueletis_canonical_tagdoc=matchdocwith|[{Odoc_model.Location_.value=`Tag(`Canonical_);_}]->true|_->false(** For module aliases where the binding site doesn't have any doc comment
attached, then we fetch the doc for the thing it aliases. *)letexpand_mod_alias_docmd=letopenModuleinmatchmd.type_with|ModuleType_->md|Alias_->matchmd.docwith|(_::_)->md|_->matchmd.expansionwith|Some(Signature(Comment(`Docsc)::Comment(`Docsdoc)::expansion))whenis_canonical_tagc->{mdwithdoc;expansion=Some(Signatureexpansion)}|_->md(** Set display type for aliases to hidden things. *)letset_display_typemd=letopenModuleinmatchmd.display_typewith|Some_->md|None->matchmd.type_with|Aliasp->beginmatchpwith|`Resolved(`Hidden_)->letdisplay_type:Module.decloption=matchmd.expansionwith|SomeAlreadyASig->assertfalse(* [md.type_] is [Alias] *)|Some(Signaturesg)->Some(ModuleType(ModuleType.Signaturesg))|Some(Functor(args,sg))->letexpr=List.fold_right(funargacc->ModuleType.Functor(arg,acc))args(ModuleType.Signaturesg)inSome(ModuleTypeexpr)|None->Nonein{mdwithdisplay_type}|_->mdend|_->mdletexpand_moduletmd=letopenModuleinmatchmd.expansionwith|Some_->md|None->ifshould_expandtmd.idmd.type_thenletroot=Identifier.Module.rootmd.idinletexpansion=force_expansiontroot(expand_moduletrootmd)inset_display_type(expand_mod_alias_doc{mdwithexpansion})elsemdletexpand_module_typetmty=letopenModuleTypeinmatchmty.expansionwith|Some_->mty|None->letroot=Identifier.ModuleType.rootmty.idinletexpansion=force_expansiontroot(expand_module_typetrootmty)in{mtywithexpansion}letremove_docs_from_signature=(* Remove bare doc comments from a signature *)letopenSignatureinfunction|Comment(`Docs_)::xs->xs|xs->xsletexpand_includetincl=letopenIncludeinifincl.expansion.resolvedtheninclelsebeginletroot=Identifier.Signature.rootincl.parentinmatchexpand_includetrootinclwith|Expandedcontent'->letcontent=remove_docs_from_signaturecontent'inletexpansion={content;resolved=true}in{inclwithexpansion}|_->inclendletexpand_classtc=letopenClassinmatchc.expansionwith|Some_->c|None->letroot=Identifier.(ClassSignature.root@@(c.id:>ClassSignature.t))inletexpansion=expand_classtrootcin{cwithexpansion}letexpand_class_typetc=letopenClassTypeinmatchc.expansionwith|Some_->c|None->letroot=Identifier.(ClassSignature.root@@(c.id:>ClassSignature.t))inletexpansion=expand_class_typetrootcin{cwithexpansion}(*
let expand_unit t unit =
let open Unit in
match unit.expansion with
| Some _ -> unit
| None ->
let root = Identifier.module_root unit.id in
let expansion = expand_unit t root unit in
{ unit with expansion }
*)classt?equal?hashlookupfetch=objectvalt=create?equal?hashlookupfetchvalunit=NoneinheritMaps.typesassupermethodrootx=x(* Define virtual methods. *)methodidentifier_modulex=xmethodidentifier_module_typex=xmethodidentifier_typex=xmethodidentifier_constructorx=xmethodidentifier_fieldx=xmethodidentifier_extensionx=xmethodidentifier_exceptionx=xmethodidentifier_valuex=xmethodidentifier_classx=xmethodidentifier_class_typex=xmethodidentifier_methodx=xmethodidentifier_instance_variablex=xmethodidentifier_labelx=xmethodidentifier_pagex=xmethodidentifier_signaturex=xmethodidentifierx=xmethodpath_modulex=xmethodpath_module_typex=xmethodpath_typex=xmethodpath_class_typex=xmethodfragment_typex=xmethodfragment_modulex=xmethod!module_md=letmd'=expand_moduletmdinsuper#module_md'method!module_typemty=letmty'=expand_module_typetmtyinsuper#module_typemty'method!include_incl=letincl'=expand_includetinclinsuper#include_incl'method!module_type_functor_paramarg=letarg=expand_argumenttarginsuper#module_type_functor_paramargmethod!class_c=letc'=expand_classtcinsuper#class_c'method!class_typec=letc'=expand_class_typetcinsuper#class_typec'(* method! documentation_special_modules (rf, txt as pair) =
let rf' = self#reference_module rf in
let txt' =
match txt with
| _ :: _ -> txt
| [] ->
match t.fetch_unit_from_ref rf' with
| None -> txt
| Some u ->
let open Odoc_model.Comment in
match u.Compilation_unit.doc with
| Ok { text; _ } ->
begin match text with
| [] -> txt
| _ -> text
end
| _ -> txt
in
let txt' = self#documentation_text txt' in
if rf != rf' || txt != txt' then (rf', txt')
else pair *)(* CR trefis: TODO *)methodreference_modulex=xmethodreference_module_typex=xmethodreference_typex=xmethodreference_constructorx=xmethodreference_fieldx=xmethodreference_extensionx=xmethodreference_exceptionx=xmethodreference_valuex=xmethodreference_classx=xmethodreference_class_typex=xmethodreference_methodx=xmethodreference_instance_variablex=xmethodreference_labelx=xmethodreference_anyx=xmethodexpandunit=letthis={<unit=Someunit>}inthis#unitunitendletbuild_expander?equal?hashlookupfetch=newt?equal?hashlookupfetchletexpandeu=e#expandu