rbs 0.2.0 → 0.6.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/.github/workflows/ruby.yml +7 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +35 -0
- data/COPYING +1 -1
- data/Gemfile +16 -2
- data/README.md +87 -48
- data/Rakefile +54 -22
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/bin/test_runner.rb +0 -2
- data/docs/sigs.md +6 -6
- data/docs/stdlib.md +3 -5
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +3 -0
- data/lib/rbs/ast/declarations.rb +115 -14
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +301 -123
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +64 -53
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +646 -603
- data/lib/rbs/environment.rb +352 -210
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +159 -3
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/namespace.rb +18 -0
- data/lib/rbs/parser.y +75 -21
- data/lib/rbs/prototype/rb.rb +119 -117
- data/lib/rbs/prototype/rbi.rb +5 -3
- data/lib/rbs/prototype/runtime.rb +34 -7
- data/lib/rbs/substitution.rb +8 -1
- data/lib/rbs/test.rb +81 -3
- data/lib/rbs/test/errors.rb +1 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +13 -14
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +116 -0
- data/lib/rbs/test/type_check.rb +44 -7
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +51 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +127 -91
- data/rbs.gemspec +0 -9
- data/schema/annotation.json +14 -0
- data/schema/comment.json +26 -0
- data/schema/decls.json +353 -0
- data/schema/function.json +87 -0
- data/schema/location.json +56 -0
- data/schema/members.json +248 -0
- data/schema/methodType.json +44 -0
- data/schema/types.json +299 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/encoding.rbs +2 -0
- data/stdlib/builtin/enumerable.rbs +2 -2
- data/stdlib/builtin/enumerator.rbs +3 -1
- data/stdlib/builtin/fiber.rbs +5 -1
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/proc.rbs +1 -2
- data/stdlib/builtin/symbol.rbs +1 -1
- data/stdlib/builtin/thread.rbs +2 -2
- data/stdlib/csv/csv.rbs +4 -6
- data/stdlib/fiber/fiber.rbs +117 -0
- data/stdlib/json/json.rbs +1 -1
- data/stdlib/logger/formatter.rbs +23 -0
- data/stdlib/logger/log_device.rbs +39 -0
- data/stdlib/logger/logger.rbs +507 -0
- data/stdlib/logger/period.rbs +7 -0
- data/stdlib/logger/severity.rbs +8 -0
- data/stdlib/mutex_m/mutex_m.rbs +77 -0
- data/stdlib/pathname/pathname.rbs +6 -6
- data/stdlib/prime/integer-extension.rbs +1 -1
- data/stdlib/prime/prime.rbs +44 -44
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +26 -116
- data/lib/rbs/test/test_helper.rb +0 -183
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -6,19 +6,20 @@ module RBS
|
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@source_decls = []
|
9
|
-
@toplevel_members = []
|
10
9
|
end
|
11
10
|
|
12
11
|
def decls
|
13
12
|
decls = []
|
14
13
|
|
15
|
-
|
14
|
+
top_decls, top_members = source_decls.partition {|decl| decl.is_a?(AST::Declarations::Base) }
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
decls.push(*top_decls)
|
17
|
+
|
18
|
+
unless top_members.empty?
|
19
|
+
top = AST::Declarations::Class.new(
|
19
20
|
name: TypeName.new(name: :Object, namespace: Namespace.empty),
|
20
|
-
|
21
|
-
members:
|
21
|
+
super_class: nil,
|
22
|
+
members: top_members,
|
22
23
|
annotations: [],
|
23
24
|
comment: nil,
|
24
25
|
location: nil,
|
@@ -27,7 +28,7 @@ module RBS
|
|
27
28
|
decls << top
|
28
29
|
end
|
29
30
|
|
30
|
-
decls
|
31
|
+
decls
|
31
32
|
end
|
32
33
|
|
33
34
|
def parse(string)
|
@@ -51,19 +52,15 @@ module RBS
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
process RubyVM::AbstractSyntaxTree.parse(string),
|
55
|
-
end
|
56
|
-
|
57
|
-
def nested_name(name)
|
58
|
-
(current_namespace + const_to_name(name).to_namespace).to_type_name.relative!
|
55
|
+
process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, singleton: false
|
59
56
|
end
|
60
57
|
|
61
|
-
def process(node,
|
58
|
+
def process(node, decls:, comments:, singleton:)
|
62
59
|
case node.type
|
63
60
|
when :CLASS
|
64
61
|
class_name, super_class, *class_body = node.children
|
65
62
|
kls = AST::Declarations::Class.new(
|
66
|
-
name: const_to_name(class_name)
|
63
|
+
name: const_to_name(class_name),
|
67
64
|
super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: []),
|
68
65
|
type_params: AST::Declarations::ModuleTypeParams.empty,
|
69
66
|
members: [],
|
@@ -72,39 +69,42 @@ module RBS
|
|
72
69
|
comment: comments[node.first_lineno - 1]
|
73
70
|
)
|
74
71
|
|
75
|
-
|
72
|
+
decls.push kls
|
76
73
|
|
77
74
|
each_node class_body do |child|
|
78
|
-
process child,
|
75
|
+
process child, decls: kls.members, comments: comments, singleton: false
|
79
76
|
end
|
77
|
+
|
80
78
|
when :MODULE
|
81
79
|
module_name, *module_body = node.children
|
82
80
|
|
83
81
|
mod = AST::Declarations::Module.new(
|
84
|
-
name: const_to_name(module_name)
|
82
|
+
name: const_to_name(module_name),
|
85
83
|
type_params: AST::Declarations::ModuleTypeParams.empty,
|
86
|
-
|
84
|
+
self_types: [],
|
87
85
|
members: [],
|
88
86
|
annotations: [],
|
89
87
|
location: nil,
|
90
88
|
comment: comments[node.first_lineno - 1]
|
91
89
|
)
|
92
90
|
|
93
|
-
|
91
|
+
decls.push mod
|
94
92
|
|
95
93
|
each_node module_body do |child|
|
96
|
-
process child,
|
94
|
+
process child, decls: mod.members, comments: comments, singleton: false
|
97
95
|
end
|
96
|
+
|
98
97
|
when :SCLASS
|
99
|
-
this = node.children
|
98
|
+
this, body = node.children
|
99
|
+
|
100
100
|
if this.type != :SELF
|
101
101
|
RBS.logger.warn "`class <<` syntax with not-self may be compiled to incorrect code: #{this}"
|
102
102
|
end
|
103
103
|
|
104
|
-
body = node.children[1]
|
105
104
|
each_child(body) do |child|
|
106
|
-
process child,
|
105
|
+
process child, decls: decls, comments: comments, singleton: true
|
107
106
|
end
|
107
|
+
|
108
108
|
when :DEFN, :DEFS
|
109
109
|
if node.type == :DEFN
|
110
110
|
def_name, def_body = node.children
|
@@ -130,116 +130,104 @@ module RBS
|
|
130
130
|
types: types,
|
131
131
|
kind: kind,
|
132
132
|
comment: comments[node.first_lineno - 1],
|
133
|
-
attributes: []
|
133
|
+
attributes: [],
|
134
|
+
overload: false
|
134
135
|
)
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
toplevel_members.push member
|
140
|
-
end
|
137
|
+
decls.push member
|
138
|
+
|
141
139
|
when :FCALL
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
)
|
157
|
-
end
|
140
|
+
# Inside method definition cannot reach here.
|
141
|
+
args = node.children[1]&.children || []
|
142
|
+
|
143
|
+
case node.children[0]
|
144
|
+
when :include
|
145
|
+
args.each do |arg|
|
146
|
+
if (name = const_to_name(arg))
|
147
|
+
decls << AST::Members::Include.new(
|
148
|
+
name: name,
|
149
|
+
args: [],
|
150
|
+
annotations: [],
|
151
|
+
location: nil,
|
152
|
+
comment: comments[node.first_lineno - 1]
|
153
|
+
)
|
158
154
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
155
|
+
end
|
156
|
+
when :extend
|
157
|
+
args.each do |arg|
|
158
|
+
if (name = const_to_name(arg))
|
159
|
+
decls << AST::Members::Extend.new(
|
160
|
+
name: name,
|
161
|
+
args: [],
|
162
|
+
annotations: [],
|
163
|
+
location: nil,
|
164
|
+
comment: comments[node.first_lineno - 1]
|
165
|
+
)
|
170
166
|
end
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
167
|
+
end
|
168
|
+
when :attr_reader
|
169
|
+
args.each do |arg|
|
170
|
+
if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
|
171
|
+
decls << AST::Members::AttrReader.new(
|
172
|
+
name: arg.children[0],
|
173
|
+
ivar_name: nil,
|
174
|
+
type: Types::Bases::Any.new(location: nil),
|
175
|
+
location: nil,
|
176
|
+
comment: comments[node.first_lineno - 1],
|
177
|
+
annotations: []
|
178
|
+
)
|
183
179
|
end
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
180
|
+
end
|
181
|
+
when :attr_accessor
|
182
|
+
args.each do |arg|
|
183
|
+
if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
|
184
|
+
decls << AST::Members::AttrAccessor.new(
|
185
|
+
name: arg.children[0],
|
186
|
+
ivar_name: nil,
|
187
|
+
type: Types::Bases::Any.new(location: nil),
|
188
|
+
location: nil,
|
189
|
+
comment: comments[node.first_lineno - 1],
|
190
|
+
annotations: []
|
191
|
+
)
|
196
192
|
end
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
193
|
+
end
|
194
|
+
when :attr_writer
|
195
|
+
args.each do |arg|
|
196
|
+
if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
|
197
|
+
decls << AST::Members::AttrWriter.new(
|
198
|
+
name: arg.children[0],
|
199
|
+
ivar_name: nil,
|
200
|
+
type: Types::Bases::Any.new(location: nil),
|
201
|
+
location: nil,
|
202
|
+
comment: comments[node.first_lineno - 1],
|
203
|
+
annotations: []
|
204
|
+
)
|
209
205
|
end
|
210
206
|
end
|
211
207
|
end
|
208
|
+
|
212
209
|
each_child node do |child|
|
213
|
-
process child,
|
210
|
+
process child, decls: decls, comments: comments, singleton: singleton
|
214
211
|
end
|
215
212
|
|
216
213
|
when :CDECL
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
name = const_to_name(node.children[0])
|
227
|
-
if current_module
|
228
|
-
name.with_prefix current_module.name.to_namespace
|
229
|
-
else
|
230
|
-
name
|
231
|
-
end.relative!
|
232
|
-
end
|
233
|
-
|
234
|
-
source_decls << AST::Declarations::Constant.new(
|
235
|
-
name: type_name,
|
214
|
+
const_name = case
|
215
|
+
when node.children[0].is_a?(Symbol)
|
216
|
+
TypeName.new(name: node.children[0], namespace: Namespace.empty)
|
217
|
+
else
|
218
|
+
const_to_name(node.children[0])
|
219
|
+
end
|
220
|
+
|
221
|
+
decls << AST::Declarations::Constant.new(
|
222
|
+
name: const_name,
|
236
223
|
type: node_type(node.children.last),
|
237
224
|
location: nil,
|
238
225
|
comment: comments[node.first_lineno - 1]
|
239
226
|
)
|
227
|
+
|
240
228
|
else
|
241
229
|
each_child node do |child|
|
242
|
-
process child,
|
230
|
+
process child, decls: decls, comments: comments, singleton: singleton
|
243
231
|
end
|
244
232
|
end
|
245
233
|
end
|
@@ -328,7 +316,19 @@ module RBS
|
|
328
316
|
body = node.children[2]
|
329
317
|
return Types::Bases::Nil.new(location: nil) unless body
|
330
318
|
|
331
|
-
|
319
|
+
if body.type == :BLOCK
|
320
|
+
return_stmts = any_node?(body) do |n|
|
321
|
+
n.type == :RETURN
|
322
|
+
end&.map do |return_node|
|
323
|
+
returned_value = return_node.children[0]
|
324
|
+
returned_value ? literal_to_type(returned_value) : Types::Bases::Nil.new(location: nil)
|
325
|
+
end || []
|
326
|
+
last_node = body.children.last
|
327
|
+
last_evaluated = last_node ? literal_to_type(last_node) : Types::Bases::Nil.new(location: nil)
|
328
|
+
types_to_union_type([*return_stmts, last_evaluated])
|
329
|
+
else
|
330
|
+
literal_to_type(body)
|
331
|
+
end
|
332
332
|
end
|
333
333
|
|
334
334
|
def literal_to_type(node)
|
@@ -393,7 +393,7 @@ module RBS
|
|
393
393
|
value_types << literal_to_type(v)
|
394
394
|
end
|
395
395
|
|
396
|
-
if key_types.all? { |t| t.is_a?(Types::Literal) }
|
396
|
+
if !key_types.empty? && key_types.all? { |t| t.is_a?(Types::Literal) }
|
397
397
|
fields = key_types.map { |t| t.literal }.zip(value_types).to_h
|
398
398
|
Types::Record.new(fields: fields, location: nil)
|
399
399
|
else
|
@@ -408,9 +408,11 @@ module RBS
|
|
408
408
|
|
409
409
|
def types_to_union_type(types)
|
410
410
|
return untyped if types.empty?
|
411
|
-
return untyped if types.include?(untyped)
|
412
411
|
|
413
|
-
|
412
|
+
uniq = types.uniq
|
413
|
+
return uniq.first if uniq.size == 1
|
414
|
+
|
415
|
+
Types::Union.new(types: uniq, location: nil)
|
414
416
|
end
|
415
417
|
|
416
418
|
def range_element_type(types)
|
data/lib/rbs/prototype/rbi.rb
CHANGED
@@ -69,7 +69,7 @@ module RBS
|
|
69
69
|
members: [],
|
70
70
|
annotations: [],
|
71
71
|
location: nil,
|
72
|
-
|
72
|
+
self_types: [],
|
73
73
|
comment: comment
|
74
74
|
)
|
75
75
|
|
@@ -173,7 +173,8 @@ module RBS
|
|
173
173
|
types: types,
|
174
174
|
kind: :singleton,
|
175
175
|
comment: comment,
|
176
|
-
attributes: []
|
176
|
+
attributes: [],
|
177
|
+
overload: false
|
177
178
|
)
|
178
179
|
end
|
179
180
|
|
@@ -193,7 +194,8 @@ module RBS
|
|
193
194
|
types: types,
|
194
195
|
kind: :instance,
|
195
196
|
comment: comment,
|
196
|
-
attributes: []
|
197
|
+
attributes: [],
|
198
|
+
overload: false
|
197
199
|
)
|
198
200
|
end
|
199
201
|
|
@@ -128,7 +128,7 @@ module RBS
|
|
128
128
|
|
129
129
|
def merge_rbs(module_name, members, instance: nil, singleton: nil)
|
130
130
|
if merge
|
131
|
-
if env.
|
131
|
+
if env.class_decls[module_name.absolute!]
|
132
132
|
case
|
133
133
|
when instance
|
134
134
|
method = builder.build_instance(module_name.absolute!).methods[instance]
|
@@ -152,9 +152,10 @@ module RBS
|
|
152
152
|
},
|
153
153
|
kind: kind,
|
154
154
|
location: nil,
|
155
|
-
comment: method.
|
155
|
+
comment: method.comments[0],
|
156
156
|
annotations: method.annotations,
|
157
|
-
attributes: method.attributes
|
157
|
+
attributes: method.attributes,
|
158
|
+
overload: false
|
158
159
|
)
|
159
160
|
return
|
160
161
|
end
|
@@ -192,7 +193,8 @@ module RBS
|
|
192
193
|
location: nil,
|
193
194
|
comment: nil,
|
194
195
|
annotations: [],
|
195
|
-
attributes: []
|
196
|
+
attributes: [],
|
197
|
+
overload: false
|
196
198
|
)
|
197
199
|
end
|
198
200
|
else
|
@@ -225,7 +227,8 @@ module RBS
|
|
225
227
|
location: nil,
|
226
228
|
comment: nil,
|
227
229
|
annotations: [],
|
228
|
-
attributes: []
|
230
|
+
attributes: [],
|
231
|
+
overload: false
|
229
232
|
)
|
230
233
|
end
|
231
234
|
else
|
@@ -259,7 +262,8 @@ module RBS
|
|
259
262
|
location: nil,
|
260
263
|
comment: nil,
|
261
264
|
annotations: [],
|
262
|
-
attributes: []
|
265
|
+
attributes: [],
|
266
|
+
overload: false
|
263
267
|
)
|
264
268
|
end
|
265
269
|
else
|
@@ -281,6 +285,11 @@ module RBS
|
|
281
285
|
value = mod.const_get(name)
|
282
286
|
|
283
287
|
next if value.is_a?(Class) || value.is_a?(Module)
|
288
|
+
unless value.class.name
|
289
|
+
RBS.logger.warn("Skipping constant #{name} #{value} of #{mod} as an instance of anonymous class")
|
290
|
+
next
|
291
|
+
end
|
292
|
+
|
284
293
|
type = case value
|
285
294
|
when true, false
|
286
295
|
Types::Bases::Bool.new(location: nil)
|
@@ -306,6 +315,9 @@ module RBS
|
|
306
315
|
type_name = to_type_name(mod.name)
|
307
316
|
super_class = if mod.superclass == ::Object
|
308
317
|
nil
|
318
|
+
elsif mod.superclass.name.nil?
|
319
|
+
RBS.logger.warn("Skipping anonymous superclass #{mod.superclass} of #{mod}")
|
320
|
+
nil
|
309
321
|
else
|
310
322
|
AST::Declarations::Class::Super.new(name: to_type_name(mod.superclass.name), args: [])
|
311
323
|
end
|
@@ -321,6 +333,11 @@ module RBS
|
|
321
333
|
)
|
322
334
|
|
323
335
|
each_mixin(mod.included_modules, *mod.superclass.included_modules, *mod.included_modules.flat_map(&:included_modules)) do |included_module|
|
336
|
+
unless included_module.name
|
337
|
+
RBS.logger.warn("Skipping anonymous module #{included_module} included in #{mod}")
|
338
|
+
next
|
339
|
+
end
|
340
|
+
|
324
341
|
module_name = to_type_name(included_module.name)
|
325
342
|
if module_name.namespace == type_name.namespace
|
326
343
|
module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
|
@@ -343,12 +360,17 @@ module RBS
|
|
343
360
|
end
|
344
361
|
|
345
362
|
def generate_module(mod)
|
363
|
+
unless mod.name
|
364
|
+
RBS.logger.warn("Skipping anonymous module #{mod}")
|
365
|
+
return
|
366
|
+
end
|
367
|
+
|
346
368
|
type_name = to_type_name(mod.name)
|
347
369
|
|
348
370
|
decl = AST::Declarations::Module.new(
|
349
371
|
name: type_name,
|
350
372
|
type_params: AST::Declarations::ModuleTypeParams.empty,
|
351
|
-
|
373
|
+
self_types: [],
|
352
374
|
members: [],
|
353
375
|
annotations: [],
|
354
376
|
location: nil,
|
@@ -356,6 +378,11 @@ module RBS
|
|
356
378
|
)
|
357
379
|
|
358
380
|
each_mixin(mod.included_modules, *mod.included_modules.flat_map(&:included_modules), namespace: type_name.namespace) do |included_module|
|
381
|
+
unless included_module.name
|
382
|
+
RBS.logger.warn("Skipping anonymous module #{included_module} included in #{mod}")
|
383
|
+
next
|
384
|
+
end
|
385
|
+
|
359
386
|
module_name = to_type_name(included_module.name)
|
360
387
|
if module_name.namespace == type_name.namespace
|
361
388
|
module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
|