raap 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/README.md +59 -1
- data/lib/raap/cli.rb +15 -16
- data/lib/raap/coverage.rb +180 -0
- data/lib/raap/function_type.rb +37 -12
- data/lib/raap/method_property.rb +33 -2
- data/lib/raap/method_type.rb +63 -13
- data/lib/raap/rbs.rb +42 -0
- data/lib/raap/type.rb +28 -20
- data/lib/raap/type_substitution.rb +4 -0
- data/lib/raap/value/interface.rb +9 -20
- data/lib/raap/value/intersection.rb +6 -7
- data/lib/raap/value/variable.rb +1 -1
- data/lib/raap/version.rb +1 -1
- data/lib/raap.rb +1 -0
- data/public/example.webp +0 -0
- data/sig/raap.rbs +54 -18
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f119356b79f6beb968f26d019dda506e8eada4a48e178bd029e7e97d187f2d2c
|
4
|
+
data.tar.gz: f72f9d682ff47f11d51ebcf547a7f991c75b9be731eabc018fbb5b5a727dc358
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d3fbbfd916eb8526d9021e94408f4af402d80455c89b822c74557a76a31b8fc93a0d7acd8e47efdca32a8b1a19fb37a2b8f997e3c7ad6083e2f61d72052973a
|
7
|
+
data.tar.gz: cfbeb8a13d53e16a6e51701c30354ea1537c8b6b7a7ef46665b7e0efe9db43a4ce769370f38f558e4a384c80a039960faa65acbc8648c8f36e3725a53c2c1075
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# RaaP
|
2
2
|
|
3
|
-
<img src="https://raw.githubusercontent.com/ksss/raap/main/public/jacket.webp" width=
|
3
|
+
<img src="https://raw.githubusercontent.com/ksss/raap/main/public/jacket.webp" width=500/>
|
4
4
|
|
5
5
|
## RBS as a Property
|
6
6
|
|
@@ -14,6 +14,10 @@ The return value of the method is checked to see if it matches the type, if not,
|
|
14
14
|
|
15
15
|
If you write an RBS, it becomes a test case.
|
16
16
|
|
17
|
+
## Example
|
18
|
+
|
19
|
+
<img src="https://raw.githubusercontent.com/ksss/raap/main/public/example.webp" width=700/>
|
20
|
+
|
17
21
|
## Concept
|
18
22
|
|
19
23
|
If you has next signature.
|
@@ -53,6 +57,10 @@ Then, you can start loop again.
|
|
53
57
|
|
54
58
|
Finally, you get the perfect RBS!
|
55
59
|
|
60
|
+
## Slide
|
61
|
+
|
62
|
+
https://speakerdeck.com/ksss/raap
|
63
|
+
|
56
64
|
## Installation
|
57
65
|
|
58
66
|
Install the gem and add to the application's Gemfile by executing:
|
@@ -88,6 +96,20 @@ $ raap $(cat test/raap.txt) # You can manage the methods to be tested in a fil
|
|
88
96
|
- info: A somewhat visualized representation of the execution state.
|
89
97
|
- debug: All information including stack traces.
|
90
98
|
|
99
|
+
## Coverage
|
100
|
+
|
101
|
+
RaaP randomly selects a type and generates a value for optional and union types.
|
102
|
+
|
103
|
+
By default, displays the coverage of the type that actually produced the value.
|
104
|
+
|
105
|
+
The coverage display can help you determine if a correction is needed.
|
106
|
+
|
107
|
+
### Meaning of colored types
|
108
|
+
|
109
|
+
- 🔴 Red: A type that has never been used to generate or validate a value.
|
110
|
+
- 🟡 Yellow: It is systematically difficult to determine if the type was used or not. (FIXME)
|
111
|
+
- 🟢 Green: The type used to generate and validate the value.
|
112
|
+
|
91
113
|
## Size
|
92
114
|
|
93
115
|
Random values are determined based on size.
|
@@ -150,6 +172,42 @@ You can specify size of step like `Integer#step: (to: Integer, by: Integer)`.
|
|
150
172
|
By default, raap only validates public methods.
|
151
173
|
However, by setting this option, it is possible to intentionally validate private methods in the RBS.
|
152
174
|
|
175
|
+
### `--preload path`
|
176
|
+
|
177
|
+
Simply call `Kernel.load`.
|
178
|
+
However, this simplifies the preliminary preparation.
|
179
|
+
|
180
|
+
#### Preload examples
|
181
|
+
|
182
|
+
1) Check signature of aws-sdk-s3
|
183
|
+
|
184
|
+
```rb
|
185
|
+
$ cat preload.rb
|
186
|
+
require 'aws-sdk-s3'
|
187
|
+
|
188
|
+
# Register initialize of `Aws::S3::Client` class.
|
189
|
+
RaaP::Type.register("Aws::S3::Client") do
|
190
|
+
[:call, Aws::S3::Client, :new, [], { stub_responses: true }, nil]
|
191
|
+
end
|
192
|
+
|
193
|
+
$ raap --preload ./preload.rb 'Aws::S3::Client#get_object'
|
194
|
+
```
|
195
|
+
|
196
|
+
2) Output ruby coverage by simplecov
|
197
|
+
|
198
|
+
```rb
|
199
|
+
$ cat preload.rb
|
200
|
+
require 'simplecov'
|
201
|
+
|
202
|
+
SimpleCov.command_name 'raap'
|
203
|
+
SimpleCov.start do
|
204
|
+
enable_coverage :branch
|
205
|
+
add_filter "/test/"
|
206
|
+
end
|
207
|
+
|
208
|
+
$ bundle exec raap --preload ./preload.rb -r my_class 'MyClass'
|
209
|
+
```
|
210
|
+
|
153
211
|
## First support is CLI
|
154
212
|
|
155
213
|
In RaaP, usage through the CLI is the primary support focus, and efforts are made to maintain compatibility. The use of the library's code (such as `RaaP::Type`) does not guarantee compatibility.
|
data/lib/raap/cli.rb
CHANGED
@@ -12,6 +12,7 @@ module RaaP
|
|
12
12
|
:size_to,
|
13
13
|
:size_by,
|
14
14
|
:allow_private,
|
15
|
+
:coverage,
|
15
16
|
keyword_init: true
|
16
17
|
)
|
17
18
|
|
@@ -37,13 +38,11 @@ module RaaP
|
|
37
38
|
def initialize(argv)
|
38
39
|
# defaults
|
39
40
|
@option = Option.new(
|
40
|
-
dirs: [],
|
41
|
-
requires: [],
|
42
|
-
libraries: [],
|
43
41
|
timeout: 3,
|
44
42
|
size_from: 0,
|
45
43
|
size_to: 99,
|
46
44
|
size_by: 1,
|
45
|
+
coverage: true,
|
47
46
|
allow_private: false,
|
48
47
|
)
|
49
48
|
@argv = argv
|
@@ -54,13 +53,13 @@ module RaaP
|
|
54
53
|
def load
|
55
54
|
OptionParser.new do |o|
|
56
55
|
o.on('-I', '--include PATH') do |path|
|
57
|
-
|
56
|
+
RaaP::RBS.loader.add(path: Pathname(path))
|
58
57
|
end
|
59
58
|
o.on('--library lib', 'load rbs library') do |lib|
|
60
|
-
|
59
|
+
RaaP::RBS.loader.add(library: lib, version: nil)
|
61
60
|
end
|
62
61
|
o.on('--require lib', 'require ruby library') do |lib|
|
63
|
-
|
62
|
+
require lib
|
64
63
|
end
|
65
64
|
o.on('--log-level level', "default: info") do |arg|
|
66
65
|
RaaP.logger.level = arg
|
@@ -80,18 +79,14 @@ module RaaP
|
|
80
79
|
o.on('--allow-private', "default: #{@option.allow_private}") do
|
81
80
|
@option.allow_private = true
|
82
81
|
end
|
82
|
+
o.on('--preload path', 'Kernel.load path') do |path|
|
83
|
+
Kernel.load path
|
84
|
+
end
|
85
|
+
o.on('--[no-]coverage', "Show coverage for RBS (default: #{@option.coverage})") do |arg|
|
86
|
+
@option.coverage = arg
|
87
|
+
end
|
83
88
|
end.parse!(@argv)
|
84
89
|
|
85
|
-
@option.dirs.each do |dir|
|
86
|
-
RaaP::RBS.loader.add(path: Pathname(dir))
|
87
|
-
end
|
88
|
-
@option.libraries.each do |lib|
|
89
|
-
RaaP::RBS.loader.add(library: lib, version: nil)
|
90
|
-
end
|
91
|
-
@option.requires.each do |lib|
|
92
|
-
require lib
|
93
|
-
end
|
94
|
-
|
95
90
|
self
|
96
91
|
end
|
97
92
|
|
@@ -300,6 +295,7 @@ module RaaP
|
|
300
295
|
timeout: @option.timeout,
|
301
296
|
allow_private: @option.allow_private,
|
302
297
|
)
|
298
|
+
RaaP::Coverage.start(method_type) if @option.coverage
|
303
299
|
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
304
300
|
stats = prop.run do |called|
|
305
301
|
case called
|
@@ -337,6 +333,9 @@ module RaaP
|
|
337
333
|
end
|
338
334
|
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
339
335
|
puts
|
336
|
+
RaaP::Coverage.show($stdout) if @option.coverage
|
337
|
+
puts
|
338
|
+
|
340
339
|
time_diff = end_time - start_time
|
341
340
|
time = ", time: #{(time_diff * 1000).round}ms"
|
342
341
|
stats_log = "success: #{stats.success}, skip: #{stats.skip}, exception: #{stats.exception}#{time}"
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RaaP
|
4
|
+
module Coverage
|
5
|
+
class Writer
|
6
|
+
def initialize(method_type, cov)
|
7
|
+
@method_type = method_type
|
8
|
+
@cov = cov
|
9
|
+
@cur = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(io)
|
13
|
+
RaaP.logger.debug { "Coverage: #{@cov}" }
|
14
|
+
ml = @method_type.location
|
15
|
+
unless ml
|
16
|
+
RaaP.logger.warn("No location information for `#{@method_type}`")
|
17
|
+
return
|
18
|
+
end
|
19
|
+
if ml.key?(:keyword)
|
20
|
+
# attr_{reader,writer,accessor}
|
21
|
+
phantom_member = RBS.parse_member(ml.source)
|
22
|
+
case phantom_member
|
23
|
+
when ::RBS::AST::Members::Attribute
|
24
|
+
unless phantom_member.location
|
25
|
+
RaaP.logger.warn("No location information for `#{phantom_member}`")
|
26
|
+
return
|
27
|
+
end
|
28
|
+
write_type(io, "return", phantom_member.type)
|
29
|
+
io.write(slice(@cur, @cur...phantom_member.location.end_pos))
|
30
|
+
else
|
31
|
+
RaaP.logger.error("#{phantom_member.class} is not supported")
|
32
|
+
return
|
33
|
+
end
|
34
|
+
else
|
35
|
+
# def name: () -> type
|
36
|
+
phantom_method_type = RBS.parse_method_type(ml.source)
|
37
|
+
phantom_method_type.type.yield_self do |fun|
|
38
|
+
case fun
|
39
|
+
when ::RBS::Types::Function
|
40
|
+
fun.required_positionals.each_with_index { |param, i| write_param(io, "req_#{i}", param) }
|
41
|
+
fun.optional_positionals.each_with_index { |param, i| write_param(io, "opt_#{i}", param) }
|
42
|
+
fun.rest_positionals&.yield_self { |param| write_param(io, "rest", param) }
|
43
|
+
fun.trailing_positionals.each_with_index { |param, i| write_param(io, "trail_#{i}", param) }
|
44
|
+
fun.required_keywords.each { |key, param| write_param(io, "keyreq_#{key}", param) }
|
45
|
+
fun.optional_keywords.each { |key, param| write_param(io, "key_#{key}", param) }
|
46
|
+
fun.rest_keywords&.yield_self { |param| write_param(io, "keyrest", param) }
|
47
|
+
# when ::RBS::Types::UntypedFunction
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
phantom_method_type.block&.yield_self do |b|
|
52
|
+
b.type.each_param.with_index { |param, i| write_param(io, "block_param_#{i}", param) }
|
53
|
+
write_type(io, "block_return", b.type.return_type)
|
54
|
+
end
|
55
|
+
write_type(io, "return", phantom_method_type.type.return_type)
|
56
|
+
raise unless phantom_method_type.location
|
57
|
+
|
58
|
+
io.write(slice(@cur, @cur...phantom_method_type.location.end_pos))
|
59
|
+
end
|
60
|
+
|
61
|
+
io.puts
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def slice(start, range)
|
67
|
+
ml = @method_type.location
|
68
|
+
raise unless ml
|
69
|
+
|
70
|
+
ml.source[start, range.end - range.begin] or raise
|
71
|
+
end
|
72
|
+
|
73
|
+
def write_param(io, position, param)
|
74
|
+
write_type(io, position, param.type)
|
75
|
+
end
|
76
|
+
|
77
|
+
def write_type(io, position, type)
|
78
|
+
unless type.location
|
79
|
+
RaaP.logger.warn("No location information for `#{type}`")
|
80
|
+
return
|
81
|
+
end
|
82
|
+
io.write(slice(@cur, @cur...type.location.start_pos))
|
83
|
+
@cur = type.location.start_pos
|
84
|
+
case type
|
85
|
+
when ::RBS::Types::Tuple, ::RBS::Types::Union
|
86
|
+
name = type.class.name.split('::').last.downcase
|
87
|
+
type.types.each_with_index do |t, i|
|
88
|
+
t.location or raise
|
89
|
+
io.write(slice(@cur, @cur...t.location.start_pos)) # ( or [
|
90
|
+
@cur = t.location.start_pos
|
91
|
+
write_type(io, "#{position}_#{name}_#{i}", t)
|
92
|
+
end
|
93
|
+
when ::RBS::Types::Optional
|
94
|
+
raise unless type.location
|
95
|
+
|
96
|
+
write_type(io, "#{position}_optional_left", type.type)
|
97
|
+
io.write(slice(@cur, @cur...(type.location.end_pos - 1)))
|
98
|
+
@cur = type.location.end_pos - 1
|
99
|
+
if @cov.include?("#{position}_optional_right".to_sym)
|
100
|
+
io.write(green('?'))
|
101
|
+
else
|
102
|
+
io.write(red('?'))
|
103
|
+
end
|
104
|
+
raise unless type.location
|
105
|
+
|
106
|
+
@cur = type.location.end_pos
|
107
|
+
else
|
108
|
+
raise unless type.location
|
109
|
+
|
110
|
+
if @cov.include?(position.to_sym)
|
111
|
+
io.write(green(type.location.source))
|
112
|
+
else
|
113
|
+
io.write(red(type.location.source))
|
114
|
+
end
|
115
|
+
@cur = type.location.end_pos
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def green(str) = "\e[32m#{str}\e[0m"
|
120
|
+
def red(str) = "\e[1;4;41m#{str}\e[0m"
|
121
|
+
end
|
122
|
+
|
123
|
+
class << self
|
124
|
+
def start(method_type)
|
125
|
+
@cov = Set.new
|
126
|
+
@method_type = method_type
|
127
|
+
end
|
128
|
+
|
129
|
+
def running?
|
130
|
+
!!@cov
|
131
|
+
end
|
132
|
+
|
133
|
+
def log(position)
|
134
|
+
return unless running?
|
135
|
+
|
136
|
+
cov << position.to_sym
|
137
|
+
end
|
138
|
+
|
139
|
+
def cov
|
140
|
+
@cov or raise("Coverage is not started")
|
141
|
+
end
|
142
|
+
|
143
|
+
def show(io)
|
144
|
+
return unless running?
|
145
|
+
|
146
|
+
writer = Writer.new(@method_type, cov)
|
147
|
+
writer.write(io)
|
148
|
+
end
|
149
|
+
|
150
|
+
def new_type_with_log(position, type)
|
151
|
+
log_with_type(position, type) do |t|
|
152
|
+
Type.new(t)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def log_with_type(position, type, &block)
|
157
|
+
case type
|
158
|
+
when ::RBS::Types::Tuple
|
159
|
+
# FIXME: Support Union in Tuple
|
160
|
+
type.types.each_with_index do |_t, i|
|
161
|
+
log("#{position}_tuple_#{i}")
|
162
|
+
end
|
163
|
+
block&.call(type)
|
164
|
+
when ::RBS::Types::Union
|
165
|
+
i = Random.rand(type.types.length)
|
166
|
+
log_with_type("#{position}_union_#{i}", type.types[i], &block)
|
167
|
+
when ::RBS::Types::Optional
|
168
|
+
if Random.rand(2).zero?
|
169
|
+
log_with_type("#{position}_optional_left", type.type, &block)
|
170
|
+
else
|
171
|
+
log_with_type("#{position}_optional_right", ::RBS::Types::Bases::Nil.new(location: nil), &block)
|
172
|
+
end
|
173
|
+
else
|
174
|
+
log(position)
|
175
|
+
block&.call(type)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/lib/raap/function_type.rb
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
module RaaP
|
4
4
|
class FunctionType
|
5
|
-
def initialize(fun)
|
5
|
+
def initialize(fun, coverage: true)
|
6
6
|
@fun = fun
|
7
|
+
@coverage = coverage
|
7
8
|
end
|
8
9
|
|
9
10
|
def pick_arguments(size: 10)
|
@@ -26,42 +27,66 @@ module RaaP
|
|
26
27
|
when type.respond_to?(:each_pair)
|
27
28
|
type.each_pair.to_h { |k, v| [k, to_symbolic_call_recursive(v, size: size)] }
|
28
29
|
when type.respond_to?(:each)
|
29
|
-
type.
|
30
|
+
type.map { |v| to_symbolic_call_recursive(v, size: size) }
|
30
31
|
else
|
31
32
|
type.to_symbolic_call(size: size)
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
36
|
def build_args_type
|
36
|
-
reqs = @fun.required_positionals.map
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
reqs = @fun.required_positionals.map.with_index do |param, i|
|
38
|
+
build_type_with_coverage("req_#{i}", param)
|
39
|
+
end
|
40
|
+
|
41
|
+
take_num = Random.rand(@fun.optional_positionals.length + 1)
|
42
|
+
opts = @fun.optional_positionals.take(take_num).map.each_with_index do |param, i|
|
43
|
+
build_type_with_coverage("opt_#{i}", param)
|
44
|
+
end
|
45
|
+
|
40
46
|
rest = []
|
41
|
-
if (
|
42
|
-
rest = Array.new(Random.rand(
|
47
|
+
if (rest_param = @fun.rest_positionals)
|
48
|
+
rest = Array.new(Random.rand(4)) do
|
49
|
+
build_type_with_coverage("rest", rest_param)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
tras = @fun.trailing_positionals.map.with_index do |param, i|
|
54
|
+
build_type_with_coverage("trail_#{i}", param)
|
43
55
|
end
|
56
|
+
|
44
57
|
[reqs, opts, rest, tras].flatten
|
45
58
|
end
|
46
59
|
|
47
60
|
def build_kwargs_type
|
48
|
-
reqs = @fun.required_keywords.
|
61
|
+
reqs = @fun.required_keywords.keys.to_h do |key|
|
62
|
+
[key, build_type_with_coverage("keyreq_#{key}", @fun.required_keywords[key])]
|
63
|
+
end
|
49
64
|
rand = Random.rand(@fun.optional_keywords.length + 1)
|
50
|
-
opts = @fun.optional_keywords.to_a.sample(rand).to_h
|
65
|
+
opts = @fun.optional_keywords.to_a.sample(rand).to_h do |key, param|
|
66
|
+
[key, build_type_with_coverage("key_#{key}", param)]
|
67
|
+
end
|
51
68
|
kwargs = reqs.to_h.merge(opts)
|
52
69
|
if (param = @fun.rest_keywords)
|
53
|
-
keys = Array.new(Random.rand(
|
70
|
+
keys = Array.new(Random.rand(4)) do
|
54
71
|
random_key = nil
|
55
72
|
loop do
|
56
73
|
# @type var random_key: Symbol
|
57
74
|
random_key = Type.new("Symbol").pick(size: 6)
|
58
75
|
break unless kwargs.key?(random_key)
|
59
76
|
end
|
60
|
-
[random_key,
|
77
|
+
[random_key, build_type_with_coverage("keyrest", param)]
|
61
78
|
end
|
62
79
|
kwargs.merge!(keys.to_h)
|
63
80
|
end
|
64
81
|
kwargs
|
65
82
|
end
|
83
|
+
|
84
|
+
def build_type_with_coverage(position, param)
|
85
|
+
if @coverage
|
86
|
+
Coverage.new_type_with_log(position, param.type)
|
87
|
+
else
|
88
|
+
Type.new(param.type)
|
89
|
+
end
|
90
|
+
end
|
66
91
|
end
|
67
92
|
end
|
data/lib/raap/method_property.rb
CHANGED
@@ -50,7 +50,7 @@ module RaaP
|
|
50
50
|
private
|
51
51
|
|
52
52
|
def call(size:, stats:)
|
53
|
-
if @method_type.rbs.type.each_type.find { |t| t.instance_of?(::RBS::Types::Bases::Any) }
|
53
|
+
if @method_type.rbs.type.each_param.find { |param| param.type.each_type.find { |t| t.instance_of?(::RBS::Types::Bases::Any) } }
|
54
54
|
RaaP.logger.info { "Skip type check since `#{@method_type.rbs}` includes `untyped`" }
|
55
55
|
stats.break = true
|
56
56
|
throw :break
|
@@ -67,8 +67,9 @@ module RaaP
|
|
67
67
|
begin
|
68
68
|
return_value = symbolic_caller.eval
|
69
69
|
rescue StandardError, NotImplementedError
|
70
|
-
check = [:success]
|
71
70
|
return_value = Value::Bottom.new
|
71
|
+
coverage("return", return_value, return_type)
|
72
|
+
check = [:success]
|
72
73
|
rescue Timeout::ExitException
|
73
74
|
raise
|
74
75
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
@@ -113,6 +114,7 @@ module RaaP
|
|
113
114
|
if BindCall.is_a?(return_type, ::RBS::Types::ClassSingleton)
|
114
115
|
# ::RBS::Test::TypeCheck cannot support to check singleton class
|
115
116
|
if receiver_value == return_value
|
117
|
+
coverage("return", return_value, return_type)
|
116
118
|
[:success]
|
117
119
|
else
|
118
120
|
[:failure]
|
@@ -135,6 +137,7 @@ module RaaP
|
|
135
137
|
)
|
136
138
|
begin
|
137
139
|
if type_check.value(return_value, return_type)
|
140
|
+
coverage("return", return_value, return_type, type_check)
|
138
141
|
[:success]
|
139
142
|
else
|
140
143
|
[:failure]
|
@@ -148,5 +151,33 @@ module RaaP
|
|
148
151
|
def return_type
|
149
152
|
@method_type.rbs.type.return_type
|
150
153
|
end
|
154
|
+
|
155
|
+
def coverage(position, return_value, return_type, type_check = nil)
|
156
|
+
return unless Coverage.running?
|
157
|
+
|
158
|
+
case return_type
|
159
|
+
when ::RBS::Types::Tuple
|
160
|
+
return_type.types.zip(return_value).each_with_index do |(type, value), i|
|
161
|
+
if type_check&.value(value, type)
|
162
|
+
coverage("#{position}_tuple_#{i}", value, type, type_check)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
when ::RBS::Types::Union
|
166
|
+
return_type.types.each_with_index do |type, i|
|
167
|
+
if type_check&.value(return_value, type)
|
168
|
+
coverage("#{position}_union_#{i}", return_value, type, type_check)
|
169
|
+
break
|
170
|
+
end
|
171
|
+
end
|
172
|
+
when ::RBS::Types::Optional
|
173
|
+
if return_value.nil?
|
174
|
+
Coverage.log("#{position}_optional_right")
|
175
|
+
else
|
176
|
+
coverage("#{position}_optional_left", return_value, return_type.type, type_check)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
Coverage.log(position)
|
180
|
+
end
|
181
|
+
end
|
151
182
|
end
|
152
183
|
end
|
data/lib/raap/method_type.rb
CHANGED
@@ -19,9 +19,17 @@ module RaaP
|
|
19
19
|
|
20
20
|
params = (type_params_decl + rbs.type_params).uniq
|
21
21
|
ts = TypeSubstitution.new(params, type_args)
|
22
|
-
|
23
22
|
@rbs = ts.method_type_sub(rbs, self_type: self_type, instance_type: instance_type, class_type: class_type)
|
24
|
-
|
23
|
+
function_or_untypedfunction = __skip__ = @rbs.type
|
24
|
+
@fun_type = FunctionType.new(function_or_untypedfunction)
|
25
|
+
@type_check = ::RBS::Test::TypeCheck.new(
|
26
|
+
self_class: (_ = self_type),
|
27
|
+
instance_class: (_ = instance_type),
|
28
|
+
class_class: (_ = class_type),
|
29
|
+
builder: RBS.builder,
|
30
|
+
sample_size: 100,
|
31
|
+
unchecked_classes: []
|
32
|
+
)
|
25
33
|
end
|
26
34
|
|
27
35
|
def pick_arguments(size: 10)
|
@@ -40,21 +48,63 @@ module RaaP
|
|
40
48
|
return nil if block.nil?
|
41
49
|
return nil if (block.required == false) && [true, false].sample
|
42
50
|
|
51
|
+
args_name = []
|
52
|
+
args_source = []
|
53
|
+
resource = [*'a'..'z']
|
54
|
+
case fun = block.type
|
55
|
+
when ::RBS::Types::Function
|
56
|
+
# FIXME: Support keyword types
|
57
|
+
fun.required_positionals.each do
|
58
|
+
resource.shift.tap do |name|
|
59
|
+
args_name << name
|
60
|
+
args_source << name
|
61
|
+
end
|
62
|
+
end
|
63
|
+
fun.optional_positionals.each do |param|
|
64
|
+
resource.shift.tap do |name|
|
65
|
+
# FIXME: Support without literal type
|
66
|
+
default = Type.new(param.type).pick(size: size)
|
67
|
+
args_name << name
|
68
|
+
args_source << "#{name} = #{default}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
fun.rest_positionals&.yield_self do |_|
|
72
|
+
resource.shift.tap do |name|
|
73
|
+
args_name << "*#{name}"
|
74
|
+
args_source << "*#{name}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
fun.trailing_positionals.each do
|
78
|
+
resource.shift.tap do |name|
|
79
|
+
args_name << name
|
80
|
+
args_source << name
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
# Hack: Use local variable in eval
|
43
85
|
fixed_return_value = Type.new(block.type.return_type).pick(size: size)
|
44
|
-
|
86
|
+
_ = fixed_return_value
|
87
|
+
type_check = @type_check
|
88
|
+
_ = type_check
|
89
|
+
eval(<<~RUBY) # rubocop:disable Security/Eval
|
90
|
+
-> (#{args_source.join(', ')}) do
|
91
|
+
i = 0
|
92
|
+
type_check.zip_args([#{args_name.join(', ')}], block.type) do |val, param|
|
93
|
+
unless type_check.value(val, param.type)
|
94
|
+
raise TypeError, "block argument type mismatch: expected `(\#{fun.param_to_s})`, got \#{BindCall.inspect([#{args_name.join(', ')}])}"
|
95
|
+
end
|
96
|
+
|
97
|
+
Coverage.log_with_type("block_param_\#{i}", param.type)
|
98
|
+
i += 1
|
99
|
+
end
|
100
|
+
Coverage.log_with_type("block_return", block.type.return_type)
|
101
|
+
fixed_return_value
|
102
|
+
end
|
103
|
+
RUBY
|
45
104
|
end
|
46
105
|
|
47
106
|
def check_return(return_value)
|
48
|
-
|
49
|
-
type_check = ::RBS::Test::TypeCheck.new(
|
50
|
-
self_class: untyped, # cannot support `self`
|
51
|
-
instance_class: untyped, # cannot support `instance`
|
52
|
-
class_class: untyped, # cannot support `class`
|
53
|
-
builder: RBS.builder,
|
54
|
-
sample_size: 100,
|
55
|
-
unchecked_classes: []
|
56
|
-
)
|
57
|
-
type_check.value(return_value, rbs.type.return_type)
|
107
|
+
@type_check.value(return_value, rbs.type.return_type)
|
58
108
|
end
|
59
109
|
end
|
60
110
|
end
|
data/lib/raap/rbs.rb
CHANGED
@@ -26,6 +26,48 @@ module RaaP
|
|
26
26
|
::RBS::Parser.parse_method_type(method_type, require_eof: true) or raise
|
27
27
|
end
|
28
28
|
|
29
|
+
def self.parse_member(member_type)
|
30
|
+
_, _, decls = ::RBS::Parser.parse_signature(<<~RBS)
|
31
|
+
module MemberScope
|
32
|
+
#{member_type}
|
33
|
+
end
|
34
|
+
RBS
|
35
|
+
decl = decls.first or raise
|
36
|
+
raise unless decl.is_a?(::RBS::AST::Declarations::Module)
|
37
|
+
|
38
|
+
member = decl.members.first or raise
|
39
|
+
raise unless member.is_a?(::RBS::AST::Members::Attribute)
|
40
|
+
|
41
|
+
member.tap do |m|
|
42
|
+
m = __skip__ = m
|
43
|
+
_shift_location(m.type, -m.location.start_pos)
|
44
|
+
_shift_location(m, -m.location.start_pos)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self._shift_location(localable, shift)
|
49
|
+
return if localable.location.nil?
|
50
|
+
|
51
|
+
l = localable.instance_variable_get("@location")
|
52
|
+
localable.instance_variable_set(
|
53
|
+
"@location",
|
54
|
+
::RBS::Location.new(
|
55
|
+
buffer: ::RBS::Buffer.new(
|
56
|
+
name: l.buffer.name,
|
57
|
+
content: l.buffer.content[-shift..l.end_pos],
|
58
|
+
),
|
59
|
+
start_pos: l.start_pos + shift,
|
60
|
+
end_pos: l.end_pos + shift,
|
61
|
+
)
|
62
|
+
)
|
63
|
+
case localable
|
64
|
+
when ::RBS::Types::Union
|
65
|
+
localable.types.each { |t| _shift_location(t, shift) }
|
66
|
+
when ::RBS::Types::Optional
|
67
|
+
_shift_location(localable.type, shift)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
29
71
|
def self.find_alias_decl(type_name, method_name)
|
30
72
|
env.class_decls[type_name].decls.each do |d|
|
31
73
|
d.decl.members.each do |member|
|
data/lib/raap/type.rb
CHANGED
@@ -24,6 +24,7 @@ module RaaP
|
|
24
24
|
def self.register(type_name, &block)
|
25
25
|
raise ArgumentError, "block is required" unless block
|
26
26
|
|
27
|
+
type_name = "::#{type_name}" if !type_name.start_with?("::")
|
27
28
|
GENERATORS[type_name] = __skip__ = block
|
28
29
|
end
|
29
30
|
|
@@ -69,11 +70,12 @@ module RaaP
|
|
69
70
|
t = instance.args[0] ? Type.new(instance.args[0], range: range) : Type.random
|
70
71
|
array(t)
|
71
72
|
end
|
72
|
-
register("::Binding") {
|
73
|
+
register("::Binding") { binding }
|
73
74
|
register("::Complex") { complex }
|
74
|
-
register("::Data") {
|
75
|
+
register("::Data") { Data.define }
|
75
76
|
register("::Encoding") { encoding }
|
76
|
-
register("::FalseClass") {
|
77
|
+
register("::FalseClass") { false }
|
78
|
+
register("::File") { File.open("/dev/null") }
|
77
79
|
register("::Float") { float }
|
78
80
|
register("::Hash") do
|
79
81
|
instance = __skip__ = type
|
@@ -82,18 +84,18 @@ module RaaP
|
|
82
84
|
dict(key, value)
|
83
85
|
end
|
84
86
|
register("::Integer") { integer }
|
85
|
-
register("::IO") {
|
86
|
-
register("::Method") {
|
87
|
-
register("::NilClass") {
|
88
|
-
register("::Proc") {
|
87
|
+
register("::IO") { $stdout }
|
88
|
+
register("::Method") { temp_method_object }
|
89
|
+
register("::NilClass") { nil }
|
90
|
+
register("::Proc") { Proc.new {} }
|
89
91
|
register("::Rational") { rational }
|
90
92
|
register("::Regexp") { sized { |size| Regexp.new(string.pick(size: size)) } }
|
91
93
|
register("::String") { string }
|
92
|
-
register("::Struct") {
|
94
|
+
register("::Struct") { Struct.new(:foo, :bar).new }
|
93
95
|
register("::Symbol") { symbol }
|
94
|
-
register("::Time") {
|
95
|
-
register("::TrueClass") {
|
96
|
-
register("::UnboundMethod") {
|
96
|
+
register("::Time") { [:call, Time, :now, [], {}, nil] }
|
97
|
+
register("::TrueClass") { true }
|
98
|
+
register("::UnboundMethod") { temp_method_object.unbind }
|
97
99
|
|
98
100
|
attr_reader :type
|
99
101
|
attr_reader :range
|
@@ -176,7 +178,7 @@ module RaaP
|
|
176
178
|
Object.const_get(type.name.to_s)
|
177
179
|
when ::RBS::Types::ClassInstance
|
178
180
|
case gen = GENERATORS[type.name.absolute!.to_s]
|
179
|
-
in Proc then
|
181
|
+
in Proc then pick_by_generator(gen, size: size)
|
180
182
|
in nil then to_symbolic_call_from_initialize(type, size: size)
|
181
183
|
end
|
182
184
|
when ::RBS::Types::Record
|
@@ -186,7 +188,7 @@ module RaaP
|
|
186
188
|
when ::RBS::Types::Literal
|
187
189
|
type.literal
|
188
190
|
when ::RBS::Types::Bases::Bool
|
189
|
-
bool
|
191
|
+
bool
|
190
192
|
when ::RBS::Types::Bases::Any
|
191
193
|
Type.random.to_symbolic_call(size: size)
|
192
194
|
when ::RBS::Types::Bases::Nil
|
@@ -198,6 +200,16 @@ module RaaP
|
|
198
200
|
|
199
201
|
private
|
200
202
|
|
203
|
+
def pick_by_generator(gen, size:)
|
204
|
+
ret = instance_exec(&gen)
|
205
|
+
case ret
|
206
|
+
when Sized
|
207
|
+
ret.pick(size: size)
|
208
|
+
else
|
209
|
+
ret
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
201
213
|
def to_symbolic_call_from_initialize(type, size:)
|
202
214
|
type_name = type.name.absolute!
|
203
215
|
const = Object.const_get(type_name.to_s)
|
@@ -301,16 +313,12 @@ module RaaP
|
|
301
313
|
end
|
302
314
|
|
303
315
|
def encoding
|
304
|
-
|
305
|
-
|
306
|
-
[:call, Encoding, :find, [e.name], {}, nil]
|
307
|
-
end
|
316
|
+
e = Encoding.list.sample or raise
|
317
|
+
[:call, Encoding, :find, [e.name], {}, nil]
|
308
318
|
end
|
309
319
|
|
310
320
|
def bool
|
311
|
-
|
312
|
-
Random.rand(2) == 0
|
313
|
-
end
|
321
|
+
Random.rand(2) == 0
|
314
322
|
end
|
315
323
|
|
316
324
|
def temp_method_object
|
@@ -25,6 +25,10 @@ module RaaP
|
|
25
25
|
instance_type = instance_type.is_a?(::String) ? RBS.parse_type(instance_type) : instance_type
|
26
26
|
class_type = class_type.is_a?(::String) ? RBS.parse_type(class_type) : class_type
|
27
27
|
sub = build
|
28
|
+
if sub.empty? && self_type.nil? && instance_type.nil? && class_type.nil?
|
29
|
+
return method_type
|
30
|
+
end
|
31
|
+
|
28
32
|
::RBS::MethodType.new(
|
29
33
|
type_params: [],
|
30
34
|
type: method_type.type.sub(sub).then { |ty| sub(ty, self_type: self_type, instance_type: instance_type, class_type: class_type) },
|
data/lib/raap/value/interface.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module RaaP
|
4
4
|
module Value
|
5
|
-
class Interface
|
5
|
+
class Interface
|
6
6
|
class << self
|
7
|
-
def define_method_from_interface(
|
7
|
+
def define_method_from_interface(base_mod, type, size: 3)
|
8
8
|
type = type.is_a?(::String) ? RBS.parse_type(type) : type
|
9
9
|
unless type.instance_of?(::RBS::Types::Interface)
|
10
10
|
::Kernel.raise ::TypeError, "not an interface type: #{type}"
|
@@ -22,7 +22,7 @@ module RaaP
|
|
22
22
|
ts = TypeSubstitution.new(type_params, type.args)
|
23
23
|
subed_method_type = ts.method_type_sub(method_type, self_type: self_type, instance_type: instance_type, class_type: class_type)
|
24
24
|
|
25
|
-
BindCall.define_method(
|
25
|
+
BindCall.define_method(base_mod, name) do |*_, &b|
|
26
26
|
@fixed_return_value ||= {}
|
27
27
|
@fixed_return_value[name] ||= if self_type == subed_method_type.type.return_type
|
28
28
|
self
|
@@ -30,16 +30,13 @@ module RaaP
|
|
30
30
|
Type.new(subed_method_type.type.return_type).pick(size: size)
|
31
31
|
end
|
32
32
|
# @type var b: Proc?
|
33
|
-
if b
|
33
|
+
if b && subed_method_type.block && subed_method_type.block.type.is_a?(::RBS::Types::Function)
|
34
34
|
@fixed_block_arguments ||= {}
|
35
|
-
@fixed_block_arguments[name] ||=
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
else
|
41
|
-
[]
|
42
|
-
end
|
35
|
+
@fixed_block_arguments[name] ||= size.times.map do
|
36
|
+
FunctionType.new(subed_method_type.block.type, coverage: false)
|
37
|
+
.pick_arguments(size: size)
|
38
|
+
end
|
39
|
+
|
43
40
|
@fixed_block_arguments[name].each do |a, kw|
|
44
41
|
b.call(*a, **kw)
|
45
42
|
end
|
@@ -68,14 +65,6 @@ module RaaP
|
|
68
65
|
@size = size
|
69
66
|
end
|
70
67
|
|
71
|
-
def respond_to?(name, _include_all = false)
|
72
|
-
@definition.methods.has_key?(name.to_sym)
|
73
|
-
end
|
74
|
-
|
75
|
-
def class
|
76
|
-
Interface
|
77
|
-
end
|
78
|
-
|
79
68
|
def inspect
|
80
69
|
"#<interface @type=`#{@type}` @methods=#{@definition.methods.keys} @size=#{@size}>"
|
81
70
|
end
|
@@ -17,19 +17,18 @@ module RaaP
|
|
17
17
|
raise ArgumentError, "intersection type must have at least one class instance type in `#{instances}`"
|
18
18
|
end
|
19
19
|
|
20
|
-
base = instances.find { |c| c.is_a?(::Class) } ||
|
20
|
+
base = instances.find { |c| c.is_a?(::Class) } || Object
|
21
21
|
|
22
22
|
c = Class.new(base) do
|
23
23
|
instances.select { |i| !i.is_a?(::Class) }.each do |m|
|
24
24
|
include(m)
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
t
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
Interface.define_method_from_interface(self, interface, size: size)
|
27
|
+
type.types.each do |t|
|
28
|
+
case t
|
29
|
+
when ::RBS::Types::Interface
|
30
|
+
Interface.define_method_from_interface(self, t, size: size)
|
31
|
+
end
|
33
32
|
end
|
34
33
|
end
|
35
34
|
type = ::RBS::Types::ClassInstance.new(name: TypeName(base.name), args: [], location: nil)
|
data/lib/raap/value/variable.rb
CHANGED
data/lib/raap/version.rb
CHANGED
data/lib/raap.rb
CHANGED
@@ -23,6 +23,7 @@ module RaaP
|
|
23
23
|
|
24
24
|
autoload :BindCall, "raap/bind_call"
|
25
25
|
autoload :CLI, "raap/cli"
|
26
|
+
autoload :Coverage, "raap/coverage"
|
26
27
|
autoload :FunctionType, "raap/function_type"
|
27
28
|
autoload :MethodProperty, "raap/method_property"
|
28
29
|
autoload :MethodType, "raap/method_type"
|
data/public/example.webp
ADDED
Binary file
|
data/sig/raap.rbs
CHANGED
@@ -19,21 +19,15 @@ module RaaP
|
|
19
19
|
|
20
20
|
class CLI
|
21
21
|
class Option < ::Struct[untyped]
|
22
|
-
def self.new: (?
|
22
|
+
def self.new: (?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer, ?allow_private: bool, ?coverage: bool) -> instance
|
23
23
|
|
24
|
-
def self.[]: (?
|
24
|
+
def self.[]: (?timeout: (Integer | Float | nil), ?size_from: ::Integer, ?size_to: ::Integer, ?size_by: ::Integer, ?allow_private: bool, ?coverage: bool) -> instance
|
25
25
|
|
26
26
|
def self.keyword_init?: () -> true
|
27
27
|
|
28
|
-
def self.members: () -> [ :
|
28
|
+
def self.members: () -> [ :timeout, :size_from, :size_to, :size_by, :allow_private, :coverage]
|
29
29
|
|
30
|
-
def members: () -> [ :
|
31
|
-
|
32
|
-
attr_accessor dirs: ::Array[String]
|
33
|
-
|
34
|
-
attr_accessor requires: ::Array[String]
|
35
|
-
|
36
|
-
attr_accessor libraries: ::Array[String]
|
30
|
+
def members: () -> [ :timeout, :size_from, :size_to, :size_by, :allow_private, :coverage]
|
37
31
|
|
38
32
|
attr_accessor timeout: (Integer | Float | nil)
|
39
33
|
|
@@ -44,6 +38,8 @@ module RaaP
|
|
44
38
|
attr_accessor size_by: ::Integer
|
45
39
|
|
46
40
|
attr_accessor allow_private: bool
|
41
|
+
|
42
|
+
attr_accessor coverage: bool
|
47
43
|
end
|
48
44
|
|
49
45
|
type property_result = [Integer, Symbol, ::RBS::MethodType, StringIO?]
|
@@ -71,10 +67,44 @@ module RaaP
|
|
71
67
|
def report: () -> Integer
|
72
68
|
end
|
73
69
|
|
70
|
+
module Coverage
|
71
|
+
type locs = [::RBS::Buffer::loc, ::RBS::Buffer::loc]
|
72
|
+
class Writer
|
73
|
+
@method_type: ::RBS::MethodType
|
74
|
+
@cov: ::Set[Symbol]
|
75
|
+
@cur: Integer
|
76
|
+
|
77
|
+
def initialize: (::RBS::MethodType, Set[Symbol]) -> void
|
78
|
+
def write: (IO) -> void
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def method_type_location: () -> ::RBS::Location[untyped, untyped]
|
83
|
+
def slice: (Integer, Range[Integer]) -> String
|
84
|
+
def write_param: (IO, String, ::RBS::Types::Function::Param) -> void
|
85
|
+
def write_type: (IO, String, ::RBS::Types::t) -> void
|
86
|
+
def green: (String) -> String
|
87
|
+
def red: (String) -> String
|
88
|
+
end
|
89
|
+
|
90
|
+
self.@cov: Set[Symbol]?
|
91
|
+
self.@method_type: ::RBS::MethodType
|
92
|
+
|
93
|
+
def self.start: (::RBS::MethodType) -> void
|
94
|
+
def self.running?: () -> bool
|
95
|
+
def self.log: (String | Symbol) -> void
|
96
|
+
def self.cov: () -> Set[Symbol]
|
97
|
+
def self.show: (IO) -> void
|
98
|
+
def self.new_type_with_log: (String, ::RBS::Types::t) -> Type
|
99
|
+
def self.log_with_type: (String, ::RBS::Types::t) -> nil
|
100
|
+
| (String, ::RBS::Types::t) ?{ (::RBS::Types::t) -> Type } -> Type
|
101
|
+
end
|
102
|
+
|
74
103
|
class FunctionType
|
75
104
|
@fun: ::RBS::Types::Function
|
105
|
+
@coverage: boolish
|
76
106
|
|
77
|
-
def initialize: (::RBS::Types::Function) -> void
|
107
|
+
def initialize: (::RBS::Types::Function, ?coverage: boolish) -> void
|
78
108
|
def pick_arguments: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped]]
|
79
109
|
def arguments_to_symbolic_call: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped]]
|
80
110
|
|
@@ -83,6 +113,7 @@ module RaaP
|
|
83
113
|
def to_symbolic_call_recursive: (untyped, size: Integer) -> untyped
|
84
114
|
def build_args_type: () -> Array[Type]
|
85
115
|
def build_kwargs_type: () -> Hash[Symbol, Type]
|
116
|
+
def build_type_with_coverage: (String, ::RBS::Types::Function::Param) -> Type
|
86
117
|
end
|
87
118
|
|
88
119
|
class MethodProperty
|
@@ -108,11 +139,14 @@ module RaaP
|
|
108
139
|
def call: (size: Integer, stats: Stats) -> (Result::Success | Result::Failure | Result::Skip | Result::Exception)
|
109
140
|
def check_return: (receiver_value: untyped, return_value: untyped) -> ([Symbol] | [Symbol, Exception])
|
110
141
|
def return_type: () -> RBS::Types::t
|
142
|
+
def original_return_type: () -> RBS::Types::t
|
143
|
+
def coverage: (String, untyped, RBS::Types::t, ?RBS::Test::TypeCheck?) -> void
|
111
144
|
end
|
112
145
|
|
113
146
|
class MethodType
|
114
147
|
attr_reader rbs: ::RBS::MethodType
|
115
148
|
@fun_type: FunctionType
|
149
|
+
@type_check: ::RBS::Test::TypeCheck
|
116
150
|
|
117
151
|
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
|
118
152
|
def pick_arguments: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped], ::Proc?]
|
@@ -134,6 +168,8 @@ module RaaP
|
|
134
168
|
def self.loader: () -> ::RBS::EnvironmentLoader
|
135
169
|
def self.parse_type: (String) -> ::RBS::Types::t
|
136
170
|
def self.parse_method_type: (String) -> ::RBS::MethodType
|
171
|
+
def self.parse_member: (String) -> ::RBS::AST::Members::Attribute
|
172
|
+
def self._shift_location: (untyped, Integer) -> void
|
137
173
|
def self.find_alias_decl: (::RBS::TypeName, Symbol) -> ::RBS::AST::Members::Alias?
|
138
174
|
end
|
139
175
|
|
@@ -242,7 +278,7 @@ module RaaP
|
|
242
278
|
GENERATORS: Hash[String, ^() -> Sized[untyped]]
|
243
279
|
SIMPLE_SOURCE: Array[String]
|
244
280
|
|
245
|
-
def self.register: (String) { () [self: instance] ->
|
281
|
+
def self.register: (String) { () [self: instance] -> untyped } -> void
|
246
282
|
def self.random: () -> Type
|
247
283
|
def self.random_without_basic_object: () -> Type
|
248
284
|
def self.call_new_from: (Module, ::RBS::Types::ClassInstance, size: Integer) -> symbolic_call
|
@@ -278,8 +314,8 @@ module RaaP
|
|
278
314
|
def symbol: () -> Sized[Symbol]
|
279
315
|
def array: (Type) -> Sized[Array[untyped]]
|
280
316
|
def dict: (Type, Type) -> Sized[Hash[untyped, untyped]]
|
281
|
-
def encoding: () ->
|
282
|
-
def bool: () ->
|
317
|
+
def encoding: () -> symbolic_call
|
318
|
+
def bool: () -> bool
|
283
319
|
def temp_method_object: () -> ::Method
|
284
320
|
end
|
285
321
|
|
@@ -289,19 +325,19 @@ module RaaP
|
|
289
325
|
def class: () -> class
|
290
326
|
end
|
291
327
|
|
292
|
-
class Interface
|
328
|
+
class Interface
|
293
329
|
@type: ::RBS::Types::Interface
|
294
330
|
@size: Integer
|
295
331
|
@definition: ::RBS::Definition
|
296
332
|
|
297
|
-
def self.define_method_from_interface: (
|
333
|
+
def self.define_method_from_interface: (::Module base_class, String | ::RBS::Types::Interface type, ?size: Integer) -> void
|
298
334
|
def initialize: (String | ::RBS::Types::Interface | String, ?size: Integer) -> void
|
299
335
|
def respond_to?: (Symbol, ?boolish) -> bool
|
300
336
|
def inspect: () -> String
|
301
337
|
def class: () -> class
|
302
338
|
end
|
303
339
|
|
304
|
-
|
340
|
+
module Intersection
|
305
341
|
@type: ::RBS::Types::Intersection
|
306
342
|
@children: Array[Type]
|
307
343
|
@size: Integer
|
@@ -328,7 +364,7 @@ module RaaP
|
|
328
364
|
def class: () -> class
|
329
365
|
end
|
330
366
|
|
331
|
-
class Variable
|
367
|
+
class Variable
|
332
368
|
attr_reader type: ::RBS::Types::Variable
|
333
369
|
|
334
370
|
def initialize: (::RBS::Types::Variable | String | Symbol) -> 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.8.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-
|
11
|
+
date: 2024-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rbs
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- lib/raap.rb
|
58
58
|
- lib/raap/bind_call.rb
|
59
59
|
- lib/raap/cli.rb
|
60
|
+
- lib/raap/coverage.rb
|
60
61
|
- lib/raap/function_type.rb
|
61
62
|
- lib/raap/method_property.rb
|
62
63
|
- lib/raap/method_type.rb
|
@@ -77,6 +78,7 @@ files:
|
|
77
78
|
- lib/raap/value/void.rb
|
78
79
|
- lib/raap/version.rb
|
79
80
|
- lib/shims.rb
|
81
|
+
- public/example.webp
|
80
82
|
- public/jacket.webp
|
81
83
|
- rbs_collection.lock.yaml
|
82
84
|
- rbs_collection.yaml
|
@@ -102,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
104
|
- !ruby/object:Gem::Version
|
103
105
|
version: '0'
|
104
106
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
107
|
+
rubygems_version: 3.5.9
|
106
108
|
signing_key:
|
107
109
|
specification_version: 4
|
108
110
|
summary: RBS as a Property
|