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