raap 0.1.0 → 0.3.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/README.md +56 -4
- data/lib/raap/bind_call.rb +1 -0
- data/lib/raap/cli.rb +34 -8
- data/lib/raap/method_property.rb +36 -38
- data/lib/raap/method_type.rb +13 -0
- data/lib/raap/minitest.rb +35 -0
- data/lib/raap/result.rb +10 -5
- data/lib/raap/symbolic_caller.rb +74 -28
- data/lib/raap/type.rb +46 -29
- data/lib/raap/value/module.rb +3 -2
- data/lib/raap/version.rb +1 -1
- data/lib/raap.rb +2 -2
- data/sig/raap.rbs +72 -70
- metadata +3 -3
- data/lib/raap/method_value.rb +0 -38
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 507ed156280ed3e0db1f2eb454bb03c57aa473d537d8c6ea5905ad852eba550d
         | 
| 4 | 
            +
              data.tar.gz: 3108fa50c664702f79141a3c0b5e83934d6742468d1d51bfb2febb5b64a00b12
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 269e220d72b9861881de860a71a2adff318105595880fe73e86492e255c9bb32fbeff7ac3685b83ea11d792a02b1509eb969d9956483a9415608530a3f8806bd
         | 
| 7 | 
            +
              data.tar.gz: df4e40973681eb292d7844aa5ed1427b7155f619c6ebea53792149f430ab28e42a0a0f52df9517a3af9af1e08494eaccdd8d4d84313c9d24184f6403a51e1dc5
         | 
    
        data/README.md
    CHANGED
    
    | @@ -12,17 +12,54 @@ The return value of the method is checked to see if it matches the type, if not, | |
| 12 12 |  | 
| 13 13 | 
             
            If you write an RBS, it becomes a test case.
         | 
| 14 14 |  | 
| 15 | 
            -
            ##  | 
| 15 | 
            +
            ## Concept
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            If you has next signature.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ```rbs
         | 
| 20 | 
            +
            class Foo
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            class Bar
         | 
| 24 | 
            +
              def initialize: (foo: Foo) -> void
         | 
| 25 | 
            +
              def f2s: (Float) -> String
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
            ```
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Then, RaaP run next testing code automaticaly.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            ```rb
         | 
| 32 | 
            +
            describe Bar do
         | 
| 33 | 
            +
              let(:foo) { Foo.new }
         | 
| 34 | 
            +
              let(:bar) { Bar.new(foo: foo) }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it "#f2s" do
         | 
| 37 | 
            +
                100.times do |size|
         | 
| 38 | 
            +
                  float = Random.rand * size
         | 
| 39 | 
            +
                  expect(bar.f2s(float)).to be_a(String)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
            ```
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            If you got a failure?
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            - Fix RBS
         | 
| 48 | 
            +
            - Fix implementation of `Bar#f2s`
         | 
| 16 49 |  | 
| 17 | 
            -
             | 
| 50 | 
            +
            Then, you can start loop again.
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            Finally, you get the perfect RBS!
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            ## Installation
         | 
| 18 55 |  | 
| 19 56 | 
             
            Install the gem and add to the application's Gemfile by executing:
         | 
| 20 57 |  | 
| 21 | 
            -
                $ bundle add  | 
| 58 | 
            +
                $ bundle add raap
         | 
| 22 59 |  | 
| 23 60 | 
             
            If bundler is not being used to manage dependencies, install the gem by executing:
         | 
| 24 61 |  | 
| 25 | 
            -
                $ gem install  | 
| 62 | 
            +
                $ gem install raap
         | 
| 26 63 |  | 
| 27 64 | 
             
            ## Usage
         | 
| 28 65 |  | 
| @@ -41,6 +78,21 @@ For example, an Integer with size zero is `0` and an Array is `[]`. | |
| 41 78 |  | 
| 42 79 | 
             
            RaaP, like other property-based tests, changes the size 100 times from 0 to 99 by default to generate test data.
         | 
| 43 80 |  | 
| 81 | 
            +
            ## Symbolic call
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            You may possibly see the following data structure in the debug logs.
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            ```rb
         | 
| 86 | 
            +
            [:call, Object, :method, [], {}, nil]
         | 
| 87 | 
            +
            ```
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            This is a data structure of the state of the method call.
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            Symbolic call is a tuple beginning with `:call`, followed by the receiver, method name, positional arguments, keyword arguments, and block arguments, in that order.
         | 
| 92 | 
            +
            And the receiver and arguments are nestable.
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            It is used in QuickCheck and Proper to keep as much history of method calls as possible.
         | 
| 95 | 
            +
             | 
| 44 96 | 
             
            ## Options
         | 
| 45 97 |  | 
| 46 98 | 
             
            ### `-I PATH` or `--include PATH`
         | 
    
        data/lib/raap/bind_call.rb
    CHANGED
    
    | @@ -8,6 +8,7 @@ module RaaP | |
| 8 8 | 
             
                  def extend(...) = ::Kernel.instance_method(:extend).bind_call(...)
         | 
| 9 9 | 
             
                  def name(...) = ::Module.instance_method(:name).bind_call(...)
         | 
| 10 10 | 
             
                  def to_s(...) = ::Kernel.instance_method(:to_s).bind_call(...)
         | 
| 11 | 
            +
                  def public_send(...) = ::Kernel.instance_method(:public_send).bind_call(...)
         | 
| 11 12 |  | 
| 12 13 | 
             
                  def class(obj)
         | 
| 13 14 | 
             
                    if respond_to?(obj, :class)
         | 
    
        data/lib/raap/cli.rb
    CHANGED
    
    | @@ -16,6 +16,7 @@ module RaaP | |
| 16 16 | 
             
                  :size_from,
         | 
| 17 17 | 
             
                  :size_to,
         | 
| 18 18 | 
             
                  :size_by,
         | 
| 19 | 
            +
                  :allow_private,
         | 
| 19 20 | 
             
                  keyword_init: true
         | 
| 20 21 | 
             
                )
         | 
| 21 22 |  | 
| @@ -28,6 +29,7 @@ module RaaP | |
| 28 29 | 
             
                  size_from: 0,
         | 
| 29 30 | 
             
                  size_to: 99,
         | 
| 30 31 | 
             
                  size_by: 1,
         | 
| 32 | 
            +
                  allow_private: false,
         | 
| 31 33 | 
             
                )
         | 
| 32 34 |  | 
| 33 35 | 
             
                def initialize(argv)
         | 
| @@ -60,6 +62,9 @@ module RaaP | |
| 60 62 | 
             
                    o.on('--size-by int', Integer, "default: #{CLI.option.size_by}") do |arg|
         | 
| 61 63 | 
             
                      CLI.option.size_by = arg
         | 
| 62 64 | 
             
                    end
         | 
| 65 | 
            +
                    o.on('--allow-private', "default: #{CLI.option.allow_private}") do
         | 
| 66 | 
            +
                      CLI.option.allow_private = true
         | 
| 67 | 
            +
                    end
         | 
| 63 68 | 
             
                  end.parse!(@argv)
         | 
| 64 69 |  | 
| 65 70 | 
             
                  CLI.option.dirs.each do |dir|
         | 
| @@ -103,7 +108,11 @@ module RaaP | |
| 103 108 |  | 
| 104 109 | 
             
                def run_by_instance(tag:)
         | 
| 105 110 | 
             
                  t, m = tag.split('#', 2)
         | 
| 111 | 
            +
                  t or raise
         | 
| 112 | 
            +
                  m or raise
         | 
| 106 113 | 
             
                  type = RBS.parse_type(t)
         | 
| 114 | 
            +
                  type = __skip__ = type
         | 
| 115 | 
            +
                  raise "cannot specified #{type}" unless type.respond_to?(:name)
         | 
| 107 116 | 
             
                  receiver_type = Type.new(type.to_s)
         | 
| 108 117 | 
             
                  method_name = m.to_sym
         | 
| 109 118 | 
             
                  definition = RBS.builder.build_instance(type.name)
         | 
| @@ -121,7 +130,11 @@ module RaaP | |
| 121 130 |  | 
| 122 131 | 
             
                def run_by_singleton(tag:)
         | 
| 123 132 | 
             
                  t, m = tag.split('.', 2)
         | 
| 133 | 
            +
                  t or raise
         | 
| 134 | 
            +
                  m or raise
         | 
| 124 135 | 
             
                  type = RBS.parse_type(t)
         | 
| 136 | 
            +
                  raise "cannot specified #{type.class}" unless type.respond_to?(:name)
         | 
| 137 | 
            +
                  type = __skip__ = type
         | 
| 125 138 | 
             
                  receiver_type = Type.new("singleton(#{type.name})")
         | 
| 126 139 | 
             
                  method_name = m.to_sym
         | 
| 127 140 | 
             
                  definition = RBS.builder.build_singleton(type.name)
         | 
