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 # Model exploration and traversing facilities
23 fun in_nesting_intro_mclasses
(min_visibility
: MVisibility): Set[MClass] do
24 var res
= new HashSet[MClass]
25 var lst
= in_nesting
.direct_smallers
26 for mmodule
in mmodules
do res
.add_all mmodule
.filter_intro_mclasses
(min_visibility
)
27 for mgrp
in lst
do res
.add_all mgrp
.in_nesting_intro_mclasses
(min_visibility
)
31 fun in_nesting_redef_mclasses
(min_visibility
: MVisibility): Set[MClass] do
32 var res
= new HashSet[MClass]
33 var lst
= in_nesting
.direct_smallers
34 for mmodule
in mmodules
do res
.add_all mmodule
.filter_redef_mclasses
(min_visibility
)
35 for mgrp
in lst
do res
.add_all mgrp
.in_nesting_redef_mclasses
(min_visibility
)
39 fun in_nesting_intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
40 var res
= new HashSet[MClassDef]
41 var lst
= in_nesting
.direct_smallers
42 for mmodule
in mmodules
do res
.add_all mmodule
.intro_mclassdefs
(min_visibility
)
43 for mgrp
in lst
do res
.add_all mgrp
.in_nesting_intro_mclassdefs
(min_visibility
)
47 fun in_nesting_redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
48 var res
= new HashSet[MClassDef]
49 var lst
= in_nesting
.direct_smallers
50 for mmodule
in mmodules
do res
.add_all mmodule
.redef_mclassdefs
(min_visibility
)
51 for mgrp
in lst
do res
.add_all mgrp
.in_nesting_redef_mclassdefs
(min_visibility
)
55 # Collect nested modules
56 fun collect_mmodules
: Set[MModule] do
57 var res
= new HashSet[MModule]
59 for mgroup
in in_nesting
.direct_smallers
do
60 res
.add_all mgroup
.collect_mmodules
68 # The list of intro mclassdef in the module.
69 # with visibility >= to min_visibility
70 fun intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
71 var res
= new HashSet[MClassDef]
72 for mclassdef
in mclassdefs
do
73 if not mclassdef
.is_intro
then continue
74 if mclassdef
.mclass
.visibility
< min_visibility
then continue
80 # The list of redef mclassdef in the module.
81 # with visibility >= to min_visibility
82 fun redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
83 var res
= new HashSet[MClassDef]
84 for mclassdef
in mclassdefs
do
85 if mclassdef
.is_intro
then continue
86 if mclassdef
.mclass
.visibility
< min_visibility
then continue
92 # The list of intro mclass in the module.
93 # with visibility >= to min_visibility
94 fun filter_intro_mclasses
(min_visibility
: MVisibility): Set[MClass] do
95 var res
= new HashSet[MClass]
96 for mclass
in intro_mclasses
do
97 if mclass
.visibility
< min_visibility
then continue
103 # Get the list of mclasses refined in 'self'.
104 fun redef_mclasses
: Set[MClass] do
105 var mclasses
= new HashSet[MClass]
106 for c
in mclassdefs
do
107 if not c
.is_intro
then mclasses
.add
(c
.mclass
)
112 # Get the list of mclasses refined in 'self'.
113 fun filter_redef_mclasses
(min_visibility
: MVisibility): Set[MClass] do
114 var mclasses
= new HashSet[MClass]
115 for c
in mclassdefs
do
116 if c
.mclass
.visibility
< min_visibility
then continue
117 if not c
.is_intro
then mclasses
.add
(c
.mclass
)
122 # Get the list of all mclasses imported by 'self'.
123 fun imported_mclasses
: Set[MClass] do
124 var mclasses
= new HashSet[MClass]
125 for m
in in_importation
.greaters
do
126 if m
== self then continue
127 for c
in m
.mclassdefs
do mclasses
.add
(c
.mclass
)
132 fun in_nesting_intro_mclasses
(min_visibility
: MVisibility): Set[MClass] do
133 var res
= new HashSet[MClass]
134 for mmodule
in in_nesting
.greaters
do
135 for mclass
in mmodule
.filter_intro_mclasses
(min_visibility
) do
136 if mclass
.visibility
< min_visibility
then continue
143 fun in_nesting_redef_mclasses
(min_visibility
: MVisibility): Set[MClass] do
144 var res
= new HashSet[MClass]
145 for mmodule
in self.in_nesting
.greaters
do
146 for mclass
in mmodule
.filter_redef_mclasses
(min_visibility
) do
147 if mclass
.visibility
< min_visibility
then continue
154 fun in_nesting_intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
155 var res
= new HashSet[MClassDef]
156 for mmodule
in in_nesting
.greaters
do
157 res
.add_all mmodule
.intro_mclassdefs
(min_visibility
)
162 fun in_nesting_redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
163 var res
= new HashSet[MClassDef]
164 for mmodule
in self.in_nesting
.greaters
do
165 res
.add_all mmodule
.redef_mclassdefs
(min_visibility
)
173 # Get the public owner of 'self'.
174 fun public_owner
: MModule do
175 var public_owner
= self.intro_mmodule
.public_owner
176 if public_owner
== null then
177 return self.intro_mmodule
183 # Get direct parents of 'self'.
184 fun parents
: Set[MClass] do
185 var ret
= new HashSet[MClass]
186 for mclassdef
in mclassdefs
do
187 for mclasstype
in mclassdef
.supertypes
do
188 ret
.add
(mclasstype
.mclass
)
194 # Get all ancestors of 'self'.
195 fun ancestors
: Set[MClass] do
196 var lst
= new HashSet[MClass]
197 for mclassdef
in self.mclassdefs
do
198 for super_mclassdef
in mclassdef
.in_hierarchy
.greaters
do
199 if super_mclassdef
== mclassdef
then continue # skip self
200 lst
.add
(super_mclassdef
.mclass
)
206 # Get direct children of 'self'.
207 fun children
: Set[MClass] do
208 var lst
= new HashSet[MClass]
209 for mclassdef
in self.mclassdefs
do
210 for sub_mclassdef
in mclassdef
.in_hierarchy
.direct_smallers
do
211 if sub_mclassdef
== mclassdef
then continue # skip self
212 lst
.add
(sub_mclassdef
.mclass
)
218 # Get all children of 'self'.
219 fun descendants
: Set[MClass] do
220 var lst
= new HashSet[MClass]
221 for mclassdef
in self.mclassdefs
do
222 for sub_mclassdef
in mclassdef
.in_hierarchy
.smallers
do
223 if sub_mclassdef
== mclassdef
then continue # skip self
224 lst
.add
(sub_mclassdef
.mclass
)
230 # Get the list of constructors available for 'self'.
231 fun constructors
: Set[MMethod] do
232 var res
= new HashSet[MMethod]
233 for mclassdef
in mclassdefs
do
234 for mpropdef
in mclassdef
.mpropdefs
do
235 if mpropdef
isa MMethodDef then
236 if mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
243 # Get the list of methods introduced in 'self'.
244 fun intro_methods
: Set[MMethod] do
245 var res
= new HashSet[MMethod]
246 for mclassdef
in mclassdefs
do
247 for mpropdef
in mclassdef
.mpropdefs
do
248 if mpropdef
isa MMethodDef then
249 if mpropdef
.is_intro
and not mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
256 # the set of properties introduced in 'self'.
257 fun intro_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
258 var set
= new HashSet[MProperty]
259 for mclassdef
in mclassdefs
do
260 for mprop
in mclassdef
.intro_mproperties
do
261 if mprop
.visibility
< min_visibility
then continue
268 fun intro_mpropdefs
(min_visibility
: MVisibility): Set[MPropDef] do
269 var set
= new HashSet[MPropDef]
270 for mclassdef
in mclassdefs
do
271 for mpropdef
in mclassdef
.mpropdefs
do
272 if not mpropdef
.is_intro
then continue
273 if mpropdef
.mproperty
.visibility
< min_visibility
then continue
280 # the set of locally refined properties in 'self'.
281 fun redef_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
282 var set
= new HashSet[MProperty]
283 for mclassdef
in mclassdefs
do
284 for mpropdef
in mclassdef
.mpropdefs
do
285 if mpropdef
.mproperty
.visibility
< min_visibility
then continue
286 if mpropdef
.mproperty
.intro_mclassdef
.mclass
!= self then set
.add
(mpropdef
.mproperty
)
292 fun redef_mpropdefs
(min_visibility
: MVisibility): Set[MPropDef] do
293 var set
= new HashSet[MPropDef]
294 for mclassdef
in mclassdefs
do
295 for mpropdef
in mclassdef
.mpropdefs
do
296 if mpropdef
.is_intro
then continue
297 if mpropdef
.mproperty
.visibility
< min_visibility
then continue
304 # the set of methods inherited by 'self'.
305 fun inherited_mproperties
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MProperty] do
306 var set
= new HashSet[MProperty]
307 for parent
in in_hierarchy
(mainmodule
).direct_greaters
do
308 set
.add_all
(parent
.intro_mproperties
(min_visibility
))
309 set
.add_all
(parent
.inherited_mproperties
(mainmodule
, min_visibility
))
314 # the set of introduced and redefined mproperties
315 fun local_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
316 var set
= new HashSet[MProperty]
317 set
.add_all
(intro_mproperties
(min_visibility
))
318 set
.add_all
(redef_mproperties
(min_visibility
))
322 # the set of all accessible mproperties for this class
323 fun all_mproperties
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MProperty] do
324 var set
= new HashSet[MProperty]
325 set
.add_all
(local_mproperties
(min_visibility
))
326 set
.add_all
(inherited_mproperties
(mainmodule
, min_visibility
))
330 # the set of all accessible mattributes for this class
331 fun all_mattributes
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MAttribute] do
332 var set
= new HashSet[MAttribute]
333 for mprop
in all_mproperties
(mainmodule
, min_visibility
) do
334 if mprop
isa MAttribute then set
.add
(mprop
)
339 # Get the list of locally refined methods in 'self'.
340 fun redef_methods
: Set[MMethod] do
341 var res
= new HashSet[MMethod]
342 for mclassdef
in mclassdefs
do
343 for mpropdef
in mclassdef
.mpropdefs
do
344 if mpropdef
isa MMethodDef then
345 if not mpropdef
.is_intro
and not mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
352 fun inherited_methods
: Set[MMethod] do
353 var res
= new HashSet[MMethod]
354 for s
in ancestors
do
355 for m
in s
.intro_methods
do
356 if not self.intro_methods
.has
(m
) and not self.redef_methods
.has
(m
) then res
.add
(m
)
362 # Get the list of all virtual types available in 'self'.
363 fun virtual_types
: Set[MVirtualTypeProp] do
364 var res
= new HashSet[MVirtualTypeProp]
365 for mclassdef
in mclassdefs
do
366 for mpropdef
in mclassdef
.mpropdefs
do
367 if mpropdef
isa MVirtualTypeDef then
368 res
.add
(mpropdef
.mproperty
)
372 for ancestor
in ancestors
do
373 for mclassdef
in ancestor
.mclassdefs
do
374 for mpropdef
in mclassdef
.mpropdefs
do
375 if mpropdef
isa MVirtualTypeDef then
376 res
.add
(mpropdef
.mproperty
)
384 # Get the list of all parameter types in 'self'.
385 fun parameter_types
: Map[String, MType] do
386 var res
= new HashMap[String, MType]
387 for i
in [0..intro
.parameter_names
.length
[ do
388 res
[intro
.parameter_names
[i
]] = intro
.bound_mtype
.arguments
[i
]
393 fun is_class
: Bool do
394 return self.kind
== concrete_kind
or self.kind
== abstract_kind
397 fun is_interface
: Bool do
398 return self.kind
== interface_kind
402 return self.kind
== enum_kind
405 fun is_abstract
: Bool do
406 return self.kind
== abstract_kind
410 redef class MAttribute
411 # Is this attribute nullable for sure?
413 # This mean that its introduction is declarred with a nullable static type
414 # since attributes are invariant this will work on most cases
415 # attributes with static type anchored with a virtual type are not "nullable for-sure"
416 # because this type can be redefined in subclasses
417 fun is_nullable
: Bool do return intro
.static_mtype
isa MNullableType
420 redef class MClassDef
421 # modifiers are keywords like redef, private etc.
422 fun modifiers
: Array[String] do
423 var res
= new Array[String]
427 res
.add mclass
.visibility
.to_s
429 res
.add mclass
.kind
.to_s
435 # modifiers are keywords like redef, private etc.
436 fun modifiers
: Array[String] do
437 var res
= new Array[String]
441 res
.add mproperty
.visibility
.to_s
444 if mprop
isa MVirtualTypeDef then
446 else if mprop
isa MMethodDef then
447 if mprop
.is_abstract
then
449 else if mprop
.is_intern
then
452 if mprop
.mproperty
.is_init
then
465 # Sort mentities by their name
466 class MEntityNameSorter
467 super AbstractSorter[MEntity]
468 redef fun compare
(a
, b
) do return a
.name
<=> b
.name