model_collect: collect MClass inits
[nit.git] / src / model / model_collect.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 # Collect things from a `Model`.
18 #
19 # **Warning**
20 #
21 # `model_collect` offers a flattened view of the model without considering any
22 # main module.
23 # For this reason, `model_collect` lists all the definitions reachable from all
24 # modules
25 #
26 # This is usefull for tools that need a global view of a model like `nitdoc`,
27 # `nitx` or `nituml`.
28 # It shoul not be used for compiling stuffs like computing VFT, where the listed
29 # entities could not be reachable depending on the modules really imported.
30 module model_collect
31
32 import model_views
33
34 redef class MModule
35
36 # Collect all transitive imports.
37 fun collect_ancestors(view: ModelView): Set[MModule] do
38 var res = new HashSet[MModule]
39 for mentity in in_importation.greaters do
40 if mentity == self then continue
41 if not view.accept_mentity(mentity) then continue
42 res.add mentity
43 end
44 return res
45 end
46
47 # Collect direct imports.
48 fun collect_parents(view: ModelView): Set[MModule] do
49 var res = new HashSet[MModule]
50 for mentity in in_importation.direct_greaters do
51 if mentity == self then continue
52 if not view.accept_mentity(mentity) then continue
53 res.add mentity
54 end
55 return res
56 end
57
58 # Collect direct children (modules that directly import `self`).
59 fun collect_children(view: ModelView): Set[MModule] do
60 var res = new HashSet[MModule]
61 for mentity in in_importation.direct_smallers do
62 if mentity == self then continue
63 if not view.accept_mentity(mentity) then continue
64 res.add mentity
65 end
66 return res
67 end
68
69 # Collect all transitive children.
70 fun collect_descendants(view: ModelView): Set[MModule] do
71 var res = new HashSet[MModule]
72 for mentity in in_importation.smallers do
73 if mentity == self then continue
74 if not view.accept_mentity(mentity) then continue
75 res.add mentity
76 end
77 return res
78 end
79
80 # Build the importation poset for `self`
81 fun importation_poset(view: ModelView): POSet[MModule] do
82 var mmodules = new HashSet[MModule]
83 mmodules.add self
84 mmodules.add_all collect_ancestors(view)
85 mmodules.add_all collect_parents(view)
86 mmodules.add_all collect_children(view)
87 mmodules.add_all collect_descendants(view)
88 return view.mmodules_poset(mmodules)
89 end
90
91 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
92 fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
93 var res = new HashSet[MClassDef]
94 for mclassdef in mclassdefs do
95 if not mclassdef.is_intro then continue
96 if not view.accept_mentity(mclassdef) then continue
97 res.add mclassdef
98 end
99 return res
100 end
101
102 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
103 fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
104 var res = new HashSet[MClassDef]
105 for mclassdef in mclassdefs do
106 if mclassdef.is_intro then continue
107 if not view.accept_mentity(mclassdef) then continue
108 res.add mclassdef
109 end
110 return res
111 end
112
113 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
114 fun collect_intro_mclasses(view: ModelView): Set[MClass] do
115 var res = new HashSet[MClass]
116 for mclass in intro_mclasses do
117 if not view.accept_mentity(mclass) then continue
118 res.add mclass
119 end
120 return res
121 end
122
123 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
124 fun collect_redef_mclasses(view: ModelView): Set[MClass] do
125 var mclasses = new HashSet[MClass]
126 for mclassdef in mclassdefs do
127 if not view.accept_mentity(mclassdef) then continue
128 if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
129 end
130 return mclasses
131 end
132 end
133
134 redef class MClass
135
136 # Collect direct parents of `self` with `visibility >= to min_visibility`.
137 fun collect_parents(view: ModelView): Set[MClass] do
138 var res = new HashSet[MClass]
139 for mclassdef in mclassdefs do
140 for mclasstype in mclassdef.supertypes do
141 var mclass = mclasstype.mclass
142 if not view.accept_mentity(mclass) then continue
143 res.add(mclass)
144 end
145 end
146 return res
147 end
148
149 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
150 fun collect_ancestors(view: ModelView): Set[MClass] do
151 var res = new HashSet[MClass]
152 for mclassdef in self.mclassdefs do
153 for super_mclassdef in mclassdef.in_hierarchy.greaters do
154 if super_mclassdef == mclassdef then continue # skip self
155 var mclass = super_mclassdef.mclass
156 if not view.accept_mentity(mclass) then continue
157 res.add(mclass)
158 end
159 end
160 return res
161 end
162
163 # Collect direct children of `self` with `visibility >= to min_visibility`.
164 fun collect_children(view: ModelView): Set[MClass] do
165 var res = new HashSet[MClass]
166 for mclassdef in self.mclassdefs do
167 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
168 if sub_mclassdef == mclassdef then continue # skip self
169 var mclass = sub_mclassdef.mclass
170 if not view.accept_mentity(mclass) then continue
171 res.add(mclass)
172 end
173 end
174 return res
175 end
176
177 # Collect all descendants of `self` with `visibility >= to min_visibility`.
178 fun collect_descendants(view: ModelView): Set[MClass] do
179 var res = new HashSet[MClass]
180 for mclassdef in self.mclassdefs do
181 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
182 if sub_mclassdef == mclassdef then continue # skip self
183 var mclass = sub_mclassdef.mclass
184 if not view.accept_mentity(mclass) then continue
185 res.add(mclass)
186 end
187 end
188 return res
189 end
190
191 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
192 fun collect_intro_mproperties(view: ModelView): 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 not view.accept_mentity(mprop) then continue
197 set.add(mprop)
198 end
199 end
200 return set
201 end
202
203 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
204 fun collect_redef_mproperties(view: ModelView): 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.intro_mclassdef.mclass == self then continue
209 if not view.accept_mentity(mpropdef) then continue
210 set.add(mpropdef.mproperty)
211 end
212 end
213 return set
214 end
215
216 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
217 fun collect_local_mproperties(view: ModelView): Set[MProperty] do
218 var set = new HashSet[MProperty]
219 set.add_all collect_intro_mproperties(view)
220 set.add_all collect_redef_mproperties(view)
221 return set
222 end
223
224 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
225 fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
226 var set = new HashSet[MProperty]
227 for parent in collect_parents(view) do
228 set.add_all(parent.collect_intro_mproperties(view))
229 set.add_all(parent.collect_inherited_mproperties(view))
230 end
231 return set
232 end
233
234 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
235 #
236 # This include introduced, redefined, inherited mproperties.
237 fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
238 var set = new HashSet[MProperty]
239 set.add_all(collect_intro_mproperties(view))
240 set.add_all(collect_redef_mproperties(view))
241 set.add_all(collect_inherited_mproperties(view))
242 return set
243 end
244
245 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
246 fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
247 var res = new HashSet[MMethod]
248 for mproperty in collect_intro_mproperties(view) do
249 if mproperty isa MMethod then res.add(mproperty)
250 end
251 return res
252 end
253
254 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
255 fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
256 var res = new HashSet[MMethod]
257 for mproperty in collect_redef_mproperties(view) do
258 if mproperty isa MMethod then res.add(mproperty)
259 end
260 return res
261 end
262
263 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
264 fun collect_local_mmethods(view: ModelView): Set[MMethod] do
265 var set = new HashSet[MMethod]
266 set.add_all collect_intro_mmethods(view)
267 set.add_all collect_redef_mmethods(view)
268 return set
269 end
270
271 # Collect mmethods inherited by 'self' if accepted by `view`.
272 fun collect_inherited_mmethods(view: ModelView): Set[MMethod] do
273 var res = new HashSet[MMethod]
274 for mproperty in collect_inherited_mproperties(view) do
275 if mproperty isa MMethod then res.add(mproperty)
276 end
277 return res
278 end
279
280 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
281 fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
282 var res = new HashSet[MAttribute]
283 for mproperty in collect_intro_mproperties(view) do
284 if mproperty isa MAttribute then res.add(mproperty)
285 end
286 return res
287 end
288
289 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
290 fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
291 var res = new HashSet[MAttribute]
292 for mproperty in collect_redef_mproperties(view) do
293 if mproperty isa MAttribute then res.add(mproperty)
294 end
295 return res
296 end
297
298 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
299 fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
300 var set = new HashSet[MAttribute]
301 set.add_all collect_intro_mattributes(view)
302 set.add_all collect_redef_mattributes(view)
303 return set
304 end
305
306 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
307 fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
308 var res = new HashSet[MAttribute]
309 for mproperty in collect_inherited_mproperties(view) do
310 if mproperty isa MAttribute then res.add(mproperty)
311 end
312 return res
313 end
314
315 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
316 #
317 # This include introduced, redefined, inherited mattributes.
318 fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
319 var set = new HashSet[MAttribute]
320 set.add_all(collect_intro_mattributes(view))
321 set.add_all(collect_redef_mattributes(view))
322 set.add_all(collect_inherited_mattributes(view))
323 return set
324 end
325
326 # Collect init mmethods introduced in 'self' if accepted by `view`.
327 fun collect_intro_inits(view: ModelView): Set[MMethod] do
328 var res = new HashSet[MMethod]
329 for mproperty in collect_intro_mmethods(view) do
330 if mproperty.is_init then res.add(mproperty)
331 end
332 return res
333 end
334
335 # Collect init mmethods redefined in 'self' if accepted by `view`.
336 fun collect_redef_inits(view: ModelView): Set[MMethod] do
337 var res = new HashSet[MMethod]
338 for mproperty in collect_redef_mmethods(view) do
339 if mproperty.is_init then res.add(mproperty)
340 end
341 return res
342 end
343
344 # Collect init mmethods introduced and redefined in 'self' if accepted by `view`.
345 fun collect_local_inits(view: ModelView): Set[MMethod] do
346 var set = new HashSet[MMethod]
347 set.add_all collect_intro_inits(view)
348 set.add_all collect_redef_inits(view)
349 return set
350 end
351
352 # Collect init mmethods inherited by 'self' if accepted by `view`.
353 fun collect_inherited_inits(view: ModelView): Set[MMethod] do
354 var res = new HashSet[MMethod]
355 for mproperty in collect_inherited_mmethods(view) do
356 if mproperty.is_init then res.add(mproperty)
357 end
358 return res
359 end
360
361 # Collect all init mmethods accessible by 'self' if accepted by `view`.
362 #
363 # This include introduced, redefined, inherited inits.
364 fun collect_accessible_inits(view: ModelView): Set[MMethod] do
365 var set = new HashSet[MMethod]
366 set.add_all(collect_intro_inits(view))
367 set.add_all(collect_redef_inits(view))
368 set.add_all(collect_inherited_inits(view))
369 return set
370 end
371 end
372
373 redef class MClassDef
374
375 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
376 fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
377 var res = new HashSet[MPropDef]
378 for mpropdef in mpropdefs do
379 if not view.accept_mentity(mpropdef) then continue
380 res.add mpropdef
381 end
382 return res
383 end
384
385 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
386 fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
387 var res = new HashSet[MPropDef]
388 for mpropdef in mpropdefs do
389 if not mpropdef.is_intro then continue
390 if not view.accept_mentity(mpropdef) then continue
391 res.add mpropdef
392 end
393 return res
394 end
395
396 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
397 fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
398 var res = new HashSet[MPropDef]
399 for mpropdef in mpropdefs do
400 if mpropdef.is_intro then continue
401 if not view.accept_mentity(mpropdef) then continue
402 res.add mpropdef
403 end
404 return res
405 end
406
407 # Collect modifiers like redef, private etc.
408 fun collect_modifiers: Array[String] do
409 var res = new Array[String]
410 if not is_intro then
411 res.add "redef"
412 else
413 res.add mclass.visibility.to_s
414 end
415 res.add mclass.kind.to_s
416 return res
417 end
418 end
419
420 redef class MPropDef
421 # Collect modifiers like redef, private, abstract, intern, fun etc.
422 fun collect_modifiers: Array[String] do
423 var res = new Array[String]
424 if not is_intro then
425 res.add "redef"
426 else
427 res.add mproperty.visibility.to_s
428 end
429 var mprop = self
430 if mprop isa MVirtualTypeDef then
431 res.add "type"
432 else if mprop isa MMethodDef then
433 if mprop.is_abstract then
434 res.add "abstract"
435 else if mprop.is_intern then
436 res.add "intern"
437 end
438 if mprop.mproperty.is_init then
439 res.add "init"
440 else
441 res.add "fun"
442 end
443 end
444 return res
445 end
446 end