1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 # Static types and property signatures
21 intrude import abstractmetamodel
23 redef class MMLocalClass
24 # Cached result of get_type
25 var _base_type_cache
: nullable MMType
27 # Return the type of self for this class
30 if _base_type_cache
== null then _base_type_cache
= new MMTypeSimpleClass(self)
31 return _base_type_cache
.as(not null)
34 # Register a new ancestor
35 protected fun add_ancestor
(a
: MMAncestor)
37 assert not _ancestors
.has_key
(a
.local_class
)
38 assert a
.local_class
!= self
39 _ancestors
[a
.local_class
] = a
42 # Array of ancestor that associate each superclass with the corresponding ancestor
43 readable var _ancestors
: nullable Map[MMLocalClass, MMAncestor]
45 # The ancestor type for a given superclass
46 fun ancestor
(c
: MMLocalClass): MMType
48 return _ancestors
[c
].stype
52 redef class MMLocalProperty
53 # The signature of the property (where it is declared)
54 readable writable var _signature
: nullable MMSignature
56 var _signatures_cache
: HashMap[MMType, MMSignature] = new HashMap[MMType, MMSignature]
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)
62 if _signatures_cache
.has_key
(t
) then return _signatures_cache
[t
]
64 var res
= signature
.adaptation_to
(t
)
65 _signatures_cache
[t
] = res
72 var name
: Symbol writable
74 init ( t
: MMType, n
: Symbol )
80 redef fun to_s
do return "{name}: {mmtype}"
83 # Signature for local properties
85 # The type of the reveiver
86 readable var _recv
: MMType
89 readable var _params
: Array[MMParam]
92 readable var _return_type
: nullable MMType
94 # The closure parameters
95 readable var _closures
: Array[MMClosure] = new Array[MMClosure]
97 # Return the closure named 'name'. Null if no such a closure exists.
98 fun closure_named
(name
: Symbol): nullable MMClosure
100 for c
in _closures
do
101 if c
.name
== name
then return c
106 # Number of parameters
109 return _params
.length
112 # Is self a valid subtype of an other signature
113 fun <(s
: MMSignature): Bool
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
126 for i
in [0..arity
[ do
127 if not s
[i
] < self[i
] then
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
139 # The type of the i-th parameter
140 fun [](i
: Int): MMType
142 assert _params
.length
> i
143 return _params
[i
].mmtype
149 if _params
.length
> 0 then
151 var a
= new Array[String].with_capacity
(_params
.length
)
152 for i
in [0.._params
.length
[ do
156 s
.append
("({a.join(", ")})")
158 var rt
= _return_type
159 if rt
!= null then s
.append
(": {rt}")
163 # Adapt the signature to a different receiver
164 fun adaptation_to
(r
: MMType): MMSignature
170 var p
= new Array[MMParam]
172 var new_type
= i
.mmtype
.for_module
(mod
).adapt_to
(r
)
174 if new_type
== i
.mmtype
then
177 new_param
= new MMParam( new_type
, i
.name
)
182 var rv
= _return_type
184 rv
= rv
.for_module
(mod
).adapt_to
(r
)
186 var res
= new MMSignature(p
,rv
,r
)
187 for clos
in _closures
do
188 res
.closures
.add
(clos
.adaptation_to
(r
))
193 var _not_for_self_cache
: nullable MMSignature = null
195 # Return a type approximation if the reveiver is not self
196 # Useful for virtual types
197 fun not_for_self
: MMSignature
199 if _not_for_self_cache
!= null then return _not_for_self_cache
.as(not null)
201 var need_for_self
= false
202 var p
= new Array[MMParam]
204 var new_type
= i
.mmtype
.not_for_self
206 if i
.mmtype
== new_type
then
210 new_param
= new MMParam( new_type
, i
.name
)
216 var rv
= _return_type
219 if rv
!= _return_type
then need_for_self
= true
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
230 if need_for_self
then
231 res
= new MMSignature(p
, rv
, _recv
)
232 res
.closures
.add_all
(clos
)
237 _not_for_self_cache
= res
241 init(params
: Array[MMParam], return_type
: nullable MMType, r
: MMType)
244 _return_type
= return_type
250 redef class MMExplicitImport
251 var signature
: MMSignature
253 redef init( local_class
: MMLocalClass, meth
: MMMethod )
256 signature
= meth
.signature
.adaptation_to
( local_class
.get_type
)
260 # A closure in a signature
262 # The name of the closure (without the !)
263 readable var _name
: Symbol
265 # The signature of the closure
266 readable var _signature
: MMSignature
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
272 # Is the closure optional?
273 # ie is there a default definition
274 readable var _is_optional
: Bool
276 # Adapt the signature to a different receiver
277 fun adaptation_to
(r
: MMType): MMClosure
279 return new MMClosure(_name
, _signature
.adaptation_to
(r
), _is_break
, _is_optional
)
282 init(name
: Symbol, s
: MMSignature, is_break
: Bool, is_optional
: Bool)
287 _is_optional
= is_optional
290 fun not_for_self
: MMClosure
292 var sig
= _signature
.not_for_self
293 if sig
!= _signature
then
294 return new MMClosure(_name
, sig
, _is_break
, _is_optional
)
300 fun <(c
: MMClosure): Bool
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
308 # Inheritance relation between two types
309 abstract class MMAncestor
311 writable var _stype
: nullable MMType = null
314 fun stype
: MMType do return _stype
.as(not null)
316 # The inheriter (heir) type
317 writable var _inheriter
: nullable MMType = null
319 # The inheriter (heir) type
320 fun inheriter
: MMType do return _inheriter
.as(not null)
322 fun is_reffinement
: Bool do
323 return stype
.mmmodule
!= stype
.mmmodule
326 fun is_specialisation
: Bool do
327 return stype
.local_class
.global
!= inheriter
.local_class
.global
330 # The inherited class
331 fun local_class
: MMLocalClass is abstract
335 if _stype
== null then
336 return local_class
.to_s
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
349 # The local class that self direclty or indirectly refers to
350 fun local_class
: MMLocalClass is abstract
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
356 # Is self a valid subtype of t
357 fun <(t
: MMType): Bool is abstract
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
364 # Adapt self to another module
365 fun for_module
(mod
: MMModule): MMType is abstract
367 # Get the type adapted to another receiver type
368 # Useful for formal types
369 fun adapt_to
(recv
: MMType): MMType is abstract
371 # Adapt self to another local class context
372 # Useful for genericity
373 # 'c' Must be a super-class of self
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
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
397 # The nullable version of self (if needed)
398 var _as_nullable_cache
: nullable MMType = null
400 # IS the type can accept null?
401 fun is_nullable
: Bool do return false
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
413 # Return the not null version of the type
414 # Noop if already not null
415 fun as_notnull
: MMType do return self
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
427 redef fun mmmodule
do return _base_type
.mmmodule
429 redef fun local_class
do return _base_type
.local_class
433 return t
isa MMNullableType and _base_type
< t
.as_notnull
438 return "nullable {_base_type}"
441 redef fun is_supertype
(t
)
443 return _base_type
.is_supertype
(t
)
446 redef fun for_module
(mod
)
448 return _base_type
.for_module
(mod
).as_nullable
451 redef fun adapt_to
(recv
)
453 return _base_type
.adapt_to
(recv
).as_nullable
456 redef fun upcast_for
(c
)
458 return _base_type
.upcast_for
(c
)
461 redef fun not_for_self
463 return _base_type
.not_for_self
.as_nullable
467 abstract class MMTypeClass
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)
475 return _local_class
.to_s
478 redef fun upcast_for
(c
)
481 if _local_class
!= c
then
482 t
= _local_class
.ancestor
(c
)
487 init(c
: MMLocalClass)
493 class MMTypeSimpleClass
495 redef fun is_supertype
(t
)
497 return t
.local_class
.cshe
<= _local_class
500 redef fun for_module
(mod
)
503 if mmmodule
!= mod
then
504 t
= _local_class
.for_module
(mod
).get_type
509 redef fun adapt_to
(recv
) do return self
511 init(c
: MMLocalClass)
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
530 private init(m
: MMModule) do _mmmodule
= m
535 readable var _type_none
: MMTypeNone = new MMTypeNone(self)
538 fun type_bool
: MMType
540 return class_by_name
(once
("Bool".to_symbol
)).get_type
544 # Explicitly imported cast
546 readable var _from
: MMType
547 readable var _to
: MMType
549 fun is_about_nullable_only
: Bool
551 return ( _from
.is_nullable
and _to
.as_nullable
== _from
) or
552 ( _to
.is_nullable
and _from
.as_nullable
== _to
)
555 fun is_not_null_to_nullable
: Bool
557 return not _from
.is_nullable
and _to
.is_nullable
560 fun is_nullable_to_not_null
: Bool
562 return _from
.is_nullable
and not _to
.is_nullable
567 return o
isa MMImportedCast and
568 o
.from
== from
and o
.to
== to
572 # Method local properties
574 # casts explicitely imported to be available from native implementation
575 fun explicit_casts
: Set[ MMImportedCast ] is abstract