8585092fcb6fc295c1f011fbdf4583551bacfff2
[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 MEntity
35
36 # Collect modifier keywords like `redef`, `private` etc.
37 fun collect_modifiers: Array[String] do
38 return new Array[String]
39 end
40 end
41
42 redef class MPackage
43 redef fun collect_modifiers do
44 var res = super
45 res.add "package"
46 return res
47 end
48 end
49
50 redef class MGroup
51 redef fun collect_modifiers do
52 var res = super
53 res.add "group"
54 return res
55 end
56 end
57
58 redef class MModule
59
60 redef fun collect_modifiers do
61 var res = super
62 res.add "module"
63 return res
64 end
65
66 # Collect all transitive imports.
67 fun collect_ancestors(view: ModelView): Set[MModule] do
68 var res = new HashSet[MModule]
69 for mentity in in_importation.greaters do
70 if mentity == self then continue
71 if not view.accept_mentity(mentity) then continue
72 res.add mentity
73 end
74 return res
75 end
76
77 # Collect direct imports.
78 fun collect_parents(view: ModelView): Set[MModule] do
79 var res = new HashSet[MModule]
80 for mentity in in_importation.direct_greaters do
81 if mentity == self then continue
82 if not view.accept_mentity(mentity) then continue
83 res.add mentity
84 end
85 return res
86 end
87
88 # Collect direct children (modules that directly import `self`).
89 fun collect_children(view: ModelView): Set[MModule] do
90 var res = new HashSet[MModule]
91 for mentity in in_importation.direct_smallers do
92 if mentity == self then continue
93 if not view.accept_mentity(mentity) then continue
94 res.add mentity
95 end
96 return res
97 end
98
99 # Collect all transitive children.
100 fun collect_descendants(view: ModelView): Set[MModule] do
101 var res = new HashSet[MModule]
102 for mentity in in_importation.smallers do
103 if mentity == self then continue
104 if not view.accept_mentity(mentity) then continue
105 res.add mentity
106 end
107 return res
108 end
109
110 # Build the importation poset for `self`
111 fun importation_poset(view: ModelView): POSet[MModule] do
112 var mmodules = new HashSet[MModule]
113 mmodules.add self
114 mmodules.add_all collect_ancestors(view)
115 mmodules.add_all collect_parents(view)
116 mmodules.add_all collect_children(view)
117 mmodules.add_all collect_descendants(view)
118 return view.mmodules_poset(mmodules)
119 end
120
121 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
122 fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
123 var res = new HashSet[MClassDef]
124 for mclassdef in mclassdefs do
125 if not mclassdef.is_intro then continue
126 if not view.accept_mentity(mclassdef) then continue
127 res.add mclassdef
128 end
129 return res
130 end
131
132 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
133 fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
134 var res = new HashSet[MClassDef]
135 for mclassdef in mclassdefs do
136 if mclassdef.is_intro then continue
137 if not view.accept_mentity(mclassdef) then continue
138 res.add mclassdef
139 end
140 return res
141 end
142
143 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
144 fun collect_intro_mclasses(view: ModelView): Set[MClass] do
145 var res = new HashSet[MClass]
146 for mclass in intro_mclasses do
147 if not view.accept_mentity(mclass) then continue
148 res.add mclass
149 end
150 return res
151 end
152
153 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
154 fun collect_redef_mclasses(view: ModelView): Set[MClass] do
155 var mclasses = new HashSet[MClass]
156 for mclassdef in mclassdefs do
157 if not view.accept_mentity(mclassdef) then continue
158 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
159 end
160 return mclasses
161 end
162 end
163
164 redef class MClass
165
166 redef fun collect_modifiers do return intro.collect_modifiers
167
168 # Collect direct parents of `self` with `visibility >= to min_visibility`.
169 fun collect_parents(view: ModelView): Set[MClass] do
170 var res = new HashSet[MClass]
171 for mclassdef in mclassdefs do
172 for mclasstype in mclassdef.supertypes do
173 var mclass = mclasstype.mclass
174 if not view.accept_mentity(mclass) then continue
175 res.add(mclass)
176 end
177 end
178 return res
179 end
180
181 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
182 fun collect_ancestors(view: ModelView): Set[MClass] do
183 var res = new HashSet[MClass]
184 for mclassdef in self.mclassdefs do
185 for super_mclassdef in mclassdef.in_hierarchy.greaters do
186 if super_mclassdef == mclassdef then continue # skip self
187 var mclass = super_mclassdef.mclass
188 if not view.accept_mentity(mclass) then continue
189 res.add(mclass)
190 end
191 end
192 return res
193 end
194
195 # Collect direct children of `self` with `visibility >= to min_visibility`.
196 fun collect_children(view: ModelView): Set[MClass] do
197 var res = new HashSet[MClass]
198 for mclassdef in self.mclassdefs do
199 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
200 if sub_mclassdef == mclassdef then continue # skip self
201 var mclass = sub_mclassdef.mclass
202 if not view.accept_mentity(mclass) then continue
203 res.add(mclass)
204 end
205 end
206 return res
207 end
208
209 # Collect all descendants of `self` with `visibility >= to min_visibility`.
210 fun collect_descendants(view: ModelView): Set[MClass] do
211 var res = new HashSet[MClass]
212 for mclassdef in self.mclassdefs do
213 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
214 if sub_mclassdef == mclassdef then continue # skip self
215 var mclass = sub_mclassdef.mclass
216 if not view.accept_mentity(mclass) then continue
217 res.add(mclass)
218 end
219 end
220 return res
221 end
222
223 # Build a class hierarchy poset for `self` based on its ancestors and descendants.
224 fun hierarchy_poset(mainmodule: MModule, view: ModelView): POSet[MClass] do
225 var mclasses = new HashSet[MClass]
226 mclasses.add self
227 mclasses.add_all collect_ancestors(view)
228 mclasses.add_all collect_descendants(view)
229 return view.mclasses_poset(mainmodule, mclasses)
230 end
231
232 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
233 fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
234 var set = new HashSet[MProperty]
235 for mclassdef in mclassdefs do
236 for mprop in mclassdef.intro_mproperties do
237 if not view.accept_mentity(mprop) then continue
238 set.add(mprop)
239 end
240 end
241 return set
242 end
243
244 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
245 fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
246 var set = new HashSet[MProperty]
247 for mclassdef in mclassdefs do
248 for mpropdef in mclassdef.mpropdefs do
249 if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
250 if not view.accept_mentity(mpropdef) then continue
251 set.add(mpropdef.mproperty)
252 end
253 end
254 return set
255 end
256
257 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
258 fun collect_local_mproperties(view: ModelView): Set[MProperty] do
259 var set = new HashSet[MProperty]
260 set.add_all collect_intro_mproperties(view)
261 set.add_all collect_redef_mproperties(view)
262 return set
263 end
264
265 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
266 fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
267 var set = new HashSet[MProperty]
268 for parent in collect_parents(view) do
269 set.add_all(parent.collect_intro_mproperties(view))
270 set.add_all(parent.collect_inherited_mproperties(view))
271 end
272 return set
273 end
274
275 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
276 #
277 # This include introduced, redefined, inherited mproperties.
278 fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
279 var set = new HashSet[MProperty]
280 set.add_all(collect_intro_mproperties(view))
281 set.add_all(collect_redef_mproperties(view))
282 set.add_all(collect_inherited_mproperties(view))
283 return set
284 end
285
286 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
287 fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
288 var res = new HashSet[MMethod]
289 for mproperty in collect_intro_mproperties(view) do
290 if mproperty isa MMethod then res.add(mproperty)
291 end
292 return res
293 end
294
295 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
296 fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
297 var res = new HashSet[MMethod]
298 for mproperty in collect_redef_mproperties(view) do
299 if mproperty isa MMethod then res.add(mproperty)
300 end
301 return res
302 end
303
304 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
305 fun collect_local_mmethods(view: ModelView): Set[MMethod] do
306 var set = new HashSet[MMethod]
307 set.add_all collect_intro_mmethods(view)
308 set.add_all collect_redef_mmethods(view)
309 return set
310 end
311
312 # Collect mmethods inherited by 'self' if accepted by `view`.
313 fun collect_inherited_mmethods(view: ModelView): Set[MMethod] do
314 var res = new HashSet[MMethod]
315 for mproperty in collect_inherited_mproperties(view) do
316 if mproperty isa MMethod then res.add(mproperty)
317 end
318 return res
319 end
320
321 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
322 fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
323 var res = new HashSet[MAttribute]
324 for mproperty in collect_intro_mproperties(view) do
325 if mproperty isa MAttribute then res.add(mproperty)
326 end
327 return res
328 end
329
330 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
331 fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
332 var res = new HashSet[MAttribute]
333 for mproperty in collect_redef_mproperties(view) do
334 if mproperty isa MAttribute then res.add(mproperty)
335 end
336 return res
337 end
338
339 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
340 fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
341 var set = new HashSet[MAttribute]
342 set.add_all collect_intro_mattributes(view)
343 set.add_all collect_redef_mattributes(view)
344 return set
345 end
346
347 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
348 fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
349 var res = new HashSet[MAttribute]
350 for mproperty in collect_inherited_mproperties(view) do
351 if mproperty isa MAttribute then res.add(mproperty)
352 end
353 return res
354 end
355
356 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
357 #
358 # This include introduced, redefined, inherited mattributes.
359 fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
360 var set = new HashSet[MAttribute]
361 set.add_all(collect_intro_mattributes(view))
362 set.add_all(collect_redef_mattributes(view))
363 set.add_all(collect_inherited_mattributes(view))
364 return set
365 end
366
367 # Collect init mmethods introduced in 'self' if accepted by `view`.
368 fun collect_intro_inits(view: ModelView): Set[MMethod] do
369 var res = new HashSet[MMethod]
370 for mproperty in collect_intro_mmethods(view) do
371 if mproperty.is_init then res.add(mproperty)
372 end
373 return res
374 end
375
376 # Collect init mmethods redefined in 'self' if accepted by `view`.
377 fun collect_redef_inits(view: ModelView): Set[MMethod] do
378 var res = new HashSet[MMethod]
379 for mproperty in collect_redef_mmethods(view) do
380 if mproperty.is_init then res.add(mproperty)
381 end
382 return res
383 end
384
385 # Collect init mmethods introduced and redefined in 'self' if accepted by `view`.
386 fun collect_local_inits(view: ModelView): Set[MMethod] do
387 var set = new HashSet[MMethod]
388 set.add_all collect_intro_inits(view)
389 set.add_all collect_redef_inits(view)
390 return set
391 end
392
393 # Collect init mmethods inherited by 'self' if accepted by `view`.
394 fun collect_inherited_inits(view: ModelView): Set[MMethod] do
395 var res = new HashSet[MMethod]
396 for mproperty in collect_inherited_mmethods(view) do
397 if mproperty.is_init then res.add(mproperty)
398 end
399 return res
400 end
401
402 # Collect all init mmethods accessible by 'self' if accepted by `view`.
403 #
404 # This include introduced, redefined, inherited inits.
405 fun collect_accessible_inits(view: ModelView): Set[MMethod] do
406 var set = new HashSet[MMethod]
407 set.add_all(collect_intro_inits(view))
408 set.add_all(collect_redef_inits(view))
409 set.add_all(collect_inherited_inits(view))
410 return set
411 end
412 end
413
414 redef class MClassDef
415
416 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
417 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
418 var res = new HashSet[MPropDef]
419 for mpropdef in mpropdefs do
420 if not view.accept_mentity(mpropdef) then continue
421 res.add mpropdef
422 end
423 return res
424 end
425
426 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
427 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
428 var res = new HashSet[MPropDef]
429 for mpropdef in mpropdefs do
430 if not mpropdef.is_intro then continue
431 if not view.accept_mentity(mpropdef) then continue
432 res.add mpropdef
433 end
434 return res
435 end
436
437 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
438 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
439 var res = new HashSet[MPropDef]
440 for mpropdef in mpropdefs do
441 if mpropdef.is_intro then continue
442 if not view.accept_mentity(mpropdef) then continue
443 res.add mpropdef
444 end
445 return res
446 end
447
448 redef fun collect_modifiers do
449 var res = super
450 if not is_intro then
451 res.add "redef"
452 else
453 res.add mclass.visibility.to_s
454 end
455 res.add mclass.kind.to_s
456 return res
457 end
458 end
459
460 redef class MProperty
461 redef fun collect_modifiers do return intro.collect_modifiers
462 end
463
464 redef class MPropDef
465 redef fun collect_modifiers do
466 var res = super
467 if not is_intro then
468 res.add "redef"
469 else
470 res.add mproperty.visibility.to_s
471 end
472 var mprop = self
473 if mprop isa MVirtualTypeDef then
474 res.add "type"
475 else if mprop isa MMethodDef then
476 if mprop.is_abstract then
477 res.add "abstract"
478 else if mprop.is_intern then
479 res.add "intern"
480 end
481 if mprop.mproperty.is_init then
482 res.add "init"
483 else
484 res.add "fun"
485 end
486 else if mprop isa MAttributeDef then
487 res.add "var"
488 end
489 return res
490 end
491 end