(* * Copyright (c) 2014 Leo White * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) module Ocaml_ident = Ident module Ocaml_env = Env open Names module Identifier = struct type 'a id = 'a Paths_types.id = { iv : 'a; ihash : int; ikey : string } module Id = Paths_types.Identifier type t = Id.any type t_pv = Id.any_pv let rec name_aux : t -> string = fun x -> match x.iv with | `Root (_, name) -> ModuleName.to_string name | `Page (_, name) -> PageName.to_string name | `LeafPage (_, name) -> PageName.to_string name | `Module (_, name) -> ModuleName.to_string name | `Parameter (_, name) -> ModuleName.to_string name | `Result x -> name_aux (x :> t) | `ModuleType (_, name) -> ModuleTypeName.to_string name | `Type (_, name) -> TypeName.to_string name | `Constructor (_, name) -> ConstructorName.to_string name | `Field (_, name) -> FieldName.to_string name | `UnboxedField (_, name) -> UnboxedFieldName.to_string name | `Extension (_, name) -> ExtensionName.to_string name | `ExtensionDecl (_, _, name) -> ExtensionName.to_string name | `Exception (_, name) -> ExceptionName.to_string name | `Value (_, name) -> ValueName.to_string name | `Class (_, name) -> TypeName.to_string name | `ClassType (_, name) -> TypeName.to_string name | `Method (_, name) -> MethodName.to_string name | `InstanceVariable (_, name) -> InstanceVariableName.to_string name | `Label (_, name) -> LabelName.to_string name | `SourcePage (_, name) -> name | `SourceLocation (x, anchor) -> name_aux (x :> t) ^ "#" ^ DefName.to_string anchor | `SourceLocationMod x -> name_aux (x :> t) | `SourceLocationInternal (x, anchor) -> name_aux (x :> t) ^ "#" ^ LocalName.to_string anchor | `AssetFile (_, name) -> AssetName.to_string name let rec is_hidden : t -> bool = fun x -> match x.iv with | `Root (_, name) -> ModuleName.is_hidden name | `Page (_, _) -> false | `LeafPage (_, _) -> false | `Module (_, name) -> ModuleName.is_hidden name | `Parameter (_, name) -> ModuleName.is_hidden name | `Result x -> is_hidden (x :> t) | `ModuleType (_, name) -> ModuleTypeName.is_hidden name | `Type (_, name) -> TypeName.is_hidden name | `Constructor (parent, _) -> is_hidden (parent :> t) | `Field (parent, _) -> is_hidden (parent :> t) | `UnboxedField (parent, _) -> is_hidden (parent :> t) | `Extension (parent, _) -> is_hidden (parent :> t) | `ExtensionDecl (parent, _, _) -> is_hidden (parent :> t) | `Exception (parent, _) -> is_hidden (parent :> t) | `Value (_, name) -> ValueName.is_hidden name | `Class (_, name) -> TypeName.is_hidden name | `ClassType (_, name) -> TypeName.is_hidden name | `Method (parent, _) -> is_hidden (parent :> t) | `InstanceVariable (parent, _) -> is_hidden (parent :> t) | `Label (parent, _) -> is_hidden (parent :> t) | `SourceLocationMod _ | `SourceLocation _ | `SourcePage _ | `SourceLocationInternal _ | `AssetFile _ -> false let name : [< t_pv ] id -> string = fun n -> name_aux (n :> t) let rec full_name_aux : t -> string list = fun x -> match x.iv with | `Root (_, name) -> [ ModuleName.to_string name ] | `Page (None, name) -> [ PageName.to_string name ] | `Page (Some parent, name) -> PageName.to_string name :: full_name_aux (parent :> t) | `LeafPage (None, name) -> [ PageName.to_string name ] | `LeafPage (Some parent, name) -> PageName.to_string name :: full_name_aux (parent :> t) | `Module (parent, name) -> ModuleName.to_string name :: full_name_aux (parent :> t) | `Parameter (parent, name) -> ModuleName.to_string name :: full_name_aux (parent :> t) | `Result x -> full_name_aux (x :> t) | `ModuleType (parent, name) -> ModuleTypeName.to_string name :: full_name_aux (parent :> t) | `Type (parent, name) -> TypeName.to_string name :: full_name_aux (parent :> t) | `Constructor (parent, name) -> ConstructorName.to_string name :: full_name_aux (parent :> t) | `Field (parent, name) -> FieldName.to_string name :: full_name_aux (parent :> t) | `UnboxedField (parent, name) -> UnboxedFieldName.to_string name :: full_name_aux (parent :> t) | `Extension (parent, name) -> ExtensionName.to_string name :: full_name_aux (parent :> t) | `ExtensionDecl (parent, _, name) -> ExtensionName.to_string name :: full_name_aux (parent :> t) | `Exception (parent, name) -> ExceptionName.to_string name :: full_name_aux (parent :> t) | `Value (parent, name) -> ValueName.to_string name :: full_name_aux (parent :> t) | `Class (parent, name) -> TypeName.to_string name :: full_name_aux (parent :> t) | `ClassType (parent, name) -> TypeName.to_string name :: full_name_aux (parent :> t) | `Method (parent, name) -> MethodName.to_string name :: full_name_aux (parent :> t) | `InstanceVariable (parent, name) -> InstanceVariableName.to_string name :: full_name_aux (parent :> t) | `Label (parent, name) -> LabelName.to_string name :: full_name_aux (parent :> t) | `SourceLocation (parent, name) -> DefName.to_string name :: full_name_aux (parent :> t) | `SourceLocationInternal (parent, name) -> LocalName.to_string name :: full_name_aux (parent :> t) | `SourceLocationMod name -> full_name_aux (name :> t) | `SourcePage (parent, name) -> name :: full_name_aux (parent :> t) | `AssetFile (parent, name) -> AssetName.to_string name :: full_name_aux (parent :> t) let fullname : [< t_pv ] id -> string list = fun n -> List.rev @@ full_name_aux (n :> t) let is_hidden : [< t_pv ] id -> bool = fun n -> is_hidden (n :> t) let rec label_parent_aux = let open Id in fun (n : non_src) -> match n with | { iv = `Result i; _ } -> label_parent_aux (i :> non_src) | { iv = `Root _; _ } as p -> (p :> label_parent) | { iv = `Page _; _ } as p -> (p :> label_parent) | { iv = `LeafPage _; _ } as p -> (p :> label_parent) | { iv = `Module (p, _); _ } | { iv = `ModuleType (p, _); _ } | { iv = `Parameter (p, _); _ } | { iv = `Class (p, _); _ } | { iv = `ClassType (p, _); _ } | { iv = `Type (p, _); _ } | { iv = `Extension (p, _); _ } | { iv = `ExtensionDecl (p, _, _); _ } | { iv = `Exception (p, _); _ } | { iv = `Value (p, _); _ } -> (p : signature :> label_parent) | { iv = `Label (p, _); _ } -> p | { iv = `Method (p, _); _ } | { iv = `InstanceVariable (p, _); _ } -> (p : class_signature :> label_parent) | { iv = `Constructor (p, _); _ } -> (p : datatype :> label_parent) | { iv = `Field (p, _); _ } -> (p : field_parent :> label_parent) | { iv = `UnboxedField (p, _); _ } -> (p : unboxed_field_parent :> label_parent) let label_parent n = label_parent_aux (n :> Id.non_src) let equal x y = x.ihash = y.ihash && x.ikey = y.ikey let hash x = x.ihash let compare x y = compare x.ikey y.ikey type any = t type any_pv = t_pv module type IdSig = sig type t type t_pv val equal : t -> t -> bool val hash : t -> int val compare : t -> t -> int end module Any = struct type t = any type t_pv = any_pv let equal = equal let hash = hash let compare = compare end module Signature = struct type t = Id.signature type t_pv = Id.signature_pv let equal = equal let hash = hash let compare = compare end module ClassSignature = struct type t = Id.class_signature type t_pv = Id.class_signature_pv let equal = equal let hash = hash let compare = compare end module DataType = struct type t = Id.datatype type t_pv = Id.datatype_pv end module FieldParent = struct type t = Paths_types.Identifier.field_parent type t_pv = Paths_types.Identifier.field_parent_pv end module UnboxedFieldParent = struct type t = Paths_types.Identifier.unboxed_field_parent type t_pv = Paths_types.Identifier.unboxed_field_parent_pv end module LabelParent = struct type t = Id.label_parent type t_pv = Id.label_parent_pv let equal = equal let hash = hash let compare = compare end module RootModule = struct type t = Id.root_module type t_pv = Id.root_module_pv let equal = equal let hash = hash let compare = compare end module Module = struct type t = Id.module_ type t_pv = Id.module_pv let equal = equal let hash = hash let compare = compare end module FunctorParameter = struct type t = Id.functor_parameter type t_pv = Id.functor_parameter_pv let equal = equal let hash = hash let compare = compare let functor_arg_pos { iv = `Parameter (p, _); _ } = let rec inner_sig = function | `Result { iv = p; _ } -> 1 + inner_sig p | `Module _ | `ModuleType _ | `Root _ | `Parameter _ -> 1 in inner_sig p.iv end module FunctorResult = struct type t = Id.functor_result type t_pv = Id.functor_result_pv end module ModuleType = struct type t = Id.module_type type t_pv = Id.module_type_pv let equal = equal let hash = hash let compare = compare end module Type = struct type t = Id.type_ type t_pv = Id.type_pv let equal = equal let hash = hash let compare = compare end module Constructor = struct type t = Id.constructor type t_pv = Id.constructor_pv end module Field = struct type t = Id.field type t_pv = Id.field_pv end module UnboxedField = struct type t = Id.unboxed_field type t_pv = Id.unboxed_field_pv end module Extension = struct type t = Id.extension type t_pv = Id.extension_pv end module ExtensionDecl = struct type t = Paths_types.Identifier.extension_decl type t_pv = Paths_types.Identifier.extension_decl_pv let equal = equal let hash = hash let compare = compare end module Exception = struct type t = Id.exception_ type t_pv = Id.exception_pv end module Value = struct type t = Id.value type t_pv = Id.value_pv end module Class = struct type t = Id.class_ type t_pv = Id.class_pv let equal = equal let hash = hash let compare = compare end module ClassType = struct type t = Id.class_type type t_pv = Id.class_type_pv let equal = equal let hash = hash let compare = compare end module Method = struct type t = Id.method_ type t_pv = Id.method_pv end module InstanceVariable = struct type t = Id.instance_variable type t_pv = Id.instance_variable_pv end module Label = struct type t = Paths_types.Identifier.label type t_pv = Paths_types.Identifier.label_pv let equal = equal let hash = hash let compare = compare end module Page = struct type t = Id.page type t_pv = Id.page_pv end module LeafPage = struct type t = Id.leaf_page type t_pv = Id.leaf_page_pv let equal = equal let hash = hash end module ContainerPage = struct type t = Id.container_page type t_pv = Id.container_page_pv let equal = equal let hash = hash end module NonSrc = struct type t = Paths_types.Identifier.non_src type t_pv = Paths_types.Identifier.non_src_pv let equal x y = x.ihash = y.ihash && x.ikey = y.ikey let hash x = x.ihash end module SourcePage = struct type t = Id.source_page type t_pv = Id.source_page_pv let equal = equal let hash = hash end module SourceLocation = struct type t = Paths_types.Identifier.source_location type t_pv = Paths_types.Identifier.source_location_pv end module AssetFile = struct type t = Id.asset_file type t_pv = Id.asset_file_pv end module OdocId = struct type t = Id.odoc_id type t_pv = Id.odoc_id_pv end module Path = struct module Module = struct type t = Id.path_module type t_pv = Id.path_module_pv let equal = equal let hash = hash let compare = compare end module ModuleType = struct type t = Id.path_module_type type t_pv = Id.module_type_pv let equal = equal let hash = hash let compare = compare end module Type = struct type t = Id.path_type type t_pv = Id.path_type_pv let equal = equal let hash = hash let compare = compare end module Value = struct type t = Id.path_value type t_pv = Id.value_pv let equal = equal let hash = hash let compare = compare end module ClassType = struct type t = Id.path_class_type type t_pv = Id.path_class_type_pv let equal = equal let hash = hash let compare = compare end type t = Id.path_any end module Maps = struct module Any = Map.Make (Any) module FunctorParameter = Map.Make (FunctorParameter) module Module = Map.Make (Module) module ModuleType = Map.Make (ModuleType) module Type = Map.Make (Type) module Class = Map.Make (Class) module ClassType = Map.Make (ClassType) module Label = Map.Make (Label) module Path = struct module Module = Map.Make (Path.Module) module ModuleType = Map.Make (Path.ModuleType) module Type = Map.Make (Path.Type) module ClassType = Map.Make (Path.ClassType) end end module Mk = struct let mk_fresh to_str ty f x = let ikey = Printf.sprintf "%s_%s" ty (to_str x) in let ihash = Hashtbl.hash ikey in { iv = f x; ihash; ikey } let mk_parent to_str ty f (parent, x) = let ikey = Printf.sprintf "%s_%s.%s" ty (to_str x) parent.ikey in let ihash = Hashtbl.hash ikey in { iv = f (parent, x); ihash; ikey } let mk_parent_opt to_str ty f (parent_opt, x) = let ikey = match parent_opt with | None -> Printf.sprintf "%s_%s" ty (to_str x) | Some p -> Printf.sprintf "%s_%s.%s" ty (to_str x) p.ikey in let ihash = Hashtbl.hash ikey in { iv = f (parent_opt, x); ihash; ikey } let page : ContainerPage.t option * PageName.t -> [> `Page of ContainerPage.t option * PageName.t ] id = mk_parent_opt PageName.to_string "p" (fun (p, n) -> `Page (p, n)) let leaf_page : ContainerPage.t option * PageName.t -> [> `LeafPage of ContainerPage.t option * PageName.t ] id = mk_parent_opt PageName.to_string "lp" (fun (p, n) -> `LeafPage (p, n)) let asset_file : Page.t * AssetName.t -> AssetFile.t = mk_parent AssetName.to_string "asset" (fun (p, n) -> `AssetFile (p, n)) let source_page (container_page, name) = mk_parent (fun x -> x) "sp" (fun (p, rp) -> `SourcePage (p, rp)) (container_page, name) let root : ContainerPage.t option * ModuleName.t -> [> `Root of ContainerPage.t option * ModuleName.t ] id = mk_parent_opt ModuleName.to_string "r" (fun (p, n) -> `Root (p, n)) let implementation = mk_fresh (fun s -> s) "impl" (fun s -> `Implementation (ModuleName.make_std s)) let module_ : Signature.t * ModuleName.t -> [> `Module of Signature.t * ModuleName.t ] id = mk_parent ModuleName.to_string "m" (fun (p, n) -> `Module (p, n)) let parameter : Signature.t * ModuleName.t -> [> `Parameter of Signature.t * ModuleName.t ] id = mk_parent ModuleName.to_string "p" (fun (p, n) -> `Parameter (p, n)) let result : Signature.t -> [> `Result of Signature.t ] id = fun s -> mk_parent (fun () -> "__result__") "" (fun (s, ()) -> `Result s) (s, ()) let module_type : Signature.t * ModuleTypeName.t -> [> `ModuleType of Signature.t * ModuleTypeName.t ] id = mk_parent ModuleTypeName.to_string "mt" (fun (p, n) -> `ModuleType (p, n)) let class_ : Signature.t * TypeName.t -> [> `Class of Signature.t * TypeName.t ] id = mk_parent TypeName.to_string "c" (fun (p, n) -> `Class (p, n)) let class_type : Signature.t * TypeName.t -> [> `ClassType of Signature.t * TypeName.t ] id = mk_parent TypeName.to_string "ct" (fun (p, n) -> `ClassType (p, n)) let type_ : Signature.t * TypeName.t -> [> `Type of Signature.t * TypeName.t ] id = mk_parent TypeName.to_string "t" (fun (p, n) -> `Type (p, n)) let core_type = mk_fresh (fun s -> s) "coret" (fun s -> `CoreType (TypeName.make_std s)) let constructor : DataType.t * ConstructorName.t -> [> `Constructor of DataType.t * ConstructorName.t ] id = mk_parent ConstructorName.to_string "ctor" (fun (p, n) -> `Constructor (p, n)) let field : FieldParent.t * FieldName.t -> [> `Field of FieldParent.t * FieldName.t ] id = mk_parent FieldName.to_string "fld" (fun (p, n) -> `Field (p, n)) let unboxed_field : UnboxedFieldParent.t * UnboxedFieldName.t -> [> `UnboxedField of UnboxedFieldParent.t * UnboxedFieldName.t ] id = mk_parent UnboxedFieldName.to_string "unboxedfld" (fun (p, n) -> `UnboxedField (p, n)) let extension : Signature.t * ExtensionName.t -> [> `Extension of Signature.t * ExtensionName.t ] id = mk_parent ExtensionName.to_string "extn" (fun (p, n) -> `Extension (p, n)) let extension_decl : Signature.t * (ExtensionName.t * ExtensionName.t) -> [> `ExtensionDecl of Signature.t * ExtensionName.t * ExtensionName.t ] id = mk_parent (fun (n, m) -> ExtensionName.to_string n ^ "." ^ ExtensionName.to_string m) "extn-decl" (fun (p, (n, m)) -> `ExtensionDecl (p, n, m)) let exception_ : Signature.t * ExceptionName.t -> [> `Exception of Signature.t * ExceptionName.t ] id = mk_parent ExceptionName.to_string "exn" (fun (p, n) -> `Exception (p, n)) let value : Signature.t * ValueName.t -> [> `Value of Signature.t * ValueName.t ] id = mk_parent ValueName.to_string "v" (fun (p, n) -> `Value (p, n)) let method_ : ClassSignature.t * MethodName.t -> [> `Method of ClassSignature.t * MethodName.t ] id = mk_parent MethodName.to_string "m" (fun (p, n) -> `Method (p, n)) let instance_variable : ClassSignature.t * InstanceVariableName.t -> [> `InstanceVariable of ClassSignature.t * InstanceVariableName.t ] id = mk_parent InstanceVariableName.to_string "iv" (fun (p, n) -> `InstanceVariable (p, n)) let label : LabelParent.t * LabelName.t -> [> `Label of LabelParent.t * LabelName.t ] id = mk_parent LabelName.to_string "l" (fun (p, n) -> `Label (p, n)) let source_location : SourcePage.t * DefName.t -> [> `SourceLocation of SourcePage.t * DefName.t ] id = mk_parent DefName.to_string "sl" (fun (p, n) -> `SourceLocation (p, n)) let source_location_mod : SourcePage.t -> [> `SourceLocationMod of SourcePage.t ] id = fun s -> mk_parent (fun () -> "__slm__") "" (fun (s, ()) -> `SourceLocationMod s) (s, ()) let source_location_int : SourcePage.t * LocalName.t -> [> `SourceLocationInternal of SourcePage.t * LocalName.t ] id = mk_parent LocalName.to_string "sli" (fun (p, n) -> `SourceLocationInternal (p, n)) end (* Counter for generating unique synthetic parents for include expressions. Items inside an include's module type expression need a different parent to avoid identifier conflicts with items in the enclosing signature. *) let include_parent_counter = ref 0 (* Create a synthetic parent identifier for items inside an include's module type expression. Uses a lowercase module name (illegal in normal OCaml) to ensure no clashes with real identifiers. *) let fresh_include_parent (parent : Signature.t) : Signature.t = incr include_parent_counter; let name = Printf.sprintf "include%d_" !include_parent_counter in (Mk.module_ (parent, ModuleName.make_std name) :> Signature.t) module Hashtbl = struct module Any = Hashtbl.Make (Any) module ContainerPage = Hashtbl.Make (ContainerPage) module LeafPage = Hashtbl.Make (LeafPage) module RootModule = Hashtbl.Make (RootModule) module SourcePage = Hashtbl.Make (SourcePage) end end module Path = struct type t = Paths_types.Path.any let rec is_resolved_hidden : weak_canonical_test:bool -> Paths_types.Resolved_path.any -> bool = fun ~weak_canonical_test x -> let open Paths_types.Resolved_path in let rec inner : Paths_types.Resolved_path.any -> bool = function | `Identifier { iv = `ModuleType (_, m); _ } when Names.ModuleTypeName.is_hidden m -> true | `Identifier { iv = `Type (_, t); _ } when Names.TypeName.is_hidden t -> true | `Identifier { iv = `Module (_, m); _ } when Names.ModuleName.is_hidden m -> true | `Identifier _ -> false | `Canonical (_, `Resolved _) -> false | `Canonical (x, _) -> (not weak_canonical_test) && inner (x : module_ :> any) | `Hidden _ -> true | `Subst (p1, p2) -> inner (p1 : module_type :> any) || inner (p2 : module_ :> any) | `Module (p, _) -> inner (p : module_ :> any) | `Apply (p, _) -> inner (p : module_ :> any) | `ModuleType (_, m) when Names.ModuleTypeName.is_hidden m -> true | `ModuleType (p, _) -> inner (p : module_ :> any) | `Type (_, t) when Names.TypeName.is_hidden t -> true | `CoreType t -> Names.TypeName.is_hidden t | `Type (p, _) -> inner (p : module_ :> any) | `Value (_, t) when Names.ValueName.is_hidden t -> true | `Value (p, _) -> inner (p : module_ :> any) | `Class (p, _) -> inner (p : module_ :> any) | `ClassType (p, _) -> inner (p : module_ :> any) | `Alias (dest, `Resolved src) -> inner (dest : module_ :> any) && inner (src : module_ :> any) | `Alias (dest, src) -> inner (dest : module_ :> any) && is_path_hidden (src :> Paths_types.Path.any) | `AliasModuleType (p1, p2) -> inner (p1 : module_type :> any) && inner (p2 : module_type :> any) | `SubstT (p1, p2) -> inner (p1 :> any) || inner (p2 :> any) | `Substituted m -> inner (m :> any) | `SubstitutedMT m -> inner (m :> any) | `SubstitutedT m -> inner (m :> any) | `SubstitutedCT m -> inner (m :> any) | `CanonicalModuleType (_, `Resolved _) -> false | `CanonicalModuleType (x, _) -> inner (x : module_type :> any) | `CanonicalType (_, `Resolved _) -> false | `CanonicalType (x, _) -> inner (x : type_ :> any) | `OpaqueModule m -> inner (m :> any) | `OpaqueModuleType mt -> inner (mt :> any) in inner x and is_path_hidden : Paths_types.Path.any -> bool = let open Paths_types.Path in function | `Resolved r -> is_resolved_hidden ~weak_canonical_test:false r | `Identifier (_, hidden) -> hidden | `Substituted r -> is_path_hidden (r :> any) | `SubstitutedMT r -> is_path_hidden (r :> any) | `SubstitutedT r -> is_path_hidden (r :> any) | `SubstitutedCT r -> is_path_hidden (r :> any) | `Root s -> ModuleName.is_hidden s | `Forward _ -> false | `Dot (p, n) -> ModuleName.is_hidden n || is_path_hidden (p : module_ :> any) | `DotMT (p, n) -> ModuleTypeName.is_hidden n || is_path_hidden (p : module_ :> any) | `DotT (p, n) -> TypeName.is_hidden n || is_path_hidden (p : module_ :> any) | `DotV (p, n) -> ValueName.is_hidden n || is_path_hidden (p : module_ :> any) | `Apply (p1, p2) -> is_path_hidden (p1 : module_ :> any) || is_path_hidden (p2 : module_ :> any) module Resolved = struct type t = Paths_types.Resolved_path.any let rec parent_module_type_identifier : Paths_types.Resolved_path.module_type -> Identifier.ModuleType.t option = function | `Identifier id -> Some (id : Identifier.ModuleType.t) | `ModuleType (m, n) -> ( match parent_module_identifier m with | None -> None | Some p -> Some (Identifier.Mk.module_type (p, n))) | `SubstT (m, _n) -> parent_module_type_identifier m | `CanonicalModuleType (_, `Resolved p) -> parent_module_type_identifier p | `CanonicalModuleType (p, _) -> parent_module_type_identifier p | `OpaqueModuleType mt -> parent_module_type_identifier mt | `SubstitutedMT m -> parent_module_type_identifier m | `AliasModuleType (sub, orig) -> if is_resolved_hidden ~weak_canonical_test:false (sub :> t) then parent_module_type_identifier orig else parent_module_type_identifier sub and parent_module_identifier : Paths_types.Resolved_path.module_ -> Identifier.Signature.t option = function | `Identifier id -> Some (id : Identifier.Path.Module.t :> Identifier.Signature.t) | `Subst (sub, _) -> (parent_module_type_identifier sub :> Identifier.Signature.t option) | `Hidden _ -> None | `Module (m, n) -> ( match parent_module_identifier m with | None -> None | Some p -> Some (Identifier.Mk.module_ (p, n))) | `Canonical (_, `Resolved p) -> parent_module_identifier p | `Canonical (p, _) -> parent_module_identifier p | `Apply (m, _) -> parent_module_identifier m | `Alias (dest, `Resolved src) -> if is_resolved_hidden ~weak_canonical_test:false (dest :> t) then parent_module_identifier src else parent_module_identifier dest | `Alias (dest, _src) -> parent_module_identifier dest | `Substituted m -> parent_module_identifier m | `OpaqueModule m -> parent_module_identifier m module Module = struct type t = Paths_types.Resolved_path.module_ let is_hidden m = is_resolved_hidden (m : t :> Paths_types.Resolved_path.any) end module ModuleType = struct type t = Paths_types.Resolved_path.module_type let identifier : t -> Identifier.ModuleType.t option = parent_module_type_identifier end module Type = struct type t = Paths_types.Resolved_path.type_ end module Value = struct type t = Paths_types.Resolved_path.value end module ClassType = struct type t = Paths_types.Resolved_path.class_type end let rec identifier : t -> Identifier.t option = let parent p f = match parent_module_identifier p with | None -> None | Some id -> Some (f id :> Identifier.t) in function | `Identifier id -> Some id | `CoreType _ -> None | `Subst (sub, _) -> identifier (sub :> t) | `Hidden _p -> None | `Module (m, n) -> parent m (fun p -> Identifier.Mk.module_ (p, n)) | `Canonical (_, `Resolved p) -> identifier (p :> t) | `Canonical (p, _) -> identifier (p :> t) | `Apply (m, _) -> identifier (m :> t) | `Type (m, n) -> parent m (fun p -> Identifier.Mk.type_ (p, n)) | `Value (m, n) -> parent m (fun p -> Identifier.Mk.value (p, n)) | `ModuleType (m, n) -> parent m (fun p -> Identifier.Mk.module_type (p, n)) | `Class (m, n) -> parent m (fun p -> Identifier.Mk.class_ (p, n)) | `ClassType (m, n) -> parent m (fun p -> Identifier.Mk.class_type (p, n)) | `Alias (dest, `Resolved src) -> if is_resolved_hidden ~weak_canonical_test:false (dest :> t) then identifier (src :> t) else identifier (dest :> t) | `Alias (dest, _src) -> identifier (dest :> t) | `AliasModuleType (sub, orig) -> if is_resolved_hidden ~weak_canonical_test:false (sub :> t) then identifier (orig :> t) else identifier (sub :> t) | `SubstT (p, _) -> identifier (p :> t) | `CanonicalModuleType (_, `Resolved p) -> identifier (p :> t) | `CanonicalModuleType (p, _) -> identifier (p :> t) | `CanonicalType (_, `Resolved p) -> identifier (p :> t) | `CanonicalType (p, _) -> identifier (p :> t) | `OpaqueModule m -> identifier (m :> t) | `OpaqueModuleType mt -> identifier (mt :> t) | `Substituted m -> identifier (m :> t) | `SubstitutedMT m -> identifier (m :> t) | `SubstitutedCT m -> identifier (m :> t) | `SubstitutedT m -> identifier (m :> t) let is_hidden r = is_resolved_hidden ~weak_canonical_test:false r end module Module = struct type t = Paths_types.Path.module_ end module ModuleType = struct type t = Paths_types.Path.module_type end module Type = struct type t = Paths_types.Path.type_ end module Value = struct type t = Paths_types.Path.value end module ClassType = struct type t = Paths_types.Path.class_type end let is_hidden = is_path_hidden end module Fragment = struct module Resolved = struct type t = Paths_types.Resolved_fragment.any type root = Paths_types.Resolved_fragment.root module Signature = struct type t = Paths_types.Resolved_fragment.signature let rec sgidentifier : t -> Identifier.Signature.t option = function | `Root (`ModuleType i) -> (Path.Resolved.parent_module_type_identifier i :> Identifier.Signature.t option) | `Root (`Module i) -> Path.Resolved.parent_module_identifier i | `Subst (s, _) -> (Path.Resolved.parent_module_type_identifier s :> Identifier.Signature.t option) | `Alias (i, _) -> Path.Resolved.parent_module_identifier i | `Module (m, n) -> ( match sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.module_ (p, n))) | `OpaqueModule m -> sgidentifier (m :> t) end module Module = struct type t = Paths_types.Resolved_fragment.module_ end module ModuleType = struct type t = Paths_types.Resolved_fragment.module_type end module Type = struct type t = Paths_types.Resolved_fragment.type_ end type leaf = Paths_types.Resolved_fragment.leaf let rec identifier : t -> Identifier.t option = function | `Root (`ModuleType _r) -> assert false | `Root (`Module _r) -> assert false | `Subst (s, _) -> (Path.Resolved.ModuleType.identifier s :> Identifier.t option) | `Alias (p, _) -> (Path.Resolved.parent_module_identifier p :> Identifier.t option) | `Module (m, n) -> ( match Signature.sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.module_ (p, n))) | `Module_type (m, n) -> ( match Signature.sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.module_type (p, n))) | `Type (m, n) -> ( match Signature.sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.type_ (p, n))) | `Class (m, n) -> ( match Signature.sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.class_ (p, n))) | `ClassType (m, n) -> ( match Signature.sgidentifier m with | None -> None | Some p -> Some (Identifier.Mk.class_type (p, n))) | `OpaqueModule m -> identifier (m :> t) let rec is_hidden : t -> bool = function | `Root (`ModuleType r) -> Path.Resolved.(is_hidden (r :> t)) | `Root (`Module r) -> Path.Resolved.(is_hidden (r :> t)) | `Subst (s, _) -> Path.Resolved.(is_hidden (s :> t)) | `Alias (s, _) -> Path.Resolved.(is_hidden (s :> t)) | `Module (m, _) | `Module_type (m, _) | `Type (m, _) | `Class (m, _) | `ClassType (m, _) -> is_hidden (m :> t) | `OpaqueModule m -> is_hidden (m :> t) end type t = Paths_types.Fragment.any module Signature = struct type t = Paths_types.Fragment.signature end module Module = struct type t = Paths_types.Fragment.module_ end module ModuleType = struct type t = Paths_types.Fragment.module_type end module Type = struct type t = Paths_types.Fragment.type_ end type leaf = Paths_types.Fragment.leaf end module Reference = struct module Resolved = struct open Paths_types.Resolved_reference type t = Paths_types.Resolved_reference.any let rec parent_signature_identifier : signature -> Identifier.Signature.t option = function | `Identifier id -> Some id | `Hidden _s -> None | `Alias (sub, orig) -> if Path.Resolved.(is_hidden (sub :> t)) then parent_signature_identifier (orig :> signature) else (Path.Resolved.parent_module_identifier sub :> Identifier.Signature.t option) | `AliasModuleType (sub, orig) -> if Path.Resolved.(is_hidden (sub :> t)) then parent_signature_identifier (orig :> signature) else (Path.Resolved.parent_module_type_identifier sub :> Identifier.Signature.t option) | `Module (m, n) -> ( match parent_signature_identifier m with | None -> None | Some p -> Some (Identifier.Mk.module_ (p, n))) | `ModuleType (m, n) -> ( match parent_signature_identifier m with | None -> None | Some p -> Some (Identifier.Mk.module_type (p, n))) and parent_type_identifier : datatype -> Identifier.DataType.t option = function | `Identifier id -> Some id | `Type (sg, s) -> ( match parent_signature_identifier sg with | None -> None | Some p -> Some (Identifier.Mk.type_ (p, s))) and parent_class_signature_identifier : class_signature -> Identifier.ClassSignature.t option = function | `Identifier id -> Some id | `Class (sg, s) -> ( match parent_signature_identifier sg with | None -> None | Some p -> Some (Identifier.Mk.class_ (p, s))) | `ClassType (sg, s) -> ( match parent_signature_identifier sg with | None -> None | Some p -> Some (Identifier.Mk.class_type (p, s))) and field_parent_identifier : field_parent -> Identifier.FieldParent.t option = function | `Identifier id -> Some id | (`Hidden _ | `Alias _ | `AliasModuleType _ | `Module _ | `ModuleType _) as sg -> (parent_signature_identifier sg :> Identifier.FieldParent.t option) | `Type _ as t -> (parent_type_identifier t :> Identifier.FieldParent.t option) and unboxed_field_parent_identifier : unboxed_field_parent -> Identifier.UnboxedFieldParent.t option = function | `Identifier id -> Some id | `Type _ as t -> (parent_type_identifier t :> Identifier.UnboxedFieldParent.t option) and label_parent_identifier : label_parent -> Identifier.LabelParent.t option = function | `Identifier id -> Some id | (`Class _ | `ClassType _) as c -> (parent_class_signature_identifier c :> Identifier.LabelParent.t option) | ( `Hidden _ | `Alias _ | `AliasModuleType _ | `Module _ | `ModuleType _ | `Type _ ) as r -> (field_parent_identifier r :> Identifier.LabelParent.t option) and identifier : t -> Identifier.t option = function | `Identifier id -> Some id | `UnboxedField (p, n) -> ( match unboxed_field_parent_identifier p with | None -> None | Some p -> Some (Identifier.Mk.unboxed_field (p, n))) | ( `Alias _ | `AliasModuleType _ | `Module _ | `Hidden _ | `Type _ | `Class _ | `ClassType _ | `ModuleType _ ) as r -> (label_parent_identifier r :> Identifier.t option) | `Field (p, n) -> ( match field_parent_identifier p with | None -> None | Some p -> Some (Identifier.Mk.field (p, n))) | `PolyConstructor (s, n) -> ( (* Uses an identifier for constructor even though it is not one. Document must make the links correspond. *) match parent_type_identifier s with | None -> None | Some p -> Some (Identifier.Mk.constructor (p, n))) | `Constructor (s, n) -> ( match parent_type_identifier s with | None -> None | Some p -> Some (Identifier.Mk.constructor (p, n))) | `Extension (p, q) -> ( match parent_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.extension (p, q))) | `ExtensionDecl (p, q, r) -> ( match parent_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.extension_decl (p, (q, r)))) | `Exception (p, q) -> ( match parent_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.exception_ (p, q))) | `Value (p, q) -> ( match parent_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.value (p, q))) | `Method (p, q) -> ( match parent_class_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.method_ (p, q))) | `InstanceVariable (p, q) -> ( match parent_class_signature_identifier p with | None -> None | Some p -> Some (Identifier.Mk.instance_variable (p, q))) | `Label (p, q) -> ( match label_parent_identifier p with | None -> None | Some p -> Some (Identifier.Mk.label (p, q))) module Signature = struct type t = Paths_types.Resolved_reference.signature end module ClassSignature = struct type t = Paths_types.Resolved_reference.class_signature end module DataType = struct type t = Paths_types.Resolved_reference.datatype end module FieldParent = struct type t = Paths_types.Resolved_reference.field_parent end module UnboxedFieldParent = struct type t = Paths_types.Resolved_reference.unboxed_field_parent end module LabelParent = struct type t = Paths_types.Resolved_reference.label_parent end module Module = struct type t = Paths_types.Resolved_reference.module_ end module ModuleType = struct type t = Paths_types.Resolved_reference.module_type end module Type = struct type t = Paths_types.Resolved_reference.type_ end module Constructor = struct type t = Paths_types.Resolved_reference.constructor end module Field = struct type t = Paths_types.Resolved_reference.field end module UnboxedField = struct type t = Paths_types.Resolved_reference.unboxed_field end module Extension = struct type t = Paths_types.Resolved_reference.extension end module ExtensionDecl = struct type t = Paths_types.Resolved_reference.extension_decl end module Exception = struct type t = Paths_types.Resolved_reference.exception_ end module Value = struct type t = Paths_types.Resolved_reference.value end module Class = struct type t = Paths_types.Resolved_reference.class_ end module ClassType = struct type t = Paths_types.Resolved_reference.class_type end module Method = struct type t = Paths_types.Resolved_reference.method_ end module InstanceVariable = struct type t = Paths_types.Resolved_reference.instance_variable end module Label = struct type t = Paths_types.Resolved_reference.label end module Page = struct type t = Paths_types.Resolved_reference.page end module Asset = struct let identifier = function `Identifier id -> id type t = Paths_types.Resolved_reference.asset end end type t = Paths_types.Reference.any type tag_any = Paths_types.Reference.tag_any type tag_hierarchy = Paths_types.Reference.tag_hierarchy module Signature = struct type t = Paths_types.Reference.signature end module ClassSignature = struct type t = Paths_types.Reference.class_signature end module DataType = struct type t = Paths_types.Reference.datatype end module FragmentTypeParent = struct type t = Paths_types.Reference.fragment_type_parent end module LabelParent = struct type t = Paths_types.Reference.label_parent end module Module = struct type t = Paths_types.Reference.module_ end module ModuleType = struct type t = Paths_types.Reference.module_type end module Type = struct type t = Paths_types.Reference.type_ end module Constructor = struct type t = Paths_types.Reference.constructor end module Field = struct type t = Paths_types.Reference.field end module UnboxedField = struct type t = Paths_types.Reference.unboxed_field end module Extension = struct type t = Paths_types.Reference.extension end module ExtensionDecl = struct type t = Paths_types.Reference.extension_decl end module Exception = struct type t = Paths_types.Reference.exception_ end module Value = struct type t = Paths_types.Reference.value end module Class = struct type t = Paths_types.Reference.class_ end module ClassType = struct type t = Paths_types.Reference.class_type end module Method = struct type t = Paths_types.Reference.method_ end module InstanceVariable = struct type t = Paths_types.Reference.instance_variable end module Label = struct type t = Paths_types.Reference.label end module Page = struct type t = Paths_types.Reference.page end module Asset = struct type t = Paths_types.Reference.asset end module Hierarchy = struct type t = Paths_types.Reference.hierarchy end end