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