rbs 3.4.4 → 3.5.0.pre.1
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 -0
- data/CHANGELOG.md +0 -26
- data/Gemfile +12 -1
- data/Gemfile.lock +51 -34
- data/README.md +2 -1
- data/Rakefile +2 -2
- data/core/enumerator.rbs +1 -1
- data/core/gc.rbs +272 -150
- data/core/integer.rbs +4 -3
- data/core/io/wait.rbs +4 -4
- data/core/io.rbs +10 -3
- data/core/kernel.rbs +8 -7
- data/core/module.rbs +17 -4
- data/core/range.rbs +2 -2
- data/core/regexp.rbs +101 -90
- data/core/ruby_vm.rbs +103 -103
- data/core/string.rbs +3 -3
- data/core/symbol.rbs +2 -1
- data/core/thread.rbs +1 -1
- data/core/time.rbs +24 -4
- data/docs/architecture.md +110 -0
- data/docs/syntax.md +5 -1
- data/ext/rbs_extension/constants.c +2 -0
- data/ext/rbs_extension/constants.h +1 -0
- data/ext/rbs_extension/location.c +79 -70
- data/ext/rbs_extension/location.h +23 -5
- data/ext/rbs_extension/parser.c +82 -24
- data/ext/rbs_extension/parserstate.c +4 -0
- data/ext/rbs_extension/ruby_objs.c +13 -3
- data/ext/rbs_extension/ruby_objs.h +1 -0
- data/lib/rbs/collection/config.rb +1 -1
- data/lib/rbs/collection/sources/git.rb +1 -6
- data/lib/rbs/definition_builder/method_builder.rb +1 -1
- data/lib/rbs/definition_builder.rb +8 -8
- data/lib/rbs/diff.rb +1 -1
- data/lib/rbs/environment_loader.rb +2 -1
- data/lib/rbs/errors.rb +0 -14
- data/lib/rbs/parser_aux.rb +0 -5
- data/lib/rbs/prototype/helpers.rb +22 -12
- data/lib/rbs/prototype/rb.rb +38 -4
- data/lib/rbs/prototype/rbi.rb +30 -20
- data/lib/rbs/test/errors.rb +19 -14
- data/lib/rbs/test/tester.rb +1 -1
- data/lib/rbs/test/type_check.rb +95 -16
- data/lib/rbs/types.rb +112 -13
- data/lib/rbs/unit_test/spy.rb +1 -1
- data/lib/rbs/version.rb +1 -1
- data/rbs.gemspec +1 -1
- data/sig/environment_loader.rbs +1 -1
- data/sig/errors.rbs +1 -1
- data/sig/method_types.rbs +3 -3
- data/sig/prototype/helpers.rbs +4 -0
- data/sig/prototype/rbi.rbs +2 -0
- data/sig/types.rbs +54 -4
- data/sig/variance_calculator.rbs +2 -2
- data/stdlib/csv/0/csv.rbs +4 -1
- data/stdlib/fileutils/0/fileutils.rbs +1 -1
- data/stdlib/net-http/0/net-http.rbs +29 -27
- data/stdlib/socket/0/socket.rbs +2 -2
- data/stdlib/timeout/0/timeout.rbs +6 -0
- data/stdlib/uri/0/generic.rbs +2 -2
- data/stdlib/uri/0/http.rbs +2 -2
- metadata +3 -6
- data/lib/rbs/parser_compat/lexer_error.rb +0 -6
- data/lib/rbs/parser_compat/located_value.rb +0 -7
- data/lib/rbs/parser_compat/semantics_error.rb +0 -6
- data/lib/rbs/parser_compat/syntax_error.rb +0 -6
data/lib/rbs/prototype/rb.rb
CHANGED
@@ -5,7 +5,7 @@ module RBS
|
|
5
5
|
class RB
|
6
6
|
include Helpers
|
7
7
|
|
8
|
-
Context
|
8
|
+
class Context < Struct.new(:module_function, :singleton, :namespace, :in_def, keyword_init: true)
|
9
9
|
# @implements Context
|
10
10
|
|
11
11
|
def self.initial(namespace: Namespace.root)
|
@@ -461,6 +461,8 @@ module RBS
|
|
461
461
|
|
462
462
|
def literal_to_symbol(node)
|
463
463
|
case node.type
|
464
|
+
when :SYM
|
465
|
+
node.children[0]
|
464
466
|
when :LIT
|
465
467
|
node.children[0] if node.children[0].is_a?(Symbol)
|
466
468
|
when :STR
|
@@ -495,7 +497,7 @@ module RBS
|
|
495
497
|
end
|
496
498
|
|
497
499
|
if rest
|
498
|
-
rest_name = rest == :* ? nil : rest #
|
500
|
+
rest_name = rest == :* ? nil : rest # `def f(...)` syntax has `*` name
|
499
501
|
fun = fun.update(rest_positionals: Types::Function::Param.new(name: rest_name, type: untyped))
|
500
502
|
end
|
501
503
|
|
@@ -518,7 +520,9 @@ module RBS
|
|
518
520
|
end
|
519
521
|
|
520
522
|
if kwrest && kwrest.children.any?
|
521
|
-
|
523
|
+
kwrest_name = kwrest.children[0] #: Symbol?
|
524
|
+
kwrest_name = nil if kwrest_name == :** # `def f(...)` syntax has `**` name
|
525
|
+
fun = fun.update(rest_keywords: Types::Function::Param.new(name: kwrest_name, type: untyped))
|
522
526
|
end
|
523
527
|
|
524
528
|
fun
|
@@ -574,9 +578,16 @@ module RBS
|
|
574
578
|
end
|
575
579
|
when :DSTR, :XSTR
|
576
580
|
BuiltinNames::String.instance_type
|
581
|
+
when :SYM
|
582
|
+
lit = node.children[0]
|
583
|
+
if lit.to_s.ascii_only?
|
584
|
+
Types::Literal.new(literal: lit, location: nil)
|
585
|
+
else
|
586
|
+
BuiltinNames::Symbol.instance_type
|
587
|
+
end
|
577
588
|
when :DSYM
|
578
589
|
BuiltinNames::Symbol.instance_type
|
579
|
-
when :DREGX
|
590
|
+
when :DREGX, :REGX
|
580
591
|
BuiltinNames::Regexp.instance_type
|
581
592
|
when :TRUE
|
582
593
|
Types::Literal.new(literal: true, location: nil)
|
@@ -584,6 +595,14 @@ module RBS
|
|
584
595
|
Types::Literal.new(literal: false, location: nil)
|
585
596
|
when :NIL
|
586
597
|
Types::Bases::Nil.new(location: nil)
|
598
|
+
when :INTEGER
|
599
|
+
Types::Literal.new(literal: node.children[0], location: nil)
|
600
|
+
when :FLOAT
|
601
|
+
BuiltinNames::Float.instance_type
|
602
|
+
when :RATIONAL, :IMAGINARY
|
603
|
+
lit = node.children[0]
|
604
|
+
type_name = TypeName.new(name: lit.class.name.to_sym, namespace: Namespace.root)
|
605
|
+
Types::ClassInstance.new(name: type_name, args: [], location: nil)
|
587
606
|
when :LIT
|
588
607
|
lit = node.children[0]
|
589
608
|
case lit
|
@@ -595,6 +614,11 @@ module RBS
|
|
595
614
|
end
|
596
615
|
when Integer
|
597
616
|
Types::Literal.new(literal: lit, location: nil)
|
617
|
+
when String
|
618
|
+
# For Ruby <=3.3 which generates `LIT` node for string literals inside Hash literal.
|
619
|
+
# "a" => STR node
|
620
|
+
# { "a" => nil } => LIT node
|
621
|
+
Types::Literal.new(literal: lit, location: nil)
|
598
622
|
else
|
599
623
|
type_name = TypeName.new(name: lit.class.name.to_sym, namespace: Namespace.root)
|
600
624
|
Types::ClassInstance.new(name: type_name, args: [], location: nil)
|
@@ -686,6 +710,14 @@ module RBS
|
|
686
710
|
|
687
711
|
def param_type(node, default: Types::Bases::Any.new(location: nil))
|
688
712
|
case node.type
|
713
|
+
when :INTEGER
|
714
|
+
BuiltinNames::Integer.instance_type
|
715
|
+
when :FLOAT
|
716
|
+
BuiltinNames::Float.instance_type
|
717
|
+
when :RATIONAL
|
718
|
+
Types::ClassInstance.new(name: TypeName("::Rational"), args: [], location: nil)
|
719
|
+
when :IMAGINARY
|
720
|
+
Types::ClassInstance.new(name: TypeName("::Complex"), args: [], location: nil)
|
689
721
|
when :LIT
|
690
722
|
case node.children[0]
|
691
723
|
when Symbol
|
@@ -697,6 +729,8 @@ module RBS
|
|
697
729
|
else
|
698
730
|
default
|
699
731
|
end
|
732
|
+
when :SYM
|
733
|
+
BuiltinNames::Symbol.instance_type
|
700
734
|
when :STR, :DSTR
|
701
735
|
BuiltinNames::String.instance_type
|
702
736
|
when :NIL
|
data/lib/rbs/prototype/rbi.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module RBS
|
4
4
|
module Prototype
|
5
5
|
class RBI
|
6
|
+
include Helpers
|
7
|
+
|
6
8
|
attr_reader :decls
|
7
9
|
attr_reader :modules
|
8
10
|
attr_reader :last_sig
|
@@ -218,11 +220,11 @@ module RBS
|
|
218
220
|
if (send = node.children.last) && send.type == :FCALL && send.children[0] == :type_member
|
219
221
|
unless each_arg(send.children[1]).any? {|node|
|
220
222
|
node.type == :HASH &&
|
221
|
-
each_arg(node.children[0]).each_slice(2).any? {|a, _| a
|
223
|
+
each_arg(node.children[0]).each_slice(2).any? {|a, _| symbol_literal_node?(a) == :fixed }
|
222
224
|
}
|
223
225
|
# @type var variance: AST::TypeParam::variance?
|
224
|
-
if (a0 = each_arg(send.children[1]).to_a[0]) &&
|
225
|
-
variance = case
|
226
|
+
if (a0 = each_arg(send.children[1]).to_a[0]) && (v = symbol_literal_node?(a0))
|
227
|
+
variance = case v
|
226
228
|
when :out
|
227
229
|
:covariant
|
228
230
|
when :in
|
@@ -315,14 +317,18 @@ module RBS
|
|
315
317
|
Types::Function::Param.new(name: name, type: type)
|
316
318
|
end
|
317
319
|
|
318
|
-
|
320
|
+
if method_type.type.is_a?(RBS::Types::Function)
|
321
|
+
method_type.update(type: method_type.type.update(required_positionals: required_positionals))
|
322
|
+
else
|
323
|
+
method_type
|
324
|
+
end
|
319
325
|
end
|
320
326
|
when :type_parameters
|
321
327
|
type_params = []
|
322
328
|
|
323
329
|
each_arg args do |node|
|
324
|
-
if
|
325
|
-
type_params <<
|
330
|
+
if name = symbol_literal_node?(node)
|
331
|
+
type_params << name
|
326
332
|
end
|
327
333
|
end
|
328
334
|
|
@@ -444,18 +450,22 @@ module RBS
|
|
444
450
|
end
|
445
451
|
end
|
446
452
|
|
447
|
-
method_type.
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
453
|
+
if method_type.type.is_a?(Types::Function)
|
454
|
+
method_type.update(
|
455
|
+
type: method_type.type.update(
|
456
|
+
required_positionals: required_positionals,
|
457
|
+
optional_positionals: optional_positionals,
|
458
|
+
rest_positionals: rest_positionals,
|
459
|
+
trailing_positionals: trailing_positionals,
|
460
|
+
required_keywords: required_keywords,
|
461
|
+
optional_keywords: optional_keywords,
|
462
|
+
rest_keywords: rest_keywords
|
463
|
+
),
|
464
|
+
block: method_block
|
465
|
+
)
|
466
|
+
else
|
467
|
+
method_type
|
468
|
+
end
|
459
469
|
end
|
460
470
|
|
461
471
|
def type_of(type_node, variables:)
|
@@ -613,8 +623,8 @@ module RBS
|
|
613
623
|
each_arg(node.children[0]).each_slice(2) do |var, type|
|
614
624
|
var or raise
|
615
625
|
|
616
|
-
if
|
617
|
-
hash[
|
626
|
+
if (name = symbol_literal_node?(var)) && type
|
627
|
+
hash[name] = type
|
618
628
|
end
|
619
629
|
end
|
620
630
|
|
data/lib/rbs/test/errors.rb
CHANGED
@@ -40,32 +40,37 @@ module RBS
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def self.
|
44
|
-
|
45
|
-
inspect_(error.klass).sub(/\A#<Class:(.*)>\z/, '\1')
|
43
|
+
def self.method_tag(error)
|
44
|
+
if error.klass.singleton_class?
|
45
|
+
name = inspect_(error.klass).sub(/\A#<Class:(.*)>\z/, '\1')
|
46
|
+
method_name = ".#{error.method_name}"
|
46
47
|
else
|
47
|
-
error.klass.name
|
48
|
+
name = error.klass.name
|
49
|
+
method_name = "##{error.method_name}"
|
48
50
|
end
|
49
|
-
|
51
|
+
"[#{name}#{method_name}]"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.to_string(error)
|
50
55
|
case error
|
51
56
|
when ArgumentTypeError
|
52
|
-
"
|
57
|
+
"#{method_tag(error)} ArgumentTypeError: expected #{format_param error.param} but given `#{inspect_(error.value)}`"
|
53
58
|
when BlockArgumentTypeError
|
54
|
-
"
|
59
|
+
"#{method_tag(error)} BlockArgumentTypeError: expected #{format_param error.param} but given `#{inspect_(error.value)}`"
|
55
60
|
when ArgumentError
|
56
|
-
"
|
61
|
+
"#{method_tag(error)} ArgumentError: expected method type #{error.method_type}"
|
57
62
|
when BlockArgumentError
|
58
|
-
"
|
63
|
+
"#{method_tag(error)} BlockArgumentError: expected method type #{error.method_type}"
|
59
64
|
when ReturnTypeError
|
60
|
-
"
|
65
|
+
"#{method_tag(error)} ReturnTypeError: expected `#{error.type}` but returns `#{inspect_(error.value)}`"
|
61
66
|
when BlockReturnTypeError
|
62
|
-
"
|
67
|
+
"#{method_tag(error)} BlockReturnTypeError: expected `#{error.type}` but returns `#{inspect_(error.value)}`"
|
63
68
|
when UnexpectedBlockError
|
64
|
-
"
|
69
|
+
"#{method_tag(error)} UnexpectedBlockError: unexpected block is given for `#{error.method_type}`"
|
65
70
|
when MissingBlockError
|
66
|
-
"
|
71
|
+
"#{method_tag(error)} MissingBlockError: required block is missing for `#{error.method_type}`"
|
67
72
|
when UnresolvedOverloadingError
|
68
|
-
"
|
73
|
+
"#{method_tag(error)} UnresolvedOverloadingError: couldn't find a suitable overloading"
|
69
74
|
else
|
70
75
|
raise "Unexpected error: #{inspect_(error)}"
|
71
76
|
end
|
data/lib/rbs/test/tester.rb
CHANGED
@@ -149,7 +149,7 @@ module RBS
|
|
149
149
|
method = definition.methods[method_name]
|
150
150
|
if method
|
151
151
|
RBS.logger.debug { "Type checking `#{self_class}#{format_method_name(method_name)}`..."}
|
152
|
-
errors = check.overloaded_call(method,
|
152
|
+
errors = check.overloaded_call(method, method_name, trace, errors: [])
|
153
153
|
|
154
154
|
if errors.empty?
|
155
155
|
RBS.logger.debug { "No type error detected 👏" }
|
data/lib/rbs/test/type_check.rb
CHANGED
@@ -35,22 +35,24 @@ module RBS
|
|
35
35
|
if es.size == 1
|
36
36
|
errors.push(*es[0])
|
37
37
|
else
|
38
|
+
error = Errors::UnresolvedOverloadingError.new(
|
39
|
+
klass: self_class,
|
40
|
+
method_name: method_name,
|
41
|
+
method_types: method.method_types
|
42
|
+
)
|
38
43
|
RBS.logger.warn do
|
39
|
-
|
44
|
+
tag = Errors.method_tag(error)
|
45
|
+
message = +"#{tag} UnresolvedOverloadingError "
|
40
46
|
message << method.method_types.zip(es).map do |method_type, es|
|
41
47
|
msg = +"method_type=`#{method_type}`"
|
42
48
|
details = es.map do |e|
|
43
|
-
"\"#{Errors.to_string(e).sub("
|
49
|
+
"\"#{Errors.to_string(e).sub("#{tag} ", "") }\""
|
44
50
|
end.join(', ')
|
45
51
|
msg << " details=[#{details}]"
|
46
52
|
end.join(', ')
|
47
53
|
message
|
48
54
|
end
|
49
|
-
errors <<
|
50
|
-
klass: self_class,
|
51
|
-
method_name: method_name,
|
52
|
-
method_types: method.method_types
|
53
|
-
)
|
55
|
+
errors << error
|
54
56
|
end
|
55
57
|
|
56
58
|
errors
|
@@ -281,19 +283,22 @@ module RBS
|
|
281
283
|
end
|
282
284
|
end
|
283
285
|
|
284
|
-
each_sample(values).all? do |v|
|
286
|
+
value_check = values.empty? || each_sample(values).all? do |v|
|
285
287
|
if v.size == 1
|
286
288
|
# Only one block argument.
|
287
289
|
value(v[0], type.args[0]) || value(v, type.args[0])
|
288
290
|
else
|
289
291
|
value(v, type.args[0])
|
290
292
|
end
|
291
|
-
end
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
293
|
+
end
|
294
|
+
|
295
|
+
return_check = if ret.equal?(self)
|
296
|
+
type.args[1].is_a?(Types::Bases::Bottom)
|
297
|
+
else
|
298
|
+
value(ret, type.args[1])
|
299
|
+
end
|
300
|
+
|
301
|
+
value_check && return_check
|
297
302
|
end
|
298
303
|
else
|
299
304
|
Test.call(val, IS_AP, klass)
|
@@ -308,8 +313,15 @@ module RBS
|
|
308
313
|
val.is_a?(singleton_class)
|
309
314
|
when Types::Interface
|
310
315
|
if (definition = builder.build_interface(type.name.absolute!))
|
311
|
-
definition.methods.
|
312
|
-
Test.call(val, RESPOND_TOP, method_name)
|
316
|
+
definition.methods.each.all? do |method_name, method|
|
317
|
+
next false unless Test.call(val, RESPOND_TOP, method_name)
|
318
|
+
|
319
|
+
meth = Test.call(val, METHOD, method_name)
|
320
|
+
method.defs.all? do |type_def|
|
321
|
+
type_def.member.overloads.all? do |overload|
|
322
|
+
callable_argument?(meth.parameters, overload.method_type)
|
323
|
+
end
|
324
|
+
end
|
313
325
|
end
|
314
326
|
end
|
315
327
|
when Types::Variable
|
@@ -336,6 +348,73 @@ module RBS
|
|
336
348
|
false
|
337
349
|
end
|
338
350
|
end
|
351
|
+
|
352
|
+
private
|
353
|
+
|
354
|
+
def callable_argument?(parameters, method_type)
|
355
|
+
fun = method_type.type
|
356
|
+
take_has_rest = !!parameters.find { |(op, _)| op == :rest }
|
357
|
+
|
358
|
+
fun.required_positionals.each do
|
359
|
+
op, _ = parameters.first
|
360
|
+
return false if op.nil? || op == :keyreq || op == :key || op == :keyrest
|
361
|
+
parameters.shift if op == :req || op == :opt
|
362
|
+
end
|
363
|
+
|
364
|
+
fun.optional_positionals.each do
|
365
|
+
op, _ = parameters.first
|
366
|
+
return false if op.nil? || op == :req || op == :keyreq || op == :key || op == :keyrest
|
367
|
+
parameters.shift if op == :opt
|
368
|
+
end
|
369
|
+
|
370
|
+
if fun.rest_positionals
|
371
|
+
op, _ = parameters.shift
|
372
|
+
return false if op.nil? || op != :rest
|
373
|
+
end
|
374
|
+
|
375
|
+
fun.trailing_positionals.each do
|
376
|
+
op, _ = parameters.first
|
377
|
+
return false if !take_has_rest && (op.nil? || op == :keyreq || op == :key || op == :keyrest)
|
378
|
+
index = parameters.find_index { |(op, _)| op == :req }
|
379
|
+
parameters.delete_at(index) if index
|
380
|
+
end
|
381
|
+
|
382
|
+
if fun.has_keyword?
|
383
|
+
return false if !take_has_rest && parameters.empty?
|
384
|
+
|
385
|
+
fun.required_keywords.each do |name, _|
|
386
|
+
return false if !take_has_rest && parameters.empty?
|
387
|
+
index = parameters.find_index { |(op, n)| (op == :keyreq || op == :key) && n == name }
|
388
|
+
parameters.delete_at(index) if index
|
389
|
+
end
|
390
|
+
|
391
|
+
if !fun.optional_keywords.empty?
|
392
|
+
fun.optional_keywords.each do |name, _|
|
393
|
+
return false if !take_has_rest && parameters.empty?
|
394
|
+
index = parameters.find_index { |(op, n)| op == :key && n == name }
|
395
|
+
parameters.delete_at(index) if index
|
396
|
+
end
|
397
|
+
op, _ = parameters.first
|
398
|
+
return false if op == :req
|
399
|
+
end
|
400
|
+
|
401
|
+
if fun.rest_keywords
|
402
|
+
op, _ = parameters.first
|
403
|
+
return false if (!take_has_rest && op.nil?)
|
404
|
+
# f(a) allows (Integer, a: Integer)
|
405
|
+
return false if op == :req && fun.required_keywords.empty?
|
406
|
+
end
|
407
|
+
|
408
|
+
op, _ = parameters.first
|
409
|
+
return true if (op == :req || op == :opt) && parameters.length == 1
|
410
|
+
end
|
411
|
+
|
412
|
+
# rest required arguments
|
413
|
+
op, _ = parameters.first
|
414
|
+
return false if op == :req || op == :keyreq
|
415
|
+
|
416
|
+
true
|
417
|
+
end
|
339
418
|
end
|
340
419
|
end
|
341
420
|
end
|
data/lib/rbs/types.rb
CHANGED
@@ -515,22 +515,34 @@ module RBS
|
|
515
515
|
end
|
516
516
|
|
517
517
|
class Record
|
518
|
-
attr_reader :fields
|
518
|
+
attr_reader :all_fields, :fields, :optional_fields
|
519
519
|
attr_reader :location
|
520
520
|
|
521
|
-
def initialize(fields
|
522
|
-
|
521
|
+
def initialize(all_fields: nil, fields: nil, location:)
|
522
|
+
case
|
523
|
+
when fields && all_fields.nil?
|
524
|
+
@all_fields = fields.map { |k, v| [k, [v, true]] }.to_h
|
525
|
+
@fields = fields
|
526
|
+
@optional_fields = {}
|
527
|
+
when all_fields && fields.nil?
|
528
|
+
@all_fields = all_fields
|
529
|
+
@fields = all_fields.filter_map { |k, (v, required)| [k, v] if required }.to_h
|
530
|
+
@optional_fields = all_fields.filter_map { |k, (v, required)| [k, v] unless required }.to_h
|
531
|
+
else
|
532
|
+
raise ArgumentError, "only one of `:fields` or `:all_fields` is requireds"
|
533
|
+
end
|
534
|
+
|
523
535
|
@location = location
|
524
536
|
end
|
525
537
|
|
526
538
|
def ==(other)
|
527
|
-
other.is_a?(Record) && other.fields == fields
|
539
|
+
other.is_a?(Record) && other.fields == fields && other.optional_fields == optional_fields
|
528
540
|
end
|
529
541
|
|
530
542
|
alias eql? ==
|
531
543
|
|
532
544
|
def hash
|
533
|
-
self.class.hash ^
|
545
|
+
self.class.hash ^ all_fields.hash
|
534
546
|
end
|
535
547
|
|
536
548
|
def free_variables(set = Set.new)
|
@@ -538,27 +550,35 @@ module RBS
|
|
538
550
|
fields.each_value do |type|
|
539
551
|
type.free_variables set
|
540
552
|
end
|
553
|
+
optional_fields.each_value do |type|
|
554
|
+
type.free_variables set
|
555
|
+
end
|
541
556
|
end
|
542
557
|
end
|
543
558
|
|
544
559
|
def to_json(state = _ = nil)
|
545
|
-
{ class: :record, fields: fields, location: location }.to_json(state)
|
560
|
+
{ class: :record, fields: fields, optional_fields: optional_fields, location: location }.to_json(state)
|
546
561
|
end
|
547
562
|
|
548
563
|
def sub(s)
|
549
|
-
self.class.new(
|
550
|
-
|
564
|
+
self.class.new(
|
565
|
+
all_fields: all_fields.transform_values {|ty, required| [ty.sub(s), required] },
|
566
|
+
location: location
|
567
|
+
)
|
551
568
|
end
|
552
569
|
|
553
570
|
def to_s(level = 0)
|
554
|
-
return "{ }" if
|
571
|
+
return "{ }" if all_fields.empty?
|
555
572
|
|
556
|
-
fields =
|
557
|
-
if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_0-9]*\z/)
|
573
|
+
fields = all_fields.map do |key, (type, required)|
|
574
|
+
field = if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_0-9]*\z/)
|
558
575
|
"#{key}: #{type}"
|
559
576
|
else
|
560
577
|
"#{key.inspect} => #{type}"
|
561
578
|
end
|
579
|
+
|
580
|
+
field = "?#{field}" unless required
|
581
|
+
field
|
562
582
|
end
|
563
583
|
"{ #{fields.join(", ")} }"
|
564
584
|
end
|
@@ -566,6 +586,7 @@ module RBS
|
|
566
586
|
def each_type(&block)
|
567
587
|
if block
|
568
588
|
fields.each_value(&block)
|
589
|
+
optional_fields.each_value(&block)
|
569
590
|
else
|
570
591
|
enum_for :each_type
|
571
592
|
end
|
@@ -573,7 +594,7 @@ module RBS
|
|
573
594
|
|
574
595
|
def map_type_name(&block)
|
575
596
|
Record.new(
|
576
|
-
|
597
|
+
all_fields: all_fields.transform_values {|ty, required| [ty.map_type_name(&block), required] },
|
577
598
|
location: location
|
578
599
|
)
|
579
600
|
end
|
@@ -581,7 +602,7 @@ module RBS
|
|
581
602
|
def map_type(&block)
|
582
603
|
if block
|
583
604
|
Record.new(
|
584
|
-
|
605
|
+
all_fields: all_fields.transform_values {|type, required| [yield(type), required] },
|
585
606
|
location: location
|
586
607
|
)
|
587
608
|
else
|
@@ -1181,6 +1202,84 @@ module RBS
|
|
1181
1202
|
end
|
1182
1203
|
end
|
1183
1204
|
|
1205
|
+
class UntypedFunction
|
1206
|
+
attr_reader :return_type
|
1207
|
+
|
1208
|
+
def initialize(return_type:)
|
1209
|
+
@return_type = return_type
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
def free_variables(acc = Set.new)
|
1213
|
+
return_type.free_variables(acc)
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
def map_type(&block)
|
1217
|
+
if block
|
1218
|
+
update(return_type: yield(return_type))
|
1219
|
+
else
|
1220
|
+
enum_for :map_type
|
1221
|
+
end
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
def each_type(&block)
|
1225
|
+
if block
|
1226
|
+
yield return_type
|
1227
|
+
else
|
1228
|
+
enum_for :each_type
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
def each_param(&block)
|
1233
|
+
if block
|
1234
|
+
# noop
|
1235
|
+
else
|
1236
|
+
enum_for :each_param
|
1237
|
+
end
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
def to_json(state = _ = nil)
|
1241
|
+
{
|
1242
|
+
return_type: return_type
|
1243
|
+
}.to_json(state)
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
def sub(subst)
|
1247
|
+
map_type { _1.sub(subst) }
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
def with_return_type(ty)
|
1251
|
+
update(return_type: ty)
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
def update(return_type: self.return_type)
|
1255
|
+
UntypedFunction.new(return_type: return_type)
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
def empty?
|
1259
|
+
true
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
def has_self_type?
|
1263
|
+
return_type.has_self_type?
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
def has_classish_type?
|
1267
|
+
return_type.has_classish_type?
|
1268
|
+
end
|
1269
|
+
|
1270
|
+
def with_nonreturn_void
|
1271
|
+
false
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
def param_to_s
|
1275
|
+
"?"
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
def return_to_s
|
1279
|
+
return_type.to_s(1)
|
1280
|
+
end
|
1281
|
+
end
|
1282
|
+
|
1184
1283
|
class Block
|
1185
1284
|
attr_reader :type
|
1186
1285
|
attr_reader :required
|
data/lib/rbs/unit_test/spy.rb
CHANGED
data/lib/rbs/version.rb
CHANGED
data/rbs.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
# Specify which files should be added to the gem when it is released.
|
29
29
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
30
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
31
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin|steep)/}) }
|
31
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin|steep|benchmark)/}) }
|
32
32
|
end
|
33
33
|
spec.extensions = %w{ext/rbs_extension/extconf.rb}
|
34
34
|
|
data/sig/environment_loader.rbs
CHANGED
data/sig/errors.rbs
CHANGED
data/sig/method_types.rbs
CHANGED
@@ -14,11 +14,11 @@ module RBS
|
|
14
14
|
type loc = def_loc | attr_loc
|
15
15
|
|
16
16
|
attr_reader type_params: Array[AST::TypeParam]
|
17
|
-
attr_reader type: Types::
|
17
|
+
attr_reader type: Types::function
|
18
18
|
attr_reader block: Types::Block?
|
19
19
|
attr_reader location: loc?
|
20
20
|
|
21
|
-
def initialize: (type_params: Array[AST::TypeParam], type: Types::
|
21
|
+
def initialize: (type_params: Array[AST::TypeParam], type: Types::function, block: Types::Block?, location: loc?) -> void
|
22
22
|
|
23
23
|
def ==: (untyped other) -> bool
|
24
24
|
|
@@ -29,7 +29,7 @@ module RBS
|
|
29
29
|
#
|
30
30
|
def sub: (Substitution) -> MethodType
|
31
31
|
|
32
|
-
def update: (?type_params: Array[AST::TypeParam], ?type: Types::
|
32
|
+
def update: (?type_params: Array[AST::TypeParam], ?type: Types::function, ?block: Types::Block?, ?location: loc?) -> MethodType
|
33
33
|
|
34
34
|
def free_variables: (?Set[Symbol] set) -> Set[Symbol]
|
35
35
|
|