123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678(*
* 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.LangopenComponentsopenOdoc_model.Namestype('a,'b)tbl={fresh:int->('a,'b)tbl;find:'a->'b;add:'a->'b->unit;}letmake_tbl(typea)(equal:(a->a->bool)option)(hash:(a->int)option)size=letmakecreatefindadd=letrecfreshsize=lett=createsizeinletfindx=findtxinletaddxy=addtxyin{fresh;find;add}infreshsizeinmatchequal,hashwith|None,None->make(Hashtbl.create?random:None)Hashtbl.findHashtbl.add|_->letequal=matchequalwith|None->(=)|Someeq->eqinlethash=matchhashwith|None->Hashtbl.hash|Someh->hinletmoduleHash=structtypet=aletequal=equallethash=hashendinletmoduleTbl=Hashtbl.Make(Hash)inmakeTbl.createTbl.findTbl.addtypelookup_result_found={root:Odoc_model.Root.t;hidden:bool}typelookup_unit_result=|Forward_reference|Foundoflookup_result_found|Not_foundtypet={equal:(Root.t->Root.t->bool)option;hash:(Root.t->int)option;lookup_unit:string->lookup_unit_result;lookup_page:string->Root.toption;fetch_unit:Root.t->Compilation_unit.t;fetch_page:Root.t->Odoc_model.Lang.Page.t;tbl:(Root.t,Sig.t)tbl;page_tbl:(Root.t,Page.t)tbl;}letcreate?equal?hashlookup_unitfetch_unitlookup_pagefetch_page=lettbl=make_tblequalhash7inletpage_tbl=make_tblequalhash7in{equal;hash;lookup_unit;fetch_unit;lookup_page;fetch_page;tbl;page_tbl}typelocal={t:t;local:(Identifier.Signature.t,Sig.t)tbloption;base:Identifier.Signature.toption;}letcreate_localtbase=letequal=matcht.equalwith|None->None|Some_equal->SomeIdentifier.Signature.equalinlethash=matcht.hashwith|None->None|Some_hash->SomeIdentifier.Signature.hashinletlocal=matchbasewith|None->None|Some_->Some(make_tblequalhash23)in{t;local;base;}letadd_local_module_identifier(local:local)idsg=matchlocal.localwith|None->()|Sometbl->tbl.add(id:Identifier.Module.t:>Identifier.Signature.t)sgletadd_local_module_type_identifier(local:local)idsg=matchlocal.localwith|None->()|Sometbl->tbl.add(id:Identifier.ModuleType.t:>Identifier.Signature.t)sgletadd_local_modules(local:local)idmds=matchlocal.localwith|None->()|Sometbl->List.iter(fun(name,sg)->tbl.add(`Module(id,name))sg)mdsletadd_local_module_types(local:local)idmtys=matchlocal.localwith|None->()|Sometbl->List.iter(fun(name,sg)->tbl.add(`ModuleType(id,name))sg)mtysletequals_signature_eq(base:Identifier.Signature.t)(id:Identifier.t)=matchidwith|`Root_asid->Identifier.Signature.equalbaseid|`Module_asid->Identifier.Signature.equalbaseid|`Argument_asid->Identifier.Signature.equalbase(id:>Identifier.Signature.t)|`ModuleType_asid->Identifier.Signature.equalbase(id:>Identifier.Signature.t)|`Page_->false|`Type_->false|`CoreType_->false|`Constructor_->false|`Field_->false|`Extension_->false|`Exception_->false|`CoreException_->false|`Value_->false|`Class_->false|`ClassType_->false|`Method_->false|`InstanceVariable_->false|`Label_->falseletrecis_parent_local:_->_->Identifier.t->bool=funeqbaseid->matchidwith|`Root_->false|`Page_->false|`Module(parent,_)->is_localeqbase(parent:>Identifier.t)|`Argument(parent,_,_)->is_localeqbase(parent:>Identifier.t)|`ModuleType(parent,_)->is_localeqbase(parent:>Identifier.t)|`Type(parent,_)->is_localeqbase(parent:>Identifier.t)|`CoreType_->false|`Constructor(parent,_)->is_localeqbase(parent:>Identifier.t)|`Field(parent,_)->is_localeqbase(parent:>Identifier.t)|`Extension(parent,_)->is_localeqbase(parent:>Identifier.t)|`Exception(parent,_)->is_localeqbase(parent:>Identifier.t)|`CoreException_->false|`Value(parent,_)->is_localeqbase(parent:>Identifier.t)|`Class(parent,_)->is_localeqbase(parent:>Identifier.t)|`ClassType(parent,_)->is_localeqbase(parent:>Identifier.t)|`Method(parent,_)->is_localeqbase(parent:>Identifier.t)|`InstanceVariable(parent,_)->is_localeqbase(parent:>Identifier.t)|`Label(parent,_)->is_localeqbase(parent:>Identifier.t)andis_local:_->_->Identifier.t->bool=funeqbaseid->is_parent_localeqbaseid||equals_signatureeqbaseidletis_locallocalid=matchlocal.basewith|None->false|Somebase->leteq=matchlocal.t.equalwith|None->(=)|Someeq->eqinis_localeqbaseidletlocal_module_identifier(local:local)id=matchlocal.localwith|None->Sig.unresolved|Sometbl->trytbl.find(id:Identifier.Module.t:>Identifier.Signature.t)withNot_found->Sig.unresolvedletlocal_module_type_identifier(local:local)id=matchlocal.localwith|None->Sig.unresolved|Sometbl->trytbl.find(id:Identifier.ModuleType.t:>Identifier.Signature.t)withNot_found->Sig.unresolvedletdatatypedecl=letopenTypeDeclinletopenRepresentationinmatchdecl.representationwith|None->Datatype.abstract|Some(Variantconstructors)->letopenConstructorinletname=Identifier.namedecl.idinletdecl=Datatype.variantname(List.map(funcstr->Identifier.namecstr.id)constructors)inletdecl=List.fold_right(funcstrdecl->Datatype.add_documentationcstr.docdecl)constructorsdeclindecl|Some(Recordfields)->letopenFieldinletname=Identifier.namedecl.idinletdecl=Datatype.recordname(List.map(funfield->Identifier.namefield.id)fields)inletdecl=List.fold_right(funfielddecl->Datatype.add_documentationfield.docdecl)fieldsdeclindecl|SomeExtensible->Datatype.extensibleletcore_types=letopenTypeDeclinList.map(fundecl->(Identifier.namedecl.id,datatypedecl))Predefined.core_typesletpagetblbase=trytbl.page_tbl.findbasewithNot_found->letpage=tbl.fetch_pagebaseinlett=Page.of_docpage.Odoc_model.Lang.Page.contentintbl.page_tbl.addbaset;tletpage_identifiertbl:Identifier.Page.t->_=function|`Page(base,_)->pagetblbaseletrecunittblbase=trytbl.tbl.findbasewithNot_found->letopenCompilation_unitinletunt=tbl.fetch_unitbaseinletid=(unt.id:Identifier.Module.t:>Identifier.Signature.t)inletlocal=create_localtbl(Someid)inlett=matchunt.contentwith|Moduleitems->Sig.signature(funitems->Sig.add_documentationunt.doc(signature_itemslocalitems))items|Packitems->Sig.signature(funitems->Sig.add_documentationunt.doc(packed_itemslocalitems))itemsinlett=Sig.set_hiddentunt.hiddenintbl.tbl.addbaset;tandsignature_identifiertbl(i:Identifier.Signature.t)=matchiwith|`Root(base,_)->unittblbase|`Module(id,name)->letparent=signature_identifiertblidinSig.lookup_module(ModuleName.to_stringname)parent|`Argument(id,pos,_)->letparent=signature_identifiertblidinSig.lookup_argumentposparent|`ModuleType(id,name)->letparent=signature_identifiertblidinSig.lookup_module_type(ModuleTypeName.to_stringname)parentandmodule_identifiertbl(i:Identifier.Module.t)=matchiwith|`Root(base,_)->unittblbase|`Module(id,name)->letparent=signature_identifiertblidinSig.lookup_module(ModuleName.to_stringname)parent|`Argument(id,pos,_)->letparent=signature_identifiertblidinSig.lookup_argumentposparentandmodule_type_identifiertbl(i:Identifier.ModuleType.t)=matchiwith|`ModuleType(id,name)->letparent=signature_identifiertblidinSig.lookup_module_type(ModuleTypeName.to_stringname)parentanddatatype_identifiertbl(i:Identifier.DataType.t)=matchiwith|(`Type(id,name):Identifier.Type.t)->letparent=signature_identifiertblidinSig.lookup_datatype(TypeName.to_stringname)parent|`CoreTypename->List.assoc(TypeName.to_stringname)core_typesandclass_signature_identifiertbl(p:Identifier.ClassSignature.t)=matchpwith|`Class(id,name)->letparent=signature_identifiertblidinSig.lookup_class_type(ClassName.to_stringname)parent|`ClassType(id,name)->letparent=signature_identifiertblidinSig.lookup_class_type(ClassTypeName.to_stringname)parentandresolved_module_pathlocal(p:Path.Resolved.Module.t)=matchpwith|`Identifier(id:Identifier.Module.t)->ifis_locallocal(id:>Identifier.t)thenlocal_module_identifierlocalidelsemodule_identifierlocal.tid|`Subst(sub,_)->resolved_module_type_pathlocalsub|`SubstAlias(sub,_)->resolved_module_pathlocalsub|`Hiddenp->resolved_module_pathlocalp|`Module(p,name)->letparent=resolved_module_pathlocalpinSig.lookup_module(ModuleName.to_stringname)parent|`Canonical(p,_)->resolved_module_pathlocalp|`Apply(p,arg)->letparent=resolved_module_pathlocalpinSig.lookup_apply(module_pathlocal)argparentandresolved_module_type_pathlocal(p:Path.Resolved.ModuleType.t)=matchpwith|`Identifier(id:Identifier.ModuleType.t)->ifis_locallocal(id:>Identifier.t)thenlocal_module_type_identifierlocalidelsemodule_type_identifierlocal.tid|`ModuleType(p,name)->letparent=resolved_module_pathlocalpinSig.lookup_module_type(ModuleTypeName.to_stringname)parentandresolved_class_type_pathlocal(p:Path.Resolved.ClassType.t)=matchpwith|`Identifierid->class_signature_identifierlocal.tid|`Class(p,name)->letparent=resolved_module_pathlocalpinSig.lookup_class_type(ClassName.to_stringname)parent|`ClassType(p,name)->letparent=resolved_module_pathlocalpinSig.lookup_class_type(ClassTypeName.to_stringname)parentandmodule_pathlocal(p:Path.Module.t)=matchpwith|`Roots->beginmatchlocal.t.lookup_unitswith|Not_found->letsg=Sig.unresolvedinSig.set_hiddensg(Root.contains_double_underscores)|Found{root;_}->unitlocal.troot|Forward_reference->letsg=Sig.abstractinSig.set_hiddensg(Root.contains_double_underscores)end|`Forwards->begin(* FIXME? *)matchlocal.t.lookup_unitswith|Not_found->letsg=Sig.unresolvedinSig.set_hiddensg(Root.contains_double_underscores)|Found{root;_}->unitlocal.troot|Forward_reference->letsg=Sig.abstractinSig.set_hiddensg(Root.contains_double_underscores)end|`Resolvedr->resolved_module_pathlocalr|`Dot(p,name)->letparent=module_pathlocalpinSig.lookup_modulenameparent|`Apply(p,arg)->letparent=module_pathlocalpinSig.lookup_apply(module_pathlocal)argparentandmodule_type_pathlocal=function|`Resolvedr->resolved_module_type_pathlocalr|`Dot(p,name)->letparent=module_pathlocalpinSig.lookup_module_typenameparentandclass_signature_pathlocal=function|`Resolvedp->resolved_class_type_pathlocalp|`Dot(p,name)->letparent=module_pathlocalpinSig.lookup_class_typenameparentandclass_signature_itemslocal=letopenClassSiginletopenClassSignatureinfunction|InstanceVariableivar::rest->letopenInstanceVariableinletcsig=class_signature_itemslocalrestinletcsig=add_documentationivar.doccsiginletname=Identifier.nameivar.idinadd_elementname`InstanceVariablecsig|Methodmeth::rest->letopenMethodinletcsig=class_signature_itemslocalrestinletcsig=add_documentationmeth.doccsiginletname=Identifier.namemeth.idinadd_elementname`Methodcsig|Constraint_::rest->class_signature_itemslocalrest|Inheritexpr::rest->letcsig=class_signature_itemslocalrestinletexpr=class_type_exprlocalexprininherit_exprcsig|Commentcomment::rest->letcsig=class_signature_itemslocalrestinadd_commentcommentcsig|[]->emptyandclass_signaturelocalcsig=letopenClassSignatureinclass_signature_itemslocalcsig.itemsandclass_type_exprlocal=letopenClassTypeinfunction|Constr(p,_)->ClassSig.constr(class_signature_pathlocal)p|Signaturecsig->ClassSig.signature(class_signaturelocal)csigandclass_decllocal=letopenClassinfunction|ClassTypeexpr->class_type_exprlocalexpr|Arrow(_,_,decl)->class_decllocaldeclandsignature_itemslocal=letopenSiginletopenSignatureinfunction|Module(_,md)::rest->letopenModuleinletname=Identifier.namemd.idinletdecl=module_decllocalmd.type_inletdecl=set_canonicaldeclmd.canonicalinletdecl=set_hiddendeclmd.hiddeninadd_local_module_identifierlocalmd.iddecl;letsg=signature_itemslocalrestinletsg=add_documentationmd.docsginadd_modulenamedeclsg|ModuleTypemty::rest->letopenModuleTypeinletname=Identifier.namemty.idinletexpr=matchmty.exprwith|None->abstract|Someexpr->module_type_exprlocalexprinadd_local_module_type_identifierlocalmty.idexpr;letsg=signature_itemslocalrestinletsg=add_documentationmty.docsginadd_module_typenameexprsg|Type(_,decl)::rest->letopenTypeDeclinletsg=signature_itemslocalrestinletsg=add_documentationdecl.docsginletname=Identifier.namedecl.idinletdecl=datatypedeclinadd_datatypenamedeclsg|TypExtext::rest->letopenExtensioninletsg=signature_itemslocalrestinletsg=add_documentationext.docsginList.fold_right(funcstracc->letopenConstructorinletname=Identifier.namecstr.idinletacc=add_documentationcstr.docaccinadd_elementname`Extensionacc)ext.constructorssg|Exceptionexn::rest->letopenExceptioninletsg=signature_itemslocalrestinletsg=add_documentationexn.docsginletname=Identifier.nameexn.idinadd_elementname`Exceptionsg|Valuev::rest->letopenValueinletsg=signature_itemslocalrestinletsg=add_documentationv.docsginletname=Identifier.namev.idinadd_elementname`Valuesg|Externalev::rest->letopenExternalinletsg=signature_itemslocalrestinletsg=add_documentationev.docsginletname=Identifier.nameev.idinadd_elementname`Valuesg|Class(_,cl)::rest->letopenClassinletsg=signature_itemslocalrestinletsg=add_documentationcl.docsginletname=Identifier.namecl.idinletexpr=class_decllocalcl.type_inadd_classnameexprsg|ClassType(_,clty)::rest->letopenClassTypeinletsg=signature_itemslocalrestinletsg=add_documentationclty.docsginletname=Identifier.nameclty.idinletexpr=class_type_exprlocalclty.exprinadd_class_typenameexprsg|Includeincl::rest->letopenIncludeinletdecl=module_decllocalincl.declinadd_local_moduleslocalincl.parent(modulesdecl);add_local_module_typeslocalincl.parent(module_typesdecl);letsg=signature_itemslocalrestinletsg=add_documentationincl.docsgininclude_declsg|Commentcom::rest->letsg=signature_itemslocalrestinadd_commentcomsg|ModuleSubstitutionmst::rest->letopenModuleSubstitutionin(* Treat it like an alias *)letname=Identifier.namemst.idinletdecl=module_decllocal(Aliasmst.manifest)inadd_local_module_identifierlocalmst.iddecl;letsg=signature_itemslocalrestinletsg=add_documentationmst.docsginadd_modulenamedeclsg|TypeSubstitution_::rest->signature_itemslocalrest|[]->emptyandmodule_type_exprlocalexpr=letopenSiginletopenModuleTypeinletopenFunctorParameterinmatchexprwith|Pathp->path(module_type_pathlocal)p|Signaturesg->signature(signature_itemslocal)sg|Functor(Named{id;expr=arg;_},res)->letres=module_type_exprlocalresinletarg=module_type_exprlocalarginfunctor_local.t.equallocal.t.hashidargres|Functor(Unit,res)->letres=module_type_exprlocalresingenerativeres|With(body,subs)->letbody=module_type_exprlocalbodyinList.fold_left(funbodysub->matchsubwith|ModuleEq(frag,decl)->leteq=module_decllocaldeclinwith_modulefrageqbody|TypeEq_->body|ModuleSubst(frag,_)->with_module_substfragbody|TypeSubst(frag,_)->with_type_substfragbody)bodysubs|TypeOfdecl->module_decllocaldeclandmodule_decllocaldecl=letopenSiginletopenModuleinmatchdeclwith|Aliasp->alias(module_pathlocal)p|ModuleTypeexpr->module_type_exprlocalexprandpacked_itemslocal=letopenSiginletopenCompilation_unit.Packedinfunction|{id;path}::rest->letname=Identifier.nameidinletdecl=alias(module_pathlocal)pathinadd_local_module_identifierlocaliddecl;letsg=packed_itemslocalrestinadd_modulenamedeclsg|[]->empty(* Remove local parameter from exposed versions *)letresolved_module_pathtblp=letlocal=create_localtblNoneinresolved_module_pathlocalpletresolved_module_type_pathtblp=letlocal=create_localtblNoneinresolved_module_type_pathlocalpletresolved_class_type_pathtblp=letlocal=create_localtblNoneinresolved_class_type_pathlocalpletmodule_pathtblp=letlocal=create_localtblNoneinmodule_pathlocalptypewith_={base:Sig.t;tbl:t;}letmodule_type_expr_withtblidexpr=letlocal=create_localtbl(Someid)inletbase=module_type_exprlocalexprin{base;tbl}letmodule_type_path_withtblpath=letlocal=create_localtblNoneinletbase=module_type_pathlocalpathin{base;tbl}letrecresolved_signature_fragmentwth(f:Fragment.Resolved.Signature.t)=matchfwith|`Root->wth.base|`Subst(sub,_)->resolved_module_type_pathwth.tblsub|`SubstAlias(sub,_)->resolved_module_pathwth.tblsub|`Module(p,name)->letparent=resolved_signature_fragmentwthpinSig.lookup_module(ModuleName.to_stringname)parentletrecresolved_signature_referencetbl(r:Reference.Resolved.Signature.t)=matchrwith|`Identifierid->signature_identifiertblid|`SubstAlias(sub,_)->resolved_module_pathtblsub|`Module(p,name)->letparent=resolved_signature_referencetblpinSig.lookup_module(ModuleName.to_stringname)parent|`Canonical(p,_)->resolved_signature_referencetbl(p:Reference.Resolved.Module.t:>Reference.Resolved.Signature.t)|`ModuleType(p,name)->letparent=resolved_signature_referencetblpinSig.lookup_module_type(ModuleTypeName.to_stringname)parentandresolved_class_signature_referencetbl(r:Reference.Resolved.ClassSignature.t)=matchrwith|`Identifierid->class_signature_identifiertblid|`Class(p,name)->letparent=resolved_signature_referencetblpinSig.lookup_class_type(ClassName.to_stringname)parent|`ClassType(p,name)->letparent=resolved_signature_referencetblpinSig.lookup_class_type(ClassTypeName.to_stringname)parentandresolved_datatype_referencetbl(r:Reference.Resolved.DataType.t)=matchrwith|`Identifierid->datatype_identifiertblid|`Type(p,name)->letparent=resolved_signature_referencetblpinSig.lookup_datatype(TypeName.to_stringname)parentandresolved_page_referencetbl:Reference.Resolved.Page.t->_=function|`Identifierid->page_identifiertblidletbasetbls=tbl.lookup_unitsletpage_basetbls=tbl.lookup_pages