00d52dfb140e37a36eeff5a15a0438002e20bd67
[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 module ancestors of `self` (direct and transitive imports)
398 redef fun collect_ancestors(view) do
399 var res = new HashSet[MENTITY]
400 for mentity in in_importation.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 directly imported by `self`
409 redef fun collect_parents(view) do
410 var res = new HashSet[MENTITY]
411 for mentity in in_importation.direct_greaters 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 modules that directly import `self`
420 redef fun collect_children(view) do
421 var res = new HashSet[MENTITY]
422 for mentity in in_importation.direct_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 module descendants of `self` (direct and transitive imports)
431 redef fun collect_descendants(view) do
432 var res = new HashSet[MENTITY]
433 for mentity in in_importation.smallers do
434 if mentity == self then continue
435 if not view.accept_mentity(mentity) then continue
436 res.add mentity
437 end
438 return res
439 end
440
441 # Collect all class definitions introduced in `self`
442 fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
443 var res = new HashSet[MClassDef]
444 for mclassdef in mclassdefs do
445 if not 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 refined in `self`
453 fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
454 var res = new HashSet[MClassDef]
455 for mclassdef in mclassdefs do
456 if mclassdef.is_intro then continue
457 if not view.accept_mentity(mclassdef) then continue
458 res.add mclassdef
459 end
460 return res
461 end
462
463 # Collect all class definitions introduced and refined in `self`
464 fun collect_local_mclassdefs(view: ModelView): Set[MClassDef] do
465 var res = new HashSet[MClassDef]
466 res.add_all collect_intro_mclassdefs(view)
467 res.add_all collect_redef_mclassdefs(view)
468 return res
469 end
470
471 # Collect all classes introduced in `self`
472 fun collect_intro_mclasses(view: ModelView): Set[MClass] do
473 var res = new HashSet[MClass]
474 for mclass in intro_mclasses do
475 if not view.accept_mentity(mclass) then continue
476 res.add mclass
477 end
478 return res
479 end
480
481 # Collect all classes refined in `self`
482 fun collect_redef_mclasses(view: ModelView): Set[MClass] do
483 var mclasses = new HashSet[MClass]
484 for mclassdef in mclassdefs do
485 if not view.accept_mentity(mclassdef.mclass) then continue
486 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
487 end
488 return mclasses
489 end
490
491 # Collect all classes introduced and refined in `self`
492 fun collect_local_mclasses(view: ModelView): Set[MClass] do
493 var res = new HashSet[MClass]
494 res.add_all collect_intro_mclasses(view)
495 res.add_all collect_redef_mclasses(view)
496 return res
497 end
498
499 # Collect all classes imported from `self` parents
500 fun collect_imported_mclasses(view: ModelView): Set[MClass] do
501 var res = new HashSet[MClass]
502 for parent in collect_parents(view) do
503 res.add_all parent.collect_intro_mclasses(view)
504 res.add_all parent.collect_redef_mclasses(view)
505 res.add_all parent.collect_imported_mclasses(view)
506 end
507 return res
508 end
509
510 # Collect all properties introduced in `self`
511 fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
512 var res = new HashSet[MProperty]
513 for mclass in collect_intro_mclasses(view) do
514 res.add_all mclass.collect_intro_mproperties(view)
515 end
516 return res
517 end
518
519 # Collect properties redefined in `self`
520 fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
521 var res = new HashSet[MProperty]
522 for mclassdef in mclassdefs do
523 for mpropdef in mclassdef.collect_redef_mpropdefs(view) do
524 res.add mpropdef.mproperty
525 end
526 end
527 return res
528 end
529
530 # Collect attributes introduced in `self`
531 fun collect_intro_attributes(view: ModelView): Set[MAttribute] do
532 var res = new HashSet[MAttribute]
533 for mproperty in collect_intro_mproperties(view) do
534 if mproperty isa MAttribute then res.add(mproperty)
535 end
536 return res
537 end
538
539 # Collect all inits introduced in `self`
540 fun collect_intro_inits(view: ModelView): Set[MMethod] do
541 var res = new HashSet[MMethod]
542 for mproperty in collect_intro_mproperties(view) do
543 if mproperty isa MMethod and mproperty.is_init then res.add(mproperty)
544 end
545 return res
546 end
547
548 # Collect methods introduced in `self` (without inits)
549 fun collect_intro_methods(view: ModelView): Set[MMethod] do
550 var res = new HashSet[MMethod]
551 for mproperty in collect_intro_mproperties(view) do
552 if mproperty isa MMethod and not mproperty.is_init then res.add(mproperty)
553 end
554 return res
555 end
556
557 # Collect virtual types introduced in `self`
558 fun collect_intro_vts(view: ModelView): Set[MVirtualTypeProp] do
559 var res = new HashSet[MVirtualTypeProp]
560 for mproperty in collect_intro_mproperties(view) do
561 if mproperty isa MVirtualTypeProp then res.add(mproperty)
562 end
563 return res
564 end
565 end
566
567 redef class MClass
568
569 redef fun collect_modifiers do return intro.collect_modifiers
570
571 redef fun collect_linearization(mainmodule) do
572 var mclassdefs = self.mclassdefs.to_a
573 mainmodule.linearize_mclassdefs(mclassdefs)
574 return mclassdefs
575 end
576
577 # Collect all direct parents of `self`
578 #
579 # This method uses a flattened hierarchy containing all the mclassdefs.
580 redef fun collect_parents(view) do
581 var res = new HashSet[MENTITY]
582 for mclass in in_hierarchy(view.mainmodule).direct_greaters do
583 if mclass == self or not view.accept_mentity(mclass) then continue
584 res.add mclass
585 end
586 return res
587 end
588
589 # Collect all direct children of `self`
590 #
591 # This method uses a flattened hierarchy containing all the mclassdefs.
592 redef fun collect_children(view) do
593 var res = new HashSet[MENTITY]
594 for mclass in in_hierarchy(view.mainmodule).direct_smallers do
595 if mclass == self or not view.accept_mentity(mclass) then continue
596 res.add mclass
597 end
598 return res
599 end
600
601 # Collect all class definitions of `self`
602 fun collect_mclassdefs(view: ModelView): Set[MClassDef] do
603 var res = new HashSet[MClassDef]
604 for mclassdef in mclassdefs do
605 if not view.accept_mentity(mclassdef) then continue
606 res.add mclassdef
607 end
608 return res
609 end
610
611 # Collect all property definitions that are introductions in `self`
612 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
613 var set = new HashSet[MPropDef]
614 for mclassdef in mclassdefs do
615 for mpropdef in mclassdef.mpropdefs do
616 if not mpropdef.is_intro then continue
617 if not view.accept_mentity(mpropdef) then continue
618 set.add(mpropdef)
619 end
620 end
621 return set
622 end
623
624 # Collect all properties introduced in `self`
625 fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
626 var set = new HashSet[MProperty]
627 for mclassdef in mclassdefs do
628 for mprop in mclassdef.intro_mproperties do
629 if not view.accept_mentity(mprop) then continue
630 set.add(mprop)
631 end
632 end
633 return set
634 end
635
636 # Collect all propierty definitions that are redefinition in `self`
637 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
638 var set = new HashSet[MPropDef]
639 for mclassdef in mclassdefs do
640 for mpropdef in mclassdef.mpropdefs do
641 if mpropdef.is_intro then continue
642 if not view.accept_mentity(mpropdef) then continue
643 set.add(mpropdef)
644 end
645 end
646 return set
647 end
648
649 # Collect all properties redefined in `self`
650 fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
651 var set = new HashSet[MProperty]
652 for mclassdef in mclassdefs do
653 for mpropdef in mclassdef.mpropdefs do
654 if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
655 if not view.accept_mentity(mpropdef) then continue
656 set.add(mpropdef.mproperty)
657 end
658 end
659 return set
660 end
661
662 # Collect all properties introduced and redefined in `self`
663 fun collect_local_mproperties(view: ModelView): Set[MProperty] do
664 var set = new HashSet[MProperty]
665 set.add_all collect_intro_mproperties(view)
666 set.add_all collect_redef_mproperties(view)
667 return set
668 end
669
670 # Collect all properties inehrited by `self`
671 fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
672 var set = new HashSet[MProperty]
673 for parent in collect_parents(view) do
674 set.add_all(parent.collect_intro_mproperties(view))
675 set.add_all(parent.collect_inherited_mproperties(view))
676 end
677 return set
678 end
679
680 # Collect all properties accessible by `self`
681 #
682 # This include introduced, redefined, inherited properties.
683 fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
684 var set = new HashSet[MProperty]
685 set.add_all(collect_intro_mproperties(view))
686 set.add_all(collect_redef_mproperties(view))
687 set.add_all(collect_inherited_mproperties(view))
688 return set
689 end
690
691 # Collect all methods introduced in `self`
692 fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
693 var res = new HashSet[MMethod]
694 for mproperty in collect_intro_mproperties(view) do
695 if mproperty isa MMethod then res.add(mproperty)
696 end
697 return res
698 end
699
700 # Collect all methods redefined in `self`
701 fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
702 var res = new HashSet[MMethod]
703 for mproperty in collect_redef_mproperties(view) do
704 if mproperty isa MMethod then res.add(mproperty)
705 end
706 return res
707 end
708
709 # Collect all methods introduced and redefined in `self`
710 fun collect_local_mmethods(view: ModelView): Set[MMethod] do
711 var set = new HashSet[MMethod]
712 set.add_all collect_intro_mmethods(view)
713 set.add_all collect_redef_mmethods(view)
714 return set
715 end
716
717 # Collect all methods inherited by `self`
718 fun collect_inherited_mmethods(view: ModelView): Set[MMethod] do
719 var res = new HashSet[MMethod]
720 for mproperty in collect_inherited_mproperties(view) do
721 if mproperty isa MMethod then res.add(mproperty)
722 end
723 return res
724 end
725
726 # Collect all methods accessible by `self`
727 #
728 # This include introduced, redefined, inherited methods.
729 fun collect_accessible_mmethods(view: ModelView): Set[MMethod] do
730 var set = new HashSet[MMethod]
731 set.add_all(collect_intro_mmethods(view))
732 set.add_all(collect_redef_mmethods(view))
733 set.add_all(collect_inherited_mmethods(view))
734 return set
735 end
736
737 # Collect all attributes introduced in `self`
738 fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
739 var res = new HashSet[MAttribute]
740 for mproperty in collect_intro_mproperties(view) do
741 if mproperty isa MAttribute then res.add(mproperty)
742 end
743 return res
744 end
745
746 # Collect all attributes redefined in `self`
747 fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
748 var res = new HashSet[MAttribute]
749 for mproperty in collect_redef_mproperties(view) do
750 if mproperty isa MAttribute then res.add(mproperty)
751 end
752 return res
753 end
754
755 # Collect all attributes introduced and redefined in `self`
756 fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
757 var set = new HashSet[MAttribute]
758 set.add_all collect_intro_mattributes(view)
759 set.add_all collect_redef_mattributes(view)
760 return set
761 end
762
763 # Collect all attributes inherited by `self`
764 fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
765 var res = new HashSet[MAttribute]
766 for mproperty in collect_inherited_mproperties(view) do
767 if mproperty isa MAttribute then res.add(mproperty)
768 end
769 return res
770 end
771
772 # Collect all attributes accessible by `self`
773 #
774 # This include introduced, redefined, inherited mattributes.
775 fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
776 var set = new HashSet[MAttribute]
777 set.add_all(collect_intro_mattributes(view))
778 set.add_all(collect_redef_mattributes(view))
779 set.add_all(collect_inherited_mattributes(view))
780 return set
781 end
782
783 # Collect all init methods introduced in `self`
784 fun collect_intro_inits(view: ModelView): Set[MMethod] do
785 var res = new HashSet[MMethod]
786 for mproperty in collect_intro_mmethods(view) do
787 if mproperty.is_init then res.add(mproperty)
788 end
789 return res
790 end
791
792 # Collect all init methods redefined in `self`
793 fun collect_redef_inits(view: ModelView): Set[MMethod] do
794 var res = new HashSet[MMethod]
795 for mproperty in collect_redef_mmethods(view) do
796 if mproperty.is_init then res.add(mproperty)
797 end
798 return res
799 end
800
801 # Collect all init methods introduced and redefined in `self`
802 fun collect_local_inits(view: ModelView): Set[MMethod] do
803 var set = new HashSet[MMethod]
804 set.add_all collect_intro_inits(view)
805 set.add_all collect_redef_inits(view)
806 return set
807 end
808
809 # Collect all init methods inherited by `self`
810 fun collect_inherited_inits(view: ModelView): Set[MMethod] do
811 var res = new HashSet[MMethod]
812 for mproperty in collect_inherited_mmethods(view) do
813 if mproperty.is_init then res.add(mproperty)
814 end
815 return res
816 end
817
818 # Collect all init methods accessible by `self`
819 #
820 # This include introduced, redefined, inherited inits.
821 fun collect_accessible_inits(view: ModelView): Set[MMethod] do
822 var set = new HashSet[MMethod]
823 set.add_all(collect_intro_inits(view))
824 set.add_all(collect_redef_inits(view))
825 set.add_all(collect_inherited_inits(view))
826 return set
827 end
828
829 # Collect all virtual types introduced in `self`
830 fun collect_intro_vts(view: ModelView): Set[MVirtualTypeProp] do
831 var res = new HashSet[MVirtualTypeProp]
832 for mproperty in collect_intro_mproperties(view) do
833 if mproperty isa MVirtualTypeProp then res.add(mproperty)
834 end
835 return res
836 end
837
838 # Collect all virtual types redefined in `self`
839 fun collect_redef_vts(view: ModelView): Set[MVirtualTypeProp] do
840 var res = new HashSet[MVirtualTypeProp]
841 for mproperty in collect_intro_mproperties(view) do
842 if mproperty isa MVirtualTypeProp then res.add(mproperty)
843 end
844 return res
845 end
846
847 # Collect all virtual types introduced or redefined in `self`
848 fun collect_local_vts(view: ModelView): Set[MVirtualTypeProp] do
849 var set = new HashSet[MVirtualTypeProp]
850 set.add_all collect_intro_vts(view)
851 set.add_all collect_redef_vts(view)
852 return set
853 end
854
855 # Collect all virtual types inherited by `self`
856 fun collect_inherited_vts(view: ModelView): Set[MVirtualTypeProp] do
857 var res = new HashSet[MVirtualTypeProp]
858 for mproperty in collect_inherited_mproperties(view) do
859 if mproperty isa MVirtualTypeProp then res.add(mproperty)
860 end
861 return res
862 end
863
864 # Collect all virtual types accessible by `self`
865 #
866 # This include introduced, redefined, inherited virtual types.
867 fun collect_accessible_vts(view: ModelView): Set[MVirtualTypeProp] do
868 var set = new HashSet[MVirtualTypeProp]
869 for mproperty in collect_accessible_mproperties(view) do
870 if mproperty isa MVirtualTypeProp then set.add mproperty
871 end
872 return set
873 end
874 end
875
876 redef class MClassDef
877
878 redef fun collect_modifiers do
879 var res = super
880 if not is_intro then
881 res.add "redef"
882 else
883 res.add mclass.visibility.to_s
884 end
885 res.add mclass.kind.to_s
886 return res
887 end
888
889 redef fun collect_linearization(mainmodule) do
890 var mclassdefs = new Array[MClassDef]
891 for mclassdef in in_hierarchy.as(not null).greaters do
892 if mclassdef.mclass == self.mclass then mclassdefs.add mclassdef
893 end
894 mainmodule.linearize_mclassdefs(mclassdefs)
895 return mclassdefs
896 end
897
898 redef fun collect_ancestors(view) do
899 var res = new HashSet[MENTITY]
900 var hierarchy = self.in_hierarchy
901 if hierarchy == null then return res
902 for parent in hierarchy.greaters do
903 if parent == self or not view.accept_mentity(parent) then continue
904 res.add parent
905 end
906 return res
907 end
908
909 redef fun collect_parents(view) do
910 var res = new HashSet[MENTITY]
911 var hierarchy = self.in_hierarchy
912 if hierarchy == null then return res
913 for parent in hierarchy.direct_greaters do
914 if parent == self or not view.accept_mentity(parent) then continue
915 res.add parent
916 end
917 return res
918 end
919
920 redef fun collect_children(view) do
921 var res = new HashSet[MENTITY]
922 var hierarchy = self.in_hierarchy
923 if hierarchy == null then return res
924 for child in hierarchy.direct_smallers do
925 if child == self or not view.accept_mentity(child) then continue
926 res.add child
927 end
928 return res
929 end
930
931 # Collect all property definitions in `self`
932 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
933 var res = new HashSet[MPropDef]
934 for mpropdef in mpropdefs do
935 if not view.accept_mentity(mpropdef) then continue
936 res.add mpropdef
937 end
938 return res
939 end
940
941 # Collect all attribute definitions in `self`
942 fun collect_mattributedefs(view: ModelView): Set[MAttributeDef] do
943 var res = new HashSet[MAttributeDef]
944 for mpropdef in collect_mpropdefs(view) do
945 if not mpropdef isa MAttributeDef then continue
946 res.add mpropdef
947 end
948 return res
949 end
950
951 # Collect all methods definitions in `self`
952 fun collect_mmethoddefs(view: ModelView): Set[MMethodDef] do
953 var res = new HashSet[MMethodDef]
954 for mpropdef in collect_mpropdefs(view) do
955 if not mpropdef isa MMethodDef then continue
956 res.add mpropdef
957 end
958 return res
959 end
960
961 # Collect all virtual types definitions in `self`
962 fun collect_mtypedefs(view: ModelView): Set[MVirtualTypeDef] do
963 var res = new HashSet[MVirtualTypeDef]
964 for mpropdef in collect_mpropdefs(view) do
965 if not mpropdef isa MVirtualTypeDef then continue
966 res.add mpropdef
967 end
968 return res
969 end
970
971 # Collect all property definitions that are introduction in `self`
972 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
973 var res = new HashSet[MPropDef]
974 for mpropdef in mpropdefs do
975 if not mpropdef.is_intro then continue
976 if not view.accept_mentity(mpropdef) then continue
977 res.add mpropdef
978 end
979 return res
980 end
981
982 # Collect all property definitions that are redefinition in `self`
983 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
984 var res = new HashSet[MPropDef]
985 for mpropdef in mpropdefs do
986 if mpropdef.is_intro then continue
987 if not view.accept_mentity(mpropdef) then continue
988 res.add mpropdef
989 end
990 return res
991 end
992 end
993
994 redef class MProperty
995 redef fun collect_modifiers do return intro.collect_modifiers
996
997 redef fun collect_linearization(mainmodule) do
998 var mpropdefs = self.mpropdefs.to_a
999 mainmodule.linearize_mpropdefs(mpropdefs)
1000 return mpropdefs
1001 end
1002
1003 # Collect all property definitions of `self`
1004 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
1005 var res = new HashSet[MPropDef]
1006 for mpropdef in mpropdefs do
1007 if not view.accept_mentity(mpropdef) then continue
1008 res.add mpropdef
1009 end
1010 return res
1011 end
1012
1013 # Collect all direct super definitions of `self`
1014 redef fun collect_parents(view) do
1015 var res = new HashSet[MENTITY]
1016 for mpropdef in mpropdefs do
1017 for parent in mpropdef.collect_parents(view) do
1018 if not view.accept_mentity(parent) then continue
1019 res.add parent.mproperty
1020 end
1021 end
1022 return res
1023 end
1024
1025 # Collection all definitions that have `self` as a direct super definition
1026 redef fun collect_children(view) do
1027 var res = new HashSet[MENTITY]
1028 for mpropdef in mpropdefs do
1029 for child in mpropdef.collect_parents(view) do
1030 if not view.accept_mentity(child) then continue
1031 res.add child.mproperty
1032 end
1033 end
1034 return res
1035 end
1036 end
1037
1038 redef class MPropDef
1039
1040 redef fun collect_modifiers do
1041 var res = super
1042 if not is_intro then
1043 res.add "redef"
1044 else
1045 res.add mproperty.visibility.to_s
1046 end
1047 var mprop = self
1048 if mprop isa MVirtualTypeDef then
1049 res.add "type"
1050 else if mprop isa MMethodDef then
1051 if mprop.is_abstract then
1052 res.add "abstract"
1053 else if mprop.is_intern then
1054 res.add "intern"
1055 end
1056 if mprop.mproperty.is_init then
1057 res.add "init"
1058 else
1059 res.add "fun"
1060 end
1061 else if mprop isa MAttributeDef then
1062 res.add "var"
1063 end
1064 return res
1065 end
1066
1067 redef fun collect_linearization(mainmodule) do
1068 var mpropdefs = new Array[MPropDef]
1069 var mentity = self
1070 while not mentity.is_intro do
1071 mpropdefs.add mentity
1072 mentity = mentity.lookup_next_definition(mainmodule, mentity.mclassdef.bound_mtype)
1073 end
1074 mpropdefs.add mentity
1075 mainmodule.linearize_mpropdefs(mpropdefs)
1076 return mpropdefs
1077 end
1078
1079 # Collect only the next definition of `self`
1080 redef fun collect_parents(view) do
1081 var res = new HashSet[MENTITY]
1082 var mpropdef = self
1083 while not mpropdef.is_intro do
1084 mpropdef = mpropdef.lookup_next_definition(mclassdef.mmodule, mclassdef.bound_mtype)
1085 res.add mpropdef
1086 end
1087 return res
1088 end
1089
1090 # Collect all children definitions that directly depend on `self`
1091 redef fun collect_children(view) do
1092 var res = new HashSet[MENTITY]
1093 for mpropdef in mproperty.collect_mpropdefs(view) do
1094 if mpropdef.collect_parents(view).has(self) then res.add mpropdef
1095 end
1096 return res
1097 end
1098 end