this repo has no description
at main 673 lines 26 kB view raw
1(* 2 * Copyright (c) 2014 Leo White <lpw25@cl.cam.ac.uk> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 *) 16 17 18open Asttypes 19open Typedtree 20 21module OCamlPath = Path 22 23open Odoc_model.Paths 24open Odoc_model.Lang 25 26module Env = Ident_env 27 28type env = Cmi.env = { 29 ident_env : Ident_env.t; 30 warnings_tag : string option; 31} 32 33 34let cmt_builddir : string ref = ref "" 35 36let read_core_type env ctyp = 37 Cmi.read_type_expr env ctyp.ctyp_type 38 39let rec read_pattern env parent doc pat = 40 let source_loc = None in 41 let open Signature in 42 match pat.pat_desc with 43 | Tpat_any -> [] 44#if OCAML_VERSION < (5,2,0) 45 | Tpat_var(id, _) -> 46#elif defined OXCAML 47 | Tpat_var(id, _, _uid, _, _) -> 48#else 49 | Tpat_var(id, _, _uid) -> 50#endif 51 let open Value in 52 let id = Env.find_value_identifier env.ident_env id in 53 Cmi.mark_type_expr pat.pat_type; 54 let type_ = Cmi.read_type_expr env pat.pat_type in 55 let value = Abstract in 56 let source_loc_jane = Some (Odoc_model.Lang.Source_loc_jane.of_location !cmt_builddir pat.pat_loc) in 57 [Value {id; source_loc; doc; type_; value ; source_loc_jane; modalities = [] }] 58#if OCAML_VERSION < (5,2, 0) 59 | Tpat_alias(pat, id, _) -> 60#elif defined OXCAML 61 | Tpat_alias(pat, id, _, _, _, _, _) -> 62#elif OCAML_VERSION < (5,4,0) 63 | Tpat_alias(pat, id, _,_) -> 64#else 65 | Tpat_alias(pat, id,_,_,_) -> 66#endif 67 let open Value in 68 let id = Env.find_value_identifier env.ident_env id in 69 Cmi.mark_type_expr pat.pat_type; 70 let type_ = Cmi.read_type_expr env pat.pat_type in 71 let value = Abstract in 72 let source_loc_jane = Some (Odoc_model.Lang.Source_loc_jane.of_location !cmt_builddir pat.pat_loc) in 73 Value {id; source_loc; doc; type_; value ; source_loc_jane; modalities = [] } :: read_pattern env parent doc pat 74 | Tpat_constant _ -> [] 75 | Tpat_tuple pats -> 76#if OCAML_VERSION >= (5, 4, 0) || defined OXCAML 77 let pats = List.map snd pats (* remove labels *) in 78#endif 79 List.concat (List.map (read_pattern env parent doc) pats) 80#if defined OXCAML 81 | Tpat_unboxed_tuple pats -> 82 List.concat (List.map (fun (_, p, _) -> read_pattern env parent doc p) pats) 83#endif 84#if OCAML_VERSION < (4, 13, 0) 85 | Tpat_construct(_, _, pats) -> 86#else 87 | Tpat_construct(_,_,pats,_) -> 88#endif 89 List.concat (List.map (read_pattern env parent doc) pats) 90 | Tpat_variant(_, None, _) -> [] 91 | Tpat_variant(_, Some pat, _) -> 92 read_pattern env parent doc pat 93 | Tpat_record(pats, _) -> 94 List.concat 95 (List.map 96 (fun (_, _, pat) -> read_pattern env parent doc pat) 97 pats) 98#if defined OXCAML 99 | Tpat_record_unboxed_product(pats, _) -> 100 List.concat 101 (List.map 102 (fun (_, _, pat) -> read_pattern env parent doc pat) 103 pats) 104 | Tpat_array (_, _, pats) -> 105#elif OCAML_VERSION < (5, 4, 0) 106 | Tpat_array pats -> 107#else 108 | Tpat_array (_, pats) -> 109#endif 110 List.concat (List.map (read_pattern env parent doc) pats) 111 | Tpat_or(pat, _, _) -> 112 read_pattern env parent doc pat 113 | Tpat_lazy pat -> 114 read_pattern env parent doc pat 115#if OCAML_VERSION >= (4,8,0) && OCAML_VERSION < (4,11,0) 116 | Tpat_exception pat -> 117 read_pattern env parent doc pat 118#endif 119 120let read_value_binding env parent vb = 121 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 122 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container vb.vb_attributes in 123 read_pattern env parent doc vb.vb_pat 124 125let read_value_bindings env parent vbs = 126 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 127 let items = 128 List.fold_left 129 (fun acc vb -> 130 let open Signature in 131 let comments = 132 Doc_attr.standalone_multiple container ~warnings_tag:env.warnings_tag vb.vb_attributes in 133 let comments = List.map (fun com -> Comment com) comments in 134 let vb = read_value_binding env parent vb in 135 List.rev_append vb (List.rev_append comments acc)) 136 [] vbs 137 in 138 List.rev items 139 140let read_type_extension env parent tyext = 141 let open Extension in 142 let type_path = Env.Path.read_type env.ident_env tyext.tyext_path in 143 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 144 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container tyext.tyext_attributes in 145 let type_params = 146 List.map (fun (ctyp, _) -> ctyp.ctyp_type) tyext.tyext_params 147 in 148 let constructors = 149 List.map (fun ext -> ext.ext_type) tyext.tyext_constructors 150 in 151 let type_params = 152 Cmi.mark_type_extension type_params constructors 153 in 154 let type_params = 155 List.map 156 (Cmi.read_type_parameter false Types.Variance.null) 157 type_params 158 in 159 let private_ = (tyext.tyext_private = Private) in 160 let constructors = 161 List.map 162 (fun ext -> 163 Cmi.read_extension_constructor 164 env parent ext.ext_id ext.ext_type) 165 tyext.tyext_constructors 166 in 167 { parent; type_path; doc; type_params; private_; constructors; } 168 169(** Make a standalone comment out of a comment attached to an item that isn't 170 rendered. For example, [constraint] items are read separately and not 171 associated with their comment. *) 172let mk_class_comment = function 173 | { Odoc_model.Comment.elements = []; _} -> None 174 | doc -> Some (ClassSignature.Comment (`Docs doc)) 175 176let rec read_class_type_field env parent ctf = 177 let open ClassSignature in 178 let open Odoc_model.Names in 179 let container = (parent : Identifier.ClassSignature.t :> Identifier.LabelParent.t) in 180 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container ctf.ctf_attributes in 181 match ctf.ctf_desc with 182 | Tctf_val(name, mutable_, virtual_, typ) -> 183 let open InstanceVariable in 184 let id = Identifier.Mk.instance_variable(parent, InstanceVariableName.make_std name) in 185 let mutable_ = (mutable_ = Mutable) in 186 let virtual_ = (virtual_ = Virtual) in 187 let type_ = read_core_type env typ in 188 Some (InstanceVariable {id; doc; mutable_; virtual_; type_}) 189 | Tctf_method(name, private_, virtual_, typ) -> 190 let open Method in 191 let id = Identifier.Mk.method_(parent, MethodName.make_std name) in 192 let private_ = (private_ = Private) in 193 let virtual_ = (virtual_ = Virtual) in 194 let type_ = read_core_type env typ in 195 Some (Method {id; doc; private_; virtual_; type_}) 196 | Tctf_constraint(_, _) -> mk_class_comment doc 197 | Tctf_inherit cltyp -> 198 let expr = read_class_signature env parent [] cltyp in 199 Some (Inherit {Inherit.expr; doc}) 200 | Tctf_attribute attr -> 201 match Doc_attr.standalone container ~warnings_tag:env.warnings_tag attr with 202 | None -> None 203 | Some doc -> Some (Comment doc) 204 205and read_class_signature env parent params cltyp = 206 let open ClassType in 207 match cltyp.cltyp_desc with 208 | Tcty_constr(p, _, params) -> 209 let p = Env.Path.read_class_type env.ident_env p in 210 let params = List.map (read_core_type env) params in 211 Constr(p, params) 212 | Tcty_signature csig -> 213 let open ClassSignature in 214 let self = 215 Cmi.read_self_type csig.csig_self.ctyp_type 216 in 217 let constraints = Cmi.read_class_constraints env params in 218 let items = 219 List.fold_left 220 (fun rest item -> 221 match read_class_type_field env parent item with 222 | None -> rest 223 | Some item -> item :: rest) 224 [] csig.csig_fields 225 in 226 let items = constraints @ List.rev items in 227 let items, (doc, doc_post) = Doc_attr.extract_top_comment_class items in 228 let items = 229 match doc_post with 230 | { elements = []; _ } -> items 231 | _ -> Comment (`Docs doc_post) :: items 232 in 233 Signature {self; items; doc} 234 235 | Tcty_arrow _ -> assert false 236#if OCAML_VERSION >= (4,6,0) 237 | Tcty_open _ -> assert false 238#endif 239 240let rec read_class_type env parent params cty = 241 let open Class in 242 match cty.cltyp_desc with 243 | Tcty_constr _ | Tcty_signature _ -> 244 ClassType (read_class_signature env parent params cty) 245 | Tcty_arrow(lbl, arg, res) -> 246 let lbl = Cmi.read_label lbl in 247 let arg = read_core_type env arg in 248 let res = read_class_type env parent params res in 249 Arrow(lbl, arg, res) 250#if OCAML_VERSION >= (4,8,0) 251 | Tcty_open (_, cty) -> read_class_type env parent params cty 252#elif OCAML_VERSION >= (4,6,0) 253 | Tcty_open (_, _, _, _, cty) -> read_class_type env parent params cty 254#endif 255 256 257let rec read_class_field env parent cf = 258 let open ClassSignature in 259 let open Odoc_model.Names in 260 let container = (parent : Identifier.ClassSignature.t :> Identifier.LabelParent.t) in 261 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container (cf.cf_attributes) in 262 match cf.cf_desc with 263 | Tcf_val({txt = name; _}, mutable_, _, kind, _) -> 264 let open InstanceVariable in 265 let id = Identifier.Mk.instance_variable(parent, InstanceVariableName.make_std name) in 266 let mutable_ = (mutable_ = Mutable) in 267 let virtual_, type_ = 268 match kind with 269 | Tcfk_virtual typ -> 270 true, read_core_type env typ 271 | Tcfk_concrete(_, expr) -> 272 false, Cmi.read_type_expr env expr.exp_type 273 in 274 Some (InstanceVariable {id; doc; mutable_; virtual_; type_}) 275 | Tcf_method({txt = name; _}, private_, kind) -> 276 let open Method in 277 let id = Identifier.Mk.method_(parent, MethodName.make_std name) in 278 let private_ = (private_ = Private) in 279 let virtual_, type_ = 280 match kind with 281 | Tcfk_virtual typ -> 282 true, read_core_type env typ 283 | Tcfk_concrete(_, expr) -> 284 (* Types of concrete methods in class implementation begin 285 with the object as first (implicit) argument, so we 286 must keep only the type after the first arrow. *) 287 let type_ = 288 match Cmi.read_type_expr env expr.exp_type with 289 | Arrow (_, _, t, _, _) -> t 290 | t -> t 291 in 292 false, type_ 293 in 294 Some (Method {id; doc; private_; virtual_; type_}) 295 | Tcf_constraint(_, _) -> mk_class_comment doc 296 | Tcf_inherit(_, cl, _, _, _) -> 297 let expr = read_class_structure env parent [] cl in 298 Some (Inherit {Inherit.expr; doc}) 299 | Tcf_initializer _ -> mk_class_comment doc 300 | Tcf_attribute attr -> 301 match Doc_attr.standalone container ~warnings_tag:env.warnings_tag attr with 302 | None -> None 303 | Some doc -> Some (Comment doc) 304 305and read_class_structure env parent params cl = 306 let open ClassType in 307 match cl.cl_desc with 308 | Tcl_ident _ | Tcl_apply _ -> 309 Cmi.read_class_signature env parent params cl.cl_type 310 | Tcl_structure cstr -> 311 let open ClassSignature in 312 let self = Cmi.read_self_type cstr.cstr_self.pat_type in 313 let constraints = Cmi.read_class_constraints env params in 314 let items = 315 List.fold_left 316 (fun rest item -> 317 match read_class_field env parent item with 318 | None -> rest 319 | Some item -> item :: rest) 320 [] cstr.cstr_fields 321 in 322 let items = constraints @ List.rev items in 323 let items, (doc, doc_post) = Doc_attr.extract_top_comment_class items in 324 let items = 325 match doc_post with 326 | { elements = []; _ } -> items 327 | _ -> Comment (`Docs doc_post) :: items 328 in 329 Signature {self; items; doc} 330 | Tcl_fun _ -> assert false 331 | Tcl_let(_, _, _, cl) -> read_class_structure env parent params cl 332 | Tcl_constraint(cl, None, _, _, _) -> read_class_structure env parent params cl 333 | Tcl_constraint(_, Some cltyp, _, _, _) -> 334 read_class_signature env parent params cltyp 335#if OCAML_VERSION >= (4,8,0) 336 | Tcl_open (_, cl) -> read_class_structure env parent params cl 337#elif OCAML_VERSION >= (4,6,0) 338 | Tcl_open (_, _, _, _, cl) -> read_class_structure env parent params cl 339#endif 340 341 342let rec read_class_expr env parent params cl = 343 let open Class in 344 match cl.cl_desc with 345 | Tcl_ident _ | Tcl_apply _ -> 346 Cmi.read_class_type env parent params cl.cl_type 347 | Tcl_structure _ -> 348 ClassType (read_class_structure env parent params cl) 349 | Tcl_fun(lbl, arg, _, res, _) -> 350 let lbl = Cmi.read_label lbl in 351 let arg = Cmi.read_type_expr env arg.pat_type in 352 let res = read_class_expr env parent params res in 353 Arrow(lbl, arg, res) 354 | Tcl_let(_, _, _, cl) -> 355 read_class_expr env parent params cl 356 | Tcl_constraint(cl, None, _, _, _) -> 357 read_class_expr env parent params cl 358 | Tcl_constraint(_, Some cltyp, _, _, _) -> 359 read_class_type env parent params cltyp 360#if OCAML_VERSION >= (4,8,0) 361 | Tcl_open (_, cl) -> read_class_expr env parent params cl 362#elif OCAML_VERSION >= (4,6,0) 363 | Tcl_open (_, _, _, _, cl) -> read_class_expr env parent params cl 364#endif 365 366let read_class_declaration env parent cld = 367 let open Class in 368 let id = Env.find_class_identifier env.ident_env cld.ci_id_class in 369 let source_loc = None in 370 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 371 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container cld.ci_attributes in 372 Cmi.mark_class_declaration cld.ci_decl; 373 let virtual_ = (cld.ci_virt = Virtual) in 374 let clparams = 375 List.map (fun (ctyp, _) -> ctyp.ctyp_type) cld.ci_params 376 in 377 let params = 378 List.map 379 (Cmi.read_type_parameter false Types.Variance.null) 380 clparams 381 in 382 let type_ = read_class_expr env (id :> Identifier.ClassSignature.t) clparams cld.ci_expr in 383 let source_loc_jane = Some (Odoc_model.Lang.Source_loc_jane.of_location !cmt_builddir cld.ci_loc) in 384 { id; source_loc; doc; virtual_; params; type_; expansion = None ; source_loc_jane} 385 386let read_class_declarations env parent clds = 387 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 388 let open Signature in 389 List.fold_left begin fun (acc, recursive) cld -> 390 let comments = Doc_attr.standalone_multiple container ~warnings_tag:env.warnings_tag cld.ci_attributes in 391 let comments = List.map (fun com -> Comment com) comments in 392 let cld = read_class_declaration env parent cld in 393 ((Class (recursive, cld))::(List.rev_append comments acc), And) 394 end ([], Ordinary) clds 395 |> fst 396 |> List.rev 397 398let rec read_module_expr env parent label_parent mexpr = 399 let open ModuleType in 400 let open Odoc_model.Names in 401 match mexpr.mod_desc with 402 | Tmod_ident _ -> 403 Cmi.read_module_type env parent (Odoc_model.Compat.module_type mexpr.mod_type) 404 | Tmod_structure str -> 405 let sg, () = read_structure Odoc_model.Semantics.Expect_none env parent str in 406 Signature sg 407#if OCAML_VERSION >= (4,10,0) 408 | Tmod_functor(parameter, res) -> 409 let f_parameter, env = 410 match parameter with 411 | Unit -> FunctorParameter.Unit, env 412 | Named (id_opt, _, arg) -> 413 let id, env = 414 match id_opt with 415 | None -> Identifier.Mk.parameter (parent, Odoc_model.Names.ModuleName.make_std "_"), env 416 | Some id -> let e' = Env.add_parameter parent id (ModuleName.of_ident id) env.ident_env in 417 Env.find_parameter_identifier e' id, {env with ident_env=e'} 418 in 419 let arg = Cmti.read_module_type env (id :> Identifier.Signature.t) label_parent arg in 420 421 Named { id; expr=arg }, env 422 in 423 let res = read_module_expr env (Identifier.Mk.result parent) label_parent res in 424 Functor (f_parameter, res) 425#else 426 | Tmod_functor(id, _, arg, res) -> 427 let new_env = Env.add_parameter parent id (ModuleName.of_ident id) env.ident_env in 428 let new_env = {env with ident_env = new_env} in 429 let f_parameter = 430 match arg with 431 | None -> FunctorParameter.Unit 432 | Some arg -> 433 let id = Env.find_parameter_identifier new_env.ident_env id in 434 let arg = Cmti.read_module_type env (id :> Identifier.Signature.t) label_parent arg in 435 Named { FunctorParameter. id; expr = arg; } 436 in 437 let res = read_module_expr new_env (Identifier.Mk.result parent) label_parent res in 438 Functor(f_parameter, res) 439#endif 440 | Tmod_apply _ -> 441 Cmi.read_module_type env parent (Odoc_model.Compat.module_type mexpr.mod_type) 442#if OCAML_VERSION >= (5,1,0) 443 | Tmod_apply_unit _ -> 444 Cmi.read_module_type env parent (Odoc_model.Compat.module_type mexpr.mod_type) 445#endif 446 | Tmod_constraint(_, _, Tmodtype_explicit mty, _) -> 447 Cmti.read_module_type env parent label_parent mty 448 | Tmod_constraint(mexpr, _, Tmodtype_implicit, _) -> 449 read_module_expr env parent label_parent mexpr 450 | Tmod_unpack(_, mty) -> 451 Cmi.read_module_type env parent (Odoc_model.Compat.module_type mty) 452and unwrap_module_expr_desc = function 453 | Tmod_constraint(mexpr, _, Tmodtype_implicit, _) -> 454 unwrap_module_expr_desc mexpr.mod_desc 455 | desc -> desc 456 457(** Like [read_module_expr] but handle the canonical tag in the top-comment. *) 458and read_module_expr_maybe_canonical env parent container ~canonical mexpr = 459 let open ModuleType in 460 match (canonical, mexpr.mod_desc) with 461 | None, Tmod_structure str -> 462 let sg, canonical = 463 read_structure Odoc_model.Semantics.Expect_canonical env parent str 464 in 465 (Signature sg, canonical) 466 | _ -> (read_module_expr env parent container mexpr, canonical) 467 468and read_module_binding env parent mb = 469 let open Module in 470#if OCAML_VERSION >= (4,10,0) 471 match mb.mb_id with 472 | None -> None 473 | Some id -> 474 let mid = Env.find_module_identifier env.ident_env id in 475#else 476 let mid = Env.find_module_identifier env.ident_env mb.mb_id in 477#endif 478 let id = (mid :> Identifier.Module.t) in 479 let source_loc = None in 480 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 481 let doc, canonical = Doc_attr.attached ~warnings_tag:env.warnings_tag Odoc_model.Semantics.Expect_canonical container mb.mb_attributes in 482 let type_, canonical = 483 match unwrap_module_expr_desc mb.mb_expr.mod_desc with 484 | Tmod_ident (p, _) -> (Alias (Env.Path.read_module env.ident_env p, None), canonical) 485 | _ -> 486 let id = (id :> Identifier.Signature.t) in 487 let expr, canonical = 488 read_module_expr_maybe_canonical env id container ~canonical mb.mb_expr 489 in 490 (ModuleType expr, canonical) 491 in 492 let canonical = match canonical with | None -> None | Some s -> Some (Doc_attr.conv_canonical_module s) in 493 let hidden = 494#if OCAML_VERSION >= (4,10,0) 495 match canonical, mid.iv with 496 | None, (`Module (_, n) | `Parameter (_, n) | `Root (_, n)) -> Odoc_model.Names.ModuleName.is_hidden n 497 | Some _, _ -> false 498#else 499 match canonical, mid.iv with 500 | None, (`Module (_, n) | `Parameter (_, n) | `Root (_, n)) -> Odoc_model.Names.ModuleName.is_hidden n 501 | Some _, _ -> false 502#endif 503 in 504 let source_loc_jane = Some (Odoc_model.Lang.Source_loc_jane.of_location !cmt_builddir mb.mb_loc) in 505 Some {id; source_loc; doc; type_; canonical; hidden; source_loc_jane} 506 507and read_module_bindings env parent mbs = 508 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) 509 in 510 let open Signature in 511 List.fold_left 512 (fun (acc, recursive) mb -> 513 let comments = Doc_attr.standalone_multiple container ~warnings_tag:env.warnings_tag mb.mb_attributes in 514 let comments = List.map (fun com -> Comment com) comments in 515 match read_module_binding env parent mb with 516 | Some mb -> 517 ((Module (recursive, mb))::(List.rev_append comments acc), And) 518 | None -> (acc, recursive)) 519 ([], Rec) mbs 520 |> fst 521 |> List.rev 522 523and read_structure_item env parent item = 524 let open Signature in 525 match item.str_desc with 526 | Tstr_eval _ -> [] 527 | Tstr_value(_, vbs) -> 528 read_value_bindings env parent vbs 529 | Tstr_primitive vd -> 530 [Cmti.read_value_description env parent vd] 531#if OCAML_VERSION < (4,3,0) 532 | Tstr_type (decls) -> 533 let rec_flag = Ordinary in 534#else 535 | Tstr_type (rec_flag, decls) -> 536 let rec_flag = 537 match rec_flag with 538 | Recursive -> Ordinary 539 | Nonrecursive -> Nonrec 540 in 541#endif 542 Cmti.read_type_declarations env parent rec_flag decls 543 | Tstr_typext tyext -> 544 [TypExt (read_type_extension env parent tyext)] 545 | Tstr_exception ext -> 546 let ext = 547#if OCAML_VERSION >= (4,8,0) 548 Cmi.read_exception env parent ext.tyexn_constructor.ext_id ext.tyexn_constructor.ext_type 549#else 550 Cmi.read_exception env parent ext.ext_id ext.ext_type 551#endif 552 in 553 [Exception ext] 554 | Tstr_module mb -> begin 555 match read_module_binding env parent mb with 556 | Some mb -> 557 [Module (Ordinary, mb)] 558 | None -> [] 559 end 560 | Tstr_recmodule mbs -> 561 read_module_bindings env parent mbs 562 | Tstr_modtype mtd -> 563 [ModuleType (Cmti.read_module_type_declaration env parent mtd)] 564 | Tstr_open o -> 565 [Open (read_open env parent o)] 566 | Tstr_include incl -> 567 read_include env parent incl 568 | Tstr_class cls -> 569 let cls = List.map 570#if OCAML_VERSION < (4,3,0) 571 (* NOTE(@ostera): remember the virtual flag was removed post 4.02 *) 572 (fun (cl, _, _) -> cl) 573#else 574 (fun (cl, _) -> cl) 575#endif 576 cls in 577 read_class_declarations env parent cls 578 | Tstr_class_type cltyps -> 579 let cltyps = List.map (fun (_, _, clty) -> clty) cltyps in 580 Cmti.read_class_type_declarations env parent cltyps 581 | Tstr_attribute attr -> 582 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 583 match Doc_attr.standalone container ~warnings_tag:env.warnings_tag attr with 584 | None -> [] 585 | Some doc -> [Comment doc] 586 587and read_include env parent incl = 588 let open Include in 589 let loc = Doc_attr.read_location incl.incl_loc in 590 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 591 let doc, status = Doc_attr.attached ~warnings_tag:env.warnings_tag Odoc_model.Semantics.Expect_status container incl.incl_attributes in 592 let decl_modty = 593#if defined OXCAML 594 match unwrap_module_expr_desc incl.incl_mod.mod_desc, incl.incl_kind with 595 | _, (Tincl_functor _ | Tincl_gen_functor _) -> 596 (* TODO: Handle [include functor] *) 597 None 598 | Tmod_ident(p, _), Tincl_structure -> 599#else 600 match unwrap_module_expr_desc incl.incl_mod.mod_desc with 601 | Tmod_ident(p, _) -> 602#endif 603 let p = Env.Path.read_module env.ident_env p in 604 Some (ModuleType.U.TypeOf (ModuleType.StructInclude p, p)) 605 | _ -> 606 let mty = read_module_expr env parent container incl.incl_mod in 607 umty_of_mty mty 608 in 609 let content, shadowed = Cmi.read_signature_noenv env parent (Odoc_model.Compat.signature incl.incl_type) in 610 let expansion = { content; shadowed; } in 611 match decl_modty with 612 | Some m -> 613 let decl = ModuleType m in 614 [Include {parent; doc; decl; expansion; expanded = false; status; strengthened=None; loc }] 615 | _ -> 616 content.items 617 618and read_open env parent o = 619 let container = (parent : Identifier.Signature.t :> Identifier.LabelParent.t) in 620 let doc = Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tag container o.open_attributes in 621 #if OCAML_VERSION >= (4,8,0) 622 let signature = o.open_bound_items in 623 #else 624 let signature = [] in 625 #endif 626 let expansion, _ = Cmi.read_signature_noenv env parent (Odoc_model.Compat.signature signature) in 627 Open.{expansion; doc} 628 629and read_structure : 630 'tags. 'tags Odoc_model.Semantics.handle_internal_tags -> _ -> _ -> _ -> 631 _ * 'tags = 632 fun internal_tags env parent str -> 633 let e' = Env.add_structure_tree_items parent str env.ident_env in 634 let env = { env with ident_env=e' } in 635 let items, (doc, doc_post), tags = 636 let classify item = 637 match item.str_desc with 638 | Tstr_open _ -> Some `Open 639 | Tstr_attribute attr -> Some (`Attribute attr) 640 | _ -> None 641 in 642 Doc_attr.extract_top_comment internal_tags ~warnings_tag:env.warnings_tag ~classify parent str.str_items 643 in 644 let items = 645 List.fold_left 646 (fun items item -> 647 List.rev_append (read_structure_item env parent item) items) 648 [] items 649 |> List.rev 650 in 651 match doc_post with 652 | { elements = [] ; _} -> 653 ({ Signature.items; compiled = false; removed = []; doc }, tags) 654 | _ -> 655 ({ Signature.items = Comment (`Docs doc_post) :: items; compiled=false; removed = []; doc }, tags) 656 657let read_implementation root name ~warnings_tag impl = 658 let id = 659 Identifier.Mk.root (root, Odoc_model.Names.ModuleName.make_std name) 660 in 661 let sg, canonical = 662 read_structure Odoc_model.Semantics.Expect_canonical 663 { ident_env = Env.empty (); warnings_tag } 664 id impl 665 in 666 let canonical = 667 match canonical with 668 | None -> None 669 | Some s -> Some (Doc_attr.conv_canonical_module s) 670 in 671 (id, sg, canonical) 672 673let _ = Cmti.read_module_expr := read_module_expr