diff options
| author | Enrico Tassi | 2019-09-17 10:29:48 +0200 |
|---|---|---|
| committer | Enrico Tassi | 2019-09-17 10:29:48 +0200 |
| commit | c18f04422cb0827994e8d7aecc384a2c448a61c9 (patch) | |
| tree | 341c0e48158cd4a732751c6aed00c9c864dbff52 /library | |
| parent | 3d7de72f45ae2f8bcedbe1db0eb8870e58757b45 (diff) | |
| parent | 73b9794cc21e9fe932d5be9836fe1c53659ba717 (diff) | |
Merge PR #10476: Remove library-specific code for `Import`.
Reviewed-by: gares
Reviewed-by: ppedrot
Diffstat (limited to 'library')
| -rw-r--r-- | library/declaremods.ml | 116 | ||||
| -rw-r--r-- | library/declaremods.mli | 15 | ||||
| -rw-r--r-- | library/lib.ml | 9 | ||||
| -rw-r--r-- | library/libobject.ml | 2 | ||||
| -rw-r--r-- | library/libobject.mli | 2 |
5 files changed, 97 insertions, 47 deletions
diff --git a/library/declaremods.ml b/library/declaremods.ml index eea129eae7..b4dc42bdfe 100644 --- a/library/declaremods.ml +++ b/library/declaremods.ml @@ -110,9 +110,9 @@ and subst_objects subst seg = | IncludeObject aobjs -> let aobjs' = subst_aobjs subst aobjs in if aobjs' == aobjs then node else (id, IncludeObject aobjs') - | ImportObject { export; mp } -> - let mp' = subst_mp subst mp in - if mp'==mp then node else (id, ImportObject { export; mp = mp' }) + | ExportObject { mpl } -> + let mpl' = List.map (subst_mp subst) mpl in + if mpl'==mpl then node else (id, ExportObject { mpl = mpl' }) | KeepObject _ -> assert false in List.Smart.map subst_one seg @@ -151,7 +151,11 @@ let expand_sobjs (_,aobjs) = expand_aobjs aobjs Module M:SIG. ... End M. have the keep list empty. *) -type module_objects = Nametab.object_prefix * Lib.lib_objects * Lib.lib_objects +type module_objects = + { module_prefix : Nametab.object_prefix; + module_substituted_objects : Lib.lib_objects; + module_keep_objects : Lib.lib_objects; + } module ModObjs : sig @@ -217,7 +221,13 @@ let do_module exists iter_objects i obj_dir obj_mp sobjs kobjs = (* If we're not a functor, let's iter on the internal components *) if sobjs_no_functor sobjs then begin let objs = expand_sobjs sobjs in - ModObjs.set obj_mp (prefix,objs,kobjs); + let module_objects = + { module_prefix = prefix; + module_substituted_objects = objs; + module_keep_objects = kobjs; + } + in + ModObjs.set obj_mp module_objects; iter_objects (i+1) prefix objs; iter_objects (i+1) prefix kobjs end @@ -233,7 +243,7 @@ let do_module' exists iter_objects i ((sp,kn),sobjs) = (** Nota: Interactive modules and module types cannot be recached! This used to be checked more properly here. *) -let do_modtype i sp mp sobjs = +let load_modtype i sp mp sobjs = if Nametab.exists_modtype sp then anomaly (pr_path sp ++ str " already exists."); Nametab.push_modtype (Nametab.Until i) sp mp; @@ -247,9 +257,9 @@ let rec load_object i (name, obj) = | ModuleObject sobjs -> do_module' false load_objects i (name, sobjs) | ModuleTypeObject sobjs -> let (sp,kn) = name in - do_modtype i sp (mp_of_kn kn) sobjs + load_modtype i sp (mp_of_kn kn) sobjs | IncludeObject aobjs -> load_include i (name, aobjs) - | ImportObject _ -> () + | ExportObject _ -> () | KeepObject objs -> load_keep i (name, objs) and load_objects i prefix objs = @@ -266,32 +276,69 @@ and load_keep i ((sp,kn),kobjs) = (* Invariant : seg isn't empty *) let obj_dir = dir_of_sp sp and obj_mp = mp_of_kn kn in let prefix = Nametab.{ obj_dir ; obj_mp; obj_sec = DirPath.empty } in - let prefix',sobjs,kobjs0 = + let modobjs = try ModObjs.get obj_mp with Not_found -> assert false (* a substobjs should already be loaded *) in - assert Nametab.(eq_op prefix' prefix); - assert (List.is_empty kobjs0); - ModObjs.set obj_mp (prefix,sobjs,kobjs); + assert Nametab.(eq_op modobjs.module_prefix prefix); + assert (List.is_empty modobjs.module_keep_objects); + ModObjs.set obj_mp { modobjs with module_keep_objects = kobjs }; load_objects i prefix kobjs (** {6 Implementation of Import and Export commands} *) -let rec really_import_module mp = +let mark_object obj (exports,acc) = + (exports, obj::acc) + +let rec collect_module_objects mp acc = (* May raise Not_found for unknown module and for functors *) - let prefix,sobjs,keepobjs = ModObjs.get mp in - open_objects 1 prefix sobjs; - open_objects 1 prefix keepobjs + let modobjs = ModObjs.get mp in + let prefix = modobjs.module_prefix in + let acc = collect_objects 1 prefix modobjs.module_keep_objects acc in + collect_objects 1 prefix modobjs.module_substituted_objects acc + +and collect_object i (name, obj as o) acc = + match obj with + | ExportObject { mpl; _ } -> collect_export i mpl acc + | AtomicObject _ | IncludeObject _ | KeepObject _ + | ModuleObject _ | ModuleTypeObject _ -> mark_object o acc + +and collect_objects i prefix objs acc = + List.fold_right (fun (id, obj) acc -> collect_object i (Lib.make_oname prefix id, obj) acc) objs acc + +and collect_one_export mp (exports,objs as acc) = + if not (MPset.mem mp exports) then + collect_module_objects mp (MPset.add mp exports, objs) + else acc + +and collect_export i mpl acc = + if Int.equal i 1 then + List.fold_right collect_one_export mpl acc + else acc -and open_object i (name, obj) = +let rec open_object i (name, obj) = match obj with | AtomicObject o -> Libobject.open_object i (name, o) - | ModuleObject sobjs -> do_module' true open_objects i (name, sobjs) + | ModuleObject sobjs -> + let dir = dir_of_sp (fst name) in + let mp = mp_of_kn (snd name) in + open_module i dir mp sobjs | ModuleTypeObject sobjs -> open_modtype i (name, sobjs) | IncludeObject aobjs -> open_include i (name, aobjs) - | ImportObject { mp; _ } -> open_import i mp + | ExportObject { mpl; _ } -> open_export i mpl | KeepObject objs -> open_keep i (name, objs) +and open_module i obj_dir obj_mp sobjs = + let prefix = Nametab.{ obj_dir ; obj_mp; obj_sec = DirPath.empty } in + let dirinfo = Nametab.GlobDirRef.DirModule prefix in + consistency_checks true obj_dir dirinfo; + Nametab.push_dir (Nametab.Exactly i) obj_dir dirinfo; + (* If we're not a functor, let's iter on the internal components *) + if sobjs_no_functor sobjs then begin + let modobjs = ModObjs.get obj_mp in + open_objects (i+1) modobjs.module_prefix modobjs.module_substituted_objects + end + and open_objects i prefix objs = List.iter (fun (id, obj) -> open_object i (Lib.make_oname prefix id, obj)) objs @@ -312,8 +359,9 @@ and open_include i ((sp,kn), aobjs) = let o = expand_aobjs aobjs in open_objects i prefix o -and open_import i mp = - if Int.equal i 1 then really_import_module mp +and open_export i mpl = + let _,objs = collect_export i mpl (MPset.empty, []) in + List.iter (open_object 1) objs and open_keep i ((sp,kn),kobjs) = let obj_dir = dir_of_sp sp and obj_mp = mp_of_kn kn in @@ -326,9 +374,9 @@ let rec cache_object (name, obj) = | ModuleObject sobjs -> do_module' false load_objects 1 (name, sobjs) | ModuleTypeObject sobjs -> let (sp,kn) = name in - do_modtype 1 sp (mp_of_kn kn) sobjs + load_modtype 0 sp (mp_of_kn kn) sobjs | IncludeObject aobjs -> cache_include (name, aobjs) - | ImportObject { mp } -> really_import_module mp + | ExportObject { mpl } -> anomaly Pp.(str "Export should not be cached") | KeepObject objs -> cache_keep (name, objs) and cache_include ((sp,kn), aobjs) = @@ -975,9 +1023,13 @@ let end_library ?except ~output_native_objects dir = let substitute, keep, _ = Lib.classify_segment lib_stack in cenv,(substitute,keep),ast -let import_module export mp = - really_import_module mp; - Lib.add_anonymous_entry (Lib.Leaf (ImportObject { export; mp })) +let import_modules ~export mpl = + let _,objs = List.fold_right collect_module_objects mpl (MPset.empty, []) in + List.iter (open_object 1) objs; + if export then Lib.add_anonymous_entry (Lib.Leaf (ExportObject { mpl })) + +let import_module ~export mp = + import_modules ~export [mp] (** {6 Iterators} *) @@ -988,9 +1040,10 @@ let iter_all_segments f = List.iter (apply_obj prefix) objs | _ -> f (Lib.make_oname prefix id) obj in - let apply_mod_obj _ (prefix,substobjs,keepobjs) = - List.iter (apply_obj prefix) substobjs; - List.iter (apply_obj prefix) keepobjs + let apply_mod_obj _ modobjs = + let prefix = modobjs.module_prefix in + List.iter (apply_obj prefix) modobjs.module_substituted_objects; + List.iter (apply_obj prefix) modobjs.module_keep_objects in let apply_node = function | sp, Lib.Leaf o -> f sp o @@ -1016,9 +1069,10 @@ let debug_print_modtab _ = | [] -> str "[]" | l -> str "[." ++ int (List.length l) ++ str ".]" in - let pr_modinfo mp (prefix,substobjs,keepobjs) s = + let pr_modinfo mp modobjs s = + let objs = modobjs.module_substituted_objects @ modobjs.module_keep_objects in s ++ str (ModPath.to_string mp) ++ (spc ()) - ++ (pr_seg (Lib.segment_of_objects prefix (substobjs@keepobjs))) + ++ (pr_seg (Lib.segment_of_objects modobjs.module_prefix objs)) in let modules = MPmap.fold pr_modinfo (ModObjs.all ()) (mt ()) in hov 0 modules diff --git a/library/declaremods.mli b/library/declaremods.mli index ada53dbff0..b7c7cd1dba 100644 --- a/library/declaremods.mli +++ b/library/declaremods.mli @@ -103,18 +103,17 @@ val end_library : (** append a function to be executed at end_library *) val append_end_library_hook : (unit -> unit) -> unit -(** [really_import_module mp] opens the module [mp] (in a Caml sense). +(** [import_module export mp] imports the module [mp]. It modifies Nametab and performs the [open_object] function for every object of the module. Raises [Not_found] when [mp] is unknown - or when [mp] corresponds to a functor. *) - -val really_import_module : ModPath.t -> unit - -(** [import_module export mp] is a synchronous version of - [really_import_module]. If [export] is [true], the module is also + or when [mp] corresponds to a functor. If [export] is [true], the module is also opened every time the module containing it is. *) -val import_module : bool -> ModPath.t -> unit +val import_module : export:bool -> ModPath.t -> unit + +(** Same as [import_module] but for multiple modules, and more optimized than + iterating [import_module]. *) +val import_modules : export:bool -> ModPath.t list -> unit (** Include *) diff --git a/library/lib.ml b/library/lib.ml index 3f51826315..851f086961 100644 --- a/library/lib.ml +++ b/library/lib.ml @@ -73,11 +73,8 @@ let classify_segment seg = clean ((id,o)::substl, keepl, anticipl) stk | KeepObject _ -> clean (substl, (id,o)::keepl, anticipl) stk - | ImportObject { export } -> - if export then - clean ((id,o)::substl, keepl, anticipl) stk - else - clean acc stk + | ExportObject _ -> + clean ((id,o)::substl, keepl, anticipl) stk | AtomicObject obj -> begin match classify_object obj with | Dispose -> clean acc stk @@ -615,7 +612,7 @@ let discharge_item ((sp,_ as oname),e) = | Leaf lobj -> begin match lobj with | ModuleObject _ | ModuleTypeObject _ | IncludeObject _ | KeepObject _ - | ImportObject _ -> None + | ExportObject _ -> None | AtomicObject obj -> Option.map (fun o -> (basename sp,o)) (discharge_object (oname,obj)) end diff --git a/library/libobject.ml b/library/libobject.ml index 27e7810e6c..932f065f73 100644 --- a/library/libobject.ml +++ b/library/libobject.ml @@ -75,7 +75,7 @@ and t = | ModuleTypeObject of substitutive_objects | IncludeObject of algebraic_objects | KeepObject of objects - | ImportObject of { export : bool; mp : ModPath.t } + | ExportObject of { mpl : ModPath.t list } | AtomicObject of obj and objects = (Names.Id.t * t) list diff --git a/library/libobject.mli b/library/libobject.mli index 3b37db4a6f..146ccc293f 100644 --- a/library/libobject.mli +++ b/library/libobject.mli @@ -112,7 +112,7 @@ and t = | ModuleTypeObject of substitutive_objects | IncludeObject of algebraic_objects | KeepObject of objects - | ImportObject of { export : bool; mp : Names.ModPath.t } + | ExportObject of { mpl : Names.ModPath.t list } | AtomicObject of obj and objects = (Names.Id.t * t) list |
