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