diff --git a/src/exe.ml b/src/exe.ml index f836797d..b5b4598e 100644 --- a/src/exe.ml +++ b/src/exe.ml @@ -6,7 +6,7 @@ module SC = Super_context module Program = struct type t = { name : string - ; main_module_name : string + ; main_module_name : Module.Name.t } end @@ -123,7 +123,7 @@ let build_and_link_many sctx = let modules = - String_map.map modules ~f:(Module.set_obj_name ~wrapper:None) + Module.Name.Map.map modules ~f:(Module.set_obj_name ~wrapper:None) in let dep_graphs = @@ -139,7 +139,8 @@ let build_and_link_many List.iter programs ~f:(fun { Program.name; main_module_name } -> let top_sorted_modules = - let main = Option.value_exn (String_map.find modules main_module_name) in + let main = Option.value_exn + (Module.Name.Map.find modules main_module_name) in Ocamldep.Dep_graph.top_closed_implementations dep_graphs.impl [main] in diff --git a/src/exe.mli b/src/exe.mli index 18a46baf..ce9019ea 100644 --- a/src/exe.mli +++ b/src/exe.mli @@ -1,11 +1,9 @@ (** Compilation and linking of executables *) -open Import - module Program : sig type t = { name : string - ; main_module_name : string + ; main_module_name : Module.Name.t } end @@ -40,11 +38,11 @@ val build_and_link : dir:Path.t -> obj_dir:Path.t -> program:Program.t - -> modules:Module.t String_map.t + -> modules:Module.t Module.Name.Map.t -> scope:Scope.t -> linkages:Linkage.t list -> ?requires:(unit, Lib.L.t) Build.t - -> ?already_used:String_set.t + -> ?already_used:Module.Name.Set.t -> ?flags:Ocaml_flags.t -> ?link_flags:(unit, string list) Build.t -> ?js_of_ocaml:Jbuild.Js_of_ocaml.t @@ -55,11 +53,11 @@ val build_and_link_many : dir:Path.t -> obj_dir:Path.t -> programs:Program.t list - -> modules:Module.t String_map.t + -> modules:Module.t Module.Name.Map.t -> scope:Scope.t -> linkages:Linkage.t list -> ?requires:(unit, Lib.L.t) Build.t - -> ?already_used:String_set.t + -> ?already_used:Module.Name.Set.t -> ?flags:Ocaml_flags.t -> ?link_flags:(unit, string list) Build.t -> ?js_of_ocaml:Jbuild.Js_of_ocaml.t diff --git a/src/gen_rules.ml b/src/gen_rules.ml index 13212444..c692b2f1 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -25,34 +25,40 @@ module Gen(P : Install_rules.Params) = struct +-----------------------------------------------------------------+ *) module Eval_modules = Ordered_set_lang.Make(struct - type t = (Module.t, string * Loc.t) result - let name = function - | Error (s, _) -> s - | Ok m -> Module.name m + type t = (Module.t, Module.Name.t * Loc.t) result + let name r = ( + (match r with + | Error (s, _) -> s + | Ok m -> Module.name m) + |> Module.Name.to_string + ) end) - let parse_modules ~(all_modules : Module.t String_map.t) ~buildable = + let parse_modules ~(all_modules : Module.t Module.Name.Map.t) ~buildable = let conf : Buildable.t = buildable in - let standard_modules = String_map.map all_modules ~f:(fun m -> Ok m) in - let fake_modules = ref String_map.empty in + let standard_modules = Module.Name.Map.map all_modules ~f:(fun m -> Ok m) in + let fake_modules = ref Module.Name.Map.empty in let parse ~loc s = - let s = String.capitalize s in - match String_map.find all_modules s with + let name = Module.Name.of_string s in + match Module.Name.Map.find all_modules name with | Some m -> Ok m | None -> - fake_modules := String_map.add !fake_modules s loc; - Error (s, loc) + fake_modules := Module.Name.Map.add !fake_modules name loc; + Error (name, loc) in let modules = + let standard = Module.Name.Map.to_smap standard_modules in Eval_modules.eval_unordered conf.modules ~parse - ~standard:standard_modules + ~standard + |> Module.Name.Map.of_smap in let only_present_modules modules = - String_map.filter_map ~f:(function + Module.Name.Map.filter_map ~f:(function | Ok m -> Some m - | Error (s, loc) -> Loc.fail loc "Module %s doesn't exist." s + | Error (s, loc) -> + Loc.fail loc "Module %a doesn't exist." Module.Name.pp s ) modules in let modules = only_present_modules modules in @@ -61,27 +67,31 @@ module Gen(P : Install_rules.Params) = struct conf.modules_without_implementation ~parse ~standard:String_map.empty + |> Module.Name.Map.of_smap in let intf_only = only_present_modules intf_only in - String_map.iteri !fake_modules ~f:(fun m loc -> - Loc.warn loc "Module %s is excluded but it doesn't exist." m + Module.Name.Map.iteri !fake_modules ~f:(fun m loc -> + Loc.warn loc "Module %a is excluded but it doesn't exist." + Module.Name.pp m ); let real_intf_only = - String_map.filter modules + Module.Name.Map.filter modules ~f:(fun (m : Module.t) -> Option.is_none m.impl) in - if String_map.equal intf_only real_intf_only + if Module.Name.Map.equal intf_only real_intf_only ~equal:(fun a b -> Module.name a = Module.name b) then modules else begin let should_be_listed, shouldn't_be_listed = - String_map.merge intf_only real_intf_only ~f:(fun name x y -> + Module.Name.Map.merge intf_only real_intf_only ~f:(fun name x y -> match x, y with | Some _, Some _ -> None - | None , Some _ -> Some (Left (String.uncapitalize name)) - | Some _, None -> Some (Right (String.uncapitalize name)) + | None , Some _ -> + Some (Left (String.uncapitalize (Module.Name.to_string name))) + | Some _, None -> + Some (Right (String.uncapitalize (Module.Name.to_string name))) | None , None -> assert false) - |> String_map.values + |> Module.Name.Map.values |> List.partition_map ~f:(fun x -> x) in let list_modules l = @@ -116,17 +126,18 @@ module Gen(P : Install_rules.Params) = struct let module Eval = Ordered_set_lang.Make(struct type t = Loc.t * Module.t - let name (_, m) = Module.name m + let name (_, m) = Module.Name.to_string (Module.name m) end) in let parse ~loc s = - let s = String.capitalize s in - match String_map.find all_modules s with + let name = Module.Name.of_string s in + match Module.Name.Map.find all_modules name with | Some m -> m | None -> Loc.fail loc "Module %s doesn't exist." s in let parse ~loc s = (loc, parse ~loc s) in let shouldn't_be_listed = + let all_modules = Module.Name.Map.to_smap all_modules in Eval.eval_unordered conf.modules_without_implementation ~parse ~standard:(String_map.map all_modules ~f:(fun m -> (Loc.none, m))) @@ -137,8 +148,8 @@ module Gen(P : Install_rules.Params) = struct (* CR-soon jdimino for jdimino: report all errors *) let loc, m = List.hd shouldn't_be_listed in Loc.fail loc - "Module %s has an implementation, it cannot be listed here" - m.name + "Module %a has an implementation, it cannot be listed here" + Module.Name.pp m.name end; modules end @@ -264,18 +275,19 @@ module Gen(P : Install_rules.Params) = struct in let parse_one_set files = List.map files ~f:(fun (f : Module.File.t) -> - (String.capitalize (Filename.chop_extension f.name), f)) - |> String_map.of_list + (Module.Name.of_string (Filename.chop_extension f.name), f)) + |> Module.Name.Map.of_list |> function | Ok x -> x | Error (name, f1, f2) -> let src_dir = Path.drop_build_context_exn dir in - die "too many files for module %s in %s: %s and %s" - name (Path.to_string src_dir) f1.name f2.name + die "too many files for module %a in %s: %s and %s" + Module.Name.pp name (Path.to_string src_dir) + f1.name f2.name in let impls = parse_one_set impl_files in let intfs = parse_one_set intf_files in - String_map.merge impls intfs ~f:(fun name impl intf -> + Module.Name.Map.merge impls intfs ~f:(fun name impl intf -> Some { Module.name ; impl @@ -292,9 +304,9 @@ module Gen(P : Install_rules.Params) = struct guess_modules ~dir ~files) type modules_by_lib = - { modules : Module.t String_map.t + { modules : Module.t Module.Name.Map.t ; alias_module : Module.t option - ; main_module_name : string + ; main_module_name : Module.Name.t } let modules_by_lib = @@ -305,9 +317,9 @@ module Gen(P : Install_rules.Params) = struct let modules = parse_modules ~all_modules ~buildable:lib.buildable in - let main_module_name = String.capitalize lib.name in + let main_module_name = Module.Name.of_string lib.name in let modules = - String_map.map modules ~f:(fun (m : Module.t) -> + Module.Name.Map.map modules ~f:(fun (m : Module.t) -> let wrapper = if not lib.wrapped || m.name = main_module_name then None @@ -318,16 +330,16 @@ module Gen(P : Install_rules.Params) = struct in let alias_module = if not lib.wrapped || - (String_map.cardinal modules = 1 && - String_map.mem modules main_module_name) then + (Module.Name.Map.cardinal modules = 1 && + Module.Name.Map.mem modules main_module_name) then None - else if String_map.mem modules main_module_name then + else if Module.Name.Map.mem modules main_module_name then (* This module needs an implementaion for non-jbuilder users of the library: https://github.com/ocaml/dune/issues/567 *) Some - { Module.name = main_module_name ^ "__" + { Module.name = Module.Name.add_suffix main_module_name "__" ; intf = None ; impl = Some { name = sprintf "%s__.ml-gen" lib.name ; syntax = OCaml @@ -351,9 +363,9 @@ module Gen(P : Install_rules.Params) = struct let modules = match alias_module with | None -> modules - | Some m -> String_map.add modules m.name m + | Some m -> Module.Name.Map.add modules m.name m in - String_map.values modules + Module.Name.Map.values modules (* +-----------------------------------------------------------------+ | Library stuff | @@ -519,15 +531,16 @@ module Gen(P : Install_rules.Params) = struct let modules = match alias_module with | None -> modules - | Some m -> String_map.add modules m.name m + | Some m -> Module.Name.Map.add modules m.name m in let dep_graphs = Ocamldep.rules sctx ~dir ~modules ~already_used ~alias_module - ~lib_interface_module:(if lib.wrapped then - String_map.find modules main_module_name - else - None) + ~lib_interface_module:( + if lib.wrapped then + Module.Name.Map.find modules main_module_name + else + None) in Option.iter alias_module ~f:(fun m -> @@ -538,12 +551,15 @@ module Gen(P : Install_rules.Params) = struct in SC.add_rule sctx (Build.return - (String_map.values (String_map.remove modules m.name) + (Module.Name.Map.values (Module.Name.Map.remove modules m.name) |> List.map ~f:(fun (m : Module.t) -> sprintf "(** @canonical %s.%s *)\n\ module %s = %s\n" - main_module_name m.name - m.name (Module.real_unit_name m)) + (Module.Name.to_string main_module_name) + (Module.Name.to_string m.name) + (Module.Name.to_string m.name) + (Module.Name.to_string (Module.real_unit_name m)) + ) |> String.concat ~sep:"\n") >>> Build.write_file_dyn (Path.relative dir file.name))); @@ -571,7 +587,7 @@ module Gen(P : Install_rules.Params) = struct ~dep_graphs:(Ocamldep.Dep_graphs.dummy m) ~requires:( let requires = - if String_map.is_empty modules then + if Module.Name.Map.is_empty modules then (* Just so that we setup lib dependencies for empty libraries *) requires else @@ -645,7 +661,7 @@ module Gen(P : Install_rules.Params) = struct List.iter Cm_kind.all ~f:(fun cm_kind -> let files = - String_map.fold modules ~init:[] ~f:(fun m acc -> + Module.Name.Map.fold modules ~init:[] ~f:(fun m acc -> match Module.cm_file m ~obj_dir cm_kind with | None -> acc | Some fn -> fn :: acc) @@ -659,7 +675,7 @@ module Gen(P : Install_rules.Params) = struct let top_sorted_modules = Ocamldep.Dep_graph.top_closed_implementations dep_graphs.impl - (String_map.values modules) + (Module.Name.Map.values modules) in List.iter Mode.all ~f:(fun mode -> build_lib lib ~scope ~flags ~dir ~obj_dir ~mode ~top_sorted_modules); @@ -712,7 +728,7 @@ module Gen(P : Install_rules.Params) = struct match alias_module with | None -> Ocaml_flags.common flags | Some m -> - Ocaml_flags.prepend_common ["-open"; m.name] flags + Ocaml_flags.prepend_common ["-open"; Module.Name.to_string m.name] flags |> Ocaml_flags.common in @@ -743,7 +759,7 @@ module Gen(P : Install_rules.Params) = struct in let already_used = match modules_partitioner with - | None -> String_set.empty + | None -> Module.Name.Set.empty | Some mp -> Modules_partitioner.acknowledge mp ~loc:exes.buildable.loc ~modules @@ -763,14 +779,16 @@ module Gen(P : Install_rules.Params) = struct let programs = List.map exes.names ~f:(fun (loc, name) -> - let mod_name = String.capitalize name in - match String_map.find modules mod_name with + let mod_name = Module.Name.of_string name in + match Module.Name.Map.find modules mod_name with | Some m -> if not (Module.has_impl m) then - Loc.fail loc "Module %s has no implementation." mod_name + Loc.fail loc "Module %a has no implementation." + Module.Name.pp mod_name else { Exe.Program.name; main_module_name = mod_name } - | None -> Loc.fail loc "Module %s doesn't exist." mod_name) + | None -> Loc.fail loc "Module %a doesn't exist." + Module.Name.pp mod_name) in let linkages = diff --git a/src/import.ml b/src/import.ml index fc8d7c8b..1764e90d 100644 --- a/src/import.ml +++ b/src/import.ml @@ -128,6 +128,8 @@ module Fmt = struct let list = Format.pp_print_list let string s ppf = Format.pp_print_string ppf s + let nl = Format.pp_print_newline + let prefix f g ppf x = f ppf; g ppf x end diff --git a/src/inline_tests.ml b/src/inline_tests.ml index 294bb82b..b313677b 100644 --- a/src/inline_tests.ml +++ b/src/inline_tests.ml @@ -172,9 +172,9 @@ include Sub_system.Register_end_point( let name = "run" in let main_module_filename = name ^ ".ml" in - let main_module_name = String.capitalize name in + let main_module_name = Module.Name.of_string name in let modules = - String_map.singleton main_module_name + Module.Name.Map.singleton main_module_name { Module. name = main_module_name ; impl = Some { name = main_module_filename @@ -205,7 +205,7 @@ include Sub_system.Register_end_point( (* Generate the runner file *) SC.add_rule sctx ( let target = Path.relative inline_test_dir main_module_filename in - let source_modules = String_map.values source_modules in + let source_modules = Module.Name.Map.values source_modules in let files ml_kind = Action.Var_expansion.Paths ( List.filter_map source_modules ~f:(fun m -> @@ -274,7 +274,7 @@ include Sub_system.Register_end_point( A.chdir dir (A.progn (A.run (Ok exe) flags :: - (String_map.values source_modules + (Module.Name.Map.values source_modules |> List.concat_map ~f:(fun m -> [ Module.file m ~dir Impl ; Module.file m ~dir Intf diff --git a/src/jbuild.ml b/src/jbuild.ml index 3f08aef7..621997cd 100644 --- a/src/jbuild.ml +++ b/src/jbuild.ml @@ -288,19 +288,20 @@ module Preprocess = struct end module Per_module = struct - include Per_item.Make(String) + include Per_item.Make(Module.Name) let t ~default a sexp = match sexp with | List (_, Atom (_, A "per_module") :: rest) -> begin List.map rest ~f:(fun sexp -> let pp, names = pair a module_names sexp in - (String_set.to_list names, pp)) + (List.map ~f:Module.Name.of_string (String_set.to_list names), pp)) |> of_mapping ~default |> function | Ok t -> t | Error (name, _, _) -> - of_sexp_error sexp (sprintf "module %s present in two different sets" name) + of_sexp_error sexp (sprintf "module %s present in two different sets" + (Module.Name.to_string name)) end | sexp -> for_all (a sexp) end @@ -516,7 +517,7 @@ module Buildable = struct let single_preprocess t = if Per_module.is_constant t.preprocess then - Per_module.get t.preprocess "" + Per_module.get t.preprocess (Module.Name.of_string "") else Preprocess.No_preprocessing end diff --git a/src/jbuild.mli b/src/jbuild.mli index 1ee4aba3..c005e894 100644 --- a/src/jbuild.mli +++ b/src/jbuild.mli @@ -61,7 +61,7 @@ module Preprocess : sig | Pps of pps end -module Per_module : Per_item.S with type key = string +module Per_module : Per_item.S with type key = Module.Name.t module Preprocess_map : sig type t = Preprocess.t Per_module.t @@ -71,7 +71,7 @@ module Preprocess_map : sig (** [find module_name] find the preprocessing specification for a given module *) - val find : string -> t -> Preprocess.t + val find : Module.Name.t -> t -> Preprocess.t val pps : t -> (Loc.t * Pp.t) list end diff --git a/src/module.ml b/src/module.ml index e48dde11..7c6d6673 100644 --- a/src/module.ml +++ b/src/module.ml @@ -1,5 +1,32 @@ open Import +module Name = struct + type t = string + + let t = Sexp.atom + + let add_suffix = (^) + + let compare = compare + let of_string = String.capitalize + let to_string x = x + + let pp = Format.pp_print_string + let pp_quote fmt x = Format.fprintf fmt "%S" x + + module Set = struct + include String_set + let of_sset x = x + end + + module Map = struct + include String_map + + let to_smap x = x + let of_smap x = x + end +end + module Syntax = struct type t = OCaml | Reason end @@ -26,7 +53,7 @@ module File = struct end type t = - { name : string + { name : Name.t ; impl : File.t option ; intf : File.t option ; obj_name : string @@ -34,7 +61,7 @@ type t = let name t = t.name -let real_unit_name t = String.capitalize (Filename.basename t.obj_name) +let real_unit_name t = Name.of_string (Filename.basename t.obj_name) let has_impl t = Option.is_some t.impl diff --git a/src/module.mli b/src/module.mli index 6ddceb62..ffb22f42 100644 --- a/src/module.mli +++ b/src/module.mli @@ -1,5 +1,31 @@ open! Import +module Name : sig + type t = private string + + val add_suffix : t -> string -> t + + val t : t Sexp.To_sexp.t + val compare : t -> t -> Ordering.t + val of_string : string -> t + val to_string : t -> string + + val pp : Format.formatter -> t -> unit + val pp_quote : Format.formatter -> t -> unit + + module Set : sig + include Set.S with type elt = t + + val of_sset : String_set.t -> t + end + module Map : sig + include Map.S with type key = t + + val to_smap : 'a t -> 'a String_map.t + val of_smap : 'a String_map.t -> 'a t + end +end + module Syntax : sig type t = OCaml | Reason end @@ -14,7 +40,7 @@ module File : sig end type t = - { name : string (** Name of the module. This is always the basename of the filename + { name : Name.t (** Name of the module. This is always the basename of the filename without the extension. *) ; impl : File.t option ; intf : File.t option @@ -23,10 +49,10 @@ type t = modules. *) } -val name : t -> string +val name : t -> Name.t (** Real unit name once wrapped. This is always a valid module name. *) -val real_unit_name : t -> string +val real_unit_name : t -> Name.t val file : t -> dir: Path.t -> Ml_kind.t -> Path.t option val cm_source : t -> dir: Path.t -> Cm_kind.t -> Path.t option diff --git a/src/module_compilation.ml b/src/module_compilation.ml index cda090a5..384791a5 100644 --- a/src/module_compilation.ml +++ b/src/module_compilation.ml @@ -103,7 +103,8 @@ let build_cm sctx ?sandbox ~dynlink ~flags ~cm_kind ~dep_graphs ; A "-I"; Path obj_dir ; (match alias_module with | None -> S [] - | Some (m : Module.t) -> As ["-open"; m.name]) + | Some (m : Module.t) -> + As ["-open"; Module.Name.to_string m.name]) ; A "-o"; Target dst ; A "-c"; Ml_kind.flag ml_kind; Dep src ]))) @@ -143,10 +144,10 @@ let build_modules sctx ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~obj_dir ; cmx = cmi_and_cmx_requires } in - String_map.iter + Module.Name.Map.iter (match alias_module with | None -> modules - | Some (m : Module.t) -> String_map.remove modules m.name) + | Some (m : Module.t) -> Module.Name.Map.remove modules m.name) ~f:(fun m -> build_module sctx m ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~obj_dir ~dep_graphs ~requires ~alias_module) diff --git a/src/module_compilation.mli b/src/module_compilation.mli index 8631d910..8b3b98dd 100644 --- a/src/module_compilation.mli +++ b/src/module_compilation.mli @@ -1,7 +1,5 @@ (** OCaml module compilation *) -open Import - (** Setup rules to build a single module. [requires] must declare dependencies on files of libraries. @@ -31,7 +29,7 @@ val build_modules -> dir:Path.t -> obj_dir:Path.t -> dep_graphs:Ocamldep.Dep_graphs.t - -> modules:Module.t String_map.t + -> modules:Module.t Module.Name.Map.t -> requires:(unit, Lib.t list) Build.t -> alias_module:Module.t option -> unit diff --git a/src/modules_partitioner.ml b/src/modules_partitioner.ml index f66d4210..36fbc8b6 100644 --- a/src/modules_partitioner.ml +++ b/src/modules_partitioner.ml @@ -2,25 +2,25 @@ open Import type t = { dir : Path.t - ; all_modules : Module.t String_map.t - ; mutable used : Loc.t list String_map.t + ; all_modules : Module.t Module.Name.Map.t + ; mutable used : Loc.t list Module.Name.Map.t } let create ~dir ~all_modules = { dir ; all_modules - ; used = String_map.empty + ; used = Module.Name.Map.empty } let acknowledge t ~loc ~modules = let already_used = - String_map.merge modules t.used ~f:(fun _name x l -> + Module.Name.Map.merge modules t.used ~f:(fun _name x l -> Option.some_if (Option.is_some x && Option.is_some l) ()) - |> String_map.keys - |> String_set.of_list + |> Module.Name.Map.keys + |> Module.Name.Set.of_list in t.used <- - String_map.merge modules t.used ~f:(fun _name x l -> + Module.Name.Map.merge modules t.used ~f:(fun _name x l -> match x with | None -> l | Some _ -> Some (loc :: Option.value l ~default:[])); @@ -32,14 +32,14 @@ let emit_warnings t = |> Path.to_string |> Loc.in_file in - String_map.iteri t.used ~f:(fun name locs -> + Module.Name.Map.iteri t.used ~f:(fun name locs -> if List.length locs > 1 then Loc.warn loc - "Module %S is used in several stanzas:@\n\ + "Module %a is used in several stanzas:@\n\ @[%a@]@\n\ @[%a@]@\n\ This warning will become an error in the future." - name + Module.Name.pp_quote name (Fmt.list (Fmt.prefix (Fmt.string "- ") Loc.pp_file_colon_line)) locs Format.pp_print_text diff --git a/src/modules_partitioner.mli b/src/modules_partitioner.mli index a8e0be86..6168b404 100644 --- a/src/modules_partitioner.mli +++ b/src/modules_partitioner.mli @@ -1,12 +1,10 @@ (** Checks modules partitioning inside a directory *) -open Import - type t val create : dir:Path.t - -> all_modules:Module.t String_map.t + -> all_modules:Module.t Module.Name.Map.t -> t (** [acknowledge t ~loc ~modules] registers the fact that [modules] @@ -18,8 +16,8 @@ val create val acknowledge : t -> loc:Loc.t - -> modules:Module.t String_map.t - -> String_set.t + -> modules:Module.t Module.Name.Map.t + -> Module.Name.Set.t (** To be called after processing a directory. Emit warnings about detected problems *) diff --git a/src/ocamldep.ml b/src/ocamldep.ml index bfbbbf9a..cd79f04e 100644 --- a/src/ocamldep.ml +++ b/src/ocamldep.ml @@ -6,39 +6,41 @@ module SC = Super_context module Dep_graph = struct type t = { dir : Path.t - ; per_module : (unit, Module.t list) Build.t String_map.t + ; per_module : (unit, Module.t list) Build.t Module.Name.Map.t } let deps_of t (m : Module.t) = - match String_map.find t.per_module m.name with + match Module.Name.Map.find t.per_module m.name with | Some x -> x | None -> Sexp.code_error "Ocamldep.Dep_graph.deps_of" [ "dir", Path.sexp_of_t t.dir - ; "modules", Sexp.To_sexp.(list string) (String_map.keys t.per_module) - ; "module", Sexp.atom m.name + ; "modules", Sexp.To_sexp.(list Module.Name.t) + (Module.Name.Map.keys t.per_module) + ; "module", Module.Name.t m.name ] module Dep_closure = - Top_closure.Make(String)(struct + Top_closure.Make(Module.Name)(struct type t = Module.t - type graph = t list String_map.t + type graph = t list Module.Name.Map.t let key (t : t) = t.name - let deps t map = Option.value_exn (String_map.find map (key t)) + let deps t map = Option.value_exn (Module.Name.Map.find map (key t)) end) let top_closed t modules = Build.all - (List.map (String_map.to_list t.per_module) ~f:(fun (unit, deps) -> + (List.map (Module.Name.Map.to_list t.per_module) ~f:(fun (unit, deps) -> deps >>^ fun deps -> (unit, deps))) >>^ fun per_module -> - let per_module = String_map.of_list_exn per_module in + let per_module = Module.Name.Map.of_list_exn per_module in match Dep_closure.top_closure per_module modules with | Ok modules -> modules | Error cycle -> - die "dependency cycle between modules in %s:\n %s" (Path.to_string t.dir) - (String.concat ~sep:"\n-> " - (List.map cycle ~f:Module.name)) + die "dependency cycle between modules in %s:\n %a" + (Path.to_string t.dir) + (Fmt.list ~pp_sep:Fmt.nl (Fmt.prefix (Fmt.string "-> ") Module.Name.pp)) + (List.map cycle ~f:Module.name) let top_closed_implementations t modules = Build.memoize "top sorted implementations" ( @@ -48,7 +50,7 @@ module Dep_graph = struct let dummy (m : Module.t) = { dir = Path.root - ; per_module = String_map.singleton m.name (Build.return []) + ; per_module = Module.Name.Map.singleton m.name (Build.return []) } end @@ -83,10 +85,11 @@ let parse_deps ~dir ~file ~(unit : Module.t) String.extract_blank_separated_words (String.sub line ~pos:(i + 1) ~len:(String.length line - (i + 1))) |> List.filter_map ~f:(fun m -> + let m = Module.Name.of_string m in if m = unit.name then None else - String_map.find modules m) + Module.Name.Map.find modules m) in (match lib_interface_module with | None -> () @@ -98,15 +101,17 @@ let parse_deps ~dir ~file ~(unit : Module.t) in if unit.name <> m.name && not is_alias_module && List.exists deps ~f:(fun x -> Module.name x = m.name) then - die "Module %s in directory %s depends on %s.\n\ + die "Module %a in directory %s depends on %a.\n\ This doesn't make sense to me.\n\ \n\ - %s is the main module of the library and is \ + %a is the main module of the library and is \ the only module exposed \n\ outside of the library. Consequently, it should \ be the one depending \n\ on all the other modules in the library." - unit.name (Path.to_string dir) m.name m.name); + Module.Name.pp unit.name (Path.to_string dir) + Module.Name.pp m.name + Module.Name.pp m.name); let deps = match alias_module with | None -> deps @@ -115,16 +120,16 @@ let parse_deps ~dir ~file ~(unit : Module.t) deps let rules ~(ml_kind:Ml_kind.t) ~dir ~modules - ?(already_used=String_set.empty) + ?(already_used=Module.Name.Set.empty) ~alias_module ~lib_interface_module sctx = let per_module = - String_map.map modules ~f:(fun unit -> + Module.Name.Map.map modules ~f:(fun unit -> match Module.file ~dir unit ml_kind with | None -> Build.return [] | Some file -> let ocamldep_output = Path.extend_basename file ~suffix:".d" in let context = SC.context sctx in - if not (String_set.mem already_used unit.name) then + if not (Module.Name.Set.mem already_used unit.name) then SC.add_rule sctx (Build.run ~context (Ok context.ocamldep) [A "-modules"; Ml_kind.flag ml_kind; Dep file] @@ -137,7 +142,7 @@ let rules ~(ml_kind:Ml_kind.t) ~dir ~modules let per_module = match alias_module with | None -> per_module - | Some m -> String_map.add per_module m.name (Build.return []) + | Some m -> Module.Name.Map.add per_module m.name (Build.return []) in { Dep_graph. dir diff --git a/src/ocamldep.mli b/src/ocamldep.mli index 85ddfe41..685c23a7 100644 --- a/src/ocamldep.mli +++ b/src/ocamldep.mli @@ -1,6 +1,4 @@ -(** ocamldep managenemt *) - -open Import +(** ocamldep management *) module Dep_graph : sig type t @@ -36,8 +34,8 @@ end Return arrows that evaluate to the dependency graphs. *) val rules : dir:Path.t - -> modules:Module.t String_map.t - -> ?already_used:String_set.t + -> modules:Module.t Module.Name.Map.t + -> ?already_used:Module.Name.Set.t -> alias_module:Module.t option -> lib_interface_module:Module.t option -> Super_context.t diff --git a/src/odoc.ml b/src/odoc.ml index 544f64f7..c011a24c 100644 --- a/src/odoc.ml +++ b/src/odoc.ml @@ -198,7 +198,8 @@ let all_mld_files sctx ~(lib : Library.t) ~modules ~dir files = "{1 Library %s}\n\ This library exposes the following toplevel modules: {!modules:%s}." lib_name - (String_map.keys modules |> String.concat ~sep:" ")))) + ((Module.Name.Map.keys modules :> string list) + |> String.concat ~sep:" ")))) >>> Build.write_file_dyn generated_mld); mld @@ -242,7 +243,7 @@ let setup_library_rules sctx (lib : Library.t) ~dir ~scope ~modules ~mld_files ~doc_dir ~lib_unique_name (Mld m)) in let modules_and_odoc_files = - List.map (String_map.values modules) ~f:(fun m -> + List.map (Module.Name.Map.values modules) ~f:(fun m -> compile sctx ~odoc ~dir ~obj_dir ~includes ~dep_graphs ~doc_dir ~lib_unique_name (Module m)) in diff --git a/src/odoc.mli b/src/odoc.mli index 260b66ba..655d05e1 100644 --- a/src/odoc.mli +++ b/src/odoc.mli @@ -1,6 +1,5 @@ (** Odoc rules *) -open Import open Jbuild val setup_library_rules @@ -8,7 +7,7 @@ val setup_library_rules -> Library.t -> dir:Path.t -> scope:Scope.t - -> modules:Module.t String_map.t + -> modules:Module.t Module.Name.Map.t -> mld_files:string list -> requires:(unit, Lib.t list) Build.t -> dep_graphs:Ocamldep.Dep_graphs.t diff --git a/src/preprocessing.ml b/src/preprocessing.ml index c0f55104..4d539b1f 100644 --- a/src/preprocessing.ml +++ b/src/preprocessing.ml @@ -365,5 +365,5 @@ let pp_and_lint_modules sctx ~dir ~dep_kind ~modules ~lint ~preprocess ; Ml_kind.ppx_driver_flag kind; Dep src ]))))) in - String_map.map modules ~f:(fun (m : Module.t) -> + Module.Name.Map.map modules ~f:(fun (m : Module.t) -> Per_module.get preprocess m.name m) diff --git a/src/preprocessing.mli b/src/preprocessing.mli index 736d9638..a323b19a 100644 --- a/src/preprocessing.mli +++ b/src/preprocessing.mli @@ -8,13 +8,13 @@ val pp_and_lint_modules : Super_context.t -> dir:Path.t -> dep_kind:Build.lib_dep_kind - -> modules:Module.t String_map.t + -> modules:Module.t Module.Name.Map.t -> lint:Jbuild.Preprocess_map.t -> preprocess:Jbuild.Preprocess_map.t -> preprocessor_deps:(unit, Path.t list) Build.t -> lib_name:string option -> scope:Scope.t - -> Module.t String_map.t + -> Module.t Module.Name.Map.t (** Get a path to a cached ppx driver *) val get_ppx_driver diff --git a/src/sub_system_intf.ml b/src/sub_system_intf.ml index aa16ada3..948bffef 100644 --- a/src/sub_system_intf.ml +++ b/src/sub_system_intf.ml @@ -67,7 +67,7 @@ module Library_compilation_context = struct ; dir : Path.t ; stanza : Jbuild.Library.t ; scope : Scope.t - ; source_modules : Module.t String_map.t + ; source_modules : Module.t Module.Name.Map.t ; compile_info : Lib.Compile.t } end diff --git a/src/utop.ml b/src/utop.ml index d8cca6e8..99ba693a 100644 --- a/src/utop.ml +++ b/src/utop.ml @@ -4,7 +4,7 @@ open Build.O open! No_io let exe_name = "utop" -let main_module_name = String.capitalize exe_name +let main_module_name = Module.Name.of_string exe_name let main_module_filename = exe_name ^ ".ml" let pp_ml fmt include_dirs = @@ -51,7 +51,7 @@ let setup sctx ~dir ~(libs : Library.t list) ~scope = | [] -> () | _ :: _ -> let modules = - String_map.singleton + Module.Name.Map.singleton main_module_name { Module. name = main_module_name