1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 # Collect things from a `Model`.
21 # `model_collect` offers a flattened view of the model without considering any
23 # For this reason, `model_collect` lists all the definitions reachable from all
26 # This is usefull for tools that need a global view of a model like `nitdoc`,
28 # It should not be used for compiling stuffs like computing VFT, where the listed
29 # entities could not be reachable depending on the modules really imported.
36 # FIXME used to bypass RTA limitation on type resolution.
39 # Collect modifier keywords like `redef`, `private` etc.
40 fun collect_modifiers
: Array[String] do
41 return new Array[String]
44 # Collect `self` linearization anchored on `mainmodule`.
45 fun collect_linearization
(mainmodule
: MModule): nullable Array[MEntity] do
49 # Collect `self` ancestors (direct and indirect).
51 # The concept of ancestor is abstract at this stage.
52 fun collect_ancestors
(view
: ModelView): Set[MENTITY] do
53 var done
= new HashSet[MENTITY]
54 var todo
= new Array[MENTITY]
56 todo
.add_all collect_parents
(view
)
57 while todo
.not_empty
do
58 var mentity
= todo
.pop
59 if mentity
== self or done
.has
(mentity
) then continue
60 print
"{mentity} == {self}"
62 todo
.add_all mentity
.collect_parents
(view
)
67 # Collect `self` parents (direct ancestors).
69 # The concept of parent is abstract at this stage.
70 fun collect_parents
(view
: ModelView): Set[MENTITY] is abstract
72 # Collect `self` children (direct descendants).
74 # The concept of child is abstract at this stage.
75 fun collect_children
(view
: ModelView): Set[MENTITY] is abstract
77 # Collect `self` descendants (direct and direct).
79 # The concept of descendant is abstract at this stage.
80 fun collect_descendants
(view
: ModelView): Set[MENTITY] do
81 var done
= new HashSet[MENTITY]
82 var todo
= new Array[MENTITY]
84 todo
.add_all collect_children
(view
)
85 while todo
.not_empty
do
86 var mentity
= todo
.pop
87 if mentity
== self or done
.has
(mentity
) then continue
89 todo
.add_all mentity
.collect_children
(view
)
94 # Build a poset representing `self` in it's own hierarchy.
96 # The notion of hierarchy depends on the type of MEntity.
99 # * MPackage: package dependencies
100 # * MGroup: group dependencies
101 # * MModule: modules imports
102 # * MClass: class inheritance (all classdefs flattened)
103 # * MClassDef: classdef inheritance
104 # * MProperty: property definitions graph (all propdefs flattened)
105 # * MPropDef: property definitions graph
106 fun hierarchy_poset
(view
: ModelView): POSet[MENTITY] do
107 var done
= new HashSet[MENTITY]
108 var mentities
= new Array[MENTITY]
110 var poset
= new POSet[MENTITY]
111 while mentities
.not_empty
do
112 var mentity
= mentities
.pop
113 if done
.has
(mentity
) then continue
115 poset
.add_node mentity
116 for parent
in mentity
.collect_parents
(view
) do
117 poset
.add_edge
(mentity
, parent
)
120 for child
in mentity
.collect_children
(view
) do
121 poset
.add_edge
(child
, mentity
)
130 redef fun collect_modifiers
do
136 # `MPackage` parents are its direct dependencies.
137 redef fun collect_parents
(view
) do
138 var res
= new HashSet[MENTITY]
139 for mgroup
in mgroups
do
140 for parent
in mgroup
.collect_parents
(view
) do
141 var mpackage
= parent
.mpackage
142 if mpackage
== self or not view
.accept_mentity
(mpackage
) then continue
149 # `MPackage` children are packages that directly depends on `self`.
150 redef fun collect_children
(view
) do
151 var res
= new HashSet[MENTITY]
152 for mpackage
in view
.mpackages
do
153 if mpackage
.collect_parents
(view
).has
(self) then res
.add mpackage
158 # `MModules` contained in `self`.
159 fun collect_mmodules
(view
: ModelView): HashSet[MModule] do
160 var res
= new HashSet[MModule]
161 for mgroup
in mgroups
do
162 for mmodule
in mgroup
.mmodules
do
163 if not view
.accept_mentity
(mmodule
) then continue
172 redef fun collect_modifiers
do
178 # `MGroup` parents are its direct dependencies.
179 redef fun collect_parents
(view
) do
180 var res
= new HashSet[MENTITY]
181 for mmodule
in mmodules
do
182 for parent
in mmodule
.collect_parents
(view
) do
183 var mgroup
= parent
.mgroup
184 if mgroup
== null or mgroup
== self then continue
185 if not view
.accept_mentity
(mgroup
) then continue
192 # `MGroup` children are mgroups that directly depends on `self`.
193 redef fun collect_children
(view
) do
194 var res
= new HashSet[MENTITY]
195 for mgroup
in view
.mgroups
do
196 if mgroup
== self or not view
.accept_mentity
(mgroup
) then continue
197 if mgroup
.collect_parents
(view
).has
(self) then res
.add mgroup
205 redef fun collect_modifiers
do
211 # `MModule` ancestors are all its transitive imports.
212 redef fun collect_ancestors
(view
) do
213 var res
= new HashSet[MENTITY]
214 for mentity
in in_importation
.greaters
do
215 if mentity
== self then continue
216 if not view
.accept_mentity
(mentity
) then continue
222 # `MModule` parents are all its direct imports.
223 redef fun collect_parents
(view
) do
224 var res
= new HashSet[MENTITY]
225 for mentity
in in_importation
.direct_greaters
do
226 if mentity
== self then continue
227 if not view
.accept_mentity
(mentity
) then continue
233 # `MModule` children are modules that directly import `self`.
234 redef fun collect_children
(view
) do
235 var res
= new HashSet[MENTITY]
236 for mentity
in in_importation
.direct_smallers
do
237 if mentity
== self then continue
238 if not view
.accept_mentity
(mentity
) then continue
244 # `MModule` children are modules that transitively import `self`.
245 redef fun collect_descendants
(view
) do
246 var res
= new HashSet[MENTITY]
247 for mentity
in in_importation
.smallers
do
248 if mentity
== self then continue
249 if not view
.accept_mentity
(mentity
) then continue
255 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
256 fun collect_intro_mclassdefs
(view
: ModelView): Set[MClassDef] do
257 var res
= new HashSet[MClassDef]
258 for mclassdef
in mclassdefs
do
259 if not mclassdef
.is_intro
then continue
260 if not view
.accept_mentity
(mclassdef
) then continue
266 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
267 fun collect_redef_mclassdefs
(view
: ModelView): Set[MClassDef] do
268 var res
= new HashSet[MClassDef]
269 for mclassdef
in mclassdefs
do
270 if mclassdef
.is_intro
then continue
271 if not view
.accept_mentity
(mclassdef
) then continue
277 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
278 fun collect_intro_mclasses
(view
: ModelView): Set[MClass] do
279 var res
= new HashSet[MClass]
280 for mclass
in intro_mclasses
do
281 if not view
.accept_mentity
(mclass
) then continue
287 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
288 fun collect_redef_mclasses
(view
: ModelView): Set[MClass] do
289 var mclasses
= new HashSet[MClass]
290 for mclassdef
in mclassdefs
do
291 if not view
.accept_mentity
(mclassdef
) then continue
292 if not mclassdef
.is_intro
then mclasses
.add
(mclassdef
.mclass
)
300 redef fun collect_modifiers
do return intro
.collect_modifiers
302 redef fun collect_linearization
(mainmodule
) do
303 var mclassdefs
= self.mclassdefs
.to_a
304 mainmodule
.linearize_mclassdefs
(mclassdefs
)
308 # `MClass` parents are the direct parents of `self`.
310 # This method uses a flattened hierarchy containing all the mclassdefs.
311 redef fun collect_parents
(view
) do
312 var res
= new HashSet[MENTITY]
313 for mclassdef
in mclassdefs
do
314 for parent
in mclassdef
.collect_parents
(view
) do
315 var mclass
= parent
.mclass
316 if mclass
== self or not view
.accept_mentity
(parent
) then continue
323 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
324 redef fun collect_ancestors
(view
) do
325 var res
= new HashSet[MENTITY]
326 for mclassdef
in mclassdefs
do
327 for parent
in mclassdef
.collect_parents
(view
) do
328 if not view
.accept_mentity
(parent
) then continue
329 res
.add parent
.mclass
335 # `MClass` parents are the direct parents of `self`.
337 # This method uses a flattened hierarchy containing all the mclassdefs.
338 redef fun collect_children
(view
) do
339 var res
= new HashSet[MENTITY]
340 for mclassdef
in mclassdefs
do
341 for child
in mclassdef
.collect_children
(view
) do
342 var mclass
= child
.mclass
343 if mclass
== self or not view
.accept_mentity
(child
) then continue
350 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
351 fun collect_intro_mproperties
(view
: ModelView): Set[MProperty] do
352 var set
= new HashSet[MProperty]
353 for mclassdef
in mclassdefs
do
354 for mprop
in mclassdef
.intro_mproperties
do
355 if not view
.accept_mentity
(mprop
) then continue
362 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
363 fun collect_redef_mproperties
(view
: ModelView): Set[MProperty] do
364 var set
= new HashSet[MProperty]
365 for mclassdef
in mclassdefs
do
366 for mpropdef
in mclassdef
.mpropdefs
do
367 if mpropdef
.mproperty
.intro_mclassdef
.mclass
== self then continue
368 if not view
.accept_mentity
(mpropdef
) then continue
369 set
.add
(mpropdef
.mproperty
)
375 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
376 fun collect_local_mproperties
(view
: ModelView): Set[MProperty] do
377 var set
= new HashSet[MProperty]
378 set
.add_all collect_intro_mproperties
(view
)
379 set
.add_all collect_redef_mproperties
(view
)
383 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
384 fun collect_inherited_mproperties
(view
: ModelView): Set[MProperty] do
385 var set
= new HashSet[MProperty]
386 for parent
in collect_parents
(view
) do
387 set
.add_all
(parent
.collect_intro_mproperties
(view
))
388 set
.add_all
(parent
.collect_inherited_mproperties
(view
))
393 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
395 # This include introduced, redefined, inherited mproperties.
396 fun collect_accessible_mproperties
(view
: ModelView): Set[MProperty] do
397 var set
= new HashSet[MProperty]
398 set
.add_all
(collect_intro_mproperties
(view
))
399 set
.add_all
(collect_redef_mproperties
(view
))
400 set
.add_all
(collect_inherited_mproperties
(view
))
404 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
405 fun collect_intro_mmethods
(view
: ModelView): Set[MMethod] do
406 var res
= new HashSet[MMethod]
407 for mproperty
in collect_intro_mproperties
(view
) do
408 if mproperty
isa MMethod then res
.add
(mproperty
)
413 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
414 fun collect_redef_mmethods
(view
: ModelView): Set[MMethod] do
415 var res
= new HashSet[MMethod]
416 for mproperty
in collect_redef_mproperties
(view
) do
417 if mproperty
isa MMethod then res
.add
(mproperty
)
422 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
423 fun collect_local_mmethods
(view
: ModelView): Set[MMethod] do
424 var set
= new HashSet[MMethod]
425 set
.add_all collect_intro_mmethods
(view
)
426 set
.add_all collect_redef_mmethods
(view
)
430 # Collect mmethods inherited by 'self' if accepted by `view`.
431 fun collect_inherited_mmethods
(view
: ModelView): Set[MMethod] do
432 var res
= new HashSet[MMethod]
433 for mproperty
in collect_inherited_mproperties
(view
) do
434 if mproperty
isa MMethod then res
.add
(mproperty
)
439 # Collect all mmethods accessible by 'self' with `visibility >= min_visibility`.
441 # This include introduced, redefined, inherited mmethods.
442 fun collect_accessible_mmethods
(view
: ModelView): Set[MMethod] do
443 var set
= new HashSet[MMethod]
444 set
.add_all
(collect_intro_mmethods
(view
))
445 set
.add_all
(collect_redef_mmethods
(view
))
446 set
.add_all
(collect_inherited_mmethods
(view
))
450 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
451 fun collect_intro_mattributes
(view
: ModelView): Set[MAttribute] do
452 var res
= new HashSet[MAttribute]
453 for mproperty
in collect_intro_mproperties
(view
) do
454 if mproperty
isa MAttribute then res
.add
(mproperty
)
459 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
460 fun collect_redef_mattributes
(view
: ModelView): Set[MAttribute] do
461 var res
= new HashSet[MAttribute]
462 for mproperty
in collect_redef_mproperties
(view
) do
463 if mproperty
isa MAttribute then res
.add
(mproperty
)
468 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
469 fun collect_local_mattributes
(view
: ModelView): Set[MAttribute] do
470 var set
= new HashSet[MAttribute]
471 set
.add_all collect_intro_mattributes
(view
)
472 set
.add_all collect_redef_mattributes
(view
)
476 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
477 fun collect_inherited_mattributes
(view
: ModelView): Set[MAttribute] do
478 var res
= new HashSet[MAttribute]
479 for mproperty
in collect_inherited_mproperties
(view
) do
480 if mproperty
isa MAttribute then res
.add
(mproperty
)
485 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
487 # This include introduced, redefined, inherited mattributes.
488 fun collect_accessible_mattributes
(view
: ModelView): Set[MAttribute] do
489 var set
= new HashSet[MAttribute]
490 set
.add_all
(collect_intro_mattributes
(view
))
491 set
.add_all
(collect_redef_mattributes
(view
))
492 set
.add_all
(collect_inherited_mattributes
(view
))
496 # Collect init mmethods introduced in 'self' if accepted by `view`.
497 fun collect_intro_inits
(view
: ModelView): Set[MMethod] do
498 var res
= new HashSet[MMethod]
499 for mproperty
in collect_intro_mmethods
(view
) do
500 if mproperty
.is_init
then res
.add
(mproperty
)
505 # Collect init mmethods redefined in 'self' if accepted by `view`.
506 fun collect_redef_inits
(view
: ModelView): Set[MMethod] do
507 var res
= new HashSet[MMethod]
508 for mproperty
in collect_redef_mmethods
(view
) do
509 if mproperty
.is_init
then res
.add
(mproperty
)
514 # Collect init mmethods introduced and redefined in 'self' if accepted by `view`.
515 fun collect_local_inits
(view
: ModelView): Set[MMethod] do
516 var set
= new HashSet[MMethod]
517 set
.add_all collect_intro_inits
(view
)
518 set
.add_all collect_redef_inits
(view
)
522 # Collect init mmethods inherited by 'self' if accepted by `view`.
523 fun collect_inherited_inits
(view
: ModelView): Set[MMethod] do
524 var res
= new HashSet[MMethod]
525 for mproperty
in collect_inherited_mmethods
(view
) do
526 if mproperty
.is_init
then res
.add
(mproperty
)
531 # Collect all init mmethods accessible by 'self' if accepted by `view`.
533 # This include introduced, redefined, inherited inits.
534 fun collect_accessible_inits
(view
: ModelView): Set[MMethod] do
535 var set
= new HashSet[MMethod]
536 set
.add_all
(collect_intro_inits
(view
))
537 set
.add_all
(collect_redef_inits
(view
))
538 set
.add_all
(collect_inherited_inits
(view
))
542 # Collect all virtual types accessible by 'self' if accepted by `view`.
544 # This include introduced, redefined, inherited virtual types.
545 fun collect_accessible_vts
(view
: ModelView): Set[MVirtualTypeProp] do
546 var set
= new HashSet[MVirtualTypeProp]
547 for mproperty
in collect_accessible_mproperties
(view
) do
548 if mproperty
isa MVirtualTypeProp then set
.add mproperty
554 redef class MClassDef
556 redef fun collect_linearization
(mainmodule
) do
557 var mclassdefs
= new Array[MClassDef]
558 for mclassdef
in in_hierarchy
.as(not null).greaters
do
559 if mclassdef
.mclass
== self.mclass
then mclassdefs
.add mclassdef
561 mainmodule
.linearize_mclassdefs
(mclassdefs
)
565 # `MClassDef` ancestors are its direct and transitive super classes.
566 redef fun collect_ancestors
(view
) do
567 var res
= new HashSet[MENTITY]
568 var hierarchy
= self.in_hierarchy
569 if hierarchy
== null then return res
570 for parent
in hierarchy
.greaters
do
571 if parent
== self or not view
.accept_mentity
(parent
) then continue
577 # `MClassDef` parents are its direct super classes.
578 redef fun collect_parents
(view
) do
579 var res
= new HashSet[MENTITY]
580 var hierarchy
= self.in_hierarchy
581 if hierarchy
== null then return res
582 for parent
in hierarchy
.direct_greaters
do
583 if parent
== self or not view
.accept_mentity
(parent
) then continue
589 # `MClassDef` children are its direct subclasses.
590 redef fun collect_children
(view
) do
591 var res
= new HashSet[MENTITY]
592 var hierarchy
= self.in_hierarchy
593 if hierarchy
== null then return res
594 for child
in hierarchy
.direct_smallers
do
595 if child
== self or not view
.accept_mentity
(child
) then continue
601 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
602 fun collect_mpropdefs
(view
: ModelView): Set[MPropDef] do
603 var res
= new HashSet[MPropDef]
604 for mpropdef
in mpropdefs
do
605 if not view
.accept_mentity
(mpropdef
) then continue
611 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
612 fun collect_intro_mpropdefs
(view
: ModelView): Set[MPropDef] do
613 var res
= new HashSet[MPropDef]
614 for mpropdef
in mpropdefs
do
615 if not mpropdef
.is_intro
then continue
616 if not view
.accept_mentity
(mpropdef
) then continue
622 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
623 fun collect_redef_mpropdefs
(view
: ModelView): Set[MPropDef] do
624 var res
= new HashSet[MPropDef]
625 for mpropdef
in mpropdefs
do
626 if mpropdef
.is_intro
then continue
627 if not view
.accept_mentity
(mpropdef
) then continue
633 redef fun collect_modifiers
do
638 res
.add mclass
.visibility
.to_s
640 res
.add mclass
.kind
.to_s
645 redef class MProperty
646 redef fun collect_modifiers
do return intro
.collect_modifiers
648 redef fun collect_linearization
(mainmodule
) do
649 var mpropdefs
= self.mpropdefs
.to_a
650 mainmodule
.linearize_mpropdefs
(mpropdefs
)
654 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
655 fun collect_mpropdefs
(view
: ModelView): Set[MPropDef] do
656 var res
= new HashSet[MPropDef]
657 for mpropdef
in mpropdefs
do
658 if not view
.accept_mentity
(mpropdef
) then continue
664 # `MProperty` parents are all direct super definition of `self`.
666 # This method uses a flattened hierarchy containing all the mpropdefs.
667 redef fun collect_parents
(view
) do
668 var res
= new HashSet[MENTITY]
669 for mpropdef
in mpropdefs
do
670 for parent
in mpropdef
.collect_parents
(view
) do
671 if not view
.accept_mentity
(parent
) then continue
672 res
.add parent
.mproperty
678 # `MProperty` parents are all direct sub definition of `self`.
680 # This method uses a flattened hierarchy containing all the mpropdefs.
681 redef fun collect_children
(view
) do
682 var res
= new HashSet[MENTITY]
683 for mpropdef
in mpropdefs
do
684 for child
in mpropdef
.collect_parents
(view
) do
685 if not view
.accept_mentity
(child
) then continue
686 res
.add child
.mproperty
694 redef fun collect_modifiers
do
699 res
.add mproperty
.visibility
.to_s
702 if mprop
isa MVirtualTypeDef then
704 else if mprop
isa MMethodDef then
705 if mprop
.is_abstract
then
707 else if mprop
.is_intern
then
710 if mprop
.mproperty
.is_init
then
715 else if mprop
isa MAttributeDef then
721 redef fun collect_linearization
(mainmodule
) do
722 var mpropdefs
= new Array[MPropDef]
724 while not mentity
.is_intro
do
725 mpropdefs
.add mentity
726 mentity
= mentity
.lookup_next_definition
(mainmodule
, mentity
.mclassdef
.bound_mtype
)
728 mpropdefs
.add mentity
729 mainmodule
.linearize_mpropdefs
(mpropdefs
)
733 # `MPropDef` parents include only the next definition of `self`.
734 redef fun collect_parents
(view
) do
735 var res
= new HashSet[MENTITY]
737 while not mpropdef
.is_intro
do
738 mpropdef
= mpropdef
.lookup_next_definition
(mclassdef
.mmodule
, mclassdef
.bound_mtype
)
744 # `MPropdef` children are definitions that directly depends on `self`.
745 redef fun collect_children
(view
) do
746 var res
= new HashSet[MENTITY]
747 for mpropdef
in mproperty
.collect_mpropdefs
(view
) do
748 if mpropdef
.collect_parents
(view
).has
(self) then res
.add mpropdef