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
160 redef fun collect_modifiers
do
166 # `MGroup` parents are its direct dependencies.
167 redef fun collect_parents
(view
) do
168 var res
= new HashSet[MENTITY]
169 for mmodule
in mmodules
do
170 for parent
in mmodule
.collect_parents
(view
) do
171 var mgroup
= parent
.mgroup
172 if mgroup
== null or mgroup
== self then continue
173 if not view
.accept_mentity
(mgroup
) then continue
180 # `MGroup` children are mgroups that directly depends on `self`.
181 redef fun collect_children
(view
) do
182 var res
= new HashSet[MENTITY]
183 for mgroup
in view
.mgroups
do
184 if mgroup
== self or not view
.accept_mentity
(mgroup
) then continue
185 if mgroup
.collect_parents
(view
).has
(self) then res
.add mgroup
193 redef fun collect_modifiers
do
199 # `MModule` ancestors are all its transitive imports.
200 redef fun collect_ancestors
(view
) do
201 var res
= new HashSet[MENTITY]
202 for mentity
in in_importation
.greaters
do
203 if mentity
== self then continue
204 if not view
.accept_mentity
(mentity
) then continue
210 # `MModule` parents are all its direct imports.
211 redef fun collect_parents
(view
) do
212 var res
= new HashSet[MENTITY]
213 for mentity
in in_importation
.direct_greaters
do
214 if mentity
== self then continue
215 if not view
.accept_mentity
(mentity
) then continue
221 # `MModule` children are modules that directly import `self`.
222 redef fun collect_children
(view
) do
223 var res
= new HashSet[MENTITY]
224 for mentity
in in_importation
.direct_smallers
do
225 if mentity
== self then continue
226 if not view
.accept_mentity
(mentity
) then continue
232 # `MModule` children are modules that transitively import `self`.
233 redef fun collect_descendants
(view
) do
234 var res
= new HashSet[MENTITY]
235 for mentity
in in_importation
.smallers
do
236 if mentity
== self then continue
237 if not view
.accept_mentity
(mentity
) then continue
243 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
244 fun collect_intro_mclassdefs
(view
: ModelView): Set[MClassDef] do
245 var res
= new HashSet[MClassDef]
246 for mclassdef
in mclassdefs
do
247 if not mclassdef
.is_intro
then continue
248 if not view
.accept_mentity
(mclassdef
) then continue
254 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
255 fun collect_redef_mclassdefs
(view
: ModelView): Set[MClassDef] do
256 var res
= new HashSet[MClassDef]
257 for mclassdef
in mclassdefs
do
258 if mclassdef
.is_intro
then continue
259 if not view
.accept_mentity
(mclassdef
) then continue
265 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
266 fun collect_intro_mclasses
(view
: ModelView): Set[MClass] do
267 var res
= new HashSet[MClass]
268 for mclass
in intro_mclasses
do
269 if not view
.accept_mentity
(mclass
) then continue
275 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
276 fun collect_redef_mclasses
(view
: ModelView): Set[MClass] do
277 var mclasses
= new HashSet[MClass]
278 for mclassdef
in mclassdefs
do
279 if not view
.accept_mentity
(mclassdef
) then continue
280 if not mclassdef
.is_intro
then mclasses
.add
(mclassdef
.mclass
)
288 redef fun collect_modifiers
do return intro
.collect_modifiers
290 redef fun collect_linearization
(mainmodule
) do
291 var mclassdefs
= self.mclassdefs
.to_a
292 mainmodule
.linearize_mclassdefs
(mclassdefs
)
296 # `MClass` parents are the direct parents of `self`.
298 # This method uses a flattened hierarchy containing all the mclassdefs.
299 redef fun collect_parents
(view
) do
300 var res
= new HashSet[MENTITY]
301 for mclassdef
in mclassdefs
do
302 for parent
in mclassdef
.collect_parents
(view
) do
303 var mclass
= parent
.mclass
304 if mclass
== self or not view
.accept_mentity
(parent
) then continue
311 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
312 redef fun collect_ancestors
(view
) do
313 var res
= new HashSet[MENTITY]
314 for mclassdef
in mclassdefs
do
315 for parent
in mclassdef
.collect_parents
(view
) do
316 if not view
.accept_mentity
(parent
) then continue
317 res
.add parent
.mclass
323 # `MClass` parents are the direct parents of `self`.
325 # This method uses a flattened hierarchy containing all the mclassdefs.
326 redef fun collect_children
(view
) do
327 var res
= new HashSet[MENTITY]
328 for mclassdef
in mclassdefs
do
329 for child
in mclassdef
.collect_children
(view
) do
330 var mclass
= child
.mclass
331 if mclass
== self or not view
.accept_mentity
(child
) then continue
338 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
339 fun collect_intro_mproperties
(view
: ModelView): Set[MProperty] do
340 var set
= new HashSet[MProperty]
341 for mclassdef
in mclassdefs
do
342 for mprop
in mclassdef
.intro_mproperties
do
343 if not view
.accept_mentity
(mprop
) then continue
350 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
351 fun collect_redef_mproperties
(view
: ModelView): Set[MProperty] do
352 var set
= new HashSet[MProperty]
353 for mclassdef
in mclassdefs
do
354 for mpropdef
in mclassdef
.mpropdefs
do
355 if mpropdef
.mproperty
.intro_mclassdef
.mclass
== self then continue
356 if not view
.accept_mentity
(mpropdef
) then continue
357 set
.add
(mpropdef
.mproperty
)
363 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
364 fun collect_local_mproperties
(view
: ModelView): Set[MProperty] do
365 var set
= new HashSet[MProperty]
366 set
.add_all collect_intro_mproperties
(view
)
367 set
.add_all collect_redef_mproperties
(view
)
371 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
372 fun collect_inherited_mproperties
(view
: ModelView): Set[MProperty] do
373 var set
= new HashSet[MProperty]
374 for parent
in collect_parents
(view
) do
375 set
.add_all
(parent
.collect_intro_mproperties
(view
))
376 set
.add_all
(parent
.collect_inherited_mproperties
(view
))
381 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
383 # This include introduced, redefined, inherited mproperties.
384 fun collect_accessible_mproperties
(view
: ModelView): Set[MProperty] do
385 var set
= new HashSet[MProperty]
386 set
.add_all
(collect_intro_mproperties
(view
))
387 set
.add_all
(collect_redef_mproperties
(view
))
388 set
.add_all
(collect_inherited_mproperties
(view
))
392 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
393 fun collect_intro_mmethods
(view
: ModelView): Set[MMethod] do
394 var res
= new HashSet[MMethod]
395 for mproperty
in collect_intro_mproperties
(view
) do
396 if mproperty
isa MMethod then res
.add
(mproperty
)
401 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
402 fun collect_redef_mmethods
(view
: ModelView): Set[MMethod] do
403 var res
= new HashSet[MMethod]
404 for mproperty
in collect_redef_mproperties
(view
) do
405 if mproperty
isa MMethod then res
.add
(mproperty
)
410 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
411 fun collect_local_mmethods
(view
: ModelView): Set[MMethod] do
412 var set
= new HashSet[MMethod]
413 set
.add_all collect_intro_mmethods
(view
)
414 set
.add_all collect_redef_mmethods
(view
)
418 # Collect mmethods inherited by 'self' if accepted by `view`.
419 fun collect_inherited_mmethods
(view
: ModelView): Set[MMethod] do
420 var res
= new HashSet[MMethod]
421 for mproperty
in collect_inherited_mproperties
(view
) do
422 if mproperty
isa MMethod then res
.add
(mproperty
)
427 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
428 fun collect_intro_mattributes
(view
: ModelView): Set[MAttribute] do
429 var res
= new HashSet[MAttribute]
430 for mproperty
in collect_intro_mproperties
(view
) do
431 if mproperty
isa MAttribute then res
.add
(mproperty
)
436 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
437 fun collect_redef_mattributes
(view
: ModelView): Set[MAttribute] do
438 var res
= new HashSet[MAttribute]
439 for mproperty
in collect_redef_mproperties
(view
) do
440 if mproperty
isa MAttribute then res
.add
(mproperty
)
445 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
446 fun collect_local_mattributes
(view
: ModelView): Set[MAttribute] do
447 var set
= new HashSet[MAttribute]
448 set
.add_all collect_intro_mattributes
(view
)
449 set
.add_all collect_redef_mattributes
(view
)
453 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
454 fun collect_inherited_mattributes
(view
: ModelView): Set[MAttribute] do
455 var res
= new HashSet[MAttribute]
456 for mproperty
in collect_inherited_mproperties
(view
) do
457 if mproperty
isa MAttribute then res
.add
(mproperty
)
462 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
464 # This include introduced, redefined, inherited mattributes.
465 fun collect_accessible_mattributes
(view
: ModelView): Set[MAttribute] do
466 var set
= new HashSet[MAttribute]
467 set
.add_all
(collect_intro_mattributes
(view
))
468 set
.add_all
(collect_redef_mattributes
(view
))
469 set
.add_all
(collect_inherited_mattributes
(view
))
473 # Collect init mmethods introduced in 'self' if accepted by `view`.
474 fun collect_intro_inits
(view
: ModelView): Set[MMethod] do
475 var res
= new HashSet[MMethod]
476 for mproperty
in collect_intro_mmethods
(view
) do
477 if mproperty
.is_init
then res
.add
(mproperty
)
482 # Collect init mmethods redefined in 'self' if accepted by `view`.
483 fun collect_redef_inits
(view
: ModelView): Set[MMethod] do
484 var res
= new HashSet[MMethod]
485 for mproperty
in collect_redef_mmethods
(view
) do
486 if mproperty
.is_init
then res
.add
(mproperty
)
491 # Collect init mmethods introduced and redefined in 'self' if accepted by `view`.
492 fun collect_local_inits
(view
: ModelView): Set[MMethod] do
493 var set
= new HashSet[MMethod]
494 set
.add_all collect_intro_inits
(view
)
495 set
.add_all collect_redef_inits
(view
)
499 # Collect init mmethods inherited by 'self' if accepted by `view`.
500 fun collect_inherited_inits
(view
: ModelView): Set[MMethod] do
501 var res
= new HashSet[MMethod]
502 for mproperty
in collect_inherited_mmethods
(view
) do
503 if mproperty
.is_init
then res
.add
(mproperty
)
508 # Collect all init mmethods accessible by 'self' if accepted by `view`.
510 # This include introduced, redefined, inherited inits.
511 fun collect_accessible_inits
(view
: ModelView): Set[MMethod] do
512 var set
= new HashSet[MMethod]
513 set
.add_all
(collect_intro_inits
(view
))
514 set
.add_all
(collect_redef_inits
(view
))
515 set
.add_all
(collect_inherited_inits
(view
))
520 redef class MClassDef
522 redef fun collect_linearization
(mainmodule
) do
523 var mclassdefs
= new Array[MClassDef]
524 for mclassdef
in in_hierarchy
.as(not null).greaters
do
525 if mclassdef
.mclass
== self.mclass
then mclassdefs
.add mclassdef
527 mainmodule
.linearize_mclassdefs
(mclassdefs
)
531 # `MClassDef` ancestors are its direct and transitive super classes.
532 redef fun collect_ancestors
(view
) do
533 var res
= new HashSet[MENTITY]
534 var hierarchy
= self.in_hierarchy
535 if hierarchy
== null then return res
536 for parent
in hierarchy
.greaters
do
537 if parent
== self or not view
.accept_mentity
(parent
) then continue
543 # `MClassDef` parents are its direct super classes.
544 redef fun collect_parents
(view
) do
545 var res
= new HashSet[MENTITY]
546 var hierarchy
= self.in_hierarchy
547 if hierarchy
== null then return res
548 for parent
in hierarchy
.direct_greaters
do
549 if parent
== self or not view
.accept_mentity
(parent
) then continue
555 # `MClassDef` children are its direct subclasses.
556 redef fun collect_children
(view
) do
557 var res
= new HashSet[MENTITY]
558 var hierarchy
= self.in_hierarchy
559 if hierarchy
== null then return res
560 for child
in hierarchy
.direct_smallers
do
561 if child
== self or not view
.accept_mentity
(child
) then continue
567 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
568 fun collect_mpropdefs
(view
: ModelView): Set[MPropDef] do
569 var res
= new HashSet[MPropDef]
570 for mpropdef
in mpropdefs
do
571 if not view
.accept_mentity
(mpropdef
) then continue
577 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
578 fun collect_intro_mpropdefs
(view
: ModelView): Set[MPropDef] do
579 var res
= new HashSet[MPropDef]
580 for mpropdef
in mpropdefs
do
581 if not mpropdef
.is_intro
then continue
582 if not view
.accept_mentity
(mpropdef
) then continue
588 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
589 fun collect_redef_mpropdefs
(view
: ModelView): Set[MPropDef] do
590 var res
= new HashSet[MPropDef]
591 for mpropdef
in mpropdefs
do
592 if mpropdef
.is_intro
then continue
593 if not view
.accept_mentity
(mpropdef
) then continue
599 redef fun collect_modifiers
do
604 res
.add mclass
.visibility
.to_s
606 res
.add mclass
.kind
.to_s
611 redef class MProperty
612 redef fun collect_modifiers
do return intro
.collect_modifiers
614 redef fun collect_linearization
(mainmodule
) do
615 var mpropdefs
= self.mpropdefs
.to_a
616 mainmodule
.linearize_mpropdefs
(mpropdefs
)
620 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
621 fun collect_mpropdefs
(view
: ModelView): Set[MPropDef] do
622 var res
= new HashSet[MPropDef]
623 for mpropdef
in mpropdefs
do
624 if not view
.accept_mentity
(mpropdef
) then continue
630 # `MProperty` parents are all direct super definition of `self`.
632 # This method uses a flattened hierarchy containing all the mpropdefs.
633 redef fun collect_parents
(view
) do
634 var res
= new HashSet[MENTITY]
635 for mpropdef
in mpropdefs
do
636 for parent
in mpropdef
.collect_parents
(view
) do
637 if not view
.accept_mentity
(parent
) then continue
638 res
.add parent
.mproperty
644 # `MProperty` parents are all direct sub definition of `self`.
646 # This method uses a flattened hierarchy containing all the mpropdefs.
647 redef fun collect_children
(view
) do
648 var res
= new HashSet[MENTITY]
649 for mpropdef
in mpropdefs
do
650 for child
in mpropdef
.collect_parents
(view
) do
651 if not view
.accept_mentity
(child
) then continue
652 res
.add child
.mproperty
660 redef fun collect_modifiers
do
665 res
.add mproperty
.visibility
.to_s
668 if mprop
isa MVirtualTypeDef then
670 else if mprop
isa MMethodDef then
671 if mprop
.is_abstract
then
673 else if mprop
.is_intern
then
676 if mprop
.mproperty
.is_init
then
681 else if mprop
isa MAttributeDef then
687 redef fun collect_linearization
(mainmodule
) do
688 var mpropdefs
= new Array[MPropDef]
690 while not mentity
.is_intro
do
691 mpropdefs
.add mentity
692 mentity
= mentity
.lookup_next_definition
(mainmodule
, mentity
.mclassdef
.bound_mtype
)
694 mpropdefs
.add mentity
695 mainmodule
.linearize_mpropdefs
(mpropdefs
)
699 # `MPropDef` parents include only the next definition of `self`.
700 redef fun collect_parents
(view
) do
701 var res
= new HashSet[MENTITY]
703 while not mpropdef
.is_intro
do
704 mpropdef
= mpropdef
.lookup_next_definition
(mclassdef
.mmodule
, mclassdef
.bound_mtype
)
710 # `MPropdef` children are definitions that directly depends on `self`.
711 redef fun collect_children
(view
) do
712 var res
= new HashSet[MENTITY]
713 for mpropdef
in mproperty
.collect_mpropdefs
(view
) do
714 if mpropdef
.collect_parents
(view
).has
(self) then res
.add mpropdef