Class: RaaP::Value::Interface

Inherits:
Object
  • Object
show all
Defined in:
lib/raap/value/interface.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, size: 3) ⇒ Interface

Returns a new instance of Interface.



59
60
61
62
63
64
65
66
# File 'lib/raap/value/interface.rb', line 59

def initialize(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
  @definition = RBS.builder.build_interface(@type.name.absolute!)
  @size = size
end

Class Method Details

.define_method_from_interface(base_mod, type, size: 3) ⇒ Object



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

  # Referring to Steep
  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
      # @type var b: Proc?
      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

.new(type, size: 3) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/raap/value/interface.rb', line 49

def new(type, size: 3)
  temp_class = ::Class.new(Interface) do |c|
    define_method_from_interface(c, type, size: size)
  end
  instance = temp_class.allocate
  instance.__send__(:initialize, type, size: size)
  instance
end

Instance Method Details

#inspectObject



68
69
70
# File 'lib/raap/value/interface.rb', line 68

def inspect
  "#<interface @type=`#{@type}` @methods=#{@definition.methods.keys} @size=#{@size}>"
end