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 cached result of signature
58 attr _signature_cache
: MMSignature
60 # return signature for this property
61 meth signature
: MMSignature # FIXME must rewrite
63 if _signature_cache
== null then
64 if _super_prop
== null then
65 _signature_cache
= _concrete_property
.signature
67 _signature_cache
= _super_prop
.signature
70 assert _signature_cache
!= null
71 return _signature_cache
74 meth signature
=(s
: MMSignature) do _signature_cache
= s
77 # Signature for local properties
79 # The type of the reveiver
80 readable attr _recv
: MMType
83 attr _params
: Array[MMType]
86 readable attr _return_type
: MMType
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 assert arity
== s
.arity
104 assert (_return_type
== null) == (s
.return_type
== null)
105 if _return_type
!= null and not _return_type
< s
.return_type
then
109 for i
in [0..arity
[ do
110 if not s
[i
] < self[i
] then
117 # The type of the i-th parameter
118 meth
[](i
: Int): MMType
120 assert _params
.length
> i
127 if _params
!= null and _params
.length
> 0 then
129 var a
= new Array[String].with_capacity
(_params
.length
)
130 for i
in [0.._params
.length
[ do
131 #var pn = _params_name[i]
136 s
= "({a.join(",")})"
140 if _return_type
!= null then
141 s
.append
(": {_return_type}")
146 init(params
: Array[MMType], return_type
: MMType, r
: MMType)
148 assert params
!= null
150 _return_type
= return_type
155 # Inheritance relation between two types
156 abstract class MMAncestor
158 readable writable attr _stype
: MMType
160 # The inheriter (heir) type
161 readable writable attr _inheriter
: MMType
163 meth is_reffinement
: Bool do
164 return stype
.module != stype
.module
167 meth is_specialisation
: Bool do
168 return stype
.local_class
.global
!= inheriter
.local_class
.global
171 # The inherited class
172 meth local_class
: MMLocalClass is abstract
176 if stype
== null then
177 return local_class
.to_s
185 # Note that static type a related to a specific module
186 abstract class MMType
187 # The module where self makes sence
188 meth
module: MMModule is abstract
190 # The local class that self direclty or indirectly refers to
191 meth local_class
: MMLocalClass is abstract
193 # Is self a valid subtype of t
194 meth
<(t
: MMType): Bool is abstract
196 # Is self a valid supertype of t
197 # This method must be only called within definition of < if
198 # a double dispatch is needed
199 meth is_supertype
(t
: MMType): Bool is abstract
201 # Select a method from its name
202 meth select_method
(name
: Symbol): MMMethod
204 assert local_class
!= null
206 var res
= select_property
(local_class
.method
(name
))
207 assert res
isa MMMethod
211 # Select an attribute from its name
212 meth select_attribute
(name
: Symbol): MMAttribute
215 assert local_class
!= null
216 var res
= select_property
(local_class
.attribute
(name
))
217 assert res
isa MMAttribute
221 # Select a local property from its global property
222 meth select_property
(t
: MMGlobalProperty): MMLocalProperty is abstract
224 # Adapt self to another module
225 meth for_module
(mod
: MMModule): MMType is abstract
227 # Get the type adapted to another receiver type
228 # Useful for formal types
229 meth adapt_to
(recv
: MMType): MMType is abstract
231 # Adapt self to another local class context
232 # Useful for genericity
233 meth upcast_for
(c
: MMLocalClass): MMType is abstract
235 # Return a type approximation if the reveiver is not self
236 # Useful for virtual types
237 meth not_for_self
: MMType do return self
242 redef readable attr _local_class
: MMLocalClass
243 redef meth
module do return _local_class
.module end
244 redef meth
<(t
) do return t
!= null and t
.is_supertype
(self)
248 return _local_class
.to_s
251 redef meth upcast_for
(c
)
253 assert _local_class
!= null
257 if _local_class
!= c
then
258 t
= _local_class
.ancestor
(c
)
264 init(c
: MMLocalClass)
270 class MMTypeSimpleClass
272 redef meth is_supertype
(t
)
274 return t
.local_class
.cshe
<= _local_class
277 redef meth select_property
(g
)
279 assert _local_class
!= null
283 return _local_class
[g
]
286 redef meth for_module
(mod
)
289 if module != mod
then
290 t
= _local_class
.for_module
(mod
).get_type
296 redef meth adapt_to
(recv
) do return self
298 redef init(c
: MMLocalClass)
307 redef readable attr _module
: MMModule
308 redef meth
<(t
) do return true
309 redef meth is_supertype
(t
) do return false
310 redef meth local_class
do abort
311 redef meth upcast_for
(c
) do return self
313 private init(m
: MMModule) do _module
= m
318 readable attr _type_none
: MMTypeNone = new MMTypeNone(self)