| @@ -150,6 +163,8 @@ module RaaP | |
| 150 163 |  | 
| 151 164 | 
             
                def run_by_type_name(tag:)
         | 
| 152 165 | 
             
                  type = RBS.parse_type(tag)
         | 
| 166 | 
            +
                  type = __skip__ = type
         | 
| 167 | 
            +
                  raise "cannot specified #{type.class}" unless type.respond_to?(:name)
         | 
| 153 168 | 
             
                  type_name = type.name.absolute!
         | 
| 154 169 |  | 
| 155 170 | 
             
                  ret = []
         | 
| @@ -157,6 +172,7 @@ module RaaP | |
| 157 172 | 
             
                  definition = RBS.builder.build_singleton(type_name)
         | 
| 158 173 | 
             
                  type_params_decl = definition.type_params_decl
         | 
| 159 174 | 
             
                  definition.methods.filter_map do |method_name, method|
         | 
| 175 | 
            +
                    next unless method.accessibility == :public
         | 
| 160 176 | 
             
                    next if method.defined_in != type_name
         | 
| 161 177 | 
             
                    next if method_name == :fork || method_name == :spawn # TODO: skip solution
         | 
| 162 178 | 
             
                    puts "# #{type_name}.#{method_name}"
         | 
| @@ -169,6 +185,7 @@ module RaaP | |
| 169 185 | 
             
                  definition = RBS.builder.build_instance(type_name)
         | 
| 170 186 | 
             
                  type_params_decl = definition.type_params_decl
         | 
| 171 187 | 
             
                  definition.methods.filter_map do |method_name, method|
         | 
| 188 | 
            +
                    next unless method.accessibility == :public
         | 
| 172 189 | 
             
                    next if method.defined_in != type_name
         | 
| 173 190 | 
             
                    next if method_name == :fork || method_name == :spawn # TODO: skip solution
         | 
| 174 191 | 
             
                    puts "# #{type_name}##{method_name}"
         | 
| @@ -182,12 +199,13 @@ module RaaP | |
| 182 199 | 
             
                end
         | 
| 183 200 |  | 
| 184 201 | 
             
                def property(receiver_type:, type_params_decl:, method_type:, method_name:)
         | 
| 202 | 
            +
                  rtype = __skip__ = receiver_type.type
         | 
| 185 203 | 
             
                  if receiver_type.type.instance_of?(::RBS::Types::ClassSingleton)
         | 
| 186 204 | 
             
                    prefix = 'self.'
         | 
| 187 205 | 
             
                    type_args = []
         | 
| 188 206 | 
             
                  else
         | 
| 189 207 | 
             
                    prefix = ''
         | 
| 190 | 
            -
                    type_args =  | 
| 208 | 
            +
                    type_args = rtype.args
         | 
| 191 209 | 
             
                  end
         | 
| 192 210 | 
             
                  puts "## def #{prefix}#{method_name}: #{method_type}"
         | 
| 193 211 | 
             
                  status = 0
         | 
| @@ -198,23 +216,27 @@ module RaaP | |
| 198 216 | 
             
                      method_type,
         | 
| 199 217 | 
             
                      type_params_decl:,
         | 
| 200 218 | 
             
                      type_args:,
         | 
| 201 | 
            -
                      self_type:  | 
| 202 | 
            -
                      instance_type: ::RBS::Types::ClassInstance.new(name:  | 
| 203 | 
            -
                      class_type: ::RBS::Types::ClassSingleton.new(name:  | 
| 219 | 
            +
                      self_type: rtype,
         | 
| 220 | 
            +
                      instance_type: ::RBS::Types::ClassInstance.new(name: rtype.name, args: type_args, location: nil),
         | 
| 221 | 
            +
                      class_type: ::RBS::Types::ClassSingleton.new(name: rtype.name, location: nil),
         | 
| 204 222 | 
             
                    ),
         | 
| 205 223 | 
             
                    size_step: CLI.option.size_from.step(to: CLI.option.size_to, by: CLI.option.size_by),
         | 
| 206 224 | 
             
                    timeout: CLI.option.timeout,
         | 
| 225 | 
            +
                    allow_private: true,
         | 
| 207 226 | 
             
                  ).run do |called|
         | 
| 208 227 | 
             
                    case called
         | 
| 209 228 | 
             
                    in Result::Success => s
         | 
| 210 | 
            -
                      RaaP.logger.debug { "Success: #{s.called_str}" }
         | 
| 211 229 | 
             
                      print '.'
         | 
| 230 | 
            +
                      RaaP.logger.debug { "Success: #{s.called_str}" }
         | 
| 212 231 | 
             
                    in Result::Failure => f
         | 
| 213 232 | 
             
                      puts 'F'
         | 
| 214 233 | 
             
                      puts "Failed in case of `#{f.called_str}`"
         | 
| 234 | 
            +
                      if e = f.exception
         | 
| 235 | 
            +
                        RaaP.logger.debug { "Failure: [#{e.class}] #{e.message}" }
         | 
| 236 | 
            +
                      end
         | 
| 215 237 | 
             
                      puts
         | 
| 216 238 | 
             
                      RaaP.logger.debug { PP.pp(f.symbolic_call, ''.dup) }
         | 
| 217 | 
            -
                      puts " | 
| 239 | 
            +
                      puts "### call stack:"
         | 
| 218 240 | 
             
                      puts
         | 
| 219 241 | 
             
                      puts "```"
         | 
| 220 242 | 
             
                      puts SymbolicCaller.new(f.symbolic_call).to_lines.join("\n")
         | 
| @@ -223,10 +245,14 @@ module RaaP | |
| 223 245 | 
             
                      throw :break
         | 
| 224 246 | 
             
                    in Result::Skip => s
         | 
| 225 247 | 
             
                      print 'S'
         | 
| 248 | 
            +
                      RaaP.logger.debug { PP.pp(s.symbolic_call, ''.dup) }
         | 
| 249 | 
            +
                      RaaP.logger.debug("Skip: [#{s.exception.class}] #{s.exception.message}")
         | 
| 250 | 
            +
                      RaaP.logger.debug(s.exception.backtrace.join("\n"))
         | 
| 226 251 | 
             
                    in Result::Exception => e
         | 
| 227 | 
            -
                      RaaP.logger.info("#{e.exception.class}: #{e.exception.message}")
         | 
| 228 | 
            -
                      RaaP.logger.debug(e.exception.backtrace.join("\n"))
         | 
| 229 252 | 
             
                      print 'E'
         | 
| 253 | 
            +
                      RaaP.logger.debug { PP.pp(e.symbolic_call, ''.dup) }
         | 
| 254 | 
            +
                      RaaP.logger.debug("Exception: [#{e.exception.class}] #{e.exception.message}")
         | 
| 255 | 
            +
                      RaaP.logger.debug(e.exception.backtrace.join("\n"))
         | 
| 230 256 | 
             
                    end
         | 
| 231 257 | 
             
                  end
         | 
| 232 258 | 
             
                  puts
         | 
    
        data/lib/raap/method_property.rb
    CHANGED
    
    | @@ -8,25 +8,17 @@ module RaaP | |
| 8 8 | 
             
                  end
         | 
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 | 
            -
                 | 
| 12 | 
            -
                attr_reader :method_name
         | 
| 13 | 
            -
                attr_reader :method_type
         | 
| 14 | 
            -
                attr_reader :size_step
         | 
| 15 | 
            -
                attr_reader :timeout
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                def initialize(receiver_type:, method_name:, method_type:, size_step:, timeout:)
         | 
| 11 | 
            +
                def initialize(receiver_type:, method_name:, method_type:, size_step:, timeout:, allow_private: false)
         | 
| 18 12 | 
             
                  @receiver_type = receiver_type
         | 
| 19 13 | 
             
                  @method_name = method_name
         | 
| 20 14 | 
             
                  @method_type = method_type
         | 
| 21 15 | 
             
                  @size_step = size_step
         | 
| 22 16 | 
             
                  @timeout = timeout
         | 
| 17 | 
            +
                  @allow_private = allow_private
         | 
| 23 18 | 
             
                end
         | 
| 24 19 |  | 
| 25 20 | 
             
                def run
         | 
| 26 21 | 
             
                  stats = Stats.new
         | 
| 27 | 
            -
                  if receiver_type.type.to_s == 'String' && method_name == :initialize
         | 
| 28 | 
            -
                    return stats
         | 
| 29 | 
            -
                  end
         | 
| 30 22 | 
             
                  begin
         | 
| 31 23 | 
             
                    Timeout.timeout(@timeout) do
         | 
| 32 24 | 
             
                      catch(:break) do
         | 
| @@ -44,47 +36,53 @@ module RaaP | |
| 44 36 | 
             
                private
         | 
