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