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