1 # coding: utf-8
2 # frozen_string_literal: true
3
4
5
6 module Umu
7
8 module Environment
9
10 module Context
11
12 module Type
13
14 module Signature
15
16 module Method
17
18 class Abstract
19 attr_reader :meth_sym
20 attr_reader :mess_sym
21
22 alias to_sym mess_sym
23
24
25 def initialize(meth_sym, mess_sym)
26 ASSERT.kind_of meth_sym, ::Symbol
27 ASSERT.kind_of mess_sym, ::Symbol
28
29 @meth_sym = meth_sym
30 @mess_sym = mess_sym
31 end
32
33
34 def ==(other)
35 other.kind_of?(Abstract) && self.mess_sym == other.mess_sym
36 end
37 alias eql? ==
38
39
40 def <=>(other)
41 ASSERT.kind_of other, Abstract
42
43 self.mess_sym <=> other.mess_sym
44 end
45
46
47 def hash
48 self.mess_sym.hash
49 end
50
51
52 def to_s
53 if __keyword_method__?
54 format("(%s) -> %s",
55 __extract_keywords__.map { |lab, typ|
56 format "%s:%s", lab, typ.type_sym.to_s
57 }.join(' '),
58
59 self.ret_class.type_sym.to_s
60 )
61 else
62 format("%s : %s",
63 self.mess_sym.to_s,
64
65 (
66 self.param_classes + [self.ret_class]
67 ).map { |typ|
68 typ.type_sym.to_s
69 }.join(' -> ')
70 )
71 end
72 end
73
74
75 def param_classes
76 raise X::InternalSubclassResponsibility
77 end
78
79
80 def ret_class
81 raise X::InternalSubclassResponsibility
82 end
83
84
85 private
86
87 def __keyword_method__?
88 /:/ =~ self.mess_sym
89 end
90
91
92 def __extract_keywords__
93 labels = self.mess_sym.to_s.split(':')
94 ASSERT.assert labels.size == self.param_classes.size
95
96 labels.zip self.param_classes
97 end
98 end
99
100
101
102 class Entry < Abstract
103 attr_reader :param_class_signats
104 attr_reader :ret_class_signat
105
106
107 def initialize(
108 meth_sym, mess_sym, param_class_signats, ret_class_signat
109 )
110 ASSERT.kind_of meth_sym, ::Symbol
111 ASSERT.kind_of mess_sym, ::Symbol
112 ASSERT.kind_of param_class_signats, ::Array
113 ASSERT.kind_of ret_class_signat, Class::Abstract
114
115 super(meth_sym, mess_sym)
116
117 @param_class_signats = param_class_signats
118 @ret_class_signat = ret_class_signat
119 end
120
121
122 def param_classes
123 self.param_class_signats
124 end
125
126
127 def ret_class
128 self.ret_class_signat
129 end
130 end
131
132
133
134 class Info < Abstract
135 attr_reader :param_class_types
136 attr_reader :ret_class_type
137
138
139 def initialize(
140 meth_sym, mess_sym, param_class_types, ret_class_type
141 )
142 ASSERT.kind_of meth_sym, ::Symbol
143 ASSERT.kind_of mess_sym, ::Symbol
144 ASSERT.kind_of param_class_types, ::Array
145 ASSERT.subclass_of ret_class_type, VC::Top
146
147 super(meth_sym, mess_sym)
148
149 @param_class_types = param_class_types
150 @ret_class_type = ret_class_type
151 end
152
153
154 def param_classes
155 self.param_class_types
156 end
157
158
159 def ret_class
160 self.ret_class_type
161 end
162
163
164 =begin
165 def to_a
166 [meth_sym, ret_class_type, mess_sym, param_class_types].freeze
167 end
168 =end
169
170
171 def format_info
172 (
173 if __keyword_method__?
174 [
175 format("(%s)",
176 __extract_keywords__.map { |lab, typ|
177 format "%s:%s", lab, typ.type_sym.to_s
178 }.join(' ')
179 ),
180
181 nil
182 ]
183 else
184 [
185 self.mess_sym.to_s,
186
187 self.param_classes.map { |typ|
188 typ.type_sym.to_s
189 }.join(' -> ')
190 ]
191 end
192 ) + [
193 self.ret_class.type_sym.to_s
194 ]
195 end
196
197
198 def to_signat(env)
199 ret_signat = env.ty_signat_of_class self.ret_class_type
200 param_signats = self.param_class_types.map { |klass|
201 ASSERT.subclass_of klass, VC::Top
202
203 env.ty_signat_of_class klass
204 }
205
206 ECTS.make_method_signat(
207 self.meth_sym, self.mess_sym, param_signats, ret_signat
208 )
209 end
210 end
211
212 end # Umu::Environment::Context::Type::Signature::Method
213
214
215 module_function
216
217 def make_method_signat(
218 meth_sym, mess_sym, param_class_signats, ret_class_signat
219 )
220 ASSERT.kind_of meth_sym, ::Symbol
221 ASSERT.kind_of mess_sym, ::Symbol
222 ASSERT.kind_of param_class_signats, ::Array
223 ASSERT.kind_of ret_class_signat, Class::Abstract
224
225 Method::Entry.new(
226 meth_sym, mess_sym, param_class_signats.freeze, ret_class_signat
227 ).freeze
228 end
229
230
231 def make_method_info(
232 meth_sym, mess_sym, param_class_types, ret_class_type
233 )
234 ASSERT.kind_of meth_sym, ::Symbol
235 ASSERT.kind_of mess_sym, ::Symbol
236 ASSERT.kind_of param_class_types, ::Array
237 ASSERT.subclass_of ret_class_type, VC::Top
238
239 Method::Info.new(
240 meth_sym, mess_sym, param_class_types.freeze, ret_class_type
241 ).freeze
242 end
243
244 end # Umu::Environment::Context::Type::Signature
245
246 end # Umu::Environment::Context::Type
247
248 end # Umu::Environment::Context
249
250 end # Umu::Environment
251
252 end # Umu