1 (***********************************************************************)
4 (* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
6 (* Copyright 2001 Institut National de Recherche en Informatique et *)
7 (* en Automatique. All rights reserved. This file is distributed *)
8 (* under the terms of the Q Public License version 1.0. *)
10 (***********************************************************************)
12 (* $Id: odoc_cross.ml 8418 2007-10-09 10:29:37Z weis $ *)
14 (** Cross referencing. *)
16 module Name = Odoc_name
25 (*** Replacements of aliases : if e1 = e2 and e2 = e3, then replace e2 by e3 to have e1 = e3,
26 in order to associate the element with complete information. *)
28 (** The module used to keep what refs were modified. *)
31 struct type t = string * ref_kind option
32 let compare = Pervasives.compare
36 let verified_refs = ref S.empty
38 let add_verified v = verified_refs := S.add v !verified_refs
39 let was_verified v = S.mem v !verified_refs
41 (** The module with the predicates used to get the aliased modules, classes and exceptions. *)
49 Module_alias _ -> true
52 let p_module_type mt _ =
55 Some (Module_type_alias _) -> true
58 let p_class c _ = (false, false)
59 let p_class_type ct _ = (false, false)
60 let p_value v _ = false
61 let p_type t _ = false
62 let p_exception e _ = e.ex_alias <> None
63 let p_attribute a _ = false
64 let p_method m _ = false
65 let p_section s _ = false
68 (** The module used to get the aliased elements. *)
69 module Search_alias = Odoc_search.Search (P_alias)
75 (** Couples of module name aliases. *)
76 let (module_aliases : (Name.t, Name.t * alias_state) Hashtbl.t) = Hashtbl.create 13 ;;
78 (** Couples of module or module type name aliases. *)
79 let module_and_modtype_aliases = Hashtbl.create 13;;
81 (** Couples of exception name aliases. *)
82 let exception_aliases = Hashtbl.create 13;;
84 let rec build_alias_list = function
86 | (Odoc_search.Res_module m) :: q ->
90 Hashtbl.add module_aliases m.m_name (ma.ma_name, Alias_to_resolve);
91 Hashtbl.add module_and_modtype_aliases m.m_name (ma.ma_name, Alias_to_resolve)
95 | (Odoc_search.Res_module_type mt) :: q ->
98 Some (Module_type_alias mta) ->
99 Hashtbl.add module_and_modtype_aliases
100 mt.mt_name (mta.mta_name, Alias_to_resolve)
104 | (Odoc_search.Res_exception e) :: q ->
106 match e.ex_alias with
109 Hashtbl.add exception_aliases
110 e.ex_name (ea.ea_name,Alias_to_resolve)
116 (** Retrieve the aliases for modules, module types and exceptions
117 and put them in global hash tables. *)
118 let get_alias_names module_list =
119 Hashtbl.clear module_aliases;
120 Hashtbl.clear module_and_modtype_aliases;
121 Hashtbl.clear exception_aliases;
122 build_alias_list (Search_alias.search module_list 0)
124 exception Found of string
128 match Hashtbl.find t name with
129 (s, Alias_resolved) -> s
130 | (s, Alias_to_resolve) -> f t s
136 if Name.prefix n2 name then
137 let ln2 = String.length n2 in
138 let s = n3^(String.sub name ln2 ((String.length name) - ln2)) in
142 Hashtbl.replace t name (name, Alias_resolved);
147 Hashtbl.replace t s2 (s2, Alias_resolved);
150 fun name alias_tbl ->
157 let compare = Pervasives.compare
160 module Ele_map = Map.Make (Map_ord)
162 let known_elements = ref Ele_map.empty
163 let add_known_element name k =
165 let l = Ele_map.find name !known_elements in
166 let s = Ele_map.remove name !known_elements in
167 known_elements := Ele_map.add name (k::l) s
170 known_elements := Ele_map.add name [k] !known_elements
172 let rec get_known_elements name =
173 try Ele_map.find name !known_elements
176 let kind_name_exists kind =
179 RK_module -> (fun e -> match e with Odoc_search.Res_module _ -> true | _ -> false)
180 | RK_module_type -> (fun e -> match e with Odoc_search.Res_module_type _ -> true | _ -> false)
181 | RK_class -> (fun e -> match e with Odoc_search.Res_class_type _ -> true | _ -> false)
182 | RK_class_type -> (fun e -> match e with Odoc_search.Res_class_type _ -> true | _ -> false)
183 | RK_value -> (fun e -> match e with Odoc_search.Res_value _ -> true | _ -> false)
184 | RK_type -> (fun e -> match e with Odoc_search.Res_type _ -> true | _ -> false)
185 | RK_exception -> (fun e -> match e with Odoc_search.Res_exception _ -> true | _ -> false)
186 | RK_attribute -> (fun e -> match e with Odoc_search.Res_attribute _ -> true | _ -> false)
187 | RK_method -> (fun e -> match e with Odoc_search.Res_method _ -> true | _ -> false)
188 | RK_section _ -> assert false
191 try List.exists pred (get_known_elements name)
192 with Not_found -> false
194 let module_exists = kind_name_exists RK_module
195 let module_type_exists = kind_name_exists RK_module_type
196 let class_exists = kind_name_exists RK_class
197 let class_type_exists = kind_name_exists RK_class_type
198 let value_exists = kind_name_exists RK_value
199 let type_exists = kind_name_exists RK_type
200 let exception_exists = kind_name_exists RK_exception
201 let attribute_exists = kind_name_exists RK_attribute
202 let method_exists = kind_name_exists RK_method
204 let lookup_module name =
206 (fun k -> match k with Odoc_search.Res_module _ -> true | _ -> false)
207 (get_known_elements name)
209 | Odoc_search.Res_module m -> m
212 let lookup_module_type name =
214 (fun k -> match k with Odoc_search.Res_module_type _ -> true | _ -> false)
215 (get_known_elements name)
217 | Odoc_search.Res_module_type m -> m
220 let lookup_class name =
222 (fun k -> match k with Odoc_search.Res_class _ -> true | _ -> false)
223 (get_known_elements name)
225 | Odoc_search.Res_class c -> c
228 let lookup_class_type name =
230 (fun k -> match k with Odoc_search.Res_class_type _ -> true | _ -> false)
231 (get_known_elements name)
233 | Odoc_search.Res_class_type c -> c
236 let lookup_exception name =
238 (fun k -> match k with Odoc_search.Res_exception _ -> true | _ -> false)
239 (get_known_elements name)
241 | Odoc_search.Res_exception e -> e
246 inherit Odoc_scan.scanner
247 method scan_value v =
248 add_known_element v.val_name (Odoc_search.Res_value v)
250 add_known_element t.ty_name (Odoc_search.Res_type t)
251 method scan_exception e =
252 add_known_element e.ex_name (Odoc_search.Res_exception e)
253 method scan_attribute a =
254 add_known_element a.att_value.val_name
255 (Odoc_search.Res_attribute a)
256 method scan_method m =
257 add_known_element m.met_value.val_name
258 (Odoc_search.Res_method m)
259 method scan_class_pre c =
260 add_known_element c.cl_name (Odoc_search.Res_class c);
262 method scan_class_type_pre c =
263 add_known_element c.clt_name (Odoc_search.Res_class_type c);
265 method scan_module_pre m =
266 add_known_element m.m_name (Odoc_search.Res_module m);
268 method scan_module_type_pre m =
269 add_known_element m.mt_name (Odoc_search.Res_module_type m);
274 let init_known_elements_map module_list =
276 c#scan_module_list module_list
279 (** The type to describe the names not found. *)
280 type not_found_name =
289 (** Functions to find and associate aliases elements. *)
291 let rec associate_in_module module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) m =
292 let rec iter_kind (acc_b, acc_inc, acc_names) k =
294 Module_struct elements ->
296 (associate_in_module_element module_list m.m_name)
297 (acc_b, acc_inc, acc_names)
302 match ma.ma_module with
304 (acc_b, acc_inc, acc_names)
307 try Some (Mod (lookup_module ma.ma_name))
309 try Some (Modtype (lookup_module_type ma.ma_name))
310 with Not_found -> None
313 None -> (acc_b, (Name.head m.m_name) :: acc_inc,
314 (* we don't want to output warning messages for
315 "sig ... end" or "struct ... end" modules not found *)
316 (if ma.ma_name = Odoc_messages.struct_end or
317 ma.ma_name = Odoc_messages.sig_end then
320 (NF_mmt ma.ma_name) :: acc_names)
323 ma.ma_module <- Some mmt ;
324 (true, acc_inc, acc_names)
327 | Module_functor (_, k) ->
328 iter_kind (acc_b, acc_inc, acc_names) k
330 | Module_with (tk, _) ->
331 associate_in_module_type module_list (acc_b, acc_inc, acc_names)
332 { mt_name = "" ; mt_info = None ; mt_type = None ;
333 mt_is_interface = false ; mt_file = ""; mt_kind = Some tk ;
334 mt_loc = Odoc_types.dummy_loc }
336 | Module_apply (k1, k2) ->
337 let (acc_b2, acc_inc2, acc_names2) = iter_kind (acc_b, acc_inc, acc_names) k1 in
338 iter_kind (acc_b2, acc_inc2, acc_names2) k2
340 | Module_constraint (k, tk) ->
341 let (acc_b2, acc_inc2, acc_names2) = iter_kind (acc_b, acc_inc, acc_names) k in
342 associate_in_module_type module_list (acc_b2, acc_inc2, acc_names2)
343 { mt_name = "" ; mt_info = None ; mt_type = None ;
344 mt_is_interface = false ; mt_file = "" ; mt_kind = Some tk ;
345 mt_loc = Odoc_types.dummy_loc }
347 iter_kind (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) m.m_kind
349 and associate_in_module_type module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) mt =
350 let rec iter_kind (acc_b, acc_inc, acc_names) k =
352 Module_type_struct elements ->
354 (associate_in_module_element module_list mt.mt_name)
355 (acc_b, acc_inc, acc_names)
358 | Module_type_functor (_, k) ->
359 iter_kind (acc_b, acc_inc, acc_names) k
361 | Module_type_with (k, _) ->
362 iter_kind (acc_b, acc_inc, acc_names) k
364 | Module_type_alias mta ->
365 match mta.mta_module with
367 (acc_b, acc_inc, acc_names)
370 try Some (lookup_module_type mta.mta_name)
371 with Not_found -> None
374 None -> (acc_b, (Name.head mt.mt_name) :: acc_inc,
375 (* we don't want to output warning messages for
376 "sig ... end" or "struct ... end" modules not found *)
377 (if mta.mta_name = Odoc_messages.struct_end or
378 mta.mta_name = Odoc_messages.sig_end then
381 (NF_mt mta.mta_name) :: acc_names)
384 mta.mta_module <- Some mt ;
385 (true, acc_inc, acc_names)
387 match mt.mt_kind with
388 None -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
389 | Some k -> iter_kind (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) k
391 and associate_in_module_element module_list m_name (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) element =
393 Element_module m -> associate_in_module module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) m
394 | Element_module_type mt -> associate_in_module_type module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) mt
395 | Element_included_module im ->
397 match im.im_module with
398 Some _ -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
401 try Some (Mod (lookup_module im.im_name))
403 try Some (Modtype (lookup_module_type im.im_name))
404 with Not_found -> None
407 None -> (acc_b_modif, (Name.head m_name) :: acc_incomplete_top_module_names,
408 (* we don't want to output warning messages for
409 "sig ... end" or "struct ... end" modules not found *)
410 (if im.im_name = Odoc_messages.struct_end or
411 im.im_name = Odoc_messages.sig_end then
414 (NF_mmt im.im_name) :: acc_names_not_found)
417 im.im_module <- Some mmt ;
418 (true, acc_incomplete_top_module_names, acc_names_not_found)
420 | Element_class cl -> associate_in_class module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) cl
421 | Element_class_type ct -> associate_in_class_type module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) ct
422 | Element_value _ -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
423 | Element_exception ex ->
425 match ex.ex_alias with
426 None -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
430 (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
433 try Some (lookup_exception ea.ea_name)
434 with Not_found -> None
437 None -> (acc_b_modif, (Name.head m_name) :: acc_incomplete_top_module_names, (NF_ex ea.ea_name) :: acc_names_not_found)
440 (true, acc_incomplete_top_module_names, acc_names_not_found)
442 | Element_type _ -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
443 | Element_module_comment _ -> (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found)
445 and associate_in_class module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) c =
446 let rec iter_kind (acc_b, acc_inc, acc_names) k =
448 Class_structure (inher_l, _) ->
449 let f (acc_b2, acc_inc2, acc_names2) ic =
450 match ic.ic_class with
451 Some _ -> (acc_b2, acc_inc2, acc_names2)
454 try Some (Cl (lookup_class ic.ic_name))
456 try Some (Cltype (lookup_class_type ic.ic_name, []))
457 with Not_found -> None
460 None -> (acc_b2, (Name.head c.cl_name) :: acc_inc2,
461 (* we don't want to output warning messages for "object ... end" classes not found *)
462 (if ic.ic_name = Odoc_messages.object_end then acc_names2 else (NF_cct ic.ic_name) :: acc_names2))
464 ic.ic_class <- Some cct ;
465 (true, acc_inc2, acc_names2)
467 List.fold_left f (acc_b, acc_inc, acc_names) inher_l
469 | Class_apply capp ->
471 match capp.capp_class with
472 Some _ -> (acc_b, acc_inc, acc_names)
475 try Some (lookup_class capp.capp_name)
476 with Not_found -> None
479 None -> (acc_b, (Name.head c.cl_name) :: acc_inc,
480 (* we don't want to output warning messages for "object ... end" classes not found *)
481 (if capp.capp_name = Odoc_messages.object_end then acc_names else (NF_c capp.capp_name) :: acc_names))
483 capp.capp_class <- Some c ;
484 (true, acc_inc, acc_names)
487 | Class_constr cco ->
489 match cco.cco_class with
490 Some _ -> (acc_b, acc_inc, acc_names)
493 try Some (lookup_class cco.cco_name)
494 with Not_found -> None
500 try Some (lookup_class_type cco.cco_name)
501 with Not_found -> None
505 (acc_b, (Name.head c.cl_name) :: acc_inc,
506 (* we don't want to output warning messages for "object ... end" classes not found *)
507 (if cco.cco_name = Odoc_messages.object_end then acc_names else (NF_cct cco.cco_name) :: acc_names))
509 cco.cco_class <- Some (Cltype (ct, [])) ;
510 (true, acc_inc, acc_names)
513 cco.cco_class <- Some (Cl c) ;
514 (true, acc_inc, acc_names)
516 | Class_constraint (ckind, ctkind) ->
517 let (acc_b2, acc_inc2, acc_names2) = iter_kind (acc_b, acc_inc, acc_names) ckind in
518 associate_in_class_type module_list (acc_b2, acc_inc2, acc_names2)
519 { clt_name = "" ; clt_info = None ;
520 clt_type = c.cl_type ; (* should be ok *)
521 clt_type_parameters = [] ;
522 clt_virtual = false ;
524 clt_loc = Odoc_types.dummy_loc }
526 iter_kind (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) c.cl_kind
528 and associate_in_class_type module_list (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) ct =
529 let rec iter_kind (acc_b, acc_inc, acc_names) k =
531 Class_signature (inher_l, _) ->
532 let f (acc_b2, acc_inc2, acc_names2) ic =
533 match ic.ic_class with
534 Some _ -> (acc_b2, acc_inc2, acc_names2)
537 try Some (Cltype (lookup_class_type ic.ic_name, []))
539 try Some (Cl (lookup_class ic.ic_name))
540 with Not_found -> None
543 None -> (acc_b2, (Name.head ct.clt_name) :: acc_inc2,
544 (* we don't want to output warning messages for "object ... end" class types not found *)
545 (if ic.ic_name = Odoc_messages.object_end then acc_names2 else (NF_cct ic.ic_name) :: acc_names2))
547 ic.ic_class <- Some cct ;
548 (true, acc_inc2, acc_names2)
550 List.fold_left f (acc_b, acc_inc, acc_names) inher_l
554 match cta.cta_class with
555 Some _ -> (acc_b, acc_inc, acc_names)
558 try Some (Cltype (lookup_class_type cta.cta_name, []))
560 try Some (Cl (lookup_class cta.cta_name))
561 with Not_found -> None
564 None -> (acc_b, (Name.head ct.clt_name) :: acc_inc,
565 (* we don't want to output warning messages for "object ... end" class types not found *)
566 (if cta.cta_name = Odoc_messages.object_end then acc_names else (NF_cct cta.cta_name) :: acc_names))
568 cta.cta_class <- Some c ;
569 (true, acc_inc, acc_names)
572 iter_kind (acc_b_modif, acc_incomplete_top_module_names, acc_names_not_found) ct.clt_kind
574 (*************************************************************)
575 (** Association of types to elements referenced in comments .*)
577 let ao = Odoc_misc.apply_opt
579 let not_found_of_kind kind name =
581 RK_module -> Odoc_messages.cross_module_not_found
582 | RK_module_type -> Odoc_messages.cross_module_type_not_found
583 | RK_class -> Odoc_messages.cross_class_not_found
584 | RK_class_type -> Odoc_messages.cross_class_type_not_found
585 | RK_value -> Odoc_messages.cross_value_not_found
586 | RK_type -> Odoc_messages.cross_type_not_found
587 | RK_exception -> Odoc_messages.cross_exception_not_found
588 | RK_attribute -> Odoc_messages.cross_attribute_not_found
589 | RK_method -> Odoc_messages.cross_method_not_found
590 | RK_section _ -> Odoc_messages.cross_section_not_found
593 let rec assoc_comments_text_elements parent_name module_list t_ele =
599 | Verbatim _ -> t_ele
600 | Bold t -> Bold (assoc_comments_text parent_name module_list t)
601 | Italic t -> Italic (assoc_comments_text parent_name module_list t)
602 | Center t -> Center (assoc_comments_text parent_name module_list t)
603 | Left t -> Left (assoc_comments_text parent_name module_list t)
604 | Right t -> Right (assoc_comments_text parent_name module_list t)
605 | Emphasize t -> Emphasize (assoc_comments_text parent_name module_list t)
606 | List l -> List (List.map (assoc_comments_text parent_name module_list) l)
607 | Enum l -> Enum (List.map (assoc_comments_text parent_name module_list) l)
609 | Block t -> Block (assoc_comments_text parent_name module_list t)
610 | Superscript t -> Superscript (assoc_comments_text parent_name module_list t)
611 | Subscript t -> Subscript (assoc_comments_text parent_name module_list t)
612 | Title (n, l_opt, t) -> Title (n, l_opt, (assoc_comments_text parent_name module_list t))
613 | Link (s, t) -> Link (s, (assoc_comments_text parent_name module_list t))
614 | Ref (initial_name, None) ->
616 let rec iter_parent ?parent_name name =
618 match get_known_elements name with
622 let re = Str.regexp ("^"^(Str.quote name)^"$") in
623 let t = Odoc_search.find_section module_list re in
624 let v2 = (name, Some (RK_section t)) in
626 (name, Some (RK_section t))
632 (* we look for the first element with this name *)
635 Odoc_search.Res_module m -> (m.m_name, RK_module)
636 | Odoc_search.Res_module_type mt -> (mt.mt_name, RK_module_type)
637 | Odoc_search.Res_class c -> (c.cl_name, RK_class)
638 | Odoc_search.Res_class_type ct -> (ct.clt_name, RK_class_type)
639 | Odoc_search.Res_value v -> (v.val_name, RK_value)
640 | Odoc_search.Res_type t -> (t.ty_name, RK_type)
641 | Odoc_search.Res_exception e -> (e.ex_name, RK_exception)
642 | Odoc_search.Res_attribute a -> (a.att_value.val_name, RK_attribute)
643 | Odoc_search.Res_method m -> (m.met_value.val_name, RK_method)
644 | Odoc_search.Res_section (_ ,t)-> assert false
646 add_verified (name, Some kind) ;
650 | (name, Some k) -> Ref (name, Some k)
652 match parent_name with
654 Odoc_messages.pwarning (Odoc_messages.cross_element_not_found initial_name);
655 Ref (initial_name, None)
658 match Name.father p with
662 iter_parent ?parent_name (Name.concat p initial_name)
664 iter_parent ~parent_name initial_name
666 | Ref (initial_name, Some kind) ->
668 let rec iter_parent ?parent_name name =
669 let v = (name, Some kind) in
670 if was_verified v then
671 Ref (name, Some kind)
677 (** we just verify that we find an element of this kind with this name *)
679 let re = Str.regexp ("^"^(Str.quote name)^"$") in
680 let t = Odoc_search.find_section module_list re in
681 let v2 = (name, Some (RK_section t)) in
683 (name, Some (RK_section t))
691 RK_module -> module_exists
692 | RK_module_type -> module_type_exists
693 | RK_class -> class_exists
694 | RK_class_type -> class_type_exists
695 | RK_value -> value_exists
696 | RK_type -> type_exists
697 | RK_exception -> exception_exists
698 | RK_attribute -> attribute_exists
699 | RK_method -> method_exists
700 | RK_section _ -> assert false
711 | (name, Some k) -> Ref (name, Some k)
713 match parent_name with
715 Odoc_messages.pwarning (not_found_of_kind kind initial_name);
716 Ref (initial_name, None)
719 match Name.father p with
723 iter_parent ?parent_name (Name.concat p initial_name)
725 iter_parent ~parent_name initial_name
731 | Custom (s,t) -> Custom (s, (assoc_comments_text parent_name module_list t))
733 and assoc_comments_text parent_name module_list text =
734 List.map (assoc_comments_text_elements parent_name module_list) text
736 and assoc_comments_info parent_name module_list i =
737 let ft = assoc_comments_text parent_name module_list in
740 i_desc = ao ft i.i_desc ;
741 i_sees = List.map (fun (sr, t) -> (sr, ft t)) i.i_sees;
742 i_deprecated = ao ft i.i_deprecated ;
743 i_params = List.map (fun (name, t) -> (name, ft t)) i.i_params;
744 i_raised_exceptions = List.map (fun (name, t) -> (name, ft t)) i.i_raised_exceptions;
745 i_return_value = ao ft i.i_return_value ;
746 i_custom = List.map (fun (tag, t) -> (tag, ft t)) i.i_custom ;
750 let rec assoc_comments_module_element parent_name module_list m_ele =
753 Element_module (assoc_comments_module module_list m)
754 | Element_module_type mt ->
755 Element_module_type (assoc_comments_module_type module_list mt)
756 | Element_included_module _ ->
757 m_ele (* don't go down into the aliases *)
759 Element_class (assoc_comments_class module_list c)
760 | Element_class_type ct ->
761 Element_class_type (assoc_comments_class_type module_list ct)
763 Element_value (assoc_comments_value module_list v)
764 | Element_exception e ->
765 Element_exception (assoc_comments_exception module_list e)
767 Element_type (assoc_comments_type module_list t)
768 | Element_module_comment t ->
769 Element_module_comment (assoc_comments_text parent_name module_list t)
771 and assoc_comments_class_element parent_name module_list c_ele =
774 Class_attribute (assoc_comments_attribute module_list a)
776 Class_method (assoc_comments_method module_list m)
778 Class_comment (assoc_comments_text parent_name module_list t)
780 and assoc_comments_module_kind parent_name module_list mk =
782 | Module_struct eles ->
784 (List.map (assoc_comments_module_element parent_name module_list) eles)
786 | Module_functor _ ->
788 | Module_apply (mk1, mk2) ->
789 Module_apply (assoc_comments_module_kind parent_name module_list mk1,
790 assoc_comments_module_kind parent_name module_list mk2)
791 | Module_with (mtk, s) ->
792 Module_with (assoc_comments_module_type_kind parent_name module_list mtk, s)
793 | Module_constraint (mk1, mtk) ->
795 (assoc_comments_module_kind parent_name module_list mk1,
796 assoc_comments_module_type_kind parent_name module_list mtk)
798 and assoc_comments_module_type_kind parent_name module_list mtk =
800 | Module_type_struct eles ->
802 (List.map (assoc_comments_module_element parent_name module_list) eles)
803 | Module_type_functor (params, mtk1) ->
805 (params, assoc_comments_module_type_kind parent_name module_list mtk1)
806 | Module_type_alias _ ->
808 | Module_type_with (mtk1, s) ->
810 (assoc_comments_module_type_kind parent_name module_list mtk1, s)
812 and assoc_comments_class_kind parent_name module_list ck =
814 Class_structure (inher, eles) ->
819 ic_text = ao (assoc_comments_text parent_name module_list) ic.ic_text })
823 (inher2, List.map (assoc_comments_class_element parent_name module_list) eles)
826 | Class_constr _ -> ck
827 | Class_constraint (ck1, ctk) ->
828 Class_constraint (assoc_comments_class_kind parent_name module_list ck1,
829 assoc_comments_class_type_kind parent_name module_list ctk)
831 and assoc_comments_class_type_kind parent_name module_list ctk =
833 Class_signature (inher, eles) ->
837 ic_text = ao (assoc_comments_text parent_name module_list) ic.ic_text })
840 Class_signature (inher2, List.map (assoc_comments_class_element parent_name module_list) eles)
842 | Class_type _ -> ctk
845 and assoc_comments_module module_list m =
846 m.m_info <- ao (assoc_comments_info m.m_name module_list) m.m_info ;
847 m.m_kind <- assoc_comments_module_kind m.m_name module_list m.m_kind ;
850 and assoc_comments_module_type module_list mt =
851 mt.mt_info <- ao (assoc_comments_info mt.mt_name module_list) mt.mt_info ;
852 mt.mt_kind <- ao (assoc_comments_module_type_kind mt.mt_name module_list) mt.mt_kind ;
855 and assoc_comments_class module_list c =
856 c.cl_info <- ao (assoc_comments_info c.cl_name module_list) c.cl_info ;
857 c.cl_kind <- assoc_comments_class_kind c.cl_name module_list c.cl_kind ;
858 assoc_comments_parameter_list c.cl_name module_list c.cl_parameters;
861 and assoc_comments_class_type module_list ct =
862 ct.clt_info <- ao (assoc_comments_info ct.clt_name module_list) ct.clt_info ;
863 ct.clt_kind <- assoc_comments_class_type_kind ct.clt_name module_list ct.clt_kind ;
866 and assoc_comments_parameter parent_name module_list p =
869 sn.sn_text <- ao (assoc_comments_text parent_name module_list) sn.sn_text
871 List.iter (assoc_comments_parameter parent_name module_list) l
873 and assoc_comments_parameter_list parent_name module_list pl =
874 List.iter (assoc_comments_parameter parent_name module_list) pl
876 and assoc_comments_value module_list v =
877 let parent = Name.father v.val_name in
878 v.val_info <- ao (assoc_comments_info parent module_list) v.val_info ;
879 assoc_comments_parameter_list parent module_list v.val_parameters;
882 and assoc_comments_exception module_list e =
883 let parent = Name.father e.ex_name in
884 e.ex_info <- ao (assoc_comments_info parent module_list) e.ex_info ;
887 and assoc_comments_type module_list t =
888 let parent = Name.father t.ty_name in
889 t.ty_info <- ao (assoc_comments_info parent module_list) t.ty_info ;
890 (match t.ty_kind with
894 (fun vc -> vc.vc_text <- ao (assoc_comments_text parent module_list) vc.vc_text)
898 (fun rf -> rf.rf_text <- ao (assoc_comments_text parent module_list) rf.rf_text)
903 and assoc_comments_attribute module_list a =
904 let _ = assoc_comments_value module_list a.att_value in
907 and assoc_comments_method module_list m =
908 let parent_name = Name.father m.met_value.val_name in
909 let _ = assoc_comments_value module_list m.met_value in
910 assoc_comments_parameter_list parent_name module_list m.met_value.val_parameters;
914 let associate_type_of_elements_in_comments module_list =
915 List.map (assoc_comments_module module_list) module_list
918 (***********************************************************)
919 (** The function which performs all the cross referencing. *)
920 let associate module_list =
921 get_alias_names module_list ;
922 init_known_elements_map module_list;
923 let rec remove_doubles acc = function
926 if List.mem h acc then remove_doubles acc q
927 else remove_doubles (h :: acc) q
929 let rec iter incomplete_modules =
930 let (b_modif, remaining_inc_modules, acc_names_not_found) =
931 List.fold_left (associate_in_module module_list) (false, [], []) incomplete_modules
933 let remaining_no_doubles = remove_doubles [] remaining_inc_modules in
934 let remaining_modules = List.filter
935 (fun m -> List.mem m.m_name remaining_no_doubles)
939 (* we may be able to associate something else *)
940 iter remaining_modules
942 (* nothing changed, we won't be able to associate any more *)
945 let names_not_found = iter module_list in
947 match names_not_found with
953 Odoc_messages.pwarning
956 NF_m n -> Odoc_messages.cross_module_not_found n
957 | NF_mt n -> Odoc_messages.cross_module_type_not_found n
958 | NF_mmt n -> Odoc_messages.cross_module_or_module_type_not_found n
959 | NF_c n -> Odoc_messages.cross_class_not_found n
960 | NF_ct n -> Odoc_messages.cross_class_type_not_found n
961 | NF_cct n -> Odoc_messages.cross_class_or_class_type_not_found n
962 | NF_ex n -> Odoc_messages.cross_exception_not_found n
968 (* Find a type for each name of element which is referenced in comments. *)
969 ignore (associate_type_of_elements_in_comments module_list)