syntax: 'meth' -> 'fun', 'attr' -> 'var'
[nit.git] / src / metamodel / virtualtype.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
4 # Copyright 2008 Jean Privat <jean@pryen.org>
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 # Virtual type (property of type type)
19 package virtualtype
20
21 import type_formal
22
23 redef class MMGlobalProperty
24 # Is self a virtual type
25 fun is_virtual_type: Bool do return intro isa MMTypeProperty
26 end
27
28 # Virtual type properties
29 class MMTypeProperty
30 special MMLocalProperty
31 # The virtual static type associated
32 fun stype_for(recv: MMType): nullable MMVirtualType
33 do
34 var prop = recv.local_class[global]
35 assert prop isa MMTypeProperty
36 return prop.real_stype_for(recv)
37 end
38
39 # Cached results of stype
40 var _stypes_cache: HashMap[MMType, MMVirtualType] = new HashMap[MMType, MMVirtualType]
41
42 private fun real_stype_for(recv: MMType): nullable MMVirtualType
43 do
44 # If the signature is not build: Circular definition
45 if signature == null then return null
46
47 if _stypes_cache.has_key(recv) then return _stypes_cache[recv]
48
49 var res = new MMVirtualType(self, recv)
50 _stypes_cache[recv] = res
51
52 return res
53 end
54 end
55
56 class MMVirtualType
57 special MMTypeFormal
58 # The property associed
59 readable var _property: MMTypeProperty
60
61 # The receiver type
62 readable var _recv: MMType
63
64 protected init(p: MMTypeProperty, recv: MMType)
65 do
66 super(p.name, p.signature_for(recv).return_type)
67 _property = p
68 _recv = recv
69 end
70
71 redef fun module do return _recv.module
72
73 redef fun for_module(mod)
74 do
75 if mod == module then return self
76 return adapt_to(recv.for_module(mod))
77 end
78
79 redef fun not_for_self
80 do
81 return bound.not_for_self
82 end
83
84 redef fun adapt_to(recv)
85 do
86 return property.stype_for(recv).as(not null)
87 end
88 end
89
90 redef class MMLocalClass
91 fun virtual_type(s: Symbol): MMGlobalProperty
92 do
93 var prop = get_property_by_name(s)
94 if prop.is_virtual_type then
95 return prop
96 end
97 abort
98 end
99
100 # Select a virtual type property by its name
101 fun select_virtual_type(name: Symbol): MMTypeProperty
102 do
103 var gp = virtual_type(name)
104 var res = self[gp]
105 assert res isa MMTypeProperty
106 return res
107 end
108 end