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