syntax: 'meth' -> 'fun', 'attr' -> 'var'
[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 var _base_type_cache: nullable MMType
26
27 # Return the type of self for this class
28 fun get_type: MMType
29 do
30 if _base_type_cache == null then _base_type_cache = new MMTypeSimpleClass(self)
31 return _base_type_cache.as(not null)
32 end
33
34 # Register a new ancestor
35 protected fun 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 var _ancestors: nullable Map[MMLocalClass, MMAncestor]
44
45 # The ancestor type for a given superclass
46 fun ancestor(c: MMLocalClass): MMType
47 do
48 return _ancestors[c].stype
49 end
50 end
51
52 redef class MMLocalProperty
53 # The signature of the property (where it is declared)
54 readable writable var _signature: nullable MMSignature
55
56 var _signatures_cache: HashMap[MMType, MMSignature] = new HashMap[MMType, MMSignature]
57
58 # Return the adapted signature of self for a receiver of type t
59 fun signature_for(t: MMType): MMSignature do
60 if t == local_class.get_type then return signature.as(not null)
61
62 if _signatures_cache.has_key(t) then return _signatures_cache[t]
63
64 var res = signature.adaptation_to(t)
65 _signatures_cache[t] = res
66 return res
67 end
68 end
69
70 # Signature for local properties
71 class MMSignature
72 # The type of the reveiver
73 readable var _recv: MMType
74
75 # The parameter types
76 var _params: Array[MMType]
77
78 # The return type
79 readable var _return_type: nullable MMType
80
81 # The closure parameters
82 readable var _closures: Array[MMClosure] = new Array[MMClosure]
83
84 # Number of parameters
85 fun arity: Int
86 do
87 return _params.length
88 end
89
90 # Is self a valid subtype of an other signature
91 fun <(s: MMSignature): Bool
92 do
93 if self == s then
94 return true
95 end
96 assert _recv.module == s.recv.module
97 var rt = _return_type
98 var srt = s.return_type
99 if arity != s.arity or (rt == null) != (srt == null) then return false
100 if rt != null and not rt < srt.as(not null) then
101 return false
102 end
103
104 for i in [0..arity[ do
105 if not s[i] < self[i] then
106 return false
107 end
108 end
109
110 if closures.length != s.closures.length then return false
111 for i in [0..closures.length[ do
112 if not s.closures[i] < closures[i] then return false
113 end
114 return true
115 end
116
117 # The type of the i-th parameter
118 fun [](i: Int): MMType
119 do
120 assert _params.length > i
121 return _params[i]
122 end
123
124 redef fun to_s
125 do
126 var s = new Buffer
127 if _params.length > 0 then
128 var tmp: String
129 var a = new Array[String].with_capacity(_params.length)
130 for i in [0.._params.length[ do
131 #var pn = _params_name[i]
132 var p = _params[i]
133 #a.add("{pn}: {p}")
134 a.add(p.to_s)
135 end
136 s.append("({a.join(",")})")
137 end
138 if _return_type != null then
139 s.append(": {_return_type}")
140 end
141 return s.to_s
142 end
143
144 # Adapt the signature to a different receiver
145 fun adaptation_to(r: MMType): MMSignature
146 do
147 if _recv == r then
148 return self
149 end
150 var mod = r.module
151 var p = new Array[MMType]
152 for i in _params do
153 p.add(i.for_module(mod).adapt_to(r))
154 end
155 var rv = _return_type
156 if rv != null then
157 rv = rv.for_module(mod).adapt_to(r)
158 end
159 var res = new MMSignature(p,rv,r)
160 for clos in _closures do
161 res.closures.add(clos.adaptation_to(r))
162 end
163 return res
164 end
165
166 var _not_for_self_cache: nullable MMSignature = null
167
168 # Return a type approximation if the reveiver is not self
169 # Useful for virtual types
170 fun not_for_self: MMSignature
171 do
172 if _not_for_self_cache != null then return _not_for_self_cache.as(not null)
173
174 var need_for_self = false
175 var p = new Array[MMType]
176 for i in _params do
177 var i2 = i.not_for_self
178 if i != i2 then need_for_self = true
179 p.add(i2)
180 end
181
182 var rv = _return_type
183 if rv != null then
184 rv = rv.not_for_self
185 if rv != _return_type then need_for_self = true
186 end
187
188 var clos = new Array[MMClosure]
189 for c in _closures do
190 var c2 = c.not_for_self
191 if c2 != c then need_for_self = true
192 clos.add(c2)
193 end
194
195 var res: MMSignature
196 if need_for_self then
197 res = new MMSignature(p, rv, _recv)
198 res.closures.add_all(clos)
199 else
200 res = self
201 end
202
203 _not_for_self_cache = res
204 return res
205 end
206
207 init(params: Array[MMType], return_type: nullable MMType, r: MMType)
208 do
209 _params = params
210 _return_type = return_type
211 _recv = r
212 end
213 end
214
215 # A closure in a signature
216 class MMClosure
217 # The signature of the closure
218 readable var _signature: MMSignature
219
220 # Is the closure a brek one
221 # aka is defined with the break keyword thus does not return
222 readable var _is_break: Bool
223
224 # Is the closure optional?
225 # ie is there a default definition
226 readable var _is_optional: Bool
227
228 # Adapt the signature to a different receiver
229 fun adaptation_to(r: MMType): MMClosure
230 do
231 return new MMClosure(_signature.adaptation_to(r), _is_break, _is_optional)
232 end
233
234 init(s: MMSignature, is_break: Bool, is_optional: Bool)
235 do
236 _signature = s
237 _is_break = is_break
238 _is_optional = is_optional
239 end
240
241 fun not_for_self: MMClosure
242 do
243 var sig = _signature.not_for_self
244 if sig != _signature then
245 return new MMClosure(sig, _is_break, _is_optional)
246 else
247 return self
248 end
249 end
250
251 fun <(c: MMClosure): Bool
252 do
253 if c.is_optional and not is_optional then return false
254 if not c.is_break and is_break then return false
255 return c.signature < signature
256 end
257 end
258
259 # Inheritance relation between two types
260 abstract class MMAncestor
261 # The inherited type
262 writable var _stype: nullable MMType = null
263
264 # The inherited type
265 fun stype: MMType do return _stype.as(not null)
266
267 # The inheriter (heir) type
268 writable var _inheriter: nullable MMType = null
269
270 # The inheriter (heir) type
271 fun inheriter: MMType do return _inheriter.as(not null)
272
273 fun is_reffinement: Bool do
274 return stype.module != stype.module
275 end
276
277 fun is_specialisation: Bool do
278 return stype.local_class.global != inheriter.local_class.global
279 end
280
281 # The inherited class
282 fun local_class: MMLocalClass is abstract
283
284 redef fun to_s
285 do
286 if _stype == null then
287 return local_class.to_s
288 else
289 return stype.to_s
290 end
291 end
292 end
293
294 # A static type
295 # Note that static type a related to a specific module
296 abstract class MMType
297 # The module where self makes sence
298 fun module: MMModule is abstract
299
300 # The local class that self direclty or indirectly refers to
301 fun local_class: MMLocalClass is abstract
302
303 # Is the type a valid one
304 # For instance, circular dependency on formal types is invalid
305 fun is_valid: Bool do return true
306
307 # Is self a valid subtype of t
308 fun <(t : MMType): Bool is abstract
309
310 # Is self a valid supertype of t
311 # This method must be only called within definition of < if
312 # a double dispatch is needed
313 fun is_supertype(t: MMType): Bool is abstract
314
315 # Adapt self to another module
316 fun for_module(mod: MMModule): MMType is abstract
317
318 # Get the type adapted to another receiver type
319 # Useful for formal types
320 fun adapt_to(recv: MMType): MMType is abstract
321
322 # Adapt self to another local class context
323 # Useful for genericity
324 # 'c' Must be a super-class of self
325 # Example:
326 # class A[E]
327 # class B[F] special A[F]
328 # class C[G] special B[String]
329 # class D special C[Float]
330 # 'A[Int]'.upcast_for('A') -> 'A[Int]'
331 # 'A[Int]'.upcast_for('B') -> abort
332 # 'B[Int]'.upcast_for('B') -> 'B[Int]'
333 # 'B[Int]'.upcast_for('A') -> 'A[Int]'
334 # 'B[Int]'.upcast_for('C') -> abort
335 # 'C[Int]'.upcast_for('C') -> 'C[Int]'
336 # 'C[Int]'.upcast_for('B') -> 'B[String]'
337 # 'C[Int]'.upcast_for('A') -> 'A[String]'
338 # 'D'.upcast_for('D') -> 'D'
339 # 'D'.upcast_for('C') -> 'C[Float]'
340 # 'D'.upcast_for('B') -> 'C[String]'
341 # 'D'.upcast_for('A') -> 'A[String]'
342 fun upcast_for(c: MMLocalClass): MMType is abstract
343
344 # Return a type approximation if the reveiver is not self
345 # Useful for virtual types
346 fun not_for_self: MMType do return self
347
348 # The nullable version of self (if needed)
349 var _as_nullable_cache: nullable MMType = null
350
351 # IS the type can accept null?
352 fun is_nullable: Bool do return false
353
354 # Return the nullable version of the type
355 # Noop if already nullable
356 fun as_nullable: MMType do
357 var cache = _as_nullable_cache
358 if cache != null then return cache
359 var res = new MMNullableType(self)
360 _as_nullable_cache = res
361 return res
362 end
363
364 # Return the not null version of the type
365 # Noop if already not null
366 fun as_notnull: MMType do return self
367 end
368
369 class MMNullableType
370 special MMType
371 var _base_type: MMType
372 redef fun is_valid do return _base_type.is_valid
373 redef fun is_nullable: Bool do return true
374 redef fun as_notnull do return _base_type
375 redef fun as_nullable do return self
376 init(t: MMType) do _base_type = t
377
378 redef fun module do return _base_type.module
379
380 redef fun local_class do return _base_type.local_class
381
382 redef fun <(t)
383 do
384 return t isa MMNullableType and _base_type < t.as_notnull
385 end
386
387 redef fun to_s
388 do
389 return "nullable {_base_type}"
390 end
391
392 redef fun is_supertype(t)
393 do
394 return _base_type.is_supertype(t)
395 end
396
397 redef fun for_module(mod)
398 do
399 return _base_type.for_module(mod).as_nullable
400 end
401
402 redef fun adapt_to(recv)
403 do
404 return _base_type.adapt_to(recv).as_nullable
405 end
406
407 redef fun upcast_for(c)
408 do
409 return _base_type.upcast_for(c)
410 end
411
412 redef fun not_for_self
413 do
414 return _base_type.not_for_self.as_nullable
415 end
416 end
417
418 class MMTypeClass
419 special MMType
420 redef readable var _local_class: MMLocalClass
421 redef fun module do return _local_class.module end
422 redef fun <(t) do return t.is_supertype(self)
423
424 redef fun to_s
425 do
426 return _local_class.to_s
427 end
428
429 redef fun upcast_for(c)
430 do
431 var t: MMType = self
432 if _local_class != c then
433 t = _local_class.ancestor(c)
434 end
435 return t
436 end
437
438 init(c : MMLocalClass)
439 do
440 _local_class = c
441 end
442 end
443
444 class MMTypeSimpleClass
445 special MMTypeClass
446 redef fun is_supertype(t)
447 do
448 return t.local_class.cshe <= _local_class
449 end
450
451 redef fun for_module(mod)
452 do
453 var t: MMType = self
454 if module != mod then
455 t = _local_class.for_module(mod).get_type
456 end
457 return t
458 end
459
460 redef fun adapt_to(recv) do return self
461
462 init(c: MMLocalClass)
463 do
464 super(c)
465 end
466 end
467
468 # The type of null
469 class MMTypeNone
470 special MMType
471 redef readable var _module: MMModule
472 redef fun is_nullable: Bool do return true
473 redef fun <(t) do return t isa MMTypeNone or t isa MMNullableType
474 redef fun to_s do return "null"
475 redef fun is_supertype(t) do return false
476 redef fun local_class do abort
477 redef fun upcast_for(c) do abort
478 redef fun as_nullable do return self
479 redef fun as_notnull do abort
480
481 private init(m: MMModule) do _module = m
482 end
483
484 redef class MMModule
485 # The type of null
486 readable var _type_none: MMTypeNone = new MMTypeNone(self)
487 end