Module LibobjectSource

Libobject declares persistent objects, given with methods:

* a caching function specifying how to add the object in the current scope; If the object wishes to register its visibility in the Nametab, it should do so for all possible suffixes.

* a loading function, specifying what to do when the module containing the object is loaded; If the object wishes to register its visibility in the Nametab, it should do so for all suffixes no shorter than the "int" argument

* an opening function, specifying what to do when the module containing the object is opened (imported); If the object wishes to register its visibility in the Nametab, it should do so for the suffix of the length the "int" argument

* a classification function, specifying what to do with the object, when the current module (containing the object) is ended; The possibilities are: Dispose - the object dies at the end of the module Substitute - meaning the object is substitutive and the module name must be updated Keep - the object is not substitutive, but survives module closing Anticipate - this is for objects that have to be explicitly managed by the end_module function (like Require and Read markers)

The classification function is also an occasion for a cleanup (if this function returns Keep or Substitute of some object, the cache method is never called for it)

* a substitution function, performing the substitution; this function should be declared for substitutive objects only (see above). NB: the substitution might now be delayed instead of happening at module creation, so this function should _not_ depend on the current environment

* a discharge function, that is applied at section closing time to collect the data necessary to rebuild the discharged form of the non volatile objects

* a rebuild function, that is applied after section closing to rebuild the non volatile content of a section from the data collected by the discharge function

Any type defined as a persistent object must be pure (e.g. no references) and marshallable by the OCaml Marshal module (e.g. no closures).

Sourcetype 'a substitutivity =
  1. | Dispose
  2. | Substitute of 'a
  3. | Keep of 'a
  4. | Anticipate of 'a

Both names are passed to objects: a "semantic" kernel_name, which can be substituted and a "syntactic" full_path which can be printed

Sourcetype open_filter =
  1. | Unfiltered
  2. | Names of Globnames.ExtRefSet.t
Sourcetype 'a object_declaration = {
  1. object_name : string;
  2. cache_function : (object_name * 'a) -> unit;
  3. load_function : int -> (object_name * 'a) -> unit;
  4. open_function : open_filter -> int -> (object_name * 'a) -> unit;
  5. classify_function : 'a -> 'a substitutivity;
  6. subst_function : (Mod_subst.substitution * 'a) -> 'a;
  7. discharge_function : (object_name * 'a) -> 'a option;
  8. rebuild_function : 'a -> 'a;
}
Sourceval simple_open : (int -> (object_name * 'a) -> unit) -> open_filter -> int -> (object_name * 'a) -> unit

Combinator for making objects which are only opened by unfiltered Import

Sourceval filter_and : open_filter -> open_filter -> open_filter option

Returns None when the intersection is empty.

Sourceval in_filter_ref : Names.GlobRef.t -> open_filter -> bool

The default object is a "Keep" object with empty methods. Object creators are advised to use the construction {(default_object "MY_OBJECT") with cache_function = ... } and specify only these functions which are not empty/meaningless

Sourceval default_object : string -> 'a object_declaration
Sourceval ident_subst_function : (Mod_subst.substitution * 'a) -> 'a

the identity substitution function

...

Given an object declaration, the function declare_object_full will hand back two functions, the "injection" and "projection" functions for dynamically typed library-objects.

Sourcemodule Dyn : Dyn.S
Sourcetype obj = Dyn.t
Sourcetype algebraic_objects =
  1. | Objs of objects
  2. | Ref of Names.ModPath.t * Mod_subst.substitution
Sourceand t =
  1. | ModuleObject of substitutive_objects
  2. | ModuleTypeObject of substitutive_objects
  3. | IncludeObject of algebraic_objects
  4. | KeepObject of objects
  5. | ExportObject of {
    1. mpl : (open_filter * Names.ModPath.t) list;
    }
  6. | AtomicObject of obj
Sourceand objects = (Names.Id.t * t) list
Sourceand substitutive_objects = Names.MBId.t list * algebraic_objects
Sourceval declare_object_full : 'a object_declaration -> 'a Dyn.tag
Sourceval declare_object : 'a object_declaration -> 'a -> obj
Sourceval cache_object : (object_name * obj) -> unit
Sourceval load_object : int -> (object_name * obj) -> unit
Sourceval open_object : open_filter -> int -> (object_name * obj) -> unit
Sourceval subst_object : (Mod_subst.substitution * obj) -> obj
Sourceval classify_object : obj -> obj substitutivity
Sourceval discharge_object : (object_name * obj) -> obj option
Sourceval rebuild_object : obj -> obj

Higher-level API for objects with fixed scope.

We recommend to avoid declaring superglobal objects and using the nodischarge variants.

Sourceval local_object : string -> cache:((object_name * 'a) -> unit) -> discharge:((object_name * 'a) -> 'a option) -> 'a object_declaration
Sourceval local_object_nodischarge : string -> cache:((object_name * 'a) -> unit) -> 'a object_declaration
Sourceval global_object : string -> cache:((object_name * 'a) -> unit) -> subst:((Mod_subst.substitution * 'a) -> 'a) option -> discharge:((object_name * 'a) -> 'a option) -> 'a object_declaration
Sourceval global_object_nodischarge : string -> cache:((object_name * 'a) -> unit) -> subst:((Mod_subst.substitution * 'a) -> 'a) option -> 'a object_declaration
Sourceval superglobal_object : string -> cache:((object_name * 'a) -> unit) -> subst:((Mod_subst.substitution * 'a) -> 'a) option -> discharge:((object_name * 'a) -> 'a option) -> 'a object_declaration
Sourceval superglobal_object_nodischarge : string -> cache:((object_name * 'a) -> unit) -> subst:((Mod_subst.substitution * 'a) -> 'a) option -> 'a object_declaration
Debug
Sourceval dump : unit -> (int * string) list