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