123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148openMlFront_CoremoduleLibraryIdMap=Map.Make(LibraryId)typeconfig={unit_id:UnitId.t;remote_spec :RemoteSpec.t}typet={configs :configLibraryIdMap.t}letppppf{configs}=Format.fprintfppf"%a"(Format.pp_print_list~pp_sep:(funppf()->Format.fprintfppf"@ ")(funppf(library_id,{unit_id;remote_spec})->Format.fprintfppf"@[<hov 2>(%a:@ defined in %a:@ %a)@]"LibraryId.pplibrary_idUnitId.ppunit_idRemoteSpec.ppremote_spec))(LibraryIdMap.bindingsconfigs)letempty={configs=LibraryIdMap.empty}letmergets=letconfigs=List.map(function{configs}->configs)tsinletconfigs=(* The first configuration (the leftmost) wins if there is
a duplicate library. *)List.fold_left(fun(acc:configLibraryIdMap.t)(item:configLibraryIdMap.t)->LibraryIdMap.merge(fun_library_idacc_optitem_opt->match(acc_opt,item_opt)with|Someconfig,_->Someconfig|None,Someconfig->Someconfig|None,None->None)accitem)LibraryIdMap.emptyconfigsin{configs}letremote_specs~target_abi{configs;_}=LibraryIdMap.bindingsconfigs|> List.map(fun(library_id,{unit_id=_;remote_spec})->(library_id,RemoteSpec.replace_abi~target_abiremote_spec))letfind_remote_spec~target_abi{configs;_}library_id=matchLibraryIdMap.find_optlibrary_idconfigswith|Some{remote_spec;_}->Some(RemoteSpec.replace_abi~target_abiremote_spec)|None->None(** [parse_library_id_from_module_expression expr] parses the module expression
in [module _ = Expr] and returns a library id if it ([Expr]) is a library
identifier. *)letparse_library_id_from_module_expression(expr:Parsetree.module_expr):LibraryId.toption=matchexprwith|{pmod_desc=Pmod_ident {txt=Lidentlibrary_id_candidate;_};_}->LibraryId.parselibrary_id_candidate|_->None(** [parse_library_id_from_module_expression expr] parses the module expression
in [module _ = Type] and returns a library id if it ([Type]) is a library
identifier. *)letparse_library_id_from_module_type(typ:Parsetree.module_type):LibraryId.toption=matchtypwith|{pmty_desc=Pmty_alias {txt=Lidentlibrary_id_candidate;_};_}->LibraryId.parselibrary_id_candidate|_->None(** [parse_config ~unit_id attributes] parses the attributes of
[module _ = SomeLibrary_Std] to find its ocamldoc attribute and returns
the configuration if the ocamldoc contains the library configuration.
For example. the version 1 configuration is returned from:
{[
module _ = SomeLibrary_Std
(** {[ `v1 [
`blib ["https://gitlab.com/api/v4/projects/45955665/packages/generic/@DKML_TARGET_ABI@/2.1.4/@DKML_TARGET_ABI@-4.14.2-DkSDKFFI_OCaml-2.1.4-none.blibs.tar.gz"];
`clib ["https://gitlab.com/api/v4/projects/45955665/packages/generic/@DKML_TARGET_ABI@/2.1.4/@DKML_TARGET_ABI@-4.14.2-DkSDKFFI_OCaml-2.1.4-none.clibs.tar.gz"]
] ]} *)
]}
*)letparse_config~unit_id(attributes:Parsetree.attributes):configoption=letspec_opt=List.fold_left(funacc(attr:Parsetree.attribute)->match (acc,attr)with|(None,{attr_name={txt="ocaml.doc";_};attr_payload=PStr[{pstr_desc=Pstr_eval({pexp_desc;_},_attributes);_};];_;})->(matchParseAst.parse_constant_stringpexp_descwith|Somelabel->RemoteSpec.parse_from_ocamldoclabel|None->None)|_->acc)Noneattributesinmatchspec_optwith|Someremote_spec->Some{unit_id;remote_spec}|None->Noneletscan_structureunit_id(structure:Parsetree.structure)=let(configs:configLibraryIdMap.t)=(* Let the LAST module expression win within a compilation unit. *)List.fold_right(fun(item:Parsetree.structure_item)(acc:configLibraryIdMap.t)->matchitemwith|{pstr_desc=Pstr_module{pmb_expr;pmb_attributes;_};_}->(matchparse_library_id_from_module_expressionpmb_exprwith|Somelibrary_id->(matchparse_config~unit_idpmb_attributeswith|Someconfig->(* Do not overwrite later (LAST) values *)LibraryIdMap.updatelibrary_id(functionNone->Some config|Some_->None)acc|None->acc)|_->acc)|_->acc)structureLibraryIdMap.emptyin{configs}letscan_signatureunit_id(signature:Parsetree.signature)=let(configs:configLibraryIdMap.t)=(* Let the LAST module expression win within a compilation unit. *)List.fold_right(fun(item:Parsetree.signature_item)(acc:configLibraryIdMap.t)->matchitemwith|{psig_desc=Psig_module{pmd_type;pmd_attributes;_};_}->(matchparse_library_id_from_module_typepmd_typewith|Somelibrary_id->(matchparse_config~unit_idpmd_attributeswith|Someconfig->(* Do not overwrite later (LAST) values *)LibraryIdMap.updatelibrary_id(functionNone->Some config|Some_->None)acc|None->acc)|_->acc)|_->acc)signatureLibraryIdMap.emptyin{configs}