| 45 37 |  | 
| 46 38 | 
             
                def call(size:, stats:)
         | 
| 47 | 
            -
                  receiver_value = receiver_type.pick(size: size, eval: false)
         | 
| 48 | 
            -
                   | 
| 49 | 
            -
                   | 
| 50 | 
            -
                  symbolic_call =  | 
| 51 | 
            -
                   | 
| 52 | 
            -
                   | 
| 53 | 
            -
                     | 
| 54 | 
            -
             | 
| 55 | 
            -
                     | 
| 56 | 
            -
                       | 
| 57 | 
            -
             | 
| 39 | 
            +
                  receiver_value = @receiver_type.pick(size: size, eval: false)
         | 
| 40 | 
            +
                  args, kwargs, block = @method_type.pick_arguments(size: size, eval: false)
         | 
| 41 | 
            +
                  # @type var symbolic_call: symbolic_call
         | 
| 42 | 
            +
                  symbolic_call = [:call, receiver_value, @method_name, args, kwargs, block]
         | 
| 43 | 
            +
                  symbolic_caller = SymbolicCaller.new(symbolic_call, allow_private: @allow_private)
         | 
| 44 | 
            +
                  begin
         | 
| 45 | 
            +
                    # ensure symbolic_call
         | 
| 46 | 
            +
                    check = false
         | 
| 47 | 
            +
                    if return_type.instance_of?(::RBS::Types::Bases::Bottom)
         | 
| 48 | 
            +
                      begin
         | 
| 49 | 
            +
                        return_value = symbolic_caller.eval
         | 
| 50 | 
            +
                      rescue StandardError, NotImplementedError
         | 
| 51 | 
            +
                        check = true
         | 
| 52 | 
            +
                        return_value = Value::Bottom.new
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                    else
         | 
| 55 | 
            +
                      return_value = symbolic_caller.eval
         | 
| 56 | 
            +
                      check = check_return(receiver_value:, return_value:, method_type: @method_type)
         | 
| 58 57 | 
             
                    end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
                     | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
                    Result::Failure.new(method_value:, return_value:, symbolic_call:)
         | 
| 58 | 
            +
                    if check
         | 
| 59 | 
            +
                      stats.success += 1
         | 
| 60 | 
            +
                      Result::Success.new(symbolic_call:, return_value:)
         | 
| 61 | 
            +
                    else
         | 
| 62 | 
            +
                      Result::Failure.new(symbolic_call:, return_value:)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
                  rescue TypeError => exception
         | 
| 65 | 
            +
                    Result::Failure.new(symbolic_call:, return_value:, exception:)
         | 
| 68 66 | 
             
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                # not ensure symbolic_call
         | 
| 69 69 | 
             
                rescue NoMethodError => exception
         | 
| 70 70 | 
             
                  stats.skip += 1
         | 
