123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111open!Coreopen!Asynctypet={ml:string;mli:stringoption;module_name:string}[@@derivingsexp,compare][@@sexp.allow_extra_fields]typetmp_t={mutabletmp_ml:stringoption;mutabletmp_mli:stringoption;tmp_module_name:string}letvalid_module_names=not(String.is_emptys)&&matchs.[0]with|'A'..'Z'->String.for_alls~f:(function|'a'..'z'|'A'..'Z'|'_'|'0'..'9'|'\''->true|_->false)|_->false;;letmodule_name~full_path~path_no_ext=letbasename=Filename.basenamepath_no_extinletunchecked_module_name=String.capitalizebasenameinifvalid_module_nameunchecked_module_namethenunchecked_module_nameelseinvalid_argf"%s is not a valid ocaml filename"full_path();;letenrich_bundle({ml;mli;module_name=_}asbundle)=matchmliwith|Some_->returnbundle|None->letmli=Filename.chop_extensionml^".mli"inSys.file_existsmli>>|function|`Yes->{bundlewithmli=Somemli}|`No->bundle|`Unknown->raise_s[%sexp"File_in_unknown_state",(mli:string),[%here]];;letml_with_mli_reorderfilenames=lettbl=String.Table.create()inletinit_bundleaccstr=letpath_no_ext,ext_opt=Filename.split_extensionstrinletext=matchext_optwith|None->`none|Some"ml"->`ml|Some"mli"->`mli|Someext->invalid_argf"Expected .ml or .mli files, got : %s"ext()in(* giving this error after the one about extensions *)letmodule_name=module_name~full_path:str~path_no_extinletacc,data=matchHashtbl.findtblmodule_namewith|None->letdata={tmp_ml=None;tmp_mli=None;tmp_module_name=module_name}inHashtbl.add_exntbl~key:module_name~data;data::acc,data|Somedata->acc,datainbeginmatchext,datawith|(`ml|`none),{tmp_ml=Someold_ml;_}->invalid_argf"Several implementations provided for %s: %s and %s"module_namestrold_ml()|`mli,{tmp_mli=Someold_mli;_}->invalid_argf"Several interfaces provided for %s: %s and %s"module_namestrold_mli()|`none,{tmp_ml=None;_}->data.tmp_ml<-Some(str^".ml")|`ml,{tmp_ml=None;_}->data.tmp_ml<-Somestr|`mli,{tmp_mli=None;_}->data.tmp_mli<-Somestrend;accinletrev_paths=List.fold_leftfilenames~init:[]~f:init_bundleinList.rev_maprev_paths~f:(fun{tmp_ml;tmp_mli=mli;tmp_module_name=module_name}->letml=matchtmp_mlwith|None->(* same behaviour as before *)Filename.chop_extension(Option.value_exnmli)^".ml"|Someml->mlin{ml;mli;module_name});;letfrom_filenamesfilenames=Deferred.Or_error.try_with~extract_exn:true(fun()->letpairs=ml_with_mli_reorderfilenamesinDeferred.List.mappairs~f:enrich_bundle);;letto_pathnames{ml;mli;module_name}=`mlml,`mlimli,`module_namemodule_name;;letmodule_namet=t.module_name;;