Merge: doc: fixed some typos and other misc. corrections
[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 the model.
18 #
19 # This module introduce several usefull methods to list and count things from a
20 # Model.
21 #
22 # ~~~nitish
23 # print number of parents for `{my_class}`
24 # print my_class.collect_parents.count
25 # ~~~
26 #
27 # Collect methods can also be used with a ModelFilter:
28 # ~~~nitish
29 # var filter = new ModelFilter(min_visibility = private_visibility)
30 # print my_class.collect_parents(filter).count
31 # ~~~
32 #
33 # **Warning**
34 #
35 # `model_collect` offers a flattened filter of the model without considering any
36 # main module.
37 # For this reason, `model_collect` lists all the definitions reachable from all
38 # modules.
39 #
40 # This is usefull for tools that need a global filter of a model like `nitdoc`,
41 # `nitx`, `nitmetrics` or `nituml`.
42 # It should not be used for compiling stuffs like computing VFT, where the listed
43 # entities could not be reachable depending on the modules really imported.
44 module model_collect
45
46 import model_filters
47
48 redef class MEntity
49
50 # FIXME used to bypass RTA limitation on type resolution
51 type MENTITY: SELF
52
53 # Collect modifier keywords like `redef`, `private` etc
54 fun collect_modifiers: Array[String] do return new Array[String]
55
56 # Collect `self` linearization anchored on `mainmodule`
57 fun collect_linearization(mainmodule: MModule): nullable Array[MEntity] do
58 return null
59 end
60
61 # Collect `self` ancestors (direct and indirect)
62 #
63 # The concept of ancestor is abstract at this stage.
64 fun collect_ancestors(mainmodule: MModule, filter: nullable ModelFilter): Set[MENTITY] do
65 var done = new HashSet[MENTITY]
66 var todo = new Array[MENTITY]
67
68 todo.add_all collect_parents(mainmodule, filter)
69 while todo.not_empty do
70 var mentity = todo.pop
71 if mentity == self or done.has(mentity) then continue
72 done.add mentity
73 todo.add_all mentity.collect_parents(mainmodule, filter)
74 end
75 return done
76 end
77
78 # Collect `self` parents (direct ancestors)
79 #
80 # The concept of parent is abstract at this stage.
81 fun collect_parents(mainmodule: MModule, filter: nullable ModelFilter): Set[MENTITY] is abstract
82
83 # Collect `self` children (direct descendants)
84 #
85 # The concept of child is abstract at this stage.
86 fun collect_children(mainmodule: MModule, filter: nullable ModelFilter): Set[MENTITY] is abstract
87
88 # Collect `self` descendants (direct and direct)
89 #
90 # The concept of descendant is abstract at this stage.
91 fun collect_descendants(mainmodule: MModule, filter: nullable ModelFilter): Set[MENTITY] do
92 var done = new HashSet[MENTITY]
93 var todo = new Array[MENTITY]
94
95 todo.add_all collect_children(mainmodule, filter)
96 while todo.not_empty do
97 var mentity = todo.pop
98 if mentity == self or done.has(mentity) then continue
99 done.add mentity
100 todo.add_all mentity.collect_children(mainmodule, filter)
101 end
102 return done
103 end
104
105 # Build a poset representing `self` in it's own hierarchy
106 #
107 # The notion of hierarchy depends on the type of MEntity.
108 #
109 # Here a recap:
110 # * `MPackage`: package dependencies
111 # * `MGroup`: group dependencies
112 # * `MModule`: modules imports
113 # * `MClass`: class inheritance (all classdefs flattened)
114 # * `MClassDef`: classdef inheritance
115 # * `MProperty`: property definitions graph (all propdefs flattened)
116 # * `MPropDef`: property definitions graph
117 fun hierarchy_poset(mainmodule: MModule, filter: nullable ModelFilter): POSet[MENTITY] do
118 var poset = new POSet[MENTITY]
119 var parents_done = new HashSet[MENTITY]
120 var parents = new Array[MENTITY]
121 parents.add self
122 while parents.not_empty do
123 var mentity = parents.pop
124 if parents_done.has(mentity) then continue
125 parents_done.add mentity
126 poset.add_node mentity
127 for parent in mentity.collect_parents(mainmodule, filter) do
128 poset.add_edge(mentity, parent)
129 parents.add parent
130 end
131 end
132 var children_done = new HashSet[MEntity]
133 var children = new Array[MEntity]
134 children.add self
135 while children.not_empty do
136 var mentity = children.pop
137 if children_done.has(mentity) then continue
138 children_done.add mentity
139 for child in mentity.collect_children(mainmodule, filter) do
140 poset.add_edge(child, mentity)
141 children.add child
142 end
143 end
144 return poset
145 end
146 end
147
148 redef class Model
149
150 # Collect all MPackages in `self`
151 fun collect_mpackages(filter: nullable ModelFilter): HashSet[MPackage] do
152 var res = new HashSet[MPackage]
153 for mpackage in mpackages do
154 if filter == null or filter.accept_mentity(mpackage) then res.add(mpackage)
155 end
156 return res
157 end
158
159 # Collect all MGroups in `self`
160 fun collect_mgroups(filter: nullable ModelFilter): HashSet[MGroup] do
161 var res = new HashSet[MGroup]
162 for mpackage in collect_mpackages(filter) do
163 res.add_all mpackage.collect_all_mgroups(filter)
164 end
165 return res
166 end
167
168 # Collect all MModules in `self`
169 fun collect_mmodules(filter: nullable ModelFilter): HashSet[MModule] do
170 var res = new HashSet[MModule]
171 for mpackage in collect_mpackages(filter) do
172 res.add_all mpackage.collect_all_mmodules(filter)
173 end
174 return res
175 end
176
177 # Collect all MClasses in `self`
178 fun collect_mclasses(filter: nullable ModelFilter): HashSet[MClass] do
179 var res = new HashSet[MClass]
180 for mclass in mclasses do
181 if filter == null or filter.accept_mentity(mclass) then res.add mclass
182 end
183 return res
184 end
185
186 # Collect all MClasses introduced in `self`
187 fun collect_intro_mclasses(filter: nullable ModelFilter): HashSet[MClass] do
188 var res = new HashSet[MClass]
189 for mpackage in collect_mpackages(filter) do
190 res.add_all mpackage.collect_intro_mclasses(filter)
191 end
192 return res
193 end
194
195 # Collect all MClassDefs in `self`
196 fun collect_mclassdefs(filter: nullable ModelFilter): HashSet[MClassDef] do
197 var res = new HashSet[MClassDef]
198 for mclass in collect_mclasses(filter) do
199 res.add_all mclass.collect_mclassdefs(filter)
200 end
201 return res
202 end
203
204 # Collect all MProperties introduced in `self`
205 fun collect_intro_mproperties(filter: nullable ModelFilter): HashSet[MProperty] do
206 var res = new HashSet[MProperty]
207 for mpackage in collect_mpackages(filter) do
208 res.add_all mpackage.collect_intro_mproperties(filter)
209 end
210 return res
211 end
212
213 # Collect all MProperties in `self`
214 fun collect_mproperties(filter: nullable ModelFilter): HashSet[MProperty] do
215 var res = new HashSet[MProperty]
216 for mproperty in mproperties do
217 if filter == null or filter.accept_mentity(mproperty) then res.add mproperty
218 end
219 return res
220 end
221
222 # Collect all MPropDefs in `self`
223 fun collect_mpropdefs(filter: nullable ModelFilter): HashSet[MPropDef] do
224 var res = new HashSet[MPropDef]
225 for mproperty in collect_mproperties(filter) do
226 for mpropdef in mproperty.mpropdefs do
227 if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
228 end
229 end
230 return res
231 end
232
233 # Collect all MEntities in `self`
234 fun collect_mentities(filter: nullable ModelFilter): HashSet[MEntity] do
235 var res = new HashSet[MEntity]
236 res.add_all collect_mpackages(filter)
237 res.add_all collect_mgroups(filter)
238 res.add_all collect_mmodules(filter)
239 res.add_all collect_mclasses(filter)
240 res.add_all collect_mclassdefs(filter)
241 res.add_all collect_mproperties(filter)
242 res.add_all collect_mpropdefs(filter)
243 return res
244 end
245
246 # Searches the MEntity that matches `full_name`.
247 fun mentity_by_full_name(full_name: String, filter: nullable ModelFilter): nullable MEntity do
248 for mentity in collect_mentities(filter) do
249 if filter != null and not filter.accept_mentity(mentity) then continue
250 if mentity.full_name == full_name then return mentity
251 end
252 return null
253 end
254
255 # Searches the MEntities that matches `full_name`.
256 fun mentities_by_name(name: String, filter: nullable ModelFilter): Array[MEntity] do
257 var res = new Array[MEntity]
258 for mentity in collect_mentities(filter) do
259 if filter != null and not filter.accept_mentity(mentity) then continue
260 if mentity.name == name then res.add mentity
261 end
262 return res
263 end
264 end
265
266 redef class MPackage
267
268 redef fun collect_modifiers do return super + ["package"]
269
270 # Collect all packages directly imported by `self`
271 redef fun collect_parents(mainmodule, filter) do
272 var res = new HashSet[MENTITY]
273 for mgroup in mgroups do
274 for parent in mgroup.collect_parents(mainmodule, filter) do
275 var mpackage = parent.mpackage
276 if mpackage == self then continue
277 if filter == null or filter.accept_mentity(mpackage) then res.add(mpackage)
278 end
279 end
280 return res
281 end
282
283 # Collect all packages that directly depends on `self`
284 redef fun collect_children(mainmodule, filter) do
285 var res = new HashSet[MENTITY]
286 for mpackage in model.collect_mpackages(filter) do
287 if mpackage.collect_parents(mainmodule, filter).has(self) then res.add mpackage
288 end
289 return res
290 end
291
292 # Collect all groups contained in `self`
293 fun collect_all_mgroups(filter: nullable ModelFilter): HashSet[MGroup] do
294 var res = new HashSet[MGroup]
295 for mgroup in mgroups do
296 if filter == null or filter.accept_mentity(mgroup) then res.add(mgroup)
297 end
298 return res
299 end
300
301 # Collect only groups contained in `self.root`
302 fun collect_mgroups(filter: nullable ModelFilter): HashSet[MGroup] do
303 var res = new HashSet[MGroup]
304 var root = self.root
305 if root == null then return res
306 res.add_all root.collect_mgroups(filter)
307 return res
308 end
309
310 # Collect all modules contained in `self`
311 fun collect_all_mmodules(filter: nullable ModelFilter): HashSet[MModule] do
312 var res = new HashSet[MModule]
313 for mgroup in collect_all_mgroups(filter) do
314 res.add_all mgroup.collect_mmodules(filter)
315 end
316 return res
317 end
318
319 # Collect only modules contained in `self.root`
320 fun collect_mmodules(filter: nullable ModelFilter): HashSet[MModule] do
321 var res = new HashSet[MModule]
322 var root = self.root
323 if root == null then return res
324 res.add_all root.collect_mmodules(filter)
325 return res
326 end
327
328 # Collect all classes introduced in `self`
329 fun collect_intro_mclasses(filter: nullable ModelFilter): HashSet[MClass] do
330 var res = new HashSet[MClass]
331 for mgroup in mgroups do
332 for mmodule in collect_all_mmodules(filter) do
333 res.add_all mmodule.collect_intro_mclasses(filter)
334 end
335 end
336 return res
337 end
338
339 # Collect all classes redefined or refined in `self`
340 fun collect_redef_mclasses(filter: nullable ModelFilter): Set[MClass] do
341 var res = new HashSet[MClass]
342 for mgroup in mgroups do
343 for mmodule in collect_all_mmodules(filter) do
344 res.add_all mmodule.collect_redef_mclasses(filter)
345 end
346 end
347 return res
348 end
349
350 # Collect all properties introduced in `self`
351 fun collect_intro_mproperties(filter: nullable ModelFilter): HashSet[MProperty] do
352 var res = new HashSet[MProperty]
353 for mgroup in mgroups do
354 for mmodule in collect_all_mmodules(filter) do
355 res.add_all mmodule.collect_intro_mproperties(filter)
356 end
357 end
358 return res
359 end
360
361 # Collect all properties redefined in `self`
362 fun collect_redef_mproperties(filter: nullable ModelFilter): HashSet[MProperty] do
363 var res = new HashSet[MProperty]
364 for mgroup in mgroups do
365 for mmodule in collect_all_mmodules(filter) do
366 res.add_all mmodule.collect_redef_mproperties(filter)
367 end
368 end
369 return res
370 end
371
372 # Collect all attributes introduced in `self`
373 fun collect_intro_attributes(filter: nullable ModelFilter): Set[MAttribute] do
374 var res = new HashSet[MAttribute]
375 for mgroup in mgroups do
376 for mmodule in collect_all_mmodules(filter) do
377 res.add_all mmodule.collect_intro_attributes(filter)
378 end
379 end
380 return res
381 end
382
383 # Collect all inits introduced in `self`
384 fun collect_intro_inits(filter: nullable ModelFilter): Set[MMethod] do
385 var res = new HashSet[MMethod]
386 for mgroup in mgroups do
387 for mmodule in collect_all_mmodules(filter) do
388 res.add_all mmodule.collect_intro_inits(filter)
389 end
390 end
391 return res
392 end
393
394 # Collect all methods introduced in `self` excluding inits
395 #
396 # See `collect_intro_inits`.
397 fun collect_intro_methods(filter: nullable ModelFilter): Set[MMethod] do
398 var res = new HashSet[MMethod]
399 for mgroup in mgroups do
400 for mmodule in collect_all_mmodules(filter) do
401 res.add_all mmodule.collect_intro_methods(filter)
402 end
403 end
404 return res
405 end
406
407 # Collect all virtual types introduced in `self`
408 fun collect_intro_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
409 var res = new HashSet[MVirtualTypeProp]
410 for mgroup in mgroups do
411 for mmodule in collect_all_mmodules(filter) do
412 res.add_all mmodule.collect_intro_vts(filter)
413 end
414 end
415 return res
416 end
417 end
418
419 redef class MGroup
420
421 redef fun collect_modifiers do return super + ["group"]
422
423 # Collect all groups directly import by `self`
424 redef fun collect_parents(mainmodule, filter) do
425 var res = new HashSet[MENTITY]
426 for mmodule in mmodules do
427 for parent in mmodule.collect_parents(mainmodule, filter) do
428 var mgroup = parent.mgroup
429 if mgroup == null or mgroup == self then continue
430 if filter == null or filter.accept_mentity(mgroup) then res.add(mgroup)
431 end
432 end
433 return res
434 end
435
436 # Collect all group that directly import `self`
437 redef fun collect_children(mainmodule, filter) do
438 var res = new HashSet[MENTITY]
439 for mgroup in model.collect_mgroups(filter) do
440 if mgroup == self then continue
441 if filter != null and not filter.accept_mentity(mgroup) then continue
442 if mgroup.collect_parents(mainmodule, filter).has(self) then res.add mgroup
443 end
444 return res
445 end
446
447 # Collect all groups contained in `self`
448 fun collect_mgroups(filter: nullable ModelFilter): HashSet[MENTITY] do
449 var res = new HashSet[MENTITY]
450 for mgroup in in_nesting.direct_smallers do
451 if filter == null or filter.accept_mentity(mgroup) then res.add(mgroup)
452 end
453 return res
454 end
455
456 # Collect all modules contained in `self`
457 fun collect_all_mmodules(filter: nullable ModelFilter): HashSet[MModule] do
458 var res = new HashSet[MModule]
459 for mgroup in collect_mgroups(filter) do
460 res.add_all mgroup.collect_all_mmodules(filter)
461 end
462 return res
463 end
464
465 # Collect all modules contained in `self`
466 fun collect_mmodules(filter: nullable ModelFilter): HashSet[MModule] do
467 var res = new HashSet[MModule]
468 for mmodule in mmodules do
469 if filter == null or filter.accept_mentity(mmodule) then res.add(mmodule)
470 end
471 return res
472 end
473 end
474
475 redef class MModule
476
477 redef fun collect_modifiers do return super + ["module"]
478
479 # Collect all modules directly imported by `self`
480 redef fun collect_ancestors(mainmodule, filter) do
481 var res = new HashSet[MENTITY]
482 for mentity in in_importation.greaters do
483 if mentity == self then continue
484 if filter == null or filter.accept_mentity(mentity) then res.add mentity
485 end
486 return res
487 end
488
489 # Collect all modules directly imported by `self`
490 redef fun collect_parents(mainmodule, filter) do
491 var res = new HashSet[MENTITY]
492 for mentity in in_importation.direct_greaters do
493 if mentity == self then continue
494 if filter == null or filter.accept_mentity(mentity) then res.add mentity
495 end
496 return res
497 end
498
499 # Collect all modules that directly import `self`
500 redef fun collect_children(mainmodule, filter) do
501 var res = new HashSet[MENTITY]
502 for mentity in in_importation.direct_smallers do
503 if mentity == self then continue
504 if filter == null or filter.accept_mentity(mentity) then res.add mentity
505 end
506 return res
507 end
508
509 # Collect all module descendants of `self` (direct and transitive imports)
510 redef fun collect_descendants(mainmodule, filter) do
511 var res = new HashSet[MENTITY]
512 for mentity in in_importation.smallers do
513 if mentity == self then continue
514 if filter == null or filter.accept_mentity(mentity) then res.add mentity
515 end
516 return res
517 end
518
519 # Collect all class definitions introduced in `self`
520 fun collect_intro_mclassdefs(filter: nullable ModelFilter): Set[MClassDef] do
521 var res = new HashSet[MClassDef]
522 for mclassdef in mclassdefs do
523 if not mclassdef.is_intro then continue
524 if filter == null or filter.accept_mentity(mclassdef) then res.add mclassdef
525 end
526 return res
527 end
528
529 # Collect all class definitions refined in `self`
530 fun collect_redef_mclassdefs(filter: nullable ModelFilter): Set[MClassDef] do
531 var res = new HashSet[MClassDef]
532 for mclassdef in mclassdefs do
533 if mclassdef.is_intro then continue
534 if filter == null or filter.accept_mentity(mclassdef) then res.add mclassdef
535 end
536 return res
537 end
538
539 # Collect all class definitions introduced and refined in `self`
540 fun collect_local_mclassdefs(filter: nullable ModelFilter): Set[MClassDef] do
541 var res = new HashSet[MClassDef]
542 res.add_all collect_intro_mclassdefs(filter)
543 res.add_all collect_redef_mclassdefs(filter)
544 return res
545 end
546
547 # Collect all classes introduced in `self`
548 fun collect_intro_mclasses(filter: nullable ModelFilter): Set[MClass] do
549 var res = new HashSet[MClass]
550 for mclass in intro_mclasses do
551 if filter == null or filter.accept_mentity(mclass) then res.add mclass
552 end
553 return res
554 end
555
556 # Collect all classes refined in `self`
557 fun collect_redef_mclasses(filter: nullable ModelFilter): Set[MClass] do
558 var mclasses = new HashSet[MClass]
559 for mclassdef in mclassdefs do
560 if filter != null and not filter.accept_mentity(mclassdef.mclass) then continue
561 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
562 end
563 return mclasses
564 end
565
566 # Collect all classes introduced and refined in `self`
567 fun collect_local_mclasses(filter: nullable ModelFilter): Set[MClass] do
568 var res = new HashSet[MClass]
569 res.add_all collect_intro_mclasses(filter)
570 res.add_all collect_redef_mclasses(filter)
571 return res
572 end
573
574 # Collect all classes imported from `self` parents
575 fun collect_imported_mclasses(mainmodule: MModule, filter: nullable ModelFilter): Set[MClass] do
576 var res = new HashSet[MClass]
577 for parent in collect_parents(mainmodule, filter) do
578 res.add_all parent.collect_intro_mclasses(filter)
579 res.add_all parent.collect_redef_mclasses(filter)
580 res.add_all parent.collect_imported_mclasses(mainmodule, filter)
581 end
582 return res
583 end
584
585 # Collect all properties introduced in `self`
586 fun collect_intro_mproperties(filter: nullable ModelFilter): Set[MProperty] do
587 var res = new HashSet[MProperty]
588 for mclass in collect_intro_mclasses(filter) do
589 res.add_all mclass.collect_intro_mproperties(filter)
590 end
591 return res
592 end
593
594 # Collect properties redefined in `self`
595 fun collect_redef_mproperties(filter: nullable ModelFilter): Set[MProperty] do
596 var res = new HashSet[MProperty]
597 for mclassdef in mclassdefs do
598 for mpropdef in mclassdef.collect_redef_mpropdefs(filter) do
599 res.add mpropdef.mproperty
600 end
601 end
602 return res
603 end
604
605 # Collect attributes introduced in `self`
606 fun collect_intro_attributes(filter: nullable ModelFilter): Set[MAttribute] do
607 var res = new HashSet[MAttribute]
608 for mproperty in collect_intro_mproperties(filter) do
609 if mproperty isa MAttribute then res.add(mproperty)
610 end
611 return res
612 end
613
614 # Collect all inits introduced in `self`
615 fun collect_intro_inits(filter: nullable ModelFilter): Set[MMethod] do
616 var res = new HashSet[MMethod]
617 for mproperty in collect_intro_mproperties(filter) do
618 if mproperty isa MMethod and mproperty.is_init then res.add(mproperty)
619 end
620 return res
621 end
622
623 # Collect methods introduced in `self` (without inits)
624 fun collect_intro_methods(filter: nullable ModelFilter): Set[MMethod] do
625 var res = new HashSet[MMethod]
626 for mproperty in collect_intro_mproperties(filter) do
627 if mproperty isa MMethod and not mproperty.is_init then res.add(mproperty)
628 end
629 return res
630 end
631
632 # Collect virtual types introduced in `self`
633 fun collect_intro_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
634 var res = new HashSet[MVirtualTypeProp]
635 for mproperty in collect_intro_mproperties(filter) do
636 if mproperty isa MVirtualTypeProp then res.add(mproperty)
637 end
638 return res
639 end
640 end
641
642 redef class MClass
643
644 redef fun collect_modifiers do return intro.collect_modifiers
645
646 redef fun collect_linearization(mainmodule) do
647 var mclassdefs = self.mclassdefs.to_a
648 mainmodule.linearize_mclassdefs(mclassdefs)
649 return mclassdefs
650 end
651
652 # Collect all ancestors of `self`
653 redef fun collect_ancestors(mainmodule, filter) do
654 var res = new HashSet[MENTITY]
655 if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
656 for mclass in in_hierarchy(mainmodule).greaters do
657 if mclass == self then continue
658 if filter == null or filter.accept_mentity(mclass) then res.add mclass
659 end
660 return res
661 end
662
663 # Collect all direct parents of `self`
664 redef fun collect_parents(mainmodule, filter) do
665 var res = new HashSet[MENTITY]
666 if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
667 for mclass in in_hierarchy(mainmodule).direct_greaters do
668 if mclass == self then continue
669 if filter == null or filter.accept_mentity(mclass) then res.add mclass
670 end
671 return res
672 end
673
674 # Collect all direct children of `self`
675 redef fun collect_children(mainmodule, filter) do
676 var res = new HashSet[MENTITY]
677 if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
678 for mclass in in_hierarchy(mainmodule).direct_smallers do
679 if mclass == self then continue
680 if filter == null or filter.accept_mentity(mclass) then res.add mclass
681 end
682 return res
683 end
684
685 # Collect all descendants of `self`
686 redef fun collect_descendants(mainmodule, filter) do
687 var res = new HashSet[MENTITY]
688 if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
689 for mclass in in_hierarchy(mainmodule).smallers do
690 if mclass == self then continue
691 if filter == null or filter.accept_mentity(mclass) then res.add mclass
692 end
693 return res
694 end
695
696 # Collect all class definitions of `self`
697 fun collect_mclassdefs(filter: nullable ModelFilter): Set[MClassDef] do
698 var res = new HashSet[MClassDef]
699 for mclassdef in mclassdefs do
700 if filter == null or filter.accept_mentity(mclassdef) then res.add mclassdef
701 end
702 return res
703 end
704
705 # Collect all property definitions that are introductions in `self`
706 fun collect_intro_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
707 var set = new HashSet[MPropDef]
708 for mclassdef in mclassdefs do
709 for mpropdef in mclassdef.mpropdefs do
710 if not mpropdef.is_intro then continue
711 if filter == null or filter.accept_mentity(mpropdef) then set.add(mpropdef)
712 end
713 end
714 return set
715 end
716
717 # Collect all properties introduced in `self`
718 fun collect_intro_mproperties(filter: nullable ModelFilter): Set[MProperty] do
719 var set = new HashSet[MProperty]
720 for mclassdef in mclassdefs do
721 for mprop in mclassdef.intro_mproperties do
722 if filter == null or filter.accept_mentity(mprop) then set.add(mprop)
723 end
724 end
725 return set
726 end
727
728 # Collect all propierty definitions that are redefinition in `self`
729 fun collect_redef_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
730 var set = new HashSet[MPropDef]
731 for mclassdef in mclassdefs do
732 for mpropdef in mclassdef.mpropdefs do
733 if mpropdef.is_intro then continue
734 if filter == null or filter.accept_mentity(mpropdef) then set.add(mpropdef)
735 end
736 end
737 return set
738 end
739
740 # Collect all properties redefined in `self`
741 fun collect_redef_mproperties(filter: nullable ModelFilter): Set[MProperty] do
742 var set = new HashSet[MProperty]
743 for mclassdef in mclassdefs do
744 for mpropdef in mclassdef.mpropdefs do
745 if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
746 if filter == null or filter.accept_mentity(mpropdef) then
747 set.add(mpropdef.mproperty)
748 end
749 end
750 end
751 return set
752 end
753
754 # Collect all properties introduced and redefined in `self`
755 fun collect_local_mproperties(filter: nullable ModelFilter): Set[MProperty] do
756 var set = new HashSet[MProperty]
757 set.add_all collect_intro_mproperties(filter)
758 set.add_all collect_redef_mproperties(filter)
759 return set
760 end
761
762 # Collect all properties inehrited by `self`
763 fun collect_inherited_mproperties(mainmodule: MModule, filter: nullable ModelFilter): Set[MProperty] do
764 var set = new HashSet[MProperty]
765 for parent in collect_parents(mainmodule, filter) do
766 set.add_all(parent.collect_intro_mproperties(filter))
767 set.add_all(parent.collect_inherited_mproperties(mainmodule, filter))
768 end
769 return set
770 end
771
772 # Collect all properties accessible by `self`
773 #
774 # This include introduced, redefined, inherited properties.
775 fun collect_accessible_mproperties(mainmodule: MModule, filter: nullable ModelFilter): Set[MProperty] do
776 var set = new HashSet[MProperty]
777 set.add_all(collect_intro_mproperties(filter))
778 set.add_all(collect_redef_mproperties(filter))
779 set.add_all(collect_inherited_mproperties(mainmodule, filter))
780 return set
781 end
782
783 # Collect all methods introduced in `self`
784 fun collect_intro_mmethods(filter: nullable ModelFilter): Set[MMethod] do
785 var res = new HashSet[MMethod]
786 for mproperty in collect_intro_mproperties(filter) do
787 if mproperty isa MMethod then res.add(mproperty)
788 end
789 return res
790 end
791
792 # Collect all methods redefined in `self`
793 fun collect_redef_mmethods(filter: nullable ModelFilter): Set[MMethod] do
794 var res = new HashSet[MMethod]
795 for mproperty in collect_redef_mproperties(filter) do
796 if mproperty isa MMethod then res.add(mproperty)
797 end
798 return res
799 end
800
801 # Collect all methods introduced and redefined in `self`
802 fun collect_local_mmethods(filter: nullable ModelFilter): Set[MMethod] do
803 var set = new HashSet[MMethod]
804 set.add_all collect_intro_mmethods(filter)
805 set.add_all collect_redef_mmethods(filter)
806 return set
807 end
808
809 # Collect all methods inherited by `self`
810 fun collect_inherited_mmethods(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
811 var res = new HashSet[MMethod]
812 for mproperty in collect_inherited_mproperties(mainmodule, filter) do
813 if mproperty isa MMethod then res.add(mproperty)
814 end
815 return res
816 end
817
818 # Collect all methods accessible by `self`
819 #
820 # This include introduced, redefined, inherited methods.
821 fun collect_accessible_mmethods(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
822 var set = new HashSet[MMethod]
823 set.add_all(collect_intro_mmethods(filter))
824 set.add_all(collect_redef_mmethods(filter))
825 set.add_all(collect_inherited_mmethods(mainmodule, filter))
826 return set
827 end
828
829 # Collect all attributes introduced in `self`
830 fun collect_intro_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
831 var res = new HashSet[MAttribute]
832 for mproperty in collect_intro_mproperties(filter) do
833 if mproperty isa MAttribute then res.add(mproperty)
834 end
835 return res
836 end
837
838 # Collect all attributes redefined in `self`
839 fun collect_redef_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
840 var res = new HashSet[MAttribute]
841 for mproperty in collect_redef_mproperties(filter) do
842 if mproperty isa MAttribute then res.add(mproperty)
843 end
844 return res
845 end
846
847 # Collect all attributes introduced and redefined in `self`
848 fun collect_local_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
849 var set = new HashSet[MAttribute]
850 set.add_all collect_intro_mattributes(filter)
851 set.add_all collect_redef_mattributes(filter)
852 return set
853 end
854
855 # Collect all attributes inherited by `self`
856 fun collect_inherited_mattributes(mainmodule: MModule, filter: nullable ModelFilter): Set[MAttribute] do
857 var res = new HashSet[MAttribute]
858 for mproperty in collect_inherited_mproperties(mainmodule, filter) do
859 if mproperty isa MAttribute then res.add(mproperty)
860 end
861 return res
862 end
863
864 # Collect all attributes accessible by `self`
865 #
866 # This include introduced, redefined, inherited mattributes.
867 fun collect_accessible_mattributes(mainmodule: MModule, filter: nullable ModelFilter): Set[MAttribute] do
868 var set = new HashSet[MAttribute]
869 set.add_all(collect_intro_mattributes(filter))
870 set.add_all(collect_redef_mattributes(filter))
871 set.add_all(collect_inherited_mattributes(mainmodule, filter))
872 return set
873 end
874
875 # Collect all init methods introduced in `self`
876 fun collect_intro_inits(filter: nullable ModelFilter): Set[MMethod] do
877 var res = new HashSet[MMethod]
878 for mproperty in collect_intro_mmethods(filter) do
879 if mproperty.is_init then res.add(mproperty)
880 end
881 return res
882 end
883
884 # Collect all init methods redefined in `self`
885 fun collect_redef_inits(filter: nullable ModelFilter): Set[MMethod] do
886 var res = new HashSet[MMethod]
887 for mproperty in collect_redef_mmethods(filter) do
888 if mproperty.is_init then res.add(mproperty)
889 end
890 return res
891 end
892
893 # Collect all init methods introduced and redefined in `self`
894 fun collect_local_inits(filter: nullable ModelFilter): Set[MMethod] do
895 var set = new HashSet[MMethod]
896 set.add_all collect_intro_inits(filter)
897 set.add_all collect_redef_inits(filter)
898 return set
899 end
900
901 # Collect all init methods inherited by `self`
902 fun collect_inherited_inits(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
903 var res = new HashSet[MMethod]
904 for mproperty in collect_inherited_mmethods(mainmodule, filter) do
905 if mproperty.is_init then res.add(mproperty)
906 end
907 return res
908 end
909
910 # Collect all init methods accessible by `self`
911 #
912 # This include introduced, redefined, inherited inits.
913 fun collect_accessible_inits(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
914 var set = new HashSet[MMethod]
915 set.add_all(collect_intro_inits(filter))
916 set.add_all(collect_redef_inits(filter))
917 set.add_all(collect_inherited_inits(mainmodule, filter))
918 return set
919 end
920
921 # Collect all virtual types introduced in `self`
922 fun collect_intro_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
923 var res = new HashSet[MVirtualTypeProp]
924 for mproperty in collect_intro_mproperties(filter) do
925 if mproperty isa MVirtualTypeProp then res.add(mproperty)
926 end
927 return res
928 end
929
930 # Collect all virtual types redefined in `self`
931 fun collect_redef_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
932 var res = new HashSet[MVirtualTypeProp]
933 for mproperty in collect_intro_mproperties(filter) do
934 if mproperty isa MVirtualTypeProp then res.add(mproperty)
935 end
936 return res
937 end
938
939 # Collect all virtual types introduced or redefined in `self`
940 fun collect_local_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
941 var set = new HashSet[MVirtualTypeProp]
942 set.add_all collect_intro_vts(filter)
943 set.add_all collect_redef_vts(filter)
944 return set
945 end
946
947 # Collect all virtual types inherited by `self`
948 fun collect_inherited_vts(mainmodule: MModule, filter: nullable ModelFilter): Set[MVirtualTypeProp] do
949 var res = new HashSet[MVirtualTypeProp]
950 for mproperty in collect_inherited_mproperties(mainmodule, filter) do
951 if mproperty isa MVirtualTypeProp then res.add(mproperty)
952 end
953 return res
954 end
955
956 # Collect all virtual types accessible by `self`
957 #
958 # This include introduced, redefined, inherited virtual types.
959 fun collect_accessible_vts(mainmodule: MModule, filter: nullable ModelFilter): Set[MVirtualTypeProp] do
960 var set = new HashSet[MVirtualTypeProp]
961 for mproperty in collect_accessible_mproperties(mainmodule, filter) do
962 if mproperty isa MVirtualTypeProp then set.add mproperty
963 end
964 return set
965 end
966 end
967
968 redef class MClassDef
969
970 redef fun collect_modifiers do
971 var res = super
972 if not is_intro then
973 res.add "redef"
974 else
975 if mclass.visibility != public_visibility then
976 res.add mclass.visibility.to_s
977 end
978 end
979 res.add mclass.kind.to_s
980 return res
981 end
982
983 redef fun collect_linearization(mainmodule) do
984 var mclassdefs = new Array[MClassDef]
985 for mclassdef in in_hierarchy.as(not null).greaters do
986 if mclassdef.mclass == self.mclass then mclassdefs.add mclassdef
987 end
988 mainmodule.linearize_mclassdefs(mclassdefs)
989 return mclassdefs
990 end
991
992 redef fun collect_parents(mainmodule, filter) do
993 var res = new HashSet[MENTITY]
994 var hierarchy = self.in_hierarchy
995 if hierarchy == null then return res
996 for parent in hierarchy.direct_greaters do
997 if parent == self then continue
998 if filter == null or filter.accept_mentity(parent) then res.add parent
999 end
1000 return res
1001 end
1002
1003 redef fun collect_children(mainmodule, filter) do
1004 var res = new HashSet[MENTITY]
1005 var hierarchy = self.in_hierarchy
1006 if hierarchy == null then return res
1007 for child in hierarchy.direct_smallers do
1008 if child == self then continue
1009 if filter == null or filter.accept_mentity(child) then res.add child
1010 end
1011 return res
1012 end
1013
1014 # Collect all property definitions in `self`
1015 fun collect_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
1016 var res = new HashSet[MPropDef]
1017 for mpropdef in mpropdefs do
1018 if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
1019 end
1020 return res
1021 end
1022
1023 # Collect all attribute definitions in `self`
1024 fun collect_mattributedefs(filter: nullable ModelFilter): Set[MAttributeDef] do
1025 var res = new HashSet[MAttributeDef]
1026 for mpropdef in collect_mpropdefs(filter) do
1027 if not mpropdef isa MAttributeDef then continue
1028 res.add mpropdef
1029 end
1030 return res
1031 end
1032
1033 # Collect all methods definitions in `self`
1034 fun collect_mmethoddefs(filter: nullable ModelFilter): Set[MMethodDef] do
1035 var res = new HashSet[MMethodDef]
1036 for mpropdef in collect_mpropdefs(filter) do
1037 if not mpropdef isa MMethodDef then continue
1038 res.add mpropdef
1039 end
1040 return res
1041 end
1042
1043 # Collect all virtual types definitions in `self`
1044 fun collect_mtypedefs(filter: nullable ModelFilter): Set[MVirtualTypeDef] do
1045 var res = new HashSet[MVirtualTypeDef]
1046 for mpropdef in collect_mpropdefs(filter) do
1047 if not mpropdef isa MVirtualTypeDef then continue
1048 res.add mpropdef
1049 end
1050 return res
1051 end
1052
1053 # Collect all property definitions that are introduction in `self`
1054 fun collect_intro_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
1055 var res = new HashSet[MPropDef]
1056 for mpropdef in mpropdefs do
1057 if not mpropdef.is_intro then continue
1058 if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
1059 end
1060 return res
1061 end
1062
1063 # Collect all property definitions that are redefinition in `self`
1064 fun collect_redef_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
1065 var res = new HashSet[MPropDef]
1066 for mpropdef in mpropdefs do
1067 if mpropdef.is_intro then continue
1068 if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
1069 end
1070 return res
1071 end
1072 end
1073
1074 redef class MProperty
1075 redef fun collect_modifiers do return intro.collect_modifiers
1076
1077 redef fun collect_linearization(mainmodule) do
1078 var mpropdefs = self.mpropdefs.to_a
1079 mainmodule.linearize_mpropdefs(mpropdefs)
1080 return mpropdefs
1081 end
1082
1083 # Collect all property definitions of `self`
1084 fun collect_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
1085 var res = new HashSet[MPropDef]
1086 for mpropdef in mpropdefs do
1087 if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
1088 end
1089 return res
1090 end
1091
1092 # Collect all direct super definitions of `self`
1093 redef fun collect_parents(mainmodule, filter) do
1094 var res = new HashSet[MENTITY]
1095 for mpropdef in mpropdefs do
1096 for parent in mpropdef.collect_parents(mainmodule, filter) do
1097 var mprop = parent.mproperty
1098 if filter == null or filter.accept_mentity(mprop) then res.add mprop
1099 end
1100 end
1101 return res
1102 end
1103
1104 # Collection all definitions that have `self` as a direct super definition
1105 redef fun collect_children(mainmodule, filter) do
1106 var res = new HashSet[MENTITY]
1107 for mpropdef in mpropdefs do
1108 for child in mpropdef.collect_parents(mainmodule, filter) do
1109 var mprop = child.mproperty
1110 if filter == null or filter.accept_mentity(mprop) then res.add mprop
1111 end
1112 end
1113 return res
1114 end
1115 end
1116
1117 redef class MPropDef
1118
1119 redef fun collect_modifiers do
1120 var res = super
1121 if not is_intro then
1122 res.add "redef"
1123 else
1124 if mproperty.visibility != public_visibility then
1125 res.add mproperty.visibility.to_s
1126 end
1127 end
1128 var mprop = self
1129 if mprop isa MVirtualTypeDef then
1130 res.add "type"
1131 else if mprop isa MMethodDef then
1132 if mprop.is_abstract then
1133 res.add "abstract"
1134 else if mprop.is_intern then
1135 res.add "intern"
1136 end
1137 if mprop.mproperty.is_init then
1138 res.add "init"
1139 else
1140 res.add "fun"
1141 end
1142 else if mprop isa MAttributeDef then
1143 res.add "var"
1144 end
1145 return res
1146 end
1147
1148 redef fun collect_linearization(mainmodule) do
1149 var mpropdefs = new Array[MPropDef]
1150 var mentity = self
1151 while not mentity.is_intro do
1152 mpropdefs.add mentity
1153 mentity = mentity.lookup_next_definition(mainmodule, mentity.mclassdef.bound_mtype)
1154 end
1155 mpropdefs.add mentity
1156 mainmodule.linearize_mpropdefs(mpropdefs)
1157 return mpropdefs
1158 end
1159
1160 # Collect only the next definition of `self`
1161 redef fun collect_parents(mainmodule, filter) do
1162 var res = new HashSet[MENTITY]
1163 var mpropdef = self
1164 while not mpropdef.is_intro do
1165 mpropdef = mpropdef.lookup_next_definition(mclassdef.mmodule, mclassdef.bound_mtype)
1166 res.add mpropdef
1167 end
1168 return res
1169 end
1170
1171 # Collect all children definitions that directly depend on `self`
1172 redef fun collect_children(mainmodule, filter) do
1173 var res = new HashSet[MENTITY]
1174 for mpropdef in mproperty.collect_mpropdefs(filter) do
1175 if mpropdef.collect_parents(mainmodule, filter).has(self) then res.add mpropdef
1176 end
1177 return res
1178 end
1179 end