123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1999 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)openAsttypesopenLocationopenLongidentopenParsetreemoduleString=Misc.Stdlib.Stringletpp_deps=ref[](* Module resolution map *)(* Node (set of imports for this path, map for submodules) *)typemap_tree=NodeofString.Set.t*bound_mapandbound_map=map_treeString.Map.tletbound=Node(String.Set.empty,String.Map.empty)(*let get_free (Node (s, _m)) = s*)letget_map(Node(_s,m))=mletmake_leafs=Node(String.Set.singletons,String.Map.empty)letmake_nodem=Node(String.Set.empty,m)letrecweaken_maps(Node(s0,m0))=Node(String.Set.unionss0,String.Map.map(weaken_maps)m0)letreccollect_free(Node(s,m))=String.Map.fold(fun_n->String.Set.union(collect_freen))ms(* Returns the imports required to access the structure at path p *)(* Only raises Not_found if the head of p is not in the toplevel map *)letreclookup_freepm=matchpwith[]->raiseNot_found|s::p->letNode(f,m')=String.Map.findsmintrylookup_freepm'withNot_found->f(* Returns the node corresponding to the structure at path p *)letreclookup_maplidm=matchlidwithLidents->String.Map.findsm|Ldot(l,s)->String.Map.finds(get_map(lookup_maplm))|Lapply_->raiseNot_found(* Collect free module identifiers in the a.s.t. *)letfree_structure_names=refString.Set.emptyletadd_namess=free_structure_names:=String.Set.unions!free_structure_namesletrecadd_pathbv?(p=[])=function|Lidents->letfree=trylookup_free(s::p)bvwithNot_found->String.Set.singletonsin(*String.Set.iter (fun s -> Printf.eprintf "%s " s) free;
prerr_endline "";*)add_namesfree|Ldot(l,s)->add_pathbv~p:(s::p)l|Lapply(l1,l2)->add_pathbvl1;add_pathbvl2letopen_modulebvlid=matchlookup_maplidbvwith|Node(s,m)->add_namess;String.Map.foldString.Map.addmbv|exceptionNot_found->add_pathbvlid;bvletadd_parentbvlid=matchlid.txtwithLdot(l,_s)->add_pathbvl|_->()letadd=add_parentletadd_module_pathbvlid=add_pathbvlid.txtlethandle_extensionext=match(fstext).txtwith|"error"|"ocaml.error"->raise(Location.Error(Builtin_attributes.error_of_extensionext))|_->()letrecadd_typebvty=matchty.ptyp_descwithPtyp_any->()|Ptyp_var_->()|Ptyp_arrow(_,t1,t2)->add_typebvt1;add_typebvt2|Ptyp_tupletl->List.iter(add_typebv)tl|Ptyp_constr(c,tl)->addbvc;List.iter(add_typebv)tl|Ptyp_object(fl,_)->List.iter(fun{pof_desc;_}->matchpof_descwith|Otag(_,t)->add_typebvt|Oinheritt->add_typebvt)fl|Ptyp_class(c,tl)->addbvc;List.iter(add_typebv)tl|Ptyp_alias(t,_)->add_typebvt|Ptyp_variant(fl,_,_)->List.iter(fun{prf_desc;_}->matchprf_descwith|Rtag(_,_,stl)->List.iter(add_typebv)stl|Rinheritsty->add_typebvsty)fl|Ptyp_poly(_,t)->add_typebvt|Ptyp_packagept->add_package_typebvpt|Ptyp_extensione->handle_extensioneandadd_package_typebv(lid,l)=addbvlid;List.iter(add_typebv)(List.map(fun(_,e)->e)l)letadd_optadd_fnbv=functionNone->()|Somex->add_fnbvxletadd_constructor_argumentsbv=function|Pcstr_tuplel->List.iter(add_typebv)l|Pcstr_recordl->List.iter(funl->add_typebvl.pld_type)lletadd_constructor_declbvpcd=add_constructor_argumentsbvpcd.pcd_args;Option.iter(add_typebv)pcd.pcd_resletadd_type_declarationbvtd=List.iter(fun(ty1,ty2,_)->add_typebvty1;add_typebvty2)td.ptype_cstrs;add_optadd_typebvtd.ptype_manifest;letadd_tkind=functionPtype_abstract->()|Ptype_variantcstrs->List.iter(add_constructor_declbv)cstrs|Ptype_recordlbls->List.iter(funpld->add_typebvpld.pld_type)lbls|Ptype_open->()inadd_tkindtd.ptype_kindletadd_extension_constructorbvext=matchext.pext_kindwithPext_decl(_,args,rty)->add_constructor_argumentsbvargs;Option.iter(add_typebv)rty|Pext_rebindlid->addbvlidletadd_type_extensionbvte=addbvte.ptyext_path;List.iter(add_extension_constructorbv)te.ptyext_constructorsletadd_type_exceptionbvte=add_extension_constructorbvte.ptyexn_constructorletpattern_bv=refString.Map.emptyletrecadd_patternbvpat=matchpat.ppat_descwithPpat_any->()|Ppat_var_->()|Ppat_alias(p,_)->add_patternbvp|Ppat_interval_|Ppat_constant_->()|Ppat_tuplepl->List.iter(add_patternbv)pl|Ppat_construct(c,opt)->addbvc;add_opt(funbv(_,p)->add_patternbvp)bvopt|Ppat_record(pl,_)->List.iter(fun(lbl,p)->addbvlbl;add_patternbvp)pl|Ppat_arraypl->List.iter(add_patternbv)pl|Ppat_or(p1,p2)->add_patternbvp1;add_patternbvp2|Ppat_constraint(p,ty)->add_patternbvp;add_typebvty|Ppat_variant(_,op)->add_optadd_patternbvop|Ppat_typeli->addbvli|Ppat_lazyp->add_patternbvp|Ppat_unpackid->Option.iter(funname->pattern_bv:=String.Map.addnamebound!pattern_bv)id.txt|Ppat_open(m,p)->letbv=open_modulebvm.txtinadd_patternbvp|Ppat_exceptionp->add_patternbvp|Ppat_extensione->handle_extensioneletadd_patternbvpat=pattern_bv:=bv;add_patternbvpat;!pattern_bvletrecadd_exprbvexp=matchexp.pexp_descwithPexp_identl->addbvl|Pexp_constant_->()|Pexp_let(rf,pel,e)->letbv=add_bindingsrfbvpelinadd_exprbve|Pexp_fun(_,opte,p,e)->add_optadd_exprbvopte;add_expr(add_patternbvp)e|Pexp_functionpel->add_casesbvpel|Pexp_apply(e,el)->add_exprbve;List.iter(fun(_,e)->add_exprbve)el|Pexp_match(e,pel)->add_exprbve;add_casesbvpel|Pexp_try(e,pel)->add_exprbve;add_casesbvpel|Pexp_tupleel->List.iter(add_exprbv)el|Pexp_construct(c,opte)->addbvc;add_optadd_exprbvopte|Pexp_variant(_,opte)->add_optadd_exprbvopte|Pexp_record(lblel,opte)->List.iter(fun(lbl,e)->addbvlbl;add_exprbve)lblel;add_optadd_exprbvopte|Pexp_field(e,fld)->add_exprbve;addbvfld|Pexp_setfield(e1,fld,e2)->add_exprbve1;addbvfld;add_exprbve2|Pexp_arrayel->List.iter(add_exprbv)el|Pexp_ifthenelse(e1,e2,opte3)->add_exprbve1;add_exprbve2;add_optadd_exprbvopte3|Pexp_sequence(e1,e2)->add_exprbve1;add_exprbve2|Pexp_while(e1,e2)->add_exprbve1;add_exprbve2|Pexp_for(_,e1,e2,_,e3)->add_exprbve1;add_exprbve2;add_exprbve3|Pexp_coerce(e1,oty2,ty3)->add_exprbve1;add_optadd_typebvoty2;add_typebvty3|Pexp_constraint(e1,ty2)->add_exprbve1;add_typebvty2|Pexp_send(e,_m)->add_exprbve|Pexp_newli->addbvli|Pexp_setinstvar(_v,e)->add_exprbve|Pexp_overridesel->List.iter(fun(_s,e)->add_exprbve)sel|Pexp_letmodule(id,m,e)->letb=add_module_bindingbvminletbv=matchid.txtwith|None->bv|Someid->String.Map.addidbbvinadd_exprbve|Pexp_letexception(_,e)->add_exprbve|Pexp_assert(e)->add_exprbve|Pexp_lazy(e)->add_exprbve|Pexp_poly(e,t)->add_exprbve;add_optadd_typebvt|Pexp_object{pcstr_self=pat;pcstr_fields=fieldl}->letbv=add_patternbvpatinList.iter(add_class_fieldbv)fieldl|Pexp_newtype(_,e)->add_exprbve|Pexp_packm->add_module_exprbvm|Pexp_open(o,e)->letbv=open_declarationbvoinadd_exprbve|Pexp_letop{let_;ands;body}->letbv'=add_binding_opbvbvlet_inletbv'=List.fold_left(add_binding_opbv)bv'andsinadd_exprbv'body|Pexp_extension(({txt=("ocaml.extension_constructor"|"extension_constructor");_},PStr[item])ase)->beginmatchitem.pstr_descwith|Pstr_eval({pexp_desc=Pexp_construct(c,None)},_)->addbvc|_->handle_extensioneend|Pexp_extensione->handle_extensione|Pexp_unreachable->()andadd_casesbvcases=List.iter(add_casebv)casesandadd_casebv{pc_lhs;pc_guard;pc_rhs}=letbv=add_patternbvpc_lhsinadd_optadd_exprbvpc_guard;add_exprbvpc_rhsandadd_bindingsrecfbvpel=letbv'=List.fold_left(funbvx->add_patternbvx.pvb_pat)bvpelinletbv=ifrecf=Recursivethenbv'elsebvinList.iter(funx->add_exprbvx.pvb_expr)pel;bv'andadd_binding_opbvbv'pbop=add_exprbvpbop.pbop_exp;add_patternbv'pbop.pbop_patandadd_modtypebvmty=matchmty.pmty_descwithPmty_identl->addbvl|Pmty_aliasl->add_module_pathbvl|Pmty_signatures->add_signaturebvs|Pmty_functor(param,mty2)->letbv=matchparamwith|Unit->bv|Named(id,mty1)->add_modtypebvmty1;matchid.txtwith|None->bv|Somename->String.Map.addnameboundbvinadd_modtypebvmty2|Pmty_with(mty,cstrl)->add_modtypebvmty;List.iter(function|Pwith_type(_,td)->add_type_declarationbvtd|Pwith_module(_,lid)->add_module_pathbvlid|Pwith_modtype(_,mty)->add_modtypebvmty|Pwith_typesubst(_,td)->add_type_declarationbvtd|Pwith_modsubst(_,lid)->add_module_pathbvlid|Pwith_modtypesubst(_,mty)->add_modtypebvmty)cstrl|Pmty_typeofm->add_module_exprbvm|Pmty_extensione->handle_extensioneandadd_module_aliasbvl=(* If we are in delayed dependencies mode, we delay the dependencies
induced by "Lident s" *)(if!Clflags.transparent_modulesthenadd_parentelseadd_module_path)bvl;trylookup_mapl.txtbvwithNot_found->matchl.txtwithLidents->make_leafs|_->add_module_pathbvl;bound(* cannot delay *)andadd_modtype_bindingbvmty=matchmty.pmty_descwithPmty_aliasl->add_module_aliasbvl|Pmty_signatures->make_node(add_signature_bindingbvs)|Pmty_typeofmodl->add_module_bindingbvmodl|_->add_modtypebvmty;boundandadd_signaturebvsg=ignore(add_signature_bindingbvsg)andadd_signature_bindingbvsg=snd(List.fold_leftadd_sig_item(bv,String.Map.empty)sg)andadd_sig_item(bv,m)item=matchitem.psig_descwithPsig_valuevd->add_typebvvd.pval_type;(bv,m)|Psig_type(_,dcls)|Psig_typesubstdcls->List.iter(add_type_declarationbv)dcls;(bv,m)|Psig_typextte->add_type_extensionbvte;(bv,m)|Psig_exceptionte->add_type_exceptionbvte;(bv,m)|Psig_modulepmd->letm'=add_modtype_bindingbvpmd.pmd_typeinletaddmap=matchpmd.pmd_name.txtwith|None->map|Somename->String.Map.addnamem'mapin(addbv,addm)|Psig_modsubstpms->letm'=add_module_aliasbvpms.pms_manifestinletadd=String.Map.addpms.pms_name.txtm'in(addbv,addm)|Psig_recmoduledecls->letadd=List.fold_right(funpmdmap->matchpmd.pmd_name.txtwith|None->map|Somename->String.Map.addnameboundmap)declsinletbv'=addbvandm'=addminList.iter(funpmd->add_modtypebv'pmd.pmd_type)decls;(bv',m')|Psig_modtypex|Psig_modtypesubstx->beginmatchx.pmtd_typewithNone->()|Somemty->add_modtypebvmtyend;(bv,m)|Psig_openod->(open_descriptionbvod,m)|Psig_includeincl->letNode(s,m')=add_modtype_bindingbvincl.pincl_modinadd_namess;letadd=String.Map.foldString.Map.addm'in(addbv,addm)|Psig_classcdl->List.iter(add_class_descriptionbv)cdl;(bv,m)|Psig_class_typecdtl->List.iter(add_class_type_declarationbv)cdtl;(bv,m)|Psig_attribute_->(bv,m)|Psig_extension(e,_)->handle_extensione;(bv,m)andopen_descriptionbvod=letNode(s,m)=add_module_aliasbvod.popen_exprinadd_namess;String.Map.foldString.Map.addmbvandopen_declarationbvod=letNode(s,m)=add_module_bindingbvod.popen_exprinadd_namess;String.Map.foldString.Map.addmbvandadd_module_bindingbvmodl=matchmodl.pmod_descwithPmod_identl->add_module_aliasbvl|Pmod_structures->make_node(snd@@add_structure_bindingbvs)|_->add_module_exprbvmodl;boundandadd_module_exprbvmodl=matchmodl.pmod_descwithPmod_identl->add_module_pathbvl|Pmod_structures->ignore(add_structurebvs)|Pmod_functor(param,modl)->letbv=matchparamwith|Unit->bv|Named(id,mty)->add_modtypebvmty;matchid.txtwith|None->bv|Somename->String.Map.addnameboundbvinadd_module_exprbvmodl|Pmod_apply(mod1,mod2)->add_module_exprbvmod1;add_module_exprbvmod2|Pmod_constraint(modl,mty)->add_module_exprbvmodl;add_modtypebvmty|Pmod_unpack(e)->add_exprbve|Pmod_extensione->handle_extensioneandadd_class_typebvcty=matchcty.pcty_descwithPcty_constr(l,tyl)->addbvl;List.iter(add_typebv)tyl|Pcty_signature{pcsig_self=ty;pcsig_fields=fieldl}->add_typebvty;List.iter(add_class_type_fieldbv)fieldl|Pcty_arrow(_,ty1,cty2)->add_typebvty1;add_class_typebvcty2|Pcty_extensione->handle_extensione|Pcty_open(o,e)->letbv=open_descriptionbvoinadd_class_typebveandadd_class_type_fieldbvpctf=matchpctf.pctf_descwithPctf_inheritcty->add_class_typebvcty|Pctf_val(_,_,_,ty)->add_typebvty|Pctf_method(_,_,_,ty)->add_typebvty|Pctf_constraint(ty1,ty2)->add_typebvty1;add_typebvty2|Pctf_attribute_->()|Pctf_extensione->handle_extensioneandadd_class_descriptionbvinfos=add_class_typebvinfos.pci_exprandadd_class_type_declarationbvinfos=add_class_descriptionbvinfosandadd_structurebvitem_list=let(bv,m)=add_structure_bindingbvitem_listinadd_names(collect_free(make_nodem));bvandadd_structure_bindingbvitem_list=List.fold_leftadd_struct_item(bv,String.Map.empty)item_listandadd_struct_item(bv,m)item:_String.Map.t*_String.Map.t=matchitem.pstr_descwithPstr_eval(e,_attrs)->add_exprbve;(bv,m)|Pstr_value(rf,pel)->letbv=add_bindingsrfbvpelin(bv,m)|Pstr_primitivevd->add_typebvvd.pval_type;(bv,m)|Pstr_type(_,dcls)->List.iter(add_type_declarationbv)dcls;(bv,m)|Pstr_typextte->add_type_extensionbvte;(bv,m)|Pstr_exceptionte->add_type_exceptionbvte;(bv,m)|Pstr_modulex->letb=add_module_bindingbvx.pmb_exprinletaddmap=matchx.pmb_name.txtwith|None->map|Somename->String.Map.addnamebmapin(addbv,addm)|Pstr_recmodulebindings->letadd=List.fold_right(funxmap->matchx.pmb_name.txtwith|None->map|Somename->String.Map.addnameboundmap)bindingsinletbv'=addbvandm=addminList.iter(funx->add_module_exprbv'x.pmb_expr)bindings;(bv',m)|Pstr_modtypex->beginmatchx.pmtd_typewithNone->()|Somemty->add_modtypebvmtyend;(bv,m)|Pstr_openod->(open_declarationbvod,m)|Pstr_classcdl->List.iter(add_class_declarationbv)cdl;(bv,m)|Pstr_class_typecdtl->List.iter(add_class_type_declarationbv)cdtl;(bv,m)|Pstr_includeincl->letNode(s,m')asn=add_module_bindingbvincl.pincl_modinif!Clflags.transparent_modulesthenadd_namesselse(* If we are not in the delayed dependency mode, we need to
collect all delayed dependencies imported by the include statement *)add_names(collect_freen);letadd=String.Map.foldString.Map.addm'in(addbv,addm)|Pstr_attribute_->(bv,m)|Pstr_extension(e,_)->handle_extensione;(bv,m)andadd_use_filebvtop_phrs=ignore(List.fold_leftadd_top_phrasebvtop_phrs)andadd_implementationbvl=ignore(add_structure_bindingbvl)andadd_implementation_bindingbvl=snd(add_structure_bindingbvl)andadd_top_phrasebv=function|Ptop_defstr->add_structurebvstr|Ptop_dir_->bvandadd_class_exprbvce=matchce.pcl_descwithPcl_constr(l,tyl)->addbvl;List.iter(add_typebv)tyl|Pcl_structure{pcstr_self=pat;pcstr_fields=fieldl}->letbv=add_patternbvpatinList.iter(add_class_fieldbv)fieldl|Pcl_fun(_,opte,pat,ce)->add_optadd_exprbvopte;letbv=add_patternbvpatinadd_class_exprbvce|Pcl_apply(ce,exprl)->add_class_exprbvce;List.iter(fun(_,e)->add_exprbve)exprl|Pcl_let(rf,pel,ce)->letbv=add_bindingsrfbvpelinadd_class_exprbvce|Pcl_constraint(ce,ct)->add_class_exprbvce;add_class_typebvct|Pcl_extensione->handle_extensione|Pcl_open(o,e)->letbv=open_descriptionbvoinadd_class_exprbveandadd_class_fieldbvpcf=matchpcf.pcf_descwithPcf_inherit(_,ce,_)->add_class_exprbvce|Pcf_val(_,_,Cfk_concrete(_,e))|Pcf_method(_,_,Cfk_concrete(_,e))->add_exprbve|Pcf_val(_,_,Cfk_virtualty)|Pcf_method(_,_,Cfk_virtualty)->add_typebvty|Pcf_constraint(ty1,ty2)->add_typebvty1;add_typebvty2|Pcf_initializere->add_exprbve|Pcf_attribute_->()|Pcf_extensione->handle_extensioneandadd_class_declarationbvdecl=add_class_exprbvdecl.pci_expr