this repo has no description
at main 1316 lines 48 kB view raw
1(* Second round of resolution tackles references and forward paths *) 2open Odoc_model 3open Lang 4module Id = Paths.Identifier 5 6module Opt = struct 7 let map f = function Some x -> Some (f x) | None -> None 8end 9 10(* omg. Our current warning system is spread on different system. Hence this 11 atrocity. *) 12let maybe_suppress env warnings_tag = 13 if Env.should_suppress_warnings env warnings_tag then fun f -> 14 Lookup_failures.catch_failures ~filename:"" (fun () -> 15 Error.catch_warnings f |> fun x -> 16 Error.unpack_warnings x |> fst |> Error.unpack_warnings |> fst) 17 |> Error.unpack_warnings |> fst 18 else fun f -> f () |> Error.raise_warnings 19 20let source_loc env id loc = 21 let id = (id :> Id.NonSrc.t) in 22 match loc with Some _ as loc -> loc | None -> Shape_tools.lookup_def env id 23 24(** Equivalent to {!Comment.synopsis}. *) 25let synopsis_from_comment (docs : Component.CComment.docs) = 26 match docs.elements with 27 | ({ value = #Comment.nestable_block_element; _ } as e) :: _ -> 28 (* Only the first element is considered. *) 29 Comment.synopsis [ e ] 30 | _ -> None 31 32let synopsis_of_module env (m : Component.Module.t) = 33 let open Odoc_utils.ResultMonad in 34 match synopsis_from_comment m.doc with 35 | Some _ as s -> s 36 | None -> ( 37 let rec handle_expansion : Tools.expansion -> _ = function 38 | Functor (_, expr) -> ( 39 match Tools.expansion_of_module_type_expr env expr with 40 | Ok e -> handle_expansion e 41 | Error _ as e -> e) 42 | Signature sg -> Ok sg 43 in 44 (* If there is no doc, look at the expansion. *) 45 match 46 Tools.expansion_of_module env m >>= fun exp -> handle_expansion exp 47 with 48 | Ok sg -> synopsis_from_comment (Component.extract_signature_doc sg) 49 | Error _ -> None) 50 51let ambiguous_label_warning label_name labels = 52 let pp_label_loc fmt (`Label (_, x)) = 53 Location_.pp_span_start fmt x.Component.Label.location 54 in 55 Lookup_failures.report_warning 56 "@[<2>Label '%s' is ambiguous. The other occurences are:@ %a@]" label_name 57 (Format.pp_print_list ~pp_sep:Format.pp_force_newline pp_label_loc) 58 labels 59 60(** Raise a warning when a label explicitly set by the user collides. This 61 warning triggers even if one of the colliding labels have been automatically 62 generated. *) 63let check_ambiguous_label ~loc env 64 ( attrs, 65 ({ Odoc_model.Paths.Identifier.iv = `Label (_, label_name); _ } as id), 66 _ ) = 67 if attrs.Comment.heading_label_explicit then 68 (* Looking for an identical identifier but a different location. *) 69 let conflicting (`Label (id', comp)) = 70 Id.equal id id' 71 && not (Location_.span_equal comp.Component.Label.location loc) 72 in 73 let label_name = Names.LabelName.to_string label_name in 74 match Env.lookup_by_name Env.s_label label_name env with 75 | Ok lbl when conflicting lbl -> ambiguous_label_warning label_name [ lbl ] 76 | Error (`Ambiguous (hd, tl)) -> ( 77 match List.filter conflicting (hd :: tl) with 78 | [] -> () 79 | xs -> ambiguous_label_warning label_name xs) 80 | Ok _ | Error `Not_found -> () 81 82let expansion_needed self target = 83 let self = (self :> Paths.Path.Resolved.t) in 84 let hidden_alias = Paths.Path.Resolved.is_hidden self 85 and self_canonical = 86 let i = Paths.Path.Resolved.identifier self in 87 i = Some (target :> Paths.Identifier.t) 88 in 89 90 self_canonical || hidden_alias 91 92exception Loop 93 94let rec is_forward : Paths.Path.Module.t -> bool = function 95 | `Resolved _ -> false 96 | `Root _ -> false 97 | `Forward _ -> true 98 | `Identifier _ -> false 99 | `Dot (p, _) -> is_forward p 100 | `Apply (p1, p2) -> is_forward p1 || is_forward p2 101 | `Substituted s -> is_forward s 102 103let rec should_reresolve : Paths.Path.Resolved.t -> bool = 104 fun p -> 105 let open Paths.Path.Resolved in 106 match p with 107 | `CoreType _ -> false 108 | `Identifier _ -> false 109 | `Subst (x, y) -> should_reresolve (x :> t) || should_reresolve (y :> t) 110 | `Hidden p -> should_reresolve (p :> t) 111 | `Canonical (x, y) -> 112 should_reresolve (x :> t) || should_resolve (y :> Paths.Path.t) 113 | `CanonicalModuleType (x, y) -> 114 should_reresolve (x :> t) || should_resolve (y :> Paths.Path.t) 115 | `CanonicalType (x, y) -> 116 should_reresolve (x :> t) || should_resolve (y :> Paths.Path.t) 117 | `Apply (x, y) -> 118 should_reresolve (x :> t) || should_reresolve (y :> Paths.Path.Resolved.t) 119 | `SubstT (x, y) -> should_reresolve (x :> t) || should_reresolve (y :> t) 120 | `Alias (y, x) -> 121 should_resolve (x :> Paths.Path.t) || should_reresolve (y :> t) 122 | `AliasModuleType (x, y) -> 123 should_reresolve (x :> t) || should_reresolve (y :> t) 124 | `Type (p, _) 125 | `Value (p, _) 126 | `Class (p, _) 127 | `ClassType (p, _) 128 | `ModuleType (p, _) 129 | `Module (p, _) -> 130 should_reresolve (p :> t) 131 | `OpaqueModule m -> should_reresolve (m :> t) 132 | `OpaqueModuleType m -> should_reresolve (m :> t) 133 | `Substituted m -> should_reresolve (m :> t) 134 | `SubstitutedMT m -> should_reresolve (m :> t) 135 | `SubstitutedT m -> should_reresolve (m :> t) 136 | `SubstitutedCT m -> should_reresolve (m :> t) 137 138and should_resolve : Paths.Path.t -> bool = 139 fun p -> match p with `Resolved p -> should_reresolve p | _ -> true 140 141let type_path : Env.t -> Paths.Path.Type.t -> Paths.Path.Type.t = 142 fun env p -> 143 if not (should_resolve (p :> Paths.Path.t)) then p 144 else 145 let cp = Component.Of_Lang.(type_path (empty ()) p) in 146 match cp with 147 | `Resolved p -> 148 let result = Tools.reresolve_type env p in 149 `Resolved Lang_of.(Path.resolved_type (empty ()) result) 150 | _ -> ( 151 match Tools.resolve_type_path env cp with 152 | Ok p' -> 153 let result = Tools.reresolve_type env p' in 154 `Resolved Lang_of.(Path.resolved_type (empty ()) result) 155 | Error e -> 156 Errors.report ~what:(`Type_path cp) ~tools_error:e `Lookup; 157 p) 158 159let value_path : Env.t -> Paths.Path.Value.t -> Paths.Path.Value.t = 160 fun env p -> 161 if not (should_resolve (p :> Paths.Path.t)) then p 162 else 163 let cp = Component.Of_Lang.(value_path (empty ()) p) in 164 match cp with 165 | `Resolved p -> 166 let result = Tools.reresolve_value env p in 167 `Resolved Lang_of.(Path.resolved_value (empty ()) result) 168 | _ -> ( 169 match Tools.resolve_value_path env cp with 170 | Ok p' -> 171 let result = Tools.reresolve_value env p' in 172 `Resolved Lang_of.(Path.resolved_value (empty ()) result) 173 | Error e -> 174 Errors.report ~what:(`Value_path cp) ~tools_error:e `Lookup; 175 p) 176 177let class_type_path : Env.t -> Paths.Path.ClassType.t -> Paths.Path.ClassType.t 178 = 179 fun env p -> 180 if not (should_resolve (p :> Paths.Path.t)) then p 181 else 182 let cp = Component.Of_Lang.(class_type_path (empty ()) p) in 183 match cp with 184 | `Resolved p -> 185 let result = Tools.reresolve_class_type env p in 186 `Resolved Lang_of.(Path.resolved_class_type (empty ()) result) 187 | _ -> ( 188 match Tools.resolve_class_type_path env cp with 189 | Ok p' -> 190 let result = Tools.reresolve_class_type env p' in 191 `Resolved Lang_of.(Path.resolved_class_type (empty ()) result) 192 | Error e -> 193 Errors.report ~what:(`Class_type_path cp) ~tools_error:e `Lookup; 194 p) 195 196and module_type_path : 197 Env.t -> Paths.Path.ModuleType.t -> Paths.Path.ModuleType.t = 198 fun env p -> 199 if not (should_resolve (p :> Paths.Path.t)) then p 200 else 201 let cp = Component.Of_Lang.(module_type_path (empty ()) p) in 202 match cp with 203 | `Resolved p -> 204 let result = Tools.reresolve_module_type env p in 205 `Resolved Lang_of.(Path.resolved_module_type (empty ()) result) 206 | _ -> ( 207 match Tools.resolve_module_type_path env cp with 208 | Ok p' -> 209 let result = Tools.reresolve_module_type env p' in 210 `Resolved Lang_of.(Path.resolved_module_type (empty ()) result) 211 | Error e -> 212 Errors.report ~what:(`Module_type_path cp) ~tools_error:e `Resolve; 213 p) 214 215and module_path : Env.t -> Paths.Path.Module.t -> Paths.Path.Module.t = 216 fun env p -> 217 if not (should_resolve (p :> Paths.Path.t)) then p 218 else 219 let cp = Component.Of_Lang.(module_path (empty ()) p) in 220 match cp with 221 | `Resolved p -> 222 let after = Tools.reresolve_module env p in 223 `Resolved Lang_of.(Path.resolved_module (empty ()) after) 224 | _ -> ( 225 match Tools.resolve_module_path env cp with 226 | Ok p' -> 227 let result = Tools.reresolve_module env p' in 228 `Resolved Lang_of.(Path.resolved_module (empty ()) result) 229 | Error _ when is_forward p -> p 230 | Error e -> 231 Errors.report ~what:(`Module_path cp) ~tools_error:e `Resolve; 232 p) 233 234let rec comment_inline_element : 235 loc:_ -> 236 Env.t -> 237 string option -> 238 Comment.inline_element -> 239 Comment.inline_element = 240 fun ~loc:_ env warnings_tag x -> 241 match x with 242 | `Styled (s, ls) -> 243 `Styled 244 ( s, 245 List.map (with_location (comment_inline_element env warnings_tag)) ls 246 ) 247 | `Reference (r, content) as orig -> ( 248 match 249 maybe_suppress env warnings_tag (fun () -> 250 Ref_tools.resolve_reference env r) 251 with 252 | Ok (ref_, c) -> 253 let content = 254 (* In case of labels, use the heading text as reference text if 255 it's not specified. *) 256 match (content, c) with 257 | [], Some content -> 258 Comment.link_content_of_inline_elements content 259 | content, _ -> content 260 in 261 `Reference (`Resolved ref_, content) 262 | Error e -> 263 if not (Env.should_suppress_warnings env warnings_tag) then 264 Errors.report ~what:(`Reference r) ~tools_error:(`Reference e) 265 `Resolve; 266 orig) 267 | y -> y 268 269and paragraph env warnings_tag elts = 270 List.map (with_location (comment_inline_element env warnings_tag)) elts 271 272and resolve_external_synopsis env warnings_tag synopsis = 273 let env = Env.inherit_resolver env in 274 paragraph env warnings_tag synopsis 275 276and comment_nestable_block_element env warnings_tag parent ~loc:_ 277 (x : Comment.nestable_block_element) = 278 match x with 279 | `Paragraph elts -> `Paragraph (paragraph env warnings_tag elts) 280 | (`Code_block _ | `Math_block _ | `Verbatim _) as x -> x 281 | `List (x, ys) -> 282 `List 283 ( x, 284 List.rev_map 285 (comment_nestable_block_element_list env warnings_tag parent) 286 ys 287 |> List.rev ) 288 | `Table { data; align } -> 289 let data = 290 let map f x = List.rev_map f x |> List.rev in 291 map 292 (map (fun (cell, cell_type) -> 293 ( comment_nestable_block_element_list env warnings_tag parent cell, 294 cell_type ))) 295 data 296 in 297 `Table { Comment.data; align } 298 | `Modules refs -> 299 let refs = 300 List.rev_map 301 (fun (r : Comment.module_reference) -> 302 match 303 maybe_suppress env warnings_tag (fun () -> 304 Ref_tools.resolve_module_reference env r.module_reference) 305 with 306 | Ok (r, _, m) -> 307 let module_synopsis = 308 Opt.map 309 (resolve_external_synopsis env warnings_tag) 310 (synopsis_of_module env m) 311 in 312 { Comment.module_reference = `Resolved r; module_synopsis } 313 | Error e -> 314 if not (Env.should_suppress_warnings env warnings_tag) then 315 Errors.report 316 ~what:(`Reference (r.module_reference :> Paths.Reference.t)) 317 ~tools_error:(`Reference e) `Resolve; 318 r) 319 refs 320 |> List.rev 321 in 322 `Modules refs 323 | `Media (`Reference r, m, content) as orig -> ( 324 match 325 maybe_suppress env warnings_tag (fun () -> 326 Ref_tools.resolve_asset_reference env r) 327 with 328 | Ok x -> `Media (`Reference (`Resolved x), m, content) 329 | Error e -> 330 if not (Env.should_suppress_warnings env warnings_tag) then 331 Errors.report 332 ~what:(`Reference (r :> Paths.Reference.t)) 333 ~tools_error:(`Reference e) `Resolve; 334 orig) 335 | `Media _ as orig -> orig 336 337and comment_nestable_block_element_list env warnings_tag parent 338 (xs : Comment.nestable_block_element Comment.with_location list) = 339 List.rev_map 340 (with_location (comment_nestable_block_element env warnings_tag parent)) 341 xs 342 |> List.rev 343 344and comment_tag env warnings_tag parent ~loc:_ (x : Comment.tag) = 345 match x with 346 | `Custom (name, content) -> 347 let resolved = 348 comment_nestable_block_element_list env warnings_tag parent content 349 in 350 let prefix = Odoc_extension_registry.prefix_of_tag name in 351 let content = 352 match Odoc_extension_registry.find_link_handler ~prefix with 353 | Some handler -> handler name (Obj.repr env) resolved 354 | None -> resolved 355 in 356 `Custom (name, content) 357 | `Deprecated content -> 358 `Deprecated 359 (comment_nestable_block_element_list env warnings_tag parent content) 360 | `Param (name, content) -> 361 `Param 362 ( name, 363 comment_nestable_block_element_list env warnings_tag parent content ) 364 | `Raise ((`Reference (r, reference_content) as orig), content) -> ( 365 match 366 maybe_suppress env warnings_tag (fun () -> 367 Ref_tools.resolve_reference env r) 368 with 369 | Ok (x, _) -> 370 `Raise 371 ( `Reference (`Resolved x, reference_content), 372 comment_nestable_block_element_list env warnings_tag parent 373 content ) 374 | Error e -> 375 if not (Env.should_suppress_warnings env warnings_tag) then 376 Errors.report ~what:(`Reference r) ~tools_error:(`Reference e) 377 `Resolve; 378 `Raise 379 ( orig, 380 comment_nestable_block_element_list env warnings_tag parent 381 content )) 382 | `Raise ((`Code_span _ as orig), content) -> 383 `Raise 384 ( orig, 385 comment_nestable_block_element_list env warnings_tag parent content ) 386 | `Return content -> 387 `Return 388 (comment_nestable_block_element_list env warnings_tag parent content) 389 | `See (kind, target, content) -> 390 `See 391 ( kind, 392 target, 393 comment_nestable_block_element_list env warnings_tag parent content ) 394 | `Before (version, content) -> 395 `Before 396 ( version, 397 comment_nestable_block_element_list env warnings_tag parent content ) 398 | `Author _ | `Since _ | `Alert _ | `Version _ -> 399 x (* only contain primitives *) 400 401and comment_block_element env warnings_tag parent ~loc 402 (x : Comment.block_element) = 403 match x with 404 | #Comment.nestable_block_element as x -> 405 (comment_nestable_block_element env warnings_tag parent ~loc x 406 :> Comment.block_element) 407 | `Heading (attrs, label, elems) -> 408 let cie = comment_inline_element env warnings_tag in 409 let elems = 410 List.rev_map (fun ele -> with_location cie ele) elems |> List.rev 411 in 412 let h = (attrs, label, elems) in 413 check_ambiguous_label ~loc env h; 414 `Heading h 415 | `Tag t -> `Tag (comment_tag env warnings_tag parent ~loc t) 416 417and with_location : type a. 418 (loc:_ -> a -> a) -> a Location_.with_location -> a Location_.with_location 419 = 420 fun fn { value; location = loc } -> 421 let value = Lookup_failures.with_location loc (fun () -> fn ~loc value) in 422 { value; location = loc } 423 424and comment_docs env parent d = 425 { 426 Comment.elements = 427 List.rev_map 428 (with_location 429 (comment_block_element env d.Comment.warnings_tag 430 (parent :> Id.LabelParent.t))) 431 d.Comment.elements 432 |> List.rev; 433 warnings_tag = d.warnings_tag; 434 } 435 436and comment env parent = function 437 | `Stop -> `Stop 438 | `Docs d -> `Docs (comment_docs env parent d) 439 440and open_ env parent = function 441 | { Odoc_model__Lang.Open.doc; _ } as open_ -> 442 { open_ with doc = comment_docs env parent doc } 443 444let warn_on_hidden_representation (id : Id.Type.t) 445 (r : Lang.TypeDecl.Representation.t) = 446 let open Paths.Identifier in 447 let rec internal_typ_exp typ_expr = 448 let open Lang.TypeExpr in 449 let open Paths.Path in 450 match typ_expr with 451 | Constr (p, ts) -> 452 is_hidden (p :> Paths.Path.t) 453 || List.exists (fun t -> internal_typ_exp t) ts 454 | Poly (_, t) | Alias (t, _) -> internal_typ_exp t 455 | Arrow (_, t, t2, _, _) -> internal_typ_exp t || internal_typ_exp t2 456 | Tuple ts -> List.exists (fun (_, t) -> internal_typ_exp t) ts 457 | Class (_, ts) -> List.exists (fun t -> internal_typ_exp t) ts 458 | _ -> false 459 in 460 461 let internal_cstr_arg t = 462 let open Lang.TypeDecl.Constructor in 463 let open Lang.TypeDecl.Field in 464 match t.args with 465 | Tuple type_exprs -> 466 List.exists (fun type_expr -> internal_typ_exp type_expr) type_exprs 467 | Record fields -> 468 List.exists (fun field -> internal_typ_exp field.type_) fields 469 in 470 471 let internal_field t = 472 let open Lang.TypeDecl.Field in 473 internal_typ_exp t.type_ 474 in 475 476 let internal_unboxed_field t = 477 let open Lang.TypeDecl.UnboxedField in 478 internal_typ_exp t.type_ 479 in 480 481 let fmt_cfg = Component.Fmt.{ default with short_paths = true } in 482 match r with 483 | Variant constructors -> 484 if List.exists internal_cstr_arg constructors then 485 Lookup_failures.report_warning "@[<2>Hidden constructors in type '%a'@]" 486 Component.Fmt.(model_identifier fmt_cfg) 487 (id :> Id.any) 488 | Record fields -> ( 489 match List.filter internal_field fields with 490 | [] -> () 491 | hidden -> 492 let field_names = 493 List.map 494 (fun f -> Paths.Identifier.name f.Lang.TypeDecl.Field.id) 495 hidden 496 in 497 Lookup_failures.report_warning 498 "@[<2>Hidden fields in type '%a': %s@]" 499 Component.Fmt.(model_identifier fmt_cfg) 500 (id :> Id.any) (String.concat ", " field_names)) 501 | Record_unboxed_product fields -> 502 if List.exists internal_unboxed_field fields then 503 Lookup_failures.report_warning "@[<2>Hidden unboxed fields in type '%a'@]" 504 Component.Fmt.(model_identifier fmt_cfg) 505 (id :> Id.any) 506 | Extensible -> () 507 508let rec unit env t = 509 let open Compilation_unit in 510 let content = 511 if t.hidden then t.content 512 else 513 match t.content with 514 | Module sg -> 515 let sg = signature env (t.id :> Id.Signature.t) sg in 516 Module sg 517 | Pack _ as p -> p 518 in 519 let source_loc = source_loc env t.id t.source_loc in 520 { t with content; linked = true; source_loc } 521 522and value_ env parent t = 523 let open Value in 524 { 525 t with 526 source_loc = source_loc env t.id t.source_loc; 527 doc = comment_docs env parent t.doc; 528 type_ = type_expression env parent [] t.type_; 529 } 530 531and exception_ env parent e = 532 let open Exception in 533 let res = Opt.map (type_expression env parent []) e.res in 534 let args = type_decl_constructor_argument env parent e.args in 535 let source_loc = source_loc env e.id e.source_loc in 536 let doc = comment_docs env parent e.doc in 537 { e with source_loc; res; args; doc } 538 539and extension env parent t = 540 let open Extension in 541 let constructor c = 542 let open Constructor in 543 { 544 c with 545 source_loc = source_loc env c.id c.source_loc; 546 args = type_decl_constructor_argument env parent c.args; 547 res = Opt.map (type_expression env parent []) c.res; 548 doc = comment_docs env parent c.doc; 549 } 550 in 551 let type_path = type_path env t.type_path in 552 let constructors = List.map constructor t.constructors in 553 let doc = comment_docs env parent t.doc in 554 { t with type_path; constructors; doc } 555 556and class_type_expr env parent = 557 let open ClassType in 558 function 559 | Constr (path, texps) -> 560 Constr (path, List.map (type_expression env parent []) texps) 561 | Signature s -> Signature (class_signature env parent s) 562 563and class_type env parent c = 564 let open ClassType in 565 let doc = comment_docs env parent c.doc in 566 { 567 c with 568 source_loc = source_loc env c.id c.source_loc; 569 expr = class_type_expr env parent c.expr; 570 doc; 571 } 572 573and class_signature env parent c = 574 let open ClassSignature in 575 let env = Env.open_class_signature c env in 576 let map_item = function 577 | Method m -> Method (method_ env parent m) 578 | InstanceVariable i -> InstanceVariable (instance_variable env parent i) 579 | Constraint cst -> Constraint (constraint_ env parent cst) 580 | Inherit c -> Inherit (inherit_ env parent c) 581 | Comment c -> Comment c 582 in 583 { 584 self = Opt.map (type_expression env parent []) c.self; 585 items = List.map map_item c.items; 586 doc = comment_docs env parent c.doc; 587 } 588 589and method_ env parent m = 590 let open Method in 591 let doc = comment_docs env parent m.doc in 592 { m with type_ = type_expression env parent [] m.type_; doc } 593 594and instance_variable env parent i = 595 let open InstanceVariable in 596 let doc = comment_docs env parent i.doc in 597 { i with type_ = type_expression env parent [] i.type_; doc } 598 599and constraint_ env parent cst = 600 let open ClassSignature.Constraint in 601 let left = type_expression env parent [] cst.left 602 and right = type_expression env parent [] cst.right 603 and doc = comment_docs env parent cst.doc in 604 { left; right; doc } 605 606and inherit_ env parent ih = 607 let open ClassSignature.Inherit in 608 let expr = class_type_expr env parent ih.expr 609 and doc = comment_docs env parent ih.doc in 610 { expr; doc } 611 612and class_ env parent c = 613 let open Class in 614 let rec map_decl = function 615 | ClassType expr -> ClassType (class_type_expr env parent expr) 616 | Arrow (lbl, expr, decl) -> 617 Arrow (lbl, type_expression env parent [] expr, map_decl decl) 618 in 619 let doc = comment_docs env parent c.doc in 620 let source_loc = source_loc env c.id c.source_loc in 621 let type_ = map_decl c.type_ in 622 { c with source_loc; type_; doc } 623 624and module_substitution env parent m = 625 let open ModuleSubstitution in 626 let doc = comment_docs env parent m.doc in 627 { m with manifest = module_path env m.manifest; doc } 628 629and signature : Env.t -> Id.Signature.t -> Signature.t -> _ = 630 fun env id s -> 631 let env = Env.open_signature s env |> Env.add_docs s.doc in 632 let items = signature_items env id s.items 633 and doc = comment_docs env id s.doc in 634 { s with items; doc } 635 636and signature_items : 637 Env.t -> Id.Signature.t -> Signature.item list -> Signature.item list = 638 fun env id s -> 639 let open Signature in 640 let items, _ = 641 List.fold_left 642 (fun (items, env) item -> 643 let std i = (i :: items, env) in 644 match item with 645 | Module (r, m) -> std @@ Module (r, module_ env m) 646 | ModuleSubstitution m -> 647 let env' = Env.open_module_substitution m env in 648 (ModuleSubstitution (module_substitution env id m) :: items, env') 649 | Type (r, t) -> std @@ Type (r, type_decl env id t) 650 | TypeSubstitution t -> 651 let env' = Env.open_type_substitution t env in 652 (TypeSubstitution (type_decl env id t) :: items, env') 653 | ModuleType mt -> std @@ ModuleType (module_type env mt) 654 | ModuleTypeSubstitution mts -> 655 let env' = Env.open_module_type_substitution mts env in 656 ( ModuleTypeSubstitution (module_type_substitution env mts) :: items, 657 env' ) 658 | Value v -> std @@ Value (value_ env id v) 659 | Comment c -> std @@ Comment (comment env id c) 660 | TypExt t -> std @@ TypExt (extension env id t) 661 | Exception e -> std @@ Exception (exception_ env id e) 662 | Class (r, c) -> std @@ Class (r, class_ env id c) 663 | ClassType (r, c) -> std @@ ClassType (r, class_type env id c) 664 | Include i -> std @@ Include (include_ env i) 665 | Open o -> std @@ Open (open_ env id o)) 666 ([], env) s 667 in 668 List.rev items 669 670and simple_expansion : 671 Env.t -> 672 Id.Signature.t -> 673 ModuleType.simple_expansion -> 674 ModuleType.simple_expansion = 675 fun env id m -> 676 match m with 677 | Signature sg -> Signature (signature env id sg) 678 | Functor (arg, sg) -> 679 let env' = Env.add_functor_parameter arg env in 680 Functor (functor_argument env arg, simple_expansion env' id sg) 681 682and module_ : Env.t -> Module.t -> Module.t = 683 fun env m -> 684 let open Module in 685 let open Odoc_utils.ResultMonad in 686 let sg_id = (m.id :> Id.Signature.t) in 687 if m.hidden then m 688 else 689 let type_ = module_decl env sg_id m.type_ in 690 let type_ = 691 match type_ with 692 | Alias (`Resolved p, _) -> 693 if expansion_needed p m.id then 694 let cp = Component.Of_Lang.(resolved_module_path (empty ()) p) in 695 match 696 Tools.expansion_of_module_path ~strengthen:false env 697 (`Resolved cp) 698 >>= Expand_tools.handle_expansion env (m.id :> Id.Signature.t) 699 with 700 | Ok (_, e) -> 701 let le = Lang_of.(simple_expansion (empty ()) sg_id e) in 702 Alias (`Resolved p, Some (simple_expansion env sg_id le)) 703 | Error _ -> type_ 704 else type_ 705 | Alias _ | ModuleType _ -> type_ 706 in 707 let source_loc = source_loc env m.id m.source_loc in 708 let doc = comment_docs env sg_id m.doc in 709 { m with source_loc; doc; type_ } 710 711and module_decl : Env.t -> Id.Signature.t -> Module.decl -> Module.decl = 712 fun env id decl -> 713 let open Module in 714 match decl with 715 | ModuleType expr -> ModuleType (module_type_expr env id expr) 716 | Alias (p, e) -> 717 Alias (module_path env p, Opt.map (simple_expansion env id) e) 718 719and include_decl : Env.t -> Id.Signature.t -> Include.decl -> Include.decl = 720 fun env id decl -> 721 let open Include in 722 let rec is_elidable_with_u : Odoc_model.Lang.ModuleType.U.expr -> bool = 723 function 724 | Path _ -> false 725 | Signature _ -> true 726 | With (_, expr) -> is_elidable_with_u expr 727 | TypeOf _ -> false 728 | Strengthen (expr, _, _) -> is_elidable_with_u expr 729 in 730 match decl with 731 | ModuleType expr when is_elidable_with_u expr -> ModuleType expr 732 | ModuleType expr -> ModuleType (u_module_type_expr env id expr) 733 | Alias p -> Alias (module_path env p) 734 735and module_type : Env.t -> ModuleType.t -> ModuleType.t = 736 fun env m -> 737 let sg_id = (m.id :> Id.Signature.t) in 738 let open ModuleType in 739 let expr' = 740 match m.expr with 741 | None -> None 742 | Some expr -> Some (module_type_expr env sg_id expr) 743 in 744 (* let self_canonical = 745 match m.expr with 746 | Some (Path (`Resolved p)) when Paths.Path.Resolved.ModuleType.canonical_ident p = Some m.id -> 747 true 748 | _ -> false 749 in*) 750 let doc = comment_docs env sg_id m.doc in 751 let source_loc = (source_loc env m.id) m.source_loc in 752 { m with source_loc; expr = expr'; doc } 753 754and module_type_substitution : 755 Env.t -> ModuleTypeSubstitution.t -> ModuleTypeSubstitution.t = 756 fun env m -> 757 let sg_id = (m.id :> Id.Signature.t) in 758 let open ModuleTypeSubstitution in 759 let manifest' = module_type_expr env sg_id m.manifest in 760 let doc = comment_docs env sg_id m.doc in 761 { m with manifest = manifest'; doc } 762 763and include_ : Env.t -> Include.t -> Include.t = 764 fun env i -> 765 let open Include in 766 let decl = include_decl env i.parent i.decl in 767 let doc = comment_docs env i.parent i.doc in 768 let expansion = 769 (* Don't call {!signature} to avoid adding the content of the expansion to 770 the environment, which is already done recursively by 771 {!Env.open_signature}. *) 772 let content = 773 (* Add context around errors from the expansion. *) 774 Lookup_failures.with_context 775 "While resolving the expansion of include at %a" Location_.pp_span_start 776 i.loc (fun () -> 777 let { content; _ } = i.expansion in 778 let items = signature_items env i.parent content.items 779 and doc = comment_docs env i.parent content.doc in 780 { content with items; doc }) 781 in 782 { i.expansion with content } 783 in 784 { i with decl; expansion; doc } 785 786and functor_parameter_parameter : 787 Env.t -> FunctorParameter.parameter -> FunctorParameter.parameter = 788 fun env a -> 789 let sg_id = (a.id :> Id.Signature.t) in 790 let expr = module_type_expr env sg_id a.expr in 791 { a with expr } 792 793and functor_argument env a = 794 match a with 795 | FunctorParameter.Unit -> FunctorParameter.Unit 796 | Named arg -> Named (functor_parameter_parameter env arg) 797 798and handle_fragments env id sg subs = 799 let open ModuleType in 800 List.fold_left 801 (fun (sg_res, subs) lsub -> 802 match (sg_res, lsub) with 803 | Ok sg, ModuleEq (frag, decl) -> 804 let frag' = 805 match frag with 806 | `Resolved f -> 807 let cfrag = 808 Component.Of_Lang.(resolved_module_fragment (empty ()) f) 809 in 810 `Resolved 811 (Tools.reresolve_module_fragment env cfrag 812 |> Lang_of.(Path.resolved_module_fragment (empty ()))) 813 | _ -> frag 814 in 815 let sg' = 816 Tools.fragmap env 817 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 818 sg 819 in 820 (sg', ModuleEq (frag', module_decl env id decl) :: subs) 821 | Ok sg, TypeEq (frag, eqn) -> 822 let frag' = 823 match frag with 824 | `Resolved f -> 825 let cfrag = 826 Component.Of_Lang.(resolved_type_fragment (empty ()) f) 827 in 828 `Resolved 829 (Tools.reresolve_type_fragment env cfrag 830 |> Lang_of.(Path.resolved_type_fragment (empty ()))) 831 | _ -> frag 832 in 833 let sg' = 834 Tools.fragmap env 835 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 836 sg 837 in 838 (sg', TypeEq (frag', type_decl_equation env id eqn) :: subs) 839 | Ok sg, ModuleTypeEq (frag, eqn) -> 840 let frag' = 841 match frag with 842 | `Resolved f -> 843 let cfrag = 844 Component.Of_Lang.(resolved_module_type_fragment (empty ()) f) 845 in 846 `Resolved 847 (Tools.reresolve_module_type_fragment env cfrag 848 |> Lang_of.(Path.resolved_module_type_fragment (empty ()))) 849 | _ -> frag 850 in 851 let sg' = 852 Tools.fragmap env 853 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 854 sg 855 in 856 (sg', ModuleTypeEq (frag', module_type_expr env id eqn) :: subs) 857 | Ok sg, ModuleSubst (frag, mpath) -> 858 let frag' = 859 match frag with 860 | `Resolved f -> 861 let cfrag = 862 Component.Of_Lang.(resolved_module_fragment (empty ()) f) 863 in 864 `Resolved 865 (Tools.reresolve_module_fragment env cfrag 866 |> Lang_of.(Path.resolved_module_fragment (empty ()))) 867 | _ -> frag 868 in 869 let sg' = 870 Tools.fragmap env 871 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 872 sg 873 in 874 (sg', ModuleSubst (frag', module_path env mpath) :: subs) 875 | Ok sg, TypeSubst (frag, eqn) -> 876 let frag' = 877 match frag with 878 | `Resolved f -> 879 let cfrag = 880 Component.Of_Lang.(resolved_type_fragment (empty ()) f) 881 in 882 `Resolved 883 (Tools.reresolve_type_fragment env cfrag 884 |> Lang_of.(Path.resolved_type_fragment (empty ()))) 885 | _ -> frag 886 in 887 let sg' = 888 Tools.fragmap env 889 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 890 sg 891 in 892 (sg', TypeSubst (frag', type_decl_equation env id eqn) :: subs) 893 | Ok sg, ModuleTypeSubst (frag, eqn) -> 894 let frag' = 895 match frag with 896 | `Resolved f -> 897 let cfrag = 898 Component.Of_Lang.(resolved_module_type_fragment (empty ()) f) 899 in 900 `Resolved 901 (Tools.reresolve_module_type_fragment env cfrag 902 |> Lang_of.(Path.resolved_module_type_fragment (empty ()))) 903 | _ -> frag 904 in 905 let sg' = 906 Tools.fragmap env 907 Component.Of_Lang.(with_module_type_substitution (empty ()) lsub) 908 sg 909 in 910 (sg', ModuleTypeSubst (frag', module_type_expr env id eqn) :: subs) 911 | (Error _ as e), lsub -> (e, lsub :: subs)) 912 (Ok sg, []) subs 913 |> snd |> List.rev 914 915and u_module_type_expr : 916 Env.t -> Id.Signature.t -> ModuleType.U.expr -> ModuleType.U.expr = 917 fun env id expr -> 918 match expr with 919 | Signature s -> Signature s 920 (* No need to link 'unexpanded' module type expressions that are actually expanded... *) 921 | Path p -> Path (module_type_path env p) 922 | With (subs, expr) as unresolved -> ( 923 let cexpr = Component.Of_Lang.(u_module_type_expr (empty ()) expr) in 924 match Tools.signature_of_u_module_type_expr env cexpr with 925 | Ok sg -> 926 With (handle_fragments env id sg subs, u_module_type_expr env id expr) 927 | Error e -> 928 Errors.report ~what:(`Module_type_U cexpr) ~tools_error:e `Resolve; 929 unresolved) 930 | TypeOf (StructInclude p, original_path) -> 931 TypeOf (StructInclude (module_path env p), original_path) 932 | TypeOf (ModPath p, original_path) -> 933 TypeOf (ModPath (module_path env p), original_path) 934 | Strengthen (expr, path, aliasable) -> 935 let expr = u_module_type_expr env id expr in 936 Strengthen (expr, module_path env path, aliasable) 937 938and module_type_expr : 939 Env.t -> Id.Signature.t -> ModuleType.expr -> ModuleType.expr = 940 fun env id expr -> 941 let open ModuleType in 942 let open Odoc_utils.ResultMonad in 943 let do_expn cur (e : Paths.Path.ModuleType.t option) = 944 match (cur, e) with 945 | Some e, _ -> 946 Some (simple_expansion env (id :> Paths.Identifier.Signature.t) e) 947 | None, Some (`Resolved p_path) -> 948 if expansion_needed p_path id then 949 let cp = 950 Component.Of_Lang.(resolved_module_type_path (empty ()) p_path) 951 in 952 match 953 Tools.expansion_of_module_type_expr env 954 (Path { p_path = `Resolved cp; p_expansion = None }) 955 >>= Expand_tools.handle_expansion env (id :> Id.Signature.t) 956 with 957 | Ok (_, e) -> 958 let le = Lang_of.(simple_expansion (empty ()) id e) in 959 Some (simple_expansion env id le) 960 | Error _ -> None 961 else None 962 | None, _ -> None 963 in 964 match expr with 965 | Signature s -> Signature (signature env id s) 966 | Path { p_path; p_expansion } -> 967 let p_path = module_type_path env p_path in 968 Path { p_path; p_expansion = do_expn p_expansion (Some p_path) } 969 | With { w_substitutions; w_expansion; w_expr } as unresolved -> ( 970 let cexpr = Component.Of_Lang.(u_module_type_expr (empty ()) w_expr) in 971 match Tools.signature_of_u_module_type_expr env cexpr with 972 | Ok sg -> 973 With 974 { 975 w_substitutions = handle_fragments env id sg w_substitutions; 976 w_expansion = do_expn w_expansion None; 977 w_expr = u_module_type_expr env id w_expr; 978 } 979 | Error e -> 980 Errors.report ~what:(`Module_type_U cexpr) ~tools_error:e `Expand; 981 unresolved) 982 | Functor (arg, res) -> 983 let arg' = functor_argument env arg in 984 let env = Env.add_functor_parameter arg env in 985 let res' = module_type_expr env (Paths.Identifier.Mk.result id) res in 986 Functor (arg', res') 987 | TypeOf { t_desc = StructInclude p; t_expansion; t_original_path } -> 988 TypeOf 989 { 990 t_desc = StructInclude (module_path env p); 991 t_expansion = do_expn t_expansion None; 992 t_original_path; 993 } 994 | TypeOf { t_desc = ModPath p; t_expansion; t_original_path } -> 995 TypeOf 996 { 997 t_desc = ModPath (module_path env p); 998 t_expansion = do_expn t_expansion None; 999 t_original_path; 1000 } 1001 | Strengthen { s_expr; s_path; s_aliasable; s_expansion } -> 1002 Strengthen 1003 { 1004 s_expr = u_module_type_expr env id s_expr; 1005 s_path = module_path env s_path; 1006 s_aliasable; 1007 s_expansion = do_expn s_expansion None; 1008 } 1009 1010and type_decl_representation : 1011 Env.t -> 1012 Id.Signature.t -> 1013 TypeDecl.Representation.t -> 1014 TypeDecl.Representation.t = 1015 fun env parent r -> 1016 let open TypeDecl.Representation in 1017 match r with 1018 | Variant cs -> Variant (List.map (type_decl_constructor env parent) cs) 1019 | Record fs -> Record (List.map (type_decl_field env parent) fs) 1020 | Record_unboxed_product fs -> 1021 Record_unboxed_product (List.map (type_decl_unboxed_field env parent) fs) 1022 | Extensible -> Extensible 1023 1024and type_decl : Env.t -> Id.Signature.t -> TypeDecl.t -> TypeDecl.t = 1025 fun env parent t -> 1026 let open TypeDecl in 1027 let equation = type_decl_equation env parent t.equation in 1028 let doc = comment_docs env parent t.doc in 1029 let source_loc = source_loc env t.id t.source_loc in 1030 let hidden_path = 1031 match equation.Equation.manifest with 1032 | Some (Constr (`Resolved path, params)) 1033 when Paths.Path.Resolved.(is_hidden (path :> t)) 1034 || Paths.Path.Resolved.(identifier (path :> t)) 1035 = Some (t.id :> Paths.Identifier.t) -> 1036 Some (path, params) 1037 | _ -> None 1038 in 1039 let representation = 1040 Opt.map 1041 (fun r -> 1042 let r' = type_decl_representation env parent r in 1043 warn_on_hidden_representation t.id r'; 1044 r') 1045 t.representation 1046 in 1047 let default = { t with source_loc; equation; doc; representation } in 1048 match hidden_path with 1049 | Some (p, params) -> ( 1050 let p' = Component.Of_Lang.(resolved_type_path (empty ()) p) in 1051 match Tools.lookup_type env p' with 1052 | Ok (`FType (_, t')) -> 1053 let equation = 1054 try 1055 Expand_tools.collapse_eqns default.equation 1056 (Lang_of.type_decl_equation (Lang_of.empty ()) 1057 (parent :> Id.FieldParent.t) 1058 t'.equation) 1059 params 1060 with _ -> default.equation 1061 in 1062 { default with equation = type_decl_equation env parent equation } 1063 | Ok (`FClass _ | `FClassType _ | `FType_removed _ | `CoreType _) 1064 | Error _ -> 1065 default) 1066 | None -> default 1067 1068and type_decl_equation env parent t = 1069 let open TypeDecl.Equation in 1070 let manifest = Opt.map (type_expression env parent []) t.manifest in 1071 let constraints = 1072 List.map 1073 (fun (tex1, tex2) -> 1074 (type_expression env parent [] tex1, type_expression env parent [] tex2)) 1075 t.constraints 1076 in 1077 { t with manifest; constraints } 1078 1079and type_decl_field env parent f = 1080 let open TypeDecl.Field in 1081 let doc = comment_docs env parent f.doc in 1082 { f with type_ = type_expression env parent [] f.type_; doc } 1083 1084and type_decl_unboxed_field env parent f = 1085 let open TypeDecl.UnboxedField in 1086 let doc = comment_docs env parent f.doc in 1087 { f with type_ = type_expression env parent [] f.type_; doc } 1088 1089and type_decl_constructor_argument env parent c = 1090 let open TypeDecl.Constructor in 1091 match c with 1092 | Tuple ts -> Tuple (List.map (type_expression env parent []) ts) 1093 | Record fs -> Record (List.map (type_decl_field env parent) fs) 1094 1095and type_decl_constructor env parent c = 1096 let open TypeDecl.Constructor in 1097 let doc = comment_docs env parent c.doc in 1098 let args = type_decl_constructor_argument env parent c.args in 1099 let res = Opt.map (type_expression env parent []) c.res in 1100 { c with doc; args; res } 1101 1102and type_expression_polyvar env parent visited v = 1103 let open TypeExpr.Polymorphic_variant in 1104 let constructor c = 1105 let open Constructor in 1106 let doc = comment_docs env parent c.doc in 1107 { 1108 c with 1109 arguments = List.map (type_expression env parent visited) c.arguments; 1110 doc; 1111 } 1112 in 1113 let element = function 1114 | Type t -> 1115 Type 1116 (match type_expression env parent visited t with 1117 | Constr _ as x -> x 1118 | _ -> t) 1119 (* These have to remain Constrs *) 1120 | Constructor c -> Constructor (constructor c) 1121 in 1122 { v with elements = List.map element v.elements } 1123 1124and type_expression_object env parent visited o = 1125 let open TypeExpr.Object in 1126 let method_ m = 1127 { m with type_ = type_expression env parent visited m.type_ } 1128 in 1129 let field = function 1130 | Method m -> Method (method_ m) 1131 | Inherit t -> Inherit (type_expression env parent visited t) 1132 in 1133 { o with fields = List.map field o.fields } 1134 1135and type_expression_package env parent visited p = 1136 let open TypeExpr.Package in 1137 let substitution (frag, t) = 1138 let cfrag = Component.Of_Lang.(type_fragment (empty ()) frag) in 1139 let frag' = 1140 match cfrag with 1141 | `Resolved f -> `Resolved (Tools.reresolve_type_fragment env f) 1142 | _ -> cfrag 1143 in 1144 ( Lang_of.(Path.type_fragment (empty ()) frag'), 1145 type_expression env parent visited t ) 1146 in 1147 { 1148 path = module_type_path env p.path; 1149 substitutions = List.map substitution p.substitutions; 1150 } 1151 1152and type_expression : Env.t -> Id.Signature.t -> _ -> _ = 1153 fun env parent visited texpr -> 1154 let open TypeExpr in 1155 match texpr with 1156 | Var _ | Any -> texpr 1157 | Alias (t, str) -> Alias (type_expression env parent visited t, str) 1158 | Arrow (lbl, t1, t2, modes, ret_modes) -> 1159 Arrow 1160 ( lbl, 1161 type_expression env parent visited t1, 1162 type_expression env parent visited t2, 1163 modes, 1164 ret_modes ) 1165 | Tuple ts -> 1166 Tuple 1167 (List.map 1168 (fun (lbl, ty) -> (lbl, type_expression env parent visited ty)) 1169 ts) 1170 | Unboxed_tuple ts -> 1171 Unboxed_tuple (List.map (fun (l, t) -> l, type_expression env parent visited t) ts) 1172 | Constr (path', ts') -> ( 1173 let path = type_path env path' in 1174 let ts = List.map (type_expression env parent visited) ts' in 1175 if not (Paths.Path.is_hidden (path :> Paths.Path.t)) then Constr (path, ts) 1176 else 1177 let cp = Component.Of_Lang.(type_path (empty ()) path') in 1178 match Tools.resolve_type env cp with 1179 | Ok (cp', `FType (_, t)) -> 1180 let cp' = Tools.reresolve_type env cp' in 1181 let p = Lang_of.(Path.resolved_type (empty ()) cp') in 1182 if List.mem p visited then raise Loop 1183 else if Cpath.is_resolved_type_hidden cp' then 1184 match t.Component.TypeDecl.equation with 1185 | { manifest = Some expr; params; _ } -> ( 1186 try 1187 let map = 1188 List.fold_left2 1189 (fun acc param sub -> 1190 match param.Lang.TypeDecl.desc with 1191 | Lang.TypeDecl.Var (x, _) -> (x, sub) :: acc 1192 | Any -> acc) 1193 [] params ts 1194 in 1195 let t' = 1196 Expand_tools.type_expr map 1197 Lang_of.( 1198 type_expr (empty ()) (parent :> Id.LabelParent.t) expr) 1199 in 1200 type_expression env parent (p :: visited) t' 1201 with 1202 | Loop -> Constr (`Resolved p, ts) 1203 | e -> 1204 Format.eprintf 1205 "Caught unexpected exception when expanding type \ 1206 declaration (%s)@." 1207 (Printexc.to_string e); 1208 Constr (`Resolved p, ts)) 1209 | _ -> Constr (`Resolved p, ts) 1210 else Constr (`Resolved p, ts) 1211 | Ok (cp', (`FClass _ | `FClassType _ | `CoreType _)) -> 1212 let p = Lang_of.(Path.resolved_type (empty ()) cp') in 1213 Constr (`Resolved p, ts) 1214 | Ok (_cp, `FType_removed (_, x, _eq)) -> 1215 (* Type variables ? *) 1216 Lang_of.(type_expr (empty ()) (parent :> Id.LabelParent.t) x) 1217 | Error _ -> Constr (path', ts)) 1218 | Polymorphic_variant v -> 1219 Polymorphic_variant (type_expression_polyvar env parent visited v) 1220 | Object o -> Object (type_expression_object env parent visited o) 1221 | Class (path', ts') -> ( 1222 let path = class_type_path env path' in 1223 let ts = List.map (type_expression env parent visited) ts' in 1224 if not (Paths.Path.is_hidden (path :> Paths.Path.t)) then Class (path, ts) 1225 else 1226 let cp = Component.Of_Lang.(class_type_path (empty ()) path') in 1227 match Tools.resolve_class_type env cp with 1228 | Ok (cp', (`FClass _ | `FClassType _)) -> 1229 let cp' = Tools.reresolve_class_type env cp' in 1230 let p = Lang_of.(Path.resolved_class_type (empty ()) cp') in 1231 Class (`Resolved p, ts) 1232 | _ -> Class (path', ts)) 1233 | Poly (strs, t) -> Poly (strs, type_expression env parent visited t) 1234 | Quote t -> Quote (type_expression env parent visited t) 1235 | Splice t -> Splice (type_expression env parent visited t) 1236 | Package p -> Package (type_expression_package env parent visited p) 1237 1238let link ~filename x y = 1239 Lookup_failures.catch_failures ~filename (fun () -> 1240 if y.Lang.Compilation_unit.linked then y else unit x y) 1241 1242let page env page = 1243 let () = 1244 List.iter 1245 (fun child -> 1246 match child with 1247 | Page.Page_child page -> ( 1248 match Env.lookup_page_by_name page env with 1249 | Ok _ -> () 1250 | Error `Not_found -> Errors.report ~what:(`Child_page page) `Lookup 1251 ) 1252 | Page.Module_child mod_ -> ( 1253 match 1254 Env.lookup_root_module 1255 (Odoc_model.Names.ModuleName.make_std mod_) 1256 env 1257 with 1258 | Some _ -> () 1259 | None -> Errors.report ~what:(`Child_module mod_) `Lookup)) 1260 page.Lang.Page.children 1261 in 1262 { 1263 page with 1264 Page.content = comment_docs env page.Page.name page.content; 1265 linked = true; 1266 } 1267 1268let source_info env infos = 1269 let open Source_info in 1270 let jump_to v f_impl f_doc = 1271 let documentation = 1272 match v.documentation with Some p -> Some (f_doc p) | None -> None 1273 in 1274 let implementation = 1275 match v.implementation with 1276 | Some (Unresolved p) -> ( 1277 match f_impl p with 1278 | Some x -> Some (Resolved x) 1279 | None -> v.implementation) 1280 | x -> x 1281 in 1282 { documentation; implementation } 1283 in 1284 List.map 1285 (fun (i, pos) -> 1286 let info = 1287 match i with 1288 | Value v -> 1289 Value 1290 (jump_to v (Shape_tools.lookup_value_path env) (value_path env)) 1291 | Module v -> 1292 Module 1293 (jump_to v (Shape_tools.lookup_module_path env) (module_path env)) 1294 | ModuleType v -> 1295 ModuleType 1296 (jump_to v 1297 (Shape_tools.lookup_module_type_path env) 1298 (module_type_path env)) 1299 | Type v -> 1300 Type (jump_to v (Shape_tools.lookup_type_path env) (type_path env)) 1301 | i -> i 1302 in 1303 (info, pos)) 1304 infos 1305 1306let impl env i = 1307 let open Implementation in 1308 { i with source_info = source_info env i.source_info; linked = true } 1309 1310let resolve_page ~filename env p = 1311 Lookup_failures.catch_failures ~filename (fun () -> 1312 if p.Lang.Page.linked then p else page env p) 1313 1314let resolve_impl ~filename env i = 1315 Lookup_failures.catch_failures ~filename (fun () -> 1316 if i.Lang.Implementation.linked then i else impl env i)