model_utils: add mclass children accessors
[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 end
43
44 redef class MClass
45
46 # Get direct parents of 'self'.
47 fun parents: Set[MClass] do
48 var ret = new HashSet[MClass]
49 for mclassdef in mclassdefs do
50 for mclasstype in mclassdef.supertypes do
51 ret.add(mclasstype.mclass)
52 end
53 end
54 return ret
55 end
56
57 # Get all ancestors of 'self'.
58 fun ancestors: Set[MClass] do
59 var lst = new HashSet[MClass]
60 for mclassdef in self.mclassdefs do
61 for super_mclassdef in mclassdef.in_hierarchy.greaters do
62 if super_mclassdef == mclassdef then continue # skip self
63 lst.add(super_mclassdef.mclass)
64 end
65 end
66 return lst
67 end
68
69 # Get direct children of 'self'.
70 fun children: Set[MClass] do
71 var lst = new HashSet[MClass]
72 for mclassdef in self.mclassdefs do
73 for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
74 if sub_mclassdef == mclassdef then continue # skip self
75 lst.add(sub_mclassdef.mclass)
76 end
77 end
78 return lst
79 end
80
81 # Get all children of 'self'.
82 fun descendants: Set[MClass] do
83 var lst = new HashSet[MClass]
84 for mclassdef in self.mclassdefs do
85 for sub_mclassdef in mclassdef.in_hierarchy.smallers do
86 if sub_mclassdef == mclassdef then continue # skip self
87 lst.add(sub_mclassdef.mclass)
88 end
89 end
90 return lst
91 end
92
93 # Get the list of constructors available for 'self'.
94 fun constructors: Set[MMethod] do
95 var res = new HashSet[MMethod]
96 for mclassdef in mclassdefs do
97 for mpropdef in mclassdef.mpropdefs do
98 if mpropdef isa MMethodDef then
99 if mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
100 end
101 end
102 end
103 return res
104 end
105
106 # Get the list of methods introduced in 'self'.
107 fun intro_methods: Set[MMethod] do
108 var res = new HashSet[MMethod]
109 for mclassdef in mclassdefs do
110 for mpropdef in mclassdef.mpropdefs do
111 if mpropdef isa MMethodDef then
112 if mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
113 end
114 end
115 end
116 return res
117 end
118
119 # Get the list of locally refined methods in 'self'.
120 fun redef_methods: Set[MMethod] do
121 var res = new HashSet[MMethod]
122 for mclassdef in mclassdefs do
123 for mpropdef in mclassdef.mpropdefs do
124 if mpropdef isa MMethodDef then
125 if not mpropdef.is_intro and not mpropdef.mproperty.is_init then res.add(mpropdef.mproperty)
126 end
127 end
128 end
129 return res
130 end
131
132 # Get the list of methods inherited by 'self'.
133 fun inherited_methods: Set[MMethod] do
134 var res = new HashSet[MMethod]
135 for s in ancestors do
136 for m in s.intro_methods do
137 if not self.intro_methods.has(m) and not self.redef_methods.has(m) then res.add(m)
138 end
139 end
140 return res
141 end
142
143 # Get the list of all virtual types available in 'self'.
144 fun virtual_types: Set[MVirtualTypeProp] do
145 var res = new HashSet[MVirtualTypeProp]
146 for mclassdef in mclassdefs do
147 for mpropdef in mclassdef.mpropdefs do
148 if mpropdef isa MVirtualTypeDef then
149 res.add(mpropdef.mproperty)
150 end
151 end
152 end
153 for ancestor in ancestors do
154 for mclassdef in ancestor.mclassdefs do
155 for mpropdef in mclassdef.mpropdefs do
156 if mpropdef isa MVirtualTypeDef then
157 res.add(mpropdef.mproperty)
158 end
159 end
160 end
161 end
162 return res
163 end
164
165 # Get the list of all parameter types in 'self'.
166 fun parameter_types: Map[String, MType] do
167 var res = new HashMap[String, MType]
168 for i in [0..intro.parameter_names.length[ do
169 res[intro.parameter_names[i]] = intro.bound_mtype.arguments[i]
170 end
171 return res
172 end
173
174 fun is_class: Bool do
175 return self.kind == concrete_kind or self.kind == abstract_kind
176 end
177
178 fun is_interface: Bool do
179 return self.kind == interface_kind
180 end
181
182 fun is_enum: Bool do
183 return self.kind == enum_kind
184 end
185
186 fun is_abstract: Bool do
187 return self.kind == abstract_kind
188 end
189 end