raap 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +31 -0
- data/README.md +32 -3
- data/Rakefile +10 -1
- data/exe/raap +4 -1
- data/lib/raap/bind_call.rb +21 -7
- data/lib/raap/cli.rb +211 -125
- data/lib/raap/function_type.rb +14 -10
- data/lib/raap/method_property.rb +60 -28
- data/lib/raap/method_type.rb +13 -6
- data/lib/raap/minitest.rb +9 -3
- data/lib/raap/rbs.rb +19 -0
- data/lib/raap/result.rb +84 -8
- data/lib/raap/sized.rb +2 -0
- data/lib/raap/symbolic_caller.rb +38 -26
- data/lib/raap/type.rb +111 -115
- data/lib/raap/type_substitution.rb +5 -1
- data/lib/raap/value/bottom.rb +2 -0
- data/lib/raap/value/interface.rb +61 -27
- data/lib/raap/value/intersection.rb +26 -21
- data/lib/raap/value/module.rb +50 -7
- data/lib/raap/value/top.rb +2 -0
- data/lib/raap/value/variable.rb +12 -1
- data/lib/raap/value/void.rb +2 -0
- data/lib/raap/version.rb +1 -1
- data/lib/raap.rb +3 -2
- data/public/jacket.webp +0 -0
- data/rbs_collection.lock.yaml +61 -1
- data/rbs_collection.yaml +0 -1
- data/sig/raap.rbs +63 -34
- data/sig/shims.rbs +4 -0
- metadata +10 -9
data/lib/raap/type.rb
CHANGED
@@ -13,25 +13,61 @@ module RaaP
|
|
13
13
|
|
14
14
|
def self.positive_float
|
15
15
|
x = Random.rand
|
16
|
-
x / Math.sqrt(1 - x * x)
|
16
|
+
x / Math.sqrt(1 - (x * x))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
GENERATORS = {}
|
21
21
|
SIMPLE_SOURCE = ('a'..'z').to_a << '_'
|
22
|
-
RECURSION = Hash.new { |h, k| h[k] = { count: 0, logged: false } }
|
23
22
|
|
24
23
|
# Type.register "::Integer::positive" { sized { |size| size } }
|
25
24
|
def self.register(type_name, &block)
|
26
25
|
raise ArgumentError, "block is required" unless block
|
26
|
+
|
27
27
|
GENERATORS[type_name] = __skip__ = block
|
28
28
|
end
|
29
29
|
|
30
|
+
def self.random
|
31
|
+
Type.new("Integer | Float | Rational | Complex | String | Symbol | bool | Encoding | BasicObject | nil | Time")
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.random_without_basic_object
|
35
|
+
random.tap do |r|
|
36
|
+
# @type var rtype: ::RBS::Types::Union
|
37
|
+
rtype = r.type
|
38
|
+
rtype.types.reject! { |t| t.to_s == "BasicObject" }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.call_new_from(base, type, size:)
|
43
|
+
type_name = type.name.absolute!
|
44
|
+
definition = RBS.builder.build_singleton(type_name)
|
45
|
+
snew = definition.methods[:new]
|
46
|
+
if snew
|
47
|
+
# class
|
48
|
+
rbs_method_type = snew.method_types.sample or raise
|
49
|
+
type_params = definition.type_params_decl.concat(rbs_method_type.type_params.drop(definition.type_params_decl.length))
|
50
|
+
ts = TypeSubstitution.new(type_params, type.args)
|
51
|
+
maped_rbs_method_type = ts.method_type_sub(rbs_method_type)
|
52
|
+
method_type = MethodType.new(maped_rbs_method_type)
|
53
|
+
|
54
|
+
begin
|
55
|
+
args, kwargs, block = method_type.arguments_to_symbolic_call(size:)
|
56
|
+
[:call, base, :new, args, kwargs, block]
|
57
|
+
rescue
|
58
|
+
$stderr.puts "Fail with `#{rbs_method_type}`"
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
else
|
62
|
+
[:call, Value::Module, :new, [type.to_s], { size: }, nil]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
30
66
|
# Special class case
|
31
67
|
register("::Array") do
|
32
|
-
|
33
|
-
t =
|
34
|
-
array(
|
68
|
+
instance = __skip__ = type
|
69
|
+
t = instance.args[0] ? Type.new(instance.args[0], range:) : Type.random
|
70
|
+
array(t)
|
35
71
|
end
|
36
72
|
register("::Binding") { sized { binding } }
|
37
73
|
register("::Complex") { complex }
|
@@ -40,14 +76,10 @@ module RaaP
|
|
40
76
|
register("::FalseClass") { sized { false } }
|
41
77
|
register("::Float") { float }
|
42
78
|
register("::Hash") do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
v = _type.args[1] || 'untyped'
|
48
|
-
[Type.new(k).pick(size: size), Type.new(v).pick(size: size)]
|
49
|
-
end
|
50
|
-
end
|
79
|
+
instance = __skip__ = type
|
80
|
+
key = instance.args[0] ? Type.new(instance.args[0]) : Type.random_without_basic_object
|
81
|
+
value = instance.args[1] ? Type.new(instance.args[1]) : Type.random
|
82
|
+
dict(key, value)
|
51
83
|
end
|
52
84
|
register("::Integer") { integer }
|
53
85
|
register("::IO") { sized { $stdout } }
|
@@ -55,11 +87,11 @@ module RaaP
|
|
55
87
|
register("::NilClass") { sized { nil } }
|
56
88
|
register("::Proc") { sized { Proc.new {} } }
|
57
89
|
register("::Rational") { rational }
|
58
|
-
register("::Regexp") { sized { |size| Regexp.new(string.pick(size:
|
90
|
+
register("::Regexp") { sized { |size| Regexp.new(string.pick(size:)) } }
|
59
91
|
register("::String") { string }
|
60
92
|
register("::Struct") { sized { Struct.new(:foo, :bar).new } }
|
61
93
|
register("::Symbol") { symbol }
|
62
|
-
register("::Time") { sized { Time
|
94
|
+
register("::Time") { sized { [:call, Time, :now, [], {}, nil] } }
|
63
95
|
register("::TrueClass") { sized { true } }
|
64
96
|
register("::UnboundMethod") { sized { temp_method_object.unbind } }
|
65
97
|
|
@@ -79,15 +111,18 @@ module RaaP
|
|
79
111
|
|
80
112
|
def sized(&block)
|
81
113
|
Sized.new(&block).tap do |sized|
|
82
|
-
if s = @such_that
|
114
|
+
if (s = @such_that)
|
83
115
|
sized.such_that(&s)
|
84
116
|
end
|
85
117
|
end
|
86
118
|
end
|
87
119
|
|
88
|
-
def pick(size: 10
|
89
|
-
|
90
|
-
|
120
|
+
def pick(size: 10)
|
121
|
+
to_symbolic_caller(size:).eval
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_symbolic_caller(size: 10)
|
125
|
+
SymbolicCaller.new(to_symbolic_call(size:))
|
91
126
|
end
|
92
127
|
|
93
128
|
def to_symbolic_call(size: 10)
|
@@ -96,15 +131,23 @@ module RaaP
|
|
96
131
|
|
97
132
|
case type
|
98
133
|
when ::RBS::Types::Tuple
|
99
|
-
type.types.map { |t| Type.new(t).
|
134
|
+
type.types.map { |t| Type.new(t).to_symbolic_call(size:) }
|
100
135
|
when ::RBS::Types::Union
|
101
|
-
type.types.sample&.then { |t| Type.new(t).
|
136
|
+
type.types.sample&.then { |t| Type.new(t).to_symbolic_call(size:) }
|
102
137
|
when ::RBS::Types::Intersection
|
103
|
-
|
138
|
+
if type.free_variables.empty?
|
139
|
+
[:call, Value::Intersection, :new, [type.to_s], { size: }, nil]
|
140
|
+
else
|
141
|
+
[:call, Value::Intersection, :new, [type], { size: }, nil]
|
142
|
+
end
|
104
143
|
when ::RBS::Types::Interface
|
105
|
-
|
144
|
+
if type.free_variables.empty?
|
145
|
+
[:call, Value::Interface, :new, [type.to_s], { size: }, nil]
|
146
|
+
else
|
147
|
+
[:call, Value::Interface, :new, [type], { size: }, nil]
|
148
|
+
end
|
106
149
|
when ::RBS::Types::Variable
|
107
|
-
[:call, Value::Variable, :new, [type], {}, nil]
|
150
|
+
[:call, Value::Variable, :new, [type.to_s], {}, nil]
|
108
151
|
when ::RBS::Types::Bases::Void
|
109
152
|
[:call, Value::Void, :new, [], {}, nil]
|
110
153
|
when ::RBS::Types::Bases::Top
|
@@ -113,72 +156,52 @@ module RaaP
|
|
113
156
|
[:call, Value::Bottom, :new, [], {}, nil]
|
114
157
|
when ::RBS::Types::Optional
|
115
158
|
case Random.rand(2)
|
116
|
-
in 0 then Type.new(type.type).
|
159
|
+
in 0 then Type.new(type.type).to_symbolic_call(size: size / 2)
|
117
160
|
in 1 then nil
|
118
161
|
end
|
119
162
|
when ::RBS::Types::Alias
|
120
163
|
case gen = GENERATORS[type.name.absolute!.to_s]
|
121
164
|
in Proc then instance_exec(&gen)
|
122
|
-
in nil then Type.new(RBS.builder.expand_alias2(type.name, type.args)).
|
165
|
+
in nil then Type.new(RBS.builder.expand_alias2(type.name, type.args)).to_symbolic_call(size:)
|
123
166
|
end
|
124
167
|
when ::RBS::Types::Bases::Class
|
125
|
-
|
168
|
+
RaaP.logger.warn("Unresolved `class` type, use Object instead.")
|
169
|
+
Object
|
126
170
|
when ::RBS::Types::Bases::Instance
|
127
|
-
|
171
|
+
RaaP.logger.warn("Unresolved `instance` type, use Object.new instead.")
|
172
|
+
Object.new
|
128
173
|
when ::RBS::Types::Bases::Self
|
129
174
|
raise "cannot resolve `self` type"
|
130
175
|
when ::RBS::Types::ClassSingleton
|
131
176
|
Object.const_get(type.name.to_s)
|
132
177
|
when ::RBS::Types::ClassInstance
|
133
178
|
case gen = GENERATORS[type.name.absolute!.to_s]
|
134
|
-
in Proc then instance_exec(&gen).pick(size:
|
135
|
-
in nil then
|
179
|
+
in Proc then instance_exec(&gen).pick(size:)
|
180
|
+
in nil then to_symbolic_call_from_initialize(type, size:)
|
136
181
|
end
|
137
182
|
when ::RBS::Types::Record
|
138
|
-
type.fields.transform_values { |t| Type.new(t).
|
183
|
+
type.fields.transform_values { |t| Type.new(t).to_symbolic_call(size: size / 2) }
|
139
184
|
when ::RBS::Types::Proc
|
140
|
-
Proc.new { Type.new(type.type.return_type).
|
185
|
+
Proc.new { Type.new(type.type.return_type).to_symbolic_call(size:) }
|
141
186
|
when ::RBS::Types::Literal
|
142
187
|
type.literal
|
143
188
|
when ::RBS::Types::Bases::Bool
|
144
|
-
bool.pick(size:
|
189
|
+
bool.pick(size:)
|
145
190
|
when ::RBS::Types::Bases::Any
|
146
|
-
|
191
|
+
Type.random.to_symbolic_call(size:)
|
147
192
|
when ::RBS::Types::Bases::Nil
|
148
193
|
nil
|
149
194
|
else
|
150
|
-
raise "not implemented #{type
|
195
|
+
raise "not implemented #{type}"
|
151
196
|
end
|
152
197
|
end
|
153
198
|
|
154
199
|
private
|
155
200
|
|
156
|
-
def
|
201
|
+
def to_symbolic_call_from_initialize(type, size:)
|
157
202
|
type_name = type.name.absolute!
|
158
203
|
const = Object.const_get(type_name.to_s)
|
159
|
-
|
160
|
-
snew = definition.methods[:new]
|
161
|
-
if snew
|
162
|
-
# class
|
163
|
-
rbs_method_type = snew.method_types.sample or raise
|
164
|
-
type_params = definition.type_params_decl.concat(rbs_method_type.type_params.drop(definition.type_params_decl.length))
|
165
|
-
ts = TypeSubstitution.new(type_params, type.args)
|
166
|
-
maped_rbs_method_type = rbs_method_type
|
167
|
-
maped_rbs_method_type = ts.method_type_sub(rbs_method_type)
|
168
|
-
method_type = MethodType.new(maped_rbs_method_type)
|
169
|
-
|
170
|
-
begin
|
171
|
-
try(times: 5, size: size) do |size|
|
172
|
-
args, kwargs, block = method_type.pick_arguments(size: size, eval: false)
|
173
|
-
[:call, const, :new, args, kwargs, block]
|
174
|
-
end
|
175
|
-
rescue
|
176
|
-
$stderr.puts "Fail with `#{rbs_method_type}`"
|
177
|
-
raise
|
178
|
-
end
|
179
|
-
else
|
180
|
-
[:call, Value::Module, :new, [type], {}, nil]
|
181
|
-
end
|
204
|
+
Type.call_new_from(const, type, size:)
|
182
205
|
end
|
183
206
|
|
184
207
|
def parse(type)
|
@@ -192,33 +215,8 @@ module RaaP
|
|
192
215
|
end
|
193
216
|
end
|
194
217
|
|
195
|
-
def try(times:, size:)
|
196
|
-
# @type var error: Exception?
|
197
|
-
ret = error = nil
|
198
|
-
times.times do
|
199
|
-
ret = yield size
|
200
|
-
if ret
|
201
|
-
error = nil
|
202
|
-
break
|
203
|
-
end
|
204
|
-
rescue => e
|
205
|
-
size += 1
|
206
|
-
error = e
|
207
|
-
next
|
208
|
-
end
|
209
|
-
|
210
|
-
if error
|
211
|
-
$stderr.puts
|
212
|
-
$stderr.puts "=== Catch error when generating type `#{type}`. Please check your RBS or RaaP bug. ==="
|
213
|
-
$stderr.puts "(#{error.class}) #{error.message}"
|
214
|
-
raise error
|
215
|
-
end
|
216
|
-
|
217
|
-
ret
|
218
|
-
end
|
219
|
-
|
220
218
|
def integer
|
221
|
-
sized { |size| float.pick(size:
|
219
|
+
sized { |size| float.pick(size:).round }
|
222
220
|
end
|
223
221
|
|
224
222
|
def none_zero_integer
|
@@ -231,9 +229,9 @@ module RaaP
|
|
231
229
|
in nil, nil
|
232
230
|
Arithmetic.float * size
|
233
231
|
in nil, high
|
234
|
-
high - Arithmetic.positive_float * size
|
232
|
+
high - (Arithmetic.positive_float * size)
|
235
233
|
in low, nil
|
236
|
-
low + Arithmetic.positive_float * size
|
234
|
+
low + (Arithmetic.positive_float * size)
|
237
235
|
in low, high
|
238
236
|
Random.rand(Range.new(low.to_f, high.to_f, @range.exclude_end?))
|
239
237
|
end.round(2)
|
@@ -242,16 +240,16 @@ module RaaP
|
|
242
240
|
|
243
241
|
def rational
|
244
242
|
sized do |size|
|
245
|
-
a = integer.pick(size:
|
246
|
-
b = none_zero_integer.pick(size:
|
243
|
+
a = integer.pick(size:)
|
244
|
+
b = none_zero_integer.pick(size:)
|
247
245
|
[:call, Kernel, :Rational, [a, b], {}, nil]
|
248
246
|
end
|
249
247
|
end
|
250
248
|
|
251
249
|
def complex
|
252
250
|
sized do |size|
|
253
|
-
a = integer.pick(size:
|
254
|
-
b = none_zero_integer.pick(size:
|
251
|
+
a = integer.pick(size:)
|
252
|
+
b = none_zero_integer.pick(size:)
|
255
253
|
[:call, Kernel, :Complex, [a, b], {}, nil]
|
256
254
|
end
|
257
255
|
end
|
@@ -262,13 +260,11 @@ module RaaP
|
|
262
260
|
+""
|
263
261
|
else
|
264
262
|
case [@range.begin, @range.end]
|
265
|
-
in nil, nil
|
263
|
+
in [nil, nil]
|
266
264
|
size.times.map { SIMPLE_SOURCE.sample }.join
|
267
|
-
in nil, _
|
268
|
-
raise "Should set range.begin and range.end"
|
269
|
-
in _, nil
|
265
|
+
in [nil, _] | [_, nil]
|
270
266
|
raise "Should set range.begin and range.end"
|
271
|
-
in s, e
|
267
|
+
in [s, e]
|
272
268
|
a = (s..e).to_a
|
273
269
|
size.times.map { a.sample }.join
|
274
270
|
end
|
@@ -278,14 +274,28 @@ module RaaP
|
|
278
274
|
|
279
275
|
def symbol
|
280
276
|
sized do |size|
|
281
|
-
string.pick(size:
|
277
|
+
string.pick(size:).to_sym
|
282
278
|
end
|
283
279
|
end
|
284
280
|
|
285
281
|
def array(type)
|
286
282
|
sized do |size|
|
287
|
-
Array.new(integer.pick(size:
|
288
|
-
type.
|
283
|
+
Array.new(integer.pick(size:).abs) do
|
284
|
+
type.to_symbolic_call(size: size / 2)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Create Hash object. But not `hash`.
|
290
|
+
# Avoid to use `hash` since core method name
|
291
|
+
def dict(key_type, value_type)
|
292
|
+
sized do |size|
|
293
|
+
csize = size / 2
|
294
|
+
Array.new(integer.pick(size:).abs).to_h do
|
295
|
+
[
|
296
|
+
key_type.to_symbolic_call(size: csize),
|
297
|
+
value_type.to_symbolic_call(size: csize)
|
298
|
+
]
|
289
299
|
end
|
290
300
|
end
|
291
301
|
end
|
@@ -293,7 +303,7 @@ module RaaP
|
|
293
303
|
def encoding
|
294
304
|
sized do
|
295
305
|
e = Encoding.list.sample or raise
|
296
|
-
[:call, Encoding, :find, [e.name], {}
|
306
|
+
[:call, Encoding, :find, [e.name], {}, nil]
|
297
307
|
end
|
298
308
|
end
|
299
309
|
|
@@ -303,24 +313,10 @@ module RaaP
|
|
303
313
|
end
|
304
314
|
end
|
305
315
|
|
306
|
-
def untyped
|
307
|
-
case Random.rand(9)
|
308
|
-
in 0 then integer
|
309
|
-
in 1 then float
|
310
|
-
in 2 then rational
|
311
|
-
in 3 then complex
|
312
|
-
in 4 then string
|
313
|
-
in 5 then symbol
|
314
|
-
in 6 then bool
|
315
|
-
in 7 then encoding
|
316
|
-
in 8 then sized { [:call, BasicObject, :new, [], {}, nil] }
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
316
|
def temp_method_object
|
321
317
|
o = Object.new
|
322
318
|
m = 6.times.map { SIMPLE_SOURCE.sample }.join
|
323
|
-
o.define_singleton_method(m) {
|
319
|
+
o.define_singleton_method(m) {}
|
324
320
|
o.method(m)
|
325
321
|
end
|
326
322
|
end
|
@@ -14,13 +14,16 @@ module RaaP
|
|
14
14
|
elsif bound.upper_bound
|
15
15
|
[bound.name, bound.upper_bound]
|
16
16
|
else
|
17
|
-
[bound.name, ::RBS::Types::
|
17
|
+
[bound.name, ::RBS::Types::Variable.new(name: bound.name, location: nil)]
|
18
18
|
end
|
19
19
|
end
|
20
20
|
::RBS::Substitution.build(bound_map.keys, bound_map.values)
|
21
21
|
end
|
22
22
|
|
23
23
|
def method_type_sub(method_type, self_type: nil, instance_type: nil, class_type: nil)
|
24
|
+
self_type = self_type.is_a?(::String) ? RBS.parse_type(self_type) : self_type
|
25
|
+
instance_type = instance_type.is_a?(::String) ? RBS.parse_type(instance_type) : instance_type
|
26
|
+
class_type = class_type.is_a?(::String) ? RBS.parse_type(class_type) : class_type
|
24
27
|
sub = build
|
25
28
|
::RBS::MethodType.new(
|
26
29
|
type_params: [],
|
@@ -36,6 +39,7 @@ module RaaP
|
|
36
39
|
if self_type.nil? && instance_type.nil? && class_type.nil?
|
37
40
|
return search
|
38
41
|
end
|
42
|
+
|
39
43
|
search.map_type do |ty|
|
40
44
|
case ty
|
41
45
|
when ::RBS::Types::Bases::Self
|
data/lib/raap/value/bottom.rb
CHANGED
data/lib/raap/value/interface.rb
CHANGED
@@ -3,39 +3,73 @@
|
|
3
3
|
module RaaP
|
4
4
|
module Value
|
5
5
|
class Interface < BasicObject
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class << self
|
7
|
+
def define_method_from_interface(base_class, type, size: 3)
|
8
|
+
type = type.is_a?(::String) ? RBS.parse_type(type) : type
|
9
|
+
unless type.instance_of?(::RBS::Types::Interface)
|
10
|
+
::Kernel.raise ::TypeError, "not an interface type: #{type}"
|
11
|
+
end
|
12
|
+
self_type = type
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
type_params = definition.type_params_decl.concat(method_type.type_params.drop(definition.type_params_decl.length))
|
14
|
-
ts = TypeSubstitution.new(type_params, @type.args)
|
14
|
+
# Referring to Steep
|
15
|
+
instance_type = ::RBS::Types::ClassInstance.new(name: TypeName("::Object"), args: [], location: nil)
|
16
|
+
class_type = ::RBS::Types::ClassSingleton.new(name: TypeName("::Object"), location: nil)
|
15
17
|
|
16
|
-
|
18
|
+
definition = RBS.builder.build_interface(type.name.absolute!)
|
19
|
+
definition.methods.each do |name, method|
|
20
|
+
method_type = method.method_types.sample or ::Kernel.raise
|
21
|
+
type_params = definition.type_params_decl.concat(method_type.type_params.drop(definition.type_params_decl.length))
|
22
|
+
ts = TypeSubstitution.new(type_params, type.args)
|
23
|
+
subed_method_type = ts.method_type_sub(method_type, self_type:, instance_type:, class_type:)
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
BindCall.define_method(base_class, name) do |*_, &b|
|
26
|
+
@fixed_return_value ||= {}
|
27
|
+
@fixed_return_value[name] ||= if self_type == subed_method_type.type.return_type
|
28
|
+
self
|
29
|
+
else
|
30
|
+
Type.new(subed_method_type.type.return_type).pick(size:)
|
31
|
+
end
|
32
|
+
# @type var b: Proc?
|
33
|
+
if b
|
34
|
+
@fixed_block_arguments ||= {}
|
35
|
+
@fixed_block_arguments[name] ||= if subed_method_type.block
|
36
|
+
size.times.map do
|
37
|
+
FunctionType.new(subed_method_type.block.type)
|
38
|
+
.pick_arguments(size:)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
[]
|
42
|
+
end
|
43
|
+
@fixed_block_arguments[name].each do |a, kw|
|
44
|
+
b.call(*a, **kw)
|
45
|
+
end
|
34
46
|
end
|
47
|
+
@fixed_return_value[name]
|
35
48
|
end
|
36
|
-
@fixed_return_value
|
37
49
|
end
|
38
50
|
end
|
51
|
+
|
52
|
+
def new(type, size: 3)
|
53
|
+
temp_class = ::Class.new(Interface) do |c|
|
54
|
+
define_method_from_interface(c, type, size:)
|
55
|
+
end
|
56
|
+
instance = temp_class.allocate
|
57
|
+
instance.__send__(:initialize, type, size:)
|
58
|
+
instance
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize(type, size: 3)
|
63
|
+
@type = type.is_a?(::String) ? RBS.parse_type(type) : type
|
64
|
+
unless @type.instance_of?(::RBS::Types::Interface)
|
65
|
+
::Kernel.raise ::TypeError, "not an interface type: #{type}"
|
66
|
+
end
|
67
|
+
@definition = RBS.builder.build_interface(@type.name.absolute!)
|
68
|
+
@size = size
|
69
|
+
end
|
70
|
+
|
71
|
+
def respond_to?(name, _include_all = false)
|
72
|
+
@definition.methods.has_key?(name.to_sym)
|
39
73
|
end
|
40
74
|
|
41
75
|
def class
|
@@ -43,7 +77,7 @@ module RaaP
|
|
43
77
|
end
|
44
78
|
|
45
79
|
def inspect
|
46
|
-
"#<interface @type
|
80
|
+
"#<interface @type=`#{@type}` @methods=#{@definition.methods.keys} @size=#{@size}>"
|
47
81
|
end
|
48
82
|
end
|
49
83
|
end
|
@@ -2,33 +2,38 @@
|
|
2
2
|
|
3
3
|
module RaaP
|
4
4
|
module Value
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
module Intersection
|
6
|
+
# Build an object to realize an intersection.
|
7
|
+
def self.new(type, size: 3)
|
8
|
+
type = type.is_a?(::String) ? RBS.parse_type(type) : type
|
9
|
+
unless type.instance_of?(::RBS::Types::Intersection)
|
10
|
+
::Kernel.raise ::TypeError, "not an intersection type: #{type}"
|
11
|
+
end
|
12
|
+
instances = type.types.filter_map do |t|
|
13
|
+
t.instance_of?(::RBS::Types::ClassInstance) && Object.const_get(t.name.absolute!.to_s)
|
14
|
+
end
|
15
|
+
instances.uniq!
|
16
|
+
unless instances.count { |c| c.is_a?(::Class) } <= 1
|
17
|
+
raise ArgumentError, "intersection type must have at least one class instance type in `#{instances}`"
|
18
|
+
end
|
11
19
|
|
12
|
-
|
13
|
-
"#<intersection @type=#{@type.to_s.inspect} @size=#{@size.inspect}>"
|
14
|
-
end
|
20
|
+
base = instances.find { |c| c.is_a?(::Class) } || BasicObject
|
15
21
|
|
16
|
-
|
17
|
-
|
18
|
-
|
22
|
+
c = Class.new(base) do
|
23
|
+
instances.select { |i| !i.is_a?(::Class) }.each do |m|
|
24
|
+
include(m)
|
25
|
+
end
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
if BindCall.respond_to?(child, name)
|
23
|
-
return child.__send__(name, *args, **kwargs, &block)
|
27
|
+
interfaces = type.types.select do |t|
|
28
|
+
t.instance_of?(::RBS::Types::Interface)
|
24
29
|
end
|
25
|
-
end
|
26
|
-
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
interfaces.each do |interface|
|
32
|
+
Interface.define_method_from_interface(self, interface, size:)
|
33
|
+
end
|
31
34
|
end
|
35
|
+
type = ::RBS::Types::ClassInstance.new(name: TypeName(base.name), args: [], location: nil)
|
36
|
+
SymbolicCaller.new(Type.call_new_from(c, type, size:)).eval
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|
data/lib/raap/value/module.rb
CHANGED
@@ -1,17 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RaaP
|
2
4
|
module Value
|
3
5
|
# FIXME: consider self_types
|
4
6
|
# HINT: intersection?
|
5
|
-
class Module
|
6
|
-
|
7
|
+
class Module < BasicObject
|
8
|
+
def initialize(type, size: 3)
|
9
|
+
@type = type.is_a?(::String) ? ::RaaP::RBS.parse_type(type) : type
|
10
|
+
@size = size
|
11
|
+
unless @type.instance_of?(::RBS::Types::ClassInstance)
|
12
|
+
::Kernel.raise ::TypeError, "not a module type: #{@type}"
|
13
|
+
end
|
14
|
+
|
15
|
+
one_instance_ancestors = ::RaaP::RBS.builder.ancestor_builder.one_instance_ancestors(@type.name.absolute!).self_types
|
16
|
+
@self_type = if one_instance_ancestors.nil? || one_instance_ancestors.empty?
|
17
|
+
::Object.new
|
18
|
+
else
|
19
|
+
one_instance_ancestors.map do |a_instance|
|
20
|
+
if a_instance.args.empty?
|
21
|
+
# : BasicObject
|
22
|
+
a_instance.name.absolute!.to_s
|
23
|
+
else
|
24
|
+
# : _Each[Integer]
|
25
|
+
args = a_instance.args.zip(@type.args).map do |_var, instance|
|
26
|
+
if instance
|
27
|
+
instance.to_s
|
28
|
+
else
|
29
|
+
'untyped'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
"#{a_instance.name}[#{args.map(&:to_s).join(', ')}]"
|
33
|
+
end
|
34
|
+
end.then do |ts|
|
35
|
+
if !ts.include?('::BasicObject') || ts.any? { |t| t.split('::').last&.start_with?('_') }
|
36
|
+
ts.unshift('Object')
|
37
|
+
end
|
38
|
+
Type.new(ts.uniq.join(' & ')).pick(size:)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
const = ::Object.const_get(@type.name.absolute!.to_s)
|
42
|
+
BindCall.extend(self, const)
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(name, *args, **kwargs, &block)
|
46
|
+
@self_type.__send__(name, *args, **kwargs, &block)
|
47
|
+
end
|
7
48
|
|
8
|
-
def
|
9
|
-
@
|
10
|
-
|
11
|
-
|
49
|
+
def respond_to?(name, include_all = false)
|
50
|
+
if BindCall.instance_of?(@self_type, ::BasicObject)
|
51
|
+
BindCall.respond_to?(@self_type, name, include_all)
|
52
|
+
else
|
53
|
+
@self_type.respond_to?(name, include_all)
|
54
|
+
end
|
12
55
|
end
|
13
56
|
|
14
|
-
def inspect = "#<module #{@type}>"
|
57
|
+
def inspect = "#<module #{@type} : #{BindCall.class(@self_type)} size=#{@size}>"
|
15
58
|
def class = Value::Module
|
16
59
|
end
|
17
60
|
end
|