start removing implicit properties
[nit.git] / src / metamodel / static_type.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 # Static types and property signatures
19 package static_type
20
21 intrude import abstractmetamodel
22
23 redef class MMLocalClass
24 # Cached result of get_type
25 attr _base_type_cache: MMType
26
27 # Return the type of self for this class
28 meth get_type: MMType
29 do
30 if _base_type_cache == null then _base_type_cache = new MMTypeSimpleClass(self)
31 return _base_type_cache
32 end
33
34 # Register a new ancestor
35 protected meth add_ancestor(a: MMAncestor)
36 do
37 assert not _ancestors.has_key(a.local_class)
38 assert a.local_class != self
39 _ancestors[a.local_class] = a
40 end
41
42 # Array of ancestor that associate each superclass with the corresponding ancestor
43 readable attr _ancestors: Map[MMLocalClass, MMAncestor]
44
45 # The ancestor type for a given superclass
46 meth ancestor(c: MMLocalClass): MMType
47 do
48 assert _ancestors != null
49 if _ancestors.has_key(c) then
50 return _ancestors[c].stype
51 end
52 return null
53 end
54 end
55
56 redef class MMLocalProperty
57 # The signature of the property (where it is declared)
58 readable writable attr _signature: MMSignature
59
60 # Return the adapted signature of self for a receiver of type t
61 meth signature_for(t: MMType): MMSignature do
62 var x = self
63 assert x isa MMConcreteProperty
64 return x.signature.adaptation_to(t)
65 end
66 end
67
68 # Signature for local properties
69 class MMSignature
70 # The type of the reveiver
71 readable attr _recv: MMType
72
73 # The parameter types
74 attr _params: Array[MMType]
75
76 # The return type
77 readable attr _return_type: MMType
78
79 # Number of parameters
80 meth arity: Int
81 do
82 assert _params != null
83 return _params.length
84 end
85
86 # Is self a valid subtype of an other signature
87 meth <(s: MMSignature): Bool
88 do
89 assert s != null
90 if self == s then
91 return true
92 end
93 assert _recv.module == s.recv.module
94 assert arity == s.arity
95 assert (_return_type == null) == (s.return_type == null)
96 if _return_type != null and not _return_type < s.return_type then
97 return false
98 end
99
100 for i in [0..arity[ do
101 if not s[i] < self[i] then
102 return false
103 end
104 end
105 return true
106 end
107
108 # The type of the i-th parameter
109 meth [](i: Int): MMType
110 do
111 assert _params.length > i
112 return _params[i]
113 end
114
115 redef meth to_s
116 do
117 var s: String
118 if _params != null and _params.length > 0 then
119 var tmp: String
120 var a = new Array[String].with_capacity(_params.length)
121 for i in [0.._params.length[ do
122 #var pn = _params_name[i]
123 var p = _params[i]
124 #a.add("{pn}: {p}")
125 a.add(p.to_s)
126 end
127 s = "({a.join(",")})"
128 else
129 s = ""
130 end
131 if _return_type != null then
132 s.append(": {_return_type}")
133 end
134 return s
135 end
136
137 # Adapt the signature to a different receiver
138 meth adaptation_to(r: MMType): MMSignature
139 do
140 if _recv == r then
141 return self
142 end
143 var mod = r.module
144 var p = _params
145 if p != null then
146 p = new Array[MMType]
147 for i in _params do
148 p.add(i.for_module(mod).adapt_to(r))
149 end
150 end
151 var rv = _return_type
152 if rv != null then
153 rv = rv.for_module(mod).adapt_to(r)
154 end
155 return new MMSignature(p,rv,r)
156 end
157
158 init(params: Array[MMType], return_type: MMType, r: MMType)
159 do
160 assert params != null
161 _params = params
162 _return_type = return_type
163 _recv = r
164 end
165 end
166
167 # Inheritance relation between two types
168 abstract class MMAncestor
169 # The inherited type
170 readable writable attr _stype: MMType
171
172 # The inheriter (heir) type
173 readable writable attr _inheriter: MMType
174
175 meth is_reffinement: Bool do
176 return stype.module != stype.module
177 end
178
179 meth is_specialisation: Bool do
180 return stype.local_class.global != inheriter.local_class.global
181 end
182
183 # The inherited class
184 meth local_class: MMLocalClass is abstract
185
186 redef meth to_s
187 do
188 if stype == null then
189 return local_class.to_s
190 else
191 return stype.to_s
192 end
193 end
194 end
195
196 # A static type
197 # Note that static type a related to a specific module
198 abstract class MMType
199 # The module where self makes sence
200 meth module: MMModule is abstract
201
202 # The local class that self direclty or indirectly refers to
203 meth local_class: MMLocalClass is abstract
204
205 # Is self a valid subtype of t
206 meth <(t : MMType): Bool is abstract
207
208 # Is self a valid supertype of t
209 # This method must be only called within definition of < if
210 # a double dispatch is needed
211 meth is_supertype(t: MMType): Bool is abstract
212
213 # Select a method from its name
214 meth select_method(name: Symbol): MMMethod
215 do
216 assert local_class != null
217 assert name != null
218 var res = select_property(local_class.method(name))
219 assert res isa MMMethod
220 return res
221 end
222
223 # Select an attribute from its name
224 meth select_attribute(name: Symbol): MMAttribute
225 do
226 assert name != null
227 assert local_class != null
228 var res = select_property(local_class.attribute(name))
229 assert res isa MMAttribute
230 return res
231 end
232
233 # Select a local property from its global property
234 meth select_property(t: MMGlobalProperty): MMLocalProperty is abstract
235
236 # Adapt self to another module
237 meth for_module(mod: MMModule): MMType is abstract
238
239 # Get the type adapted to another receiver type
240 # Useful for formal types
241 meth adapt_to(recv: MMType): MMType is abstract
242
243 # Adapt self to another local class context
244 # Useful for genericity
245 meth upcast_for(c: MMLocalClass): MMType is abstract
246
247 # Return a type approximation if the reveiver is not self
248 # Useful for virtual types
249 meth not_for_self: MMType do return self
250 end
251
252 class MMTypeClass
253 special MMType
254 redef readable attr _local_class: MMLocalClass
255 redef meth module do return _local_class.module end
256 redef meth <(t) do return t != null and t.is_supertype(self)
257
258 redef meth to_s
259 do
260 return _local_class.to_s
261 end
262
263 redef meth upcast_for(c)
264 do
265 assert _local_class != null
266 assert c != null
267
268 var t: MMType = self
269 if _local_class != c then
270 t = _local_class.ancestor(c)
271 end
272 assert t != null
273 return t
274 end
275
276 init(c : MMLocalClass)
277 do
278 _local_class = c
279 end
280 end
281
282 class MMTypeSimpleClass
283 special MMTypeClass
284 redef meth is_supertype(t)
285 do
286 return t.local_class.cshe <= _local_class
287 end
288
289 redef meth select_property(g)
290 do
291 assert _local_class != null
292 if g == null then
293 return null
294 end
295 return _local_class[g]
296 end
297
298 redef meth for_module(mod)
299 do
300 var t: MMType = self
301 if module != mod then
302 t = _local_class.for_module(mod).get_type
303 end
304 assert t != null
305 return t
306 end
307
308 redef meth adapt_to(recv) do return self
309
310 redef init(c: MMLocalClass)
311 do
312 super(c)
313 end
314 end
315
316 # The type of null
317 class MMTypeNone
318 special MMType
319 redef readable attr _module: MMModule
320 redef meth <(t) do return true
321 redef meth is_supertype(t) do return false
322 redef meth local_class do abort
323 redef meth upcast_for(c) do return self
324
325 private init(m: MMModule) do _module = m
326 end
327
328 redef class MMModule
329 # The type of null
330 readable attr _type_none: MMTypeNone = new MMTypeNone(self)
331 end