this repo has no description

fix(odoc): correct OxCaml API field names and add cmti mode extraction

- Fix Jkind.Desc.t field access: use `layout` instead of `base` (the
type is `layout_and_axes`, not `base_and_axes`)
- Fix Jkind layout pattern matching: remove non-existent `Layout`,
`Univar`, and `Kconstr` constructors to match actual compiler API
- Fix Parsetree.jkind_annotation field: use `pjkind_desc` instead of
`pjka_desc`, and handle `Pjk_abbreviation of string` (not Longident)
- Extract arrow modes from cmti path by reading underlying Types.type_expr
- Expose Cmi.extract_arg_modes in .mli for use by cmti.ml

Verified end-to-end: modes render correctly for both .cmi and .cmti
inputs (e.g., `val f : string @ local unique -> int`), and jkind
annotations appear on type variables (e.g., `('a : float64)`).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+20 -10
+6 -8
src/loader/cmi.ml
··· 537 537 Returns [None] for the default [value] layout or unknown layouts. *) 538 538 let extract_jkind_of_tvar jkind = 539 539 let desc = Jkind.get jkind in 540 - match desc.base with 541 - | Layout (Sort (Base Value)) -> None (* default — don't annotate *) 542 - | Layout (Sort (Base b)) -> Some (Jkind_types.Sort.to_string_base b) 543 - | Layout (Sort (Var _)) -> None (* sort variable — not determined *) 544 - | Layout (Sort (Univar _)) -> None (* universally quantified sort *) 545 - | Layout (Product _) -> None (* product layout — complex, skip for now *) 546 - | Layout Any -> None 547 - | Kconstr _ -> None (* abstract kind — skip *) 540 + match desc.layout with 541 + | Sort (Base Value) -> None (* default — don't annotate *) 542 + | Sort (Base b) -> Some (Jkind_types.Sort.to_string_base b) 543 + | Sort (Var _) -> None (* sort variable — not determined *) 544 + | Product _ -> None (* product layout — complex, skip for now *) 545 + | Any -> None 548 546 #endif 549 547 550 548 let rec read_type_expr env typ =
+4
src/loader/cmi.mli
··· 88 88 Odoc_model.Compat.signature -> Odoc_model.Lang.Signature.t 89 89 90 90 91 + #if defined OXCAML 92 + val extract_arg_modes : Mode.Alloc.lr -> string list 93 + #endif 94 + 91 95 val read_extension_constructor : env -> 92 96 Paths.Identifier.Signature.t -> 93 97 Ident.t -> Types.extension_constructor ->
+10 -2
src/loader/cmti.ml
··· 47 47 | Ttyp_var (None, _jkind_annot) -> Any 48 48 | Ttyp_var (Some s, jkind_annot) -> 49 49 let jkind = match jkind_annot with 50 - | Some { Parsetree.pjka_desc = Pjk_abbreviation lid; _ } -> 51 - let name = Longident.last lid.txt in 50 + | Some { Parsetree.pjkind_desc = Pjk_abbreviation name; _ } -> 52 51 if name = "value" then None else Some name 53 52 | _ -> None 54 53 in ··· 75 74 #endif 76 75 in 77 76 let res = read_core_type env container res in 77 + #if defined OXCAML 78 + let arg_modes = match Types.get_desc ctyp.ctyp_type with 79 + | Tarrow((_lbl, marg, _mret), _arg, _res, _) -> 80 + Cmi.extract_arg_modes marg 81 + | _ -> [] 82 + in 83 + Arrow(lbl, arg, res, arg_modes) 84 + #else 78 85 Arrow(lbl, arg, res, []) 86 + #endif 79 87 | Ttyp_tuple typs -> 80 88 #if OCAML_VERSION >= (5,4,0) || defined OXCAML 81 89 let typs = List.map (fun (lbl,x) -> lbl, read_core_type env container x) typs in