nitpackage: check existence of README.md files
[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_all_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_all_mmodules(view: ModelView): HashSet[MModule] do
384 var res = new HashSet[MModule]
385 for mgroup in collect_mgroups(view) do
386 res.add_all mgroup.collect_all_mmodules(view)
387 end
388 return res
389 end
390
391 # Collect all modules contained in `self`
392 fun collect_mmodules(view: ModelView): HashSet[MModule] do
393 var res = new HashSet[MModule]
394 for mmodule in mmodules do
395 if not view.accept_mentity(mmodule) then continue
396 res.add(mmodule)
397 end
398 return res
399 end
400 end
401
402 redef class MModule
403
404 redef fun collect_modifiers do return super + ["module"]
405
406 # Collect all modules directly imported by `self`
407 redef fun collect_parents(view) do
408 var res = new HashSet[MENTITY]
409 for mentity in in_importation.direct_greaters do
410 if mentity == self then continue
411 if not view.accept_mentity(mentity) then continue
412 res.add mentity
413 end
414 return res
415 end
416
417 # Collect all modules that directly import `self`
418 redef fun collect_children(view) do
419 var res = new HashSet[MENTITY]
420 for mentity in in_importation.direct_smallers do
421 if mentity == self then continue
422 if not view.accept_mentity(mentity) then continue
423 res.add mentity
424 end
425 return res
426 end
427
428 # Collect all module descendants of `self` (direct and transitive imports)
429 redef fun collect_descendants(view) do
430 var res = new HashSet[MENTITY]
431 for mentity in in_importation.smallers do
432 if mentity == self then continue
433 if not view.accept_mentity(mentity) then continue
434 res.add mentity
435 end
436 return res
437 end
438
439 # Collect all class definitions introduced in `self`
440 fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
441 var res = new HashSet[MClassDef]
442 for mclassdef in mclassdefs do
443 if not mclassdef.is_intro then continue
444 if not view.accept_mentity(mclassdef) then continue
445 res.add mclassdef
446 end
447 return res
448 end
449
450 # Collect all class definitions refined in `self`
451 fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
452 var res = new HashSet[MClassDef]
453 for mclassdef in mclassdefs do
454 if mclassdef.is_intro then continue
455 if not view.accept_mentity(mclassdef) then continue
456 res.add mclassdef
457 end
458 return res
459 end
460
461 # Collect all class definitions introduced and refined in `self`
462 fun collect_local_mclassdefs(view: ModelView): Set[MClassDef] do
463 var res = new HashSet[MClassDef]
464 res.add_all collect_intro_mclassdefs(view)
465 res.add_all collect_redef_mclassdefs(view)
466 return res
467 end
468
469 # Collect all classes introduced in `self`
470 fun collect_intro_mclasses(view: ModelView): Set[MClass] do
471 var res = new HashSet[MClass]
472 for mclass in intro_mclasses do
473 if not view.accept_mentity(mclass) then continue
474 res.add mclass
475 end
476 return res
477 end
478
479 # Collect all classes refined in `self`
480 fun collect_redef_mclasses(view: ModelView): Set[MClass] do
481 var mclasses = new HashSet[MClass]
482 for mclassdef in mclassdefs do
483 if not view.accept_mentity(mclassdef.mclass) then continue
484 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
485 end
486 return mclasses
487 end
488
489 # Collect all classes introduced and refined in `self`
490 fun collect_local_mclasses(view: ModelView): Set[MClass] do
491 var res = new HashSet[MClass]
492 res.add_all collect_intro_mclasses(view)
493 res.add_all collect_redef_mclasses(view)
494 return res
495 end
496
497 # Collect all classes imported from `self` parents
498 fun collect_imported_mclasses(view: ModelView): Set[MClass] do
499 var res = new HashSet[MClass]
500 for parent in collect_parents(view) do
501 res.add_all parent.collect_intro_mclasses(view)
502 res.add_all parent.collect_redef_mclasses(view)
503 res.add_all parent.collect_imported_mclasses(view)
504 end
505 return res
506 end
507
508 # Collect all properties introduced in `self`
509 fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
510 var res = new HashSet[MProperty]
511 for mclass in collect_intro_mclasses(view) do
512 res.add_all mclass.collect_intro_mproperties(view)
513 end
514 return res
515 end
516
517 # Collect properties redefined in `self`
518 fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
519 var res = new HashSet[MProperty]
520 for mclassdef in mclassdefs do
521 for mpropdef in mclassdef.collect_redef_mpropdefs(view) do
522 res.add mpropdef.mproperty
523 end
524 end
525 return res
526 end
527
528 # Collect attributes introduced in `self`
529 fun collect_intro_attributes(view: ModelView): Set[MAttribute] do
530 var res = new HashSet[MAttribute]
531 for mproperty in collect_intro_mproperties(view) do
532 if mproperty isa MAttribute then res.add(mproperty)
533 end
534 return res
535 end
536
537 # Collect all inits introduced in `self`
538 fun collect_intro_inits(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 mproperty.is_init then res.add(mproperty)
542 end
543 return res
544 end
545
546 # Collect methods introduced in `self` (without inits)
547 fun collect_intro_methods(view: ModelView): Set[MMethod] do
548 var res = new HashSet[MMethod]
549 for mproperty in collect_intro_mproperties(view) do
550 if mproperty isa MMethod and not mproperty.is_init then res.add(mproperty)
551 end
552 return res
553 end
554
555 # Collect virtual types introduced in `self`
556 fun collect_intro_vts(view: ModelView): Set[MVirtualTypeProp] do
557 var res = new HashSet[MVirtualTypeProp]
558 for mproperty in collect_intro_mproperties(view) do
559 if mproperty isa MVirtualTypeProp then res.add(mproperty)
560 end
561 return res
562 end
563 end
564
565 redef class MClass
566
567 redef fun collect_modifiers do return intro.collect_modifiers
568
569 redef fun collect_linearization(mainmodule) do
570 var mclassdefs = self.mclassdefs.to_a
571 mainmodule.linearize_mclassdefs(mclassdefs)
572 return mclassdefs
573 end
574
575 # Collect all direct parents of `self`
576 #
577 # This method uses a flattened hierarchy containing all the mclassdefs.
578 redef fun collect_parents(view) do
579 var res = new HashSet[MENTITY]
580 if not view.mainmodule.flatten_mclass_hierarchy.has(self) then return res
581 for mclass in in_hierarchy(view.mainmodule).direct_greaters do
582 if mclass == self or not view.accept_mentity(mclass) then continue
583 res.add mclass
584 end
585 return res
586 end
587
588 # Collect all direct children of `self`
589 #
590 # This method uses a flattened hierarchy containing all the mclassdefs.
591 redef fun collect_children(view) do
592 var res = new HashSet[MENTITY]
593 if not view.mainmodule.flatten_mclass_hierarchy.has(self) then return res
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 if mclass.visibility != public_visibility then
884 res.add mclass.visibility.to_s
885 end
886 end
887 res.add mclass.kind.to_s
888 return res
889 end
890
891 redef fun collect_linearization(mainmodule) do
892 var mclassdefs = new Array[MClassDef]
893 for mclassdef in in_hierarchy.as(not null).greaters do
894 if mclassdef.mclass == self.mclass then mclassdefs.add mclassdef
895 end
896 mainmodule.linearize_mclassdefs(mclassdefs)
897 return mclassdefs
898 end
899
900 redef fun collect_parents(view) do
901 var res = new HashSet[MENTITY]
902 var hierarchy = self.in_hierarchy
903 if hierarchy == null then return res
904 for parent in hierarchy.direct_greaters do
905 if parent == self or not view.accept_mentity(parent) then continue
906 res.add parent
907 end
908 return res
909 end
910
911 redef fun collect_children(view) do
912 var res = new HashSet[MENTITY]
913 var hierarchy = self.in_hierarchy
914 if hierarchy == null then return res
915 for child in hierarchy.direct_smallers do
916 if child == self or not view.accept_mentity(child) then continue
917 res.add child
918 end
919 return res
920 end
921
922 # Collect all property definitions in `self`
923 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
924 var res = new HashSet[MPropDef]
925 for mpropdef in mpropdefs do
926 if not view.accept_mentity(mpropdef) then continue
927 res.add mpropdef
928 end
929 return res
930 end
931
932 # Collect all attribute definitions in `self`
933 fun collect_mattributedefs(view: ModelView): Set[MAttributeDef] do
934 var res = new HashSet[MAttributeDef]
935 for mpropdef in collect_mpropdefs(view) do
936 if not mpropdef isa MAttributeDef then continue
937 res.add mpropdef
938 end
939 return res
940 end
941
942 # Collect all methods definitions in `self`
943 fun collect_mmethoddefs(view: ModelView): Set[MMethodDef] do
944 var res = new HashSet[MMethodDef]
945 for mpropdef in collect_mpropdefs(view) do
946 if not mpropdef isa MMethodDef then continue
947 res.add mpropdef
948 end
949 return res
950 end
951
952 # Collect all virtual types definitions in `self`
953 fun collect_mtypedefs(view: ModelView): Set[MVirtualTypeDef] do
954 var res = new HashSet[MVirtualTypeDef]
955 for mpropdef in collect_mpropdefs(view) do
956 if not mpropdef isa MVirtualTypeDef then continue
957 res.add mpropdef
958 end
959 return res
960 end
961
962 # Collect all property definitions that are introduction in `self`
963 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
964 var res = new HashSet[MPropDef]
965 for mpropdef in mpropdefs do
966 if not 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
973 # Collect all property definitions that are redefinition in `self`
974 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
975 var res = new HashSet[MPropDef]
976 for mpropdef in mpropdefs do
977 if mpropdef.is_intro then continue
978 if not view.accept_mentity(mpropdef) then continue
979 res.add mpropdef
980 end
981 return res
982 end
983 end
984
985 redef class MProperty
986 redef fun collect_modifiers do return intro.collect_modifiers
987
988 redef fun collect_linearization(mainmodule) do
989 var mpropdefs = self.mpropdefs.to_a
990 mainmodule.linearize_mpropdefs(mpropdefs)
991 return mpropdefs
992 end
993
994 # Collect all property definitions of `self`
995 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
996 var res = new HashSet[MPropDef]
997 for mpropdef in mpropdefs do
998 if not view.accept_mentity(mpropdef) then continue
999 res.add mpropdef
1000 end
1001 return res
1002 end
1003
1004 # Collect all direct super definitions of `self`
1005 redef fun collect_parents(view) do
1006 var res = new HashSet[MENTITY]
1007 for mpropdef in mpropdefs do
1008 for parent in mpropdef.collect_parents(view) do
1009 if not view.accept_mentity(parent) then continue
1010 res.add parent.mproperty
1011 end
1012 end
1013 return res
1014 end
1015
1016 # Collection all definitions that have `self` as a direct super definition
1017 redef fun collect_children(view) do
1018 var res = new HashSet[MENTITY]
1019 for mpropdef in mpropdefs do
1020 for child in mpropdef.collect_parents(view) do
1021 if not view.accept_mentity(child) then continue
1022 res.add child.mproperty
1023 end
1024 end
1025 return res
1026 end
1027 end
1028
1029 redef class MPropDef
1030
1031 redef fun collect_modifiers do
1032 var res = super
1033 if not is_intro then
1034 res.add "redef"
1035 else
1036 if mproperty.visibility != public_visibility then
1037 res.add mproperty.visibility.to_s
1038 end
1039 end
1040 var mprop = self
1041 if mprop isa MVirtualTypeDef then
1042 res.add "type"
1043 else if mprop isa MMethodDef then
1044 if mprop.is_abstract then
1045 res.add "abstract"
1046 else if mprop.is_intern then
1047 res.add "intern"
1048 end
1049 if mprop.mproperty.is_init then
1050 res.add "init"
1051 else
1052 res.add "fun"
1053 end
1054 else if mprop isa MAttributeDef then
1055 res.add "var"
1056 end
1057 return res
1058 end
1059
1060 redef fun collect_linearization(mainmodule) do
1061 var mpropdefs = new Array[MPropDef]
1062 var mentity = self
1063 while not mentity.is_intro do
1064 mpropdefs.add mentity
1065 mentity = mentity.lookup_next_definition(mainmodule, mentity.mclassdef.bound_mtype)
1066 end
1067 mpropdefs.add mentity
1068 mainmodule.linearize_mpropdefs(mpropdefs)
1069 return mpropdefs
1070 end
1071
1072 # Collect only the next definition of `self`
1073 redef fun collect_parents(view) do
1074 var res = new HashSet[MENTITY]
1075 var mpropdef = self
1076 while not mpropdef.is_intro do
1077 mpropdef = mpropdef.lookup_next_definition(mclassdef.mmodule, mclassdef.bound_mtype)
1078 res.add mpropdef
1079 end
1080 return res
1081 end
1082
1083 # Collect all children definitions that directly depend on `self`
1084 redef fun collect_children(view) do
1085 var res = new HashSet[MENTITY]
1086 for mpropdef in mproperty.collect_mpropdefs(view) do
1087 if mpropdef.collect_parents(view).has(self) then res.add mpropdef
1088 end
1089 return res
1090 end
1091 end