123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291openUtils.ResultMonadopenOdoc_modelopenErrors.Tools_errortypeexpansion=|SignatureofComponent.Signature.t|FunctorofComponent.FunctorParameter.t*Component.ModuleType.exprletrecmodule_needs_recompile:Component.Module.t->bool=funm->module_decl_needs_recompilem.type_andmodule_decl_needs_recompile:Component.Module.decl->bool=function|Alias_->false|ModuleTypeexpr->module_type_expr_needs_recompileexprandmodule_type_expr_needs_recompile:Component.ModuleType.expr->bool=function|Path_->false|Signature_->false|With_->true|Functor(_,expr)->module_type_expr_needs_recompileexpr|TypeOf_->falseandmodule_type_needs_recompile:Component.ModuleType.t->bool=funm->matchm.exprwith|None->false|Someexpr->module_type_expr_needs_recompileexprletrecaux_expansion_of_module:Env.t->strengthen:bool->Component.Module.t->(expansion,signature_of_module_error)Result.result=letopenComponent.Moduleinfunenv~strengthenm->aux_expansion_of_module_declenv~strengthenm.type_andaux_expansion_of_module_declenv~strengthenty=letopenComponent.Moduleinmatchtywith|Alias(path,_)->aux_expansion_of_module_aliasenv~strengthenpath|ModuleTypeexpr->aux_expansion_of_module_type_exprenvexprandaux_expansion_of_module_aliasenv~strengthenpath=(* Format.eprintf "aux_expansion_of_module_alias (strengthen=%b, path=%a)\n%!"
strengthen Component.Fmt.module_path path; *)matchTools.resolve_moduleenv~mark_substituted:false~add_canonical:falsepathwith|Ok(p,m)->((* Don't strengthen if the alias is definitely hidden. We can't always resolve canonical
paths at this stage so use the weak canonical test that assumes all canonical paths
will resolve correctly *)letstrengthen=strengthen&¬(Cpath.is_resolved_module_hidden~weak_canonical_test:truep)inletm=Component.Delayed.getminmatch(aux_expansion_of_moduleenv~strengthen:truem,m.doc)with|(Error_ase),_->e|Ok(Signaturesg),[]->(* Format.eprintf "Maybe strenthening now...\n%!"; *)letsg'=ifstrengthenthenStrengthen.signature?canonical:m.canonical(`Resolvedp)sgelsesginOk(Signaturesg')|Ok(Signaturesg),docs->(* Format.eprintf "Maybe strenthening now...\n%!"; *)letsg'=ifstrengthenthenStrengthen.signature?canonical:m.canonical(`Resolvedp)sgelsesgin(* Format.eprintf "Before:\n%a\n\n%!After\n%a\n\n%!"
Component.Fmt.signature sg
Component.Fmt.signature sg'; *)Ok(Signature{sg'withitems=Comment(`Docsdocs)::sg'.items})|Ok(Functor_asx),_->Okx)|Errore->Error(`UnresolvedPath(`Module(path,e)))(* We need to reresolve fragments in expansions as the root of the fragment
may well change - so we turn resolved fragments back into unresolved ones
here *)andunresolve_subssubs=List.map(function|Component.ModuleType.ModuleEq(`Resolvedf,m)->Component.ModuleType.ModuleEq(Cfrag.unresolve_modulef,m)|ModuleSubst(`Resolvedf,m)->ModuleSubst(Cfrag.unresolve_modulef,m)|TypeEq(`Resolvedf,t)->TypeEq(Cfrag.unresolve_typef,t)|TypeSubst(`Resolvedf,t)->TypeSubst(Cfrag.unresolve_typef,t)|x->x)subsandaux_expansion_of_module_type_type_of_descenvt:(expansion,signature_of_module_error)Result.result=matchtwith|Component.ModuleType.ModPathp->aux_expansion_of_module_aliasenv~strengthen:falsep|StructIncludep->aux_expansion_of_module_aliasenv~strengthen:truepandassert_not_functor=functionSignaturesg->Oksg|_->assertfalseandaux_expansion_of_u_module_type_exprenvexpr:(Component.Signature.t,signature_of_module_error)Result.result=letopenUtils.ResultMonadinmatchexprwith|Component.ModuleType.U.Pathp->Tools.resolve_module_type~mark_substituted:false~add_canonical:trueenvp|>map_error(fune->`UnresolvedPath(`ModuleType(p,e)))>>=fun(_,mt)->aux_expansion_of_module_typeenvmt>>=assert_not_functor|Signaturesg->Oksg|With(subs,s)->aux_expansion_of_u_module_type_exprenvs>>=funsg->letsubs=unresolve_subssubsinTools.handle_signature_with_subs~mark_substituted:falseenvsgsubs|TypeOf{t_expansion=Some(Signaturesg);_}->Oksg|TypeOf{t_desc;_}->Error(`UnexpandedTypeOft_desc)andaux_expansion_of_module_type_exprenvexpr:(expansion,signature_of_module_error)Result.result=matchexprwith|Path{p_path;_}->Tools.resolve_module_type~mark_substituted:false~add_canonical:trueenvp_path|>map_error(fune->`UnresolvedPath(`ModuleType(p_path,e)))>>=fun(_,mt)->aux_expansion_of_module_typeenvmt|Signatures->Ok(Signatures)|With{w_substitutions;w_expr;_}->(aux_expansion_of_u_module_type_exprenvw_expr>>=funsg->letsubs=unresolve_subsw_substitutionsinTools.handle_signature_with_subs~mark_substituted:falseenvsgsubs)>>=funsg->Ok(Signaturesg)|Functor(arg,expr)->Ok(Functor(arg,expr))|TypeOf{t_expansion=Some(Signaturesg);_}->Ok(Signaturesg)|TypeOf{t_desc;_}->Error(`UnexpandedTypeOft_desc)andaux_expansion_of_module_typeenvmt=letopenComponent.ModuleTypeinmatchmt.exprwith|None->Error`OpaqueModule|Someexpr->aux_expansion_of_module_type_exprenvexprandhandle_expansionenvidexpansion=lethandle_argumentparentarg_optexprenv=(* If there's an argument, extend the environment with the argument, then
do the substitution on the signature to replace the local identifier with
the global one *)matcharg_optwith|Component.FunctorParameter.Unit->(env,expr)|Namedarg->letidentifier=`Parameter(parent,Ident.Name.typed_functor_parameterarg.Component.FunctorParameter.id)inletm=Component.module_of_functor_argumentarginletenv'=Env.add_moduleidentifier(Component.Delayed.put_valm)m.docenvinletsubst=Subst.add_module(arg.id:>Ident.path_module)(`Resolved(`Identifieridentifier))(`Identifieridentifier)Subst.identityinletsubst=Subst.mto_invalidate_module(arg.id:>Ident.path_module)substin(env',Subst.module_type_exprsubstexpr)inletrecexpandidenvexpansion:(Env.t*Component.ModuleType.simple_expansion,_)Result.result=matchexpansionwith|Signaturesg->Ok(env,(Component.ModuleType.Signaturesg:Component.ModuleType.simple_expansion))|Functor(arg,expr)->letenv',expr'=handle_argumentidargexprenvinaux_expansion_of_module_type_exprenv'expr'>>=funres->expand(`Resultid)envres>>=fun(env,res)->Ok(env,(Component.ModuleType.Functor(arg,res):Component.ModuleType.simple_expansion))inexpandidenvexpansionletexpansion_of_module_typeenvidm=letopenPaths.Identifierinaux_expansion_of_module_typeenvm>>=handle_expansionenv(id:ModuleType.t:>Signature.t)>>=fun(env,e)->Ok(env,module_type_needs_recompilem,e)letexpansion_of_module_type_exprenvidexpr=aux_expansion_of_module_type_exprenvexpr>>=handle_expansionenvid>>=fun(env,e)->Ok(env,module_type_expr_needs_recompileexpr,e)letexpansion_of_u_module_type_exprenvidexpr=aux_expansion_of_u_module_type_exprenvexpr>>=funsg->handle_expansionenvid(Signaturesg)>>=fun(env,e)->Ok(env,false,e)(* Nb. [strengthen=false] here because the only time we are ever expanding module aliases is when either
the module is the canonical one or it's an alias to a hidden module. In neither of these cases do we want
to strengthen. *)letexpansion_of_module_aliasenvidpath=letopenPaths.Identifierinaux_expansion_of_module_alias~strengthen:falseenvpath>>=handle_expansionenv(id:Module.t:>Signature.t)>>=fun(env,r)->Ok(env,false,r)letexpansion_of_module_type_of_descenvidt_desc=aux_expansion_of_module_type_type_of_descenvt_desc>>=handle_expansionenvidexceptionClashletrectype_exprmapt=letopenLang.TypeExprinmatchtwith|Varv->(tryList.assocvmapwith_->Format.eprintf"Failed to list assoc %s\n%!"v;failwith"bah")|Any->Any|Alias(t,s)->ifList.mem_assocsmapthenraiseClashelseAlias(type_exprmapt,s)|Arrow(l,t1,t2)->Arrow(l,type_exprmapt1,type_exprmapt2)|Tuplets->Tuple(List.map(type_exprmap)ts)|Constr(p,ts)->Constr(p,List.map(type_exprmap)ts)|Polymorphic_variantpv->Polymorphic_variant(polymorphic_variantmappv)|Objecto->Object(object_mapo)|Class(path,ts)->Class(path,List.map(type_exprmap)ts)|Poly(s,t)->Poly(s,type_exprmapt)|Packagep->Package(packagemapp)andpolymorphic_variantmappv=letopenLang.TypeExpr.Polymorphic_variantinletconstructorc={cwithConstructor.arguments=List.map(type_exprmap)c.Constructor.arguments;}inletelement=function|Typet->Type(type_exprmapt)|Constructorc->Constructor(constructorc)in{kind=pv.kind;elements=List.mapelementpv.elements}andobject_mapo=letopenLang.TypeExpr.Objectinletmethod_m={mwithtype_=type_exprmapm.type_}inletfield=function|Methodm->Method(method_m)|Inheritt->Inherit(type_exprmapt)in{owithfields=List.mapfieldo.fields}andpackagemapp=letopenLang.TypeExpr.Packageinletsubst(frag,t)=(frag,type_exprmapt)in{pwithsubstitutions=List.mapsubstp.substitutions}letcollapse_eqnseqn1eqn2params=letopenLang.TypeDeclinletmap=List.map2(funvp->matchv.descwithVarx->Some(x,p)|Any->None)eqn2.Equation.paramsparamsinletmap=List.fold_right(funxxs->matchxwithSomex->x::xs|None->xs)map[]in{eqn1withEquation.manifest=(matcheqn2.manifestwith|None->None|Somet->Some(type_exprmapt));}