ni_nitdoc: cleaned model_utils
[nit.git] / src / model_utils.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 # Model exploration and traversing facilities
18 module model_utils
19
20 import toolcontext
21 import exprbuilder
22
23 redef class MModule
24 # Get the list of mclasses refined in 'self'.
25 fun redef_mclasses: Set[MClass] do
26 var mclasses = new HashSet[MClass]
27 for c in mclassdefs do
28 if not c.is_intro then mclasses.add(c.mclass)
29 end
30 return mclasses
31 end
32
33 # Get the list of all mclasses imported by 'self'.
34 fun imported_mclasses: Set[MClass] do
35 var mclasses = new HashSet[MClass]
36 for m in in_importation.greaters do
37 if m == self then continue
38 for c in m.mclassdefs do mclasses.add(c.mclass)
39 end
40 return mclasses
41 end
42 end
43
44 redef class MClass
45
46 # Get the public owner of 'self'.
47 fun public_owner: MModule do
48 var public_owner = self.intro_mmodule.public_owner
49 if public_owner == null then
50 return self.intro_mmodule
51 else
52 return public_owner
53 end
54 end
55
56 # Get direct parents of 'self'.
57 fun parents: Set[MClass] do
58 var ret = new HashSet[MClass]
59 for mclassdef in mclassdefs do
60 for mclasstype in mclassdef.supertypes do
61 ret.add(mclasstype.mclass)
62 end
63 end
64 return ret
65 end
66
67 # Get all ancestors of 'self'.
68 fun ancestors: Set[MClass] do
69 var lst = new HashSet[MClass]
70 for mclassdef in self.mclassdefs do
71 for super_mclassdef in mclassdef.in_hierarchy.greaters do
72 if super_mclassdef == mclassdef then continue # skip self
73 lst.add(super_mclassdef.mclass)
74 end
75 end
76 return lst
77 end
78
79 # Get direct children of 'self'.
80 fun children: Set[MClass] do
81 var lst = new HashSet[MClass]
82 for mclassdef in self.mclassdefs do
83 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
84 if sub_mclassdef == mclassdef then continue # skip self
85 lst.add(sub_mclassdef.mclass)
86 end
87 end
88 return lst
89 end
90
91 # Get all children of 'self'.
92 fun descendants: Set[MClass] do
93 var lst = new HashSet[MClass]
94 for mclassdef in self.mclassdefs do
95 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
96 if sub_mclassdef == mclassdef then continue # skip self
97 lst.add(sub_mclassdef.mclass)
98 end
99 end
100 return lst
101 end
102
103 # Get the list of constructors available for 'self'.
104 fun constructors: Set[MMethod] do
105 var res = new HashSet[MMethod]
106 for mclassdef in mclassdefs do
107 for mpropdef in mclassdef.mpropdefs do
108 if mpropdef isa MMethodDef then
109 if mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
110 end
111 end
112 end
113 return res
114 end
115
116 # Get the list of methods introduced in 'self'.
117 fun intro_methods: Set[MMethod] do
118 var res = new HashSet[MMethod]
119 for mclassdef in mclassdefs do
120 for mpropdef in mclassdef.mpropdefs do
121 if mpropdef isa MMethodDef then
122 if mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
123 end
124 end
125 end
126 return res
127 end
128
129 # Get the set of properties introduced in 'self'.
130 fun intro_mproperties: Set[MProperty] do
131 var res = new HashSet[MProperty]
132 for mclassdef in mclassdefs do
133 for mpropdef in mclassdef.mpropdefs do
134 if mpropdef.is_intro then res.add(mpropdef.mproperty)
135 end
136 end
137 return res
138 end
139
140 # Get the list of locally refined methods in 'self'.
141 fun redef_methods: Set[MMethod] do
142 var res = new HashSet[MMethod]
143 for mclassdef in mclassdefs do
144 for mpropdef in mclassdef.mpropdefs do
145 if mpropdef isa MMethodDef then
146 if not mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
147 end
148 end
149 end
150 return res
151 end
152
153 # Get the set of locally refined properties in 'self'.
154 fun redef_mproperties: Set[MProperty] do
155 var res = new HashSet[MProperty]
156 for mclassdef in mclassdefs do
157 for mpropdef in mclassdef.mpropdefs do
158 if not mpropdef.is_intro then res.add(mpropdef.mproperty)
159 end
160 end
161 return res
162 end
163
164 # Get the list of methods inherited by 'self'.
165 fun inherited_methods: Set[MMethod] do
166 var res = new HashSet[MMethod]
167 for s in ancestors do
168 for m in s.intro_methods do
169 if not self.intro_methods.has(m) and not self.redef_methods.has(m) then res.add(m)
170 end
171 end
172 return res
173 end
174
175 # Get the set of all properties inherited by self
176 fun inherited_mproperties: Set[MProperty] do
177 var res = new HashSet[MProperty]
178 for s in ancestors do
179 for m in s.intro_mproperties do
180 if not self.intro_mproperties.has(m) and not self.redef_mproperties.has(m) then res.add(m)
181 end
182 end
183 return res
184 end
185
186 # Get the list of all virtual types available in 'self'.
187 fun virtual_types: Set[MVirtualTypeProp] do
188 var res = new HashSet[MVirtualTypeProp]
189 for mclassdef in mclassdefs do
190 for mpropdef in mclassdef.mpropdefs do
191 if mpropdef isa MVirtualTypeDef then
192 res.add(mpropdef.mproperty)
193 end
194 end
195 end
196 for ancestor in ancestors do
197 for mclassdef in ancestor.mclassdefs do
198 for mpropdef in mclassdef.mpropdefs do
199 if mpropdef isa MVirtualTypeDef then
200 res.add(mpropdef.mproperty)
201 end
202 end
203 end
204 end
205 return res
206 end
207
208 # Get the list of all parameter types in 'self'.
209 fun parameter_types: Map[String, MType] do
210 var res = new HashMap[String, MType]
211 for i in [0..intro.parameter_names.length[ do
212 res[intro.parameter_names[i]] = intro.bound_mtype.arguments[i]
213 end
214 return res
215 end
216
217 fun is_class: Bool do
218 return self.kind == concrete_kind or self.kind == abstract_kind
219 end
220
221 fun is_interface: Bool do
222 return self.kind == interface_kind
223 end
224
225 fun is_enum: Bool do
226 return self.kind == enum_kind
227 end
228
229 fun is_abstract: Bool do
230 return self.kind == abstract_kind
231 end
232 end