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