rbs 0.16.0 → 0.20.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 +1 -1
- data/CHANGELOG.md +30 -0
- data/README.md +1 -1
- data/Rakefile +12 -1
- data/core/array.rbs +1 -1
- data/core/builtin.rbs +2 -2
- data/core/dir.rbs +1 -1
- data/core/enumerable.rbs +41 -40
- data/core/enumerator.rbs +5 -5
- data/core/file.rbs +0 -4
- data/core/hash.rbs +9 -11
- data/core/io.rbs +1 -1
- data/core/object_space.rbs +98 -0
- data/core/range.rbs +1 -1
- data/core/struct.rbs +1 -1
- data/core/time.rbs +0 -12
- data/lib/rbs/ast/members.rb +9 -3
- data/lib/rbs/definition.rb +9 -4
- data/lib/rbs/definition_builder.rb +123 -71
- data/lib/rbs/environment.rb +3 -0
- data/lib/rbs/environment_loader.rb +1 -1
- data/lib/rbs/environment_walker.rb +70 -35
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +944 -879
- data/lib/rbs/parser.y +110 -63
- data/lib/rbs/prototype/rb.rb +163 -23
- data/lib/rbs/prototype/rbi.rb +5 -5
- data/lib/rbs/prototype/runtime.rb +2 -1
- data/lib/rbs/test/hook.rb +30 -17
- data/lib/rbs/test/type_check.rb +6 -1
- data/lib/rbs/types.rb +63 -6
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +9 -1
- data/schema/members.json +5 -1
- data/sig/definition.rbs +8 -3
- data/sig/definition_builder.rbs +6 -2
- data/sig/members.rbs +4 -1
- data/sig/method_types.rbs +3 -16
- data/sig/types.rbs +17 -1
- data/stdlib/csv/0/csv.rbs +3 -3
- data/stdlib/dbm/0/dbm.rbs +1 -3
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/prime/0/prime.rbs +1 -1
- data/stdlib/set/0/set.rbs +10 -10
- data/stdlib/singleton/0/singleton.rbs +111 -0
- data/stdlib/tsort/0/cyclic.rbs +4 -0
- data/stdlib/tsort/0/interfaces.rbs +19 -0
- data/stdlib/tsort/0/tsort.rbs +371 -0
- data/stdlib/yaml/0/dbm.rbs +221 -0
- data/stdlib/yaml/0/store.rbs +53 -0
- data/steep/Gemfile.lock +12 -12
- metadata +11 -3
data/lib/rbs/prototype/rbi.rb
CHANGED
@@ -387,19 +387,19 @@ module RBS
|
|
387
387
|
if block
|
388
388
|
if (type = vars[block])
|
389
389
|
if type.is_a?(Types::Proc)
|
390
|
-
method_block =
|
390
|
+
method_block = Types::Block.new(required: true, type: type.type)
|
391
391
|
elsif type.is_a?(Types::Bases::Any)
|
392
|
-
method_block =
|
392
|
+
method_block = Types::Block.new(
|
393
393
|
required: true,
|
394
394
|
type: Types::Function.empty(Types::Bases::Any.new(location: nil))
|
395
395
|
)
|
396
396
|
# Handle an optional block like `T.nilable(T.proc.void)`.
|
397
397
|
elsif type.is_a?(Types::Optional) && type.type.is_a?(Types::Proc)
|
398
|
-
method_block =
|
398
|
+
method_block = Types::Block.new(required: false, type: type.type.type)
|
399
399
|
else
|
400
400
|
STDERR.puts "Unexpected block type: #{type}"
|
401
401
|
PP.pp args_node, STDERR
|
402
|
-
method_block =
|
402
|
+
method_block = Types::Block.new(
|
403
403
|
required: true,
|
404
404
|
type: Types::Function.empty(Types::Bases::Any.new(location: nil))
|
405
405
|
)
|
@@ -485,7 +485,7 @@ module RBS
|
|
485
485
|
Types::Tuple.new(types: types, location: nil)
|
486
486
|
else
|
487
487
|
if proc_type?(type_node)
|
488
|
-
Types::Proc.new(type: method_type(nil, type_node, variables: variables).type, location: nil)
|
488
|
+
Types::Proc.new(type: method_type(nil, type_node, variables: variables).type, block: nil, location: nil)
|
489
489
|
else
|
490
490
|
STDERR.puts "Unexpected type_node:"
|
491
491
|
PP.pp type_node, STDERR
|
@@ -94,6 +94,7 @@ module RBS
|
|
94
94
|
optional_positionals << Types::Function::Param.new(name: name, type: untyped)
|
95
95
|
when :rest
|
96
96
|
requireds = trailing_positionals
|
97
|
+
name = nil if name == :* # For `def f(...) end` syntax
|
97
98
|
rest = Types::Function::Param.new(name: name, type: untyped)
|
98
99
|
when :keyreq
|
99
100
|
required_keywords[name] = Types::Function::Param.new(name: nil, type: untyped)
|
@@ -102,7 +103,7 @@ module RBS
|
|
102
103
|
when :keyrest
|
103
104
|
rest_keywords = Types::Function::Param.new(name: nil, type: untyped)
|
104
105
|
when :block
|
105
|
-
block =
|
106
|
+
block = Types::Block.new(
|
106
107
|
type: Types::Function.empty(untyped).update(rest_positionals: Types::Function::Param.new(name: nil, type: untyped)),
|
107
108
|
required: true
|
108
109
|
)
|
data/lib/rbs/test/hook.rb
CHANGED
@@ -27,26 +27,28 @@ module RBS
|
|
27
27
|
:>> => "rshift",
|
28
28
|
:~ => "tilda"
|
29
29
|
}
|
30
|
-
def self.alias_names(target)
|
30
|
+
def self.alias_names(target, random)
|
31
|
+
suffix = "#{RBS::Test.suffix}_#{random}"
|
32
|
+
|
31
33
|
case target
|
32
34
|
when *OPERATORS.keys
|
33
35
|
name = OPERATORS[target]
|
34
36
|
[
|
35
|
-
"#{name}____with__#{
|
36
|
-
"#{name}____without__#{
|
37
|
+
"#{name}____with__#{suffix}",
|
38
|
+
"#{name}____without__#{suffix}"
|
37
39
|
]
|
38
40
|
else
|
39
41
|
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
40
42
|
|
41
43
|
[
|
42
|
-
"#{aliased_target}__with__#{
|
43
|
-
"#{aliased_target}__without__#{
|
44
|
+
"#{aliased_target}__with__#{suffix}#{punctuation}",
|
45
|
+
"#{aliased_target}__without__#{suffix}#{punctuation}"
|
44
46
|
]
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
def self.setup_alias_method_chain(klass, target)
|
49
|
-
with_method, without_method = alias_names(target)
|
50
|
+
def self.setup_alias_method_chain(klass, target, random:)
|
51
|
+
with_method, without_method = alias_names(target, random)
|
50
52
|
|
51
53
|
RBS.logger.debug "alias name: #{target}, #{with_method}, #{without_method}"
|
52
54
|
|
@@ -65,12 +67,12 @@ module RBS
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
def self.hook_method_source(prefix, method_name, key)
|
69
|
-
with_name, without_name = alias_names(method_name)
|
70
|
+
def self.hook_method_source(prefix, method_name, key, random:)
|
71
|
+
with_name, without_name = alias_names(method_name, random)
|
70
72
|
full_method_name = "#{prefix}#{method_name}"
|
71
73
|
|
72
74
|
[__LINE__ + 1, <<RUBY]
|
73
|
-
def #{with_name}(*args)
|
75
|
+
def #{with_name}(*args, &block)
|
74
76
|
::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
|
75
77
|
|
76
78
|
begin
|
@@ -78,11 +80,18 @@ def #{with_name}(*args)
|
|
78
80
|
block_calls = []
|
79
81
|
|
80
82
|
if block_given?
|
81
|
-
|
83
|
+
receiver = self
|
84
|
+
|
85
|
+
wrapped_block = proc do |*block_args|
|
82
86
|
return_from_block = false
|
83
87
|
|
84
88
|
begin
|
85
|
-
block_result =
|
89
|
+
block_result = if receiver.equal?(self)
|
90
|
+
yield(*block_args)
|
91
|
+
else
|
92
|
+
instance_exec(*block_args, &block)
|
93
|
+
end
|
94
|
+
|
86
95
|
return_from_block = true
|
87
96
|
ensure
|
88
97
|
exn = $!
|
@@ -109,7 +118,9 @@ def #{with_name}(*args)
|
|
109
118
|
end
|
110
119
|
|
111
120
|
block_result
|
112
|
-
end
|
121
|
+
end.ruby2_keywords
|
122
|
+
|
123
|
+
result = __send__(:"#{without_name}", *args, &wrapped_block)
|
113
124
|
else
|
114
125
|
result = __send__(:"#{without_name}", *args)
|
115
126
|
end
|
@@ -154,17 +165,19 @@ RUBY
|
|
154
165
|
end
|
155
166
|
|
156
167
|
def self.hook_instance_method(klass, method, key:)
|
157
|
-
|
168
|
+
random = SecureRandom.hex(4)
|
169
|
+
line, source = hook_method_source("#{klass}#", method, key, random: random)
|
158
170
|
|
159
171
|
klass.module_eval(source, __FILE__, line)
|
160
|
-
setup_alias_method_chain klass, method
|
172
|
+
setup_alias_method_chain klass, method, random: random
|
161
173
|
end
|
162
174
|
|
163
175
|
def self.hook_singleton_method(klass, method, key:)
|
164
|
-
|
176
|
+
random = SecureRandom.hex(4)
|
177
|
+
line, source = hook_method_source("#{klass}.",method, key, random: random)
|
165
178
|
|
166
179
|
klass.singleton_class.module_eval(source, __FILE__, line)
|
167
|
-
setup_alias_method_chain klass.singleton_class, method
|
180
|
+
setup_alias_method_chain klass.singleton_class, method, random: random
|
168
181
|
end
|
169
182
|
end
|
170
183
|
end
|
data/lib/rbs/test/type_check.rb
CHANGED
@@ -288,7 +288,12 @@ module RBS
|
|
288
288
|
end
|
289
289
|
when Types::ClassSingleton
|
290
290
|
klass = get_class(type.name) or return false
|
291
|
-
|
291
|
+
singleton_class = begin
|
292
|
+
klass.singleton_class
|
293
|
+
rescue TypeError
|
294
|
+
return false
|
295
|
+
end
|
296
|
+
val.is_a?(singleton_class)
|
292
297
|
when Types::Interface
|
293
298
|
methods = Set.new(Test.call(val, METHODS))
|
294
299
|
if (definition = builder.build_interface(type.name))
|
data/lib/rbs/types.rb
CHANGED
@@ -947,44 +947,100 @@ module RBS
|
|
947
947
|
end
|
948
948
|
end
|
949
949
|
|
950
|
+
class Block
|
951
|
+
attr_reader :type
|
952
|
+
attr_reader :required
|
953
|
+
|
954
|
+
def initialize(type:, required:)
|
955
|
+
@type = type
|
956
|
+
@required = required
|
957
|
+
end
|
958
|
+
|
959
|
+
def ==(other)
|
960
|
+
other.is_a?(Block) &&
|
961
|
+
other.type == type &&
|
962
|
+
other.required == required
|
963
|
+
end
|
964
|
+
|
965
|
+
def to_json(*a)
|
966
|
+
{
|
967
|
+
type: type,
|
968
|
+
required: required
|
969
|
+
}.to_json(*a)
|
970
|
+
end
|
971
|
+
|
972
|
+
def sub(s)
|
973
|
+
self.class.new(
|
974
|
+
type: type.sub(s),
|
975
|
+
required: required
|
976
|
+
)
|
977
|
+
end
|
978
|
+
|
979
|
+
def map_type(&block)
|
980
|
+
Block.new(
|
981
|
+
required: required,
|
982
|
+
type: type.map_type(&block)
|
983
|
+
)
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
950
987
|
class Proc
|
951
988
|
attr_reader :type
|
989
|
+
attr_reader :block
|
952
990
|
attr_reader :location
|
953
991
|
|
954
|
-
def initialize(location:, type:)
|
992
|
+
def initialize(location:, type:, block:)
|
955
993
|
@type = type
|
994
|
+
@block = block
|
956
995
|
@location = location
|
957
996
|
end
|
958
997
|
|
959
998
|
def ==(other)
|
960
|
-
other.is_a?(Proc) && other.type == type
|
999
|
+
other.is_a?(Proc) && other.type == type && other.block == block
|
961
1000
|
end
|
962
1001
|
|
963
1002
|
alias eql? ==
|
964
1003
|
|
965
1004
|
def hash
|
966
|
-
self.class.hash ^ type.hash
|
1005
|
+
self.class.hash ^ type.hash ^ block.hash
|
967
1006
|
end
|
968
1007
|
|
969
1008
|
def free_variables(set = Set[])
|
970
1009
|
type.free_variables(set)
|
1010
|
+
block&.type&.free_variables(set)
|
1011
|
+
set
|
971
1012
|
end
|
972
1013
|
|
973
1014
|
def to_json(*a)
|
974
|
-
{
|
1015
|
+
{
|
1016
|
+
class: :proc,
|
1017
|
+
type: type,
|
1018
|
+
block: block,
|
1019
|
+
location: location
|
1020
|
+
}.to_json(*a)
|
975
1021
|
end
|
976
1022
|
|
977
1023
|
def sub(s)
|
978
|
-
self.class.new(type: type.sub(s), location: location)
|
1024
|
+
self.class.new(type: type.sub(s), block: block&.sub(s), location: location)
|
979
1025
|
end
|
980
1026
|
|
981
1027
|
def to_s(level = 0)
|
982
|
-
|
1028
|
+
case
|
1029
|
+
when b = block
|
1030
|
+
if b.required
|
1031
|
+
"^(#{type.param_to_s}) { (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1032
|
+
else
|
1033
|
+
"^(#{type.param_to_s}) ?{ (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1034
|
+
end
|
1035
|
+
else
|
1036
|
+
"^(#{type.param_to_s}) -> #{type.return_to_s}"
|
1037
|
+
end
|
983
1038
|
end
|
984
1039
|
|
985
1040
|
def each_type(&block)
|
986
1041
|
if block
|
987
1042
|
type.each_type(&block)
|
1043
|
+
self.block&.type&.each_type(&block)
|
988
1044
|
else
|
989
1045
|
enum_for :each_type
|
990
1046
|
end
|
@@ -993,6 +1049,7 @@ module RBS
|
|
993
1049
|
def map_type_name(&block)
|
994
1050
|
Proc.new(
|
995
1051
|
type: type.map_type_name(&block),
|
1052
|
+
block: self.block&.map_type {|type| type.map_type_name(&block) },
|
996
1053
|
location: location
|
997
1054
|
)
|
998
1055
|
end
|
data/lib/rbs/version.rb
CHANGED
data/lib/rbs/writer.rb
CHANGED
@@ -285,7 +285,15 @@ module RBS
|
|
285
285
|
else
|
286
286
|
"(#{attr.ivar_name})"
|
287
287
|
end
|
288
|
-
|
288
|
+
|
289
|
+
receiver = case attr.kind
|
290
|
+
when :singleton
|
291
|
+
"self."
|
292
|
+
when :instance
|
293
|
+
""
|
294
|
+
end
|
295
|
+
|
296
|
+
"attr_#{kind} #{receiver}#{attr.name}#{var}: #{attr.type}"
|
289
297
|
end
|
290
298
|
|
291
299
|
def preserve_empty_line(prev, decl)
|
data/schema/members.json
CHANGED
@@ -165,6 +165,10 @@
|
|
165
165
|
"name": {
|
166
166
|
"type": "string"
|
167
167
|
},
|
168
|
+
"kind": {
|
169
|
+
"type": "string",
|
170
|
+
"enum": ["instance", "singleton"]
|
171
|
+
},
|
168
172
|
"type": {
|
169
173
|
"$ref": "types.json"
|
170
174
|
},
|
@@ -194,7 +198,7 @@
|
|
194
198
|
"$ref": "location.json"
|
195
199
|
}
|
196
200
|
},
|
197
|
-
"required": ["member", "name", "ivar_name", "type", "annotations", "comment", "location"]
|
201
|
+
"required": ["member", "name", "ivar_name", "type", "annotations", "kind", "comment", "location"]
|
198
202
|
},
|
199
203
|
"visibility": {
|
200
204
|
"title": "Visibility specifier",
|
data/sig/definition.rbs
CHANGED
@@ -21,13 +21,13 @@ module RBS
|
|
21
21
|
attr_reader defined_in: TypeName
|
22
22
|
attr_reader implemented_in: TypeName?
|
23
23
|
|
24
|
-
def initialize: (type: MethodType, member: method_member, defined_in: TypeName
|
24
|
+
def initialize: (type: MethodType, member: method_member, defined_in: TypeName, implemented_in: TypeName?) -> void
|
25
25
|
|
26
26
|
def comment: () -> AST::Comment?
|
27
27
|
|
28
28
|
def annotations: () -> Array[AST::Annotation]
|
29
29
|
|
30
|
-
def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName
|
30
|
+
def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName, ?implemented_in: TypeName?) -> TypeDef
|
31
31
|
|
32
32
|
def overload?: () -> bool
|
33
33
|
end
|
@@ -42,8 +42,13 @@ module RBS
|
|
42
42
|
attr_reader comments: Array[AST::Comment]
|
43
43
|
attr_reader annotations: Array[AST::Annotation]
|
44
44
|
attr_reader members: Array[method_member]
|
45
|
+
attr_reader alias_of: Method?
|
45
46
|
|
46
|
-
def initialize: (super_method: Method?,
|
47
|
+
def initialize: (super_method: Method?,
|
48
|
+
defs: Array[TypeDef],
|
49
|
+
accessibility: accessibility,
|
50
|
+
alias_of: Method?,
|
51
|
+
?annotations: Array[AST::Annotation]) -> void
|
47
52
|
|
48
53
|
def public?: () -> bool
|
49
54
|
|
data/sig/definition_builder.rbs
CHANGED
@@ -62,7 +62,7 @@ module RBS
|
|
62
62
|
def ensure_namespace!: (Namespace, location: Location?) -> void
|
63
63
|
|
64
64
|
def build_singleton: (TypeName) -> Definition
|
65
|
-
|
65
|
+
|
66
66
|
def build_instance: (TypeName) -> Definition
|
67
67
|
|
68
68
|
def build_interface: (TypeName) -> Definition
|
@@ -71,11 +71,12 @@ module RBS
|
|
71
71
|
|
72
72
|
def build_one_singleton: (TypeName) -> Definition
|
73
73
|
|
74
|
+
type ancestors = Definition::InstanceAncestors | Definition::SingletonAncestors | nil
|
74
75
|
def merge_definitions: (TypeName,
|
75
76
|
Array[[Definition::Ancestor::t, Definition]],
|
76
77
|
entry: Environment::ModuleEntry | Environment::ClassEntry,
|
77
78
|
self_type: Definition::self_type,
|
78
|
-
ancestors:
|
79
|
+
ancestors: ancestors) -> Definition
|
79
80
|
|
80
81
|
type method_kind = :instance | :singleton
|
81
82
|
def merge_method: (TypeName, Hash[Symbol, Definition::Method], Symbol, Definition::Method, Substitution, kind: method_kind) -> void
|
@@ -92,5 +93,8 @@ module RBS
|
|
92
93
|
def validate_parameter_variance: (decl: AST::Declarations::Class | AST::Declarations::Module | AST::Declarations::Interface, methods: Hash[Symbol, Definition::Method]) -> void
|
93
94
|
|
94
95
|
def expand_alias: (TypeName) -> Types::t
|
96
|
+
|
97
|
+
type attributes = AST::Members::AttrReader | AST::Members::AttrWriter | AST::Members::AttrAccessor
|
98
|
+
def build_attribute: (type_name: TypeName, definition: Definition, member: attributes, accessibility: Definition::accessibility) -> void
|
95
99
|
end
|
96
100
|
end
|
data/sig/members.rbs
CHANGED
@@ -91,14 +91,17 @@ module RBS
|
|
91
91
|
end
|
92
92
|
|
93
93
|
module Attribute
|
94
|
+
type kind = :instance | :singleton
|
95
|
+
|
94
96
|
attr_reader name: Symbol
|
95
97
|
attr_reader type: Types::t
|
98
|
+
attr_reader kind: kind
|
96
99
|
attr_reader ivar_name: Symbol | false | nil
|
97
100
|
attr_reader annotations: Array[Annotation]
|
98
101
|
attr_reader location: Location?
|
99
102
|
attr_reader comment: Comment?
|
100
103
|
|
101
|
-
def initialize: (name: Symbol, type: Types::t, ivar_name: Symbol | false | nil, annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
104
|
+
def initialize: (name: Symbol, type: Types::t, ivar_name: Symbol | false | nil, kind: kind, annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
102
105
|
|
103
106
|
include _HashEqual
|
104
107
|
end
|
data/sig/method_types.rbs
CHANGED
@@ -1,24 +1,11 @@
|
|
1
1
|
module RBS
|
2
2
|
class MethodType
|
3
|
-
class Block
|
4
|
-
attr_reader type: Types::Function
|
5
|
-
attr_reader required: bool
|
6
|
-
|
7
|
-
def initialize: (type: Types::Function, required: boolish) -> void
|
8
|
-
|
9
|
-
def ==: (untyped other) -> bool
|
10
|
-
|
11
|
-
def to_json: (*untyped) -> String
|
12
|
-
|
13
|
-
def sub: (Substitution) -> Block
|
14
|
-
end
|
15
|
-
|
16
3
|
attr_reader type_params: Array[Symbol]
|
17
4
|
attr_reader type: Types::Function
|
18
|
-
attr_reader block: Block?
|
5
|
+
attr_reader block: Types::Block?
|
19
6
|
attr_reader location: Location?
|
20
7
|
|
21
|
-
def initialize: (type_params: Array[Symbol], type: Types::Function, block: Block?, location: Location?) -> void
|
8
|
+
def initialize: (type_params: Array[Symbol], type: Types::Function, block: Types::Block?, location: Location?) -> void
|
22
9
|
|
23
10
|
def ==: (untyped other) -> bool
|
24
11
|
|
@@ -26,7 +13,7 @@ module RBS
|
|
26
13
|
|
27
14
|
def sub: (Substitution) -> MethodType
|
28
15
|
|
29
|
-
def update: (?type_params: Array[Symbol], ?type: Types::Function, ?block: Block?, ?location: Location?) -> MethodType
|
16
|
+
def update: (?type_params: Array[Symbol], ?type: Types::Function, ?block: Types::Block?, ?location: Location?) -> MethodType
|
30
17
|
|
31
18
|
def free_variables: (?Set[Symbol] set) -> Set[Symbol]
|
32
19
|
|