7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# File 'lib/raap/value/interface.rb', line 7
def define_method_from_interface(base_mod, type, size: 3)
type = type.is_a?(::String) ? RBS.parse_type(type) : type
unless type.instance_of?(::RBS::Types::Interface)
::Kernel.raise ::TypeError, "not an interface type: #{type}"
end
self_type = type
instance_type = ::RBS::Types::ClassInstance.new(name: TypeName("::Object"), args: [], location: nil)
class_type = ::RBS::Types::ClassSingleton.new(name: TypeName("::Object"), location: nil)
definition = RBS.builder.build_interface(type.name.absolute!)
definition.methods.each do |name, method|
method_type = method.method_types.sample or ::Kernel.raise
type_params = definition.type_params_decl.concat(method_type.type_params.drop(definition.type_params_decl.length))
ts = TypeSubstitution.new(type_params, type.args)
subed_method_type = ts.method_type_sub(method_type, self_type: self_type, instance_type: instance_type, class_type: class_type)
BindCall.define_method(base_mod, name) do |*_, &b|
@fixed_return_value ||= {}
@fixed_return_value[name] ||= if self_type == subed_method_type.type.return_type
self
else
Type.new(subed_method_type.type.return_type).pick(size: size)
end
if b && subed_method_type.block && subed_method_type.block.type.is_a?(::RBS::Types::Function)
@fixed_block_arguments ||= {}
@fixed_block_arguments[name] ||= size.times.map do
FunctionType.new(subed_method_type.block.type, coverage: false)
.pick_arguments(size: size)
end
@fixed_block_arguments[name].each do |a, kw|
b.call(*a, **kw)
end
end
@fixed_return_value[name]
end
end
end
|