1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969openOdoc_model.Names(* Add [result] and a bind operator over it in scope *)openUtilsopenResultMonadtype('a,'b)either=Leftof'a|Rightof'bletfilter_mapfx=List.rev@@List.fold_left(funaccx->matchfxwithSomex->x::acc|None->acc)[]xtypemodule_modifiers=[`AliasedofCpath.Resolved.module_|`SubstMTofCpath.Resolved.module_type]typemodule_type_modifiers=[`AliasModuleTypeofCpath.Resolved.module_type](* These three functions take a fully-qualified canonical path and return
a list of shorter possibilities to test *)letc_mod_possenvp=(* canonical module paths *)letrecinner=function|`Dot(p,n)->(letrest=List.map(funp->`Dot(p,n))(innerp)inmatchEnv.lookup_by_nameEnv.s_modulenenvwith|Ok(`Module(id,m))->letm=Component.Delayed.getmin`Identifier(id,m.hidden)::rest|Error_->rest)|p->[p]ininnerpletc_modty_possenvp=(* canonical module type paths *)matchpwith|`Dot(p,n)->(letrest=List.map(funp->`Dot(p,n))(c_mod_possenvp)inmatchEnv.lookup_by_nameEnv.s_module_typenenvwith|Ok(`ModuleType(id,_))->`Identifier(id,false)::rest|Error_->rest)|p->[p]letc_ty_possenvp=(* canonical type paths *)matchpwith|`Dot(p,n)->(letrest=List.map(funp->`Dot(p,n))(c_mod_possenvp)inmatchEnv.lookup_by_nameEnv.s_typenenvwith|Ok(`Type(id,_))->`Identifier((id:>Odoc_model.Paths.Identifier.Path.Type.t),false)::rest|Error_->rest)|p->[p](* Small helper function for resolving canonical paths.
[canonical_helper env resolve lang_of possibilities p2] takes the
fully-qualified path [p2] and returns the shortest resolved path
whose identifier is the same as the resolved fully qualified path.
[resolve] is a function that resolves an arbitrary unresolved path,
[lang_of] turns a resolved path into a generic resolved Lang path
and [possibilities] is a function that, given the fully qualified
unresolved path, returns an ordered list of all possible unresolved
paths starting with the shortest and including the longest one. *)letcanonical_helper:'unresolved'resolved.Env.t->(Env.t->'unresolved->('resolved*'result,_)result)->('resolved->Odoc_model.Paths.Path.Resolved.t)->(Env.t->'unresolved->'unresolvedlist)->'unresolved->('resolved*'result)option=funenvresolvelang_ofpossibilitiesp2->letresolvep=matchresolveenvpwithOkrp->Somerp|Error_->Noneinletget_identifiercpath=Odoc_model.Paths.Path.Resolved.identifier(lang_ofcpath)inmatchresolvep2with|None->None|Some(rp2,_)->(letfallback_id=get_identifierrp2inletresolved=filter_mapresolve(possibilitiesenvp2)inletfind_fn(r,_)=get_identifierr=fallback_idintrySome(List.findfind_fnresolved)with_->None)letcore_types=letopenOdoc_model.Lang.TypeDeclinletopenOdoc_model.PathsinList.map(fundecl->(Identifier.namedecl.id,Component.Of_Lang.(type_decl(empty())decl)))Odoc_model.Predefined.core_typesletprefix_substitutionpathsg=letopenComponent.Signatureinletrecget_subsub'is=matchiswith|[]->sub'|Type(id,_,_)::rest->letname=Ident.Name.typed_typeidinget_sub(Subst.add_typeid(`Type(path,name))(`Type(path,name))sub')rest|Module(id,_,_)::rest->letname=Ident.Name.typed_moduleidinget_sub(Subst.add_module(id:>Ident.path_module)(`Module(path,name))(`Module(path,name))sub')rest|ModuleType(id,_)::rest->letname=Ident.Name.typed_module_typeidinget_sub(Subst.add_module_typeid(`ModuleType(path,name))(`ModuleType(path,name))sub')rest|ModuleTypeSubstitution(id,_)::rest->letname=Ident.Name.typed_module_typeidinget_sub(Subst.add_module_typeid(`ModuleType(path,name))(`ModuleType(path,name))sub')rest|ModuleSubstitution(id,_)::rest->letname=Ident.Name.typed_moduleidinget_sub(Subst.add_module(id:>Ident.path_module)(`Module(path,name))(`Module(path,name))sub')rest|TypeSubstitution(id,_)::rest->letname=Ident.Name.typed_typeidinget_sub(Subst.add_typeid(`Type(path,name))(`Type(path,name))sub')rest|Exception_::rest|TypExt_::rest|Value(_,_)::rest|Comment_::rest->get_subsub'rest|Class(id,_,_)::rest->letname=Ident.Name.typed_classidinget_sub(Subst.add_classid(`Class(path,name))(`Class(path,name))sub')rest|ClassType(id,_,_)::rest->letname=Ident.Name.typed_class_typeidinget_sub(Subst.add_class_typeid(`ClassType(path,name))(`ClassType(path,name))sub')rest|Includei::rest->get_sub(get_subsub'i.expansion_.items)rest|Openo::rest->get_sub(get_subsub'o.expansion.items)restinletextend_sub_removedremovedsub=List.fold_right(funitemmap->matchitemwith|Component.Signature.RModule(id,_)->letname=Ident.Name.typed_moduleidinSubst.add_module(id:>Ident.path_module)(`Module(path,name))(`Module(path,name))map|Component.Signature.RModuleType(id,_)->letname=Ident.Name.typed_module_typeidinSubst.add_module_type(id:>Ident.module_type)(`ModuleType(path,name))(`ModuleType(path,name))map|Component.Signature.RType(id,_,_)->letname=Ident.Name.typed_typeidinSubst.add_typeid(`Type(path,name))(`Type(path,name))map)removedsubinget_subSubst.identitysg.items|>extend_sub_removedsg.removedletprefix_signature(path,sg)=letopenComponent.Signatureinletsub=prefix_substitutionpathsginletitems=List.map(function|Module(id,r,m)->Module(Ident.Rename.module_id,r,Component.Delayed.put(fun()->Subst.module_sub(Component.Delayed.getm)))|ModuleType(id,mt)->ModuleType(Ident.Rename.module_typeid,Component.Delayed.put(fun()->Subst.module_typesub(Component.Delayed.getmt)))|Type(id,r,t)->Type(Ident.Rename.type_id,r,Component.Delayed.put(fun()->Subst.type_sub(Component.Delayed.gett)))|TypeSubstitution(id,t)->TypeSubstitution(Ident.Rename.type_id,Subst.type_subt)|ModuleSubstitution(id,m)->ModuleSubstitution(Ident.Rename.module_id,Subst.module_substitutionsubm)|ModuleTypeSubstitution(id,m)->ModuleTypeSubstitution(Ident.Rename.module_typeid,Subst.module_type_substitutionsubm)|Exception(id,e)->Exception(id,Subst.exception_sube)|TypExtt->TypExt(Subst.extensionsubt)|Value(id,v)->Value(id,Component.Delayed.put(fun()->Subst.valuesub(Component.Delayed.getv)))|Class(id,r,c)->Class(Ident.Rename.class_id,r,Subst.class_subc)|ClassType(id,r,c)->ClassType(Ident.Rename.class_typeid,r,Subst.class_typesubc)|Includei->Include(Subst.include_subi)|Openo->Open(Subst.open_subo)|Commentc->Commentc)sg.itemsin{sgwithitems}openErrors.Tools_errortyperesolve_module_result=(Cpath.Resolved.module_*Component.Module.tComponent.Delayed.t,simple_module_lookup_error)Result.resulttyperesolve_module_type_result=(Cpath.Resolved.module_type*Component.ModuleType.t,simple_module_type_lookup_error)Result.resulttyperesolve_type_result=(Cpath.Resolved.type_*Find.careful_type,simple_type_lookup_error)Result.resulttyperesolve_class_type_result=(Cpath.Resolved.class_type*Find.careful_class,simple_type_lookup_error)Result.resulttype('a,'b,'c)sig_map={type_:'a;module_:'b;module_type:'c}letid_map={type_=None;module_=None;module_type=None}moduletypeMEMO=sigtyperesultincludeHashtbl.HashedTypeendmoduleMakeMemo(X:MEMO)=structmoduleM=Hashtbl.Make(X)letcache:(X.result*int*Env.LookupTypeSet.t)M.t=M.create10000letcache_hits:intM.t=M.create10000letenabled=reftrueletbump_counterarg=tryletnew_val=M.findcache_hitsarg+1inM.replacecache_hitsargnew_val;new_valwith_->M.addcache_hitsarg1;1letmemoizefenvarg=ifnot!enabledthenfenvargelseletenv_id=Env.idenvinletn=bump_counterarginletno_memo()=letlookups,result=Env.with_recorded_lookupsenv(funenv'->fenv'arg)inifn>1thenM.addcachearg(result,env_id,lookups);resultinmatchM.find_allcacheargwith|[]->no_memo()|xs->letrecfind_fast=function|(result,env_id',_)::_whenenv_id'=env_id->M.replacecache_hitsarg(M.findcache_hitsarg+1);result|_::ys->find_fastys|[]->findxsandfind=function|(m,_,lookups)::xs->ifEnv.verify_lookupsenvlookupsthenmelsefindxs|[]->no_memo()infind_fastxsletclear()=M.clearcache;M.clearcache_hitsendmoduleLookupModuleMemo=MakeMemo(structtypet=bool*Cpath.Resolved.module_typeresult=(Component.Module.tComponent.Delayed.t,simple_module_lookup_error)Result.resultletequal=(=)lethash=Hashtbl.hashend)moduleLookupParentMemo=MakeMemo(structtypet=bool*Cpath.Resolved.parenttyperesult=(Component.Signature.t*Component.Substitution.t,[`Parentofparent_lookup_error])Result.resultletequal=(=)lethash=Hashtbl.hashend)moduleLookupAndResolveMemo=MakeMemo(structtypet=bool*bool*Cpath.module_typeresult=resolve_module_resultletequal=(=)lethash=Hashtbl.hashend)moduleSignatureOfModuleMemo=MakeMemo(structtypet=Cpath.Resolved.module_typeresult=(Component.Signature.t,signature_of_module_error)Result.resultletequal=(=)lethash=Hashtbl.hashend)letdisable_all_caches()=LookupModuleMemo.enabled:=false;LookupAndResolveMemo.enabled:=false;SignatureOfModuleMemo.enabled:=false;LookupParentMemo.enabled:=falseletreset_caches()=LookupModuleMemo.clear();LookupAndResolveMemo.clear();SignatureOfModuleMemo.clear();LookupParentMemo.clear()letsimplify_module:Env.t->Cpath.Resolved.module_->Cpath.Resolved.module_=funenvm->matchmwith|`Module(`Module(`Identifierp),name)->(letident=(`Module((p:>Odoc_model.Paths.Identifier.Signature.t),name):Odoc_model.Paths.Identifier.Path.Module.t)inmatchEnv.(lookup_by_ids_module(ident:>Odoc_model.Paths.Identifier.Signature.t)env)with|Some_->`Identifierident|None->m)|_->mletsimplify_module_type:Env.t->Cpath.Resolved.module_type->Cpath.Resolved.module_type=funenvm->matchmwith|`ModuleType(`Module(`Identifierp),name)->(letident=(`ModuleType((p:>Odoc_model.Paths.Identifier.Signature.t),name):Odoc_model.Paths.Identifier.Path.ModuleType.t)inmatchEnv.(lookup_by_ids_module_type(ident:>Odoc_model.Paths.Identifier.Signature.t)env)with|Some_->`Identifierident|None->m)|_->mletsimplify_type:Env.t->Cpath.Resolved.type_->Cpath.Resolved.type_=funenvm->matchmwith|`Type(`Module(`Identifierp),name)->(letident=(`Type((p:>Odoc_model.Paths.Identifier.Signature.t),name):Odoc_model.Paths.Identifier.Path.Type.t)inmatchEnv.(lookup_by_ids_type(ident:>Odoc_model.Paths.Identifier.Path.Type.t)env)with|Some_->`Identifierident|None->m)|_->mletrechandle_apply~mark_substitutedenvfunc_patharg_pathm=letrecfind_functormty=matchmtywith|Component.ModuleType.Functor(Namedarg,expr)->Ok(arg.Component.FunctorParameter.id,expr)|Component.ModuleType.Path{p_path;_}->(matchresolve_module_type~mark_substituted:false~add_canonical:trueenvp_pathwith|Ok(_,{Component.ModuleType.expr=Somemty';_})->find_functormty'|_->Error`OpaqueModule)|_->Error`ApplyNotFunctorinmodule_type_expr_of_moduleenvm>>=funmty'->find_functormty'>>=fun(arg_id,result)->letnew_module={mwithComponent.Module.type_=ModuleTyperesult}inletsubstitution=ifmark_substitutedthen`Substitutedarg_pathelsearg_pathinletpath=`Apply(func_path,arg_path)inletsubst=Subst.add_module(arg_id:>Ident.path_module)(`Resolvedsubstitution)substitutionSubst.identityinletsubst=Subst.unresolve_opaque_pathssubstinOk(path,Subst.module_substnew_module)andadd_canonical_path:Component.Module.t->Cpath.Resolved.module_->Cpath.Resolved.module_=funmp->matchpwith|`Canonical_->p|_->(matchm.Component.Module.canonicalwith|Somecp->`Canonical(p,cp)|None->p)andadd_canonical_path_mt:Component.ModuleType.t->Cpath.Resolved.module_type->Cpath.Resolved.module_type=funmp->matchpwith|`CanonicalModuleType_->p|_->(matchm.canonicalwith|Somecp->`CanonicalModuleType(p,cp)|None->p)andget_substituted_module_type:Env.t->Component.ModuleType.expr->Cpath.Resolved.module_typeoption=funenvexpr->matchexprwith|Component.ModuleType.Path{p_path;_}->ifCpath.is_module_type_substitutedp_paththenmatchresolve_module_type~mark_substituted:true~add_canonical:trueenvp_pathwith|Ok(resolved_path,_)->Someresolved_path|Error_->NoneelseNone|_->Noneandget_module_type_path_modifiers:Env.t->add_canonical:bool->Component.ModuleType.t->module_type_modifiersoption=funenv~add_canonicalm->letalias_ofexpr=matchexprwith|Component.ModuleType.Pathalias_path->(matchresolve_module_type~mark_substituted:true~add_canonicalenvalias_path.p_pathwith|Ok(resolved_alias_path,_)->Someresolved_alias_path|Error_->None)(* | Functor (_arg, res) -> alias_of res *)|_->Noneinmatchm.exprwith|Somee->(matchalias_ofewithSomee->Some(`AliasModuleTypee)|None->None)|None->Noneandprocess_module_typeenv~add_canonicalmp'=letopenComponent.ModuleTypeinletopenOptionMonadin(* Loop through potential chains of module_type equalities, looking for substitutions *)letsubstpath=m.expr>>=get_substituted_module_typeenv>>=funp->Some(`SubstT(p,p'))inletp'=matchsubstpathwithSomep->p|None->p'inletp''=matchget_module_type_path_modifiersenv~add_canonicalmwith|Some(`AliasModuleTypee)->`AliasModuleType(e,p')|None->p'inletp'''=ifadd_canonicalthenadd_canonical_path_mtmp''elsep''inp'''andget_module_path_modifiers:Env.t->add_canonical:bool->Component.Module.t->_option=funenv~add_canonicalm->matchm.type_with|Alias(alias_path,_)->(matchresolve_module~mark_substituted:true~add_canonicalenvalias_pathwith|Ok(resolved_alias_path,_)->Some(`Aliasedresolved_alias_path)|Error_->None)|ModuleTypet->(matchget_substituted_module_typeenvtwith|Somes->Some(`SubstMTs)|None->None)andprocess_module_pathenv~add_canonicalmp=letp=ifm.Component.Module.hiddenthen`Hiddenpelsepinletp'=matchget_module_path_modifiersenv~add_canonicalmwith|None->p|Some(`Aliasedp')->`Alias(p',p)|Some(`SubstMTp')->`Subst(p',p)inletp''=ifadd_canonicalthenadd_canonical_pathmp'elsep'inp''andhandle_module_lookupenv~add_canonicalidparentsgsub=matchFind.careful_module_in_sigsgidwith|Some(`FModule(name,m))->letp'=simplify_moduleenv(`Module(parent,name))inletm'=Subst.module_subminletmd'=Component.Delayed.put_valm'inOk(process_module_pathenv~add_canonicalm'p',md')|Some(`FModule_removedp)->lookup_module~mark_substituted:falseenvp>>=funm->Ok(p,m)|None->Error`Find_failureandhandle_module_type_lookupenv~add_canonicalidpsgsub=letopenOptionMonadinFind.module_type_in_sigsgid>>=fun(`FModuleType(name,mt))->letmt=Subst.module_typesubmtinletp'=simplify_module_typeenv(`ModuleType(p,name))inletp''=process_module_typeenv~add_canonicalmtp'inSome(p'',mt)andhandle_type_lookupenvidpsg=matchFind.careful_type_in_sigsgidwith|Some(`FClass(name,_)ast)->Ok(`Class(p,name),t)|Some(`FClassType(name,_)ast)->Ok(`ClassType(p,name),t)|Some(`FType(name,_)ast)->Ok(simplify_typeenv(`Type(p,name)),t)|Some(`FType_removed(name,_,_)ast)->Ok(`Type(p,name),t)|None->Error`Find_failureandhandle_class_type_lookupidpsg=matchFind.careful_class_in_sigsgidwith|Some(`FClass(name,_)ast)->Ok(`Class(p,name),t)|Some(`FClassType(name,_)ast)->Ok(`ClassType(p,name),t)|Some(`FType_removed(_name,_,_)as_t)->Error`Class_replaced|None->Error`Find_failureandlookup_module:mark_substituted:bool->Env.t->Cpath.Resolved.module_->(Component.Module.tComponent.Delayed.t,simple_module_lookup_error)Result.result=fun~mark_substituted:menv'path'->letlookupenv(mark_substituted,(path:SignatureOfModuleMemo.M.key))=matchpathwith|`Locallpath->Error(`Local(env,lpath))|`Identifieri->of_option~error:(`Lookup_failurei)(Env.(lookup_by_ids_module)ienv)>>=fun(`Module(_,m))->Okm|`Substitutedx->lookup_module~mark_substitutedenvx|`Apply(functor_path,argument_path)->lookup_module~mark_substitutedenvfunctor_path>>=funfunctor_module->letfunctor_module=Component.Delayed.getfunctor_moduleinhandle_apply~mark_substitutedenvfunctor_pathargument_pathfunctor_module|>map_error(fune->`Parent(`Parent_expre))>>=fun(_,m)->Ok(Component.Delayed.put_valm)|`Module(parent,name)->letfind_in_sgsgsub=matchFind.careful_module_in_sigsg(ModuleName.to_stringname)with|None->Error`Find_failure|Some(`FModule(_,m))->Ok(Component.Delayed.put_val(Subst.module_subm))|Some(`FModule_removedp)->lookup_module~mark_substitutedenvpinlookup_parent~mark_substitutedenvparent|>map_error(fune->(e:>simple_module_lookup_error))>>=fun(sg,sub)->find_in_sgsgsub|`Alias(_,p)->lookup_module~mark_substitutedenvp|`Subst(_,p)->lookup_module~mark_substitutedenvp|`Hiddenp->lookup_module~mark_substitutedenvp|`Canonical(p,_)->lookup_module~mark_substitutedenvp|`OpaqueModulem->lookup_module~mark_substitutedenvminLookupModuleMemo.memoizelookupenv'(m,path')andlookup_module_type:mark_substituted:bool->Env.t->Cpath.Resolved.module_type->(Component.ModuleType.t,simple_module_type_lookup_error)Result.result=fun~mark_substitutedenvpath->letlookupenv=matchpathwith|`Locall->Error(`LocalMT(env,l))|`Identifieri->of_option~error:(`Lookup_failureMTi)(Env.(lookup_by_ids_module_type)ienv)>>=fun(`ModuleType(_,mt))->Okmt|`Substituteds|`CanonicalModuleType(s,_)|`SubstT(_,s)->lookup_module_type~mark_substitutedenvs|`ModuleType(parent,name)->letfind_in_sgsgsub=matchFind.module_type_in_sigsg(ModuleTypeName.to_stringname)with|None->Error`Find_failure|Some(`FModuleType(_,mt))->Ok(Subst.module_typesubmt)inlookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_module_type_lookup_error))>>=fun(sg,sub)->find_in_sgsgsub|`AliasModuleType(_,mt)->lookup_module_type~mark_substitutedenvmt|`OpaqueModuleTypem->lookup_module_type~mark_substitutedenvminlookupenvandlookup_parent:mark_substituted:bool->Env.t->Cpath.Resolved.parent->(Component.Signature.t*Component.Substitution.t,[`Parentofparent_lookup_error])Result.result=fun~mark_substituted:menv'parent'->letlookupenv(mark_substituted,parent)=matchparentwith|`Modulep->lookup_module~mark_substitutedenvp|>map_error(fune->`Parent(`Parent_modulee))>>=funm->letm=Component.Delayed.getminsignature_of_moduleenvm|>map_error(fune->`Parent(`Parent_sige))>>=funsg->Ok(sg,prefix_substitutionparentsg)|`ModuleTypep->lookup_module_type~mark_substitutedenvp|>map_error(fune->`Parent(`Parent_module_typee))>>=funmt->signature_of_module_typeenvmt|>map_error(fune->`Parent(`Parent_sige))>>=funsg->Ok(sg,prefix_substitutionparentsg)|`FragmentRoot->Env.lookup_fragment_rootenv|>of_option~error:(`Parent`Fragment_root)>>=fun(_,sg)->Ok(sg,prefix_substitutionparentsg)inLookupParentMemo.memoizelookupenv'(m,parent')andlookup_type:Env.t->Cpath.Resolved.type_->(Find.careful_type,simple_type_lookup_error)Result.result=funenvp->letdo_typepname=lookup_parent~mark_substituted:trueenvp|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(sg,sub)->handle_type_lookupenvnamepsg>>=fun(_,t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType(name,t)->`FType(name,Subst.type_subt)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOktinletres=matchpwith|`Localid->Error(`LocalType(env,id))|`Identifier(`CoreTypename)->(* CoreTypes aren't put into the environment, so they can't be handled by the
next clause. We just look them up here in the list of core types *)Ok(`FType(name,List.assoc(TypeName.to_stringname)core_types))|`Identifier(`Type_asi)->of_option~error:(`Lookup_failureTi)(Env.(lookup_by_ids_type)ienv)>>=fun(`Type((`CoreTypename|`Type(_,name)),t))->Ok(`FType(name,t))|`Identifier(`Class_asi)->of_option~error:(`Lookup_failureTi)(Env.(lookup_by_ids_class)ienv)>>=fun(`Class(`Class(_,name),t))->Ok(`FClass(name,t))|`Identifier(`ClassType_asi)->of_option~error:(`Lookup_failureTi)(Env.(lookup_by_ids_class_type)ienv)>>=fun(`ClassType(`ClassType(_,name),t))->Ok(`FClassType(name,t))|`CanonicalType(t1,_)->lookup_typeenvt1|`Substituteds->lookup_typeenvs|`Type(p,id)->do_typep(TypeName.to_stringid)|`Class(p,id)->do_typep(ClassName.to_stringid)|`ClassType(p,id)->do_typep(ClassTypeName.to_stringid)inresandlookup_class_type:Env.t->Cpath.Resolved.class_type->(Find.careful_class,simple_type_lookup_error)Result.result=funenvp->letdo_typepname=lookup_parent~mark_substituted:trueenvp|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(sg,sub)->handle_class_type_lookupnamepsg>>=fun(_,t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOktinletres=matchpwith|`Localid->Error(`LocalType(env,(id:>Ident.path_type)))|`Identifier(`Class_asi)->of_option~error:(`Lookup_failureTi)(Env.(lookup_by_ids_class)ienv)>>=fun(`Class(`Class(_,name),t))->Ok(`FClass(name,t))|`Identifier(`ClassType_asi)->of_option~error:(`Lookup_failureTi)(Env.(lookup_by_ids_class_type)ienv)>>=fun(`ClassType(`ClassType(_,name),t))->Ok(`FClassType(name,t))|`Substituteds->lookup_class_typeenvs|`Class(p,id)->do_typep(ClassName.to_stringid)|`ClassType(p,id)->do_typep(ClassTypeName.to_stringid)inresandresolve_module:mark_substituted:bool->add_canonical:bool->Env.t->Cpath.module_->resolve_module_result=fun~mark_substituted~add_canonicalenv'path->letid=(mark_substituted,add_canonical,path)inletresolveenv(mark_substituted,add_canonical,p)=matchpwith|`Dot(parent,id)->resolve_module~mark_substituted~add_canonicalenvparent|>map_error(fune'->`Parent(`Parent_modulee'))>>=fun(p,m)->letm=Component.Delayed.getminsignature_of_module_cachedenvpm|>map_error(fune->`Parent(`Parent_sige))>>=funparent_sig->letsub=prefix_substitution(`Modulep)parent_siginhandle_module_lookupenv~add_canonicalid(`Modulep)parent_sigsub|`Module(parent,id)->lookup_parent~mark_substitutedenvparent|>map_error(fune->(e:>simple_module_lookup_error))>>=fun(parent_sig,sub)->handle_module_lookupenv~add_canonical(ModuleName.to_stringid)parentparent_sigsub|`Apply(m1,m2)->(letfunc=resolve_module~mark_substituted~add_canonicalenvm1inletarg=resolve_module~mark_substituted~add_canonicalenvm2inmatch(func,arg)with|Ok(func_path',m),Ok(arg_path',_)->(letm=Component.Delayed.getminmatchhandle_apply~mark_substitutedenvfunc_path'arg_path'mwith|Ok(p,m)->Ok(p,Component.Delayed.put_valm)|Errore->Error(`Parent(`Parent_expre)))|_->Error`Unresolved_apply)|`Identifier(i,hidden)->of_option~error:(`Lookup_failurei)(Env.(lookup_by_ids_module)ienv)>>=fun(`Module(_,m))->letp=ifhiddenthen`Hidden(`Identifieri)else`IdentifieriinOk(process_module_pathenv~add_canonical(Component.Delayed.getm)p,m)|`Local(p,_)->Error(`Local(env,p))|`Resolved(`Identifieriasresolved_path)->of_option~error:(`Lookup_failurei)(Env.(lookup_by_ids_module)ienv)>>=fun(`Module(_,m))->Ok(resolved_path,m)|`Resolvedr->lookup_module~mark_substitutedenvr>>=funm->Ok(r,m)|`Substituteds->resolve_module~mark_substituted~add_canonicalenvs|>map_error(fune->`Parent(`Parent_modulee))>>=fun(p,m)->Ok(`Substitutedp,m)|`Rootr->(matchEnv.lookup_root_modulerenvwith|Some(Env.Resolved(_,p,m))->letp=`Identifier(p:>Odoc_model.Paths.Identifier.Path.Module.t)inletp=process_module_pathenv~add_canonicalmpinOk(p,Component.Delayed.put_valm)|SomeEnv.Forward->Error(`Parent(`Parent_sig`UnresolvedForwardPath))|None->Error(`Lookup_failure_rootr))|`Forwardf->resolve_module~mark_substituted~add_canonicalenv(`Rootf)|>map_error(fune->`Parent(`Parent_modulee))inLookupAndResolveMemo.memoizeresolveenv'idandresolve_module_type:mark_substituted:bool->add_canonical:bool->Env.t->Cpath.module_type->resolve_module_type_result=fun~mark_substituted~add_canonicalenvp->matchpwith|`Dot(parent,id)->resolve_module~mark_substituted~add_canonical:trueenvparent|>map_error(fune->`Parent(`Parent_modulee))>>=fun(p,m)->letm=Component.Delayed.getminsignature_of_module_cachedenvpm|>map_error(fune->`Parent(`Parent_sige))>>=funparent_sg->letsub=prefix_substitution(`Modulep)parent_sginof_option~error:`Find_failure(handle_module_type_lookupenv~add_canonicalid(`Modulep)parent_sgsub)>>=fun(p',mt)->Ok(p',mt)|`ModuleType(parent,id)->lookup_parent~mark_substitutedenvparent|>map_error(fune->(e:>simple_module_type_lookup_error))>>=fun(parent_sig,sub)->handle_module_type_lookupenv~add_canonical(ModuleTypeName.to_stringid)parentparent_sigsub|>of_option~error:`Find_failure|`Identifier(i,_)->of_option~error:(`Lookup_failureMTi)(Env.(lookup_by_ids_module_type)ienv)>>=fun(`ModuleType(_,mt))->letp=`Identifieriinletp'=process_module_typeenv~add_canonicalmtpinOk(p',mt)|`Local(l,_)->Error(`LocalMT(env,l))|`Resolvedr->lookup_module_type~mark_substitutedenvr>>=funm->Ok(r,m)|`Substituteds->resolve_module_type~mark_substituted~add_canonicalenvs|>map_error(fune->`Parent(`Parent_module_typee))>>=fun(p,m)->Ok(`Substitutedp,m)andresolve_type:Env.t->add_canonical:bool->Cpath.type_->resolve_type_result=funenv~add_canonicalp->letresult=matchpwith|`Dot(parent,id)->resolve_module~mark_substituted:true~add_canonical:trueenvparent|>map_error(fune->`Parent(`Parent_modulee))>>=fun(p,m)->letm=Component.Delayed.getminsignature_of_module_cachedenvpm|>map_error(fune->`Parent(`Parent_sige))>>=funsg->letsub=prefix_substitution(`Modulep)sginhandle_type_lookupenvid(`Modulep)sg>>=fun(p',t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType(name,t)->`FType(name,Subst.type_subt)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOk(p',t)|`Type(parent,id)->lookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(parent_sig,sub)->letresult=matchFind.datatype_in_sigparent_sig(TypeName.to_stringid)with|Some(`FType(name,t))->Some(`Type(parent,name),`FType(name,Subst.type_subt))|None->Noneinof_option~error:`Find_failureresult|`Class(parent,id)->lookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(parent_sig,sub)->lett=matchFind.type_in_sigparent_sig(ClassName.to_stringid)with|Some(`FClass(name,t))->Some(`Class(parent,name),`FClass(name,Subst.class_subt))|Some_->None|None->Noneinof_option~error:`Find_failuret|`ClassType(parent,id)->lookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(parent_sg,sub)->handle_type_lookupenv(ClassTypeName.to_stringid)parentparent_sg>>=fun(p',t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType(name,t)->`FType(name,Subst.type_subt)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOk(p',t)|`Identifier(i,_)->lookup_typeenv(`Identifieri)>>=funt->Ok(`Identifieri,t)|`Resolvedr->lookup_typeenvr>>=funt->Ok(r,t)|`Local(l,_)->Error(`LocalType(env,l))|`Substituteds->resolve_typeenv~add_canonicals>>=fun(p,m)->Ok(`Substitutedp,m)inresult>>=fun(p,t)->matchtwith|`FType(_,{canonical=Somec;_})->ifadd_canonicalthenOk(`CanonicalType(p,c),t)elseresult|_->resultandresolve_class_type:Env.t->Cpath.class_type->resolve_class_type_result=funenvp->matchpwith|`Dot(parent,id)->resolve_module~mark_substituted:true~add_canonical:trueenvparent|>map_error(fune->`Parent(`Parent_modulee))>>=fun(p,m)->letm=Component.Delayed.getminsignature_of_module_cachedenvpm|>map_error(fune->`Parent(`Parent_sige))>>=funsg->letsub=prefix_substitution(`Modulep)sginhandle_class_type_lookupid(`Modulep)sg>>=fun(p',t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOk(p',t)|`Identifier(i,_)->lookup_class_typeenv(`Identifieri)>>=funt->Ok(`Identifieri,t)|`Resolvedr->lookup_class_typeenvr>>=funt->Ok(r,t)|`Local(l,_)->Error(`LocalType(env,(l:>Ident.path_type)))|`Substituteds->resolve_class_typeenvs>>=fun(p,m)->Ok(`Substitutedp,m)|`Class(parent,id)->lookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(parent_sig,sub)->lett=matchFind.type_in_sigparent_sig(ClassName.to_stringid)with|Some(`FClass(name,t))->Some(`Class(parent,name),`FClass(name,Subst.class_subt))|Some_->None|None->Noneinof_option~error:`Find_failuret|`ClassType(parent,id)->lookup_parent~mark_substituted:trueenvparent|>map_error(fune->(e:>simple_type_lookup_error))>>=fun(parent_sg,sub)->handle_class_type_lookup(ClassTypeName.to_stringid)parentparent_sg>>=fun(p',t')->lett=matcht'with|`FClass(name,c)->`FClass(name,Subst.class_subc)|`FClassType(name,ct)->`FClassType(name,Subst.class_typesubct)|`FType_removed(name,texpr,eq)->`FType_removed(name,Subst.type_exprsubtexpr,eq)inOk(p',t)andreresolve_module:Env.t->Cpath.Resolved.module_->Cpath.Resolved.module_=funenvpath->matchpathwith|`Local_|`Identifier_->path|`Substitutedx->`Substituted(reresolve_moduleenvx)|`Apply(functor_path,argument_path)->`Apply(reresolve_moduleenvfunctor_path,reresolve_moduleenvargument_path)|`Module(parent,name)->`Module(reresolve_parentenvparent,name)|`Alias(p1,p2)->`Alias(reresolve_moduleenvp1,reresolve_moduleenvp2)|`Subst(p1,p2)->`Subst(reresolve_module_typeenvp1,reresolve_moduleenvp2)|`Hiddenp->letp'=reresolve_moduleenvpin`Hiddenp'|`Canonical(p,`Resolvedp2)->`Canonical(reresolve_moduleenvp,`Resolved(reresolve_moduleenvp2))|`Canonical(p,p2)->`Canonical(reresolve_moduleenvp,handle_canonical_moduleenvp2)|`OpaqueModulem->`OpaqueModule(reresolve_moduleenvm)andhandle_canonical_moduleenvp2=letstrip_alias:Cpath.Resolved.module_->Cpath.Resolved.module_=function|`Alias(_,p)->p|p->pinletresolveenvp=resolve_moduleenv~mark_substituted:false~add_canonical:falsep>>=fun(p,m)->Ok(strip_aliasp,m)inletlang_ofcpath=(Lang_of.(Path.resolved_module(empty())cpath):>Odoc_model.Paths.Path.Resolved.t)inmatchcanonical_helperenvresolvelang_ofc_mod_possp2with|None->p2|Some(rp,m)->letm=Component.Delayed.getmin(* Need to check if the module we're going to link to has been expanded.
ModuleTypes are always expanded if possible, but Aliases are only expanded
if they're an alias to a hidden module or if they're self canonical.
Checking if a module is self canonical is a bit tricky, since this function
is itself part of the process of resolving any canonical reference. Hence
what we do here is to look through alias chains looking for one that's marked
with the same _unresolved_ canonical path that we're currently trying to resolve.
This is particularly important because some modules don't know they're canonical!
For example the module Caml in base, which is marked as the canonical path for
all references to the standard library in the file [import0.ml], but is itself just
defined by including [Stdlib].
If a module doesn't know it's canonical, it will fail the self-canonical check, and
therefore not necessarily be expanded. If this happens, we call [process_module_path]
to stick the [`Alias] constructor back on so we'll link to the correct place. *)letexpanded=matchm.type_with|Component.Module.Alias(_,Some_)->true|Alias(`Resolvedp,None)->(* check for an alias chain with a canonical in it... *)letreccheck(m,p)=matchm.Component.Module.canonicalwith|Somep->p=p2(* The canonical path is the same one we're trying to resolve *)|None->(matchlookup_module~mark_substituted:falseenvpwith|Error_->false|Okm->(letm=Component.Delayed.getminmatchm.type_with|Alias(`Resolvedp,_)->check(m,p)|_->false))inletself_canonical()=check(m,p)inlethidden=Cpath.is_resolved_module_hidden~weak_canonical_test:truepinhidden||self_canonical()|Alias(_,_)->false|ModuleType_->trueinifexpandedthen`Resolvedrpelse`Resolved(process_module_pathenv~add_canonical:falsemrp)andhandle_canonical_module_typeenv(p2:Cpath.module_type)=letstrip_alias:Cpath.Resolved.module_type->Cpath.Resolved.module_type=function|`AliasModuleType(_,p)->p|p->pinletresolveenvp=resolve_module_typeenv~mark_substituted:false~add_canonical:falsep>>=fun(p,m)->Ok(strip_aliasp,m)inletlang_ofcpath=(Lang_of.(Path.resolved_module_type(empty())cpath):>Odoc_model.Paths.Path.Resolved.t)inmatchcanonical_helperenvresolvelang_ofc_modty_possp2with|None->p2|Some(rp,_)->`Resolvedrpandhandle_canonical_typeenv(p2:Cpath.type_)=letlang_ofcpath=(Lang_of.(Path.resolved_type(empty())cpath):>Odoc_model.Paths.Path.Resolved.t)inletresolveenvp=matchresolve_typeenv~add_canonical:falsepwith|Ok(_,`FType_removed_)->Error`Find_failure|Ok(x,y)->Ok(x,y)|Errory->Erroryinmatchcanonical_helperenvresolvelang_ofc_ty_possp2with|None->p2|Some(rp,_)->`Resolvedrpandreresolve_module_type:Env.t->Cpath.Resolved.module_type->Cpath.Resolved.module_type=funenvpath->matchpathwith|`Local_|`Identifier_->path|`Substitutedx->`Substituted(reresolve_module_typeenvx)|`ModuleType(parent,name)->`ModuleType(reresolve_parentenvparent,name)|`CanonicalModuleType(p1,`Resolvedp2)->`CanonicalModuleType(reresolve_module_typeenvp1,`Resolved(reresolve_module_typeenvp2))|`CanonicalModuleType(p1,p2)->`CanonicalModuleType(reresolve_module_typeenvp1,handle_canonical_module_typeenvp2)|`SubstT(p1,p2)->`SubstT(reresolve_module_typeenvp1,reresolve_module_typeenvp2)|`AliasModuleType(p1,p2)->`AliasModuleType(reresolve_module_typeenvp1,reresolve_module_typeenvp2)|`OpaqueModuleTypem->`OpaqueModuleType(reresolve_module_typeenvm)andreresolve_type:Env.t->Cpath.Resolved.type_->Cpath.Resolved.type_=funenvpath->letresult=matchpathwith|`Identifier_|`Local_->path|`Substituteds->`Substituted(reresolve_typeenvs)|`CanonicalType(p1,p2)->`CanonicalType(reresolve_typeenvp1,handle_canonical_typeenvp2)|`Type(p,n)->`Type(reresolve_parentenvp,n)|`Class(p,n)->`Class(reresolve_parentenvp,n)|`ClassType(p,n)->`ClassType(reresolve_parentenvp,n)inresultandreresolve_class_type:Env.t->Cpath.Resolved.class_type->Cpath.Resolved.class_type=funenvpath->letresult=matchpathwith|`Identifier_|`Local_->path|`Substituteds->`Substituted(reresolve_class_typeenvs)|`Class(p,n)->`Class(reresolve_parentenvp,n)|`ClassType(p,n)->`ClassType(reresolve_parentenvp,n)inresultandreresolve_parent:Env.t->Cpath.Resolved.parent->Cpath.Resolved.parent=funenvpath->matchpathwith|`Modulem->`Module(reresolve_moduleenvm)|`ModuleTypemty->`ModuleType(reresolve_module_typeenvmty)|`FragmentRoot->path(* *)andmodule_type_expr_of_module_decl:Env.t->Component.Module.decl->(Component.ModuleType.expr,simple_module_type_expr_of_module_error)Result.result=funenvdecl->matchdeclwith|Component.Module.Alias(`Resolvedr,_)->lookup_module~mark_substituted:falseenvr|>map_error(fune->`Parent(`Parent_modulee))>>=funm->letm=Component.Delayed.getminmodule_type_expr_of_module_declenvm.type_|Component.Module.Alias(path,_)->(matchresolve_module~mark_substituted:false~add_canonical:trueenvpathwith|Ok(_,m)->letm=Component.Delayed.getminmodule_type_expr_of_moduleenvm|Error_whenCpath.is_module_forwardpath->Error`UnresolvedForwardPath|Errore->Error(`UnresolvedPath(`Module(path,e))))|Component.Module.ModuleTypeexpr->Okexprandmodule_type_expr_of_module:Env.t->Component.Module.t->(Component.ModuleType.expr,simple_module_type_expr_of_module_error)Result.result=funenvm->module_type_expr_of_module_declenvm.type_andsignature_of_module_path:Env.t->strengthen:bool->Cpath.module_->(Component.Signature.t,signature_of_module_error)Result.result=funenv~strengthenpath->matchresolve_module~mark_substituted:true~add_canonical:trueenvpathwith|Ok(p',m)->letm=Component.Delayed.getmin(* p' is the path to the aliased module *)letstrengthen=strengthen&¬(Cpath.is_resolved_module_hidden~weak_canonical_test:truep')insignature_of_module_cachedenvp'm>>=funsg->ifstrengthenthenOk(Strengthen.signature(`Resolvedp')sg)elseOksg|Error_whenCpath.is_module_forwardpath->Error`UnresolvedForwardPath|Errore->Error(`UnresolvedPath(`Module(path,e)))andhandle_signature_with_subs:mark_substituted:bool->Env.t->Component.Signature.t->Component.ModuleType.substitutionlist->(Component.Signature.t,signature_of_module_error)Result.result=fun~mark_substitutedenvsgsubs->letopenResultMonadinList.fold_left(funsg_optsub->sg_opt>>=funsg->fragmap~mark_substitutedenvsubsg)(Oksg)subsandsignature_of_u_module_type_expr:mark_substituted:bool->Env.t->Component.ModuleType.U.expr->(Component.Signature.t,signature_of_module_error)Result.result=fun~mark_substitutedenvm->matchmwith|Component.ModuleType.U.Pathp->(matchresolve_module_type~mark_substituted~add_canonical:trueenvpwith|Ok(_,mt)->signature_of_module_typeenvmt|Errore->Error(`UnresolvedPath(`ModuleType(p,e))))|Signatures->Oks|With(subs,s)->signature_of_u_module_type_expr~mark_substitutedenvs>>=funsg->handle_signature_with_subs~mark_substitutedenvsgsubs|TypeOf{t_expansion=Some(Signaturesg);_}->Oksg|TypeOf{t_desc;_}->Error(`UnexpandedTypeOft_desc)andsignature_of_simple_expansion:Component.ModuleType.simple_expansion->Component.Signature.t=function|Signaturesg->sg|Functor(_,e)->signature_of_simple_expansioneandsignature_of_module_type_expr:mark_substituted:bool->Env.t->Component.ModuleType.expr->(Component.Signature.t,signature_of_module_error)Result.result=fun~mark_substitutedenvm->matchmwith|Component.ModuleType.Path{p_expansion=Somee;_}->Ok(signature_of_simple_expansione)|Component.ModuleType.Path{p_path;_}->(matchresolve_module_type~mark_substituted~add_canonical:trueenvp_pathwith|Ok(_,mt)->signature_of_module_typeenvmt|Errore->Error(`UnresolvedPath(`ModuleType(p_path,e))))|Component.ModuleType.Signatures->Oks(* | Component.ModuleType.With { w_expansion = Some e; _ } ->
Ok (signature_of_simple_expansion e)
Recalculate 'With' expressions always, as we need to know which
items have been removed
*)|Component.ModuleType.With{w_substitutions;w_expr;_}->signature_of_u_module_type_expr~mark_substitutedenvw_expr>>=funsg->handle_signature_with_subs~mark_substitutedenvsgw_substitutions|Component.ModuleType.Functor(Unit,expr)->signature_of_module_type_expr~mark_substitutedenvexpr|Component.ModuleType.Functor(Namedarg,expr)->ignorearg;signature_of_module_type_expr~mark_substitutedenvexpr|Component.ModuleType.TypeOf{t_expansion=Somee;_}->Ok(signature_of_simple_expansione)|Component.ModuleType.TypeOf{t_desc;_}->Error(`UnexpandedTypeOft_desc)andsignature_of_module_type:Env.t->Component.ModuleType.t->(Component.Signature.t,signature_of_module_error)Result.result=funenvm->matchm.exprwith|None->Error`OpaqueModule|Someexpr->signature_of_module_type_expr~mark_substituted:falseenvexprandsignature_of_module_decl:Env.t->Component.Module.decl->(Component.Signature.t,signature_of_module_error)Result.result=funenvdecl->matchdeclwith|Component.Module.Alias(_,Somee)->Ok(signature_of_simple_expansione)|Component.Module.Alias(p,_)->signature_of_module_pathenv~strengthen:truep|Component.Module.ModuleTypeexpr->signature_of_module_type_expr~mark_substituted:falseenvexprandsignature_of_module:Env.t->Component.Module.t->(Component.Signature.t,signature_of_module_error)Result.result=funenvm->signature_of_module_declenvm.type_andsignature_of_module_cached:Env.t->Cpath.Resolved.module_->Component.Module.t->(Component.Signature.t,signature_of_module_error)Result.result=funenv'pathm->letid=pathinletrunenv_id=signature_of_moduleenvminSignatureOfModuleMemo.memoizerunenv'idandumty_of_mty:Component.ModuleType.expr->Component.ModuleType.U.expr=function|Signaturesg->Signaturesg|Path{p_path;_}->Pathp_path|TypeOft->TypeOft|With{w_substitutions;w_expr;_}->With(w_substitutions,w_expr)|Functor_->assertfalseandfragmap:mark_substituted:bool->Env.t->Component.ModuleType.substitution->Component.Signature.t->(Component.Signature.t,signature_of_module_error)Result.result=fun~mark_substitutedenvsubsg->(* Used when we haven't finished the substitution. For example, if the
substitution is `M.t = u`, this function is used to map the declaration
of `M` to be `M : ... with type t = u` *)letmap_module_decldeclsubst=letopenComponent.Moduleinmatchdeclwith|Alias(path,_)->signature_of_module_pathenv~strengthen:truepath>>=funsg->Ok(ModuleType(With{w_substitutions=[subst];w_expansion=None;w_expr=TypeOf{t_desc=StructIncludepath;t_expansion=Some(Signaturesg);};}))|ModuleTypemty'->Ok(ModuleType(With{w_substitutions=[subst];w_expansion=None;w_expr=umty_of_mtymty';}))inletmap_include_decldeclsubst=letopenComponent.Includeinmatchdeclwith|Aliasp->signature_of_module_pathenv~strengthen:truep>>=funsg->fragmap~mark_substitutedenvsubstsg>>=funsg->Ok(ModuleType(Signaturesg))|ModuleTypemty'->Ok(ModuleType(With([subst],mty')))inletmap_modulemnew_subst=letopenComponent.Moduleinmap_module_declm.type_new_subst>>=funtype_->Ok(Left{mwithtype_})inletrecmap_signaturemapitems=List.fold_right(funitemacc->acc>>=fun(items,handled,subbed_modules,removed)->match(item,map)with|Component.Signature.Type(id,r,t),{type_=Some(id',fn);_}whenIdent.Name.type_id=id'->(fn(Component.Delayed.gett)>>=function|Leftx->Ok(Component.Signature.Type(id,r,Component.Delayed.put(fun()->x))::items,true,subbed_modules,removed)|Right(texpr,eq)->Ok(items,true,subbed_modules,Component.Signature.RType(id,texpr,eq)::removed))|Component.Signature.Module(id,r,m),{module_=Some(id',fn);_}whenIdent.Name.module_id=id'->(fn(Component.Delayed.getm)>>=function|Leftx->Ok(Component.Signature.Module(id,r,Component.Delayed.put(fun()->x))::items,true,id::subbed_modules,removed)|Righty->Ok(items,true,subbed_modules,Component.Signature.RModule(id,y)::removed))|Component.Signature.Include({expansion_;_}asi),_->map_signaturemapexpansion_.items>>=fun(items',handled',subbed_modules',removed')->letcomponent=ifhandled'thenmap_include_decli.declsub>>=fundecl->letexpansion_=Component.Signature.{expansion_withitems=items';removed=removed';compiled=false;}inOk(Component.Signature.Include{iwithdecl;expansion_;strengthened=None})elseOkitemincomponent>>=func->Ok(c::items,handled'||handled,subbed_modules'@subbed_modules,removed'@removed)|(Component.Signature.ModuleType(id,mt),{module_type=Some(id',fn);_})whenIdent.Name.module_typeid=id'->(fn(Component.Delayed.getmt)>>=function|Leftx->Ok(Component.Signature.ModuleType(id,Component.Delayed.put(fun()->x))::items,true,subbed_modules,removed)|Righty->Ok(items,true,subbed_modules,Component.Signature.RModuleType(id,y)::removed))|x,_->Ok(x::items,handled,subbed_modules,removed))items(Ok([],false,[],[]))inlethandle_intermediatenamenew_subst=letmodmaps=Some(name,funm->map_modulemnew_subst)inmap_signature{id_mapwithmodule_=modmaps}sg.itemsinletnew_sg=matchsubwith|ModuleEq(frag,type_)->(matchCfrag.module_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.ModuleEq(frag',type_)inhandle_intermediatenamenew_subst|name,None->letmapfnm=lettype_=letopenComponent.Moduleinmatchtype_with|Alias(`Resolvedp,_)->letnew_p=ifmark_substitutedthen`SubstitutedpelsepinAlias(`Resolvednew_p,None)|Alias_|ModuleType_->type_inOk(Left{mwithComponent.Module.type_})inmap_signature{id_mapwithmodule_=Some(name,mapfn)}sg.items)|ModuleSubst(frag,p)->(matchCfrag.module_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.ModuleSubst(frag',p)inhandle_intermediatenamenew_subst|name,None->letmapfn_=matchresolve_module~mark_substituted~add_canonical:falseenvpwith|Ok(p,_)->Ok(Rightp)|Errore->Format.fprintfFormat.err_formatter"failed to resolve path: %a\n%!"Component.Fmt.module_pathp;Error(`UnresolvedPath(`Module(p,e)))inmap_signature{id_mapwithmodule_=Some(name,mapfn)}sg.items)|ModuleTypeEq(frag,mtye)->(matchCfrag.module_type_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.ModuleTypeEq(frag',mtye)inhandle_intermediatenamenew_subst|name,None->letmapfnt=Ok(Left{twithComponent.ModuleType.expr=Somemtye})inmap_signature{id_mapwithmodule_type=Some(name,mapfn)}sg.items)|ModuleTypeSubst(frag,mtye)->(matchCfrag.module_type_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.ModuleTypeSubst(frag',mtye)inhandle_intermediatenamenew_subst|name,None->letmapfn_t=Ok(Rightmtye)inmap_signature{id_mapwithmodule_type=Some(name,mapfn)}sg.items)|TypeEq(frag,equation)->(matchCfrag.type_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.TypeEq(frag',equation)inhandle_intermediatenamenew_subst|name,None->letmapfnt=Ok(Left{twithComponent.TypeDecl.equation})inmap_signature{id_mapwithtype_=Some(name,mapfn)}sg.items)|TypeSubst(frag,({Component.TypeDecl.Equation.manifest=Somex;_}asequation))->(matchCfrag.type_splitfragwith|name,Somefrag'->letnew_subst=Component.ModuleType.TypeSubst(frag',equation)inhandle_intermediatenamenew_subst|name,None->letmapfn_t=Ok(Right(x,equation))inmap_signature{id_mapwithtype_=Some(name,mapfn)}sg.items)|TypeSubst(_,{Component.TypeDecl.Equation.manifest=None;_})->failwith"Unhandled condition: TypeSubst with no manifest"innew_sg>>=fun(items,_handled,subbed_modules,removed)->letsub_of_removedremovedsub=matchremovedwith|Component.Signature.RModule(id,p)->Subst.add_module(id:>Ident.path_module)(`Resolvedp)psub|Component.Signature.RType(id,r_texpr,r_eq)->Subst.add_type_replacement(id:>Ident.path_type)r_texprr_eqsub|Component.Signature.RModuleType(id,e)->Subst.add_module_type_replacement(id:>Ident.module_type)esubinletsub=List.fold_rightsub_of_removedremovedSubst.identityinletmap_itemsitems=(* Invalidate resolved paths containing substituted idents - See the `With11`
test for an example of why this is necessary *)letsub_of_substitutedxsub=letx=(x:>Ident.path_module)in(ifmark_substitutedthenSubst.add_module_substitutionxsubelsesub)|>Subst.path_invalidate_modulex|>Subst.mto_invalidate_modulexinletsubstituted_sub=List.fold_rightsub_of_substitutedsubbed_modulesSubst.identityin(* Need to call `apply_sig_map` directly as we're substituting for an item
that's declared within the signature *)letitems,_,_=Subst.apply_sig_mapsubstituted_subitems[]in(* Finished marking substituted stuff *)itemsinletitems=map_itemsitemsinletres=Subst.signaturesub{Component.Signature.items;removed=removed@sg.removed;compiled=false;doc=sg.doc;}inOkresandfind_external_module_path:Cpath.Resolved.module_->Cpath.Resolved.module_option=funp->letopenOptionMonadinmatchpwith|`Subst(x,y)->find_external_module_type_pathx>>=funx->find_external_module_pathy>>=funy->Some(`Subst(x,y))|`Module(p,n)->find_external_parent_pathp>>=funp->Some(`Module(p,n))|`Localx->Some(`Localx)|`Substitutedx->find_external_module_pathx>>=funx->Some(`Substitutedx)|`Canonical(x,y)->find_external_module_pathx>>=funx->Some(`Canonical(x,y))|`Hiddenx->find_external_module_pathx>>=funx->Some(`Hiddenx)|`Alias(x,y)->(match(find_external_module_pathx,find_external_module_pathy)with|Somex,Somey->Some(`Alias(x,y))|Somex,None->Somex|None,Somex->Somex|None,None->None)|`Apply(x,y)->find_external_module_pathx>>=funx->find_external_module_pathy>>=funy->Some(`Apply(x,y))|`Identifierx->Some(`Identifierx)|`OpaqueModulem->find_external_module_pathm>>=funx->Some(`OpaqueModulex)andfind_external_module_type_path:Cpath.Resolved.module_type->Cpath.Resolved.module_typeoption=funp->letopenOptionMonadinmatchpwith|`ModuleType(p,name)->find_external_parent_pathp>>=funp->Some(`ModuleType(p,name))|`Local_->Somep|`SubstT(x,y)->find_external_module_type_pathx>>=funx->find_external_module_type_pathy>>=funy->Some(`SubstT(x,y))|`CanonicalModuleType(x,_)|`Substitutedx->find_external_module_type_pathx>>=funx->Some(`Substitutedx)|`Identifier_->Somep|`AliasModuleType(x,y)->(match(find_external_module_type_pathx,find_external_module_type_pathy)with|Somex,Somey->Some(`AliasModuleType(x,y))|Somex,None->Somex|None,Somex->Somex|None,None->None)|`OpaqueModuleTypem->find_external_module_type_pathm>>=funx->Some(`OpaqueModuleTypex)andfind_external_parent_path:Cpath.Resolved.parent->Cpath.Resolved.parentoption=funp->letopenOptionMonadinmatchpwith|`Modulem->find_external_module_pathm>>=funm->Some(`Modulem)|`ModuleTypem->find_external_module_type_pathm>>=funm->Some(`ModuleTypem)|`FragmentRoot->Noneandfixup_module_cfrag(f:Cfrag.resolved_module):Cfrag.resolved_module=matchfwith|`Subst(path,frag)->(matchfind_external_module_type_pathpathwith|Somep->`Subst(p,frag)|None->frag)|`Alias(path,frag)->(matchfind_external_module_pathpathwith|Somep->`Alias(p,frag)|None->frag)|`Module(parent,name)->`Module(fixup_signature_cfragparent,name)|`OpaqueModulem->`OpaqueModule(fixup_module_cfragm)andfixup_module_type_cfrag(f:Cfrag.resolved_module_type):Cfrag.resolved_module_type=matchfwith|`ModuleType(parent,name)->`ModuleType(fixup_signature_cfragparent,name)andfixup_signature_cfrag(f:Cfrag.resolved_signature)=matchfwith|`Rootx->`Rootx|(`OpaqueModule_|`Subst_|`Alias_|`Module_)asf->(fixup_module_cfragf:>Cfrag.resolved_signature)andfixup_type_cfrag(f:Cfrag.resolved_type):Cfrag.resolved_type=matchfwith|`Type(p,x)->`Type(fixup_signature_cfragp,x)|`Class(p,x)->`Class(fixup_signature_cfragp,x)|`ClassType(p,x)->`ClassType(fixup_signature_cfragp,x)andfind_module_with_replacement:Env.t->Component.Signature.t->string->(Component.Module.tComponent.Delayed.t,simple_module_lookup_error)Result.result=funenvsgname->matchFind.careful_module_in_sigsgnamewith|Some(`FModule(_,m))->Ok(Component.Delayed.put_valm)|Some(`FModule_removedpath)->lookup_module~mark_substituted:falseenvpath|None->Error`Find_failureandfind_module_type_with_replacement:Env.t->Component.Signature.t->string->(Component.ModuleType.tComponent.Delayed.t,simple_module_type_lookup_error)Result.result=fun_envsgname->matchFind.careful_module_type_in_sigsgnamewith|Some(`FModuleType(_,m))->Ok(Component.Delayed.put_valm)|None->Error`Find_failure|Some(`FModuleType_removed_mty)->Error`Find_failureandresolve_signature_fragment:Env.t->Cfrag.root*Component.Signature.t->Cfrag.signature->(Cfrag.resolved_signature*Cpath.Resolved.parent*Component.Signature.t)option=funenv(p,sg)frag->matchfragwith|`Root->letsg=prefix_signature(`FragmentRoot,sg)inSome(`Rootp,`FragmentRoot,sg)|`Resolved_r->None|`Dot(parent,name)->letopenOptionMonadinresolve_signature_fragmentenv(p,sg)parent>>=fun(pfrag,ppath,sg)->of_result(find_module_with_replacementenvsgname)>>=funm'->letmname=ModuleName.make_stdnameinletnew_path=`Module(ppath,mname)inletnew_frag=`Module(pfrag,mname)inletm'=Component.Delayed.getm'inletmodifier=get_module_path_modifiersenv~add_canonical:falsem'inletcp',f'=matchmodifierwith|None->(new_path,new_frag)|Some(`Aliasedp')->(`Alias(p',new_path),`Alias(p',new_frag))|Some(`SubstMTp')->(`Subst(p',new_path),`Subst(p',new_frag))in(* Don't use the cached one - `FragmentRoot` is not unique *)of_result(signature_of_moduleenvm')>>=funparent_sg->letsg=prefix_signature(`Modulecp',parent_sg)inSome(f',`Modulecp',sg)andresolve_module_fragment:Env.t->Cfrag.root*Component.Signature.t->Cfrag.module_->Cfrag.resolved_moduleoption=funenv(p,sg)frag->matchfragwith|`Resolvedr->Somer|`Dot(parent,name)->letopenOptionMonadinresolve_signature_fragmentenv(p,sg)parent>>=fun(pfrag,_ppath,sg)->of_result(find_module_with_replacementenvsgname)>>=funm'->letmname=ModuleName.make_stdnameinletnew_frag=`Module(pfrag,mname)inletm'=Component.Delayed.getm'inletmodifier=get_module_path_modifiersenv~add_canonical:falsem'inletf'=matchmodifierwith|None->new_frag|Some(`Aliasedp')->`Alias(p',new_frag)|Some(`SubstMTp')->`Subst(p',new_frag)inletf''=matchsignature_of_moduleenvm'with|Ok(_m:Component.Signature.t)->f'|Error`OpaqueModule->`OpaqueModulef'|Error(`UnresolvedForwardPath|`UnresolvedPath_)->f'|Error(`UnexpandedTypeOf_)->f'inSome(fixup_module_cfragf'')andresolve_module_type_fragment:Env.t->Cfrag.root*Component.Signature.t->Cfrag.module_type->Cfrag.resolved_module_typeoption=funenv(p,sg)frag->matchfragwith|`Resolvedr->Somer|`Dot(parent,name)->letopenOptionMonadinresolve_signature_fragmentenv(p,sg)parent>>=fun(pfrag,_ppath,sg)->of_result(find_module_type_with_replacementenvsgname)>>=funmt'->letmtname=ModuleTypeName.make_stdnameinletf'=`ModuleType(pfrag,mtname)inletm'=Component.Delayed.getmt'inletf''=matchsignature_of_module_typeenvm'with|Ok(_m:Component.Signature.t)->f'|Error(`UnresolvedForwardPath|`UnresolvedPath_|`OpaqueModule|`UnexpandedTypeOf_)->f'inSome(fixup_module_type_cfragf'')andresolve_type_fragment:Env.t->Cfrag.root*Component.Signature.t->Cfrag.type_->Cfrag.resolved_typeoption=funenv(p,sg)frag->matchfragwith|`Resolvedr->Somer|`Dot(parent,name)->letopenOptionMonadinresolve_signature_fragmentenv(p,sg)parent>>=fun(pfrag,_ppath,_sg)->letresult=fixup_type_cfrag(`Type(pfrag,TypeName.make_stdname))inSomeresultletrecreresolve_signature_fragment:Env.t->Cfrag.resolved_signature->Cfrag.resolved_signature=funenvm->matchmwith|`Root(`ModuleTypep)->`Root(`ModuleType(reresolve_module_typeenvp))|`Root(`Modulep)->`Root(`Module(reresolve_moduleenvp))|(`OpaqueModule_|`Subst_|`Alias_|`Module_)asx->(reresolve_module_fragmentenvx:>Cfrag.resolved_signature)andreresolve_module_fragment:Env.t->Cfrag.resolved_module->Cfrag.resolved_module=funenvm->matchmwith|`Subst(p,f)->letp'=reresolve_module_typeenvpin`Subst(p',reresolve_module_fragmentenvf)|`Alias(p,f)->letp'=reresolve_moduleenvpin`Alias(p',reresolve_module_fragmentenvf)|`OpaqueModulem->`OpaqueModule(reresolve_module_fragmentenvm)|`Module(sg,m)->`Module(reresolve_signature_fragmentenvsg,m)andreresolve_type_fragment:Env.t->Cfrag.resolved_type->Cfrag.resolved_type=funenvm->matchmwith|`Type(p,n)->`Type(reresolve_signature_fragmentenvp,n)|`ClassType(p,n)->`ClassType(reresolve_signature_fragmentenvp,n)|`Class(p,n)->`Class(reresolve_signature_fragmentenvp,n)andreresolve_module_type_fragment:Env.t->Cfrag.resolved_module_type->Cfrag.resolved_module_type=funenvm->matchmwith|`ModuleType(p,n)->`ModuleType(reresolve_signature_fragmentenvp,n)letrecclass_signature_of_class:Env.t->Component.Class.t->Component.ClassSignature.toption=funenvc->letrecinnerdecl=matchdeclwith|Component.Class.ClassTypee->class_signature_of_class_type_exprenve|Arrow(_,_,d)->innerdininnerc.type_andclass_signature_of_class_type_expr:Env.t->Component.ClassType.expr->Component.ClassSignature.toption=funenve->matchewith|Signatures->Somes|Constr(p,_)->(matchresolve_typeenv~add_canonical:true(p:>Cpath.type_)with|Ok(_,`FClass(_,c))->class_signature_of_classenvc|Ok(_,`FClassType(_,c))->class_signature_of_class_typeenvc|_->None)andclass_signature_of_class_type:Env.t->Component.ClassType.t->Component.ClassSignature.toption=funenvc->class_signature_of_class_type_exprenvc.exprletresolve_module_pathenvp=resolve_module~mark_substituted:true~add_canonical:trueenvp>>=fun(p,m)->matchpwith|`Identifier(`Root_)|`Hidden(`Identifier(`Root_))->Okp|_->(letm=Component.Delayed.getminmatchsignature_of_module_cachedenvpmwith|Ok_->Okp|Error`OpaqueModule->Ok(`OpaqueModulep)|Error(`UnresolvedForwardPath|`UnresolvedPath_)->Okp|Error(`UnexpandedTypeOf_)->Okp)letresolve_module_type_pathenvp=resolve_module_type~mark_substituted:true~add_canonical:trueenvp>>=fun(p,mt)->matchsignature_of_module_typeenvmtwith|Ok_->Okp|Error`OpaqueModule->Ok(`OpaqueModuleTypep)|Error(`UnresolvedForwardPath|`UnresolvedPath_)|Error(`UnexpandedTypeOf_)->Okpletresolve_type_pathenvp=resolve_typeenv~add_canonical:truep>>=fun(p,_)->Okpletresolve_class_type_pathenvp=resolve_class_typeenvp>>=fun(p,_)->Okp