rbs 3.4.4 → 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +12 -4
- data/.github/workflows/dependabot.yml +26 -0
- data/.github/workflows/ruby.yml +14 -1
- data/CHANGELOG.md +87 -1
- data/README.md +5 -3
- data/Rakefile +20 -3
- data/Steepfile +1 -1
- data/core/enumerator.rbs +1 -1
- data/core/float.rbs +2 -1
- data/core/gc.rbs +272 -150
- data/core/integer.rbs +6 -4
- 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/proc.rbs +1 -1
- data/core/range.rbs +2 -2
- data/core/rational.rbs +2 -1
- data/core/regexp.rbs +101 -90
- data/core/ruby_vm.rbs +107 -103
- data/core/rubygems/rubygems.rbs +1 -1
- data/core/set.rbs +13 -7
- 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/gem.md +0 -1
- 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/lexer.c +1338 -1341
- data/ext/rbs_extension/lexer.h +2 -0
- data/ext/rbs_extension/lexer.re +2 -3
- data/ext/rbs_extension/lexstate.c +5 -1
- data/ext/rbs_extension/location.c +80 -70
- data/ext/rbs_extension/location.h +25 -5
- data/ext/rbs_extension/parser.c +149 -43
- data/ext/rbs_extension/parserstate.c +12 -1
- data/ext/rbs_extension/parserstate.h +9 -0
- data/ext/rbs_extension/ruby_objs.c +13 -3
- data/ext/rbs_extension/ruby_objs.h +1 -0
- data/lib/rbs/cli/validate.rb +2 -2
- data/lib/rbs/cli.rb +4 -6
- 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/location_aux.rb +6 -1
- data/lib/rbs/parser/lex_result.rb +15 -0
- data/lib/rbs/parser/token.rb +23 -0
- data/lib/rbs/parser_aux.rb +12 -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 +7 -2
- data/sig/environment_loader.rbs +1 -1
- data/sig/errors.rbs +1 -1
- data/sig/manifest.yaml +0 -1
- data/sig/method_types.rbs +3 -3
- data/sig/parser.rbs +28 -0
- 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
- data/stdlib/uri/0/mailto.rbs +84 -0
- metadata +7 -9
- data/Gemfile +0 -30
- data/Gemfile.lock +0 -117
- 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/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,12 @@ 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
|
31
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
32
|
+
[
|
33
|
+
%r{^(test|spec|features|bin|steep|benchmark)/},
|
34
|
+
/Gemfile/
|
35
|
+
].any? {|r| f.match(r) }
|
36
|
+
end
|
32
37
|
end
|
33
38
|
spec.extensions = %w{ext/rbs_extension/extconf.rb}
|
34
39
|
|
@@ -36,5 +41,5 @@ Gem::Specification.new do |spec|
|
|
36
41
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
42
|
spec.require_paths = ["lib"]
|
38
43
|
spec.required_ruby_version = ">= 3.0"
|
39
|
-
spec.add_dependency "
|
44
|
+
spec.add_dependency "logger"
|
40
45
|
end
|
data/sig/environment_loader.rbs
CHANGED
data/sig/errors.rbs
CHANGED
data/sig/manifest.yaml
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
|
|
data/sig/parser.rbs
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
module RBS
|
2
2
|
class Parser
|
3
|
+
# Result of `Parser.lex`
|
4
|
+
class LexResult
|
5
|
+
attr_reader buffer: Buffer
|
6
|
+
attr_reader value: Array[Token]
|
7
|
+
|
8
|
+
def initialize: (buffer: Buffer, value: Array[Token]) -> void
|
9
|
+
end
|
10
|
+
|
11
|
+
# Represents a token per result of `Parser.lex`.
|
12
|
+
class Token
|
13
|
+
attr_reader type: Symbol
|
14
|
+
attr_reader location: Location[untyped, untyped]
|
15
|
+
|
16
|
+
def initialize: (type: Symbol, location: Location[untyped, untyped]) -> void
|
17
|
+
def value: () -> String
|
18
|
+
def comment?: () -> bool
|
19
|
+
end
|
20
|
+
|
3
21
|
# Parse a method type and return it
|
4
22
|
#
|
5
23
|
# When `range` keyword is specified, it starts parsing from the `begin` to the `end` of the range.
|
@@ -50,6 +68,14 @@ module RBS
|
|
50
68
|
#
|
51
69
|
def self.parse_signature: (Buffer | String) -> [Buffer, Array[AST::Directives::t], Array[AST::Declarations::t]]
|
52
70
|
|
71
|
+
# Parse whole RBS file and return result.
|
72
|
+
#
|
73
|
+
# ```ruby
|
74
|
+
# RBS::Parser.lex("# Comment\nmodule A\nend\n").value.map(&:type)
|
75
|
+
# # => [:tLINECOMMENT, :kMODULE, :tUIDENT, :kEND, :pEOF]
|
76
|
+
# ```
|
77
|
+
def self.lex: (Buffer | String) -> LexResult
|
78
|
+
|
53
79
|
KEYWORDS: Hash[String, bot]
|
54
80
|
|
55
81
|
private
|
@@ -62,6 +88,8 @@ module RBS
|
|
62
88
|
|
63
89
|
def self._parse_signature: (Buffer, Integer end_pos) -> [Array[AST::Directives::t], Array[AST::Declarations::t]]
|
64
90
|
|
91
|
+
def self._lex: (Buffer, Integer end_pos) -> Array[[Symbol, Location[untyped, untyped]]]
|
92
|
+
|
65
93
|
class LocatedValue
|
66
94
|
end
|
67
95
|
end
|
data/sig/prototype/helpers.rbs
CHANGED
@@ -13,6 +13,10 @@ module RBS
|
|
13
13
|
|
14
14
|
def keyword_hash?: (node) -> bool
|
15
15
|
|
16
|
+
# Returns a symbol if the node is a symbol literal node
|
17
|
+
#
|
18
|
+
def symbol_literal_node?: (node) -> Symbol?
|
19
|
+
|
16
20
|
def args_from_node: (node?) -> Array[untyped]
|
17
21
|
|
18
22
|
def untyped: () -> Types::Bases::Any
|
data/sig/prototype/rbi.rbs
CHANGED
data/sig/types.rbs
CHANGED
@@ -301,11 +301,16 @@ module RBS
|
|
301
301
|
end
|
302
302
|
|
303
303
|
class Record
|
304
|
+
attr_reader all_fields: Hash[Symbol, [t, bool]]
|
305
|
+
|
304
306
|
attr_reader fields: Hash[Symbol, t]
|
305
307
|
|
308
|
+
attr_reader optional_fields: Hash[Symbol, t]
|
309
|
+
|
306
310
|
type loc = Location[bot, bot]
|
307
311
|
|
308
312
|
def initialize: (fields: Hash[Symbol, t], location: loc?) -> void
|
313
|
+
| (all_fields: Hash[Symbol, [t, bool]], location: loc?) -> void
|
309
314
|
|
310
315
|
include _TypeBase
|
311
316
|
|
@@ -443,13 +448,58 @@ module RBS
|
|
443
448
|
def with_nonreturn_void?: () -> bool
|
444
449
|
end
|
445
450
|
|
451
|
+
# Function type without type checking arguments
|
452
|
+
#
|
453
|
+
class UntypedFunction
|
454
|
+
attr_reader return_type: t
|
455
|
+
|
456
|
+
def initialize: (return_type: t) -> void
|
457
|
+
|
458
|
+
def free_variables: (?Set[Symbol]) -> Set[Symbol]
|
459
|
+
|
460
|
+
def map_type: { (t) -> t } -> UntypedFunction
|
461
|
+
| -> Enumerator[t, UntypedFunction]
|
462
|
+
|
463
|
+
def map_type_name: () { (TypeName, Location[untyped, untyped]?, t) -> TypeName } -> UntypedFunction
|
464
|
+
|
465
|
+
def each_type: () { (t) -> void } -> void
|
466
|
+
| -> Enumerator[t, void]
|
467
|
+
|
468
|
+
def each_param: () { (Function::Param) -> void } -> void
|
469
|
+
| -> Enumerator[Function::Param, void]
|
470
|
+
|
471
|
+
include _ToJson
|
472
|
+
|
473
|
+
def sub: (Substitution) -> UntypedFunction
|
474
|
+
|
475
|
+
def with_return_type: (t) -> UntypedFunction
|
476
|
+
|
477
|
+
def update: (?return_type: t) -> UntypedFunction
|
478
|
+
|
479
|
+
def empty?: () -> bool
|
480
|
+
|
481
|
+
def has_self_type?: () -> bool
|
482
|
+
|
483
|
+
def has_classish_type?: () -> bool
|
484
|
+
|
485
|
+
def with_nonreturn_void?: () -> bool
|
486
|
+
|
487
|
+
# Returns `?`
|
488
|
+
def param_to_s: () -> String
|
489
|
+
|
490
|
+
# Returns `return_type.to_s(1)`
|
491
|
+
def return_to_s: () -> String
|
492
|
+
end
|
493
|
+
|
494
|
+
type function = Types::Function | Types::UntypedFunction
|
495
|
+
|
446
496
|
class Block
|
447
|
-
attr_reader type:
|
497
|
+
attr_reader type: function
|
448
498
|
attr_reader required: bool
|
449
499
|
|
450
500
|
attr_reader self_type: t?
|
451
501
|
|
452
|
-
def initialize: (type:
|
502
|
+
def initialize: (type: function, ?self_type: t?, required: boolish) -> void
|
453
503
|
|
454
504
|
def ==: (untyped other) -> bool
|
455
505
|
|
@@ -465,14 +515,14 @@ module RBS
|
|
465
515
|
end
|
466
516
|
|
467
517
|
class Proc
|
468
|
-
attr_reader type:
|
518
|
+
attr_reader type: function
|
469
519
|
attr_reader block: Block?
|
470
520
|
|
471
521
|
attr_reader self_type: t?
|
472
522
|
|
473
523
|
type loc = Location[bot, bot]
|
474
524
|
|
475
|
-
def initialize: (location: loc?, type:
|
525
|
+
def initialize: (location: loc?, type: function, ?self_type: t?, block: Block?) -> void
|
476
526
|
|
477
527
|
include _TypeBase
|
478
528
|
|
data/sig/variance_calculator.rbs
CHANGED
@@ -73,14 +73,14 @@ module RBS
|
|
73
73
|
def in_inherit: (name: TypeName, args: Array[Types::t], variables: Array[Symbol]) -> Result
|
74
74
|
|
75
75
|
# The type name must be normalized
|
76
|
-
#
|
76
|
+
#
|
77
77
|
def in_type_alias: (name: TypeName) -> Result
|
78
78
|
|
79
79
|
private
|
80
80
|
|
81
81
|
def type: (Types::t, result: Result, context: variance) -> void
|
82
82
|
|
83
|
-
def function: (Types::
|
83
|
+
def function: (Types::function, result: Result, context: variance) -> void
|
84
84
|
|
85
85
|
def negate: (variance) -> variance
|
86
86
|
end
|
data/stdlib/csv/0/csv.rbs
CHANGED
@@ -1722,7 +1722,10 @@ class CSV < Object
|
|
1722
1722
|
# would read `UTF-32BE` data from the file but transcode it to `UTF-8`
|
1723
1723
|
# before parsing.
|
1724
1724
|
#
|
1725
|
-
def self.foreach:
|
1725
|
+
def self.foreach: (String | IO path, ?String mode, headers: true, **untyped options) { (::CSV::Row arg0) -> void } -> void
|
1726
|
+
| (String | IO path, ?String mode, headers: true, **untyped options) -> Enumerator[::CSV::Row, void]
|
1727
|
+
| (String | IO path, ?String mode, **untyped options) { (::Array[String?] arg0) -> void } -> void
|
1728
|
+
| (String | IO path, ?String mode, **untyped options) -> Enumerator[::Array[String?], void]
|
1726
1729
|
|
1727
1730
|
# <!--
|
1728
1731
|
# rdoc-file=lib/csv.rb
|