diff --git a/CHANGES.md b/CHANGES.md index f7d64d2f91..fb32f45690 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) +- OCaml 5.5.0 support (@panglesd, @xvw, #1406) ### Fixed - Fix compile-time crashing bugs #930 and #1385 (@jonludlam, #1400) diff --git a/odoc-parser.opam b/odoc-parser.opam index 92935df19a..8db379515a 100644 --- a/odoc-parser.opam +++ b/odoc-parser.opam @@ -14,7 +14,7 @@ dev-repo: "git+https://github.com/ocaml/odoc.git" doc: "https://ocaml.github.io/odoc/odoc_parser" depends: [ "dune" {>= "3.21"} - "ocaml" {>= "4.08.0" & < "5.5"} + "ocaml" {>= "4.08.0"} "astring" "camlp-streams" "ppx_expect" {with-test} diff --git a/odoc.opam b/odoc.opam index 62478fe47c..4589994626 100644 --- a/odoc.opam +++ b/odoc.opam @@ -45,7 +45,7 @@ depends: [ "cppo" {build & >= "1.1.0"} "dune" {>= "3.21.0"} "fpath" {>= "0.7.3"} - "ocaml" {>= "4.08.0" & < "5.5"} + "ocaml" {>= "4.08.0" & < "5.6"} "tyxml" {>= "4.4.0"} "fmt" "crunch" {>= "1.4.1"} diff --git a/src/document/generator.ml b/src/document/generator.ml index de14ee9a5a..0e481f582c 100644 --- a/src/document/generator.ml +++ b/src/document/generator.ml @@ -485,19 +485,36 @@ module Make (Syntax : SYNTAX) = struct | Splice t -> O.span (O.txt "$" ++ type_expr ~needs_parentheses:true t) | Package pkg -> enclose ~l:"(" ~r:")" - (O.keyword "module" ++ O.txt " " - ++ Link.from_path (pkg.path :> Paths.Path.t) - ++ - match pkg.substitutions with - | [] -> O.noop - | fst :: lst -> - O.sp - ++ O.box_hv (O.keyword "with" ++ O.txt " " ++ package_subst fst) - ++ O.list lst ~f:(fun s -> - O.cut - ++ (O.box_hv - @@ O.txt " " ++ O.keyword "and" ++ O.txt " " - ++ package_subst s))) + (O.keyword "module" ++ O.txt " " ++ package_path pkg) + | Arrow_functor (lbl, m_arg, dst) -> + let lbl = + match lbl with None -> O.noop | Some lbl -> label lbl ++ O.txt ":" + in + let name = + match m_arg.id.iv with + | `Parameter (_, name) -> ModuleName.to_string name + in + let dst = type_expr dst in + let pkg = + enclose ~l:"(" ~r:")" + @@ O.keyword "module" ++ O.txt " " ++ O.txt name ++ O.txt " : " + ++ package_path m_arg.package + in + lbl ++ pkg ++ O.sp ++ Syntax.Type.arrow ++ O.sp ++ dst + + and package_path pkg = + Link.from_path (pkg.path :> Paths.Path.t) + ++ + match pkg.substitutions with + | [] -> O.noop + | fst :: lst -> + O.sp + ++ O.box_hv (O.keyword "with" ++ O.txt " " ++ package_subst fst) + ++ O.list lst ~f:(fun s -> + O.cut + ++ (O.box_hv + @@ O.txt " " ++ O.keyword "and" ++ O.txt " " + ++ package_subst s)) and package_subst ((frag_typ, te) : Paths.Fragment.Type.t * Odoc_model.Lang.TypeExpr.t) : diff --git a/src/loader/cmi.ml b/src/loader/cmi.ml index db7bfd1ba3..06270d51a0 100644 --- a/src/loader/cmi.ml +++ b/src/loader/cmi.ml @@ -300,7 +300,13 @@ let mark_type ty = | Tpoly (ty, tyl) -> List.iter (fun t -> add_alias t) tyl; loop visited ty -#if OCAML_VERSION>=(5,4,0) +#if OCAML_VERSION>=(5,5,0) + | Tpackage p -> + List.iter (fun (_,x) -> loop visited x) p.pack_constraints + | Tfunctor (_lbl, _id, pkg, ret_type) -> + List.iter (fun (_,x) -> loop visited x) pkg.pack_constraints; + loop visited ret_type +#elif OCAML_VERSION>=(5,4,0) | Tpackage p -> List.iter (fun (_,x) -> loop visited x) p.pack_cstrs #elif OCAML_VERSION>=(4,13,0) @@ -428,6 +434,9 @@ let mark_type_kind = function #endif List.iter (fun ld -> mark_type ld.ld_type) lds | Type_open -> () +#if OCAML_VERSION >= (5,5,0) + | Type_external _ -> () +#endif let mark_type_declaration decl = let params = prepare_type_parameters decl.type_params decl.type_manifest in @@ -554,7 +563,10 @@ let rec read_type_expr env typ = remove_names tyl; Poly(vars, typ) | Tunivar _ -> Var (name_of_type typ) -#if OCAML_VERSION>=(5,4,0) +#if OCAML_VERSION>=(5,5,0) + | Tpackage {pack_path=p; pack_constraints } -> + let eqs = List.filter_map (fun (l,ty) -> Option.map (fun x -> x, ty) (Longident.unflatten l)) pack_constraints in +#elif OCAML_VERSION>=(5,4,0) | Tpackage {pack_path=p; pack_cstrs } -> let eqs = List.filter_map (fun (l,ty) -> Option.map (fun x -> x, ty) (Longident.unflatten l)) pack_cstrs in #elif OCAML_VERSION>=(4,13,0) @@ -563,22 +575,30 @@ let rec read_type_expr env typ = | Tpackage(p, frags, tyl) -> let eqs = List.combine frags tyl in #endif - let open TypeExpr.Package in - let path = Env.Path.read_module_type env.ident_env p in - let substitutions = - List.map - (fun (frag,typ) -> - let frag = Env.Fragment.read_type frag in - let typ = read_type_expr env typ in - (frag, typ)) - eqs - in - - Package {path; substitutions} + let package = read_package env eqs p in + Package package #if OCAML_VERSION<(4,13,0) | Tsubst typ -> read_type_expr env typ #else | Tsubst (typ,_) -> read_type_expr env typ +#endif +#if OCAML_VERSION >= (5,5,0) + | Tfunctor (lbl, id, pkg, ret_type) -> + let lbl = read_label lbl in + let parent = Identifier.fresh_module_arg_parent () in + let id = Ocaml_ident.of_unscoped id in + let e', id = + Env.add_module_arg parent id (ModuleName.hidden_of_ident id) + env.ident_env + in + let env = {env with ident_env = e'} in + let ret = read_type_expr env ret_type in + let eqs = + List.filter_map (fun (l,ty) -> Option.map (fun x -> x, ty) (Longident.unflatten l)) pkg.pack_constraints + in + let package = read_package env eqs pkg.pack_path in + Arrow_functor(lbl, {id ; package}, ret) + #endif | Tlink _ -> assert false #if defined OXCAML @@ -592,6 +612,20 @@ let rec read_type_expr env typ = | Some name -> Alias(typ, name) end +and read_package env eqs p = + let open TypeExpr in + let open TypeExpr.Package in + let path = Env.Path.read_module_type env.ident_env p in + let substitutions = + List.map + (fun (frag,typ) -> + let frag = Env.Fragment.read_type frag in + let typ = read_type_expr env typ in + (frag, typ)) + eqs + in + {path; substitutions} + and read_row env _px row = let open TypeExpr in let open TypeExpr.Polymorphic_variant in @@ -811,6 +845,9 @@ let read_type_kind env parent = in Some (Record lbls) | Type_open -> Some Extensible +#if OCAML_VERSION >= (5,5,0) + | Type_external _ -> None +#endif let read_injectivity var = #if OCAML_VERSION < (5, 1, 0) @@ -893,6 +930,10 @@ let read_type_declaration env parent id decl = List.exists (fun cd -> cd.cd_res <> None) tll | Type_open -> decl.type_manifest = None +#if OCAML_VERSION >= (5,5,0) + | Type_external _ -> + decl.type_manifest = None || decl.type_private = Private +#endif in let params = List.map2 (read_type_parameter abstr) decl.type_variance params diff --git a/src/loader/cmti.ml b/src/loader/cmti.ml index 5468d42af3..e74246692e 100644 --- a/src/loader/cmti.ml +++ b/src/loader/cmti.ml @@ -173,22 +173,15 @@ let rec read_core_type env container ctyp = #else | Ttyp_poly(vars, typ) -> Poly(vars, read_core_type env container typ) #endif -#if OCAML_VERSION >= (5,4,0) +#if OCAML_VERSION >= (5,5,0) + | Ttyp_package {tpt_path = pack_path; tpt_constraints=pack_fields; _} -> +#elif OCAML_VERSION >= (5,4,0) | Ttyp_package {tpt_path = pack_path; tpt_cstrs=pack_fields; _} -> #else | Ttyp_package {pack_path; pack_fields; _} -> #endif - let open TypeExpr.Package in - let path = Env.Path.read_module_type env.ident_env pack_path in - let substitutions = - List.map - (fun (frag, typ) -> - let frag = Env.Fragment.read_type frag.Location.txt in - let typ = read_core_type env container typ in - (frag, typ)) - pack_fields - in - Package {path; substitutions} + let pkg = read_package env container pack_path pack_fields in + Package pkg #if OCAML_VERSION >= (5,2,0) | Ttyp_open (_p,_l,t) -> (* TODO: adjust model *) @@ -199,8 +192,33 @@ let rec read_core_type env container ctyp = | Ttyp_splice typ -> Splice (read_core_type env container typ) | Ttyp_call_pos -> Constr(Env.Path.read_type env.ident_env Predef.path_lexing_position, []) | Ttyp_of_kind _ -> assert false +#elif OCAML_VERSION >= (5,5,0) + | Ttyp_functor (lbl, id, pkg, ret_type) -> + let lbl = read_label lbl in + let parent = Identifier.fresh_module_arg_parent () in + let e', id = + Env.add_module_arg parent id.txt (ModuleName.hidden_of_ident id.txt) + env.ident_env + in + let env = {env with ident_env = e'} in + let ret = read_core_type env container ret_type in + let package = read_package env container pkg.tpt_path pkg.tpt_constraints in + Arrow_functor(lbl, {id ; package}, ret) #endif +and read_package env container pack_path pack_fields = + let open TypeExpr.Package in + let path = Env.Path.read_module_type env.ident_env pack_path in + let substitutions = + List.map + (fun (frag, typ) -> + let frag = Env.Fragment.read_type frag.Location.txt in + let typ = read_core_type env container typ in + (frag, typ)) + pack_fields + in + {path; substitutions} + let read_value_description env parent vd = let open Signature in let id = Env.find_value_identifier env.ident_env vd.val_id in @@ -333,6 +351,9 @@ let read_type_kind env parent = Some (Record_unboxed_product lbls) #endif | Ttype_open -> Some Extensible +#if OCAML_VERSION >= (5,5,0) + | Ttype_external _ -> None +#endif let read_type_equation env container decl = let open TypeDecl.Equation in @@ -344,7 +365,11 @@ let read_type_equation env container decl = (fun (typ1, typ2, _) -> (read_core_type env container typ1, read_core_type env container typ2)) +#if OCAML_VERSION >= (5,5,0) + decl.typ_constraints +#else decl.typ_cstrs +#endif in {params; private_; manifest; constraints} @@ -661,7 +686,11 @@ and read_module_type env parent label_parent mty = let p = Env.Path.read_module env.ident_env p in TypeOf {t_desc = ModPath p; t_original_path = p; t_expansion = None} | Tmod_structure {str_items = [{str_desc = Tstr_include {incl_mod; _}; _}]; _} -> begin +#if OCAML_VERSION >= (5,5,0) + match Typedtree.path_of_module incl_mod with +#else match Typemod.path_of_module incl_mod with +#endif | Some p -> let p = Env.Path.read_module env.ident_env p in TypeOf {t_desc=StructInclude p; t_original_path = p; t_expansion = None} diff --git a/src/loader/ident_env.ml b/src/loader/ident_env.ml index 54788364af..f8671d735f 100644 --- a/src/loader/ident_env.ml +++ b/src/loader/ident_env.ml @@ -132,7 +132,11 @@ and extract_signature_type_items_extract vis ~hidden item rest = | Type_variant (cstrs, _) -> #endif List.map (fun c -> `Constructor (c.Types.cd_id, id, Some c.cd_loc)) cstrs - | Type_open -> [] in + | Type_open -> [] +#if OCAML_VERSION >= (5,5,0) + | Type_external _ -> [] +#endif + in `Type (id, hidden, None) :: constrs @ extract_signature_type_items vis rest | Sig_module(id, _, _, _, _), _ -> @@ -221,6 +225,9 @@ let rec extract_signature_tree_items : bool -> Typedtree.signature_item list -> | Ttype_record_unboxed_product _ -> [] #endif | Ttype_open -> [] +#if OCAML_VERSION >= (5,5,0) + | Ttype_external _ -> [] +#endif ) decls @ extract_signature_tree_items hide_item rest @@ -389,6 +396,9 @@ let rec extract_structure_tree_items : bool -> Typedtree.structure_item list -> | Ttype_record_unboxed_product _ -> [] #endif | Ttype_open -> [] +#if OCAML_VERSION >= (5,5,0) + | Ttype_external _ -> [] +#endif )) decls @ extract_structure_tree_items hide_item rest @@ -660,6 +670,13 @@ let add_parameter parent id name env = let parameters = Ident.add id oid env.parameters in { env with module_paths; modules; parameters } +let add_module_arg parent id name env = + let oid = Odoc_model.Paths.Identifier.Mk.(parameter (parent, name)) in + let path = `Identifier (oid, false) in + let module_paths = Ident.add id path env.module_paths in + let modules = Ident.add id oid env.modules in + { env with module_paths; modules }, oid + let find_module env id = Ident.find_same id env.module_paths diff --git a/src/loader/ident_env.mli b/src/loader/ident_env.mli index 531ceb6261..c7bd95e1d2 100644 --- a/src/loader/ident_env.mli +++ b/src/loader/ident_env.mli @@ -23,6 +23,13 @@ val empty : unit -> t val add_parameter : Paths.Identifier.Signature.t -> Ident.t -> Names.ModuleName.t -> t -> t +val add_module_arg : + Paths.Identifier.Signature.t -> + Ident.t -> + Names.ModuleName.t -> + t -> + t * Odoc_model.Paths.Identifier.FunctorParameter.t + val handle_signature_type_items : Paths.Identifier.Signature.t -> Compat.signature -> t -> t diff --git a/src/model/lang.ml b/src/model/lang.ml index e801ebbf2e..432eb88152 100644 --- a/src/model/lang.ml +++ b/src/model/lang.ml @@ -451,6 +451,10 @@ and TypeExpr : sig type t = { path : Path.ModuleType.t; substitutions : substitution list } end + module Module : sig + type t = { package : Package.t; id : Identifier.FunctorParameter.t } + end + type label = Label of string | RawOptional of string | Optional of string type t = @@ -468,6 +472,7 @@ and TypeExpr : sig | Quote of t | Splice of t | Package of TypeExpr.Package.t + | Arrow_functor of label option * Module.t * t end = TypeExpr diff --git a/src/model/paths.ml b/src/model/paths.ml index a1042b64cd..9d26fdad87 100644 --- a/src/model/paths.ml +++ b/src/model/paths.ml @@ -659,6 +659,16 @@ module Identifier = struct let name = Printf.sprintf "include%d_" !include_parent_counter in (Mk.module_ (parent, ModuleName.make_std name) :> Signature.t) + let module_arg_parent_counter = ref 0 + + (* Create a synthetic parent identifier for module arguments, which can't have + unique identifier, as they can be introduced multiple times with the same + name in a single type expression . *) + let fresh_module_arg_parent () : Signature.t = + incr module_arg_parent_counter; + let name = Printf.sprintf "module_arg_%d_" !module_arg_parent_counter in + (Mk.root (None, ModuleName.hidden_of_string name) :> Signature.t) + module Hashtbl = struct module Any = Hashtbl.Make (Any) module ContainerPage = Hashtbl.Make (ContainerPage) @@ -684,7 +694,7 @@ module Path = struct | `Identifier { iv = `Module (_, m); _ } when Names.ModuleName.is_hidden m -> true - | `Identifier _ -> false + | `Identifier id -> Identifier.is_hidden id | `Canonical (_, `Resolved _) -> false | `Canonical (x, _) -> (not weak_canonical_test) && inner (x : module_ :> any) @@ -727,7 +737,7 @@ module Path = struct let open Paths_types.Path in function | `Resolved r -> is_resolved_hidden ~weak_canonical_test:false r - | `Identifier (_, hidden) -> hidden + | `Identifier (id, hidden) -> hidden || Identifier.is_hidden id | `Substituted r -> is_path_hidden (r :> any) | `SubstitutedMT r -> is_path_hidden (r :> any) | `SubstitutedT r -> is_path_hidden (r :> any) diff --git a/src/model/paths.mli b/src/model/paths.mli index 1892f008ba..0f5c16aca3 100644 --- a/src/model/paths.mli +++ b/src/model/paths.mli @@ -364,6 +364,11 @@ module Identifier : sig type expression. Uses a lowercase module name (illegal in normal OCaml) to ensure no clashes with real identifiers. Each call returns a fresh identifier. *) + + val fresh_module_arg_parent : unit -> Signature.t + (** Create a synthetic parent identifier for module arguments, which can't + have unique identifier, as they can be introduced multiple times with the + same name in a single type expression . *) end (** Normal OCaml paths (i.e. the ones present in types) *) diff --git a/src/model_desc/lang_desc.ml b/src/model_desc/lang_desc.ml index 8df9471334..2e59a456d2 100644 --- a/src/model_desc/lang_desc.ml +++ b/src/model_desc/lang_desc.ml @@ -637,6 +637,14 @@ and typeexpr_package = List typeexpr_package_substitution ); ] +and typeexpr_module_arg = + let open Lang.TypeExpr.Module in + Record + [ + F ("id", (fun t -> t.id), identifier); + F ("package", (fun t -> t.package), typeexpr_package); + ] + and typeexpr_label = let open Lang.TypeExpr in Variant @@ -670,7 +678,12 @@ and typeexpr_t = | Poly (x1, x2) -> C ("Poly", (x1, x2), Pair (List string, typeexpr_t)) | Quote x -> C ("Quote", x, typeexpr_t) | Splice x -> C ("Splice", x, typeexpr_t) - | Package x -> C ("Package", x, typeexpr_package)) + | Package x -> C ("Package", x, typeexpr_package) + | Arrow_functor (lbl, m_arg, t) -> + C + ( "Arrow_functor", + (lbl, m_arg, t), + Triple (Option typeexpr_label, typeexpr_module_arg, typeexpr_t) )) (** {3 Compilation_unit} *) diff --git a/src/xref2/compile.ml b/src/xref2/compile.ml index 6d92d8e071..1066425741 100644 --- a/src/xref2/compile.ml +++ b/src/xref2/compile.ml @@ -838,6 +838,10 @@ and type_expression_object env parent o = in { o with fields = List.map field o.fields } +and type_expression_module_arg env parent m_arg = + let open TypeExpr.Module in + { m_arg with package = type_expression_package env parent m_arg.package } + and type_expression_package env parent p = let open TypeExpr.Package in let cp = Component.Of_Lang.(module_type_path (empty ()) p.path) in @@ -956,6 +960,12 @@ and type_expression : Env.t -> Id.LabelParent.t -> _ -> _ = | Quote t -> Quote (type_expression env parent t) | Splice t -> Splice (type_expression env parent t) | Package p -> Package (type_expression_package env parent p) + | Arrow_functor (lbl, m_arg, t) -> + let new_env = Env.add_module_arg m_arg env in + Arrow_functor + ( lbl, + type_expression_module_arg env parent m_arg, + type_expression new_env parent t ) let compile ~filename env compilation_unit = Lookup_failures.catch_failures ~filename (fun () -> unit env compilation_unit) diff --git a/src/xref2/component.ml b/src/xref2/component.ml index 9017fea357..64b9996a4a 100644 --- a/src/xref2/component.ml +++ b/src/xref2/component.ml @@ -115,6 +115,10 @@ and TypeExpr : sig type t = { path : Cpath.module_type; substitutions : substitution list } end + module Module : sig + type t = { package : Package.t; id : Ident.module_ } + end + type label = Odoc_model.Lang.TypeExpr.label type t = @@ -132,6 +136,7 @@ and TypeExpr : sig | Quote of t | Splice of t | Package of TypeExpr.Package.t + | Arrow_functor of label option * Module.t * t end = TypeExpr @@ -1211,6 +1216,11 @@ module Fmt = struct | Quote t -> Format.fprintf ppf "(quote %a)" (type_expr c) t | Splice t -> Format.fprintf ppf "(splice %a)" (type_expr c) t | Package x -> type_package c ppf x + | Arrow_functor (l, m_arg, t) -> + Format.fprintf ppf "%a(%a) -> %a" type_expr_label l (type_module_arg c) + m_arg (type_expr c) t + + and type_module_arg _c ppf _m = Format.fprintf ppf "(module_arg)" and resolved_module_path : config -> Format.formatter -> Cpath.Resolved.module_ -> unit = @@ -2356,6 +2366,14 @@ module Of_Lang = struct | Quote t -> Quote (type_expression ident_map t) | Splice t -> Splice (type_expression ident_map t) | Package p -> Package (type_package ident_map p) + | Arrow_functor (lbl, m_arg, t) -> + Arrow_functor + (lbl, type_module_arg ident_map m_arg, type_expression ident_map t) + + and type_module_arg ident_map { package; id } = + let id = Ident.Of_Identifier.functor_parameter id in + let package = type_package ident_map package in + { package; id } and module_decl ident_map m = match m with diff --git a/src/xref2/component.mli b/src/xref2/component.mli index 0cd6e900f5..c4fe50d51b 100644 --- a/src/xref2/component.mli +++ b/src/xref2/component.mli @@ -110,6 +110,10 @@ and TypeExpr : sig type t = { path : Cpath.module_type; substitutions : substitution list } end + module Module : sig + type t = { package : Package.t; id : Ident.module_ } + end + type label = Odoc_model.Lang.TypeExpr.label type t = @@ -127,6 +131,7 @@ and TypeExpr : sig | Quote of t | Splice of t | Package of TypeExpr.Package.t + | Arrow_functor of label option * Module.t * t end and Extension : sig diff --git a/src/xref2/env.ml b/src/xref2/env.ml index 751e8a2147..f254db4328 100644 --- a/src/xref2/env.ml +++ b/src/xref2/env.ml @@ -701,6 +701,21 @@ let add_functor_parameter : Lang.FunctorParameter.t -> t -> t = { elements = []; warnings_tag = None } t +let add_module_arg : Lang.TypeExpr.Module.t -> t -> t = + fun p t -> + let id = (p.id :> Paths.Identifier.Path.Module.t) in + let m = + let expr = + Lang.ModuleType.Path { p_path = p.package.path; p_expansion = None } + in + let open Component.Of_Lang in + mk_functor_parameter (module_type_expr (empty ()) expr) + in + add_module id + (Component.Delayed.put_val m) + { elements = []; warnings_tag = None } + t + let add_functor_args' : Paths.Identifier.Signature.t -> Component.ModuleType.expr -> t -> t = let open Component in diff --git a/src/xref2/env.mli b/src/xref2/env.mli index 413986088a..a2e2325a5a 100644 --- a/src/xref2/env.mli +++ b/src/xref2/env.mli @@ -166,6 +166,8 @@ val s_fragment_type_parent : Component.Element.fragment_type_parent scope val add_functor_parameter : Lang.FunctorParameter.t -> t -> t +val add_module_arg : Lang.TypeExpr.Module.t -> t -> t + val open_class_signature : Lang.ClassSignature.t -> t -> t val open_signature : Lang.Signature.t -> t -> t diff --git a/src/xref2/expand_tools.ml b/src/xref2/expand_tools.ml index c87ef6e420..6ec6930ad4 100644 --- a/src/xref2/expand_tools.ml +++ b/src/xref2/expand_tools.ml @@ -69,6 +69,9 @@ let rec type_expr map t = | Package p -> Package (package map p) | Quote t -> Quote (type_expr map t) | Splice t -> Splice (type_expr map t) + | Arrow_functor (l, m_arg, t) -> + let m_arg = module_arg map m_arg in + Arrow_functor (l, m_arg, type_expr map t) and polymorphic_variant map pv = let open Lang.TypeExpr.Polymorphic_variant in @@ -98,6 +101,10 @@ and package map p = let subst (frag, t) = (frag, type_expr map t) in { p with substitutions = List.map subst p.substitutions } +and module_arg map m = + let open Lang.TypeExpr.Module in + { m with package = package map m.package } + let collapse_eqns eqn1 eqn2 params = let open Lang.TypeDecl in let map = diff --git a/src/xref2/lang_of.ml b/src/xref2/lang_of.ml index ed5f45dfd0..a1b17fb6a5 100644 --- a/src/xref2/lang_of.ml +++ b/src/xref2/lang_of.ml @@ -1017,6 +1017,11 @@ and type_expr_package map (parent : Identifier.LabelParent.t) t = t.substitutions; } +and type_expr_module_arg map (parent : Identifier.LabelParent.t) + (t : Component.TypeExpr.Module.t) = + let id = List.assoc t.id map.functor_parameter in + { Lang.TypeExpr.Module.id; package = type_expr_package map parent t.package } + and type_expr map (parent : Identifier.LabelParent.t) (t : Component.TypeExpr.t) : Odoc_model.Lang.TypeExpr.t = try @@ -1043,6 +1048,9 @@ and type_expr map (parent : Identifier.LabelParent.t) (t : Component.TypeExpr.t) | Quote t -> Quote (type_expr map parent t) | Splice t -> Splice (type_expr map parent t) | Package p -> Package (type_expr_package map parent p) + | Arrow_functor (lbl, m_arg, t) -> + Arrow_functor + (lbl, type_expr_module_arg map parent m_arg, type_expr map parent t) with e -> let bt = Printexc.get_backtrace () in Format.fprintf Format.err_formatter diff --git a/src/xref2/link.ml b/src/xref2/link.ml index 0cdac826db..82c5809af5 100644 --- a/src/xref2/link.ml +++ b/src/xref2/link.ml @@ -1106,6 +1106,11 @@ and type_expression_object env parent visited o = in { o with fields = List.map field o.fields } +and type_expression_module_arg env parent visited m_arg = + let open TypeExpr.Module in + let package = type_expression_package env parent visited m_arg.package in + { m_arg with package } + and type_expression_package env parent visited p = let open TypeExpr.Package in let substitution (frag, t) = @@ -1207,6 +1212,12 @@ and type_expression : Env.t -> Id.Signature.t -> _ -> _ = | Quote t -> Quote (type_expression env parent visited t) | Splice t -> Splice (type_expression env parent visited t) | Package p -> Package (type_expression_package env parent visited p) + | Arrow_functor (lbl, m_arg, t) -> + let new_env = Env.add_module_arg m_arg env in + Arrow_functor + ( lbl, + type_expression_module_arg env parent visited m_arg, + type_expression new_env parent visited t ) let link ~filename x y = Lookup_failures.catch_failures ~filename (fun () -> diff --git a/src/xref2/shape_tools.cppo.ml b/src/xref2/shape_tools.cppo.ml index 2b16cb2e4e..9302b56ce5 100644 --- a/src/xref2/shape_tools.cppo.ml +++ b/src/xref2/shape_tools.cppo.ml @@ -120,6 +120,8 @@ let unit_of_uid uid = | Internal -> None #if defined OXCAML | Unboxed_version _ -> None +#elif OCAML_VERSION >= (5,5,0) + | Local_opaque_item _ -> None #endif #if OCAML_VERSION >= (5,2,0) diff --git a/src/xref2/subst.ml b/src/xref2/subst.ml index e6c02e469b..c7cc903ca8 100644 --- a/src/xref2/subst.ml +++ b/src/xref2/subst.ml @@ -179,6 +179,13 @@ let rec substitute_vars vars t = | Quote t -> Quote (substitute_vars vars t) | Splice t -> Splice (substitute_vars vars t) | Package p -> Package (substitute_vars_package vars p) + | Arrow_functor (lbl, m_arg, t) -> + Arrow_functor + (lbl, substitute_vars_module_arg vars m_arg, substitute_vars vars t) + +and substitute_vars_module_arg vars m_arg = + let package = substitute_vars_package vars m_arg.package in + { m_arg with package } and substitute_vars_package vars p = let open TypeExpr.Package in @@ -622,6 +629,12 @@ and type_expr s t = | Quote t -> Quote (type_expr s t) | Splice t -> Splice (type_expr s t) | Package p -> Package (type_package s p) + | Arrow_functor (lbl, m_arg, t) -> + Arrow_functor (lbl, type_module_arg s m_arg, type_expr s t) + +and type_module_arg s m_arg = + let package = type_package s m_arg.package in + { m_arg with package } and simple_expansion : t -> diff --git a/test/generators/cases/ocaml_55.mli b/test/generators/cases/ocaml_55.mli new file mode 100644 index 0000000000..e41d207f12 --- /dev/null +++ b/test/generators/cases/ocaml_55.mli @@ -0,0 +1,21 @@ +module type X = sig type t val x : int end + +type m = (module X) + +val f0 : m -> unit + +val f55 : (module M : X) -> M.t + +val f' : (module M : X with type t = int) -> int + +val f'' : (module X with type t = int) -> int + +module type Y = sig type 'a t val return : 'a -> 'a t end + +val g : (module M : Y) -> int M.t + +val g' : (module M : Y) -> int + +val g'' : (module Y) -> int + +val map2: ('a. 'a -> 'a) -> 'a * 'b -> 'a * 'b diff --git a/test/generators/gen_rules/gen_rules.ml b/test/generators/gen_rules/gen_rules.ml index e20d5f64ab..1548f8a26d 100644 --- a/test/generators/gen_rules/gen_rules.ml +++ b/test/generators/gen_rules/gen_rules.ml @@ -67,6 +67,7 @@ let constraints = ("module_type_subst.mli", Min "4.13"); ("class_comments.mli", Min "4.08"); ("functor_ml.ml", Min "4.14"); + ("ocaml_55.mli", Min "5.5"); ("oxcaml.mli", OxCaml); ] diff --git a/test/generators/html/Ocaml_55-module-type-X.html b/test/generators/html/Ocaml_55-module-type-X.html new file mode 100644 index 0000000000..a49ceb9027 --- /dev/null +++ b/test/generators/html/Ocaml_55-module-type-X.html @@ -0,0 +1,33 @@ + + + X (Ocaml_55.X) + + + + + + + + +
+

Module type Ocaml_55.X

+
+
+
+
+ + type t +
+
+
+
+ + val x : int +
+
+
+ + diff --git a/test/generators/html/Ocaml_55-module-type-Y.html b/test/generators/html/Ocaml_55-module-type-Y.html new file mode 100644 index 0000000000..19e462f0e8 --- /dev/null +++ b/test/generators/html/Ocaml_55-module-type-Y.html @@ -0,0 +1,41 @@ + + + Y (Ocaml_55.Y) + + + + + + + + +
+

Module type Ocaml_55.Y

+
+
+
+
+ + type 'a t + +
+
+
+
+ + + val return : + 'a + -> + + 'a t + + +
+
+
+ + diff --git a/test/generators/html/Ocaml_55.html b/test/generators/html/Ocaml_55.html new file mode 100644 index 0000000000..4f31ef681f --- /dev/null +++ b/test/generators/html/Ocaml_55.html @@ -0,0 +1,175 @@ + + + Ocaml_55 (Ocaml_55) + + + + + + + + +
+

Module Ocaml_55

+
+
+
+
+ + + module + type + X + + = sig ... + end + + +
+
+
+
+ + type m + = + (module + X) + + + +
+
+
+
+ + + val f0 : + m -> + unit + + +
+
+
+
+ + + val f55 : + (module M : + X) + -> + M.t + + +
+
+
+
+ + + val f' : + (module M : + X + with type + t = int) + -> int + + +
+
+
+
+ + + val f'' : + + (module + X + with type + t = int) + -> + int + + +
+
+
+
+ + + module + type + Y + + = sig ... + end + + +
+
+
+
+ + + val g : + (module M : + Y) + -> + int M.t + + +
+
+
+
+ + + val g' : + (module M : + Y) + -> int + + +
+
+
+
+ + + val g'' : + + (module + Y) + -> + int + + +
+
+
+
+ + + val map2 : + + ('a. + 'a + -> + 'a) + -> + + + ('a * + 'b) + -> + 'a * + 'b + + +
+
+
+ + diff --git a/test/generators/html/ocaml_55.targets b/test/generators/html/ocaml_55.targets new file mode 100644 index 0000000000..fb491ea1be --- /dev/null +++ b/test/generators/html/ocaml_55.targets @@ -0,0 +1,3 @@ +Ocaml_55.html +Ocaml_55-module-type-X.html +Ocaml_55-module-type-Y.html diff --git a/test/generators/latex/Ocaml_55.tex b/test/generators/latex/Ocaml_55.tex new file mode 100644 index 0000000000..de2466d441 --- /dev/null +++ b/test/generators/latex/Ocaml_55.tex @@ -0,0 +1,20 @@ +\section{Module \ocamlinlinecode{Ocaml\_\allowbreak{}55}}\label{Ocaml_55}% +\label{Ocaml_55--module-type-X}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[Ocaml_55-module-type-X]{\ocamlinlinecode{X}}}\label{Ocaml_55-module-type-X}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Ocaml_55-module-type-X--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t}\\ +\label{Ocaml_55-module-type-X--val-x}\ocamlcodefragment{\ocamltag{keyword}{val} x : int}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\\ +\label{Ocaml_55--type-m}\ocamlcodefragment{\ocamltag{keyword}{type} m = (\ocamltag{keyword}{module} \hyperref[Ocaml_55-module-type-X]{\ocamlinlinecode{X}})}\\ +\label{Ocaml_55--val-f0}\ocamlcodefragment{\ocamltag{keyword}{val} f0 : \hyperref[Ocaml_55--type-m]{\ocamlinlinecode{m}} \ocamltag{arrow}{$\rightarrow$} unit}\\ +\label{Ocaml_55--val-f55}\ocamlcodefragment{\ocamltag{keyword}{val} f55 : (\ocamltag{keyword}{module} M : \hyperref[Ocaml_55-module-type-X]{\ocamlinlinecode{X}}) \ocamltag{arrow}{$\rightarrow$} \hyperref[xref-unresolved]{\ocamlinlinecode{M.\allowbreak{}t}}}\\ +\label{Ocaml_55--val-f'}\ocamlcodefragment{\ocamltag{keyword}{val} f' : (\ocamltag{keyword}{module} M : \hyperref[Ocaml_55-module-type-X]{\ocamlinlinecode{X}} \ocamltag{keyword}{with} \ocamltag{keyword}{type} \hyperref[Ocaml_55-module-type-X--type-t]{\ocamlinlinecode{t}} = int) \ocamltag{arrow}{$\rightarrow$} int}\\ +\label{Ocaml_55--val-f''}\ocamlcodefragment{\ocamltag{keyword}{val} f'' : (\ocamltag{keyword}{module} \hyperref[Ocaml_55-module-type-X]{\ocamlinlinecode{X}} \ocamltag{keyword}{with} \ocamltag{keyword}{type} \hyperref[Ocaml_55-module-type-X--type-t]{\ocamlinlinecode{t}} = int) \ocamltag{arrow}{$\rightarrow$} int}\\ +\label{Ocaml_55--module-type-Y}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[Ocaml_55-module-type-Y]{\ocamlinlinecode{Y}}}\label{Ocaml_55-module-type-Y}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{Ocaml_55-module-type-Y--type-t}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t}\\ +\label{Ocaml_55-module-type-Y--val-return}\ocamlcodefragment{\ocamltag{keyword}{val} return : \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a} \hyperref[Ocaml_55-module-type-Y--type-t]{\ocamlinlinecode{t}}}\\ +\end{ocamlindent}% +\ocamlcodefragment{\ocamltag{keyword}{end}}\\ +\label{Ocaml_55--val-g}\ocamlcodefragment{\ocamltag{keyword}{val} g : (\ocamltag{keyword}{module} M : \hyperref[Ocaml_55-module-type-Y]{\ocamlinlinecode{Y}}) \ocamltag{arrow}{$\rightarrow$} int \hyperref[xref-unresolved]{\ocamlinlinecode{M.\allowbreak{}t}}}\\ +\label{Ocaml_55--val-g'}\ocamlcodefragment{\ocamltag{keyword}{val} g' : (\ocamltag{keyword}{module} M : \hyperref[Ocaml_55-module-type-Y]{\ocamlinlinecode{Y}}) \ocamltag{arrow}{$\rightarrow$} int}\\ +\label{Ocaml_55--val-g''}\ocamlcodefragment{\ocamltag{keyword}{val} g'' : (\ocamltag{keyword}{module} \hyperref[Ocaml_55-module-type-Y]{\ocamlinlinecode{Y}}) \ocamltag{arrow}{$\rightarrow$} int}\\ +\label{Ocaml_55--val-map2}\ocamlcodefragment{\ocamltag{keyword}{val} map2 : ('a.\allowbreak{} \ocamltag{type-var}{'a} \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a}) \ocamltag{arrow}{$\rightarrow$} (\ocamltag{type-var}{'a} * \ocamltag{type-var}{'b}) \ocamltag{arrow}{$\rightarrow$} \ocamltag{type-var}{'a} * \ocamltag{type-var}{'b}}\\ + + diff --git a/test/generators/latex/ocaml_55.targets b/test/generators/latex/ocaml_55.targets new file mode 100644 index 0000000000..6bb2d3d3da --- /dev/null +++ b/test/generators/latex/ocaml_55.targets @@ -0,0 +1 @@ +Ocaml_55.tex diff --git a/test/generators/link.dune.inc b/test/generators/link.dune.inc index e5d3455c96..88177118d6 100644 --- a/test/generators/link.dune.inc +++ b/test/generators/link.dune.inc @@ -542,6 +542,30 @@ (enabled_if (>= %{ocaml_version} 4.04))) +(rule + (target ocaml_55.cmti) + (package odoc) + (action + (run ocamlc -c -bin-annot -o %{target} %{dep:cases/ocaml_55.mli})) + (enabled_if + (>= %{ocaml_version} 5.5))) + +(rule + (target ocaml_55.odoc) + (package odoc) + (action + (run odoc compile -o %{target} %{dep:ocaml_55.cmti})) + (enabled_if + (>= %{ocaml_version} 5.5))) + +(rule + (target ocaml_55.odocl) + (package odoc) + (action + (run odoc link -o %{target} %{dep:ocaml_55.odoc})) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule (target ocamlary.cmti) (package odoc) @@ -7380,6 +7404,200 @@ (enabled_if (>= %{ocaml_version} 4.04)))) +(subdir + html + (rule + (targets + Ocaml_55.html.gen + Ocaml_55-module-type-X.html.gen + Ocaml_55-module-type-Y.html.gen) + (package odoc) + (action + (run + odoc + html-generate + --indent + --flat + --extra-suffix + gen + -o + . + %{dep:../ocaml_55.odocl})) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55.html Ocaml_55.html.gen)) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55-module-type-X.html Ocaml_55-module-type-X.html.gen)) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55-module-type-Y.html Ocaml_55-module-type-Y.html.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + html + (rule + (target ocaml_55.targets.gen) + (package odoc) + (action + (with-outputs-to + ocaml_55.targets.gen + (run odoc html-targets -o . %{dep:../ocaml_55.odocl} --flat))) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff ocaml_55.targets ocaml_55.targets.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + latex + (rule + (targets Ocaml_55.tex.gen) + (package odoc) + (action + (run odoc latex-generate -o . --extra-suffix gen %{dep:../ocaml_55.odocl})) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55.tex Ocaml_55.tex.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + latex + (rule + (target ocaml_55.targets.gen) + (package odoc) + (action + (with-outputs-to + ocaml_55.targets.gen + (run odoc latex-targets -o . %{dep:../ocaml_55.odocl}))) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff ocaml_55.targets ocaml_55.targets.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + man + (rule + (targets Ocaml_55.3o.gen) + (package odoc) + (action + (run odoc man-generate -o . --extra-suffix gen %{dep:../ocaml_55.odocl})) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55.3o Ocaml_55.3o.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + man + (rule + (target ocaml_55.targets.gen) + (package odoc) + (action + (with-outputs-to + ocaml_55.targets.gen + (run odoc man-targets -o . %{dep:../ocaml_55.odocl}))) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff ocaml_55.targets ocaml_55.targets.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + markdown + (rule + (targets + Ocaml_55.md.gen + Ocaml_55-module-type-X.md.gen + Ocaml_55-module-type-Y.md.gen) + (package odoc) + (action + (run + odoc + markdown-generate + -o + . + --extra-suffix + gen + %{dep:../ocaml_55.odocl})) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55.md Ocaml_55.md.gen)) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55-module-type-X.md Ocaml_55-module-type-X.md.gen)) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff Ocaml_55-module-type-Y.md Ocaml_55-module-type-Y.md.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + +(subdir + markdown + (rule + (target ocaml_55.targets.gen) + (package odoc) + (action + (with-outputs-to + ocaml_55.targets.gen + (run odoc markdown-targets -o . %{dep:../ocaml_55.odocl}))) + (enabled_if + (>= %{ocaml_version} 5.5))) + (rule + (alias runtest) + (package odoc) + (action + (diff ocaml_55.targets ocaml_55.targets.gen)) + (enabled_if + (>= %{ocaml_version} 5.5)))) + (subdir html (rule diff --git a/test/generators/man/Ocaml_55.3o b/test/generators/man/Ocaml_55.3o new file mode 100644 index 0000000000..e4ed83e9a2 --- /dev/null +++ b/test/generators/man/Ocaml_55.3o @@ -0,0 +1,50 @@ + +.TH Ocaml_55 3 "" "Odoc" "OCaml Library" +.SH Name +Ocaml_55 +.SH Synopsis +.sp +.in 2 +\fBModule Ocaml_55\fR +.in +.sp +.SH Documentation +.sp +.nf +\f[CB]module\fR \f[CB]type\fR X = \f[CB]sig\fR +.br +.ti +2 +\f[CB]type\fR t +.sp +.ti +2 +\f[CB]val\fR x : int +.br +\f[CB]end\fR +.sp +\f[CB]type\fR m = (\f[CB]module\fR X) +.sp +\f[CB]val\fR f0 : m \f[CB]\->\fR unit +.sp +\f[CB]val\fR f55 : (\f[CB]module\fR M : X) \f[CB]\->\fR M\.t +.sp +\f[CB]val\fR f' : (\f[CB]module\fR M : X \f[CB]with\fR \f[CB]type\fR t = int) \f[CB]\->\fR int +.sp +\f[CB]val\fR f'' : (\f[CB]module\fR X \f[CB]with\fR \f[CB]type\fR t = int) \f[CB]\->\fR int +.sp +\f[CB]module\fR \f[CB]type\fR Y = \f[CB]sig\fR +.br +.ti +2 +\f[CB]type\fR 'a t +.sp +.ti +2 +\f[CB]val\fR return : \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR t +.br +\f[CB]end\fR +.sp +\f[CB]val\fR g : (\f[CB]module\fR M : Y) \f[CB]\->\fR int M\.t +.sp +\f[CB]val\fR g' : (\f[CB]module\fR M : Y) \f[CB]\->\fR int +.sp +\f[CB]val\fR g'' : (\f[CB]module\fR Y) \f[CB]\->\fR int +.sp +\f[CB]val\fR map2 : ('a\. \f[CB]'a\fR \f[CB]\->\fR \f[CB]'a\fR) \f[CB]\->\fR (\f[CB]'a\fR * \f[CB]'b\fR) \f[CB]\->\fR \f[CB]'a\fR * \f[CB]'b\fR diff --git a/test/generators/man/ocaml_55.targets b/test/generators/man/ocaml_55.targets new file mode 100644 index 0000000000..f540aa2e96 --- /dev/null +++ b/test/generators/man/ocaml_55.targets @@ -0,0 +1 @@ +Ocaml_55.3o diff --git a/test/generators/markdown/Ocaml_55-module-type-X.md b/test/generators/markdown/Ocaml_55-module-type-X.md new file mode 100644 index 0000000000..12faae1bf9 --- /dev/null +++ b/test/generators/markdown/Ocaml_55-module-type-X.md @@ -0,0 +1,9 @@ + +# Module type `Ocaml_55.X` + +```ocaml +type t +``` +```ocaml +val x : int +``` \ No newline at end of file diff --git a/test/generators/markdown/Ocaml_55-module-type-Y.md b/test/generators/markdown/Ocaml_55-module-type-Y.md new file mode 100644 index 0000000000..41457df468 --- /dev/null +++ b/test/generators/markdown/Ocaml_55-module-type-Y.md @@ -0,0 +1,9 @@ + +# Module type `Ocaml_55.Y` + +```ocaml +type 'a t +``` +```ocaml +val return : 'a -> 'a t +``` \ No newline at end of file diff --git a/test/generators/markdown/Ocaml_55.md b/test/generators/markdown/Ocaml_55.md new file mode 100644 index 0000000000..5d4a34978a --- /dev/null +++ b/test/generators/markdown/Ocaml_55.md @@ -0,0 +1,36 @@ + +# Module `Ocaml_55` + +```ocaml +module type X = sig ... end +``` +```ocaml +type m = (module X) +``` +```ocaml +val f0 : m -> unit +``` +```ocaml +val f55 : (module M : X) -> M.t +``` +```ocaml +val f' : (module M : X with type t = int) -> int +``` +```ocaml +val f'' : (module X with type t = int) -> int +``` +```ocaml +module type Y = sig ... end +``` +```ocaml +val g : (module M : Y) -> int M.t +``` +```ocaml +val g' : (module M : Y) -> int +``` +```ocaml +val g'' : (module Y) -> int +``` +```ocaml +val map2 : ('a. 'a -> 'a) -> ('a * 'b) -> 'a * 'b +``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-X.md b/test/generators/markdown/Recent-X.md index d1d4858704..480cf2e22b 100644 --- a/test/generators/markdown/Recent-X.md +++ b/test/generators/markdown/Recent-X.md @@ -1,15 +1,15 @@ # Module `Recent.X` -``` +```ocaml module L := Z.Y ``` -``` +```ocaml type t = int L.X.t ``` -``` +```ocaml type u := int ``` -``` +```ocaml type v = u L.X.t ``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-Z-Y-X.md b/test/generators/markdown/Recent-Z-Y-X.md index 74a5fc997c..8c3d0d18c3 100644 --- a/test/generators/markdown/Recent-Z-Y-X.md +++ b/test/generators/markdown/Recent-Z-Y-X.md @@ -1,6 +1,6 @@ # Module `Y.X` -``` +```ocaml type 'a t ``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-Z-Y.md b/test/generators/markdown/Recent-Z-Y.md index 93d7cc96e6..15ba3da283 100644 --- a/test/generators/markdown/Recent-Z-Y.md +++ b/test/generators/markdown/Recent-Z-Y.md @@ -1,6 +1,6 @@ # Module `Z.Y` -``` +```ocaml module X : sig ... end ``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-Z.md b/test/generators/markdown/Recent-Z.md index fa06f69c30..86bd9aaa3f 100644 --- a/test/generators/markdown/Recent-Z.md +++ b/test/generators/markdown/Recent-Z.md @@ -1,6 +1,6 @@ # Module `Recent.Z` -``` +```ocaml module Y : sig ... end ``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-module-type-PolyS.md b/test/generators/markdown/Recent-module-type-PolyS.md index f43d7afa3f..0edf1a9682 100644 --- a/test/generators/markdown/Recent-module-type-PolyS.md +++ b/test/generators/markdown/Recent-module-type-PolyS.md @@ -1,15 +1,9 @@ # Module type `Recent.PolyS` -``` +```ocaml type t = [ -``` -``` -| `A -``` -``` -| `B -``` -``` + | `A + | `B ] ``` \ No newline at end of file diff --git a/test/generators/markdown/Recent-module-type-S1.md b/test/generators/markdown/Recent-module-type-S1.md index fc503f25e1..63a7cbe0a7 100644 --- a/test/generators/markdown/Recent-module-type-S1.md +++ b/test/generators/markdown/Recent-module-type-S1.md @@ -4,7 +4,7 @@ ## Parameters -``` +```ocaml module _ : S ``` diff --git a/test/generators/markdown/Recent.md b/test/generators/markdown/Recent.md index 837f7894da..95e87797bb 100644 --- a/test/generators/markdown/Recent.md +++ b/test/generators/markdown/Recent.md @@ -1,13 +1,13 @@ # Module `Recent` -``` +```ocaml module type S = sig ... end ``` -``` +```ocaml module type S1 = functor (_ : S) -> S ``` -``` +```ocaml type variant = | A | B of int @@ -17,7 +17,7 @@ type variant = a : int; } ``` -``` +```ocaml type _ gadt = | A : int gadt | B : int -> string gadt (* foo *) @@ -25,7 +25,7 @@ type _ gadt = a : int; } -> unit gadt ``` -``` +```ocaml type polymorphic_variant = [ | `A | `B of int @@ -33,38 +33,38 @@ type polymorphic_variant = [ | `D (* bar *) ] ``` -``` +```ocaml type empty_variant = | ``` -``` +```ocaml type nonrec nonrec_ = int ``` -``` +```ocaml type empty_conj = | X : [< `X of & 'a & int * float ] -> empty_conj ``` -``` +```ocaml type conj = | X : [< `X of int & [< `B of int & float ] ] -> conj ``` -``` +```ocaml val empty_conj : [< `X of & 'a & int * float ] ``` -``` +```ocaml val conj : [< `X of int & [< `B of int & float ] ] ``` -``` +```ocaml module Z : sig ... end ``` -``` +```ocaml module X : sig ... end ``` -``` +```ocaml module type PolyS = sig ... end ``` -``` +```ocaml type +-'a phantom ``` -``` +```ocaml val f : (x:int * y:int) phantom -> unit -``` +``` \ No newline at end of file diff --git a/test/generators/markdown/ocaml_55.targets b/test/generators/markdown/ocaml_55.targets new file mode 100644 index 0000000000..e59d9f384e --- /dev/null +++ b/test/generators/markdown/ocaml_55.targets @@ -0,0 +1,3 @@ +Ocaml_55.md +Ocaml_55-module-type-X.md +Ocaml_55-module-type-Y.md diff --git a/test/search/html_search.t/run.t b/test/search/html_search.t/run.t index 3f39c790d8..ff4a2f7fde 100644 --- a/test/search/html_search.t/run.t +++ b/test/search/html_search.t/run.t @@ -215,11 +215,7 @@ Testing the warnings/errors for the `compile-index` command: Passing an inexistent file: $ odoc compile-index --root babar - $ odoc compile-index --file-list babar - odoc: option '--file-list': no 'babar' file or directory - Usage: odoc compile-index [OPTION]… [FILE]… - Try 'odoc compile-index --help' or 'odoc --help' for more information. - [2] + $ ! odoc compile-index --file-list babar > /dev/null 2>&1 Passing an empty folder is allowed: diff --git a/test/sources/lookup_def.t/run.t b/test/sources/lookup_def.t/run.t index 7877163102..e40ea74ca8 100644 --- a/test/sources/lookup_def.t/run.t +++ b/test/sources/lookup_def.t/run.t @@ -5,11 +5,7 @@ Compile the modules: $ odoc compile-impl --source-id src/a.ml -I . a.cmt $ odoc compile -I . a.cmti - $ odoc link -I . src-a.odoc - odoc: FILE.odoc argument: no 'src-a.odoc' file or directory - Usage: odoc link [--custom-layout] [--open=MODULE] [OPTION]… FILE.odoc - Try 'odoc link --help' or 'odoc --help' for more information. - [2] + $ ! odoc link -I . src-a.odoc > /dev/null 2>&1 $ odoc link -I . a.odoc Show the locations: diff --git a/test/sources/source.t/run.t b/test/sources/source.t/run.t index 5ec6c77e46..020ee1b1db 100644 --- a/test/sources/source.t/run.t +++ b/test/sources/source.t/run.t @@ -386,29 +386,11 @@ Ids generated in the source code: Html generation for implementation and mld/interface uses different commands - $ odoc html-generate-source --indent -o html a.odocl - odoc: required option --impl is missing - Usage: odoc html-generate-source [OPTION]… FILE.ml - Try 'odoc html-generate-source --help' or 'odoc --help' for more information. - [2] - $ odoc html-generate-source --indent -o html --impl a.odocl a.ml - ERROR: Expected an implementation unit - [1] - $ odoc html-generate-source --indent -o html --impl impl-a.odocl - odoc: required argument FILE.ml is missing - Usage: odoc html-generate-source [OPTION]… FILE.ml - Try 'odoc html-generate-source --help' or 'odoc --help' for more information. - [2] - $ odoc html-generate-source --indent -o html a.ml - odoc: required option --impl is missing - Usage: odoc html-generate-source [OPTION]… FILE.ml - Try 'odoc html-generate-source --help' or 'odoc --help' for more information. - [2] - $ odoc html-generate --source a.ml --indent -o html impl-a.odocl - odoc: unknown option '--source'. - Usage: odoc html-generate [OPTION]… FILE.odocl… - Try 'odoc html-generate --help' or 'odoc --help' for more information. - [2] + $ ! odoc html-generate-source --indent -o html a.odocl > /dev/null 2>&1 + $ ! odoc html-generate-source --indent -o html --impl a.odocl a.ml > /dev/null 2>&1 + $ ! odoc html-generate-source --indent -o html --impl impl-a.odocl > /dev/null 2>&1 + $ ! odoc html-generate-source --indent -o html a.ml > /dev/null 2>&1 + $ ! odoc html-generate --source a.ml --indent -o html impl-a.odocl > /dev/null 2>&1 Compiling without --source-id makes it impossible to generate the source: