diff --git a/CHANGES.md b/CHANGES.md index f7d64d2f91..6e5b869e19 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - `markdown-generate` command now accepts multiple `.odocl` files in a single invocation, eliminating the need for shell scripting (@davesnx, #1387) - Support for OxCaml (@lukemaurer, @art-w, #1399) +- Support for OxCaml kind annotations (@art-w, #1410) ### Fixed - Fix compile-time crashing bugs #930 and #1385 (@jonludlam, #1400) diff --git a/sherlodoc/index/load_doc.ml b/sherlodoc/index/load_doc.ml index 689113d2ff..cf417947c7 100644 --- a/sherlodoc/index/load_doc.ml +++ b/sherlodoc/index/load_doc.ml @@ -82,8 +82,8 @@ let searchable_type_of_constructor args res = | TypeDecl.Constructor.Tuple args -> begin match args with | _ :: _ :: _ -> - TypeExpr.(Arrow (None, Tuple (List.map (fun x -> None, x) args), res)) - | [ arg ] -> TypeExpr.(Arrow (None, arg, res)) + TypeExpr.Arrow (None, Tuple (List.map (fun (x, _mods) -> None, x) args), res) + | [ (arg, _) ] -> TypeExpr.Arrow (None, arg, res) | _ -> res end | TypeDecl.Constructor.Record fields -> diff --git a/src/document/generator.ml b/src/document/generator.ml index de14ee9a5a..f9086872fb 100644 --- a/src/document/generator.ml +++ b/src/document/generator.ml @@ -306,6 +306,10 @@ module Make (Syntax : SYNTAX) = struct val format_type_path : delim:[ `parens | `brackets ] -> Lang.TypeExpr.t list -> text -> text + + val kind_annotation : Odoc_model.Lang.KindAnnotation.t -> text + + val with_kind_annotation : Odoc_model.Lang.KindAnnotation.t -> text -> text end = struct let rec te_variant (t : Odoc_model.Lang.TypeExpr.Polymorphic_variant.t) = let style_arguments ~constant arguments = @@ -426,6 +430,30 @@ module Make (Syntax : SYNTAX) = struct then enclose ~l:lparen res ~r:")" else res + and kind_annotation (k : Odoc_model.Lang.KindAnnotation.t) = + match k with + | Default -> O.noop + | Abbreviation s -> O.txt s + | Mod (base, modes) -> + kind_annotation base ++ O.txt " " ++ O.keyword "mod" + ++ O.txt (" " ^ String.concat ~sep:" " modes) + | With (base, ty, modalities) -> ( + kind_annotation base ++ O.txt " " ++ O.keyword "with" ++ O.txt " " + ++ type_expr ty + ++ + match modalities with + | [] -> O.noop + | mods -> + O.txt " " ++ O.keyword "mod" + ++ O.txt (" " ^ String.concat ~sep:" " mods)) + | Kind_of ty -> O.keyword "kind_of_" ++ O.txt " " ++ type_expr ty + | Product ks -> O.list ks ~sep:(O.txt " & ") ~f:kind_annotation + + and with_kind_annotation kind base = + match kind with + | Odoc_model.Lang.KindAnnotation.Default -> base + | k -> O.txt "(" ++ base ++ O.txt " : " ++ kind_annotation k ++ O.txt ")" + and type_expr ?(needs_parentheses = false) (t : Odoc_model.Lang.TypeExpr.t) = let enclose_parens_if_needed res = @@ -478,9 +506,11 @@ module Make (Syntax : SYNTAX) = struct format_type_path ~delim:`brackets args (Link.from_path (path :> Paths.Path.t)) | Poly (polyvars, t) -> - enclose_parens_if_needed - @@ O.txt ("'" ^ String.concat ~sep:" '" polyvars ^ ". ") - ++ type_expr t + let format_poly_var (name, kind) = + with_kind_annotation kind (O.txt ("'" ^ name)) + in + let vars = O.list polyvars ~sep:(O.txt " ") ~f:format_poly_var in + enclose_parens_if_needed @@ (vars ++ O.txt ". " ++ type_expr t) | Quote t -> O.span (O.txt "<[ " ++ O.box_hv (type_expr t) ++ O.txt " ]>") | Splice t -> O.span (O.txt "$" ++ type_expr ~needs_parentheses:true t) | Package pkg -> @@ -537,23 +567,29 @@ module Make (Syntax : SYNTAX) = struct text * bool val format_constraints : (Lang.TypeExpr.t * Lang.TypeExpr.t) list -> text + + val format_modalities : Odoc_model.Lang.Modalities.t -> text end = struct + let format_modalities modalities = + match modalities with + | [] -> O.noop + | mods -> + O.txt " " ++ O.txt "@@" ++ O.txt " " + ++ O.txt (String.concat ~sep:" " mods) + let record fields = - let field mutable_ id typ = + let field mutable_ id typ modalities = let url = Url.from_identifier ~stop_before:true id in let name = Paths.Identifier.name id in let attrs = [ "def"; "record"; Url.Anchor.string_of_kind url.kind ] in let cell = - (* O.td ~a:[ O.a_class ["def"; kind ] ] - * [O.a ~a:[O.a_href ("#" ^ anchor); O.a_class ["anchor"]] [] - * ; *) O.code ((if mutable_ then O.keyword "mutable" ++ O.txt " " else O.noop) ++ O.txt name ++ O.txt Syntax.Type.annotation_separator ++ type_expr typ + ++ format_modalities modalities ++ O.txt Syntax.Type.Record.field_separator) - (* ] *) in (url, attrs, cell) in @@ -562,7 +598,9 @@ module Make (Syntax : SYNTAX) = struct |> List.map (fun fld -> let open Odoc_model.Lang.TypeDecl.Field in let url, attrs, code = - field fld.mutable_ (fld.id :> Paths.Identifier.t) fld.type_ + field fld.mutable_ + (fld.id :> Paths.Identifier.t) + fld.type_ fld.modalities in let anchor = Some url in let doc = fld.doc.elements in @@ -640,7 +678,9 @@ module Make (Syntax : SYNTAX) = struct | Tuple lst -> let params = O.list lst ~sep:Syntax.Type.Tuple.element_separator - ~f:(type_expr ~needs_parentheses:is_gadt) + ~f:(fun (te, mods) -> + type_expr ~needs_parentheses:is_gadt te + ++ format_modalities mods) in O.documentedSrc (cstr @@ -821,8 +861,8 @@ module Make (Syntax : SYNTAX) = struct Odoc_model.Lang.TypeDecl.param list -> text = fun ?(delim = `parens) params -> - let format_param { Odoc_model.Lang.TypeDecl.desc; variance; injectivity } - = + let format_param_str + { Odoc_model.Lang.TypeDecl.desc; variance; injectivity; kind = _ } = let desc = match desc with | Odoc_model.Lang.TypeDecl.Any -> [ "_" ] @@ -838,15 +878,22 @@ module Make (Syntax : SYNTAX) = struct let final = if injectivity then "!" :: var_desc else var_desc in String.concat ~sep:"" final in - O.txt - (match params with - | [] -> "" - | [ x ] -> format_param x |> Syntax.Type.handle_format_params - | lst -> ( - let params = String.concat ~sep:", " (List.map format_param lst) in - (match delim with `parens -> "(" | `brackets -> "[") - ^ params - ^ match delim with `parens -> ")" | `brackets -> "]")) + let format_param p = + Type_expression.with_kind_annotation p.Odoc_model.Lang.TypeDecl.kind + (O.txt (format_param_str p)) + in + match params with + | [] -> O.noop + | [ x ] -> + let base = format_param_str x |> Syntax.Type.handle_format_params in + Type_expression.with_kind_annotation x.kind (O.txt base) + | lst -> + let left, right = + match delim with `parens -> ("(", ")") | `brackets -> ("[", "]") + in + O.txt left + ++ O.list lst ~sep:(O.txt ", ") ~f:format_param + ++ O.txt right let format_constraints constraints = O.list constraints ~f:(fun (t1, t2) -> @@ -896,7 +943,12 @@ module Make (Syntax : SYNTAX) = struct let params = format_params l in Syntax.Type.handle_constructor_params (O.txt tyname) params in - let intro = keyword' ++ O.txt " " ++ tconstr in + let kind_annot = + match t.equation.kind with + | Default -> O.noop + | k -> O.txt " : " ++ Type_expression.kind_annotation k + in + let intro = keyword' ++ O.txt " " ++ tconstr ++ kind_annot in let constraints = format_constraints t.equation.constraints in let manifest, need_private, long_prefix = match t.equation.manifest with @@ -978,6 +1030,7 @@ module Make (Syntax : SYNTAX) = struct ++ O.txt " " ++ O.txt name ++ O.txt Syntax.Type.annotation_separator ++ O.cut ++ type_expr t.type_ + ++ Type_declaration.format_modalities t.modalities ++ if semicolon then O.txt ";" else O.noop) in let attr = [ "value" ] @ extra_attr in diff --git a/src/loader/cmi.ml b/src/loader/cmi.ml index db7bfd1ba3..1e5900cf2c 100644 --- a/src/loader/cmi.ml +++ b/src/loader/cmi.ml @@ -490,6 +490,63 @@ let mark_class_declaration cld = List.iter mark_type_parameter cld.cty_params; mark_class_type cld.cty_params cld.cty_type +#if defined OXCAML +let read_parsetree_core_type (ct : Parsetree.core_type) = + let open TypeExpr in + match ct.ptyp_desc with + | Ptyp_var (s, _) -> Var s + | Ptyp_any _ -> Any + | _ -> failwith "invalid core type" + +let rec read_jkind_annotation (jk : Parsetree.jkind_annotation) = + let open KindAnnotation in + match jk.pjkind_desc with + | Pjk_default -> Default + | Pjk_abbreviation s -> Abbreviation s + | Pjk_mod (jk', modes) -> + let modes = List.map (fun (m : Parsetree.mode Location.loc) -> + let (Parsetree.Mode s) = m.txt in s) modes in + Mod (read_jkind_annotation jk', modes) + | Pjk_with (jk', cty, modalities) -> + let ty = read_parsetree_core_type cty in + let modalities = List.map (fun (m : Parsetree.modality Location.loc) -> + let (Parsetree.Modality s) = m.txt in s) modalities in + With (read_jkind_annotation jk', ty, modalities) + | Pjk_kind_of cty -> + Kind_of (read_parsetree_core_type cty) + | Pjk_product jks -> + Product (List.map read_jkind_annotation jks) + +let read_jkind_annotation = function + | None -> KindAnnotation.Default + | Some jk -> + match read_jkind_annotation jk with + | Abbreviation "value" -> Default + | k -> k + +let jkind_of_type_desc te = + match te with + | Tvar { jkind; _ } | Tunivar { jkind; _ } -> + read_jkind_annotation jkind.annotation + | _ -> KindAnnotation.Default + +let read_modalities mut modalities = + Typemode.untransl_modalities mut modalities + |> List.map (fun (m : Parsetree.modality Location.loc) -> + let (Parsetree.Modality s) = m.txt in s) + +let read_value_modalities modalities = + let const = + Ctype.zap_modalities_to_floor_if_modes_enabled_at Alpha modalities + in + read_modalities Immutable const + +#else + +let jkind_of_type_desc _te = KindAnnotation.Default + +#endif + let rec read_type_expr env typ = let open TypeExpr in let px = proxy typ in @@ -549,10 +606,14 @@ let rec read_type_expr env typ = | Tpoly (typ, []) -> read_type_expr env typ | Tpoly (typ, tyl) -> let tyl = List.map Compat.repr tyl in - let vars = List.map name_of_type_repr tyl in + let vars_with_kinds = List.map (fun ty -> + let name = name_of_type_repr ty in + let kind = jkind_of_type_desc ty.desc in + (name, kind) + ) tyl in let typ = read_type_expr env typ in remove_names tyl; - Poly(vars, typ) + Poly(vars_with_kinds, typ) | Tunivar _ -> Var (name_of_type typ) #if OCAML_VERSION>=(5,4,0) | Tpackage {pack_path=p; pack_cstrs } -> @@ -723,7 +784,14 @@ let read_value_description ({ident_env ; warnings_tag} as env) parent id vd = External primitives | _ -> assert false in - Value { Value.id; source_loc; doc; type_; value } + let modalities = +#if defined OXCAML + read_value_modalities vd.val_modalities +#else + [] +#endif + in + Value { Value.id; source_loc; doc; type_; value; modalities } #if defined OXCAML let is_mutable = Types.is_mutable @@ -741,21 +809,36 @@ let read_label_declaration env parent ld = in let mutable_ = is_mutable ld.ld_mutable in let type_ = read_type_expr env ld.ld_type in - {id; doc; mutable_; type_} + let modalities = +#if defined OXCAML + read_modalities ld.ld_mutable ld.ld_modalities +#else + [] +#endif + in + {id; doc; mutable_; type_; modalities} let read_constructor_declaration_arguments env parent arg = #if OCAML_VERSION < (4,3,0) (* NOTE(@ostera): constructor with inlined records were introduced post 4.02 so it's safe to use Tuple here *) ignore parent; - TypeDecl.Constructor.Tuple(List.map (read_type_expr env) arg) + TypeDecl.Constructor.Tuple(List.map (fun x -> read_type_expr env x, []) arg) #else let open TypeDecl.Constructor in match arg with #if defined OXCAML - | Cstr_tuple args -> Tuple (List.map (fun arg -> read_type_expr env arg.ca_type) args) + | Cstr_tuple args -> + let args_with_modalities = + List.map + (fun arg -> + read_type_expr env arg.ca_type, + read_modalities Immutable arg.ca_modalities) + args + in + Tuple args_with_modalities #else - | Cstr_tuple args -> Tuple (List.map (read_type_expr env) args) + | Cstr_tuple args -> Tuple (List.map (fun arg -> read_type_expr env arg, []) args) #endif | Cstr_record lds -> Record (List.map (read_label_declaration env parent) lds) @@ -827,6 +910,7 @@ let read_type_parameter abstr var param = if name = "_" then Any else Var name in + let kind = jkind_of_type_desc (Compat.get_desc param) in let variance = if not (abstr || aliasable param) then None else begin @@ -836,7 +920,7 @@ let read_type_parameter abstr var param = else None end in let injectivity = read_injectivity var in - {desc; variance; injectivity} + {desc; variance; injectivity; kind} let read_type_constraints env params = List.fold_right @@ -898,7 +982,14 @@ let read_type_declaration env parent id decl = List.map2 (read_type_parameter abstr) decl.type_variance params in let private_ = (decl.type_private = Private) in - let equation = Equation.{params; manifest; constraints; private_} in + let kind = +#if defined OXCAML + read_jkind_annotation decl.type_jkind.annotation +#else + KindAnnotation.Default +#endif + in + let equation = Equation.{params; manifest; constraints; private_; kind} in {id; source_loc; doc; canonical; equation; representation} let read_extension_constructor env parent id ext = diff --git a/src/loader/cmi.mli b/src/loader/cmi.mli index 1d0cca0ac5..794ed43361 100644 --- a/src/loader/cmi.mli +++ b/src/loader/cmi.mli @@ -96,3 +96,18 @@ val read_extension_constructor : env -> val read_exception : env -> Paths.Identifier.Signature.t -> Ident.t -> Types.extension_constructor -> Odoc_model.Lang.Exception.t + +#if defined OXCAML +val read_jkind_annotation : + Parsetree.jkind_annotation option -> + Odoc_model.Lang.KindAnnotation.t + +val read_modalities : + Types.mutability -> + Mode.Modality.Const.t -> + Odoc_model.Lang.Modalities.t + +val read_value_modalities : + Mode.Modality.t -> + Odoc_model.Lang.Modalities.t +#endif diff --git a/src/loader/cmt.ml b/src/loader/cmt.ml index bf5131878d..445af7e092 100644 --- a/src/loader/cmt.ml +++ b/src/loader/cmt.ml @@ -53,7 +53,7 @@ let rec read_pattern env parent doc pat = Cmi.mark_type_expr pat.pat_type; let type_ = Cmi.read_type_expr env pat.pat_type in let value = Abstract in - [Value {id; source_loc; doc; type_; value}] + [Value {id; source_loc; doc; type_; value; modalities = []}] #if OCAML_VERSION < (5,2, 0) | Tpat_alias(pat, id, _) -> #elif defined OXCAML @@ -68,7 +68,7 @@ let rec read_pattern env parent doc pat = Cmi.mark_type_expr pat.pat_type; let type_ = Cmi.read_type_expr env pat.pat_type in let value = Abstract in - Value {id; source_loc; doc; type_; value} :: read_pattern env parent doc pat + Value {id; source_loc; doc; type_; value; modalities = []} :: read_pattern env parent doc pat | Tpat_constant _ -> [] | Tpat_tuple pats -> #if OCAML_VERSION >= (5, 4, 0) || defined OXCAML diff --git a/src/loader/cmti.ml b/src/loader/cmti.ml index 5468d42af3..6e0ce444c1 100644 --- a/src/loader/cmti.ml +++ b/src/loader/cmti.ml @@ -168,10 +168,11 @@ let rec read_core_type env container ctyp = | Ttyp_poly([], typ) -> read_core_type env container typ #if defined OXCAML | Ttyp_poly(vars, typ) -> - (* TODO: presumably want the layouts, eventually *) - Poly(List.map fst vars, read_core_type env container typ) + Poly(List.map (fun (name, jk) -> + (name, Cmi.read_jkind_annotation jk) + ) vars, read_core_type env container typ) #else - | Ttyp_poly(vars, typ) -> Poly(vars, read_core_type env container typ) + | Ttyp_poly(vars, typ) -> Poly(List.map (fun v -> (v, KindAnnotation.Default)) vars, read_core_type env container typ) #endif #if OCAML_VERSION >= (5,4,0) | Ttyp_package {tpt_path = pack_path; tpt_cstrs=pack_fields; _} -> @@ -215,19 +216,25 @@ let read_value_description env parent vd = | [] -> Value.Abstract | primitives -> External primitives in - Value { Value.id; source_loc; doc; type_; value } + let modalities = +#if defined OXCAML + Cmi.read_value_modalities vd.val_val.val_modalities +#else + [] +#endif + in + Value { Value.id; source_loc; doc; type_; value; modalities } let read_type_parameter (ctyp, var_and_injectivity) = let open TypeDecl in - let desc = + let desc, kind = match ctyp.ctyp_desc with #if defined OXCAML - (* TODO: presumably we want the layouts below, eventually *) - | Ttyp_var (None, _layout) -> Any - | Ttyp_var (Some s, _layout) -> Var s + | Ttyp_var (None, layout) -> Any, Cmi.read_jkind_annotation layout + | Ttyp_var (Some s, layout) -> Var s, Cmi.read_jkind_annotation layout #else - | Ttyp_any -> Any - | Ttyp_var s -> Var s + | Ttyp_any -> Any, KindAnnotation.Default + | Ttyp_var s -> Var s, KindAnnotation.Default #endif | _ -> assert false in @@ -254,7 +261,7 @@ let read_type_parameter (ctyp, var_and_injectivity) = var, injectivity #endif in - {desc; variance; injectivity} + {desc; variance; injectivity; kind} #if defined OXCAML let is_mutable = Types.is_mutable @@ -270,7 +277,14 @@ let read_label_declaration env parent label_parent ld = let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag label_parent ld.ld_attributes in let mutable_ = is_mutable ld.ld_mutable in let type_ = read_core_type env label_parent ld.ld_type in - {id; doc; mutable_; type_} + let modalities = +#if defined OXCAML + Cmi.read_modalities ld.ld_mutable ld.ld_modalities +#else + [] +#endif + in + {id; doc; mutable_; type_; modalities} let read_unboxed_label_declaration env parent label_parent ld = let open TypeDecl.UnboxedField in @@ -286,14 +300,21 @@ let read_constructor_declaration_arguments env parent label_parent arg = let open TypeDecl.Constructor in #if OCAML_VERSION < (4,3,0) ignore parent; - Tuple (List.map (read_core_type env label_parent) arg) + Tuple (List.map (fun x -> read_core_type env label_parent x, []) arg) #else match arg with | Cstr_tuple args -> #if defined OXCAML - Tuple (List.map (fun arg -> read_core_type env label_parent arg.ca_type) args) + let args_with_modalities = + List.map + (fun arg -> + read_core_type env label_parent arg.ca_type, + Cmi.read_modalities Immutable arg.ca_modalities) + args + in + Tuple args_with_modalities #else - Tuple (List.map (fun arg -> read_core_type env label_parent arg) args) + Tuple (List.map (fun arg -> read_core_type env label_parent arg, []) args) #endif | Cstr_record lds -> Record (List.map (read_label_declaration env parent label_parent) lds) @@ -346,7 +367,14 @@ let read_type_equation env container decl = read_core_type env container typ2)) decl.typ_cstrs in - {params; private_; manifest; constraints} + let kind = +#if defined OXCAML + Cmi.read_jkind_annotation decl.typ_jkind_annotation +#else + KindAnnotation.Default +#endif + in + {params; private_; manifest; constraints; kind} let read_type_declaration env parent decl = let open TypeDecl in @@ -608,7 +636,17 @@ let rec read_with_constraint env global_parent parent (_, frag, constr) = and read_module_type env parent label_parent mty = let open ModuleType in match mty.mty_desc with - | Tmty_ident(p, _) -> Path { p_path = Env.Path.read_module_type env.ident_env p; p_expansion = None } + | Tmty_ident(p, _) -> + (match mty.mty_type with +#if defined OXCAML + | Mty_signature sg -> + (* For modules with modalities (e.g. [module M : S @@ portable]), + the mty_desc stores only [Tmty_ident S] so we use the mty_type + for the expanded signature with modalities applied to each value. *) + let mty_type = Odoc_model.Compat.module_type mty.mty_type in + Cmi.read_module_type env parent mty_type +#endif + | _ -> Path { p_path = Env.Path.read_module_type env.ident_env p; p_expansion = None }) | Tmty_signature sg -> let sg, () = read_signature Odoc_model.Semantics.Expect_none env parent sg in Signature sg diff --git a/src/model/lang.ml b/src/model/lang.ml index e801ebbf2e..dbe736db1e 100644 --- a/src/model/lang.ml +++ b/src/model/lang.ml @@ -212,6 +212,11 @@ end = (** {3 Type Declarations} *) +and Modalities : sig + type t = string list +end = + Modalities + and TypeDecl : sig module Field : sig type t = { @@ -219,6 +224,7 @@ and TypeDecl : sig doc : Comment.docs; mutable_ : bool; type_ : TypeExpr.t; + modalities : Modalities.t; } end @@ -232,7 +238,9 @@ and TypeDecl : sig end module Constructor : sig - type argument = Tuple of TypeExpr.t list | Record of Field.t list + type argument = + | Tuple of (TypeExpr.t * Modalities.t) list + | Record of Field.t list type t = { id : Identifier.Constructor.t; @@ -258,6 +266,7 @@ and TypeDecl : sig desc : param_desc; variance : variance option; injectivity : bool; + kind : KindAnnotation.t; } module Equation : sig @@ -266,6 +275,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : KindAnnotation.t; } end @@ -327,6 +337,7 @@ and Value : sig value : value; doc : Comment.docs; type_ : TypeExpr.t; + modalities : Modalities.t; } end = Value @@ -417,6 +428,19 @@ and InstanceVariable : sig end = InstanceVariable +(** {3 Kind annotations} *) + +and KindAnnotation : sig + type t = + | Default + | Abbreviation of string + | Mod of t * string list + | With of t * TypeExpr.t * string list + | Kind_of of TypeExpr.t + | Product of t list +end = + KindAnnotation + (** {3 Type expressions} *) and TypeExpr : sig @@ -464,7 +488,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Path.ClassType.t * t list - | Poly of string list * t + | Poly of (string * KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t diff --git a/src/model_desc/lang_desc.ml b/src/model_desc/lang_desc.ml index 8df9471334..3b9900855f 100644 --- a/src/model_desc/lang_desc.ml +++ b/src/model_desc/lang_desc.ml @@ -323,6 +323,7 @@ and typedecl_field = F ("doc", (fun t -> t.doc), docs); F ("mutable_", (fun t -> t.mutable_), bool); F ("type_", (fun t -> t.type_), typeexpr_t); + F ("modalities", (fun t -> t.modalities), List string); ] and typedecl_unboxed_field = @@ -339,7 +340,7 @@ and typedecl_constructor_argument = let open Lang.TypeDecl.Constructor in T.Variant (function - | Tuple x -> C ("Tuple", x, List typeexpr_t) + | Tuple x -> C ("Tuple", x, List (Pair (typeexpr_t, List string))) | Record x -> C ("Record", x, List typedecl_field)) and typedecl_constructor = @@ -367,6 +368,21 @@ and typedecl_variance = Variant (function Pos -> C0 "Pos" | Neg -> C0 "Neg" | Bivariant -> C0 "Bivariant") +and kind_annotation = + let open Lang.KindAnnotation in + Variant + (function + | Default -> C0 "Default" + | Abbreviation x -> C ("Abbreviation", x, string) + | Mod (x1, x2) -> C ("Mod", (x1, x2), Pair (kind_annotation, List string)) + | With (x1, x2, x3) -> + C + ( "With", + (x1, x2, x3), + Triple (kind_annotation, typeexpr_t, List string) ) + | Kind_of x -> C ("Kind_of", x, typeexpr_t) + | Product x -> C ("Product", x, List kind_annotation)) + and typedecl_param_desc = let open Lang.TypeDecl in Variant (function Any -> C0 "Any" | Var x -> C ("Var", x, string)) @@ -378,6 +394,7 @@ and typedecl_param = F ("desc", (fun t -> t.desc), typedecl_param_desc); F ("variance", (fun t -> t.variance), Option typedecl_variance); F ("injectivity", (fun t -> t.injectivity), bool); + F ("kind", (fun t -> t.kind), kind_annotation); ] and typedecl_equation = @@ -391,6 +408,7 @@ and typedecl_equation = ( "constraints", (fun t -> t.constraints), List (Pair (typeexpr_t, typeexpr_t)) ); + F ("kind", (fun t -> t.kind), kind_annotation); ] and typedecl_t = @@ -460,6 +478,7 @@ and value_t = F ("doc", (fun t -> t.doc), docs); F ("type_", (fun t -> t.type_), typeexpr_t); F ("value", (fun t -> t.value), value_value_t); + F ("modalities", (fun t -> t.modalities), List string); ] (** {3 Class} *) @@ -667,7 +686,11 @@ and typeexpr_t = | Object x -> C ("Object", x, typeexpr_object) | Class (x1, x2) -> C ("Class", ((x1 :> Paths.Path.t), x2), Pair (path, List typeexpr_t)) - | Poly (x1, x2) -> C ("Poly", (x1, x2), Pair (List string, typeexpr_t)) + | Poly (x1, x2) -> + C + ( "Poly", + (x1, x2), + Pair (List (Pair (string, kind_annotation)), typeexpr_t) ) | Quote x -> C ("Quote", x, typeexpr_t) | Splice x -> C ("Splice", x, typeexpr_t) | Package x -> C ("Package", x, typeexpr_package)) diff --git a/src/search/html.ml b/src/search/html.ml index df5aaab310..b1245179fd 100644 --- a/src/search/html.ml +++ b/src/search/html.ml @@ -34,10 +34,10 @@ let display_constructor_args args = let open Odoc_model.Lang in match args with | TypeDecl.Constructor.Tuple args -> - let no_label arg = (None, arg) in + let no_label (arg, _mods) = (None, arg) in (match args with | _ :: _ :: _ -> Some TypeExpr.(Tuple (List.map no_label args)) - | [ arg ] -> Some arg + | [ (arg, _) ] -> Some arg | _ -> None) |> map_option Text.of_type | TypeDecl.Constructor.Record fields -> Some (Text.of_record fields) @@ -55,7 +55,7 @@ let field_rhs ({ mutable_ = _; type_; parent_type = _ } : Entry.field_entry) = " : " ^ Text.of_type type_ let typedecl_params ?(delim = `parens) params = - let format_param { TypeDecl.desc; variance; injectivity } = + let format_param { TypeDecl.desc; variance; injectivity; kind = _ } = let desc = match desc with TypeDecl.Any -> [ "_" ] | Var s -> [ "'"; s ] in diff --git a/src/search/json_index/json_search.ml b/src/search/json_index/json_search.ml index e490e7b41b..5813e606b8 100644 --- a/src/search/json_index/json_search.ml +++ b/src/search/json_index/json_search.ml @@ -7,7 +7,9 @@ let json_of_args (args : Odoc_model.Lang.TypeDecl.Constructor.argument) = `Object [ ("kind", `String "Tuple"); - ("vals", `Array (List.map (fun te -> `String (Text.of_type te)) tel)); + ( "vals", + `Array (List.map (fun (te, _mods) -> `String (Text.of_type te)) tel) + ); ] | Record fl -> `Object @@ -21,6 +23,7 @@ let json_of_args (args : Odoc_model.Lang.TypeDecl.Constructor.argument) = mutable_; type_; doc = _; + modalities = _; } -> `Object [ @@ -152,6 +155,7 @@ let of_entry ({ Entry.id; doc; kind } as entry) html occurrences = private_; manifest; constraints; + kind = _; } = equation in diff --git a/src/xref2/compile.ml b/src/xref2/compile.ml index 6d92d8e071..c792c4f631 100644 --- a/src/xref2/compile.ml +++ b/src/xref2/compile.ml @@ -803,7 +803,9 @@ and type_decl_unboxed_field env parent f = and type_decl_constructor_argument env parent c = let open TypeDecl.Constructor in match c with - | Tuple ts -> Tuple (List.map (type_expression env parent) ts) + | Tuple ts -> + Tuple + (List.map (fun (te, mods) -> (type_expression env parent te, mods)) ts) | Record fs -> Record (List.map (type_decl_field env parent) fs) and type_decl_constructor : diff --git a/src/xref2/component.ml b/src/xref2/component.ml index 9017fea357..c793944cbf 100644 --- a/src/xref2/component.ml +++ b/src/xref2/component.ml @@ -128,7 +128,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Cpath.class_type * t list - | Poly of string list * t + | Poly of (string * Odoc_model.Lang.KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t @@ -247,6 +247,7 @@ and TypeDecl : sig doc : CComment.docs; mutable_ : bool; type_ : TypeExpr.t; + modalities : Odoc_model.Lang.Modalities.t; } end @@ -260,7 +261,9 @@ and TypeDecl : sig end module Constructor : sig - type argument = Tuple of TypeExpr.t list | Record of Field.t list + type argument = + | Tuple of (TypeExpr.t * Odoc_model.Lang.Modalities.t) list + | Record of Field.t list type t = { name : string; @@ -286,6 +289,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : Odoc_model.Lang.KindAnnotation.t; } end @@ -307,6 +311,7 @@ and Value : sig doc : CComment.docs; type_ : TypeExpr.t; value : value; + modalities : Odoc_model.Lang.Modalities.t; } end = Value @@ -1048,7 +1053,7 @@ module Fmt = struct and type_decl_constructor_arg c ppf = let open TypeDecl.Constructor in function - | Tuple ts -> type_constructor_params c ppf ts + | Tuple ts -> type_constructor_params c ppf (List.map fst ts) | Record fs -> type_decl_fields c ppf fs and type_decl_field c ppf t = @@ -2249,7 +2254,8 @@ module Of_Lang = struct let open Odoc_model.Lang.TypeDecl.Constructor in match a with | Tuple ts -> - TypeDecl.Constructor.Tuple (List.map (type_expression ident_map) ts) + TypeDecl.Constructor.Tuple + (List.map (fun (te, mods) -> (type_expression ident_map te, mods)) ts) | Record fs -> Record (List.map (type_decl_field ident_map) fs) and type_decl_field ident_map f = @@ -2260,6 +2266,7 @@ module Of_Lang = struct doc = docs ident_map f.doc; mutable_ = f.mutable_; type_; + modalities = f.modalities; } and type_decl_unboxed_field ident_map f = @@ -2282,6 +2289,7 @@ module Of_Lang = struct (fun (x, y) -> (type_expression ident_map x, type_expression ident_map y)) teq.constraints; + kind = teq.kind; } and type_expr_polyvar ident_map v = @@ -2586,6 +2594,7 @@ module Of_Lang = struct doc = docs ident_map v.doc; value = v.value; source_loc = v.source_loc; + modalities = v.modalities; } and include_ ident_map i = diff --git a/src/xref2/component.mli b/src/xref2/component.mli index 0cd6e900f5..07b9fd593f 100644 --- a/src/xref2/component.mli +++ b/src/xref2/component.mli @@ -123,7 +123,7 @@ and TypeExpr : sig | Polymorphic_variant of TypeExpr.Polymorphic_variant.t | Object of TypeExpr.Object.t | Class of Cpath.class_type * t list - | Poly of string list * t + | Poly of (string * Odoc_model.Lang.KindAnnotation.t) list * t | Quote of t | Splice of t | Package of TypeExpr.Package.t @@ -237,6 +237,7 @@ and TypeDecl : sig doc : CComment.docs; mutable_ : bool; type_ : TypeExpr.t; + modalities : Odoc_model.Lang.Modalities.t; } end @@ -250,7 +251,9 @@ and TypeDecl : sig end module Constructor : sig - type argument = Tuple of TypeExpr.t list | Record of Field.t list + type argument = + | Tuple of (TypeExpr.t * Odoc_model.Lang.Modalities.t) list + | Record of Field.t list type t = { name : string; @@ -276,6 +279,7 @@ and TypeDecl : sig private_ : bool; manifest : TypeExpr.t option; constraints : (TypeExpr.t * TypeExpr.t) list; + kind : Odoc_model.Lang.KindAnnotation.t; } end @@ -349,6 +353,7 @@ and Value : sig doc : CComment.docs; type_ : TypeExpr.t; value : value; + modalities : Odoc_model.Lang.Modalities.t; } end diff --git a/src/xref2/lang_of.ml b/src/xref2/lang_of.ml index ed5f45dfd0..1767cd976c 100644 --- a/src/xref2/lang_of.ml +++ b/src/xref2/lang_of.ml @@ -692,6 +692,7 @@ and value_ map parent id v = doc = docs (parent :> Identifier.LabelParent.t) v.doc; type_ = type_expr map (parent :> Identifier.LabelParent.t) v.type_; value = v.value; + modalities = v.modalities; } and typ_ext map parent t = @@ -907,7 +908,11 @@ and type_decl_constructor_argument : fun map parent a -> match a with | Tuple ls -> - Tuple (List.map (type_expr map (parent :> Identifier.LabelParent.t)) ls) + Tuple + (List.map + (fun (te, mods) -> + (type_expr map (parent :> Identifier.LabelParent.t) te, mods)) + ls) | Record fs -> Record (List.map (type_decl_field map (parent :> Identifier.FieldParent.t)) fs) @@ -924,6 +929,7 @@ and type_decl_field : doc = docs (parent :> Identifier.LabelParent.t) f.doc; mutable_ = f.mutable_; type_ = type_expr map (parent :> Identifier.LabelParent.t) f.type_; + modalities = f.modalities; } and type_decl_unboxed_field : @@ -954,6 +960,7 @@ and type_decl_equation map (parent : Identifier.FieldParent.t) List.map (fun (x, y) -> (type_expr map parent x, type_expr map parent y)) eqn.constraints; + kind = eqn.kind; } and type_decl map parent id (t : Component.TypeDecl.t) : diff --git a/src/xref2/link.ml b/src/xref2/link.ml index 0cdac826db..fca592ce57 100644 --- a/src/xref2/link.ml +++ b/src/xref2/link.ml @@ -452,7 +452,9 @@ let warn_on_hidden_representation (id : Id.Type.t) let open Lang.TypeDecl.Field in match t.args with | Tuple type_exprs -> - List.exists (fun type_expr -> internal_typ_exp type_expr) type_exprs + List.exists + (fun (type_expr, _) -> internal_typ_exp type_expr) + type_exprs | Record fields -> List.exists (fun field -> internal_typ_exp field.type_) fields in @@ -1063,7 +1065,11 @@ and type_decl_unboxed_field env parent f = and type_decl_constructor_argument env parent c = let open TypeDecl.Constructor in match c with - | Tuple ts -> Tuple (List.map (type_expression env parent []) ts) + | Tuple ts -> + Tuple + (List.map + (fun (te, mods) -> (type_expression env parent [] te, mods)) + ts) | Record fs -> Record (List.map (type_decl_field env parent) fs) and type_decl_constructor env parent c = diff --git a/src/xref2/strengthen.ml b/src/xref2/strengthen.ml index a1c4125960..c6460856d6 100644 --- a/src/xref2/strengthen.ml +++ b/src/xref2/strengthen.ml @@ -112,6 +112,7 @@ and type_decl : Cpath.type_ -> TypeDecl.t -> TypeDecl.t = private_ = e.private_; manifest; constraints = e.constraints; + kind = e.kind; } in { t with equation } diff --git a/src/xref2/subst.ml b/src/xref2/subst.ml index e6c02e469b..c196f18794 100644 --- a/src/xref2/subst.ml +++ b/src/xref2/subst.ml @@ -763,7 +763,7 @@ and type_decl_unboxed_field s f = and type_decl_constructor_arg s a = let open Component.TypeDecl.Constructor in match a with - | Tuple ts -> Tuple (list type_expr s ts) + | Tuple ts -> Tuple (List.map (fun (te, mods) -> (type_expr s te, mods)) ts) | Record fs -> Record (list type_decl_field s fs) and type_decl_equation s t = diff --git a/src/xref2/test.md b/src/xref2/test.md index 6c4306b182..b64a29119a 100644 --- a/src/xref2/test.md +++ b/src/xref2/test.md @@ -211,7 +211,8 @@ and so we simply look up the type in the environment, giving a `Component.Type.t canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary, {Odoc_model.Lang.TypeDecl.id = @@ -248,7 +249,7 @@ and so we simply look up the type in the environment, giving a `Component.Type.t x); ihash = 622581103; ikey = "t_x.r_Root.p_None"}), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}} @@ -355,7 +356,8 @@ val module_ : Component.Module.t Component.Delayed.t = canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -383,7 +385,8 @@ Odoc_xref2.Tools.Signature canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -539,7 +542,9 @@ val m : Component.Element.module_type option = {Odoc_xref2.Component.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = + Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -1074,7 +1079,8 @@ Odoc_xref2.Tools.Signature canonical = None; equation = {Odoc_xref2.Component.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}; get = None})]; compiled = false; removed = []; @@ -2631,7 +2637,8 @@ let resolved = Common.compile_signature sg;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None} ``` @@ -2700,7 +2707,8 @@ let sg = Common.signature_of_mli_string test_data;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = false; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2722,7 +2730,8 @@ let sg = Common.signature_of_mli_string test_data;; canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.ModuleType {Odoc_model.Lang.ModuleType.id = @@ -2765,7 +2774,8 @@ let sg = Common.signature_of_mli_string test_data;; u); ihash = 15973539; ikey = "t_u.r_Root.p_None"}), [])); - constraints = []})]; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default})]; w_expansion = None; w_expr = Odoc_model.Lang.ModuleType.U.Path @@ -2835,7 +2845,8 @@ Odoc_model.Lang.ModuleType.Path canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = Some (Odoc_model.Lang.TypeDecl.Representation.Variant @@ -3125,7 +3136,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = @@ -3214,7 +3225,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = @@ -3335,7 +3346,7 @@ let sg = Common.signature_of_mli_string test_data;; false), t), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Value {Odoc_model.Lang.Value.id = diff --git a/test/generators/cases/oxcaml.mli b/test/generators/cases/oxcaml.mli index 9a60035c51..1d742b94c3 100644 --- a/test/generators/cases/oxcaml.mli +++ b/test/generators/cases/oxcaml.mli @@ -1,2 +1,198 @@ val f : int -> ('a . 'a -> 'a) -> unit (** Polymorphic arguments require parentheses *) + +(** {1 Layouts} *) + +type t_any : any +(** Layout [any]. *) + +type t_value_or_null : value_or_null +(** Layout [value_or_null]. *) + +type t_float64 : float64 +(** Layout [float64]. *) + +type t_float32 : float32 +(** Layout [float32]. *) + +type t_word : word +(** Layout [word]. *) + +type t_bits64 : bits64 +(** Layout [bits64]. *) + +type t_bits32 : bits32 +(** Layout [bits32]. *) + +type t_vec128 : vec128 +(** Layout [vec128]. *) + +type t_void : void +(** Layout [void]. *) + +(** {1 Kind abbreviations} *) + +type t_value : value +(** [value] is the default kind, so the annotation is not rendered. *) + +type t_immediate : immediate +(** Kind abbreviation [immediate]. *) + +type t_immediate64 : immediate64 +(** Kind abbreviation [immediate64]. *) + +type t_immutable_data : immutable_data +(** Kind abbreviation [immutable_data]. *) + +type t_sync_data : sync_data +(** Kind abbreviation [sync_data]. *) + +type t_mutable_data : mutable_data +(** Kind abbreviation [mutable_data]. *) + +(** {1 Kind annotations with modalities} *) + +type t_portable : value mod portable +(** Kind annotation with a modality. *) + +type t_contended : value mod contended +(** Kind annotation with a different modality. *) + +type t_multi_mod : value mod portable contended +(** Kind annotation with multiple modalities. *) + +type t_everything : float64 mod everything +(** The [everything] bounds abbreviation. *) + +(** {1 Kind annotations on parameterized types} *) + +type ('a : immediate) imm_param +(** A type parameter with a kind constraint. *) + +type ('a : float64) float_param +(** A type parameter with a different kind constraint. *) + +type ('a : immediate, 'b : float64) multi_kind +(** Multiple kind-constrained parameters. *) + +(** {1 Kind annotations with [with] constraints} *) + +type 'a t_with : immediate with 'a +(** Kind annotation with a [with] constraint. *) + +(** {1 Kind annotations on type aliases} *) + +type t_alias : immediate = int +(** Has both a kind annotation and a manifest. *) + +(** {1 Kind-constrained polymorphism in values} *) + +val poly_immediate : ('a : immediate). 'a -> 'a +(** Kind constraint on a polymorphic type variable. *) + +val poly_float64 : ('a : float64). 'a -> 'a +(** Kind constraint on a polymorphic type variable with a different kind. *) + +(** {1 Modalities} *) + +type opaque + +type modalities_all = { + f_global : opaque @@ global; + (** Locality modality. *) + f_local : opaque @@ local; + (** Locality modality (identity, not rendered). *) + f_unique : opaque @@ unique; + (** Uniqueness modality. *) + f_aliased : opaque @@ aliased; + (** Uniqueness modality (identity, not rendered). *) + f_many : opaque @@ many; + (** Linearity modality. *) + f_once : opaque @@ once; + (** Linearity modality (identity, not rendered). *) + f_portable : opaque @@ portable; + (** Portability modality. *) + f_nonportable : opaque @@ nonportable; + (** Portability modality (identity, not rendered). *) + f_uncontended : opaque @@ uncontended; + (** Contention modality (identity, not rendered). *) + f_contended : opaque @@ contended; + (** Contention modality. *) + f_unyielding : opaque @@ unyielding; + (** Yield modality. *) + f_yielding : opaque @@ yielding; + (** Yield modality (identity, not rendered). *) + f_forkable : opaque @@ forkable; + (** Fork modality. *) + f_unforkable : opaque @@ unforkable; + (** Fork modality (identity, not rendered). *) + f_stateless : opaque @@ stateless; + (** Statefulness modality. *) + f_stateful : opaque @@ stateful; + (** Statefulness modality (identity, not rendered). *) + f_immutable : opaque @@ immutable; + (** Visibility modality. *) + f_read_write : opaque @@ read_write; + (** Visibility modality (identity, not rendered). *) + f_no_modality : opaque; + (** No modality, for reference. *) +} + +(** {1 Multiple modalities on a field} *) + +type modalities_multi = { + a : opaque @@ global portable; + (** Field with [global portable] modalities. *) +} + +(** {1 Modalities on tuple and function fields} *) + +type modalities_tuple = { + f : int * string @@ portable; + (** Tuple field with modality. *) +} + +type modalities_fn = { + g : int -> int @@ portable; + (** Function field with modality. *) +} + +(** {1 Modalities on constructor arguments} *) + +type modalities_cstr = + | A of string @@ global + (** Constructor argument with [global] modality. *) + | B of (int -> int) @@ portable + (** Function constructor argument with modality. *) + | C of int * string @@ portable + (** Tuple constructor argument with modality. *) + | D of int @@ portable * string @@ global + (** Per-element modalities in a constructor tuple. *) + | E + (** Constant constructor. *) + +(** {1 Modalities on values} *) + +val portable_fn : (int -> int) @@ portable +(** Value with [portable] modality. *) + +(** {1 Modalities on module declarations} *) + +module type S = sig + val x : int + val f : string -> bool + type s = { a : int } +end + +module M1 : S +(** Module without modality. *) + +module M2 : S @@ portable +(** Module with [portable] modality. The modality is applied to + all value members of [M2]. *) + +module M3 : sig @@ contended + val f : string -> bool + type s +end +(** [contended] modality applied to all definitions in the module. *) diff --git a/test/generators/gen_rules/gen_rules.ml b/test/generators/gen_rules/gen_rules.ml index e20d5f64ab..ad9c1bd4d8 100644 --- a/test/generators/gen_rules/gen_rules.ml +++ b/test/generators/gen_rules/gen_rules.ml @@ -62,7 +62,7 @@ let constraints = ("ocamlary.mli", Min "4.14"); ("recent.mli", Min "5.4"); ("labels.mli", Min "4.09"); - ("recent_impl.ml", Min "4.09"); + ("recent_impl.ml", MinNotOxCaml "4.09"); ("bugs_pre_410.ml", Max "4.09"); ("module_type_subst.mli", Min "4.13"); ("class_comments.mli", Min "4.08"); diff --git a/test/generators/gen_rules_lib.ml b/test/generators/gen_rules_lib.ml index b3340e0221..dff635cf1c 100644 --- a/test/generators/gen_rules_lib.ml +++ b/test/generators/gen_rules_lib.ml @@ -7,6 +7,7 @@ type enabledif = | Max of string | MinMax of string * string | OxCaml + | MinNotOxCaml of string type test_case = { input : Fpath.t; @@ -54,6 +55,19 @@ module Dune = struct ]; ] | Some OxCaml -> [ List [ Atom "enabled_if"; Atom "%{ocaml-config:ox}" ] ] + | Some (MinNotOxCaml v) -> + [ + List + [ + Atom "enabled_if"; + List + [ + Atom "and"; + List [ Atom ">="; Atom "%{ocaml_version}"; Atom v ]; + List [ Atom "not"; Atom "%{ocaml-config:ox}" ]; + ]; + ]; + ] | None -> [] let run cmd = List (Atom "run" :: arg_list cmd) diff --git a/test/generators/html/Oxcaml-M1.html b/test/generators/html/Oxcaml-M1.html new file mode 100644 index 0000000000..151e180df3 --- /dev/null +++ b/test/generators/html/Oxcaml-M1.html @@ -0,0 +1,52 @@ + + + M1 (Oxcaml.M1) + + + + + + + + +
+

Module Oxcaml.M1

+

Module without modality.

+
+
+
+
+ + val x : int +
+
+
+
+ + + val f : + string -> bool + + +
+
+
+
+ + type s = + { + +
    +
  1. + + a : int; +
  2. +
} +
+
+
+ + diff --git a/test/generators/html/Oxcaml-M2.html b/test/generators/html/Oxcaml-M2.html new file mode 100644 index 0000000000..14e077302e --- /dev/null +++ b/test/generators/html/Oxcaml-M2.html @@ -0,0 +1,56 @@ + + + M2 (Oxcaml.M2) + + + + + + + + +
+

Module Oxcaml.M2

+

Module with portable modality. The modality is applied + to all value members of M2. +

+
+
+
+
+ + val x : int @@ portable + +
+
+
+
+ + + val f : + string -> bool + @@ portable + + +
+
+
+
+ + type s : immutable_data + = { + +
    +
  1. + + a : int; +
  2. +
} +
+
+
+ + diff --git a/test/generators/html/Oxcaml-M3.html b/test/generators/html/Oxcaml-M3.html new file mode 100644 index 0000000000..4ebcb31cc8 --- /dev/null +++ b/test/generators/html/Oxcaml-M3.html @@ -0,0 +1,41 @@ + + + M3 (Oxcaml.M3) + + + + + + + + +
+

Module Oxcaml.M3

+

contended modality applied to all definitions in the + module. +

+
+
+
+
+ + + val f : + string -> bool + @@ contended + + +
+
+
+
+ + type s +
+
+
+ + diff --git a/test/generators/html/Oxcaml-module-type-S.html b/test/generators/html/Oxcaml-module-type-S.html new file mode 100644 index 0000000000..7d3075d563 --- /dev/null +++ b/test/generators/html/Oxcaml-module-type-S.html @@ -0,0 +1,51 @@ + + + S (Oxcaml.S) + + + + + + + + +
+

Module type Oxcaml.S

+
+
+
+
+ + val x : int +
+
+
+
+ + + val f : + string -> bool + + +
+
+
+
+ + type s = + { + +
    +
  1. + + a : int; +
  2. +
} +
+
+
+ + diff --git a/test/generators/html/Oxcaml.html b/test/generators/html/Oxcaml.html index f6760c5410..91f57bd956 100644 --- a/test/generators/html/Oxcaml.html +++ b/test/generators/html/Oxcaml.html @@ -14,6 +14,58 @@

Module Oxcaml

+
+ +
@@ -33,6 +85,728 @@

Module Oxcaml

Polymorphic arguments require parentheses

+

Layouts

+
+
+ + type t_any : any +

Layout any.

+
+
+
+ + + type t_value_or_null : value_or_null + + +
+

Layout value_or_null.

+
+
+
+ + type t_float64 : float64 + +

Layout float64.

+
+
+
+ + type t_float32 : float32 + +

Layout float32.

+
+
+
+ + type t_word : word + +

Layout word.

+
+
+
+ + type t_bits64 : bits64 + +

Layout bits64.

+
+
+
+ + type t_bits32 : bits32 + +

Layout bits32.

+
+
+
+ + type t_vec128 : vec128 + +

Layout vec128.

+
+
+
+ + type t_void : void + +

Layout void.

+
+

+ Kind abbreviations +

+
+
+ + type t_value +
+
+

value is the default kind, so the annotation is + not rendered. +

+
+
+
+
+ + + type t_immediate : immediate + +
+

Kind abbreviation immediate.

+
+
+
+
+ + + type t_immediate64 : immediate64 + + +
+

Kind abbreviation immediate64.

+
+
+
+
+ + + type t_immutable_data : + immutable_data + + +
+
+

Kind abbreviation immutable_data.

+
+
+
+
+ + + type t_sync_data : sync_data + +
+

Kind abbreviation sync_data.

+
+
+
+
+ + + type t_mutable_data : mutable_data + + +
+

Kind abbreviation mutable_data.

+
+
+

+ Kind + annotations with modalities +

+
+
+ + + type t_portable : value + mod portable + + +

Kind annotation with a modality.

+
+
+
+ + + type t_contended : value + mod contended + + +
+

Kind annotation with a different modality.

+
+
+
+
+ + + type t_multi_mod : value + mod portable contended + + +
+

Kind annotation with multiple modalities.

+
+
+
+
+ + + type t_everything : float64 + mod everything + + +
+
+

The everything bounds abbreviation.

+
+
+

+ + Kind annotations on parameterized types +

+
+
+ + + type + ('a : immediate) imm_param + + +
+

A type parameter with a kind constraint.

+
+
+
+
+ + + type + ('a : float64) float_param + + +
+
+

A type parameter with a different kind constraint.

+
+
+
+
+ + + type + (('a : immediate), ('b : float64)) multi_kind + + +
+

Multiple kind-constrained parameters.

+
+

+ + Kind annotations with with constraints +

+
+
+ + + type 'a t_with : + immediate with + 'a + + +
+
+

Kind annotation with a with constraint.

+
+
+

+ Kind + annotations on type aliases +

+
+
+ + type t_alias : immediate + = int + +
+

Has both a kind annotation and a manifest.

+
+
+

+ + Kind-constrained polymorphism in values +

+
+
+ + + val poly_immediate : ('a : immediate + ). + 'a + -> + 'a + + +
+
+

Kind constraint on a polymorphic type variable.

+
+
+
+
+ + + val poly_float64 : ('a : float64 + ). + 'a + -> + 'a + + +
+
+

Kind constraint on a polymorphic type variable with a different kind. +

+
+
+

Modalities +

+
+
+ + type opaque +
+
+
+
+ + type modalities_all + = { + +
    +
  1. + + + f_global : opaque @@ global; + +
    (* +

    Locality modality.

    *) +
    +
  2. +
  3. + + f_local : opaque; +
    (* +

    Locality modality (identity, not rendered).

    + *) +
    +
  4. +
  5. + + f_unique : opaque; + +
    (* +

    Uniqueness modality.

    *) +
    +
  6. +
  7. + + f_aliased : opaque @@ aliased; + + +
    (* +

    Uniqueness modality (identity, not rendered).

    + *) +
    +
  8. +
  9. + + f_many : opaque @@ many; + +
    (* +

    Linearity modality.

    *) +
    +
  10. +
  11. + + f_once : opaque; +
    (* +

    Linearity modality (identity, not rendered).

    + *) +
    +
  12. +
  13. + + + f_portable : opaque @@ portable; + + +
    (* +

    Portability modality.

    *) +
    +
  14. +
  15. + + f_nonportable : opaque; + +
    (* +

    Portability modality (identity, not rendered).

    + *) +
    +
  16. +
  17. + + f_uncontended : opaque; + +
    (* +

    Contention modality (identity, not rendered).

    + *) +
    +
  18. +
  19. + + + f_contended : opaque @@ contended; + + +
    (* +

    Contention modality.

    *) +
    +
  20. +
  21. + + + f_unyielding : opaque @@ unyielding; + + +
    (* +

    Yield modality.

    *) +
    +
  22. +
  23. + + f_yielding : opaque; + +
    (* +

    Yield modality (identity, not rendered).

    + *) +
    +
  24. +
  25. + + + f_forkable : opaque @@ forkable; + + +
    (* +

    Fork modality.

    *) +
    +
  26. +
  27. + + f_unforkable : opaque; + +
    (* +

    Fork modality (identity, not rendered).

    + *) +
    +
  28. +
  29. + + + f_stateless : opaque @@ stateless; + + +
    (* +

    Statefulness modality.

    *) +
    +
  30. +
  31. + + f_stateful : opaque; + +
    (* +

    Statefulness modality (identity, not rendered).

    + *) +
    +
  32. +
  33. + + + f_immutable : opaque @@ immutable; + + +
    (* +

    Visibility modality.

    *) +
    +
  34. +
  35. + + f_read_write : opaque; + +
    (* +

    Visibility modality (identity, not rendered).

    + *) +
    +
  36. +
  37. + + f_no_modality : opaque; + +
    (* +

    No modality, for reference.

    + *) +
    +
  38. +
} +
+
+

+ Multiple + modalities on a field +

+
+
+ + type modalities_multi + = { + +
    +
  1. + + + a : opaque @@ global portable; + + +
    (* +

    Field with global portable modalities.

    + *) +
    +
  2. +
} +
+
+

+ + Modalities on tuple and function fields +

+
+
+ + type modalities_tuple + = { + +
    +
  1. + + f : int * string @@ portable; +
    (* +

    Tuple field with modality.

    + *) +
    +
  2. +
} +
+
+
+
+ + type modalities_fn + = { + +
    +
  1. + + + g : int -> + int @@ portable; + + +
    (* +

    Function field with modality.

    + *) +
    +
  2. +
} +
+
+

+ + Modalities on constructor arguments +

+
+
+ + type modalities_cstr + = + +
    +
  1. + | + A + of string @@ global + + +
    (* +

    Constructor argument with global modality.

    + *) +
    +
  2. +
  3. + | + B + of + int -> int @@ + portable + + +
    (* +

    Function constructor argument with modality.

    + *) +
    +
  4. +
  5. + | + C + of int * string @@ portable + + +
    (* +

    Tuple constructor argument with modality.

    + *) +
    +
  6. +
  7. + | + D + of int @@ portable * string @@ + global + + +
    (* +

    Per-element modalities in a constructor tuple.

    + *) +
    +
  8. +
  9. + | E + +
    (* +

    Constant constructor.

    *) +
    +
  10. +
+
+
+

+ Modalities on + values +

+
+
+ + + val portable_fn : + int -> int @@ portable + + +
+

Value with portable modality.

+
+
+

+ + Modalities on module declarations +

+
+
+ + + module + type + S + + = sig ... + end + + +
+
+
+
+ + + module + M1 + : S + +

Module without modality.

+
+
+
+ + + module + M2 + + : sig ... + end + + +
+
+

Module with portable modality. The modality is applied + to all value members of M2. +

+
+
+
+
+ + + module + M3 + + : sig ... + end + + +
+
+

contended modality applied to all definitions in + the module. +

+
diff --git a/test/generators/html/oxcaml.targets b/test/generators/html/oxcaml.targets index 83c7bab09f..77bc5f1da0 100644 --- a/test/generators/html/oxcaml.targets +++ b/test/generators/html/oxcaml.targets @@ -1 +1,5 @@ Oxcaml.html +Oxcaml-module-type-S.html +Oxcaml-M1.html +Oxcaml-M2.html +Oxcaml-M3.html diff --git a/test/generators/latex/Oxcaml.M1.tex b/test/generators/latex/Oxcaml.M1.tex new file mode 100644 index 0000000000..400640afdc --- /dev/null +++ b/test/generators/latex/Oxcaml.M1.tex @@ -0,0 +1,12 @@ +\section{Module \ocamlinlinecode{Oxcaml.\allowbreak{}M1}}\label{Oxcaml-M1}% +Module without modality. + +\label{Oxcaml-M1--val-x}\ocamlcodefragment{\ocamltag{keyword}{val} x : int}\\ +\label{Oxcaml-M1--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : string \ocamltag{arrow}{$\rightarrow$} bool}\\ +\label{Oxcaml-M1--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{Oxcaml-M1--type-s.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ + + diff --git a/test/generators/latex/Oxcaml.M2.tex b/test/generators/latex/Oxcaml.M2.tex new file mode 100644 index 0000000000..9897a40b9d --- /dev/null +++ b/test/generators/latex/Oxcaml.M2.tex @@ -0,0 +1,12 @@ +\section{Module \ocamlinlinecode{Oxcaml.\allowbreak{}M2}}\label{Oxcaml-M2}% +Module with \ocamlinlinecode{portable} modality. The modality is applied to all value members of \ocamlinlinecode{M2}. + +\label{Oxcaml-M2--val-x}\ocamlcodefragment{\ocamltag{keyword}{val} x : int}\\ +\label{Oxcaml-M2--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : string \ocamltag{arrow}{$\rightarrow$} bool}\\ +\label{Oxcaml-M2--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{Oxcaml-M2--type-s.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ + + diff --git a/test/generators/latex/Oxcaml.M3.tex b/test/generators/latex/Oxcaml.M3.tex new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/generators/latex/Oxcaml.tex b/test/generators/latex/Oxcaml.tex index db657fcbe7..967897532a 100644 --- a/test/generators/latex/Oxcaml.tex +++ b/test/generators/latex/Oxcaml.tex @@ -1,5 +1,162 @@ \section{Module \ocamlinlinecode{Oxcaml}}\label{Oxcaml}% \label{Oxcaml--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : int \ocamltag{arrow}{$\rightarrow$} ('a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}) \ocamltag{arrow}{$\rightarrow$} unit}\begin{ocamlindent}Polymorphic arguments require parentheses\end{ocamlindent}% \medbreak +\subsection{Layouts\label{Oxcaml--layouts}}% +\label{Oxcaml--type-t_any}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}any : any}\begin{ocamlindent}Layout \ocamlinlinecode{any}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_value_or_null}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value\_\allowbreak{}or\_\allowbreak{}null : value\_\allowbreak{}or\_\allowbreak{}null}\begin{ocamlindent}Layout \ocamlinlinecode{value\_\allowbreak{}or\_\allowbreak{}null}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_float64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float64 : float64}\begin{ocamlindent}Layout \ocamlinlinecode{float64}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_float32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}float32 : float32}\begin{ocamlindent}Layout \ocamlinlinecode{float32}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_word}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}word : word}\begin{ocamlindent}Layout \ocamlinlinecode{word}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_bits64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits64 : bits64}\begin{ocamlindent}Layout \ocamlinlinecode{bits64}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_bits32}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}bits32 : bits32}\begin{ocamlindent}Layout \ocamlinlinecode{bits32}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_vec128}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}vec128 : vec128}\begin{ocamlindent}Layout \ocamlinlinecode{vec128}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_void}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}void : void}\begin{ocamlindent}Layout \ocamlinlinecode{void}.\end{ocamlindent}% +\medbreak +\subsection{Kind abbreviations\label{Oxcaml--kind-abbreviations}}% +\label{Oxcaml--type-t_value}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}value}\begin{ocamlindent}\ocamlinlinecode{value} is the default kind, so the annotation is not rendered.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_immediate}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate : immediate}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immediate}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_immediate64}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immediate64 : immediate64}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immediate64}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_immutable_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}immutable\_\allowbreak{}data : immutable\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{immutable\_\allowbreak{}data}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_sync_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}sync\_\allowbreak{}data : sync\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{sync\_\allowbreak{}data}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_mutable_data}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}mutable\_\allowbreak{}data : mutable\_\allowbreak{}data}\begin{ocamlindent}Kind abbreviation \ocamlinlinecode{mutable\_\allowbreak{}data}.\end{ocamlindent}% +\medbreak +\subsection{Kind annotations with modalities\label{Oxcaml--kind-annotations-with-modalities}}% +\label{Oxcaml--type-t_portable}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}portable : value \ocamltag{keyword}{mod} portable}\begin{ocamlindent}Kind annotation with a modality.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_contended}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}contended : value \ocamltag{keyword}{mod} contended}\begin{ocamlindent}Kind annotation with a different modality.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_multi_mod}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}multi\_\allowbreak{}mod : value \ocamltag{keyword}{mod} portable contended}\begin{ocamlindent}Kind annotation with multiple modalities.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-t_everything}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}everything : float64 \ocamltag{keyword}{mod} everything}\begin{ocamlindent}The \ocamlinlinecode{everything} bounds abbreviation.\end{ocamlindent}% +\medbreak +\subsection{Kind annotations on parameterized types\label{Oxcaml--kind-annotations-on-parameterized-types}}% +\label{Oxcaml--type-imm_param}\ocamlcodefragment{\ocamltag{keyword}{type} ('a : immediate) imm\_\allowbreak{}param}\begin{ocamlindent}A type parameter with a kind constraint.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-float_param}\ocamlcodefragment{\ocamltag{keyword}{type} ('a : float64) float\_\allowbreak{}param}\begin{ocamlindent}A type parameter with a different kind constraint.\end{ocamlindent}% +\medbreak +\label{Oxcaml--type-multi_kind}\ocamlcodefragment{\ocamltag{keyword}{type} (('a : immediate),\allowbreak{} ('b : float64)) multi\_\allowbreak{}kind}\begin{ocamlindent}Multiple kind-constrained parameters.\end{ocamlindent}% +\medbreak +\subsection{Kind annotations with \ocamlinlinecode{with} constraints\label{Oxcaml--kind-annotations-with-with-constraints}}% +\label{Oxcaml--type-t_with}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t\_\allowbreak{}with : immediate \ocamltag{keyword}{with} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind annotation with a \ocamlinlinecode{with} constraint.\end{ocamlindent}% +\medbreak +\subsection{Kind annotations on type aliases\label{Oxcaml--kind-annotations-on-type-aliases}}% +\label{Oxcaml--type-t_alias}\ocamlcodefragment{\ocamltag{keyword}{type} t\_\allowbreak{}alias : immediate = int}\begin{ocamlindent}Has both a kind annotation and a manifest.\end{ocamlindent}% +\medbreak +\subsection{Kind-constrained polymorphism in values\label{Oxcaml--kind-constrained-polymorphism-in-values}}% +\label{Oxcaml--val-poly_immediate}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}immediate : ('a : immediate).\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind constraint on a polymorphic type variable.\end{ocamlindent}% +\medbreak +\label{Oxcaml--val-poly_float64}\ocamlcodefragment{\ocamltag{keyword}{val} poly\_\allowbreak{}float64 : ('a : float64).\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}}\begin{ocamlindent}Kind constraint on a polymorphic type variable with a different kind.\end{ocamlindent}% +\medbreak +\subsection{Modalities\label{Oxcaml--modalities}}% +\label{Oxcaml--type-opaque}\ocamlcodefragment{\ocamltag{keyword}{type} opaque}\\ +\label{Oxcaml--type-modalities_all}\ocamlcodefragment{\ocamltag{keyword}{type} modalities\_\allowbreak{}all = \{}\begin{ocamlindent}\ocamlinlinecode{f\_\allowbreak{}global : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ global;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_global}% +\begin{ocamlindent}Locality modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}local : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_local}% +\begin{ocamlindent}Locality modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}unique : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_unique}% +\begin{ocamlindent}Uniqueness modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}aliased : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ aliased;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_aliased}% +\begin{ocamlindent}Uniqueness modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}many : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ many;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_many}% +\begin{ocamlindent}Linearity modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}once : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_once}% +\begin{ocamlindent}Linearity modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}portable : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ portable;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_portable}% +\begin{ocamlindent}Portability modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}nonportable : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_nonportable}% +\begin{ocamlindent}Portability modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}uncontended : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_uncontended}% +\begin{ocamlindent}Contention modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}contended : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ contended;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_contended}% +\begin{ocamlindent}Contention modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}unyielding : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ unyielding;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_unyielding}% +\begin{ocamlindent}Yield modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}yielding : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_yielding}% +\begin{ocamlindent}Yield modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}forkable : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ forkable;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_forkable}% +\begin{ocamlindent}Fork modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}unforkable : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_unforkable}% +\begin{ocamlindent}Fork modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}stateless : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ stateless;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_stateless}% +\begin{ocamlindent}Statefulness modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}stateful : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_stateful}% +\begin{ocamlindent}Statefulness modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}immutable : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ immutable;\allowbreak{}}\label{Oxcaml--type-modalities_all.f_immutable}% +\begin{ocamlindent}Visibility modality.\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}read\_\allowbreak{}write : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_read_write}% +\begin{ocamlindent}Visibility modality (identity, not rendered).\end{ocamlindent}% +\ocamlinlinecode{f\_\allowbreak{}no\_\allowbreak{}modality : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}};\allowbreak{}}\label{Oxcaml--type-modalities_all.f_no_modality}% +\begin{ocamlindent}No modality, for reference.\end{ocamlindent}% +\end{ocamlindent}% +\ocamlcodefragment{\}}\\ +\subsection{Multiple modalities on a field\label{Oxcaml--multiple-modalities-on-a-field}}% +\label{Oxcaml--type-modalities_multi}\ocamlcodefragment{\ocamltag{keyword}{type} modalities\_\allowbreak{}multi = \{}\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{a : \hyperref[Oxcaml--type-opaque]{\ocamlinlinecode{opaque}} @@ global portable;\allowbreak{}}\label{Oxcaml--type-modalities_multi.a}& Field with \ocamlinlinecode{global portable} modalities.\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\subsection{Modalities on tuple and function fields\label{Oxcaml--modalities-on-tuple-and-function-fields}}% +\label{Oxcaml--type-modalities_tuple}\ocamlcodefragment{\ocamltag{keyword}{type} modalities\_\allowbreak{}tuple = \{}\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{f : int * string @@ portable;\allowbreak{}}\label{Oxcaml--type-modalities_tuple.f}& Tuple field with modality.\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\label{Oxcaml--type-modalities_fn}\ocamlcodefragment{\ocamltag{keyword}{type} modalities\_\allowbreak{}fn = \{}\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{g : int \ocamltag{arrow}{$\rightarrow$} int @@ portable;\allowbreak{}}\label{Oxcaml--type-modalities_fn.g}& Function field with modality.\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\subsection{Modalities on constructor arguments\label{Oxcaml--modalities-on-constructor-arguments}}% +\label{Oxcaml--type-modalities_cstr}\ocamlcodefragment{\ocamltag{keyword}{type} modalities\_\allowbreak{}cstr = }\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} \ocamltag{keyword}{of} string @@ global}\label{Oxcaml--type-modalities_cstr.A}& Constructor argument with \ocamlinlinecode{global} modality.\\ +\ocamlcodefragment{| \ocamltag{constructor}{B} \ocamltag{keyword}{of} int \ocamltag{arrow}{$\rightarrow$} int @@ portable}\label{Oxcaml--type-modalities_cstr.B}& Function constructor argument with modality.\\ +\ocamlcodefragment{| \ocamltag{constructor}{C} \ocamltag{keyword}{of} int * string @@ portable}\label{Oxcaml--type-modalities_cstr.C}& Tuple constructor argument with modality.\\ +\ocamlcodefragment{| \ocamltag{constructor}{D} \ocamltag{keyword}{of} int @@ portable * string @@ global}\label{Oxcaml--type-modalities_cstr.D}& Per-element modalities in a constructor tuple.\\ +\ocamlcodefragment{| \ocamltag{constructor}{E}}\label{Oxcaml--type-modalities_cstr.E}& Constant constructor.\\ +\end{ocamltabular}% +\\ +\subsection{Modalities on values\label{Oxcaml--modalities-on-values}}% +\label{Oxcaml--val-portable_fn}\ocamlcodefragment{\ocamltag{keyword}{val} portable\_\allowbreak{}fn : int \ocamltag{arrow}{$\rightarrow$} int @@ portable}\begin{ocamlindent}Value with \ocamlinlinecode{portable} modality.\end{ocamlindent}% +\medbreak +\subsection{Modalities on module declarations\label{Oxcaml--modalities-on-module-declarations}}% +\label{Oxcaml--module-type-S}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[Oxcaml-module-type-S]{\ocamlinlinecode{S}}}\label{Oxcaml-module-type-S}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-module-type-S--val-x}\ocamlcodefragment{\ocamltag{keyword}{val} x : int}\\ +\label{Oxcaml-module-type-S--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : string \ocamltag{arrow}{$\rightarrow$} bool}\\ +\label{Oxcaml-module-type-S--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{Oxcaml-module-type-S--type-s.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\\ +\label{Oxcaml--module-M1}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-M1]{\ocamlinlinecode{M1}}}\ocamlcodefragment{ : \hyperref[Oxcaml-module-type-S]{\ocamlinlinecode{S}}}\begin{ocamlindent}Module without modality.\end{ocamlindent}% +\medbreak +\label{Oxcaml--module-M2}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-M2]{\ocamlinlinecode{M2}}}\label{Oxcaml-M2}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-M2--val-x}\ocamlcodefragment{\ocamltag{keyword}{val} x : int @@ portable}\\ +\label{Oxcaml-M2--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : string \ocamltag{arrow}{$\rightarrow$} bool @@ portable}\\ +\label{Oxcaml-M2--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s : immutable\_\allowbreak{}data = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{Oxcaml-M2--type-s.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\begin{ocamlindent}Module with \ocamlinlinecode{portable} modality. The modality is applied to all value members of \ocamlinlinecode{M2}.\end{ocamlindent}% +\medbreak +\label{Oxcaml--module-M3}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[Oxcaml-M3]{\ocamlinlinecode{M3}}}\label{Oxcaml-M3}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Oxcaml-M3--val-f}\ocamlcodefragment{\ocamltag{keyword}{val} f : string \ocamltag{arrow}{$\rightarrow$} bool @@ contended}\\ +\label{Oxcaml-M3--type-s}\ocamlcodefragment{\ocamltag{keyword}{type} s}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\begin{ocamlindent}\ocamlinlinecode{contended} modality applied to all definitions in the module.\end{ocamlindent}% +\medbreak - +\input{Oxcaml.M1.tex} diff --git a/test/generators/latex/oxcaml.targets b/test/generators/latex/oxcaml.targets index 13eabaa2ba..7f76144fb3 100644 --- a/test/generators/latex/oxcaml.targets +++ b/test/generators/latex/oxcaml.targets @@ -1 +1,2 @@ Oxcaml.tex +Oxcaml.M1.tex diff --git a/test/generators/link.dune.inc b/test/generators/link.dune.inc index e5d3455c96..c93cb5685e 100644 --- a/test/generators/link.dune.inc +++ b/test/generators/link.dune.inc @@ -617,7 +617,9 @@ (action (run ocamlc -c -bin-annot -o %{target} %{dep:cases/recent_impl.ml})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target recent_impl.odoc) @@ -625,7 +627,9 @@ (action (run odoc compile -o %{target} %{dep:recent_impl.cmt})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target recent_impl.odocl) @@ -633,7 +637,9 @@ (action (run odoc link -o %{target} %{dep:recent_impl.odoc})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (target section.cmti) @@ -11701,7 +11707,12 @@ (subdir html (rule - (targets Oxcaml.html.gen) + (targets + Oxcaml.html.gen + Oxcaml-module-type-S.html.gen + Oxcaml-M1.html.gen + Oxcaml-M2.html.gen + Oxcaml-M3.html.gen) (package odoc) (action (run @@ -11720,6 +11731,30 @@ (package odoc) (action (diff Oxcaml.html Oxcaml.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-module-type-S.html Oxcaml-module-type-S.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M1.html Oxcaml-M1.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M2.html Oxcaml-M2.html.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M3.html Oxcaml-M3.html.gen)) (enabled_if %{ocaml-config:ox}))) (subdir @@ -11742,7 +11777,7 @@ (subdir latex (rule - (targets Oxcaml.tex.gen) + (targets Oxcaml.tex.gen Oxcaml.M1.tex.gen) (package odoc) (action (run odoc latex-generate -o . --extra-suffix gen %{dep:../oxcaml.odocl})) @@ -11752,6 +11787,12 @@ (package odoc) (action (diff Oxcaml.tex Oxcaml.tex.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.M1.tex Oxcaml.M1.tex.gen)) (enabled_if %{ocaml-config:ox}))) (subdir @@ -11774,7 +11815,7 @@ (subdir man (rule - (targets Oxcaml.3o.gen) + (targets Oxcaml.3o.gen Oxcaml.M1.3o.gen Oxcaml.M2.3o.gen Oxcaml.M3.3o.gen) (package odoc) (action (run odoc man-generate -o . --extra-suffix gen %{dep:../oxcaml.odocl})) @@ -11784,6 +11825,24 @@ (package odoc) (action (diff Oxcaml.3o Oxcaml.3o.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.M1.3o Oxcaml.M1.3o.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.M2.3o Oxcaml.M2.3o.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml.M3.3o Oxcaml.M3.3o.gen)) (enabled_if %{ocaml-config:ox}))) (subdir @@ -11806,7 +11865,12 @@ (subdir markdown (rule - (targets Oxcaml.md.gen) + (targets + Oxcaml.md.gen + Oxcaml-module-type-S.md.gen + Oxcaml-M1.md.gen + Oxcaml-M2.md.gen + Oxcaml-M3.md.gen) (package odoc) (action (run @@ -11823,6 +11887,30 @@ (package odoc) (action (diff Oxcaml.md Oxcaml.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-module-type-S.md Oxcaml-module-type-S.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M1.md Oxcaml-M1.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M2.md Oxcaml-M2.md.gen)) + (enabled_if %{ocaml-config:ox})) + (rule + (alias runtest) + (package odoc) + (action + (diff Oxcaml-M3.md Oxcaml-M3.md.gen)) (enabled_if %{ocaml-config:ox}))) (subdir @@ -12195,49 +12283,63 @@ . %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.html Recent_impl.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo.html Recent_impl-Foo.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-A.html Recent_impl-Foo-A.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-B.html Recent_impl-Foo-B.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-B.html Recent_impl-B.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S.html Recent_impl-module-type-S.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12246,7 +12348,9 @@ Recent_impl-module-type-S-F.html Recent_impl-module-type-S-F.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12255,7 +12359,9 @@ Recent_impl-module-type-S-F-argument-1-_.html Recent_impl-module-type-S-F-argument-1-_.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12264,7 +12370,9 @@ Recent_impl-module-type-S-X.html Recent_impl-module-type-S-X.html.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir html @@ -12276,14 +12384,18 @@ recent_impl.targets.gen (run odoc html-targets -o . %{dep:../recent_impl.odocl} --flat))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir latex @@ -12300,21 +12412,27 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.tex Recent_impl.tex.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.B.tex Recent_impl.B.tex.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir latex @@ -12326,14 +12444,18 @@ recent_impl.targets.gen (run odoc latex-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir man @@ -12355,42 +12477,54 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.3o Recent_impl.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.3o Recent_impl.Foo.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.A.3o Recent_impl.Foo.A.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.Foo.B.3o Recent_impl.Foo.B.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.B.3o Recent_impl.B.3o.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir man @@ -12402,14 +12536,18 @@ recent_impl.targets.gen (run odoc man-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir markdown @@ -12435,56 +12573,72 @@ gen %{dep:../recent_impl.odocl})) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl.md Recent_impl.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo.md Recent_impl-Foo.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-A.md Recent_impl-Foo-A.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-Foo-B.md Recent_impl-Foo-B.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-B.md Recent_impl-B.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S.md Recent_impl-module-type-S.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S-F.md Recent_impl-module-type-S-F.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) @@ -12493,14 +12647,18 @@ Recent_impl-module-type-S-F-argument-1-_.md Recent_impl-module-type-S-F-argument-1-_.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff Recent_impl-module-type-S-X.md Recent_impl-module-type-S-X.md.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir markdown @@ -12512,14 +12670,18 @@ recent_impl.targets.gen (run odoc markdown-targets -o . %{dep:../recent_impl.odocl}))) (enabled_if - (>= %{ocaml_version} 4.09))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox})))) (rule (alias runtest) (package odoc) (action (diff recent_impl.targets recent_impl.targets.gen)) (enabled_if - (>= %{ocaml_version} 4.09)))) + (and + (>= %{ocaml_version} 4.09) + (not %{ocaml-config:ox}))))) (subdir html diff --git a/test/generators/man/Oxcaml.3o b/test/generators/man/Oxcaml.3o index a3daa8e343..29a47e391d 100644 --- a/test/generators/man/Oxcaml.3o +++ b/test/generators/man/Oxcaml.3o @@ -17,4 +17,468 @@ Oxcaml .ti +2 Polymorphic arguments require parentheses .nf +.sp +.in 3 +\fB1 Layouts\fR +.in +.sp +\f[CB]type\fR t_any : any +.fi +.br +.ti +2 +Layout any\. +.nf +.sp +\f[CB]type\fR t_value_or_null : value_or_null +.fi +.br +.ti +2 +Layout value_or_null\. +.nf +.sp +\f[CB]type\fR t_float64 : float64 +.fi +.br +.ti +2 +Layout float64\. +.nf +.sp +\f[CB]type\fR t_float32 : float32 +.fi +.br +.ti +2 +Layout float32\. +.nf +.sp +\f[CB]type\fR t_word : word +.fi +.br +.ti +2 +Layout word\. +.nf +.sp +\f[CB]type\fR t_bits64 : bits64 +.fi +.br +.ti +2 +Layout bits64\. +.nf +.sp +\f[CB]type\fR t_bits32 : bits32 +.fi +.br +.ti +2 +Layout bits32\. +.nf +.sp +\f[CB]type\fR t_vec128 : vec128 +.fi +.br +.ti +2 +Layout vec128\. +.nf +.sp +\f[CB]type\fR t_void : void +.fi +.br +.ti +2 +Layout void\. +.nf +.sp +.in 3 +\fB2 Kind abbreviations\fR +.in +.sp +\f[CB]type\fR t_value +.fi +.br +.ti +2 +value is the default kind, so the annotation is not rendered\. +.nf +.sp +\f[CB]type\fR t_immediate : immediate +.fi +.br +.ti +2 +Kind abbreviation immediate\. +.nf +.sp +\f[CB]type\fR t_immediate64 : immediate64 +.fi +.br +.ti +2 +Kind abbreviation immediate64\. +.nf +.sp +\f[CB]type\fR t_immutable_data : immutable_data +.fi +.br +.ti +2 +Kind abbreviation immutable_data\. +.nf +.sp +\f[CB]type\fR t_sync_data : sync_data +.fi +.br +.ti +2 +Kind abbreviation sync_data\. +.nf +.sp +\f[CB]type\fR t_mutable_data : mutable_data +.fi +.br +.ti +2 +Kind abbreviation mutable_data\. +.nf +.sp +.in 3 +\fB3 Kind annotations with modalities\fR +.in +.sp +\f[CB]type\fR t_portable : value \f[CB]mod\fR portable +.fi +.br +.ti +2 +Kind annotation with a modality\. +.nf +.sp +\f[CB]type\fR t_contended : value \f[CB]mod\fR contended +.fi +.br +.ti +2 +Kind annotation with a different modality\. +.nf +.sp +\f[CB]type\fR t_multi_mod : value \f[CB]mod\fR portable contended +.fi +.br +.ti +2 +Kind annotation with multiple modalities\. +.nf +.sp +\f[CB]type\fR t_everything : float64 \f[CB]mod\fR everything +.fi +.br +.ti +2 +The everything bounds abbreviation\. +.nf +.sp +.in 3 +\fB4 Kind annotations on parameterized types\fR +.in +.sp +\f[CB]type\fR ('a : immediate) imm_param +.fi +.br +.ti +2 +A type parameter with a kind constraint\. +.nf +.sp +\f[CB]type\fR ('a : float64) float_param +.fi +.br +.ti +2 +A type parameter with a different kind constraint\. +.nf +.sp +\f[CB]type\fR (('a : immediate), ('b : float64)) multi_kind +.fi +.br +.ti +2 +Multiple kind-constrained parameters\. +.nf +.sp +.in 3 +\fB5 Kind annotations with with constraints\fR +.in +.sp +\f[CB]type\fR 'a t_with : immediate \f[CB]with\fR \f[CB]'a\fR +.fi +.br +.ti +2 +Kind annotation with a with constraint\. +.nf +.sp +.in 3 +\fB6 Kind annotations on type aliases\fR +.in +.sp +\f[CB]type\fR t_alias : immediate = int +.fi +.br +.ti +2 +Has both a kind annotation and a manifest\. +.nf +.sp +.in 3 +\fB7 Kind-constrained polymorphism in values\fR +.in +.sp +\f[CB]val\fR poly_immediate : ('a : immediate)\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +.fi +.br +.ti +2 +Kind constraint on a polymorphic type variable\. +.nf +.sp +\f[CB]val\fR poly_float64 : ('a : float64)\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR +.fi +.br +.ti +2 +Kind constraint on a polymorphic type variable with a different kind\. +.nf +.sp +.in 3 +\fB8 Modalities\fR +.in +.sp +\f[CB]type\fR opaque +.sp +\f[CB]type\fR modalities_all = { +.br +.ti +2 +f_global : opaque @@ global; +.br +.ti +4 +(* Locality modality\. *) +.br +.ti +2 +f_local : opaque; +.br +.ti +4 +(* Locality modality (identity, not rendered)\. *) +.br +.ti +2 +f_unique : opaque; +.br +.ti +4 +(* Uniqueness modality\. *) +.br +.ti +2 +f_aliased : opaque @@ aliased; +.br +.ti +4 +(* Uniqueness modality (identity, not rendered)\. *) +.br +.ti +2 +f_many : opaque @@ many; +.br +.ti +4 +(* Linearity modality\. *) +.br +.ti +2 +f_once : opaque; +.br +.ti +4 +(* Linearity modality (identity, not rendered)\. *) +.br +.ti +2 +f_portable : opaque @@ portable; +.br +.ti +4 +(* Portability modality\. *) +.br +.ti +2 +f_nonportable : opaque; +.br +.ti +4 +(* Portability modality (identity, not rendered)\. *) +.br +.ti +2 +f_uncontended : opaque; +.br +.ti +4 +(* Contention modality (identity, not rendered)\. *) +.br +.ti +2 +f_contended : opaque @@ contended; +.br +.ti +4 +(* Contention modality\. *) +.br +.ti +2 +f_unyielding : opaque @@ unyielding; +.br +.ti +4 +(* Yield modality\. *) +.br +.ti +2 +f_yielding : opaque; +.br +.ti +4 +(* Yield modality (identity, not rendered)\. *) +.br +.ti +2 +f_forkable : opaque @@ forkable; +.br +.ti +4 +(* Fork modality\. *) +.br +.ti +2 +f_unforkable : opaque; +.br +.ti +4 +(* Fork modality (identity, not rendered)\. *) +.br +.ti +2 +f_stateless : opaque @@ stateless; +.br +.ti +4 +(* Statefulness modality\. *) +.br +.ti +2 +f_stateful : opaque; +.br +.ti +4 +(* Statefulness modality (identity, not rendered)\. *) +.br +.ti +2 +f_immutable : opaque @@ immutable; +.br +.ti +4 +(* Visibility modality\. *) +.br +.ti +2 +f_read_write : opaque; +.br +.ti +4 +(* Visibility modality (identity, not rendered)\. *) +.br +.ti +2 +f_no_modality : opaque; +.br +.ti +4 +(* No modality, for reference\. *) +.br +} +.sp +.in 3 +\fB9 Multiple modalities on a field\fR +.in +.sp +\f[CB]type\fR modalities_multi = { +.br +.ti +2 +a : opaque @@ global portable; +.br +.ti +4 +(* Field with global portable modalities\. *) +.br +} +.sp +.in 3 +\fB10 Modalities on tuple and function fields\fR +.in +.sp +\f[CB]type\fR modalities_tuple = { +.br +.ti +2 +f : int * string @@ portable; +.br +.ti +4 +(* Tuple field with modality\. *) +.br +} +.sp +\f[CB]type\fR modalities_fn = { +.br +.ti +2 +g : int \f[CB]\->\fR int @@ portable; +.br +.ti +4 +(* Function field with modality\. *) +.br +} +.sp +.in 3 +\fB11 Modalities on constructor arguments\fR +.in +.sp +\f[CB]type\fR modalities_cstr = +.br +.ti +2 +| \f[CB]A\fR \f[CB]of\fR string @@ global +.br +.ti +4 +(* Constructor argument with global modality\. *) +.br +.ti +2 +| \f[CB]B\fR \f[CB]of\fR int \f[CB]\->\fR int @@ portable +.br +.ti +4 +(* Function constructor argument with modality\. *) +.br +.ti +2 +| \f[CB]C\fR \f[CB]of\fR int * string @@ portable +.br +.ti +4 +(* Tuple constructor argument with modality\. *) +.br +.ti +2 +| \f[CB]D\fR \f[CB]of\fR int @@ portable * string @@ global +.br +.ti +4 +(* Per-element modalities in a constructor tuple\. *) +.br +.ti +2 +| \f[CB]E\fR +.br +.ti +4 +(* Constant constructor\. *) +.br +.sp +.in 3 +\fB12 Modalities on values\fR +.in +.sp +\f[CB]val\fR portable_fn : int \f[CB]\->\fR int @@ portable +.fi +.br +.ti +2 +Value with portable modality\. +.nf +.sp +.in 3 +\fB13 Modalities on module declarations\fR +.in +.sp +\f[CB]module\fR \f[CB]type\fR S = \f[CB]sig\fR +.br +.ti +2 +\f[CB]val\fR x : int +.sp +.ti +2 +\f[CB]val\fR f : string \f[CB]\->\fR bool +.sp +.ti +2 +\f[CB]type\fR s = { +.br +.ti +4 +a : int; +.br +.ti +2 +} +.br +\f[CB]end\fR +.sp +\f[CB]module\fR M1 : S +.fi +.br +.ti +2 +Module without modality\. +.nf +.sp +\f[CB]module\fR M2 : \f[CB]sig\fR \.\.\. \f[CB]end\fR +.fi +.br +.ti +2 +Module with portable modality\. The modality is applied to all value members of M2\. +.nf +.sp +\f[CB]module\fR M3 : \f[CB]sig\fR \.\.\. \f[CB]end\fR +.fi +.br +.ti +2 +contended modality applied to all definitions in the module\. +.nf diff --git a/test/generators/man/Oxcaml.M1.3o b/test/generators/man/Oxcaml.M1.3o new file mode 100644 index 0000000000..c4b450a8d2 --- /dev/null +++ b/test/generators/man/Oxcaml.M1.3o @@ -0,0 +1,26 @@ + +.TH M1 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.M1 +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.M1\fR +.in +.sp +.fi +Module without modality\. +.nf +.SH Documentation +.sp +.nf +\f[CB]val\fR x : int +.sp +\f[CB]val\fR f : string \f[CB]\->\fR bool +.sp +\f[CB]type\fR s = { +.br +.ti +2 +a : int; +.br +} diff --git a/test/generators/man/Oxcaml.M2.3o b/test/generators/man/Oxcaml.M2.3o new file mode 100644 index 0000000000..5176fc0c7d --- /dev/null +++ b/test/generators/man/Oxcaml.M2.3o @@ -0,0 +1,26 @@ + +.TH M2 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.M2 +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.M2\fR +.in +.sp +.fi +Module with portable modality\. The modality is applied to all value members of M2\. +.nf +.SH Documentation +.sp +.nf +\f[CB]val\fR x : int @@ portable +.sp +\f[CB]val\fR f : string \f[CB]\->\fR bool @@ portable +.sp +\f[CB]type\fR s : immutable_data = { +.br +.ti +2 +a : int; +.br +} diff --git a/test/generators/man/Oxcaml.M3.3o b/test/generators/man/Oxcaml.M3.3o new file mode 100644 index 0000000000..2dc931abd4 --- /dev/null +++ b/test/generators/man/Oxcaml.M3.3o @@ -0,0 +1,19 @@ + +.TH M3 3 "" "Odoc" "OCaml Library" +.SH Name +Oxcaml\.M3 +.SH Synopsis +.sp +.in 2 +\fBModule Oxcaml\.M3\fR +.in +.sp +.fi +contended modality applied to all definitions in the module\. +.nf +.SH Documentation +.sp +.nf +\f[CB]val\fR f : string \f[CB]\->\fR bool @@ contended +.sp +\f[CB]type\fR s diff --git a/test/generators/man/oxcaml.targets b/test/generators/man/oxcaml.targets index 6d31d9eb49..3d3984495e 100644 --- a/test/generators/man/oxcaml.targets +++ b/test/generators/man/oxcaml.targets @@ -1 +1,4 @@ Oxcaml.3o +Oxcaml.M1.3o +Oxcaml.M2.3o +Oxcaml.M3.3o diff --git a/test/generators/markdown/Oxcaml-M1.md b/test/generators/markdown/Oxcaml-M1.md new file mode 100644 index 0000000000..a29dd51776 --- /dev/null +++ b/test/generators/markdown/Oxcaml-M1.md @@ -0,0 +1,16 @@ + +# Module `Oxcaml.M1` + +Module without modality. + +```ocaml +val x : int +``` +```ocaml +val f : string -> bool +``` +```ocaml +type s = { + a : int; +} +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-M2.md b/test/generators/markdown/Oxcaml-M2.md new file mode 100644 index 0000000000..097891b7da --- /dev/null +++ b/test/generators/markdown/Oxcaml-M2.md @@ -0,0 +1,16 @@ + +# Module `Oxcaml.M2` + +Module with `portable` modality. The modality is applied to all value members of `M2`. + +```ocaml +val x : int @@ portable +``` +```ocaml +val f : string -> bool @@ portable +``` +```ocaml +type s : immutable_data = { + a : int; +} +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-M3.md b/test/generators/markdown/Oxcaml-M3.md new file mode 100644 index 0000000000..6ee348501c --- /dev/null +++ b/test/generators/markdown/Oxcaml-M3.md @@ -0,0 +1,11 @@ + +# Module `Oxcaml.M3` + +`contended` modality applied to all definitions in the module. + +```ocaml +val f : string -> bool @@ contended +``` +```ocaml +type s +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml-module-type-S.md b/test/generators/markdown/Oxcaml-module-type-S.md new file mode 100644 index 0000000000..7fed2a2c16 --- /dev/null +++ b/test/generators/markdown/Oxcaml-module-type-S.md @@ -0,0 +1,14 @@ + +# Module type `Oxcaml.S` + +```ocaml +val x : int +``` +```ocaml +val f : string -> bool +``` +```ocaml +type s = { + a : int; +} +``` \ No newline at end of file diff --git a/test/generators/markdown/Oxcaml.md b/test/generators/markdown/Oxcaml.md index 76d86c56a3..236e6835d1 100644 --- a/test/generators/markdown/Oxcaml.md +++ b/test/generators/markdown/Oxcaml.md @@ -5,3 +5,244 @@ val f : int -> ('a. 'a -> 'a) -> unit ``` Polymorphic arguments require parentheses + + +## Layouts + +```ocaml +type t_any : any +``` +Layout `any`. + +```ocaml +type t_value_or_null : value_or_null +``` +Layout `value_or_null`. + +```ocaml +type t_float64 : float64 +``` +Layout `float64`. + +```ocaml +type t_float32 : float32 +``` +Layout `float32`. + +```ocaml +type t_word : word +``` +Layout `word`. + +```ocaml +type t_bits64 : bits64 +``` +Layout `bits64`. + +```ocaml +type t_bits32 : bits32 +``` +Layout `bits32`. + +```ocaml +type t_vec128 : vec128 +``` +Layout `vec128`. + +```ocaml +type t_void : void +``` +Layout `void`. + + +## Kind abbreviations + +```ocaml +type t_value +``` +`value` is the default kind, so the annotation is not rendered. + +```ocaml +type t_immediate : immediate +``` +Kind abbreviation `immediate`. + +```ocaml +type t_immediate64 : immediate64 +``` +Kind abbreviation `immediate64`. + +```ocaml +type t_immutable_data : immutable_data +``` +Kind abbreviation `immutable_data`. + +```ocaml +type t_sync_data : sync_data +``` +Kind abbreviation `sync_data`. + +```ocaml +type t_mutable_data : mutable_data +``` +Kind abbreviation `mutable_data`. + + +## Kind annotations with modalities + +```ocaml +type t_portable : value mod portable +``` +Kind annotation with a modality. + +```ocaml +type t_contended : value mod contended +``` +Kind annotation with a different modality. + +```ocaml +type t_multi_mod : value mod portable contended +``` +Kind annotation with multiple modalities. + +```ocaml +type t_everything : float64 mod everything +``` +The `everything` bounds abbreviation. + + +## Kind annotations on parameterized types + +```ocaml +type ('a : immediate) imm_param +``` +A type parameter with a kind constraint. + +```ocaml +type ('a : float64) float_param +``` +A type parameter with a different kind constraint. + +```ocaml +type (('a : immediate), ('b : float64)) multi_kind +``` +Multiple kind-constrained parameters. + + +## Kind annotations with `with` constraints + +```ocaml +type 'a t_with : immediate with 'a +``` +Kind annotation with a `with` constraint. + + +## Kind annotations on type aliases + +```ocaml +type t_alias : immediate = int +``` +Has both a kind annotation and a manifest. + + +## Kind-constrained polymorphism in values + +```ocaml +val poly_immediate : ('a : immediate). 'a -> 'a +``` +Kind constraint on a polymorphic type variable. + +```ocaml +val poly_float64 : ('a : float64). 'a -> 'a +``` +Kind constraint on a polymorphic type variable with a different kind. + + +## Modalities + +```ocaml +type opaque +``` +```ocaml +type modalities_all = { + f_global : opaque @@ global; (* Locality modality. *) + f_local : opaque; (* Locality modality (identity, not rendered). *) + f_unique : opaque; (* Uniqueness modality. *) + f_aliased : opaque @@ aliased; (* Uniqueness modality (identity, not rendered). *) + f_many : opaque @@ many; (* Linearity modality. *) + f_once : opaque; (* Linearity modality (identity, not rendered). *) + f_portable : opaque @@ portable; (* Portability modality. *) + f_nonportable : opaque; (* Portability modality (identity, not rendered). *) + f_uncontended : opaque; (* Contention modality (identity, not rendered). *) + f_contended : opaque @@ contended; (* Contention modality. *) + f_unyielding : opaque @@ unyielding; (* Yield modality. *) + f_yielding : opaque; (* Yield modality (identity, not rendered). *) + f_forkable : opaque @@ forkable; (* Fork modality. *) + f_unforkable : opaque; (* Fork modality (identity, not rendered). *) + f_stateless : opaque @@ stateless; (* Statefulness modality. *) + f_stateful : opaque; (* Statefulness modality (identity, not rendered). *) + f_immutable : opaque @@ immutable; (* Visibility modality. *) + f_read_write : opaque; (* Visibility modality (identity, not rendered). *) + f_no_modality : opaque; (* No modality, for reference. *) +} +``` + +## Multiple modalities on a field + +```ocaml +type modalities_multi = { + a : opaque @@ global portable; (* Field with global portable modalities. *) +} +``` + +## Modalities on tuple and function fields + +```ocaml +type modalities_tuple = { + f : int * string @@ portable; (* Tuple field with modality. *) +} +``` +```ocaml +type modalities_fn = { + g : int -> int @@ portable; (* Function field with modality. *) +} +``` + +## Modalities on constructor arguments + +```ocaml +type modalities_cstr = + | A of string @@ global (* Constructor argument with global modality. *) + | B of int -> int @@ portable (* Function constructor argument with modality. *) + | C of int * string @@ portable (* Tuple constructor argument with modality. *) + | D of int @@ portable * string @@ global (* Per-element modalities in a constructor tuple. *) + | E (* Constant constructor. *) +``` + +## Modalities on values + +```ocaml +val portable_fn : int -> int @@ portable +``` +Value with `portable` modality. + + +## Modalities on module declarations + +```ocaml +module type S = sig ... end +``` +```ocaml +module M1 : S +``` +Module without modality. + +```ocaml +module M2 : sig ... end +``` +Module with `portable` modality. The modality is applied to all value members of `M2`. + +```ocaml +module M3 : sig ... end +``` +`contended` modality applied to all definitions in the module. diff --git a/test/generators/markdown/oxcaml.targets b/test/generators/markdown/oxcaml.targets index 92e990db5e..03016b8b2f 100644 --- a/test/generators/markdown/oxcaml.targets +++ b/test/generators/markdown/oxcaml.targets @@ -1 +1,5 @@ Oxcaml.md +Oxcaml-module-type-S.md +Oxcaml-M1.md +Oxcaml-M2.md +Oxcaml-M3.md diff --git a/test/xref2/canonical_nested.t/run.t b/test/xref2/canonical_nested.t/run.t index a4435450c3..ff24d6b43a 100644 --- a/test/xref2/canonical_nested.t/run.t +++ b/test/xref2/canonical_nested.t/run.t @@ -295,7 +295,8 @@ unresolved in the paths though: "params": [], "private_": "false", "manifest": "None", - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } diff --git a/test/xref2/classes.t/run.t b/test/xref2/classes.t/run.t index 0be14ce1a9..c241e1bb6e 100644 --- a/test/xref2/classes.t/run.t +++ b/test/xref2/classes.t/run.t @@ -51,7 +51,8 @@ resolve correctly. All of the 'Class' json objects should contain [] ] }, - "value": "Abstract" + "value": "Abstract", + "modalities": [] } $ odoc_print e.odoc -r g | jq . { @@ -91,7 +92,8 @@ resolve correctly. All of the 'Class' json objects should contain [] ] }, - "value": "Abstract" + "value": "Abstract", + "modalities": [] } $ odoc_print e.odoc -r d | jq '.expr.Signature.items[1].Method.type_' { diff --git a/test/xref2/deep_substitution.t/run.t b/test/xref2/deep_substitution.t/run.t index 909a11fdcf..da3b8c6ec7 100644 --- a/test/xref2/deep_substitution.t/run.t +++ b/test/xref2/deep_substitution.t/run.t @@ -57,7 +57,8 @@ its RHS correctly replaced with an `int` ] } }, - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } diff --git a/test/xref2/github_issue_1001.t/run.t b/test/xref2/github_issue_1001.t/run.t index 4d13ffee84..b29f054c0c 100644 --- a/test/xref2/github_issue_1001.t/run.t +++ b/test/xref2/github_issue_1001.t/run.t @@ -24,7 +24,8 @@ We should have an 'Optional' argument (as opposed to a 'RawOptional' one) } ] }, - "value": "Abstract" + "value": "Abstract", + "modalities": [] } Harder case contains a "RawOptional": @@ -58,5 +59,6 @@ Harder case contains a "RawOptional": } ] }, - "value": "Abstract" + "value": "Abstract", + "modalities": [] } diff --git a/test/xref2/hidden_modules.t/run.t b/test/xref2/hidden_modules.t/run.t index 1febde41ea..eba58985b4 100644 --- a/test/xref2/hidden_modules.t/run.t +++ b/test/xref2/hidden_modules.t/run.t @@ -109,7 +109,8 @@ There should be an expansion on `NotHidden` "params": [], "private_": "false", "manifest": "None", - "constraints": [] + "constraints": [], + "kind": "Default" }, "representation": "None" } @@ -154,7 +155,8 @@ There should be an expansion on `NotHidden` [] ] }, - "value": "Abstract" + "value": "Abstract", + "modalities": [] } diff --git a/test/xref2/resolve/test.md b/test/xref2/resolve/test.md index 8f2288adf7..67c97f503c 100644 --- a/test/xref2/resolve/test.md +++ b/test/xref2/resolve/test.md @@ -106,7 +106,8 @@ Simplest possible resolution: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; - manifest = None; constraints = []}; + manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None}); Odoc_model.Lang.Signature.Type (Odoc_model.Lang.Signature.Ordinary, {Odoc_model.Lang.TypeDecl.id = @@ -144,7 +145,7 @@ Simplest possible resolution: t); ihash = 1016576344; ikey = "t_t.r_Root.p_None"}), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}; @@ -282,7 +283,8 @@ Basic resolution 2, environment lookup: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -325,7 +327,7 @@ Basic resolution 2, environment lookup: ihash = 716453475; ikey = "m_M.r_Root.p_None"}, t)), [])); - constraints = []}; + constraints = []; kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}; @@ -437,7 +439,8 @@ Basic resolution 3, module type: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -489,7 +492,8 @@ Basic resolution 3, module type: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -531,18 +535,12 @@ Basic resolution 3, module type: manifest = Some (Odoc_model.Lang.TypeExpr.Constr - (`Resolved - (`Type - (`Identifier - {Odoc_model__Paths_types.iv = ...; ihash = ...; - ikey = ...}, - ...)), - ...)); - constraints = ...}; - representation = ...}); - ...]; - compiled = ...; removed = ...; doc = ...}; - expansion = ...; linked = ...; source_loc = ...; canonical = ...} + (`Resolved (`Type (`Identifier ...)), ...)); + constraints = ...; kind = ...}; + representation = ...}); + ...]; + compiled = ...; removed = ...; doc = ...}; + expansion = ...; linked = ...; source_loc = ...; canonical = ...} ``` This example is very similar but there is one more level of nesting of the modules: @@ -665,7 +663,8 @@ Basic resolution 4, module type: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -736,7 +735,7 @@ Basic resolution 4, module type: `Root (Some {Odoc_model__Paths_types.iv - = `Page (None, ...); + = `Page (...); ihash = ...; ikey = ...}, ...); @@ -917,7 +916,8 @@ and then we can look up the type `t`. equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -989,7 +989,9 @@ and then we can look up the type `t`. {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = + Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -998,11 +1000,7 @@ and then we can look up the type `t`. p_path = `Resolved (`Identifier - {Odoc_model__Paths_types.iv = - `ModuleType - ({Odoc_model__Paths_types.iv = ...; - ihash = ...; ikey = ...}, - ...); + {Odoc_model__Paths_types.iv = `ModuleType (...); ihash = ...; ikey = ...})}); canonical = ...; hidden = ...}); ...]; @@ -1121,7 +1119,8 @@ and then we can look up the type `t`. equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -1675,7 +1674,8 @@ Resolve a module alias: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -1766,10 +1766,10 @@ Resolve a module alias: ihash = 814134997; ikey = "m_B.r_Ro"... (* string length 17; truncated *)}, - false)), + ...)), ...)), ...)); - constraints = ...}; + constraints = ...; kind = ...}; representation = ...}); ...]; compiled = ...; removed = ...; doc = ...}; @@ -1845,7 +1845,8 @@ Resolve a module alias: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}}); @@ -1926,7 +1927,7 @@ Resolve a module alias: Root); ihash = 818126955; ikey = - "r_Root.p_No"... (* string length 13; truncated *)}, + "r_Root.p_N"... (* string length 13; truncated *)}, B); ihash = 814134997; ikey = "m_B.r_Ro"... (* string length 17; truncated *)}, @@ -2014,7 +2015,8 @@ Resolve a functor: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2096,7 +2098,8 @@ Resolve a functor: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -2116,16 +2119,14 @@ Resolve a functor: Root); ihash = 818126955; ikey = - "r_Root.p_"... (* string length 13; truncated *)}, + "r_Root.p"... (* string length 13; truncated *)}, S); ihash = 527535255; ikey = "mt_S.r_R"... (* string length 18; truncated *)})}}, Odoc_model.Lang.ModuleType.Functor (Odoc_model.Lang.FunctorParameter.Named - {Odoc_model.Lang.FunctorParameter.id = - {Odoc_model__Paths_types.iv = ...; ihash = ...; ikey = ...}; - expr = ...}, + {Odoc_model.Lang.FunctorParameter.id = ...; expr = ...}, ...))); canonical = ...; hidden = ...}); ...]; @@ -2228,7 +2229,8 @@ Resolve a functor: canonical = None; equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; - private_ = false; manifest = None; constraints = []}; + private_ = false; manifest = None; constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = {Odoc_model__.Comment.elements = []; warnings_tag = None}})}; @@ -2311,7 +2313,8 @@ Resolve a functor: equation = {Odoc_model.Lang.TypeDecl.Equation.params = []; private_ = false; manifest = None; - constraints = []}; + constraints = []; + kind = Odoc_model.Lang.KindAnnotation.Default}; representation = None})]; compiled = true; removed = []; doc = @@ -2331,21 +2334,17 @@ Resolve a functor: Root); ihash = 818126955; ikey = - "r_Root.p_"... (* string length 13; truncated *)}, + "r_Root.p"... (* string length 13; truncated *)}, S); ihash = 527535255; ikey = "mt_S.r_R"... (* string length 18; truncated *)})}}, Odoc_model.Lang.ModuleType.Path {Odoc_model.Lang.ModuleType.p_expansion = - Some - (Odoc_model.Lang.ModuleType.Signature - {Odoc_model.Lang.Signature.items = [...]; compiled = ...; - removed = ...; doc = ...}); - p_path = ...}))}; - ...]; - compiled = ...; removed = ...; doc = ...}; - expansion = ...; linked = ...; source_loc = ...; canonical = ...} + Some (Odoc_model.Lang.ModuleType.Signature ...); p_path = ...}))}; + ...]; + compiled = ...; removed = ...; doc = ...}; + expansion = ...; linked = ...; source_loc = ...; canonical = ...} ``` ```ocaml skip