rename 'package' to 'module'
[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 module 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 class MMParam
71 var mmtype: MMType
72 var name: Symbol writable
73
74 init ( t : MMType, n : Symbol )
75 do
76 mmtype = t
77 name = n
78 end
79
80 redef fun to_s do return "{name}: {mmtype}"
81 end
82
83 # Signature for local properties
84 class MMSignature
85 # The type of the reveiver
86 readable var _recv: MMType
87
88 # The parameter types
89 readable var _params: Array[MMParam]
90
91 # The return type
92 readable var _return_type: nullable MMType
93
94 # The closure parameters
95 readable var _closures: Array[MMClosure] = new Array[MMClosure]
96
97 # Return the closure named 'name'. Null if no such a closure exists.
98 fun closure_named(name: Symbol): nullable MMClosure
99 do
100 for c in _closures do
101 if c.name == name then return c
102 end
103 return null
104 end
105
106 # Number of parameters
107 fun arity: Int
108 do
109 return _params.length
110 end
111
112 # Is self a valid subtype of an other signature
113 fun <(s: MMSignature): Bool
114 do
115 if self == s then
116 return true
117 end
118 assert _recv.mmmodule == s.recv.mmmodule
119 var rt = _return_type
120 var srt = s.return_type
121 if arity != s.arity or (rt == null) != (srt == null) then return false
122 if rt != null and not rt < srt.as(not null) then
123 return false
124 end
125
126 for i in [0..arity[ do
127 if not s[i] < self[i] then
128 return false
129 end
130 end
131
132 if closures.length != s.closures.length then return false
133 for i in [0..closures.length[ do
134 if not s.closures[i] < closures[i] then return false
135 end
136 return true
137 end
138
139 # The type of the i-th parameter
140 fun [](i: Int): MMType
141 do
142 assert _params.length > i
143 return _params[i].mmtype
144 end
145
146 redef fun to_s
147 do
148 var s = new Buffer
149 if _params.length > 0 then
150 var tmp: String
151 var a = new Array[String].with_capacity(_params.length)
152 for i in [0.._params.length[ do
153 var p = _params[i]
154 a.add(p.to_s)
155 end
156 s.append("({a.join(", ")})")
157 end
158 var rt = _return_type
159 if rt != null then s.append(": {rt}")
160 return s.to_s
161 end
162
163 # Adapt the signature to a different receiver
164 fun adaptation_to(r: MMType): MMSignature
165 do
166 if _recv == r then
167 return self
168 end
169 var mod = r.mmmodule
170 var p = new Array[MMParam]
171 for i in _params do
172 var new_type = i.mmtype.for_module(mod).adapt_to(r)
173 var new_param
174 if new_type == i.mmtype then
175 new_param = i
176 else
177 new_param = new MMParam( new_type, i.name )
178 end
179
180 p.add( new_param )
181 end
182 var rv = _return_type
183 if rv != null then
184 rv = rv.for_module(mod).adapt_to(r)
185 end
186 var res = new MMSignature(p,rv,r)
187 for clos in _closures do
188 res.closures.add(clos.adaptation_to(r))
189 end
190 return res
191 end
192
193 var _not_for_self_cache: nullable MMSignature = null
194
195 # Return a type approximation if the reveiver is not self
196 # Useful for virtual types
197 fun not_for_self: MMSignature
198 do
199 if _not_for_self_cache != null then return _not_for_self_cache.as(not null)
200
201 var need_for_self = false
202 var p = new Array[MMParam]
203 for i in _params do
204 var new_type = i.mmtype.not_for_self
205 var new_param
206 if i.mmtype == new_type then
207 new_param = i
208 else
209 need_for_self = true
210 new_param = new MMParam( new_type, i.name )
211 end
212
213 p.add( new_param )
214 end
215
216 var rv = _return_type
217 if rv != null then
218 rv = rv.not_for_self
219 if rv != _return_type then need_for_self = true
220 end
221
222 var clos = new Array[MMClosure]
223 for c in _closures do
224 var c2 = c.not_for_self
225 if c2 != c then need_for_self = true
226 clos.add(c2)
227 end
228
229 var res: MMSignature
230 if need_for_self then
231 res = new MMSignature(p, rv, _recv)
232 res.closures.add_all(clos)
233 else
234 res = self
235 end
236
237 _not_for_self_cache = res
238 return res
239 end
240
241 init(params: Array[MMParam], return_type: nullable MMType, r: MMType)
242 do
243 _params = params
244 _return_type = return_type
245 _recv = r
246 end
247 end
248
249
250 redef class MMExplicitImport
251 var signature : MMSignature
252
253 redef init( local_class : MMLocalClass, meth : MMMethod )
254 do
255 super
256 signature = meth.signature.adaptation_to( local_class.get_type )
257 end
258 end
259
260 # A closure in a signature
261 class MMClosure
262 # The name of the closure (without the !)
263 readable var _name: Symbol
264
265 # The signature of the closure
266 readable var _signature: MMSignature
267
268 # Is the closure a brek one
269 # aka is defined with the break keyword thus does not return
270 readable var _is_break: Bool
271
272 # Is the closure optional?
273 # ie is there a default definition
274 readable var _is_optional: Bool
275
276 # Adapt the signature to a different receiver
277 fun adaptation_to(r: MMType): MMClosure
278 do
279 return new MMClosure(_name, _signature.adaptation_to(r), _is_break, _is_optional)
280 end
281
282 init(name: Symbol, s: MMSignature, is_break: Bool, is_optional: Bool)
283 do
284 _name = name
285 _signature = s
286 _is_break = is_break
287 _is_optional = is_optional
288 end
289
290 fun not_for_self: MMClosure
291 do
292 var sig = _signature.not_for_self
293 if sig != _signature then
294 return new MMClosure(_name, sig, _is_break, _is_optional)
295 else
296 return self
297 end
298 end
299
300 fun <(c: MMClosure): Bool
301 do
302 if c.is_optional and not is_optional then return false
303 if not c.is_break and is_break then return false
304 return c.signature < signature
305 end
306 end
307
308 # Inheritance relation between two types
309 abstract class MMAncestor
310 # The inherited type
311 writable var _stype: nullable MMType = null
312
313 # The inherited type
314 fun stype: MMType do return _stype.as(not null)
315
316 # The inheriter (heir) type
317 writable var _inheriter: nullable MMType = null
318
319 # The inheriter (heir) type
320 fun inheriter: MMType do return _inheriter.as(not null)
321
322 fun is_reffinement: Bool do
323 return stype.mmmodule != stype.mmmodule
324 end
325
326 fun is_specialisation: Bool do
327 return stype.local_class.global != inheriter.local_class.global
328 end
329
330 # The inherited class
331 fun local_class: MMLocalClass is abstract
332
333 redef fun to_s
334 do
335 if _stype == null then
336 return local_class.to_s
337 else
338 return stype.to_s
339 end
340 end
341 end
342
343 # A static type
344 # Note that static type is related to a specific module
345 abstract class MMType
346 # The module where self makes sence
347 fun mmmodule: MMModule is abstract
348
349 # The local class that self direclty or indirectly refers to
350 fun local_class: MMLocalClass is abstract
351
352 # Is the type a valid one
353 # For instance, circular dependency on formal types is invalid
354 fun is_valid: Bool do return true
355
356 # Is self a valid subtype of t
357 fun <(t : MMType): Bool is abstract
358
359 # Is self a valid supertype of t
360 # This method must be only called within definition of < if
361 # a double dispatch is needed
362 fun is_supertype(t: MMType): Bool is abstract
363
364 # Adapt self to another module
365 fun for_module(mod: MMModule): MMType is abstract
366
367 # Get the type adapted to another receiver type
368 # Useful for formal types
369 fun adapt_to(recv: MMType): MMType is abstract
370
371 # Adapt self to another local class context
372 # Useful for genericity
373 # 'c' Must be a super-class of self
374 # Example:
375 # class A[E]
376 # class B[F] super A[F]
377 # class C[G] super B[String]
378 # class D super C[Float]
379 # 'A[Int]'.upcast_for('A') -> 'A[Int]'
380 # 'A[Int]'.upcast_for('B') -> abort
381 # 'B[Int]'.upcast_for('B') -> 'B[Int]'
382 # 'B[Int]'.upcast_for('A') -> 'A[Int]'
383 # 'B[Int]'.upcast_for('C') -> abort
384 # 'C[Int]'.upcast_for('C') -> 'C[Int]'
385 # 'C[Int]'.upcast_for('B') -> 'B[String]'
386 # 'C[Int]'.upcast_for('A') -> 'A[String]'
387 # 'D'.upcast_for('D') -> 'D'
388 # 'D'.upcast_for('C') -> 'C[Float]'
389 # 'D'.upcast_for('B') -> 'C[String]'
390 # 'D'.upcast_for('A') -> 'A[String]'
391 fun upcast_for(c: MMLocalClass): MMType is abstract
392
393 # Return a type approximation if the reveiver is not self
394 # Useful for virtual types
395 fun not_for_self: MMType do return self
396
397 # The nullable version of self (if needed)
398 var _as_nullable_cache: nullable MMType = null
399
400 # IS the type can accept null?
401 fun is_nullable: Bool do return false
402
403 # Return the nullable version of the type
404 # Noop if already nullable
405 fun as_nullable: MMType do
406 var cache = _as_nullable_cache
407 if cache != null then return cache
408 var res = new MMNullableType(self)
409 _as_nullable_cache = res
410 return res
411 end
412
413 # Return the not null version of the type
414 # Noop if already not null
415 fun as_notnull: MMType do return self
416 end
417
418 class MMNullableType
419 super MMType
420 readable var _base_type: MMType
421 redef fun is_valid do return _base_type.is_valid
422 redef fun is_nullable: Bool do return true
423 redef fun as_notnull do return _base_type
424 redef fun as_nullable do return self
425 init(t: MMType) do _base_type = t
426
427 redef fun mmmodule do return _base_type.mmmodule
428
429 redef fun local_class do return _base_type.local_class
430
431 redef fun <(t)
432 do
433 return t isa MMNullableType and _base_type < t.as_notnull
434 end
435
436 redef fun to_s
437 do
438 return "nullable {_base_type}"
439 end
440
441 redef fun is_supertype(t)
442 do
443 return _base_type.is_supertype(t)
444 end
445
446 redef fun for_module(mod)
447 do
448 return _base_type.for_module(mod).as_nullable
449 end
450
451 redef fun adapt_to(recv)
452 do
453 return _base_type.adapt_to(recv).as_nullable
454 end
455
456 redef fun upcast_for(c)
457 do
458 return _base_type.upcast_for(c)
459 end
460
461 redef fun not_for_self
462 do
463 return _base_type.not_for_self.as_nullable
464 end
465 end
466
467 abstract class MMTypeClass
468 super MMType
469 redef readable var _local_class: MMLocalClass
470 redef fun mmmodule do return _local_class.mmmodule end
471 redef fun <(t) do return t.is_supertype(self)
472
473 redef fun to_s
474 do
475 return _local_class.to_s
476 end
477
478 redef fun upcast_for(c)
479 do
480 var t: MMType = self
481 if _local_class != c then
482 t = _local_class.ancestor(c)
483 end
484 return t
485 end
486
487 init(c : MMLocalClass)
488 do
489 _local_class = c
490 end
491 end
492
493 class MMTypeSimpleClass
494 super MMTypeClass
495 redef fun is_supertype(t)
496 do
497 return t.local_class.cshe <= _local_class
498 end
499
500 redef fun for_module(mod)
501 do
502 var t: MMType = self
503 if mmmodule != mod then
504 t = _local_class.for_module(mod).get_type
505 end
506 return t
507 end
508
509 redef fun adapt_to(recv) do return self
510
511 init(c: MMLocalClass)
512 do
513 super(c)
514 end
515 end
516
517 # The type of null
518 class MMTypeNone
519 super MMType
520 redef readable var _mmmodule: MMModule
521 redef fun is_nullable: Bool do return true
522 redef fun <(t) do return t isa MMTypeNone or t isa MMNullableType
523 redef fun to_s do return "null"
524 redef fun is_supertype(t) do return false
525 redef fun local_class do abort
526 redef fun upcast_for(c) do abort
527 redef fun as_nullable do return self
528 redef fun as_notnull do abort
529
530 private init(m: MMModule) do _mmmodule = m
531 end
532
533 redef class MMModule
534 # The type of null
535 readable var _type_none: MMTypeNone = new MMTypeNone(self)
536
537 # The type of bool
538 fun type_bool: MMType
539 do
540 return class_by_name(once ("Bool".to_symbol)).get_type
541 end
542 end
543
544 # Explicitly imported cast
545 class MMImportedCast
546 readable var _from : MMType
547 readable var _to : MMType
548
549 fun is_about_nullable_only : Bool
550 do
551 return ( _from.is_nullable and _to.as_nullable == _from ) or
552 ( _to.is_nullable and _from.as_nullable == _to )
553 end
554
555 fun is_not_null_to_nullable : Bool
556 do
557 return not _from.is_nullable and _to.is_nullable
558 end
559
560 fun is_nullable_to_not_null : Bool
561 do
562 return _from.is_nullable and not _to.is_nullable
563 end
564
565 redef fun == ( o )
566 do
567 return o isa MMImportedCast and
568 o.from == from and o.to == to
569 end
570 end
571
572 # Method local properties
573 redef class MMMethod
574 # casts explicitely imported to be available from native implementation
575 fun explicit_casts : Set[ MMImportedCast ] is abstract
576 end