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
24 # The list of intro mclassdef in the module.
25 # with visibility >= to min_visibility
26 fun intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
27 var res
= new HashSet[MClassDef]
28 for mclassdef
in mclassdefs
do
29 if not mclassdef
.is_intro
then continue
30 if mclassdef
.mclass
.visibility
< min_visibility
then continue
36 # The list of redef mclassdef in the module.
37 # with visibility >= to min_visibility
38 fun redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
39 var res
= new HashSet[MClassDef]
40 for mclassdef
in mclassdefs
do
41 if mclassdef
.is_intro
then continue
42 if mclassdef
.mclass
.visibility
< min_visibility
then continue
48 # Get the list of mclasses refined in 'self'.
49 fun redef_mclasses
: Set[MClass] do
50 var mclasses
= new HashSet[MClass]
51 for c
in mclassdefs
do
52 if not c
.is_intro
then mclasses
.add
(c
.mclass
)
57 # Get the list of all mclasses imported by 'self'.
58 fun imported_mclasses
: Set[MClass] do
59 var mclasses
= new HashSet[MClass]
60 for m
in in_importation
.greaters
do
61 if m
== self then continue
62 for c
in m
.mclassdefs
do mclasses
.add
(c
.mclass
)
67 fun in_nesting_intro_mclasses
(min_visibility
: MVisibility): Set[MClass] do
68 var res
= new HashSet[MClass]
69 for mmodule
in in_nesting
.greaters
do
70 for mclass
in mmodule
.intro_mclasses
do
71 if mclass
.visibility
< min_visibility
then continue
78 fun in_nesting_redef_mclasses
(min_visibility
: MVisibility): Set[MClass] do
79 var res
= new HashSet[MClass]
80 for mmodule
in self.in_nesting
.greaters
do
81 for mclass
in mmodule
.redef_mclasses
do
82 if mclass
.visibility
< min_visibility
then continue
89 fun in_nesting_intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
90 var res
= new HashSet[MClassDef]
91 for mmodule
in in_nesting
.greaters
do
92 res
.add_all mmodule
.intro_mclassdefs
(min_visibility
)
97 fun in_nesting_redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
98 var res
= new HashSet[MClassDef]
99 for mmodule
in self.in_nesting
.greaters
do
100 res
.add_all mmodule
.redef_mclassdefs
(min_visibility
)
108 # Get the public owner of 'self'.
109 fun public_owner
: MModule do
110 var public_owner
= self.intro_mmodule
.public_owner
111 if public_owner
== null then
112 return self.intro_mmodule
118 # Get direct parents of 'self'.
119 fun parents
: Set[MClass] do
120 var ret
= new HashSet[MClass]
121 for mclassdef
in mclassdefs
do
122 for mclasstype
in mclassdef
.supertypes
do
123 ret
.add
(mclasstype
.mclass
)
129 # Get all ancestors of 'self'.
130 fun ancestors
: Set[MClass] do
131 var lst
= new HashSet[MClass]
132 for mclassdef
in self.mclassdefs
do
133 for super_mclassdef
in mclassdef
.in_hierarchy
.greaters
do
134 if super_mclassdef
== mclassdef
then continue # skip self
135 lst
.add
(super_mclassdef
.mclass
)
141 # Get direct children of 'self'.
142 fun children
: Set[MClass] do
143 var lst
= new HashSet[MClass]
144 for mclassdef
in self.mclassdefs
do
145 for sub_mclassdef
in mclassdef
.in_hierarchy
.direct_smallers
do
146 if sub_mclassdef
== mclassdef
then continue # skip self
147 lst
.add
(sub_mclassdef
.mclass
)
153 # Get all children of 'self'.
154 fun descendants
: Set[MClass] do
155 var lst
= new HashSet[MClass]
156 for mclassdef
in self.mclassdefs
do
157 for sub_mclassdef
in mclassdef
.in_hierarchy
.smallers
do
158 if sub_mclassdef
== mclassdef
then continue # skip self
159 lst
.add
(sub_mclassdef
.mclass
)
165 # Get the list of constructors available for 'self'.
166 fun constructors
: Set[MMethod] do
167 var res
= new HashSet[MMethod]
168 for mclassdef
in mclassdefs
do
169 for mpropdef
in mclassdef
.mpropdefs
do
170 if mpropdef
isa MMethodDef then
171 if mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
178 # Get the list of methods introduced in 'self'.
179 fun intro_methods
: Set[MMethod] do
180 var res
= new HashSet[MMethod]
181 for mclassdef
in mclassdefs
do
182 for mpropdef
in mclassdef
.mpropdefs
do
183 if mpropdef
isa MMethodDef then
184 if mpropdef
.is_intro
and not mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
191 # the set of properties introduced in 'self'.
192 fun intro_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
193 var set
= new HashSet[MProperty]
194 for mclassdef
in mclassdefs
do
195 for mprop
in mclassdef
.intro_mproperties
do
196 if mprop
.visibility
< min_visibility
then continue
203 # the set of locally refined properties in 'self'.
204 fun redef_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
205 var set
= new HashSet[MProperty]
206 for mclassdef
in mclassdefs
do
207 for mpropdef
in mclassdef
.mpropdefs
do
208 if mpropdef
.mproperty
.visibility
< min_visibility
then continue
209 if mpropdef
.mproperty
.intro_mclassdef
.mclass
!= self then set
.add
(mpropdef
.mproperty
)
215 # the set of methods inherited by 'self'.
216 fun inherited_mproperties
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MProperty] do
217 var set
= new HashSet[MProperty]
218 for parent
in in_hierarchy
(mainmodule
).direct_greaters
do
219 set
.add_all
(parent
.intro_mproperties
(min_visibility
))
220 set
.add_all
(parent
.inherited_mproperties
(mainmodule
, min_visibility
))
225 # the set of introduced and redefined mproperties
226 fun local_mproperties
(min_visibility
: MVisibility): Set[MProperty] do
227 var set
= new HashSet[MProperty]
228 set
.add_all
(intro_mproperties
(min_visibility
))
229 set
.add_all
(redef_mproperties
(min_visibility
))
233 # the set of all accessible mproperties for this class
234 fun all_mproperties
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MProperty] do
235 var set
= new HashSet[MProperty]
236 set
.add_all
(local_mproperties
(min_visibility
))
237 set
.add_all
(inherited_mproperties
(mainmodule
, min_visibility
))
241 # the set of all accessible mattributes for this class
242 fun all_mattributes
(mainmodule
: MModule, min_visibility
: MVisibility): Set[MAttribute] do
243 var set
= new HashSet[MAttribute]
244 for mprop
in all_mproperties
(mainmodule
, min_visibility
) do
245 if mprop
isa MAttribute then set
.add
(mprop
)
250 # Get the list of locally refined methods in 'self'.
251 fun redef_methods
: Set[MMethod] do
252 var res
= new HashSet[MMethod]
253 for mclassdef
in mclassdefs
do
254 for mpropdef
in mclassdef
.mpropdefs
do
255 if mpropdef
isa MMethodDef then
256 if not mpropdef
.is_intro
and not mpropdef
.mproperty
.is_init
then res
.add
(mpropdef
.mproperty
)
263 fun inherited_methods
: Set[MMethod] do
264 var res
= new HashSet[MMethod]
265 for s
in ancestors
do
266 for m
in s
.intro_methods
do
267 if not self.intro_methods
.has
(m
) and not self.redef_methods
.has
(m
) then res
.add
(m
)
273 # Get the list of all virtual types available in 'self'.
274 fun virtual_types
: Set[MVirtualTypeProp] do
275 var res
= new HashSet[MVirtualTypeProp]
276 for mclassdef
in mclassdefs
do
277 for mpropdef
in mclassdef
.mpropdefs
do
278 if mpropdef
isa MVirtualTypeDef then
279 res
.add
(mpropdef
.mproperty
)
283 for ancestor
in ancestors
do
284 for mclassdef
in ancestor
.mclassdefs
do
285 for mpropdef
in mclassdef
.mpropdefs
do
286 if mpropdef
isa MVirtualTypeDef then
287 res
.add
(mpropdef
.mproperty
)
295 # Get the list of all parameter types in 'self'.
296 fun parameter_types
: Map[String, MType] do
297 var res
= new HashMap[String, MType]
298 for i
in [0..intro
.parameter_names
.length
[ do
299 res
[intro
.parameter_names
[i
]] = intro
.bound_mtype
.arguments
[i
]
304 fun is_class
: Bool do
305 return self.kind
== concrete_kind
or self.kind
== abstract_kind
308 fun is_interface
: Bool do
309 return self.kind
== interface_kind
313 return self.kind
== enum_kind
316 fun is_abstract
: Bool do
317 return self.kind
== abstract_kind
321 redef class MAttribute
322 # Is this attribute nullable for sure?
324 # This mean that its introduction is declarred with a nullable static type
325 # since attributes are invariant this will work on most cases
326 # attributes with static type anchored with a virtual type are not "nullable for-sure"
327 # because this type can be redefined in subclasses
328 fun is_nullable
: Bool do return intro
.static_mtype
isa MNullableType
331 redef class MClassDef
332 # modifiers are keywords like redef, private etc.
333 fun modifiers
: Array[String] do
334 var res
= new Array[String]
338 res
.add mclass
.visibility
.to_s
340 res
.add mclass
.kind
.to_s
346 # modifiers are keywords like redef, private etc.
347 fun modifiers
: Array[String] do
348 var res
= new Array[String]
352 res
.add mproperty
.visibility
.to_s
355 if mprop
isa MVirtualTypeDef then
357 else if mprop
isa MMethodDef then
358 if mprop
.is_abstract
then
360 else if mprop
.is_intern
then
363 if mprop
.mproperty
.is_init
then
376 # Sort mmodules by their name
377 class MModuleNameSorter
378 super AbstractSorter[MModule]
379 redef fun compare
(a
, b
) do return a
.name
<=> b
.name
383 # Sort mclasses by their name
384 class MClassNameSorter
385 super AbstractSorter[MClass]
386 redef fun compare
(a
, b
) do return a
.name
<=> b
.name
390 # Sort mclassdefs by their name
391 class MClassDefNameSorter
392 super AbstractSorter[MClassDef]
393 redef fun compare
(a
, b
) do return a
.mclass
.name
<=> b
.mclass
.name
397 # Sort mproperties by their name
398 class MPropertyNameSorter
399 super AbstractSorter[MProperty]
400 redef fun compare
(a
, b
) do return a
.name
<=> b
.name
404 # Sort mpropdefs by their name
405 class MPropDefNameSorter
406 super AbstractSorter[MPropDef]
407 redef fun compare
(a
, b
) do return a
.mproperty
.name
<=> b
.mproperty
.name