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