model: introduce `model_collect` to collect and filter things from a `Model`
[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
33
34 redef class MModule
35
36 # Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
37 fun collect_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
38 var res = new HashSet[MClassDef]
39 for mclassdef in mclassdefs do
40 if not mclassdef.is_intro then continue
41 if mclassdef.mclass.visibility < min_visibility then continue
42 res.add mclassdef
43 end
44 return res
45 end
46
47 # Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
48 fun collect_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
49 var res = new HashSet[MClassDef]
50 for mclassdef in mclassdefs do
51 if mclassdef.is_intro then continue
52 if mclassdef.mclass.visibility < min_visibility then continue
53 res.add mclassdef
54 end
55 return res
56 end
57
58 # Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
59 fun collect_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
60 var res = new HashSet[MClass]
61 for mclass in intro_mclasses do
62 if mclass.visibility < min_visibility then continue
63 res.add mclass
64 end
65 return res
66 end
67
68 # Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
69 fun collect_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
70 var mclasses = new HashSet[MClass]
71 for c in mclassdefs do
72 if c.mclass.visibility < min_visibility then continue
73 if not c.is_intro then mclasses.add(c.mclass)
74 end
75 return mclasses
76 end
77 end
78
79 redef class MClass
80
81 # Collect direct parents of `self` with `visibility >= to min_visibility`.
82 fun collect_parents(min_visibility: MVisibility): Set[MClass] do
83 var res = new HashSet[MClass]
84 for mclassdef in mclassdefs do
85 for mclasstype in mclassdef.supertypes do
86 var mclass = mclasstype.mclass
87 if mclass.visibility < min_visibility then continue
88 res.add(mclass)
89 end
90 end
91 return res
92 end
93
94 # Collect all ancestors of `self` with `visibility >= to min_visibility`.
95 fun collect_ancestors(min_visibility: MVisibility): Set[MClass] do
96 var res = new HashSet[MClass]
97 for mclassdef in self.mclassdefs do
98 for super_mclassdef in mclassdef.in_hierarchy.greaters do
99 if super_mclassdef == mclassdef then continue # skip self
100 var mclass = super_mclassdef.mclass
101 if mclass.visibility < min_visibility then continue
102 res.add(mclass)
103 end
104 end
105 return res
106 end
107
108 # Collect direct children of `self` with `visibility >= to min_visibility`.
109 fun collect_children(min_visibility: MVisibility): Set[MClass] do
110 var res = new HashSet[MClass]
111 for mclassdef in self.mclassdefs do
112 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
113 if sub_mclassdef == mclassdef then continue # skip self
114 var mclass = sub_mclassdef.mclass
115 if mclass.visibility < min_visibility then continue
116 res.add(mclass)
117 end
118 end
119 return res
120 end
121
122 # Collect all descendants of `self` with `visibility >= to min_visibility`.
123 fun descendants(min_visibility: MVisibility): Set[MClass] do
124 var res = new HashSet[MClass]
125 for mclassdef in self.mclassdefs do
126 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
127 if sub_mclassdef == mclassdef then continue # skip self
128 var mclass = sub_mclassdef.mclass
129 if mclass.visibility < min_visibility then continue
130 res.add(mclass)
131 end
132 end
133 return res
134 end
135
136 # Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
137 fun collect_intro_mproperties(min_visibility: MVisibility): Set[MProperty] do
138 var set = new HashSet[MProperty]
139 for mclassdef in mclassdefs do
140 for mprop in mclassdef.intro_mproperties do
141 if mprop.visibility < min_visibility then continue
142 set.add(mprop)
143 end
144 end
145 return set
146 end
147
148 # Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
149 fun collect_redef_mproperties(min_visibility: MVisibility): Set[MProperty] do
150 var set = new HashSet[MProperty]
151 for mclassdef in mclassdefs do
152 for mpropdef in mclassdef.mpropdefs do
153 if mpropdef.mproperty.visibility < min_visibility then continue
154 if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
155 end
156 end
157 return set
158 end
159
160 # Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
161 fun collect_local_mproperties(min_visibility: MVisibility): Set[MProperty] do
162 var set = new HashSet[MProperty]
163 set.add_all collect_intro_mproperties(min_visibility)
164 set.add_all collect_redef_mproperties(min_visibility)
165 return set
166 end
167
168 # Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
169 fun collect_inherited_mproperties(min_visibility: MVisibility): Set[MProperty] do
170 var set = new HashSet[MProperty]
171 for parent in collect_parents(min_visibility) do
172 set.add_all(parent.collect_intro_mproperties(min_visibility))
173 set.add_all(parent.collect_inherited_mproperties(min_visibility))
174 end
175 return set
176 end
177
178 # Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
179 #
180 # This include introduced, redefined, inherited mproperties.
181 fun collect_accessible_mproperties(min_visibility: MVisibility): Set[MProperty] do
182 var set = new HashSet[MProperty]
183 set.add_all(collect_intro_mproperties(min_visibility))
184 set.add_all(collect_redef_mproperties(min_visibility))
185 set.add_all(collect_inherited_mproperties(min_visibility))
186 return set
187 end
188
189 # Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
190 fun collect_intro_mmethods(min_visibility: MVisibility): Set[MMethod] do
191 var res = new HashSet[MMethod]
192 for mproperty in collect_intro_mproperties(min_visibility) do
193 if mproperty isa MMethod then res.add(mproperty)
194 end
195 return res
196 end
197
198 # Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
199 fun collect_redef_mmethods(min_visibility: MVisibility): Set[MMethod] do
200 var res = new HashSet[MMethod]
201 for mproperty in collect_redef_mproperties(min_visibility) do
202 if mproperty isa MMethod then res.add(mproperty)
203 end
204 return res
205 end
206
207 # Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
208 fun collect_local_mmethods(min_visibility: MVisibility): Set[MMethod] do
209 var set = new HashSet[MMethod]
210 set.add_all collect_intro_mmethods(min_visibility)
211 set.add_all collect_redef_mmethods(min_visibility)
212 return set
213 end
214
215 # Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
216 fun collect_intro_mattributes(min_visibility: MVisibility): Set[MAttribute] do
217 var res = new HashSet[MAttribute]
218 for mproperty in collect_intro_mproperties(min_visibility) do
219 if mproperty isa MAttribute then res.add(mproperty)
220 end
221 return res
222 end
223
224 # Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
225 fun collect_redef_mattributes(min_visibility: MVisibility): Set[MAttribute] do
226 var res = new HashSet[MAttribute]
227 for mproperty in collect_redef_mproperties(min_visibility) do
228 if mproperty isa MAttribute then res.add(mproperty)
229 end
230 return res
231 end
232
233 # Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
234 fun collect_local_mattributes(min_visibility: MVisibility): Set[MAttribute] do
235 var set = new HashSet[MAttribute]
236 set.add_all collect_intro_mattributes(min_visibility)
237 set.add_all collect_redef_mattributes(min_visibility)
238 return set
239 end
240
241 # Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
242 fun collect_inherited_mattributes(min_visibility: MVisibility): Set[MAttribute] do
243 var res = new HashSet[MAttribute]
244 for mproperty in collect_inherited_mproperties(min_visibility) do
245 if mproperty isa MAttribute then res.add(mproperty)
246 end
247 return res
248 end
249
250 # Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
251 #
252 # This include introduced, redefined, inherited mattributes.
253 fun collect_accessible_mattributes(min_visibility: MVisibility): Set[MAttribute] do
254 var set = new HashSet[MAttribute]
255 set.add_all(collect_intro_mattributes(min_visibility))
256 set.add_all(collect_redef_mattributes(min_visibility))
257 set.add_all(collect_inherited_mattributes(min_visibility))
258 return set
259 end
260 end
261
262 redef class MClassDef
263 # Collect mpropdefs in 'self' with `visibility >= min_visibility`.
264 fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
265 var res = new HashSet[MPropDef]
266 for mpropdef in mpropdefs do
267 if mpropdef.mproperty.visibility < min_visibility then continue
268 res.add mpropdef
269 end
270 return res
271 end
272
273 # Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
274 fun collect_intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
275 var res = new HashSet[MPropDef]
276 for mpropdef in mpropdefs do
277 if not mpropdef.is_intro then continue
278 if mpropdef.mproperty.visibility < min_visibility then continue
279 res.add mpropdef
280 end
281 return res
282 end
283
284 # Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
285 fun collect_redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
286 var res = new HashSet[MPropDef]
287 for mpropdef in mpropdefs do
288 if mpropdef.is_intro then continue
289 if mpropdef.mproperty.visibility < min_visibility then continue
290 res.add mpropdef
291 end
292 return res
293 end
294
295 # Collect modifiers like redef, private etc.
296 fun collect_modifiers: Array[String] do
297 var res = new Array[String]
298 if not is_intro then
299 res.add "redef"
300 else
301 res.add mclass.visibility.to_s
302 end
303 res.add mclass.kind.to_s
304 return res
305 end
306 end
307
308 redef class MPropDef
309 # Collect modifiers like redef, private, abstract, intern, fun etc.
310 fun collect_modifiers: Array[String] do
311 var res = new Array[String]
312 if not is_intro then
313 res.add "redef"
314 else
315 res.add mproperty.visibility.to_s
316 end
317 var mprop = self
318 if mprop isa MVirtualTypeDef then
319 res.add "type"
320 else if mprop isa MMethodDef then
321 if mprop.is_abstract then
322 res.add "abstract"
323 else if mprop.is_intern then
324 res.add "intern"
325 end
326 if mprop.mproperty.is_init then
327 res.add "init"
328 else
329 res.add "fun"
330 end
331 end
332 return res
333 end
334 end