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