raap 0.7.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/README.md +4 -0
- data/lib/raap/cli.rb +3 -16
- data/lib/raap/coverage.rb +28 -36
- data/lib/raap/function_type.rb +7 -2
- data/lib/raap/method_property.rb +1 -1
- data/lib/raap/method_type.rb +61 -20
- data/lib/raap/value/interface.rb +1 -1
- data/lib/raap/version.rb +1 -1
- data/sig/raap.rbs +11 -16
- metadata +2 -2
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/README.md
CHANGED
data/lib/raap/cli.rb
CHANGED
@@ -38,9 +38,6 @@ module RaaP
|
|
38
38
|
def initialize(argv)
|
39
39
|
# defaults
|
40
40
|
@option = Option.new(
|
41
|
-
dirs: [],
|
42
|
-
requires: [],
|
43
|
-
libraries: [],
|
44
41
|
timeout: 3,
|
45
42
|
size_from: 0,
|
46
43
|
size_to: 99,
|
@@ -56,13 +53,13 @@ module RaaP
|
|
56
53
|
def load
|
57
54
|
OptionParser.new do |o|
|
58
55
|
o.on('-I', '--include PATH') do |path|
|
59
|
-
|
56
|
+
RaaP::RBS.loader.add(path: Pathname(path))
|
60
57
|
end
|
61
58
|
o.on('--library lib', 'load rbs library') do |lib|
|
62
|
-
|
59
|
+
RaaP::RBS.loader.add(library: lib, version: nil)
|
63
60
|
end
|
64
61
|
o.on('--require lib', 'require ruby library') do |lib|
|
65
|
-
|
62
|
+
require lib
|
66
63
|
end
|
67
64
|
o.on('--log-level level', "default: info") do |arg|
|
68
65
|
RaaP.logger.level = arg
|
@@ -90,16 +87,6 @@ module RaaP
|
|
90
87
|
end
|
91
88
|
end.parse!(@argv)
|
92
89
|
|
93
|
-
@option.dirs.each do |dir|
|
94
|
-
RaaP::RBS.loader.add(path: Pathname(dir))
|
95
|
-
end
|
96
|
-
@option.libraries.each do |lib|
|
97
|
-
RaaP::RBS.loader.add(library: lib, version: nil)
|
98
|
-
end
|
99
|
-
@option.requires.each do |lib|
|
100
|
-
require lib
|
101
|
-
end
|
102
|
-
|
103
90
|
self
|
104
91
|
end
|
105
92
|
|
data/lib/raap/coverage.rb
CHANGED
@@ -25,7 +25,7 @@ module RaaP
|
|
25
25
|
RaaP.logger.warn("No location information for `#{phantom_member}`")
|
26
26
|
return
|
27
27
|
end
|
28
|
-
write_type(io, "return", phantom_member.type
|
28
|
+
write_type(io, "return", phantom_member.type)
|
29
29
|
io.write(slice(@cur, @cur...phantom_member.location.end_pos))
|
30
30
|
else
|
31
31
|
RaaP.logger.error("#{phantom_member.class} is not supported")
|
@@ -37,22 +37,22 @@ module RaaP
|
|
37
37
|
phantom_method_type.type.yield_self do |fun|
|
38
38
|
case fun
|
39
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
|
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
47
|
# when ::RBS::Types::UntypedFunction
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
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
|
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
54
|
end
|
55
|
-
write_type(io, "return", phantom_method_type.type.return_type
|
55
|
+
write_type(io, "return", phantom_method_type.type.return_type)
|
56
56
|
raise unless phantom_method_type.location
|
57
57
|
|
58
58
|
io.write(slice(@cur, @cur...phantom_method_type.location.end_pos))
|
@@ -70,11 +70,11 @@ module RaaP
|
|
70
70
|
ml.source[start, range.end - range.begin] or raise
|
71
71
|
end
|
72
72
|
|
73
|
-
def write_param(io, position, param
|
74
|
-
write_type(io, position, param.type
|
73
|
+
def write_param(io, position, param)
|
74
|
+
write_type(io, position, param.type)
|
75
75
|
end
|
76
76
|
|
77
|
-
def write_type(io, position, type
|
77
|
+
def write_type(io, position, type)
|
78
78
|
unless type.location
|
79
79
|
RaaP.logger.warn("No location information for `#{type}`")
|
80
80
|
return
|
@@ -88,12 +88,12 @@ module RaaP
|
|
88
88
|
t.location or raise
|
89
89
|
io.write(slice(@cur, @cur...t.location.start_pos)) # ( or [
|
90
90
|
@cur = t.location.start_pos
|
91
|
-
write_type(io, "#{position}_#{name}_#{i}", t
|
91
|
+
write_type(io, "#{position}_#{name}_#{i}", t)
|
92
92
|
end
|
93
93
|
when ::RBS::Types::Optional
|
94
94
|
raise unless type.location
|
95
95
|
|
96
|
-
write_type(io, "#{position}_optional_left", type.type
|
96
|
+
write_type(io, "#{position}_optional_left", type.type)
|
97
97
|
io.write(slice(@cur, @cur...(type.location.end_pos - 1)))
|
98
98
|
@cur = type.location.end_pos - 1
|
99
99
|
if @cov.include?("#{position}_optional_right".to_sym)
|
@@ -103,17 +103,6 @@ module RaaP
|
|
103
103
|
end
|
104
104
|
raise unless type.location
|
105
105
|
|
106
|
-
@cur = type.location.end_pos
|
107
|
-
when ::RBS::Types::Variable
|
108
|
-
case accuracy
|
109
|
-
when :abs
|
110
|
-
io.write(green(type.name.to_s))
|
111
|
-
when :opt
|
112
|
-
# Variables are substed so raap don't know if they've been used.
|
113
|
-
io.write(yellow(type.name.to_s))
|
114
|
-
end
|
115
|
-
raise unless type.location
|
116
|
-
|
117
106
|
@cur = type.location.end_pos
|
118
107
|
else
|
119
108
|
raise unless type.location
|
@@ -129,7 +118,6 @@ module RaaP
|
|
129
118
|
|
130
119
|
def green(str) = "\e[32m#{str}\e[0m"
|
131
120
|
def red(str) = "\e[1;4;41m#{str}\e[0m"
|
132
|
-
def yellow(str) = "\e[93m#{str}\e[0m"
|
133
121
|
end
|
134
122
|
|
135
123
|
class << self
|
@@ -142,8 +130,6 @@ module RaaP
|
|
142
130
|
!!@cov
|
143
131
|
end
|
144
132
|
|
145
|
-
# position: req_0
|
146
|
-
# type: union_1
|
147
133
|
def log(position)
|
148
134
|
return unless running?
|
149
135
|
|
@@ -151,7 +137,7 @@ module RaaP
|
|
151
137
|
end
|
152
138
|
|
153
139
|
def cov
|
154
|
-
@cov or raise
|
140
|
+
@cov or raise("Coverage is not started")
|
155
141
|
end
|
156
142
|
|
157
143
|
def show(io)
|
@@ -162,25 +148,31 @@ module RaaP
|
|
162
148
|
end
|
163
149
|
|
164
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)
|
165
157
|
case type
|
166
158
|
when ::RBS::Types::Tuple
|
167
159
|
# FIXME: Support Union in Tuple
|
168
160
|
type.types.each_with_index do |_t, i|
|
169
161
|
log("#{position}_tuple_#{i}")
|
170
162
|
end
|
171
|
-
|
163
|
+
block&.call(type)
|
172
164
|
when ::RBS::Types::Union
|
173
165
|
i = Random.rand(type.types.length)
|
174
|
-
|
166
|
+
log_with_type("#{position}_union_#{i}", type.types[i], &block)
|
175
167
|
when ::RBS::Types::Optional
|
176
168
|
if Random.rand(2).zero?
|
177
|
-
|
169
|
+
log_with_type("#{position}_optional_left", type.type, &block)
|
178
170
|
else
|
179
|
-
|
171
|
+
log_with_type("#{position}_optional_right", ::RBS::Types::Bases::Nil.new(location: nil), &block)
|
180
172
|
end
|
181
173
|
else
|
182
174
|
log(position)
|
183
|
-
|
175
|
+
block&.call(type)
|
184
176
|
end
|
185
177
|
end
|
186
178
|
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)
|
@@ -81,7 +82,11 @@ module RaaP
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def build_type_with_coverage(position, param)
|
84
|
-
|
85
|
+
if @coverage
|
86
|
+
Coverage.new_type_with_log(position, param.type)
|
87
|
+
else
|
88
|
+
Type.new(param.type)
|
89
|
+
end
|
85
90
|
end
|
86
91
|
end
|
87
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
|
data/lib/raap/method_type.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module RaaP
|
4
4
|
class MethodType
|
5
|
-
attr_reader :rbs
|
5
|
+
attr_reader :rbs
|
6
6
|
|
7
7
|
def initialize(method, type_params_decl: [], type_args: [], self_type: nil, instance_type: nil, class_type: nil)
|
8
8
|
rbs =
|
@@ -19,11 +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
|
-
@original_rbs = rbs
|
24
22
|
@rbs = ts.method_type_sub(rbs, self_type: self_type, instance_type: instance_type, class_type: class_type)
|
25
23
|
function_or_untypedfunction = __skip__ = @rbs.type
|
26
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
|
+
)
|
27
33
|
end
|
28
34
|
|
29
35
|
def pick_arguments(size: 10)
|
@@ -42,28 +48,63 @@ module RaaP
|
|
42
48
|
return nil if block.nil?
|
43
49
|
return nil if (block.required == false) && [true, false].sample
|
44
50
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
49
82
|
end
|
50
|
-
|
51
|
-
Coverage.new_type_with_log("block_return", block.type.return_type)
|
52
|
-
fixed_return_value
|
53
83
|
end
|
84
|
+
# Hack: Use local variable in eval
|
85
|
+
fixed_return_value = Type.new(block.type.return_type).pick(size: size)
|
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
|
54
104
|
end
|
55
105
|
|
56
106
|
def check_return(return_value)
|
57
|
-
|
58
|
-
type_check = ::RBS::Test::TypeCheck.new(
|
59
|
-
self_class: untyped, # cannot support `self`
|
60
|
-
instance_class: untyped, # cannot support `instance`
|
61
|
-
class_class: untyped, # cannot support `class`
|
62
|
-
builder: RBS.builder,
|
63
|
-
sample_size: 100,
|
64
|
-
unchecked_classes: []
|
65
|
-
)
|
66
|
-
type_check.value(return_value, rbs.type.return_type)
|
107
|
+
@type_check.value(return_value, rbs.type.return_type)
|
67
108
|
end
|
68
109
|
end
|
69
110
|
end
|
data/lib/raap/value/interface.rb
CHANGED
@@ -33,7 +33,7 @@ module RaaP
|
|
33
33
|
if b && subed_method_type.block && subed_method_type.block.type.is_a?(::RBS::Types::Function)
|
34
34
|
@fixed_block_arguments ||= {}
|
35
35
|
@fixed_block_arguments[name] ||= size.times.map do
|
36
|
-
FunctionType.new(subed_method_type.block.type)
|
36
|
+
FunctionType.new(subed_method_type.block.type, coverage: false)
|
37
37
|
.pick_arguments(size: size)
|
38
38
|
end
|
39
39
|
|
data/lib/raap/version.rb
CHANGED
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
|
|
@@ -75,7 +69,6 @@ module RaaP
|
|
75
69
|
|
76
70
|
module Coverage
|
77
71
|
type locs = [::RBS::Buffer::loc, ::RBS::Buffer::loc]
|
78
|
-
type accuracy = :abs | :opt
|
79
72
|
class Writer
|
80
73
|
@method_type: ::RBS::MethodType
|
81
74
|
@cov: ::Set[Symbol]
|
@@ -88,11 +81,10 @@ module RaaP
|
|
88
81
|
|
89
82
|
def method_type_location: () -> ::RBS::Location[untyped, untyped]
|
90
83
|
def slice: (Integer, Range[Integer]) -> String
|
91
|
-
def write_param: (IO, String, ::RBS::Types::Function::Param
|
92
|
-
def write_type: (IO, String, ::RBS::Types::t
|
84
|
+
def write_param: (IO, String, ::RBS::Types::Function::Param) -> void
|
85
|
+
def write_type: (IO, String, ::RBS::Types::t) -> void
|
93
86
|
def green: (String) -> String
|
94
87
|
def red: (String) -> String
|
95
|
-
def yellow: (String) -> String
|
96
88
|
end
|
97
89
|
|
98
90
|
self.@cov: Set[Symbol]?
|
@@ -104,12 +96,15 @@ module RaaP
|
|
104
96
|
def self.cov: () -> Set[Symbol]
|
105
97
|
def self.show: (IO) -> void
|
106
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
|
107
101
|
end
|
108
102
|
|
109
103
|
class FunctionType
|
110
104
|
@fun: ::RBS::Types::Function
|
105
|
+
@coverage: boolish
|
111
106
|
|
112
|
-
def initialize: (::RBS::Types::Function) -> void
|
107
|
+
def initialize: (::RBS::Types::Function, ?coverage: boolish) -> void
|
113
108
|
def pick_arguments: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped]]
|
114
109
|
def arguments_to_symbolic_call: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped]]
|
115
110
|
|
@@ -150,8 +145,8 @@ module RaaP
|
|
150
145
|
|
151
146
|
class MethodType
|
152
147
|
attr_reader rbs: ::RBS::MethodType
|
153
|
-
attr_reader original_rbs: ::RBS::MethodType
|
154
148
|
@fun_type: FunctionType
|
149
|
+
@type_check: ::RBS::Test::TypeCheck
|
155
150
|
|
156
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
|
157
152
|
def pick_arguments: (?size: Integer) -> [Array[untyped], Hash[Symbol, untyped], ::Proc?]
|
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
|