Add copyright notices and new function String.chomp
[ocaml.git] / ocamldoc / odoc_merge.ml
blob468c4711396dbecb9adeb5788b8ba8b83afd012d
1 (***********************************************************************)
2 (* OCamldoc *)
3 (* *)
4 (* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
5 (* *)
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. *)
9 (* *)
10 (***********************************************************************)
12 (* $Id$ *)
14 (** Merge of information from [.ml] and [.mli] for a module.*)
16 open Odoc_types
18 module Name = Odoc_name
19 open Odoc_parameter
20 open Odoc_value
21 open Odoc_type
22 open Odoc_exception
23 open Odoc_class
24 open Odoc_module
26 (** Merge two Odoctypes.info struture, completing the information of
27 the first one with the information in the second one.
28 The merge treatment depends on a given merge_option list.
29 @return the new info structure.*)
30 let merge_info merge_options (m1 : info) (m2 : info) =
31 let new_desc_opt =
32 match m1.i_desc, m2.i_desc with
33 None, None -> None
34 | None, Some d
35 | Some d, None -> Some d
36 | Some d1, Some d2 ->
37 if List.mem Merge_description merge_options then
38 Some (d1 @ (Newline :: d2))
39 else
40 Some d1
42 let new_authors =
43 match m1.i_authors, m2.i_authors with
44 [], [] -> []
45 | l, []
46 | [], l -> l
47 | l1, l2 ->
48 if List.mem Merge_author merge_options then
49 l1 @ l2
50 else
53 let new_version =
54 match m1.i_version , m2.i_version with
55 None, None -> None
56 | Some v, None
57 | None, Some v -> Some v
58 | Some v1, Some v2 ->
59 if List.mem Merge_version merge_options then
60 Some (v1^" "^v2)
61 else
62 Some v1
64 let new_sees =
65 match m1.i_sees, m2.i_sees with
66 [], [] -> []
67 | l, []
68 | [], l -> l
69 | l1, l2 ->
70 if List.mem Merge_see merge_options then
71 l1 @ l2
72 else
75 let new_since =
76 match m1.i_since, m2.i_since with
77 None, None -> None
78 | Some v, None
79 | None, Some v -> Some v
80 | Some v1, Some v2 ->
81 if List.mem Merge_since merge_options then
82 Some (v1^" "^v2)
83 else
84 Some v1
86 let new_dep =
87 match m1.i_deprecated, m2.i_deprecated with
88 None, None -> None
89 | None, Some t
90 | Some t, None -> Some t
91 | Some t1, Some t2 ->
92 if List.mem Merge_deprecated merge_options then
93 Some (t1 @ (Newline :: t2))
94 else
95 Some t1
97 let new_params =
98 match m1.i_params, m2.i_params with
99 [], [] -> []
100 | l, []
101 | [], l -> l
102 | l1, l2 ->
103 if List.mem Merge_param merge_options then
105 let l_in_m1_and_m2, l_in_m2_only = List.partition
106 (fun (param2, _) -> List.mem_assoc param2 l1)
109 let rec iter = function
110 [] -> []
111 | (param2, desc2) :: q ->
112 let desc1 = List.assoc param2 l1 in
113 (param2, desc1 @ (Newline :: desc2)) :: (iter q)
115 let l1_completed = iter l_in_m1_and_m2 in
116 l1_completed @ l_in_m2_only
118 else
121 let new_raised_exceptions =
122 match m1.i_raised_exceptions, m2.i_raised_exceptions with
123 [], [] -> []
124 | l, []
125 | [], l -> l
126 | l1, l2 ->
127 if List.mem Merge_raised_exception merge_options then
129 let l_in_m1_and_m2, l_in_m2_only = List.partition
130 (fun (exc2, _) -> List.mem_assoc exc2 l1)
133 let rec iter = function
134 [] -> []
135 | (exc2, desc2) :: q ->
136 let desc1 = List.assoc exc2 l1 in
137 (exc2, desc1 @ (Newline :: desc2)) :: (iter q)
139 let l1_completed = iter l_in_m1_and_m2 in
140 l1_completed @ l_in_m2_only
142 else
145 let new_rv =
146 match m1.i_return_value, m2.i_return_value with
147 None, None -> None
148 | None, Some t
149 | Some t, None -> Some t
150 | Some t1, Some t2 ->
151 if List.mem Merge_return_value merge_options then
152 Some (t1 @ (Newline :: t2))
153 else
154 Some t1
156 let new_custom =
157 match m1.i_custom, m2.i_custom with
158 [], [] -> []
159 | [], l
160 | l, [] -> l
161 | l1, l2 ->
162 if List.mem Merge_custom merge_options then
163 l1 @ l2
164 else
168 Odoc_types.i_desc = new_desc_opt ;
169 Odoc_types.i_authors = new_authors ;
170 Odoc_types.i_version = new_version ;
171 Odoc_types.i_sees = new_sees ;
172 Odoc_types.i_since = new_since ;
173 Odoc_types.i_deprecated = new_dep ;
174 Odoc_types.i_params = new_params ;
175 Odoc_types.i_raised_exceptions = new_raised_exceptions ;
176 Odoc_types.i_return_value = new_rv ;
177 Odoc_types.i_custom = new_custom ;
180 (** Merge of two optional info structures. *)
181 let merge_info_opt merge_options mli_opt ml_opt =
182 match mli_opt, ml_opt with
183 None, Some i -> Some i
184 | Some i, None -> Some i
185 | None, None -> None
186 | Some i1, Some i2 -> Some (merge_info merge_options i1 i2)
188 (** merge of two t_type, one for a .mli, another for the .ml.
189 The .mli type is completed with the information in the .ml type. *)
190 let merge_types merge_options mli ml =
191 mli.ty_info <- merge_info_opt merge_options mli.ty_info ml.ty_info;
192 mli.ty_loc <- { mli.ty_loc with loc_impl = ml.ty_loc.loc_impl } ;
193 mli.ty_code <- (match mli.ty_code with None -> ml.ty_code | _ -> mli.ty_code) ;
195 match mli.ty_kind, ml.ty_kind with
196 Type_abstract, _ ->
199 | Type_variant (l1, _), Type_variant (l2, _) ->
200 let f cons =
202 let cons2 = List.find
203 (fun c2 -> c2.vc_name = cons.vc_name)
206 let new_desc =
207 match cons.vc_text, cons2.vc_text with
208 None, None -> None
209 | Some d, None
210 | None, Some d -> Some d
211 | Some d1, Some d2 ->
212 if List.mem Merge_description merge_options then
213 Some (d1 @ d2)
214 else
215 Some d1
217 cons.vc_text <- new_desc
218 with
219 Not_found ->
220 if !Odoc_args.inverse_merge_ml_mli then
222 else
223 raise (Failure (Odoc_messages.different_types mli.ty_name))
225 List.iter f l1
227 | Type_record (l1, _), Type_record (l2, _) ->
228 let f record =
230 let record2= List.find
231 (fun r -> r.rf_name = record.rf_name)
234 let new_desc =
235 match record.rf_text, record2.rf_text with
236 None, None -> None
237 | Some d, None
238 | None, Some d -> Some d
239 | Some d1, Some d2 ->
240 if List.mem Merge_description merge_options then
241 Some (d1 @ d2)
242 else
243 Some d1
245 record.rf_text <- new_desc
246 with
247 Not_found ->
248 if !Odoc_args.inverse_merge_ml_mli then
250 else
251 raise (Failure (Odoc_messages.different_types mli.ty_name))
253 List.iter f l1
255 | _ ->
256 if !Odoc_args.inverse_merge_ml_mli then
258 else
259 raise (Failure (Odoc_messages.different_types mli.ty_name))
261 (** Merge of two param_info, one from a .mli, one from a .ml.
262 The text fields are not handled but will be recreated from the
263 i_params field of the info structure.
264 Here, if a parameter in the .mli has no name, we take the one
265 from the .ml. When two parameters have two different forms,
266 we take the one from the .mli. *)
267 let rec merge_param_info pi_mli pi_ml =
268 match (pi_mli, pi_ml) with
269 (Simple_name sn_mli, Simple_name sn_ml) ->
270 if sn_mli.sn_name = "" then
271 Simple_name { sn_mli with sn_name = sn_ml.sn_name }
272 else
273 pi_mli
274 | (Simple_name _, Tuple _) ->
275 pi_mli
276 | (Tuple (_, t_mli), Simple_name sn_ml) ->
277 (* if we're here, then the tuple in the .mli has no parameter names ;
278 then we take the name of the parameter of the .ml and the type of the .mli. *)
279 Simple_name { sn_ml with sn_type = t_mli }
281 | (Tuple (l_mli, t_mli), Tuple (l_ml, _)) ->
282 (* if the two tuples have different lengths
283 (which should not occurs), we return the pi_mli,
284 without further investigation.*)
285 if (List.length l_mli) <> (List.length l_ml) then
286 pi_mli
287 else
288 let new_l = List.map2 merge_param_info l_mli l_ml in
289 Tuple (new_l, t_mli)
291 (** Merge of the parameters of two functions/methods/classes, one for a .mli, another for a .ml.
292 The prameters in the .mli are completed by the name in the .ml.*)
293 let rec merge_parameters param_mli param_ml =
294 match (param_mli, param_ml) with
295 ([], []) -> []
296 | (l, []) | ([], l) -> l
297 | ((pi_mli :: li), (pi_ml :: l)) ->
298 (merge_param_info pi_mli pi_ml) :: merge_parameters li l
300 (** Merge of two t_class, one for a .mli, another for the .ml.
301 The .mli class is completed with the information in the .ml class. *)
302 let merge_classes merge_options mli ml =
303 mli.cl_info <- merge_info_opt merge_options mli.cl_info ml.cl_info;
304 mli.cl_loc <- { mli.cl_loc with loc_impl = ml.cl_loc.loc_impl } ;
305 mli.cl_parameters <- merge_parameters mli.cl_parameters ml.cl_parameters;
307 (* we must reassociate comments in @param to the the corresponding
308 parameters because the associated comment of a parameter may have been changed y the merge.*)
309 Odoc_class.class_update_parameters_text mli;
311 (* merge values *)
312 List.iter
313 (fun a ->
315 let _ = List.find
316 (fun ele ->
317 match ele with
318 Class_attribute a2 ->
319 if a2.att_value.val_name = a.att_value.val_name then
321 a.att_value.val_info <- merge_info_opt merge_options
322 a.att_value.val_info a2.att_value.val_info;
323 a.att_value.val_loc <- { a.att_value.val_loc with loc_impl = a2.att_value.val_loc.loc_impl } ;
324 if !Odoc_args.keep_code then
325 a.att_value.val_code <- a2.att_value.val_code;
326 true
328 else
329 false
330 | _ ->
331 false
333 (* we look for the last attribute with this name defined in the implementation *)
334 (List.rev (Odoc_class.class_elements ml))
337 with
338 Not_found ->
341 (Odoc_class.class_attributes mli);
342 (* merge methods *)
343 List.iter
344 (fun m ->
346 let _ = List.find
347 (fun ele ->
348 match ele with
349 Class_method m2 ->
350 if m2.met_value.val_name = m.met_value.val_name then
352 m.met_value.val_info <- merge_info_opt
353 merge_options m.met_value.val_info m2.met_value.val_info;
354 m.met_value.val_loc <- { m.met_value.val_loc with loc_impl = m2.met_value.val_loc.loc_impl } ;
355 (* merge the parameter names *)
356 m.met_value.val_parameters <- (merge_parameters
357 m.met_value.val_parameters
358 m2.met_value.val_parameters) ;
359 (* we must reassociate comments in @param to the corresponding
360 parameters because the associated comment of a parameter may have been changed by the merge.*)
361 Odoc_value.update_value_parameters_text m.met_value;
363 if !Odoc_args.keep_code then
364 m.met_value.val_code <- m2.met_value.val_code;
366 true
368 else
369 false
370 | _ ->
371 false
373 (* we look for the last method with this name defined in the implementation *)
374 (List.rev (Odoc_class.class_elements ml))
377 with
378 Not_found ->
381 (Odoc_class.class_methods mli)
383 (** merge of two t_class_type, one for a .mli, another for the .ml.
384 The .mli class is completed with the information in the .ml class. *)
385 let merge_class_types merge_options mli ml =
386 mli.clt_info <- merge_info_opt merge_options mli.clt_info ml.clt_info;
387 mli.clt_loc <- { mli.clt_loc with loc_impl = ml.clt_loc.loc_impl } ;
388 (* merge values *)
389 List.iter
390 (fun a ->
392 let _ = List.find
393 (fun ele ->
394 match ele with
395 Class_attribute a2 ->
396 if a2.att_value.val_name = a.att_value.val_name then
398 a.att_value.val_info <- merge_info_opt merge_options
399 a.att_value.val_info a2.att_value.val_info;
400 a.att_value.val_loc <- { a.att_value.val_loc with loc_impl = a2.att_value.val_loc.loc_impl } ;
401 if !Odoc_args.keep_code then
402 a.att_value.val_code <- a2.att_value.val_code;
404 true
406 else
407 false
408 | _ ->
409 false
411 (* we look for the last attribute with this name defined in the implementation *)
412 (List.rev (Odoc_class.class_type_elements ml))
415 with
416 Not_found ->
419 (Odoc_class.class_type_attributes mli);
420 (* merge methods *)
421 List.iter
422 (fun m ->
424 let _ = List.find
425 (fun ele ->
426 match ele with
427 Class_method m2 ->
428 if m2.met_value.val_name = m.met_value.val_name then
430 m.met_value.val_info <- merge_info_opt
431 merge_options m.met_value.val_info m2.met_value.val_info;
432 m.met_value.val_loc <- { m.met_value.val_loc with loc_impl = m2.met_value.val_loc.loc_impl } ;
433 m.met_value.val_parameters <- (merge_parameters
434 m.met_value.val_parameters
435 m2.met_value.val_parameters) ;
436 (* we must reassociate comments in @param to the the corresponding
437 parameters because the associated comment of a parameter may have been changed y the merge.*)
438 Odoc_value.update_value_parameters_text m.met_value;
440 if !Odoc_args.keep_code then
441 m.met_value.val_code <- m2.met_value.val_code;
443 true
445 else
446 false
447 | _ ->
448 false
450 (* we look for the last method with this name defined in the implementation *)
451 (List.rev (Odoc_class.class_type_elements ml))
454 with
455 Not_found ->
458 (Odoc_class.class_type_methods mli)
461 (** merge of two t_module_type, one for a .mli, another for the .ml.
462 The .mli module is completed with the information in the .ml module. *)
463 let rec merge_module_types merge_options mli ml =
464 mli.mt_info <- merge_info_opt merge_options mli.mt_info ml.mt_info;
465 mli.mt_loc <- { mli.mt_loc with loc_impl = ml.mt_loc.loc_impl } ;
466 (* merge exceptions *)
467 List.iter
468 (fun ex ->
470 let _ = List.find
471 (fun ele ->
472 match ele with
473 Element_exception ex2 ->
474 if ex2.ex_name = ex.ex_name then
476 ex.ex_info <- merge_info_opt merge_options ex.ex_info ex2.ex_info;
477 ex.ex_loc <- { ex.ex_loc with loc_impl = ex2.ex_loc.loc_impl } ;
478 ex.ex_code <- (match ex.ex_code with None -> ex2.ex_code | _ -> ex.ex_code) ;
479 true
481 else
482 false
483 | _ ->
484 false
486 (* we look for the last exception with this name defined in the implementation *)
487 (List.rev (Odoc_module.module_type_elements ml))
490 with
491 Not_found ->
494 (Odoc_module.module_type_exceptions mli);
495 (* merge types *)
496 List.iter
497 (fun ty ->
499 let _ = List.find
500 (fun ele ->
501 match ele with
502 Element_type ty2 ->
503 if ty2.ty_name = ty.ty_name then
505 merge_types merge_options ty ty2;
506 true
508 else
509 false
510 | _ ->
511 false
513 (* we look for the last type with this name defined in the implementation *)
514 (List.rev (Odoc_module.module_type_elements ml))
517 with
518 Not_found ->
521 (Odoc_module.module_type_types mli);
522 (* merge submodules *)
523 List.iter
524 (fun m ->
526 let _ = List.find
527 (fun ele ->
528 match ele with
529 Element_module m2 ->
530 if m2.m_name = m.m_name then
532 ignore (merge_modules merge_options m m2);
534 m.m_info <- merge_info_opt merge_options m.m_info m2.m_info;
535 m.m_loc <- { m.m_loc with loc_impl = m2.m_loc.loc_impl } ;
537 true
539 else
540 false
541 | _ ->
542 false
544 (* we look for the last module with this name defined in the implementation *)
545 (List.rev (Odoc_module.module_type_elements ml))
548 with
549 Not_found ->
552 (Odoc_module.module_type_modules mli);
554 (* merge module types *)
555 List.iter
556 (fun m ->
558 let _ = List.find
559 (fun ele ->
560 match ele with
561 Element_module_type m2 ->
562 if m2.mt_name = m.mt_name then
564 merge_module_types merge_options m m2;
565 true
567 else
568 false
569 | _ ->
570 false
572 (* we look for the last module with this name defined in the implementation *)
573 (List.rev (Odoc_module.module_type_elements ml))
576 with
577 Not_found ->
580 (Odoc_module.module_type_module_types mli);
582 (* A VOIR : merge included modules ? *)
584 (* merge values *)
585 List.iter
586 (fun v ->
588 let _ = List.find
589 (fun ele ->
590 match ele with
591 Element_value v2 ->
592 if v2.val_name = v.val_name then
594 v.val_info <- merge_info_opt merge_options v.val_info v2.val_info ;
595 v.val_loc <- { v.val_loc with loc_impl = v2.val_loc.loc_impl } ;
596 (* in the .mli we don't know any parameters so we add the ones in the .ml *)
597 v.val_parameters <- (merge_parameters
598 v.val_parameters
599 v2.val_parameters) ;
600 (* we must reassociate comments in @param to the the corresponding
601 parameters because the associated comment of a parameter may have been changed y the merge.*)
602 Odoc_value.update_value_parameters_text v;
604 if !Odoc_args.keep_code then
605 v.val_code <- v2.val_code;
607 true
609 else
610 false
611 | _ ->
612 false
614 (* we look for the last value with this name defined in the implementation *)
615 (List.rev (Odoc_module.module_type_elements ml))
618 with
619 Not_found ->
622 (Odoc_module.module_type_values mli);
624 (* merge classes *)
625 List.iter
626 (fun c ->
628 let _ = List.find
629 (fun ele ->
630 match ele with
631 Element_class c2 ->
632 if c2.cl_name = c.cl_name then
634 merge_classes merge_options c c2;
635 true
637 else
638 false
639 | _ ->
640 false
642 (* we look for the last value with this name defined in the implementation *)
643 (List.rev (Odoc_module.module_type_elements ml))
646 with
647 Not_found ->
650 (Odoc_module.module_type_classes mli);
652 (* merge class types *)
653 List.iter
654 (fun c ->
656 let _ = List.find
657 (fun ele ->
658 match ele with
659 Element_class_type c2 ->
660 if c2.clt_name = c.clt_name then
662 merge_class_types merge_options c c2;
663 true
665 else
666 false
667 | _ ->
668 false
670 (* we look for the last value with this name defined in the implementation *)
671 (List.rev (Odoc_module.module_type_elements ml))
674 with
675 Not_found ->
678 (Odoc_module.module_type_class_types mli)
680 (** merge of two t_module, one for a .mli, another for the .ml.
681 The .mli module is completed with the information in the .ml module. *)
682 and merge_modules merge_options mli ml =
683 mli.m_info <- merge_info_opt merge_options mli.m_info ml.m_info;
684 mli.m_loc <- { mli.m_loc with loc_impl = ml.m_loc.loc_impl } ;
685 let rec remove_doubles acc = function
686 [] -> acc
687 | h :: q ->
688 if List.mem h acc then remove_doubles acc q
689 else remove_doubles (h :: acc) q
691 mli.m_top_deps <- remove_doubles mli.m_top_deps ml.m_top_deps ;
693 let code =
694 if !Odoc_args.keep_code then
695 match mli.m_code, ml.m_code with
696 Some s, _ -> Some s
697 | _, Some s -> Some s
698 | _ -> None
699 else
700 None
702 let code_intf =
703 if !Odoc_args.keep_code then
704 match mli.m_code_intf, ml.m_code_intf with
705 Some s, _ -> Some s
706 | _, Some s -> Some s
707 | _ -> None
708 else
709 None
711 mli.m_code <- code;
712 mli.m_code_intf <- code_intf;
714 (* merge exceptions *)
715 List.iter
716 (fun ex ->
718 let _ = List.find
719 (fun ele ->
720 match ele with
721 Element_exception ex2 ->
722 if ex2.ex_name = ex.ex_name then
724 ex.ex_info <- merge_info_opt merge_options ex.ex_info ex2.ex_info;
725 ex.ex_loc <- { ex.ex_loc with loc_impl = ex.ex_loc.loc_impl } ;
726 ex.ex_code <- (match ex.ex_code with None -> ex2.ex_code | _ -> ex.ex_code) ;
727 true
729 else
730 false
731 | _ ->
732 false
734 (* we look for the last exception with this name defined in the implementation *)
735 (List.rev (Odoc_module.module_elements ml))
738 with
739 Not_found ->
742 (Odoc_module.module_exceptions mli);
743 (* merge types *)
744 List.iter
745 (fun ty ->
747 let _ = List.find
748 (fun ele ->
749 match ele with
750 Element_type ty2 ->
751 if ty2.ty_name = ty.ty_name then
753 merge_types merge_options ty ty2;
754 true
756 else
757 false
758 | _ ->
759 false
761 (* we look for the last type with this name defined in the implementation *)
762 (List.rev (Odoc_module.module_elements ml))
765 with
766 Not_found ->
769 (Odoc_module.module_types mli);
770 (* merge submodules *)
771 List.iter
772 (fun m ->
774 let _ = List.find
775 (fun ele ->
776 match ele with
777 Element_module m2 ->
778 if m2.m_name = m.m_name then
780 ignore (merge_modules merge_options m m2);
782 m.m_info <- merge_info_opt merge_options m.m_info m2.m_info;
783 m.m_loc <- { m.m_loc with loc_impl = m2.m_loc.loc_impl } ;
785 true
787 else
788 false
789 | _ ->
790 false
792 (* we look for the last module with this name defined in the implementation *)
793 (List.rev (Odoc_module.module_elements ml))
796 with
797 Not_found ->
800 (Odoc_module.module_modules mli);
802 (* merge module types *)
803 List.iter
804 (fun m ->
806 let _ = List.find
807 (fun ele ->
808 match ele with
809 Element_module_type m2 ->
810 if m2.mt_name = m.mt_name then
812 merge_module_types merge_options m m2;
813 true
815 else
816 false
817 | _ ->
818 false
820 (* we look for the last module with this name defined in the implementation *)
821 (List.rev (Odoc_module.module_elements ml))
824 with
825 Not_found ->
828 (Odoc_module.module_module_types mli);
830 (* A VOIR : merge included modules ? *)
832 (* merge values *)
833 List.iter
834 (fun v ->
836 let _ = List.find
837 (fun v2 ->
838 if v2.val_name = v.val_name then
840 v.val_info <- merge_info_opt merge_options v.val_info v2.val_info ;
841 v.val_loc <- { v.val_loc with loc_impl = v2.val_loc.loc_impl } ;
842 (* in the .mli we don't know any parameters so we add the ones in the .ml *)
843 v.val_parameters <- (merge_parameters
844 v.val_parameters
845 v2.val_parameters) ;
846 (* we must reassociate comments in @param to the the corresponding
847 parameters because the associated comment of a parameter may have been changed y the merge.*)
848 Odoc_value.update_value_parameters_text v;
850 if !Odoc_args.keep_code then
851 v.val_code <- v2.val_code;
852 true
854 else
855 false
857 (* we look for the last value with this name defined in the implementation *)
858 (List.rev (Odoc_module.module_values ml))
861 with
862 Not_found ->
865 (Odoc_module.module_values mli);
867 (* merge classes *)
868 List.iter
869 (fun c ->
871 let _ = List.find
872 (fun ele ->
873 match ele with
874 Element_class c2 ->
875 if c2.cl_name = c.cl_name then
877 merge_classes merge_options c c2;
878 true
880 else
881 false
882 | _ ->
883 false
885 (* we look for the last value with this name defined in the implementation *)
886 (List.rev (Odoc_module.module_elements ml))
889 with
890 Not_found ->
893 (Odoc_module.module_classes mli);
895 (* merge class types *)
896 List.iter
897 (fun c ->
899 let _ = List.find
900 (fun ele ->
901 match ele with
902 Element_class_type c2 ->
903 if c2.clt_name = c.clt_name then
905 merge_class_types merge_options c c2;
906 true
908 else
909 false
910 | _ ->
911 false
913 (* we look for the last value with this name defined in the implementation *)
914 (List.rev (Odoc_module.module_elements ml))
917 with
918 Not_found ->
921 (Odoc_module.module_class_types mli);
925 let merge merge_options modules_list =
926 let rec iter = function
927 [] -> []
928 | m :: q ->
929 (* look for another module with the same name *)
930 let (l_same, l_others) = List.partition
931 (fun m2 -> m.m_name = m2.m_name)
934 match l_same with
935 [] ->
936 (* no other module to merge with *)
937 m :: (iter l_others)
938 | m2 :: [] ->
940 (* we can merge m with m2 if there is an implementation
941 and an interface.*)
942 let f b = if !Odoc_args.inverse_merge_ml_mli then not b else b in
943 match f m.m_is_interface, f m2.m_is_interface with
944 true, false -> (merge_modules merge_options m m2) :: (iter l_others)
945 | false, true -> (merge_modules merge_options m2 m) :: (iter l_others)
946 | false, false ->
947 if !Odoc_args.inverse_merge_ml_mli then
948 (* two Module.ts for the .mli ! *)
949 raise (Failure (Odoc_messages.two_interfaces m.m_name))
950 else
951 (* two Module.t for the .ml ! *)
952 raise (Failure (Odoc_messages.two_implementations m.m_name))
953 | true, true ->
954 if !Odoc_args.inverse_merge_ml_mli then
955 (* two Module.t for the .ml ! *)
956 raise (Failure (Odoc_messages.two_implementations m.m_name))
957 else
958 (* two Module.ts for the .mli ! *)
959 raise (Failure (Odoc_messages.two_interfaces m.m_name))
961 | _ ->
962 (* two many Module.t ! *)
963 raise (Failure (Odoc_messages.too_many_module_objects m.m_name))
966 iter modules_list