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 attr _base_type_cache
: 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
34 # Register a new ancestor
35 protected meth 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 attr _ancestors
: Map[MMLocalClass, MMAncestor]
45 # The ancestor type for a given superclass
46 meth ancestor
(c
: MMLocalClass): MMType
48 assert _ancestors
!= null
49 if _ancestors
.has_key
(c
) then
50 return _ancestors
[c
].stype
56 redef class MMLocalProperty
57 # The signature of the property (where it is declared)
58 readable writable attr _signature
: MMSignature
60 attr _signatures_cache
: HashMap[MMType, MMSignature] = new HashMap[MMType, MMSignature]
62 # Return the adapted signature of self for a receiver of type t
63 meth signature_for
(t
: MMType): MMSignature do
64 if t
== local_class
.get_type
then return signature
66 if _signatures_cache
.has_key
(t
) then return _signatures_cache
[t
]
68 var res
= signature
.adaptation_to
(t
)
69 _signatures_cache
[t
] = res
74 # Signature for local properties
76 # The type of the reveiver
77 readable attr _recv
: MMType
80 attr _params
: Array[MMType]
83 readable attr _return_type
: MMType
85 # The closure parameters
86 readable attr _closures
: Array[MMClosure] = new Array[MMClosure]
88 # Number of parameters
91 assert _params
!= null
95 # Is self a valid subtype of an other signature
96 meth
<(s
: MMSignature): Bool
102 assert _recv
.module == s
.recv
.module
103 if arity
!= s
.arity
or (_return_type
== null) != (s
.return_type
== null) then return false
104 if _return_type
!= null and not _return_type
< s
.return_type
then
108 for i
in [0..arity
[ do
109 if not s
[i
] < self[i
] then
114 if closures
.length
!= s
.closures
.length
then return false
115 for i
in [0..closures
.length
[ do
116 if not s
.closures
[i
] < closures
[i
] then return false
121 # The type of the i-th parameter
122 meth
[](i
: Int): MMType
124 assert _params
.length
> i
131 if _params
!= null and _params
.length
> 0 then
133 var a
= new Array[String].with_capacity
(_params
.length
)
134 for i
in [0.._params
.length
[ do
135 #var pn = _params_name[i]
140 s
.append
("({a.join(",")})")
142 if _return_type
!= null then
143 s
.append
(": {_return_type}")
148 # Adapt the signature to a different receiver
149 meth adaptation_to
(r
: MMType): MMSignature
157 p
= new Array[MMType]
159 p
.add
(i
.for_module
(mod
).adapt_to
(r
))
162 var rv
= _return_type
164 rv
= rv
.for_module
(mod
).adapt_to
(r
)
166 var res
= new MMSignature(p
,rv
,r
)
167 for clos
in _closures
do
168 res
.closures
.add
(clos
.adaptation_to
(r
))
173 attr _not_for_self_cache
: MMSignature = null
175 # Return a type approximation if the reveiver is not self
176 # Useful for virtual types
177 meth not_for_self
: MMSignature
179 var res
= _not_for_self_cache
180 if res
!= null then return res
182 var need_for_self
= false
185 p
= new Array[MMType]
187 var i2
= i
.not_for_self
188 if i
!= i2
then need_for_self
= true
193 var rv
= _return_type
196 if rv
!= _return_type
then need_for_self
= true
201 clos
= new Array[MMClosure]
202 for c
in _closures
do
203 var c2
= c
.not_for_self
204 if c2
!= c
then need_for_self
= true
209 if need_for_self
then
210 res
= new MMSignature(p
, rv
, _recv
)
211 res
.closures
.add_all
(clos
)
216 _not_for_self_cache
= res
220 init(params
: Array[MMType], return_type
: MMType, r
: MMType)
222 assert params
!= null
224 _return_type
= return_type
229 # A closure in a signature
231 # The signature of the closure
232 readable attr _signature
: MMSignature
234 # Is the closure a brek one
235 # aka is defined with the break keyword thus does not return
236 readable attr _is_break
: Bool
238 # Is the closure optional?
239 # ie is there a default definition
240 readable attr _is_optional
: Bool
242 # Adapt the signature to a different receiver
243 meth adaptation_to
(r
: MMType): MMClosure
245 return new MMClosure(_signature
.adaptation_to
(r
), _is_break
, _is_optional
)
248 init(s
: MMSignature, is_break
: Bool, is_optional
: Bool)
252 _is_optional
= is_optional
255 meth not_for_self
: MMClosure
257 var sig
= _signature
.not_for_self
258 if sig
!= _signature
then
259 return new MMClosure(sig
, _is_break
, _is_optional
)
265 meth
<(c
: MMClosure): Bool
267 if c
.is_optional
and not is_optional
then return false
268 if not c
.is_break
and is_break
then return false
269 return c
.signature
< signature
273 # Inheritance relation between two types
274 abstract class MMAncestor
276 readable writable attr _stype
: MMType = null
278 # The inheriter (heir) type
279 readable writable attr _inheriter
: MMType = null
281 meth is_reffinement
: Bool do
282 return stype
.module != stype
.module
285 meth is_specialisation
: Bool do
286 return stype
.local_class
.global
!= inheriter
.local_class
.global
289 # The inherited class
290 meth local_class
: MMLocalClass is abstract
294 if stype
== null then
295 return local_class
.to_s
303 # Note that static type a related to a specific module
304 abstract class MMType
305 # The module where self makes sence
306 meth
module: MMModule is abstract
308 # The local class that self direclty or indirectly refers to
309 meth local_class
: MMLocalClass is abstract
311 # Is self a valid subtype of t
312 meth
<(t
: MMType): Bool is abstract
314 # Is self a valid supertype of t
315 # This method must be only called within definition of < if
316 # a double dispatch is needed
317 meth is_supertype
(t
: MMType): Bool is abstract
319 # Adapt self to another module
320 meth for_module
(mod
: MMModule): MMType is abstract
322 # Get the type adapted to another receiver type
323 # Useful for formal types
324 meth adapt_to
(recv
: MMType): MMType is abstract
326 # Adapt self to another local class context
327 # Useful for genericity
328 meth upcast_for
(c
: MMLocalClass): MMType is abstract
330 # Return a type approximation if the reveiver is not self
331 # Useful for virtual types
332 meth not_for_self
: MMType do return self
337 redef readable attr _local_class
: MMLocalClass
338 redef meth
module do return _local_class
.module end
339 redef meth
<(t
) do return t
!= null and t
.is_supertype
(self)
343 return _local_class
.to_s
346 redef meth upcast_for
(c
)
348 assert _local_class
!= null
352 if _local_class
!= c
then
353 t
= _local_class
.ancestor
(c
)
359 init(c
: MMLocalClass)
365 class MMTypeSimpleClass
367 redef meth is_supertype
(t
)
369 return t
.local_class
.cshe
<= _local_class
372 redef meth for_module
(mod
)
375 if module != mod
then
376 t
= _local_class
.for_module
(mod
).get_type
382 redef meth adapt_to
(recv
) do return self
384 init(c
: MMLocalClass)
393 redef readable attr _module
: MMModule
394 redef meth
<(t
) do return true
395 redef meth is_supertype
(t
) do return false
396 redef meth local_class
do abort
397 redef meth upcast_for
(c
) do return self
399 private init(m
: MMModule) do _module
= m
404 readable attr _type_none
: MMTypeNone = new MMTypeNone(self)