this repo has no description
at main 989 lines 36 kB view raw
1(* Phase 1 - compilation *) 2 3(* First round of resolving only attempts to resolve paths and fragments, and then only those 4 that don't contain forward paths *) 5 6open Odoc_model 7open Lang 8module Id = Paths.Identifier 9 10module Opt = struct 11 let map f = function Some x -> Some (f x) | None -> None 12end 13 14let type_path : Env.t -> Paths.Path.Type.t -> Paths.Path.Type.t = 15 fun env p -> 16 match p with 17 | `Resolved _ -> p 18 | _ -> ( 19 let cp = Component.Of_Lang.(type_path (empty ()) p) in 20 match Tools.resolve_type_path env cp with 21 | Ok p' -> `Resolved Lang_of.(Path.resolved_type (empty ()) p') 22 | Error _ -> p) 23 24and value_path : Env.t -> Paths.Path.Value.t -> Paths.Path.Value.t = 25 fun env p -> 26 match p with 27 | `Resolved _ -> p 28 | _ -> ( 29 let cp = Component.Of_Lang.(value_path (empty ()) p) in 30 match Tools.resolve_value_path env cp with 31 | Ok p' -> `Resolved Lang_of.(Path.resolved_value (empty ()) p') 32 | Error _ -> p) 33 34and module_type_path : 35 Env.t -> Paths.Path.ModuleType.t -> Paths.Path.ModuleType.t = 36 fun env p -> 37 match p with 38 | `Resolved _ -> p 39 | _ -> ( 40 let cp = Component.Of_Lang.(module_type_path (empty ()) p) in 41 match Tools.resolve_module_type_path env cp with 42 | Ok p' -> `Resolved Lang_of.(Path.resolved_module_type (empty ()) p') 43 | Error _ -> p) 44 45and module_path : Env.t -> Paths.Path.Module.t -> Paths.Path.Module.t = 46 fun env p -> 47 match p with 48 | `Resolved _ -> p 49 | _ -> ( 50 let cp = Component.Of_Lang.(module_path (empty ()) p) in 51 match Tools.resolve_module_path env cp with 52 | Ok p' -> `Resolved Lang_of.(Path.resolved_module (empty ()) p') 53 | Error _ -> p) 54 55and class_type_path : Env.t -> Paths.Path.ClassType.t -> Paths.Path.ClassType.t 56 = 57 fun env p -> 58 match p with 59 | `Resolved _ -> p 60 | _ -> ( 61 let cp = Component.Of_Lang.(class_type_path (empty ()) p) in 62 match Tools.resolve_class_type_path env cp with 63 | Ok p' -> `Resolved Lang_of.(Path.resolved_class_type (empty ()) p') 64 | Error _ -> p) 65 66let rec unit env t = 67 let open Compilation_unit in 68 { t with content = content env t.id t.content } 69 70and implementation env sp = 71 let open Implementation in 72 { sp with source_info = source_info_infos env sp.source_info } 73 74and source_info_infos env infos = 75 let open Source_info in 76 let map_doc f v = 77 let documentation = 78 match v.documentation with Some p -> Some (f p) | None -> None 79 in 80 { v with documentation } 81 in 82 List.map 83 (function 84 | v, pos -> 85 let v = 86 match v with 87 | Value v -> Value (map_doc (value_path env) v) 88 | Module v -> Module (map_doc (module_path env) v) 89 | ModuleType v -> ModuleType (map_doc (module_type_path env) v) 90 | Type v -> Type (map_doc (type_path env) v) 91 | Definition _ as d -> d 92 in 93 (v, pos)) 94 infos 95 96and content env id = 97 let open Compilation_unit in 98 function 99 | Module sg -> 100 let sg = signature env (id :> Id.Signature.t) sg in 101 Module sg 102 | Pack p -> Pack p 103 104and value_ env parent t = 105 let open Value in 106 let container = (parent :> Id.LabelParent.t) in 107 try { t with type_ = type_expression env container t.type_ } 108 with _ -> 109 Errors.report ~what:(`Value t.id) `Compile; 110 t 111 112and exception_ env parent e = 113 let open Exception in 114 let container = (parent :> Id.LabelParent.t) in 115 let res = Opt.map (type_expression env container) e.res in 116 let args = type_decl_constructor_argument env container e.args in 117 { e with res; args } 118 119and extension env parent t = 120 let open Extension in 121 let container = (parent :> Id.LabelParent.t) in 122 let constructor c = 123 let open Constructor in 124 { 125 c with 126 args = type_decl_constructor_argument env container c.args; 127 res = Opt.map (type_expression env container) c.res; 128 } 129 in 130 let type_path = type_path env t.type_path in 131 let constructors = List.rev_map constructor t.constructors |> List.rev in 132 { t with type_path; constructors } 133 134and class_type_expr env parent = 135 let open ClassType in 136 let container = (parent :> Id.LabelParent.t) in 137 function 138 | Constr (path, texps) -> 139 Constr 140 ( class_type_path env path, 141 List.rev_map (type_expression env container) texps |> List.rev ) 142 | Signature s -> Signature (class_signature env parent s) 143 144and class_type env c = 145 let open ClassType in 146 let expansion = 147 match 148 let open Odoc_utils.OptionMonad in 149 Env.(lookup_by_id s_class_type) c.id env >>= fun (`ClassType (_, c')) -> 150 Tools.class_signature_of_class_type env c' >>= fun sg -> 151 let cs = 152 Lang_of.class_signature (Lang_of.empty ()) 153 (c.id :> Paths.Identifier.Path.ClassType.t) 154 sg 155 in 156 let compiled = class_signature env (c.id :> Id.ClassSignature.t) cs in 157 Some compiled 158 with 159 | Some _ as exp -> exp 160 | None -> 161 Errors.report ~what:(`Class_type c.id) `Expand; 162 c.expansion 163 in 164 { 165 c with 166 expr = class_type_expr env (c.id :> Id.ClassSignature.t) c.expr; 167 expansion; 168 } 169 170and class_signature env parent c = 171 let open ClassSignature in 172 let container = (parent : Id.ClassSignature.t :> Id.LabelParent.t) in 173 let env = Env.open_class_signature c env in 174 let map_item = function 175 | Method m -> Method (method_ env parent m) 176 | InstanceVariable i -> InstanceVariable (instance_variable env parent i) 177 | Constraint cst -> Constraint (class_constraint env container cst) 178 | Inherit ih -> Inherit (inherit_ env parent ih) 179 | Comment c -> Comment c 180 in 181 { 182 c with 183 self = Opt.map (type_expression env container) c.self; 184 items = List.rev_map map_item c.items |> List.rev; 185 } 186 187and method_ env parent m = 188 let open Method in 189 let container = (parent :> Id.LabelParent.t) in 190 { m with type_ = type_expression env container m.type_ } 191 192and instance_variable env parent i = 193 let open InstanceVariable in 194 let container = (parent :> Id.LabelParent.t) in 195 { i with type_ = type_expression env container i.type_ } 196 197and class_constraint env parent cst = 198 let open ClassSignature.Constraint in 199 { 200 cst with 201 left = type_expression env parent cst.left; 202 right = type_expression env parent cst.right; 203 } 204 205and inherit_ env parent ih = 206 let open ClassSignature.Inherit in 207 { ih with expr = class_type_expr env parent ih.expr } 208 209and class_ env parent c = 210 let open Class in 211 let container = (parent :> Id.LabelParent.t) in 212 let expansion = 213 match 214 let open Odoc_utils.OptionMonad in 215 Env.(lookup_by_id s_class) c.id env >>= fun (`Class (_, c')) -> 216 Tools.class_signature_of_class env c' >>= fun sg -> 217 let cs = 218 Lang_of.class_signature (Lang_of.empty ()) 219 (c.id :> Paths.Identifier.Path.ClassType.t) 220 sg 221 in 222 Some (class_signature env (c.id :> Id.ClassSignature.t) cs) 223 with 224 | Some _ as exp -> exp 225 | None -> 226 Errors.report ~what:(`Class c.id) `Expand; 227 c.expansion 228 in 229 let rec map_decl = function 230 | ClassType expr -> 231 ClassType (class_type_expr env (c.id :> Id.ClassSignature.t) expr) 232 | Arrow (lbl, expr, decl) -> 233 Arrow (lbl, type_expression env container expr, map_decl decl) 234 in 235 { c with type_ = map_decl c.type_; expansion } 236 237and module_substitution env m = 238 let open ModuleSubstitution in 239 { m with manifest = module_path env m.manifest } 240 241and signature_items : Env.t -> Id.Signature.t -> Signature.item list -> _ = 242 fun initial_env id s -> 243 let open Signature in 244 let rec loop items env xs = 245 match xs with 246 | [] -> (List.rev items, env) 247 | item :: rest -> ( 248 match item with 249 | Module (Nonrec, _) -> assert false 250 | Module (r, m) -> 251 let add_to_env env m = 252 let ty = 253 Component.Delayed.( 254 put (fun () -> Component.Of_Lang.(module_ (empty ()) m))) 255 in 256 Env.add_module 257 (m.id :> Paths.Identifier.Path.Module.t) 258 ty 259 { elements = []; warnings_tag = None } 260 env 261 in 262 let env = 263 match r with 264 | Nonrec -> assert false 265 | And | Ordinary -> env 266 | Rec -> 267 let rec find modules rest = 268 match rest with 269 | Module (And, m') :: sgs -> find (m' :: modules) sgs 270 | Module (_, _) :: _ -> modules 271 | Comment _ :: sgs -> find modules sgs 272 | _ -> modules 273 in 274 let modules = find [ m ] rest in 275 List.fold_left add_to_env env modules 276 in 277 let m' = module_ env m in 278 let env'' = 279 match r with 280 | Nonrec -> assert false 281 | And | Rec -> env 282 | Ordinary -> add_to_env env m' 283 in 284 loop (Module (r, m') :: items) env'' rest 285 | ModuleSubstitution m -> 286 let env' = Env.open_module_substitution m env in 287 loop 288 (ModuleSubstitution (module_substitution env m) :: items) 289 env' rest 290 | Type (r, t) -> 291 let add_to_env env t = 292 let ty = Component.Of_Lang.(type_decl (empty ()) t) in 293 Env.add_type t.id ty env 294 in 295 let env' = 296 match r with 297 | Rec -> assert false 298 | Ordinary -> 299 let rec find types rest = 300 match rest with 301 | Type (And, t) :: sgs -> find (t :: types) sgs 302 | Type (_, _) :: _ -> types 303 | Comment _ :: sgs -> find types sgs 304 | _ -> types 305 in 306 let types = find [ t ] rest in 307 List.fold_left add_to_env env types 308 | And | Nonrec -> env 309 in 310 let t' = type_decl env' t in 311 let env'' = 312 match r with 313 | Rec -> assert false 314 | Ordinary | And -> env' 315 | Nonrec -> add_to_env env' t' 316 in 317 loop (Type (r, t') :: items) env'' rest 318 | TypeSubstitution t -> 319 let env' = Env.open_type_substitution t env in 320 loop (TypeSubstitution (type_decl env t) :: items) env' rest 321 | ModuleType mt -> 322 let m' = module_type env mt in 323 let ty = Component.Of_Lang.(module_type (empty ()) m') in 324 let env' = Env.add_module_type mt.id ty env in 325 let items' = ModuleType m' :: items in 326 loop items' env' rest 327 | ModuleTypeSubstitution mt -> 328 let env' = Env.open_module_type_substitution mt env in 329 loop 330 (ModuleTypeSubstitution (module_type_substitution env mt) :: items) 331 env' rest 332 | Value v -> loop (Value (value_ env id v) :: items) env rest 333 | Comment c -> loop (Comment c :: items) env rest 334 | TypExt t -> loop (TypExt (extension env id t) :: items) env rest 335 | Exception e -> 336 loop (Exception (exception_ env id e) :: items) env rest 337 | Class (r, c) -> 338 let ty = Component.Of_Lang.(class_ (empty ()) c) in 339 let env' = Env.add_class c.id ty env in 340 let c' = class_ env' id c in 341 loop (Class (r, c') :: items) env' rest 342 | ClassType (r, c) -> 343 let ty = Component.Of_Lang.(class_type (empty ()) c) in 344 let env' = Env.add_class_type c.id ty env in 345 let c' = class_type env' c in 346 loop (ClassType (r, c') :: items) env' rest 347 | Include i -> 348 let i', env' = include_ env i in 349 loop (Include i' :: items) env' rest 350 | Open o -> loop (Open o :: items) env rest) 351 in 352 loop [] initial_env s 353 354and module_type_substitution env mt = 355 let open ModuleTypeSubstitution in 356 { 357 mt with 358 manifest = module_type_expr env (mt.id :> Id.Signature.t) mt.manifest; 359 } 360 361and signature : Env.t -> Id.Signature.t -> Signature.t -> _ = 362 fun env id s -> 363 if s.compiled then s 364 else 365 let items, _ = signature_items env id s.items in 366 { 367 Signature.items; 368 compiled = true; 369 removed = s.removed; 370 doc = s.doc (* comments are ignored while compiling *); 371 } 372 373and module_ : Env.t -> Module.t -> Module.t = 374 fun env m -> 375 let open Module in 376 { m with type_ = module_decl env (m.id :> Id.Signature.t) m.type_ } 377 378and module_decl : Env.t -> Id.Signature.t -> Module.decl -> Module.decl = 379 fun env id decl -> 380 let open Module in 381 match decl with 382 | ModuleType expr -> ModuleType (module_type_expr env id expr) 383 | Alias (p, expn) -> Alias (module_path env p, expn) 384 385and include_decl : Env.t -> Id.Signature.t -> Include.decl -> Include.decl = 386 fun env id decl -> 387 let open Include in 388 match decl with 389 | ModuleType expr -> 390 let rec is_elidable_with_u : Odoc_model.Lang.ModuleType.U.expr -> bool = 391 function 392 | Path _ -> false 393 | Signature _ -> true 394 | With (_, expr) -> is_elidable_with_u expr 395 | TypeOf _ -> false 396 | Strengthen (expr, _, _) -> is_elidable_with_u expr 397 in 398 if is_elidable_with_u expr then ModuleType expr 399 else ModuleType (u_module_type_expr env id expr) 400 | Alias p -> Alias (module_path env p) 401 402and module_type : Env.t -> ModuleType.t -> ModuleType.t = 403 fun env m -> 404 let open ModuleType in 405 let sg_id = (m.id :> Id.Signature.t) in 406 let expr = 407 match m.expr with 408 | None -> None 409 | Some e -> Some (module_type_expr env sg_id ~expand_paths:false e) 410 in 411 { m with expr } 412 413and include_ : Env.t -> Include.t -> Include.t * Env.t = 414 fun env i -> 415 let open Include in 416 let decl = Component.Of_Lang.(include_decl (empty ()) i.decl) in 417 let get_expansion () = 418 match 419 let open Odoc_utils.ResultMonad in 420 match decl with 421 | Alias p -> 422 Tools.expansion_of_module_path env ~strengthen:true p >>= fun exp -> 423 Tools.assert_not_functor exp 424 | ModuleType mty -> Tools.signature_of_u_module_type_expr env mty 425 with 426 | Error e -> 427 Errors.report ~what:(`Include decl) ~tools_error:e `Expand; 428 i.expansion 429 | Ok sg -> 430 let map = Lang_of.with_shadowed i.expansion.shadowed in 431 let sg' = 432 match i.strengthened with 433 | Some p -> 434 let cp = Component.Of_Lang.(module_path (empty ()) p) in 435 Strengthen.signature cp sg 436 | None -> sg 437 in 438 let sg'' = Tools.apply_inner_substs env sg' in 439 let e = Lang_of.(simple_expansion map i.parent (Signature sg'')) in 440 let expansion_sg = 441 match e with 442 | ModuleType.Signature sg -> sg 443 | _ -> 444 failwith "Expansion shouldn't be anything other than a signature" 445 in 446 { i.expansion with content = expansion_sg } 447 in 448 let expansion = 449 if i.expanded then i.expansion 450 else get_expansion () 451 in 452 let items, env' = signature_items env i.parent expansion.content.items in 453 let expansion = 454 { 455 expansion with 456 content = { expansion.content with items; compiled = true }; 457 } 458 in 459 let decl = include_decl env i.parent i.decl in 460 (* After compilation, expanded=true marks includes as "already 461 derived by odoc" — the expansion is authoritative without 462 re-derivation from the decl. Inline Signature decls are stripped 463 as a size optimization since the expansion is shown inline. *) 464 let stripped, decl = 465 match decl with 466 | Include.ModuleType (Signature _) -> 467 true, 468 Include.ModuleType (Signature 469 { items = []; compiled = true; removed = []; doc = i.doc }) 470 | _ -> false, decl 471 in 472 ({ i with decl; expansion; expanded = true }, env') 473 474and simple_expansion : 475 Env.t -> 476 Id.Signature.t -> 477 ModuleType.simple_expansion -> 478 ModuleType.simple_expansion = 479 fun env id e -> 480 match e with 481 | Signature sg -> Signature (signature env id sg) 482 | Functor (param, sg) -> 483 let env' = Env.add_functor_parameter param env in 484 Functor 485 ( functor_parameter env param, 486 simple_expansion env' (Paths.Identifier.Mk.result id) sg ) 487 488and functor_parameter : Env.t -> FunctorParameter.t -> FunctorParameter.t = 489 fun env param -> 490 match param with 491 | Unit -> Unit 492 | Named arg -> Named (functor_parameter_parameter env arg) 493 494and functor_parameter_parameter : 495 Env.t -> FunctorParameter.parameter -> FunctorParameter.parameter = 496 fun env a -> 497 { a with expr = module_type_expr env (a.id :> Id.Signature.t) a.expr } 498 499and module_type_expr_sub id ~fragment_root (sg_res, env, subs) lsub = 500 let open Odoc_utils.ResultMonad in 501 match sg_res with 502 | Error _ -> (sg_res, env, lsub :: subs) 503 | Ok sg -> ( 504 let lang_of_map = Lang_of.with_fragment_root fragment_root in 505 let env = Env.add_fragment_root sg env in 506 let sg_and_sub = 507 match lsub with 508 | Odoc_model.Lang.ModuleType.ModuleEq (frag, decl) -> 509 let cfrag = Component.Of_Lang.(module_fragment (empty ()) frag) in 510 let cfrag', frag' = 511 match 512 Tools.resolve_module_fragment env (fragment_root, sg) cfrag 513 with 514 | Some cfrag' -> 515 ( `Resolved cfrag', 516 `Resolved 517 (Lang_of.Path.resolved_module_fragment lang_of_map cfrag') 518 ) 519 | None -> 520 Errors.report ~what:(`With_module cfrag) `Resolve; 521 (cfrag, frag) 522 in 523 let decl' = module_decl env id decl in 524 let cdecl' = Component.Of_Lang.(module_decl (empty ()) decl') in 525 let resolved_csub = 526 Component.ModuleType.ModuleEq (cfrag', cdecl') 527 in 528 Tools.fragmap env resolved_csub sg >>= fun sg' -> 529 Ok (sg', Odoc_model.Lang.ModuleType.ModuleEq (frag', decl')) 530 | TypeEq (frag, eqn) -> 531 let cfrag = Component.Of_Lang.(type_fragment (empty ()) frag) in 532 let cfrag', frag' = 533 match 534 Tools.resolve_type_fragment env (fragment_root, sg) cfrag 535 with 536 | Some cfrag' -> 537 ( `Resolved cfrag', 538 `Resolved 539 (Lang_of.Path.resolved_type_fragment lang_of_map cfrag') 540 ) 541 | None -> 542 Errors.report ~what:(`With_type cfrag) `Compile; 543 (cfrag, frag) 544 in 545 let eqn' = type_decl_equation env (id :> Id.LabelParent.t) eqn in 546 let ceqn' = Component.Of_Lang.(type_equation (empty ()) eqn') in 547 Tools.fragmap env (Component.ModuleType.TypeEq (cfrag', ceqn')) sg 548 >>= fun sg' -> 549 Ok (sg', Odoc_model.Lang.ModuleType.TypeEq (frag', eqn')) 550 | ModuleSubst (frag, mpath) -> 551 let cfrag = Component.Of_Lang.(module_fragment (empty ()) frag) in 552 let cfrag', frag' = 553 match 554 Tools.resolve_module_fragment env (fragment_root, sg) cfrag 555 with 556 | Some cfrag -> 557 ( `Resolved cfrag, 558 `Resolved 559 (Lang_of.Path.resolved_module_fragment lang_of_map cfrag) 560 ) 561 | None -> 562 Errors.report ~what:(`With_module cfrag) `Resolve; 563 (cfrag, frag) 564 in 565 let mpath' = module_path env mpath in 566 let cmpath' = Component.Of_Lang.(module_path (empty ()) mpath') in 567 Tools.fragmap env 568 (Component.ModuleType.ModuleSubst (cfrag', cmpath')) 569 sg 570 >>= fun sg' -> 571 Ok (sg', Odoc_model.Lang.ModuleType.ModuleSubst (frag', mpath')) 572 | TypeSubst (frag, eqn) -> 573 let cfrag = Component.Of_Lang.(type_fragment (empty ()) frag) in 574 let cfrag', frag' = 575 match 576 Tools.resolve_type_fragment env (fragment_root, sg) cfrag 577 with 578 | Some cfrag -> 579 ( `Resolved cfrag, 580 `Resolved 581 (Lang_of.Path.resolved_type_fragment lang_of_map cfrag) ) 582 | None -> 583 Errors.report ~what:(`With_type cfrag) `Compile; 584 (cfrag, frag) 585 in 586 let eqn' = type_decl_equation env (id :> Id.LabelParent.t) eqn in 587 let ceqn' = Component.Of_Lang.(type_equation (empty ()) eqn') in 588 Tools.fragmap env 589 (Component.ModuleType.TypeSubst (cfrag', ceqn')) 590 sg 591 >>= fun sg' -> 592 Ok (sg', Odoc_model.Lang.ModuleType.TypeSubst (frag', eqn')) 593 | ModuleTypeEq (frag, mty) -> 594 let cfrag = 595 Component.Of_Lang.(module_type_fragment (empty ()) frag) 596 in 597 let cfrag', frag' = 598 match 599 Tools.resolve_module_type_fragment env (fragment_root, sg) cfrag 600 with 601 | Some cfrag' -> 602 ( `Resolved cfrag', 603 `Resolved 604 (Lang_of.Path.resolved_module_type_fragment lang_of_map 605 cfrag') ) 606 | None -> 607 Errors.report ~what:(`With_module_type cfrag) `Resolve; 608 (cfrag, frag) 609 in 610 let mty = module_type_expr env id mty in 611 let mty' = Component.Of_Lang.(module_type_expr (empty ()) mty) in 612 let resolved_csub = 613 Component.ModuleType.ModuleTypeEq (cfrag', mty') 614 in 615 Tools.fragmap env resolved_csub sg >>= fun sg' -> 616 Ok (sg', Odoc_model.Lang.ModuleType.ModuleTypeEq (frag', mty)) 617 | Odoc_model.Lang.ModuleType.ModuleTypeSubst (frag, mty) -> 618 let cfrag = 619 Component.Of_Lang.(module_type_fragment (empty ()) frag) 620 in 621 let cfrag', frag' = 622 match 623 Tools.resolve_module_type_fragment env (fragment_root, sg) cfrag 624 with 625 | Some cfrag' -> 626 ( `Resolved cfrag', 627 `Resolved 628 (Lang_of.Path.resolved_module_type_fragment lang_of_map 629 cfrag') ) 630 | None -> 631 Errors.report ~what:(`With_module_type cfrag) `Resolve; 632 (cfrag, frag) 633 in 634 let mty = module_type_expr env id mty in 635 let mty' = Component.Of_Lang.(module_type_expr (empty ()) mty) in 636 let resolved_csub = 637 Component.ModuleType.ModuleTypeSubst (cfrag', mty') 638 in 639 Tools.fragmap env resolved_csub sg >>= fun sg' -> 640 Ok (sg', Odoc_model.Lang.ModuleType.ModuleTypeSubst (frag', mty)) 641 in 642 643 match sg_and_sub with 644 | Ok (sg', sub') -> (Ok sg', env, sub' :: subs) 645 | Error _ -> (sg_res, env, lsub :: subs)) 646 647and module_type_map_subs env id cexpr subs = 648 let rec find_parent : Component.ModuleType.U.expr -> Cfrag.root option = 649 fun expr -> 650 match expr with 651 | Component.ModuleType.U.Signature _ -> None 652 | Path (`Resolved p) -> Some (`ModuleType p) 653 | Path _ -> None 654 | With (_, e) -> find_parent e 655 | TypeOf (ModPath (`Resolved p), _) | TypeOf (StructInclude (`Resolved p), _) 656 -> 657 Some (`Module p) 658 | TypeOf _ -> None 659 | Strengthen (e, _, _) -> find_parent e 660 in 661 match find_parent cexpr with 662 | None -> None 663 | Some parent -> ( 664 match Tools.signature_of_u_module_type_expr env cexpr with 665 | Error e -> 666 Errors.report ~what:(`Module_type id) ~tools_error:e `Lookup; 667 None 668 | Ok sg -> 669 let fragment_root = 670 match parent with (`ModuleType _ | `Module _) as x -> x 671 in 672 let _, _, subs = 673 List.fold_left 674 (module_type_expr_sub (id :> Id.Signature.t) ~fragment_root) 675 (Ok sg, env, []) subs 676 in 677 let subs = List.rev subs in 678 Some subs) 679 680and u_module_type_expr : 681 Env.t -> Id.Signature.t -> ModuleType.U.expr -> ModuleType.U.expr = 682 fun env id expr -> 683 let open ModuleType in 684 let rec inner : U.expr -> U.expr = function 685 | Signature s -> Signature s 686 | Path p -> Path (module_type_path env p) 687 | With (subs, expr) -> 688 let expr' = inner expr in 689 let cexpr = Component.Of_Lang.(u_module_type_expr (empty ()) expr') in 690 let subs' = 691 match module_type_map_subs env id cexpr subs with 692 | Some s -> s 693 | None -> subs 694 in 695 let result : ModuleType.U.expr = With (subs', expr') in 696 result 697 | TypeOf (t_desc, t_original_path) -> 698 let t_desc = 699 match t_desc with 700 | ModPath p -> ModPath (module_path env p) 701 | StructInclude p -> StructInclude (module_path env p) 702 in 703 TypeOf (t_desc, t_original_path) 704 | Strengthen (expr, path, aliasable) -> 705 Strengthen (inner expr, module_path env path, aliasable) 706 in 707 inner expr 708 709and module_type_expr : 710 Env.t -> 711 Id.Signature.t -> 712 ?expand_paths:bool -> 713 ModuleType.expr -> 714 ModuleType.expr = 715 fun env id ?(expand_paths = true) expr -> 716 let open Odoc_utils.ResultMonad in 717 let get_expansion cur e = 718 match cur with 719 | Some e -> Some (simple_expansion env id e) 720 | None -> ( 721 let ce = Component.Of_Lang.(module_type_expr (empty ()) e) in 722 match 723 Tools.expansion_of_module_type_expr env ce 724 >>= Expand_tools.handle_expansion env id 725 with 726 | Ok (_, ce) -> 727 let e = Lang_of.simple_expansion (Lang_of.empty ()) id ce in 728 Some (simple_expansion env id e) 729 | Error `OpaqueModule -> None 730 | Error e -> 731 Errors.report ~what:(`Module_type_expr ce) ~tools_error:e `Expand; 732 None) 733 in 734 match expr with 735 | Signature s -> Signature (signature env id s) 736 | Path { p_path; p_expansion } as e -> 737 let p_expansion = 738 if expand_paths then get_expansion p_expansion e else p_expansion 739 in 740 Path { p_path = module_type_path env p_path; p_expansion } 741 | With { w_substitutions; w_expansion; w_expr } as e -> ( 742 let w_expansion = get_expansion w_expansion e in 743 let rec all_withs = function 744 | ModuleType.U.With (_, e) -> all_withs e 745 | Signature _ -> true 746 | _ -> false 747 in 748 match (all_withs w_expr, w_expansion) with 749 | true, Some (Signature e) -> Signature e 750 | _ -> ( 751 let w_expr = u_module_type_expr env id w_expr in 752 let cexpr = 753 Component.Of_Lang.(u_module_type_expr (empty ()) w_expr) 754 in 755 let subs' = module_type_map_subs env id cexpr w_substitutions in 756 match subs' with 757 | None -> With { w_substitutions; w_expansion; w_expr } 758 | Some s -> With { w_substitutions = s; w_expansion; w_expr })) 759 | Functor (param, res) -> 760 let param' = functor_parameter env param in 761 let env' = Env.add_functor_parameter param env in 762 let res' = module_type_expr env' (Paths.Identifier.Mk.result id) res in 763 Functor (param', res') 764 | TypeOf { t_desc; t_original_path; t_expansion } as e -> 765 let t_expansion = get_expansion t_expansion e in 766 let t_desc = 767 match t_desc with 768 | ModPath p -> ModuleType.ModPath (module_path env p) 769 | StructInclude p -> StructInclude (module_path env p) 770 in 771 TypeOf { t_desc; t_original_path; t_expansion } 772 | Strengthen { s_expr; s_path; s_aliasable; s_expansion } as e -> 773 let s_expansion = get_expansion s_expansion e in 774 let s_expr = u_module_type_expr env id s_expr in 775 let s_path = module_path env s_path in 776 Strengthen { s_expr; s_path; s_aliasable; s_expansion } 777 778and type_decl : Env.t -> TypeDecl.t -> TypeDecl.t = 779 fun env t -> 780 let open TypeDecl in 781 let container = 782 match t.id.iv with `Type (parent, _) -> (parent :> Id.LabelParent.t) 783 in 784 let equation = type_decl_equation env container t.equation in 785 let representation = 786 Opt.map (type_decl_representation env container) t.representation 787 in 788 { t with equation; representation } 789 790and type_decl_equation : 791 Env.t -> Id.LabelParent.t -> TypeDecl.Equation.t -> TypeDecl.Equation.t = 792 fun env parent t -> 793 let open TypeDecl.Equation in 794 let manifest = Opt.map (type_expression env parent) t.manifest in 795 let constraints = 796 List.map 797 (fun (tex1, tex2) -> 798 (type_expression env parent tex1, type_expression env parent tex2)) 799 t.constraints 800 in 801 { t with manifest; constraints } 802 803and type_decl_representation : 804 Env.t -> 805 Id.LabelParent.t -> 806 TypeDecl.Representation.t -> 807 TypeDecl.Representation.t = 808 fun env parent r -> 809 let open TypeDecl.Representation in 810 match r with 811 | Variant cs -> Variant (List.map (type_decl_constructor env parent) cs) 812 | Record fs -> Record (List.map (type_decl_field env parent) fs) 813 | Record_unboxed_product fs -> 814 Record_unboxed_product (List.map (type_decl_unboxed_field env parent) fs) 815 | Extensible -> Extensible 816 817and type_decl_field env parent f = 818 let open TypeDecl.Field in 819 { f with type_ = type_expression env parent f.type_ } 820 821and type_decl_unboxed_field env parent f = 822 let open TypeDecl.UnboxedField in 823 { f with type_ = type_expression env parent f.type_ } 824 825and type_decl_constructor_argument env parent c = 826 let open TypeDecl.Constructor in 827 match c with 828 | Tuple ts -> Tuple (List.map (type_expression env parent) ts) 829 | Record fs -> Record (List.map (type_decl_field env parent) fs) 830 831and type_decl_constructor : 832 Env.t -> 833 Id.LabelParent.t -> 834 TypeDecl.Constructor.t -> 835 TypeDecl.Constructor.t = 836 fun env parent c -> 837 let open TypeDecl.Constructor in 838 let args = type_decl_constructor_argument env parent c.args in 839 let res = Opt.map (type_expression env parent) c.res in 840 { c with args; res } 841 842and type_expression_polyvar env parent v = 843 let open TypeExpr.Polymorphic_variant in 844 let constructor c = 845 let open Constructor in 846 { c with arguments = List.map (type_expression env parent) c.arguments } 847 in 848 let element = function 849 | Type t -> Type (type_expression env parent t) 850 | Constructor c -> Constructor (constructor c) 851 in 852 { v with elements = List.map element v.elements } 853 854and type_expression_object env parent o = 855 let open TypeExpr.Object in 856 let method_ m = { m with type_ = type_expression env parent m.type_ } in 857 let field = function 858 | Method m -> Method (method_ m) 859 | Inherit t -> Inherit (type_expression env parent t) 860 in 861 { o with fields = List.map field o.fields } 862 863and type_expression_package env parent p = 864 let open TypeExpr.Package in 865 let cp = Component.Of_Lang.(module_type_path (empty ()) p.path) in 866 match Tools.resolve_module_type env cp with 867 | Ok (path, mt) -> ( 868 match p.substitutions with 869 | [] -> 870 (* No substitutions, don't need to try to resolve them *) 871 { path = module_type_path env p.path; substitutions = [] } 872 | _ -> ( 873 match Tools.expansion_of_module_type env mt with 874 | Error e -> 875 Errors.report ~what:(`Package cp) ~tools_error:e `Lookup; 876 p 877 | Ok (Functor _) -> 878 failwith "Type expression package of functor with substitutions!" 879 | Ok (Signature sg) -> 880 let substitution (frag, t) = 881 let cfrag = Component.Of_Lang.(type_fragment (empty ()) frag) in 882 let frag' = 883 match 884 Tools.resolve_type_fragment env (`ModuleType path, sg) cfrag 885 with 886 | Some cfrag' -> 887 `Resolved 888 (Lang_of.(Path.resolved_type_fragment (empty ())) 889 cfrag') 890 | None -> 891 Errors.report ~what:(`Type cfrag) `Compile; 892 frag 893 in 894 (frag', type_expression env parent t) 895 in 896 { 897 path = module_type_path env p.path; 898 substitutions = List.map substitution p.substitutions; 899 })) 900 | Error _ -> { p with path = Lang_of.(Path.module_type (empty ()) cp) } 901 902and handle_arrow : 903 Env.t -> 904 Id.Id.label_parent -> 905 TypeExpr.label option -> 906 TypeExpr.t -> 907 TypeExpr.t -> 908 string list -> 909 string list -> 910 TypeExpr.t = 911 fun env parent lbl t1 t2 modes ret_modes -> 912 let t2' = type_expression env parent t2 in 913 match lbl with 914 | Some (Optional _ | Label _) | None -> 915 Arrow (lbl, type_expression env parent t1, t2', modes, ret_modes) 916 | Some (RawOptional s) -> ( 917 (* s is definitely an option type, but not _obviously_ so. *) 918 match Component.Of_Lang.(type_expression (empty ()) t1) with 919 | Constr (p, _ts) -> ( 920 (* This handles only the simplest case *) 921 let find_option t = 922 match Tools.resolve_type env t with 923 | Ok (_, `FType (_n, decl)) -> ( 924 match decl.equation.manifest with 925 | Some (Constr (`Resolved (`CoreType n), [ t ])) 926 when Names.TypeName.to_string n = "option" -> 927 let t = Lang_of.(type_expr (empty ()) parent t) in 928 Some t 929 | Some _ -> None 930 | None -> None) 931 | Ok (_, `CoreType _) -> None 932 | Ok (_, (`FClass _ | `FClassType _ | `FType_removed _)) -> None 933 | Error _ -> None 934 in 935 match find_option p with 936 | Some t1 -> 937 Arrow (Some (Optional s), type_expression env parent t1, t2', modes, ret_modes) 938 | None -> 939 Arrow (Some (RawOptional s), type_expression env parent t1, t2', modes, ret_modes)) 940 | _ -> Arrow (Some (RawOptional s), type_expression env parent t1, t2', modes, ret_modes)) 941 942and type_expression : Env.t -> Id.LabelParent.t -> _ -> _ = 943 fun env parent texpr -> 944 let open TypeExpr in 945 match texpr with 946 | Var _ | Any -> texpr 947 | Alias (t, str) -> Alias (type_expression env parent t, str) 948 | Arrow (lbl, t1, t2, modes, ret_modes) -> handle_arrow env parent lbl t1 t2 modes ret_modes 949 | Tuple ts -> 950 Tuple 951 (List.map (fun (lbl, ty) -> (lbl, type_expression env parent ty)) ts) 952 | Unboxed_tuple ts -> 953 Unboxed_tuple (List.map (fun (l, t) -> l, type_expression env parent t) ts) 954 | Constr (path, ts') -> ( 955 let cp = Component.Of_Lang.(type_path (empty ()) path) in 956 let ts = List.map (type_expression env parent) ts' in 957 match Tools.resolve_type env cp with 958 | Ok (cp, (`FType _ | `FClass _ | `FClassType _ | `CoreType _)) -> 959 let p = Lang_of.(Path.resolved_type (empty ()) cp) in 960 Constr (`Resolved p, ts) 961 | Ok (_cp, `FType_removed (_, x, _eq)) -> 962 (* Substitute type variables ? *) 963 Lang_of.(type_expr (empty ()) parent x) 964 | Error _e -> 965 Constr ((Lang_of.(Path.type_ (empty ()) cp) :> Paths.Path.Type.t), ts) 966 ) 967 | Polymorphic_variant v -> 968 Polymorphic_variant (type_expression_polyvar env parent v) 969 | Object o -> Object (type_expression_object env parent o) 970 | Class (path, ts) -> ( 971 let ts' = List.map (type_expression env parent) ts in 972 let cp = Component.Of_Lang.(class_type_path (empty ()) path) in 973 match Tools.resolve_class_type env cp with 974 | Ok (cp, (`FClass _ | `FClassType _)) -> 975 let p = Lang_of.(Path.resolved_class_type (empty ()) cp) in 976 Class (`Resolved p, ts') 977 | _ -> Class (path, ts')) 978 | Poly (strs, t) -> Poly (strs, type_expression env parent t) 979 | Quote t -> Quote (type_expression env parent t) 980 | Splice t -> Splice (type_expression env parent t) 981 | Package p -> Package (type_expression_package env parent p) 982 983let compile ~filename env compilation_unit = 984 Lookup_failures.catch_failures ~filename (fun () -> unit env compilation_unit) 985 986let compile_impl ~filename env i = 987 Lookup_failures.catch_failures ~filename (fun () -> implementation env i) 988 989let resolve_page _resolver y = y