| 71 | 
            -
                  Result::Skip.new( | 
| 71 | 
            +
                  Result::Skip.new(symbolic_call:, exception:)
         | 
| 72 72 | 
             
                rescue NameError => e
         | 
| 73 73 | 
             
                  msg = e.name.nil? ? '' : "for `#{BindCall.to_s(e.receiver)}::#{e.name}`"
         | 
| 74 74 | 
             
                  RaaP.logger.error("Implementation is not found #{msg} maybe.")
         | 
| 75 75 | 
             
                  throw :break
         | 
| 76 76 | 
             
                rescue NotImplementedError => exception
         | 
| 77 77 | 
             
                  stats.skip += 1
         | 
| 78 | 
            -
                  Result::Skip.new( | 
| 78 | 
            +
                  Result::Skip.new(symbolic_call:, exception:)
         | 
| 79 79 | 
             
                rescue SystemStackError => exception
         | 
| 80 80 | 
             
                  stats.skip += 1
         | 
| 81 81 | 
             
                  RaaP.logger.warn "Found recursive type definition."
         | 
| 82 | 
            -
                  Result::Skip.new( | 
| 83 | 
            -
                rescue TypeError => exception
         | 
| 84 | 
            -
                  Result::Failure.new(method_value:, return_value:, symbolic_call:)
         | 
| 82 | 
            +
                  Result::Skip.new(symbolic_call:, exception:)
         | 
| 85 83 | 
             
                rescue => exception
         | 
| 86 84 | 
             
                  stats.exception += 1
         | 
| 87 | 
            -
                  Result::Exception.new( | 
| 85 | 
            +
                  Result::Exception.new(symbolic_call:, exception:)
         | 
| 88 86 | 
             
                end
         | 
| 89 87 |  | 
| 90 88 | 
             
                def check_return(receiver_value:, return_value:, method_type:)
         | 
| @@ -104,7 +102,7 @@ module RaaP | |
| 104 102 | 
             
                    instance_class: instance_class,
         | 
| 105 103 | 
             
                    class_class: Module,
         | 
| 106 104 | 
             
                    builder: RBS.builder,
         | 
| 107 | 
            -
                    sample_size:  | 
| 105 | 
            +
                    sample_size: 100,
         | 
| 108 106 | 
             
                    unchecked_classes: []
         | 
| 109 107 | 
             
                  )
         | 
| 110 108 | 
             
                  begin
         | 
| @@ -116,7 +114,7 @@ module RaaP | |
| 116 114 | 
             
                end
         | 
| 117 115 |  | 
| 118 116 | 
             
                def return_type
         | 
| 119 | 
            -
                  method_type.rbs.type.return_type
         | 
| 117 | 
            +
                  @method_type.rbs.type.return_type
         | 
| 120 118 | 
             
                end
         | 
| 121 119 | 
             
              end
         | 
| 122 120 | 
             
            end
         | 
    
        data/lib/raap/method_type.rb
    CHANGED
    
    | @@ -36,5 +36,18 @@ module RaaP | |
| 36 36 |  | 
| 37 37 | 
             
                  Proc.new { Type.new(block.type.return_type).pick(size:, eval:) }
         | 
| 38 38 | 
             
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def check_return(return_value)
         | 
| 41 | 
            +
                  untyped = __skip__ = nil
         | 
| 42 | 
            +
                  type_check = ::RBS::Test::TypeCheck.new(
         | 
| 43 | 
            +
                    self_class: untyped,     # cannot support `self`
         | 
| 44 | 
            +
                    instance_class: untyped, # cannot support `instance`
         | 
| 45 | 
            +
                    class_class: untyped,    # cannot support `class`
         | 
| 46 | 
            +
                    builder: RBS.builder,
         | 
| 47 | 
            +
                    sample_size: 100,
         | 
| 48 | 
            +
                    unchecked_classes: []
         | 
| 49 | 
            +
                  )
         | 
| 50 | 
            +
                  type_check.value(return_value, rbs.type.return_type)
         | 
| 51 | 
            +
                end
         | 
| 39 52 | 
             
              end
         | 
| 40 53 | 
             
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            require 'minitest'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RaaP
         | 
| 4 | 
            +
              module Minitest
         | 
| 5 | 
            +
                def forall(*types, size_step: 0...100)
         | 
| 6 | 
            +
                  # @type self: Minitest::Test
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  if types.length == 1 && types.first.instance_of?(String) && types.first.start_with?("(")
         | 
| 9 | 
            +
                    # forall("(Integer) -> String") { |int| Foo.new.int2str(int) }
         | 
| 10 | 
            +
                    type = types.first
         | 
| 11 | 
            +
                    method_type = RaaP::MethodType.new(type)
         | 
| 12 | 
            +
                    size_step.each do |size|
         | 
| 13 | 
            +
                      # TODO assert_send_type
         | 
| 14 | 
            +
                      args, kwargs, _block = method_type.pick_arguments(size: size)
         | 
| 15 | 
            +
                      return_value = yield(*args, **kwargs)
         | 
| 16 | 
            +
                      assert method_type.check_return(return_value), "return value: #{BindCall.inspect(return_value)}[#{BindCall.class(return_value)}] is not match with `#{method_type.rbs.type.return_type}`"
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  else
         | 
| 19 | 
            +
                    # forall("Integer", "String") { |int, str| Foo.new.int_str(int, str) }
         | 
| 20 | 
            +
                    types.map! do |type|
         | 
| 21 | 
            +
                      case type
         | 
| 22 | 
            +
                      in String then RaaP::Type.new(type)
         | 
| 23 | 
            +
                      else type
         | 
| 24 | 
            +
                      end
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                    size_step.each do |size|
         | 
| 27 | 
            +
                      values = types.map { |type| type.pick(size: size) }
         | 
| 28 | 
            +
                      assert yield(*values)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            Minitest::Test.include RaaP::Minitest
         | 
    
        data/lib/raap/result.rb
    CHANGED
    
    | @@ -4,15 +4,20 @@ module RaaP | |
| 4 4 | 
             
              module Result
         | 
| 5 5 | 
             
                module CalledStr
         | 
| 6 6 | 
             
                  def called_str
         | 
| 7 | 
            -
                     | 
| 7 | 
            +
                    scr = SymbolicCaller.new(symbolic_call)
         | 
| 8 | 
            +
                    "#{scr.call_str} -> #{return_value.inspect}[#{return_value.class}]"
         | 
| 8 9 | 
             
                  end
         | 
| 9 10 | 
             
                end
         | 
| 10 11 |  | 
| 11 | 
            -
                Success = Data.define(: | 
| 12 | 
            +
                Success = Data.define(:symbolic_call, :return_value)
         | 
| 12 13 | 
             
                Success.include CalledStr
         | 
| 13 | 
            -
                Failure = Data.define(: | 
| 14 | 
            +
                Failure = Data.define(:symbolic_call, :return_value, :exception) do
         | 
| 15 | 
            +
                  def initialize(exception: nil, **)
         | 
| 16 | 
            +
                    super
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 14 19 | 
             
                Failure.include CalledStr
         | 
| 15 | 
            -
                Skip = Data.define(: | 
| 16 | 
            -
                Exception = Data.define(: | 
| 20 | 
            +
                Skip = Data.define(:symbolic_call, :exception)
         | 
| 21 | 
            +
                Exception = Data.define(:symbolic_call, :exception)
         | 
| 17 22 | 
             
              end
         | 
| 18 23 | 
             
            end
         | 
    
        data/lib/raap/symbolic_caller.rb
    CHANGED
    
    | @@ -16,10 +16,27 @@ module RaaP | |
| 16 16 | 
             
              # c = C.new(a: a, b: b)
         | 
| 17 17 | 
             
              # c.run() { }
         | 
| 18 18 | 
             
              class SymbolicCaller
         | 
| 19 | 
            +
                class Var
         | 
| 20 | 
            +
                  attr_reader :name
         | 
| 21 | 
            +
                  def initialize(name)
         | 
| 22 | 
            +
                    @name = name
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  def +(other)
         | 
| 26 | 
            +
                    "#{self}#{other}"
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def to_s
         | 
| 30 | 
            +
                    @name
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 19 34 | 
             
                attr_reader :symbolic_call
         | 
| 35 | 
            +
                attr_reader :allow_private
         | 
| 20 36 |  | 
| 21 | 
            -
                def initialize(symbolic_call)
         | 
| 37 | 
            +
                def initialize(symbolic_call, allow_private: false)
         | 
| 22 38 | 
             
                  @symbolic_call = symbolic_call
         | 
| 39 | 
            +
                  @allow_private = allow_private
         | 
| 23 40 | 
             
                end
         | 
| 24 41 |  | 
| 25 42 | 
             
                def eval
         | 
| @@ -28,8 +45,18 @@ module RaaP | |
| 28 45 | 
             
                  end
         | 
| 29 46 | 
             
                end
         | 
| 30 47 |  | 
| 31 | 
            -
                def  | 
| 32 | 
            -
                   | 
| 48 | 
            +
                def call_str
         | 
| 49 | 
            +
                  symbolic_call => [:call, receiver, Symbol => method_name, Array => args, Hash => kwargs, b]
         | 
| 50 | 
            +
                  receiver = try_eval(receiver)
         | 
| 51 | 
            +
                  args, kwargs, block = try_eval([args, kwargs, block])
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  a = []
         | 
| 54 | 
            +
                  a << args.map(&:inspect).join(', ') if !args.empty?
         | 
| 55 | 
            +
                  a << kwargs.map { |k ,v| "#{k}: #{BindCall.inspect(v)}" }.join(', ') if !kwargs.empty?
         | 
| 56 | 
            +
                  argument_str = a.join(', ')
         | 
| 57 | 
            +
                  block_str = block ? "{ }" : nil
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  "#{BindCall.inspect(receiver)}.#{method_name}(#{argument_str})#{block_str}"
         | 
| 33 60 | 
             
                end
         | 
| 34 61 |  | 
| 35 62 | 
             
                def to_lines
         | 
| @@ -39,19 +66,22 @@ module RaaP | |
| 39 66 |  | 
| 40 67 | 
             
                      is_mod = receiver_value.is_a?(Module)
         | 
| 41 68 |  | 
| 42 | 
            -
                       | 
| 43 | 
            -
             | 
| 69 | 
            +
                      case
         | 
| 70 | 
            +
                      when receiver_value == Kernel
         | 
| 71 | 
            +
                        var = Var.new(method_name.to_s.downcase)
         | 
| 72 | 
            +
                        var_eq = "#{var} = "
         | 
| 44 73 | 
             
                        receiver = ''
         | 
| 45 | 
            -
                       | 
| 46 | 
            -
                         | 
| 74 | 
            +
                      when BindCall.instance_of?(receiver_value, Var)
         | 
| 75 | 
            +
                        var_eq = ""
         | 
| 76 | 
            +
                        var = Var.new(receiver_value.name)
         | 
| 77 | 
            +
                        receiver = var + '.'
         | 
| 78 | 
            +
                      when is_mod
         | 
| 79 | 
            +
                        var = Var.new(var_name(receiver_value))
         | 
| 80 | 
            +
                        var_eq = "#{var} = "
         | 
| 47 81 | 
             
                        receiver = receiver_value.name + '.'
         | 
| 48 82 | 
             
                      else
         | 
| 49 | 
            -
                         | 
| 50 | 
            -
                        receiver =  | 
| 51 | 
            -
                          printable(receiver_value) + '.'
         | 
| 52 | 
            -
                        else
         | 
| 53 | 
            -
                          var_name(receiver_value.class) + '.'
         | 
| 54 | 
            -
                        end
         | 
| 83 | 
            +
                        var_eq = ""
         | 
| 84 | 
            +
                        receiver = Var.new(printable(receiver_value)) + '.'
         | 
| 55 85 | 
             
                      end
         | 
| 56 86 |  | 
| 57 87 | 
             
                      arguments = []
         | 
| @@ -59,15 +89,25 @@ module RaaP | |
| 59 89 | 
             
                      arguments << kwargs.map{|k,v| "#{k}: #{printable(v)}" }.join(', ') if !kwargs.empty?
         | 
| 60 90 | 
             
                      block_str = block ? " { }" : ""
         | 
| 61 91 |  | 
| 62 | 
            -
                      lines << "#{ | 
| 92 | 
            +
                      lines << "#{var_eq}#{receiver}#{method_name}(#{arguments.join(', ')})#{block_str}"
         | 
| 63 93 |  | 
| 64 | 
            -
                       | 
| 94 | 
            +
                      var
         | 
| 65 95 | 
             
                    end
         | 
| 66 96 | 
             
                  end
         | 
| 67 97 | 
             
                end
         | 
| 68 98 |  | 
| 69 99 | 
             
                private
         | 
| 70 100 |  | 
| 101 | 
            +
                def try_eval(symbolic_call)
         | 
| 102 | 
            +
                  SymbolicCaller.new(symbolic_call).eval
         | 
| 103 | 
            +
                rescue RuntimeError, NotImplementedError
         | 
| 104 | 
            +
                  symbolic_call
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                def walk(&)
         | 
| 108 | 
            +
                  _walk(@symbolic_call, &)
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 71 111 | 
             
                def _walk(symbolic_call, &block)
         | 
| 72 112 | 
             
                  return symbolic_call if BindCall::instance_of?(symbolic_call, BasicObject)
         | 
| 73 113 | 
             
                  return symbolic_call if !BindCall.respond_to?(symbolic_call, :deconstruct) && !BindCall.respond_to?(symbolic_call, :deconstruct_keys)
         | 
| @@ -78,6 +118,8 @@ module RaaP | |
| 78 118 | 
             
                    args = _walk(args, &block) if !args.empty?
         | 
| 79 119 | 
             
                    kwargs = _walk(kwargs, &block) if !kwargs.empty?
         | 
| 80 120 | 
             
                    block.call [:call, receiver, method_name, args, kwargs, b]
         | 
| 121 | 
            +
                  in Var
         | 
| 122 | 
            +
                    symbolic_call.name
         | 
| 81 123 | 
             
                  in Array
         | 
| 82 124 | 
             
                    symbolic_call.map { |sc| _walk(sc, &block) }
         | 
| 83 125 | 
             
                  in Hash
         | 
| @@ -89,12 +131,10 @@ module RaaP | |
| 89 131 |  | 
| 90 132 | 
             
                def eval_one(symbolic_call)
         | 
| 91 133 | 
             
                  symbolic_call => [:call, receiver_value, method_name, args, kwargs, block]
         | 
| 92 | 
            -
             | 
| 93 | 
            -
                  begin
         | 
| 134 | 
            +
                  if @allow_private
         | 
| 94 135 | 
             
                    receiver_value.__send__(method_name, *args, **kwargs, &block)
         | 
| 95 | 
            -
                   | 
| 96 | 
            -
                     | 
| 97 | 
            -
                    raise
         | 
| 136 | 
            +
                  else
         | 
| 137 | 
            +
                    BindCall.public_send(receiver_value, method_name, *args, **kwargs, &block)
         | 
| 98 138 | 
             
                  end
         | 
| 99 139 | 
             
                end
         | 
| 100 140 |  | 
| @@ -102,22 +142,28 @@ module RaaP | |
| 102 142 | 
             
                  printable(mod).gsub('::', '_').downcase
         | 
| 103 143 | 
             
                end
         | 
| 104 144 |  | 
| 105 | 
            -
                def printable | 
| 106 | 
            -
                   | 
| 107 | 
            -
             | 
| 108 | 
            -
                    true
         | 
| 109 | 
            -
                  else
         | 
| 110 | 
            -
                    false
         | 
| 145 | 
            +
                def printable(obj)
         | 
| 146 | 
            +
                  if obj in [:call, _, Symbol, Array, Hash, _]
         | 
| 147 | 
            +
                    return _walk(obj)
         | 
| 111 148 | 
             
                  end
         | 
| 112 | 
            -
                end
         | 
| 113 149 |  | 
| 114 | 
            -
                def printable(obj)
         | 
| 115 150 | 
             
                  case obj
         | 
| 151 | 
            +
                  when Var
         | 
| 152 | 
            +
                    obj.name
         | 
| 116 153 | 
             
                  # Object from which it can get strings that can be eval with `#inspect`
         | 
| 117 154 | 
             
                  when Symbol, Integer, Float, Regexp, nil, true, false
         | 
| 118 155 | 
             
                    obj.inspect
         | 
| 119 156 | 
             
                  when String
         | 
| 120 157 | 
             
                    obj.inspect.gsub('"', "'") or raise
         | 
| 158 | 
            +
                  when Hash
         | 
| 159 | 
            +
                    hash_body = obj.map do |k, v|
         | 
| 160 | 
            +
                      ks = printable(k)
         | 
| 161 | 
            +
                      vs = printable(v)
         | 
| 162 | 
            +
                      ks.start_with?(':') ? "#{ks[1..-1]}: #{vs}" : "#{ks} => #{vs}"
         | 
| 163 | 
            +
                    end
         | 
| 164 | 
            +
                    "{#{hash_body.join(', ')}}"
         | 
| 165 | 
            +
                  when Array
         | 
| 166 | 
            +
                    "[#{obj.map { |o| printable(o) }.join(', ')}]"
         | 
| 121 167 | 
             
                  when Module
         | 
| 122 168 | 
             
                    BindCall.name(obj) or raise
         | 
| 123 169 | 
             
                  else
         | 
    
        data/lib/raap/type.rb
    CHANGED
    
    | @@ -23,12 +23,14 @@ module RaaP | |
| 23 23 |  | 
| 24 24 | 
             
                # Type.register "::Integer::positive" { sized { |size| size } }
         | 
| 25 25 | 
             
                def self.register(type_name, &block)
         | 
| 26 | 
            -
                   | 
| 26 | 
            +
                  raise ArgumentError, "block is required" unless block
         | 
| 27 | 
            +
                  GENERATORS[type_name] = __skip__ = block
         | 
| 27 28 | 
             
                end
         | 
| 28 29 |  | 
| 29 30 | 
             
                # Special class case
         | 
| 30 31 | 
             
                register("::Array") do
         | 
| 31 | 
            -
                   | 
| 32 | 
            +
                  _type = __skip__ = type
         | 
| 33 | 
            +
                  t = _type.args[0] || 'untyped'
         | 
| 32 34 | 
             
                  array(Type.new(t, range: range))
         | 
| 33 35 | 
             
                end
         | 
| 34 36 | 
             
                register("::Binding") { sized { binding } }
         | 
| @@ -40,8 +42,9 @@ module RaaP | |
| 40 42 | 
             
                register("::Hash") do
         | 
| 41 43 | 
             
                  sized do |size|
         | 
| 42 44 | 
             
                    Array.new(integer.pick(size: size).abs).to_h do
         | 
| 43 | 
            -
                       | 
| 44 | 
            -
                       | 
| 45 | 
            +
                      _type = __skip__ = type
         | 
| 46 | 
            +
                      k = _type.args[0] || 'untyped'
         | 
| 47 | 
            +
                      v = _type.args[1] || 'untyped'
         | 
| 45 48 | 
             
                      [Type.new(k).pick(size: size), Type.new(v).pick(size: size)]
         | 
| 46 49 | 
             
                    end
         | 
| 47 50 | 
             
                  end
         | 
| @@ -66,10 +69,20 @@ module RaaP | |
| 66 69 | 
             
                def initialize(type, range: nil..nil)
         | 
| 67 70 | 
             
                  @type = parse(type)
         | 
| 68 71 | 
             
                  @range = range
         | 
| 72 | 
            +
                  @such_that = nil
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def such_that(&block)
         | 
| 76 | 
            +
                  @such_that = block
         | 
| 77 | 
            +
                  self
         | 
| 69 78 | 
             
                end
         | 
| 70 79 |  | 
| 71 80 | 
             
                def sized(&block)
         | 
| 72 | 
            -
                  Sized.new(&block)
         | 
| 81 | 
            +
                  Sized.new(&block).tap do |sized|
         | 
| 82 | 
            +
                    if s = @such_that
         | 
| 83 | 
            +
                      sized.such_that(&s)
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                  end
         | 
| 73 86 | 
             
                end
         | 
| 74 87 |  | 
| 75 88 | 
             
                def pick(size: 10, eval: true)
         | 
| @@ -87,7 +100,17 @@ module RaaP | |
| 87 100 | 
             
                  when ::RBS::Types::Union
         | 
| 88 101 | 
             
                    type.types.sample&.then { |t| Type.new(t).pick(size:) }
         | 
| 89 102 | 
             
                  when ::RBS::Types::Intersection
         | 
| 90 | 
            -
                    Value::Intersection | 
| 103 | 
            +
                    [:call, Value::Intersection, :new, [type], {size:}, nil]
         | 
| 104 | 
            +
                  when ::RBS::Types::Interface
         | 
| 105 | 
            +
                    [:call, Value::Interface, :new, [type], {size:}, nil]
         | 
| 106 | 
            +
                  when ::RBS::Types::Variable
         | 
| 107 | 
            +
                    [:call, Value::Variable, :new, [type], {}, nil]
         | 
| 108 | 
            +
                  when ::RBS::Types::Bases::Void
         | 
| 109 | 
            +
                    [:call, Value::Void, :new, [], {}, nil]
         | 
| 110 | 
            +
                  when ::RBS::Types::Bases::Top
         | 
| 111 | 
            +
                    [:call, Value::Top, :new, [], {}, nil]
         | 
| 112 | 
            +
                  when ::RBS::Types::Bases::Bottom
         | 
| 113 | 
            +
                    [:call, Value::Bottom, :new, [], {}, nil]
         | 
| 91 114 | 
             
                  when ::RBS::Types::Optional
         | 
| 92 115 | 
             
                    case Random.rand(2)
         | 
| 93 116 | 
             
                    in 0 then Type.new(type.type).pick(size:)
         | 
| @@ -104,16 +127,12 @@ module RaaP | |
| 104 127 | 
             
                    raise "cannot resolve `instance` type"
         | 
| 105 128 | 
             
                  when ::RBS::Types::Bases::Self
         | 
| 106 129 | 
             
                    raise "cannot resolve `self` type"
         | 
| 107 | 
            -
                  when ::RBS::Types::Interface
         | 
| 108 | 
            -
                    Value::Interface.new(type, size: size)
         | 
| 109 | 
            -
                  when ::RBS::Types::Variable
         | 
| 110 | 
            -
                    Value::Variable.new(type)
         | 
| 111 130 | 
             
                  when ::RBS::Types::ClassSingleton
         | 
| 112 131 | 
             
                    Object.const_get(type.name.to_s)
         | 
| 113 132 | 
             
                  when ::RBS::Types::ClassInstance
         | 
| 114 133 | 
             
                    case gen = GENERATORS[type.name.absolute!.to_s]
         | 
| 115 | 
            -
                     | 
| 116 | 
            -
                     | 
| 134 | 
            +
                    in Proc then instance_exec(&gen).pick(size: size)
         | 
| 135 | 
            +
                    in nil then pick_from_initialize(type, size:)
         | 
| 117 136 | 
             
                    end
         | 
| 118 137 | 
             
                  when ::RBS::Types::Record
         | 
| 119 138 | 
             
                    type.fields.transform_values { |t| Type.new(t).pick(size:) }
         | 
| @@ -123,21 +142,17 @@ module RaaP | |
| 123 142 | 
             
                    type.literal
         | 
| 124 143 | 
             
                  when ::RBS::Types::Bases::Bool
         | 
| 125 144 | 
             
                    bool.pick(size: size)
         | 
| 126 | 
            -
                  when ::RBS::Types::Bases::Void
         | 
| 127 | 
            -
                    Value::Void.new
         | 
| 128 145 | 
             
                  when ::RBS::Types::Bases::Any
         | 
| 129 146 | 
             
                    untyped.pick(size: size)
         | 
| 130 147 | 
             
                  when ::RBS::Types::Bases::Nil
         | 
| 131 148 | 
             
                    nil
         | 
| 132 | 
            -
                  when ::RBS::Types::Bases::Top
         | 
| 133 | 
            -
                    Value::Top.new
         | 
| 134 | 
            -
                  when ::RBS::Types::Bases::Bottom
         | 
| 135 | 
            -
                    Value::Bottom.new
         | 
| 136 149 | 
             
                  else
         | 
| 137 150 | 
             
                    raise "not implemented #{type.to_s}"
         | 
| 138 151 | 
             
                  end
         | 
| 139 152 | 
             
                end
         | 
| 140 153 |  | 
| 154 | 
            +
                private
         | 
| 155 | 
            +
             | 
| 141 156 | 
             
                def pick_from_initialize(type, size:)
         | 
| 142 157 | 
             
                  type_name = type.name.absolute!
         | 
| 143 158 | 
             
                  const = Object.const_get(type_name.to_s)
         | 
| @@ -162,12 +177,10 @@ module RaaP | |
| 162 177 | 
             
                      raise
         | 
| 163 178 | 
             
                    end
         | 
| 164 179 | 
             
                  else
         | 
| 165 | 
            -
                    Value::Module | 
| 180 | 
            +
                    [:call, Value::Module, :new, [type], {}, nil]
         | 
| 166 181 | 
             
                  end
         | 
| 167 182 | 
             
                end
         | 
| 168 183 |  | 
| 169 | 
            -
                private
         | 
| 170 | 
            -
             | 
| 171 184 | 
             
                def parse(type)
         | 
| 172 185 | 
             
                  case type
         | 
| 173 186 | 
             
                  when String
         | 
| @@ -279,24 +292,28 @@ module RaaP | |
| 279 292 |  | 
| 280 293 | 
             
                def encoding
         | 
| 281 294 | 
             
                  sized do
         | 
| 282 | 
            -
                     | 
| 283 | 
            -
                    e = Encoding.list.sample
         | 
| 295 | 
            +
                    e = Encoding.list.sample or raise
         | 
| 284 296 | 
             
                    [:call, Encoding, :find, [e.name], {} , nil]
         | 
| 285 297 | 
             
                  end
         | 
| 286 298 | 
             
                end
         | 
| 287 299 |  | 
| 288 300 | 
             
                def bool
         | 
| 289 | 
            -
                  sized  | 
| 301 | 
            +
                  sized do
         | 
| 302 | 
            +
                    Random.rand(2) == 0
         | 
| 303 | 
            +
                  end
         | 
| 290 304 | 
             
                end
         | 
| 291 305 |  | 
| 292 306 | 
             
                def untyped
         | 
| 293 | 
            -
                  case Random.rand( | 
| 307 | 
            +
                  case Random.rand(9)
         | 
| 294 308 | 
             
                  in 0 then integer
         | 
| 295 309 | 
             
                  in 1 then float
         | 
| 296 | 
            -
                  in 2 then  | 
| 297 | 
            -
                  in 3 then  | 
| 298 | 
            -
                  in 4 then  | 
| 299 | 
            -
                  in 5 then  | 
| 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] }
         | 
| 300 317 | 
             
                  end
         | 
| 301 318 | 
             
                end
         | 
| 302 319 |  | 
    
        data/lib/raap/value/module.rb
    CHANGED
    
    | @@ -1,13 +1,14 @@ | |
| 1 1 | 
             
            module RaaP
         | 
| 2 2 | 
             
              module Value
         | 
| 3 3 | 
             
                # FIXME: consider self_types
         | 
| 4 | 
            -
                 | 
| 4 | 
            +
                # HINT: intersection?
         | 
| 5 | 
            +
                class Module
         | 
| 5 6 | 
             
                  attr_reader :type
         | 
| 6 7 |  | 
| 7 8 | 
             
                  def initialize(type)
         | 
| 8 9 | 
             
                    @type = type
         | 
| 9 10 | 
             
                    const = ::Object.const_get(type.name.absolute!.to_s)
         | 
| 10 | 
            -
                     | 
| 11 | 
            +
                    extend(const)
         | 
| 11 12 | 
             
                  end
         | 
| 12 13 |  | 
| 13 14 | 
             
                  def inspect = "#<module #{@type}>"
         | 
    
        data/lib/raap/version.rb
    CHANGED
    
    
    
        data/lib/raap.rb
    CHANGED
    
    | @@ -16,14 +16,14 @@ module RaaP | |
| 16 16 | 
             
              end
         | 
| 17 17 |  | 
| 18 18 | 
             
              self.logger = ::Logger.new($stdout)
         | 
| 19 | 
            -
              self.logger.level = ::Logger:: | 
| 19 | 
            +
              self.logger.level = ::Logger::INFO
         | 
| 20 20 |  | 
| 21 21 | 
             
              autoload :BindCall, "raap/bind_call"
         | 
| 22 22 | 
             
              autoload :CLI, "raap/cli"
         | 
| 23 23 | 
             
              autoload :FunctionType, "raap/function_type"
         | 
| 24 24 | 
             
              autoload :MethodProperty, "raap/method_property"
         | 
| 25 25 | 
             
              autoload :MethodType, "raap/method_type"
         | 
| 26 | 
            -
              autoload : | 
| 26 | 
            +
              autoload :Minitest, "raap/minitest"
         | 
| 27 27 | 
             
              autoload :RBS, "raap/rbs"
         | 
| 28 28 | 
             
              autoload :Result, "raap/result"
         | 
| 29 29 | 
             
              autoload :Sized, "raap/sized"
         | 
    
        data/sig/raap.rbs
    CHANGED
    
    | @@ -19,15 +19,15 @@ module RaaP | |
| 19 19 |  | 
| 20 20 | 
             
              class CLI
         | 
| 21 21 | 
             
                class Option < ::Struct[untyped]
         | 
| 22 | 
            -
                  def self.new: (?dirs: ::Array[String], ?requires: ::Array[String], ?libraries: ::Array[String], ?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer) -> instance
         | 
| 22 | 
            +
                  def self.new: (?dirs: ::Array[String], ?requires: ::Array[String], ?libraries: ::Array[String], ?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer, ?allow_private: bool) -> instance
         | 
| 23 23 |  | 
| 24 | 
            -
                  def self.[]: (?dirs: ::Array[String], ?requires: ::Array[String], ?libraries: ::Array[String], ?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer) -> instance
         | 
| 24 | 
            +
                  def self.[]: (?dirs: ::Array[String], ?requires: ::Array[String], ?libraries: ::Array[String], ?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer, ?allow_private: bool) -> instance
         | 
| 25 25 |  | 
| 26 26 | 
             
                  def self.keyword_init?: () -> true
         | 
| 27 27 |  | 
| 28 | 
            -
                  def self.members: () -> [ :dirs, :requires, :library, :timeout, :size_from, :size_to, :size_by]
         | 
| 28 | 
            +
                  def self.members: () -> [ :dirs, :requires, :library, :timeout, :size_from, :size_to, :size_by, :allow_private]
         | 
| 29 29 |  | 
| 30 | 
            -
                  def members: () -> [ :dirs, :requires, :library, :timeout, :size_from, :size_to, :size_by]
         | 
| 30 | 
            +
                  def members: () -> [ :dirs, :requires, :library, :timeout, :size_from, :size_to, :size_by, :allow_private]
         | 
| 31 31 |  | 
| 32 32 | 
             
                  attr_accessor dirs: ::Array[String]
         | 
| 33 33 |  | 
| @@ -42,6 +42,8 @@ module RaaP | |
| 42 42 | 
             
                  attr_accessor size_to: ::Integer
         | 
| 43 43 |  | 
| 44 44 | 
             
                  attr_accessor size_by: ::Integer
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  attr_accessor allow_private: bool
         | 
| 45 47 | 
             
                end
         | 
| 46 48 |  | 
| 47 49 | 
             
                @argv: Array[String]
         | 
| @@ -81,12 +83,15 @@ module RaaP | |
| 81 83 | 
             
                  attr_accessor skip: Integer
         | 
| 82 84 | 
             
                  attr_accessor exception: Integer
         | 
| 83 85 | 
             
                end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                 | 
| 86 | 
            -
                 | 
| 87 | 
            -
                 | 
| 88 | 
            -
                 | 
| 89 | 
            -
                 | 
| 86 | 
            +
             | 
| 87 | 
            +
                @receiver_type: Type
         | 
| 88 | 
            +
                @method_name: Symbol
         | 
| 89 | 
            +
                @method_type: MethodType
         | 
| 90 | 
            +
                @size_step: _Each[Integer]
         | 
| 91 | 
            +
                @timeout: (Integer | Float | nil)
         | 
| 92 | 
            +
                @allow_private: bool
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def initialize: (receiver_type: Type, method_name: Symbol, method_type: MethodType, size_step: _Each[Integer], timeout: (Integer | Float | nil), ?allow_private: bool) -> void
         | 
| 90 95 | 
             
                def run: () { (Result::Success | Result::Failure | Result::Skip | Result::Exception) -> void } -> Stats
         | 
| 91 96 |  | 
| 92 97 | 
             
                private
         | 
| @@ -103,33 +108,17 @@ module RaaP | |
| 103 108 | 
             
                def initialize: (::RBS::MethodType | String method, ?type_params_decl: Array[untyped], ?type_args: Array[untyped], ?self_type: ::RBS::Types::ClassInstance?, ?instance_type: ::RBS::Types::ClassInstance?, ?class_type: ::RBS::Types::ClassSingleton?) -> void
         | 
| 104 109 | 
             
                def pick_arguments: (?size: Integer, ?eval: bool) -> [Array[untyped], Hash[Symbol, untyped], ::Proc?]
         | 
| 105 110 | 
             
                def pick_block: (?size: Integer, ?eval: bool) -> ::Proc?
         | 
| 111 | 
            +
                def check_return: (untyped) -> bool
         | 
| 106 112 | 
             
              end
         | 
| 107 113 |  | 
| 108 | 
            -
               | 
| 109 | 
            -
                def self.new: (untyped receiver_value, [Array[untyped], Hash[Symbol, untyped], ::Proc?] arguments, Symbol method_name, Integer size) -> instance
         | 
| 110 | 
            -
                            | (receiver_value: untyped, arguments: [Array[untyped], Hash[Symbol, untyped], ::Proc?], method_name: Symbol, size: Integer) -> instance
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                def self.[]: (untyped receiver_value, [Array[untyped], Hash[Symbol, untyped], ::Proc?] arguments, Symbol method_name, Integer size) -> instance
         | 
| 113 | 
            -
                           | (receiver_value: untyped, arguments: [Array[untyped], Hash[Symbol, untyped], ::Proc?], method_name: Symbol, size: Integer) -> instance
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                def self.members: () -> [ :receiver_value, :arguments, :method_name, :size ]
         | 
| 116 | 
            -
                def members: () -> [ :receiver_value, :arguments, :method_name, :size ]
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                attr_reader receiver_value: untyped
         | 
| 119 | 
            -
                attr_reader arguments: [Array[untyped], Hash[Symbol, untyped], ::Proc?]
         | 
| 120 | 
            -
                attr_reader method_name: Symbol
         | 
| 121 | 
            -
                attr_reader size: Integer
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                def to_symbolic_call: () -> symbolic_call
         | 
| 124 | 
            -
                def call_str: () -> String
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                private
         | 
| 127 | 
            -
             | 
| 128 | 
            -
                def argument_str: () -> String
         | 
| 129 | 
            -
                def block_str: () -> String?
         | 
| 114 | 
            +
              module Minitest
         | 
| 130 115 | 
             
              end
         | 
| 131 116 |  | 
| 132 117 | 
             
              module RBS
         | 
| 118 | 
            +
                self.@builder: ::RBS::DefinitionBuilder
         | 
| 119 | 
            +
                self.@env: ::RBS::Environment
         | 
| 120 | 
            +
                self.@loader: ::RBS::EnvironmentLoader
         | 
| 121 | 
            +
             | 
| 133 122 | 
             
                def self.builder: () -> ::RBS::DefinitionBuilder
         | 
| 134 123 | 
             
                def self.env: () -> ::RBS::Environment
         | 
| 135 124 | 
             
                def self.loader: () -> ::RBS::EnvironmentLoader
         | 
| @@ -138,60 +127,67 @@ module RaaP | |
| 138 127 |  | 
| 139 128 | 
             
              module Result
         | 
| 140 129 | 
             
                interface _MethodValueReturnValue
         | 
| 141 | 
            -
                  def  | 
| 130 | 
            +
                  def symbolic_call: () -> symbolic_call
         | 
| 142 131 | 
             
                  def return_value: () -> untyped
         | 
| 143 132 | 
             
                end
         | 
| 144 133 | 
             
                module CalledStr : _MethodValueReturnValue
         | 
| 145 134 | 
             
                  def called_str: () -> String
         | 
| 146 135 | 
             
                end
         | 
| 147 136 | 
             
                class Success < Data
         | 
| 148 | 
            -
                  def self.new: ( | 
| 149 | 
            -
                  attr_reader  | 
| 137 | 
            +
                  def self.new: (symbolic_call: symbolic_call, return_value: untyped) -> instance
         | 
| 138 | 
            +
                  attr_reader symbolic_call: symbolic_call
         | 
| 150 139 | 
             
                  attr_reader return_value: untyped
         | 
| 151 140 | 
             
                  include CalledStr
         | 
| 152 141 | 
             
                end
         | 
| 153 142 | 
             
                class Failure < Data
         | 
| 154 | 
            -
                  def self.new: ( | 
| 155 | 
            -
                  attr_reader method_value: MethodValue
         | 
| 156 | 
            -
                  attr_reader return_value: untyped
         | 
| 143 | 
            +
                  def self.new: (symbolic_call: symbolic_call, return_value: untyped, ?exception: ::Exception?) -> instance
         | 
| 157 144 | 
             
                  attr_reader symbolic_call: symbolic_call
         | 
| 145 | 
            +
                  attr_reader return_value: untyped
         | 
| 146 | 
            +
                  attr_reader exception: ::Exception?
         | 
| 158 147 | 
             
                  include CalledStr
         | 
| 159 148 | 
             
                end
         | 
| 160 149 | 
             
                class Skip < Data
         | 
| 161 | 
            -
                  def self.new: ( | 
| 162 | 
            -
                  attr_reader  | 
| 150 | 
            +
                  def self.new: (symbolic_call: symbolic_call?, exception: ::Exception) -> instance
         | 
| 151 | 
            +
                  attr_reader symbolic_call: symbolic_call?
         | 
| 163 152 | 
             
                  attr_reader exception: ::Exception
         | 
| 164 153 | 
             
                end
         | 
| 165 154 | 
             
                class Exception < Data
         | 
| 166 | 
            -
                  def self.new: ( | 
| 167 | 
            -
                  attr_reader  | 
| 155 | 
            +
                  def self.new: (symbolic_call: symbolic_call?, exception: ::Exception) -> instance
         | 
| 156 | 
            +
                  attr_reader symbolic_call: symbolic_call?
         | 
| 168 157 | 
             
                  attr_reader exception: ::Exception
         | 
| 169 158 | 
             
                end
         | 
| 170 159 | 
             
              end
         | 
| 171 160 |  | 
| 172 | 
            -
               | 
| 173 | 
            -
                def pick: (size: Integer) -> T
         | 
| 174 | 
            -
              end
         | 
| 175 | 
            -
             | 
| 176 | 
            -
              class Sized
         | 
| 161 | 
            +
              class Sized[T]
         | 
| 177 162 | 
             
                @block: ::Proc
         | 
| 178 163 | 
             
                @such_that: ::Proc?
         | 
| 179 164 |  | 
| 180 165 | 
             
                def initialize: () { (Integer) -> untyped } -> void
         | 
| 181 | 
            -
                 | 
| 166 | 
            +
                def pick: (size: Integer) -> T
         | 
| 182 167 | 
             
                def such_that: () { (untyped) -> boolish } -> self
         | 
| 183 168 | 
             
                def such_that_loop: [R] () { (Integer) -> R } -> R
         | 
| 184 169 | 
             
              end
         | 
| 185 170 |  | 
| 186 171 | 
             
              class SymbolicCaller
         | 
| 172 | 
            +
                class Var
         | 
| 173 | 
            +
                  attr_reader name: String
         | 
| 174 | 
            +
                  def initialize: (String name) -> void
         | 
| 175 | 
            +
                  def +: (String) -> String
         | 
| 176 | 
            +
                  def to_s: () -> String
         | 
| 177 | 
            +
                end
         | 
| 178 | 
            +
             | 
| 187 179 | 
             
                attr_reader symbolic_call: untyped
         | 
| 188 | 
            -
                 | 
| 180 | 
            +
                attr_reader allow_private: bool
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                def initialize: (untyped, ?allow_private: bool) -> void
         | 
| 189 183 | 
             
                def eval: () -> untyped
         | 
| 190 | 
            -
                def  | 
| 184 | 
            +
                def call_str: () -> String
         | 
| 191 185 | 
             
                def to_lines: () -> Array[String]
         | 
| 192 186 |  | 
| 193 187 | 
             
                private
         | 
| 194 188 |  | 
| 189 | 
            +
                def try_eval: (untyped) -> untyped
         | 
| 190 | 
            +
                def walk: () ?{ (symbolic_call) -> untyped} -> untyped
         | 
| 195 191 | 
             
                def _walk: (untyped) ?{ (symbolic_call) -> untyped} -> untyped
         | 
| 196 192 | 
             
                def eval_one: (symbolic_call) -> untyped
         | 
| 197 193 | 
             
                def var_name: (Module) -> String
         | 
| @@ -213,7 +209,7 @@ module RaaP | |
| 213 209 | 
             
                  def map_type: { (untyped) -> untyped } -> untyped
         | 
| 214 210 | 
             
                end
         | 
| 215 211 |  | 
| 216 | 
            -
                def sub: (_MapType search, self_type: ::RBS::Types::ClassInstance?, instance_type: ::RBS::Types::ClassInstance?,  | 
| 212 | 
            +
                def sub: (_MapType search, self_type: ::RBS::Types::ClassInstance?, instance_type: ::RBS::Types::ClassInstance?, class_type: ::RBS::Types::ClassSingleton?) -> untyped
         | 
| 217 213 | 
             
              end
         | 
| 218 214 |  | 
| 219 215 | 
             
              class Type
         | 
| @@ -222,39 +218,45 @@ module RaaP | |
| 222 218 | 
             
                  def self.positive_float: () -> Float
         | 
| 223 219 | 
             
                end
         | 
| 224 220 |  | 
| 225 | 
            -
                 | 
| 221 | 
            +
                @such_that: (^(untyped) -> ::boolish)?
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                GENERATORS: Hash[String, ^() -> Sized[untyped]]
         | 
| 226 224 | 
             
                SIMPLE_SOURCE: Array[String]
         | 
| 227 225 | 
             
                RECURSION: Hash[String, :found | :logged]
         | 
| 228 226 |  | 
| 229 | 
            -
                def self.register: (String) { () [self: instance] ->  | 
| 227 | 
            +
                def self.register: (String) { () [self: instance] -> Sized[untyped] } -> void
         | 
| 230 228 | 
             
                attr_reader type: ::RBS::Types::t
         | 
| 231 229 | 
             
                attr_reader range: Range[untyped]
         | 
| 232 230 |  | 
| 233 231 | 
             
                def initialize: (String | ::RBS::Types::t, ?range: Range[untyped]) -> void
         | 
| 234 232 |  | 
| 235 | 
            -
                 | 
| 236 | 
            -
                 | 
| 233 | 
            +
                # Define rule for generating values
         | 
| 234 | 
            +
                #     type.such_that { |i| i != 0 }.pick #=> ensure that the value is not 0
         | 
| 235 | 
            +
                def such_that: () { (untyped) -> boolish } -> self
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                # Basic API for materializing values
         | 
| 238 | 
            +
                def pick: (?size: Integer, ?eval: bool) -> untyped
         | 
| 237 239 | 
             
                def to_symbolic_call: (?size: Integer) -> untyped
         | 
| 238 | 
            -
                def  | 
| 239 | 
            -
                def sized: () { (Integer size) -> untyped } -> _Pick[untyped]
         | 
| 240 | 
            +
                def sized: [T] () { (Integer size) -> T } -> Sized[T]
         | 
| 240 241 |  | 
| 241 242 | 
             
                private
         | 
| 242 243 |  | 
| 244 | 
            +
                def pick_from_initialize: (::RBS::Types::ClassInstance, size: Integer) -> (symbolic_call | Value::Module)
         | 
| 243 245 | 
             
                def parse: (String | ::RBS::Types::t) -> ::RBS::Types::t?
         | 
| 244 246 | 
             
                def try: (times: Integer, size: Integer) { (Integer size) -> untyped } -> untyped
         | 
| 245 247 |  | 
| 246 | 
            -
                def numeric: () ->  | 
| 247 | 
            -
                def integer: () ->  | 
| 248 | 
            -
                def none_zero_integer: () ->  | 
| 249 | 
            -
                def float: () ->  | 
| 250 | 
            -
                def rational: () ->  | 
| 251 | 
            -
                def complex: () ->  | 
| 252 | 
            -
                def string: () ->  | 
| 253 | 
            -
                def symbol: () ->  | 
| 254 | 
            -
                def array: (Type) ->  | 
| 255 | 
            -
                def encoding: () ->  | 
| 256 | 
            -
                def bool: () ->  | 
| 257 | 
            -
                def untyped: () ->  | 
| 248 | 
            +
                def numeric: () -> Sized[Numeric]
         | 
| 249 | 
            +
                def integer: () -> Sized[Integer]
         | 
| 250 | 
            +
                def none_zero_integer: () -> Sized[Integer]
         | 
| 251 | 
            +
                def float: () -> Sized[Float]
         | 
| 252 | 
            +
                def rational: () -> Sized[symbolic_call]
         | 
| 253 | 
            +
                def complex: () -> Sized[symbolic_call]
         | 
| 254 | 
            +
                def string: () -> Sized[String]
         | 
| 255 | 
            +
                def symbol: () -> Sized[Symbol]
         | 
| 256 | 
            +
                def array: (Type) -> Sized[Array[untyped]]
         | 
| 257 | 
            +
                def encoding: () -> Sized[symbolic_call]
         | 
| 258 | 
            +
                def bool: () -> Sized[bool]
         | 
| 259 | 
            +
                def untyped: () -> Sized[untyped]
         | 
| 258 260 | 
             
                def temp_method_object: () -> ::Method
         | 
| 259 261 | 
             
              end
         | 
| 260 262 |  | 
| @@ -284,7 +286,7 @@ module RaaP | |
| 284 286 | 
             
                  def class: () -> class
         | 
| 285 287 | 
             
                end
         | 
| 286 288 |  | 
| 287 | 
            -
                class Module | 
| 289 | 
            +
                class Module
         | 
| 288 290 | 
             
                  attr_reader type: ::RBS::Types::ClassInstance
         | 
| 289 291 |  | 
| 290 292 | 
             
                  def initialize: (::RBS::Types::ClassInstance) -> void
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: raap
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - ksss
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024-03- | 
| 11 | 
            +
            date: 2024-03-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rbs
         | 
| @@ -59,7 +59,7 @@ files: | |
| 59 59 | 
             
            - lib/raap/function_type.rb
         | 
| 60 60 | 
             
            - lib/raap/method_property.rb
         | 
| 61 61 | 
             
            - lib/raap/method_type.rb
         | 
| 62 | 
            -
            - lib/raap/ | 
| 62 | 
            +
            - lib/raap/minitest.rb
         | 
| 63 63 | 
             
            - lib/raap/rbs.rb
         | 
| 64 64 | 
             
            - lib/raap/result.rb
         | 
| 65 65 | 
             
            - lib/raap/sized.rb
         | 
    
        data/lib/raap/method_value.rb
    DELETED
    
    | @@ -1,38 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module RaaP
         | 
| 4 | 
            -
              class MethodValue < Data.define(
         | 
| 5 | 
            -
                :receiver_value,
         | 
| 6 | 
            -
                :arguments,
         | 
| 7 | 
            -
                :method_name,
         | 
| 8 | 
            -
                :size
         | 
| 9 | 
            -
              )
         | 
| 10 | 
            -
                def to_symbolic_call
         | 
| 11 | 
            -
                  args, kwargs, block = arguments
         | 
| 12 | 
            -
                  [:call, receiver_value, method_name, args, kwargs, block]
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def call_str
         | 
| 16 | 
            -
                  r = SymbolicCaller.new(receiver_value).eval
         | 
| 17 | 
            -
                  "#{BindCall.inspect(r)}.#{method_name}(#{argument_str})#{block_str}"
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                private
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def argument_str
         | 
| 23 | 
            -
                  args, kwargs, _ = SymbolicCaller.new(arguments).eval
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  r = []
         | 
| 26 | 
            -
                  r << args.map(&:inspect).join(', ') if !args.empty?
         | 
| 27 | 
            -
                  r << kwargs.map { |k ,v| "#{k}: #{BindCall.inspect(v)}" }.join(', ') if !kwargs.empty?
         | 
| 28 | 
            -
                  r.join(', ')
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def block_str
         | 
| 32 | 
            -
                  _, _, block = SymbolicCaller.new(arguments).eval
         | 
| 33 | 
            -
                  if block
         | 
| 34 | 
            -
                    "{ }"
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
              end
         | 
| 38 | 
            -
            end
         |