model_collect: collect more on MModule hierarchy
[nit.git] / src / model / model_collect.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Collect things from a `Model`.
18 #
19 # **Warning**
20 #
21 # `model_collect` offers a flattened view of the model without considering any
22 # main module.
23 # For this reason, `model_collect` lists all the definitions reachable from all
24 # modules
25 #
26 # This is usefull for tools that need a global view of a model like `nitdoc`,
27 # `nitx` or `nituml`.
28 # It shoul not be used for compiling stuffs like computing VFT, where the listed
29 # entities could not be reachable depending on the modules really imported.
30 module model_collect
31
32 import model_views
33
34 redef class MModule
35
36 # Collect all transitive imports.
37 fun collect_ancestors(view: ModelView): Set[MModule] do
38 var res = new HashSet[MModule]
39 for mentity in in_importation.greaters do
40 if mentity == self then continue
41 if not view.accept_mentity(mentity) then continue
42 res.add mentity
43 end
44 return res
45 end
46
47 # Collect direct imports.
48 fun collect_parents(view: ModelView): Set[MModule] do
49 var res = new HashSet[MModule]
50 for mentity in in_importation.direct_greaters do
51 if mentity == self then continue
52 if not view.accept_mentity(mentity) then continue
53 res.add mentity
54 end
55 return res
56 end
57
58 # Collect direct children (modules that directly import `self`).
59 fun collect_children(view: ModelView): Set[MModule] do
60 var res = new HashSet[MModule]
61 for mentity in in_importation.direct_smallers do
62 if mentity == self then continue
63 if not view.accept_mentity(mentity) then continue
64 res.add mentity
65 end
66 return res
67 end
68
69 # Collect all transitive children.
70 fun collect_descendants(view: ModelView): Set[MModule] do
71 var res = new HashSet[MModule]
72 for mentity in in_importation.smallers do
73 if mentity == self then continue
74 if not view.accept_mentity(mentity) then continue
75 res.add mentity
76 end
77 return res
78 end
79
80 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
81 fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
82 var res = new HashSet[MClassDef]
83 for mclassdef in mclassdefs do
84 if not mclassdef.is_intro then continue
85 if not view.accept_mentity(mclassdef) then continue
86 res.add mclassdef
87 end
88 return res
89 end
90
91 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
92 fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
93 var res = new HashSet[MClassDef]
94 for mclassdef in mclassdefs do
95 if mclassdef.is_intro then continue
96 if not view.accept_mentity(mclassdef) then continue
97 res.add mclassdef
98 end
99 return res
100 end
101
102 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
103 fun collect_intro_mclasses(view: ModelView): Set[MClass] do
104 var res = new HashSet[MClass]
105 for mclass in intro_mclasses do
106 if not view.accept_mentity(mclass) then continue
107 res.add mclass
108 end
109 return res
110 end
111
112 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
113 fun collect_redef_mclasses(view: ModelView): Set[MClass] do
114 var mclasses = new HashSet[MClass]
115 for mclassdef in mclassdefs do
116 if not view.accept_mentity(mclassdef) then continue
117 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
118 end
119 return mclasses
120 end
121 end
122
123 redef class MClass
124
125 # Collect direct parents of `self` with `visibility >= to min_visibility`.
126 fun collect_parents(view: ModelView): Set[MClass] do
127 var res = new HashSet[MClass]
128 for mclassdef in mclassdefs do
129 for mclasstype in mclassdef.supertypes do
130 var mclass = mclasstype.mclass
131 if not view.accept_mentity(mclass) then continue
132 res.add(mclass)
133 end
134 end
135 return res
136 end
137
138 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
139 fun collect_ancestors(view: ModelView): Set[MClass] do
140 var res = new HashSet[MClass]
141 for mclassdef in self.mclassdefs do
142 for super_mclassdef in mclassdef.in_hierarchy.greaters do
143 if super_mclassdef == mclassdef then continue # skip self
144 var mclass = super_mclassdef.mclass
145 if not view.accept_mentity(mclass) then continue
146 res.add(mclass)
147 end
148 end
149 return res
150 end
151
152 # Collect direct children of `self` with `visibility >= to min_visibility`.
153 fun collect_children(view: ModelView): Set[MClass] do
154 var res = new HashSet[MClass]
155 for mclassdef in self.mclassdefs do
156 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
157 if sub_mclassdef == mclassdef then continue # skip self
158 var mclass = sub_mclassdef.mclass
159 if not view.accept_mentity(mclass) then continue
160 res.add(mclass)
161 end
162 end
163 return res
164 end
165
166 # Collect all descendants of `self` with `visibility >= to min_visibility`.
167 fun collect_descendants(view: ModelView): Set[MClass] do
168 var res = new HashSet[MClass]
169 for mclassdef in self.mclassdefs do
170 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
171 if sub_mclassdef == mclassdef then continue # skip self
172 var mclass = sub_mclassdef.mclass
173 if not view.accept_mentity(mclass) then continue
174 res.add(mclass)
175 end
176 end
177 return res
178 end
179
180 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
181 fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
182 var set = new HashSet[MProperty]
183 for mclassdef in mclassdefs do
184 for mprop in mclassdef.intro_mproperties do
185 if not view.accept_mentity(mprop) then continue
186 set.add(mprop)
187 end
188 end
189 return set
190 end
191
192 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
193 fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
194 var set = new HashSet[MProperty]
195 for mclassdef in mclassdefs do
196 for mpropdef in mclassdef.mpropdefs do
197 if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
198 if not view.accept_mentity(mpropdef) then continue
199 set.add(mpropdef.mproperty)
200 end
201 end
202 return set
203 end
204
205 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
206 fun collect_local_mproperties(view: ModelView): Set[MProperty] do
207 var set = new HashSet[MProperty]
208 set.add_all collect_intro_mproperties(view)
209 set.add_all collect_redef_mproperties(view)
210 return set
211 end
212
213 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
214 fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
215 var set = new HashSet[MProperty]
216 for parent in collect_parents(view) do
217 set.add_all(parent.collect_intro_mproperties(view))
218 set.add_all(parent.collect_inherited_mproperties(view))
219 end
220 return set
221 end
222
223 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
224 #
225 # This include introduced, redefined, inherited mproperties.
226 fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
227 var set = new HashSet[MProperty]
228 set.add_all(collect_intro_mproperties(view))
229 set.add_all(collect_redef_mproperties(view))
230 set.add_all(collect_inherited_mproperties(view))
231 return set
232 end
233
234 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
235 fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
236 var res = new HashSet[MMethod]
237 for mproperty in collect_intro_mproperties(view) do
238 if mproperty isa MMethod then res.add(mproperty)
239 end
240 return res
241 end
242
243 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
244 fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
245 var res = new HashSet[MMethod]
246 for mproperty in collect_redef_mproperties(view) do
247 if mproperty isa MMethod then res.add(mproperty)
248 end
249 return res
250 end
251
252 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
253 fun collect_local_mmethods(view: ModelView): Set[MMethod] do
254 var set = new HashSet[MMethod]
255 set.add_all collect_intro_mmethods(view)
256 set.add_all collect_redef_mmethods(view)
257 return set
258 end
259
260 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
261 fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
262 var res = new HashSet[MAttribute]
263 for mproperty in collect_intro_mproperties(view) do
264 if mproperty isa MAttribute then res.add(mproperty)
265 end
266 return res
267 end
268
269 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
270 fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
271 var res = new HashSet[MAttribute]
272 for mproperty in collect_redef_mproperties(view) do
273 if mproperty isa MAttribute then res.add(mproperty)
274 end
275 return res
276 end
277
278 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
279 fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
280 var set = new HashSet[MAttribute]
281 set.add_all collect_intro_mattributes(view)
282 set.add_all collect_redef_mattributes(view)
283 return set
284 end
285
286 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
287 fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
288 var res = new HashSet[MAttribute]
289 for mproperty in collect_inherited_mproperties(view) do
290 if mproperty isa MAttribute then res.add(mproperty)
291 end
292 return res
293 end
294
295 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
296 #
297 # This include introduced, redefined, inherited mattributes.
298 fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
299 var set = new HashSet[MAttribute]
300 set.add_all(collect_intro_mattributes(view))
301 set.add_all(collect_redef_mattributes(view))
302 set.add_all(collect_inherited_mattributes(view))
303 return set
304 end
305 end
306
307 redef class MClassDef
308
309 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
310 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
311 var res = new HashSet[MPropDef]
312 for mpropdef in mpropdefs do
313 if not view.accept_mentity(mpropdef) then continue
314 res.add mpropdef
315 end
316 return res
317 end
318
319 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
320 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
321 var res = new HashSet[MPropDef]
322 for mpropdef in mpropdefs do
323 if not mpropdef.is_intro then continue
324 if not view.accept_mentity(mpropdef) then continue
325 res.add mpropdef
326 end
327 return res
328 end
329
330 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
331 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
332 var res = new HashSet[MPropDef]
333 for mpropdef in mpropdefs do
334 if mpropdef.is_intro then continue
335 if not view.accept_mentity(mpropdef) then continue
336 res.add mpropdef
337 end
338 return res
339 end
340
341 # Collect modifiers like redef, private etc.
342 fun collect_modifiers: Array[String] do
343 var res = new Array[String]
344 if not is_intro then
345 res.add "redef"
346 else
347 res.add mclass.visibility.to_s
348 end
349 res.add mclass.kind.to_s
350 return res
351 end
352 end
353
354 redef class MPropDef
355 # Collect modifiers like redef, private, abstract, intern, fun etc.
356 fun collect_modifiers: Array[String] do
357 var res = new Array[String]
358 if not is_intro then
359 res.add "redef"
360 else
361 res.add mproperty.visibility.to_s
362 end
363 var mprop = self
364 if mprop isa MVirtualTypeDef then
365 res.add "type"
366 else if mprop isa MMethodDef then
367 if mprop.is_abstract then
368 res.add "abstract"
369 else if mprop.is_intern then
370 res.add "intern"
371 end
372 if mprop.mproperty.is_init then
373 res.add "init"
374 else
375 res.add "fun"
376 end
377 end
378 return res
379 end
380 end