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