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 (***********************************************************************)
14 (** Top modules dependencies. *)
16 module StrS
= Depend.StringSet
17 module Module
= Odoc_module
18 module Type
= Odoc_type
22 StrS.iter
(fun e
-> l := e
:: !l) s
;
25 let impl_dependencies ast
=
26 Depend.free_structure_names
:= StrS.empty
;
27 Depend.add_use_file
StrS.empty
[Parsetree.Ptop_def ast
];
28 set_to_list !Depend.free_structure_names
30 let intf_dependencies ast
=
31 Depend.free_structure_names
:= StrS.empty
;
32 Depend.add_signature
StrS.empty ast
;
33 set_to_list !Depend.free_structure_names
40 module S
= Set.Make
(struct type t
= string let compare = compare end)
44 S.iter
(fun e
-> l := e
:: !l) s
;
49 mutable near
: S.t
; (** fils directs *)
50 mutable far
: (id
* S.t
) list
; (** fils indirects, par quel fils *)
51 reflex
: bool ; (** reflexive or not, we keep
52 information here to remove the node itself from its direct children *)
55 type graph
= node list
57 let make_node s children
=
58 let set = List.fold_right
64 near
= S.remove s
set ;
66 reflex
= List.mem s children
;
69 let get_node graph s
=
70 try List.find
(fun n
-> n
.id
= s
) graph
74 let rec trans_closure graph acc n
=
75 if S.mem n
.id acc
then
78 (* optimisation plus tard : utiliser le champ far si non vide ? *)
80 (fun child
-> fun acc2
->
81 trans_closure graph acc2
(get_node graph child
))
85 let node_trans_closure graph n
=
88 let set = trans_closure graph
S.empty
(get_node graph child
) in
95 let compute_trans_closure graph
=
96 List.iter
(node_trans_closure graph
) graph
98 let prune_node graph node
=
101 let set_reachables = List.fold_left
102 (fun acc
-> fun (ch
, reachables
) ->
106 S.union acc reachables
111 let set = S.remove node
.id
set_reachables in
112 if S.exists
(fun n2
-> S.mem child
(get_node graph n2
).near
) set then
114 node
.near
<- S.remove child node
.near
;
115 node
.far <- List.filter
(fun (ch
,_
) -> ch
<> child
) node
.far
122 node
.near
<- S.add node
.id node
.near
127 (* compute transitive closure *)
128 compute_trans_closure graph
;
130 (* remove edges to keep a transitive kernel *)
131 List.iter
(prune_node graph
) graph
;
137 (** [type_deps t] returns the list of fully qualified type names
140 let module T
= Odoc_type
in
142 let re = Str.regexp
"\\([A-Z]\\([a-zA-Z_'0-9]\\)*\\.\\)+\\([a-z][a-zA-Z_'0-9]*\\)" in
144 let s2 = Str.matched_string s
in
148 (match t
.T.ty_kind
with
149 T.Type_abstract
-> ()
150 | T.Type_variant
(cl
, _
) ->
155 let s = Odoc_print.string_of_type_expr e
in
156 ignore
(Str.global_substitute
re f s)
161 | T.Type_record
(rl
, _
) ->
164 let s = Odoc_print.string_of_type_expr r
.T.rf_type
in
165 ignore
(Str.global_substitute
re f s)
170 (match t
.T.ty_manifest
with
173 let s = Odoc_print.string_of_type_expr e
in
174 ignore
(Str.global_substitute
re f s)
179 (** Modify the modules depencies of the given list of modules,
180 to get the minimum transitivity kernel. *)
181 let kernel_deps_of_modules modules
=
183 (fun m
-> Dep.make_node m
.Module.m_name m
.Module.m_top_deps
)
186 let k = Dep.kernel graph in
189 let node = Dep.get_node k m
.Module.m_name
in
190 m
.Module.m_top_deps
<-
191 List.filter
(fun m2
-> Dep.S.mem m2
node.Dep.near
) m
.Module.m_top_deps
)
194 (** Return the list of dependencies between the given types,
195 in the form of a list [(type, names of types it depends on)].
196 @param kernel indicates if we must keep only the transitivity kernel
197 of the dependencies. Default is [false].
199 let deps_of_types ?
(kernel=false) types
=
200 let deps_pre = List.map
(fun t
-> (t
, type_deps t
)) types
in
205 (fun (t
, names
) -> Dep.make_node t
.Type.ty_name names
)
208 let k = Dep.kernel graph in
211 let node = Dep.get_node k t
.Type.ty_name
in
212 (t
, Dep.set_to_list node.Dep.near
)