rbs 0.4.0 → 0.5.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 +7 -0
- data/Gemfile +12 -0
- data/README.md +86 -47
- data/Rakefile +54 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +62 -7
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +299 -121
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +50 -44
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +647 -603
- data/lib/rbs/environment.rb +338 -209
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +141 -3
- data/lib/rbs/parser.y +14 -9
- data/lib/rbs/prototype/rb.rb +100 -112
- data/lib/rbs/prototype/rbi.rb +4 -2
- data/lib/rbs/prototype/runtime.rb +10 -6
- data/lib/rbs/substitution.rb +8 -1
- data/lib/rbs/test/hook.rb +2 -2
- data/lib/rbs/test/setup.rb +3 -1
- data/lib/rbs/test/test_helper.rb +2 -5
- data/lib/rbs/test/type_check.rb +1 -2
- 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 +125 -89
- data/rbs.gemspec +0 -10
- data/schema/decls.json +15 -0
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +1 -1
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/thread.rbs +2 -2
- data/stdlib/csv/csv.rbs +4 -6
- data/stdlib/fiber/fiber.rbs +1 -1
- data/stdlib/json/json.rbs +1 -1
- 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 +8 -129
data/lib/rbs/constant.rb
CHANGED
@@ -4,23 +4,23 @@ module RBS
|
|
4
4
|
attr_reader :type
|
5
5
|
attr_reader :declaration
|
6
6
|
|
7
|
-
def initialize(name:, type:,
|
7
|
+
def initialize(name:, type:, entry:)
|
8
8
|
@name = name
|
9
9
|
@type = type
|
10
|
-
@
|
10
|
+
@entry = entry
|
11
11
|
end
|
12
12
|
|
13
13
|
def ==(other)
|
14
14
|
other.is_a?(Constant) &&
|
15
15
|
other.name == name &&
|
16
16
|
other.type == type &&
|
17
|
-
other.
|
17
|
+
other.entry == entry
|
18
18
|
end
|
19
19
|
|
20
20
|
alias eql? ==
|
21
21
|
|
22
22
|
def hash
|
23
|
-
self.class.hash ^ name.hash ^ type.hash ^
|
23
|
+
self.class.hash ^ name.hash ^ type.hash ^ entry.hash
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/rbs/constant_table.rb
CHANGED
@@ -7,21 +7,34 @@ module RBS
|
|
7
7
|
definition_builder.env
|
8
8
|
end
|
9
9
|
|
10
|
+
def resolver
|
11
|
+
@resolver ||= TypeNameResolver.from_env(env)
|
12
|
+
end
|
13
|
+
|
10
14
|
def initialize(builder:)
|
11
15
|
@definition_builder = builder
|
12
16
|
@constant_scopes_cache = {}
|
13
17
|
end
|
14
18
|
|
19
|
+
def absolute_type(type, context:)
|
20
|
+
type.map_type_name do |type_name, location|
|
21
|
+
absolute_type_name(type_name, context: context, location: location)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def absolute_type_name(type_name, context:, location:)
|
26
|
+
resolver.resolve(type_name, context: context) or
|
27
|
+
raise NoTypeFoundError.new(type_name: type_name, location: location)
|
28
|
+
end
|
29
|
+
|
15
30
|
def name_to_constant(name)
|
16
31
|
case
|
17
|
-
when env.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
when env.class?(name)
|
22
|
-
decl = env.name_to_decl[name]
|
32
|
+
when entry = env.constant_decls[name]
|
33
|
+
type = absolute_type(entry.decl.type, context: entry.context)
|
34
|
+
Constant.new(name: name, type: type, entry: entry)
|
35
|
+
when entry = env.class_decls[name]
|
23
36
|
type = Types::ClassSingleton.new(name: name, location: nil)
|
24
|
-
Constant.new(name: name, type: type,
|
37
|
+
Constant.new(name: name, type: type, entry: entry)
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
@@ -88,14 +101,18 @@ module RBS
|
|
88
101
|
end
|
89
102
|
|
90
103
|
def constant_scopes_module(name, scopes:)
|
91
|
-
|
104
|
+
entry = env.class_decls[name]
|
92
105
|
namespace = name.to_namespace
|
93
106
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
107
|
+
entry.decls.each do |d|
|
108
|
+
d.decl.members.each do |member|
|
109
|
+
case member
|
110
|
+
when AST::Members::Include
|
111
|
+
if member.name.class?
|
112
|
+
constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location),
|
113
|
+
scopes: scopes
|
114
|
+
end
|
115
|
+
end
|
99
116
|
end
|
100
117
|
end
|
101
118
|
|
@@ -103,53 +120,42 @@ module RBS
|
|
103
120
|
end
|
104
121
|
|
105
122
|
def constant_scopes0(name, scopes: [])
|
106
|
-
|
123
|
+
entry = env.class_decls[name]
|
107
124
|
namespace = name.to_namespace
|
108
125
|
|
109
|
-
case
|
110
|
-
when
|
111
|
-
constant_scopes0 BuiltinNames::Module.name, scopes: scopes
|
112
|
-
constant_scopes_module name, scopes: scopes
|
113
|
-
|
114
|
-
when AST::Declarations::Class
|
126
|
+
case entry
|
127
|
+
when Environment::ClassEntry
|
115
128
|
unless name == BuiltinNames::BasicObject.name
|
116
|
-
super_name = decl.super_class&.yield_self
|
117
|
-
absolute_type_name(super_class.name,
|
118
|
-
|
129
|
+
super_name = entry.primary.decl.super_class&.yield_self do |super_class|
|
130
|
+
absolute_type_name(super_class.name, context: entry.primary.context, location: entry.primary.decl.location)
|
131
|
+
end || BuiltinNames::Object.name
|
119
132
|
|
120
133
|
constant_scopes0 super_name, scopes: scopes
|
121
134
|
end
|
122
135
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
136
|
+
entry.decls.each do |d|
|
137
|
+
d.decl.members.each do |member|
|
138
|
+
case member
|
139
|
+
when AST::Members::Include
|
140
|
+
if member.name.class?
|
141
|
+
constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location),
|
142
|
+
scopes: scopes
|
143
|
+
end
|
144
|
+
end
|
128
145
|
end
|
129
146
|
end
|
130
147
|
|
131
148
|
scopes.unshift namespace
|
149
|
+
|
150
|
+
when Environment::ModuleEntry
|
151
|
+
constant_scopes0 BuiltinNames::Module.name, scopes: scopes
|
152
|
+
constant_scopes_module name, scopes: scopes
|
153
|
+
|
132
154
|
else
|
133
155
|
raise "Unexpected declaration: #{name} (#{decl.class})"
|
134
156
|
end
|
135
157
|
|
136
|
-
env.each_extension(name).sort_by {|e| e.extension_name.to_s }.each do |extension|
|
137
|
-
extension.members.each do |member|
|
138
|
-
case member
|
139
|
-
when AST::Members::Include
|
140
|
-
constant_scopes_module absolute_type_name(member.name, namespace: namespace),
|
141
|
-
scopes: []
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
158
|
scopes
|
147
159
|
end
|
148
|
-
|
149
|
-
def absolute_type_name(name, namespace:)
|
150
|
-
env.absolute_type_name(name, namespace: namespace) do
|
151
|
-
raise
|
152
|
-
end
|
153
|
-
end
|
154
160
|
end
|
155
161
|
end
|
data/lib/rbs/definition.rb
CHANGED
@@ -10,27 +10,76 @@ module RBS
|
|
10
10
|
@type = type
|
11
11
|
@declared_in = declared_in
|
12
12
|
end
|
13
|
+
|
14
|
+
def sub(s)
|
15
|
+
self.class.new(
|
16
|
+
parent_variable: parent_variable,
|
17
|
+
type: type.sub(s),
|
18
|
+
declared_in: declared_in
|
19
|
+
)
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
15
23
|
class Method
|
24
|
+
class TypeDef
|
25
|
+
attr_reader :type
|
26
|
+
attr_reader :member
|
27
|
+
attr_reader :defined_in
|
28
|
+
attr_reader :implemented_in
|
29
|
+
|
30
|
+
def initialize(type:, member:, defined_in:, implemented_in:)
|
31
|
+
@type = type
|
32
|
+
@member = member
|
33
|
+
@defined_in = defined_in
|
34
|
+
@implemented_in = implemented_in
|
35
|
+
end
|
36
|
+
|
37
|
+
def comment
|
38
|
+
member.comment
|
39
|
+
end
|
40
|
+
|
41
|
+
def annotations
|
42
|
+
member.annotations
|
43
|
+
end
|
44
|
+
|
45
|
+
def update(type: self.type, member: self.member, defined_in: self.defined_in, implemented_in: self.implemented_in)
|
46
|
+
TypeDef.new(type: type, member: member, defined_in: defined_in, implemented_in: implemented_in)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
16
50
|
attr_reader :super_method
|
17
|
-
attr_reader :
|
18
|
-
attr_reader :defined_in
|
19
|
-
attr_reader :implemented_in
|
51
|
+
attr_reader :defs
|
20
52
|
attr_reader :accessibility
|
21
|
-
attr_reader :attributes
|
22
|
-
attr_reader :annotations
|
23
|
-
attr_reader :comment
|
24
53
|
|
25
|
-
def initialize(super_method:,
|
54
|
+
def initialize(super_method:, defs:, accessibility:)
|
26
55
|
@super_method = super_method
|
27
|
-
@
|
28
|
-
@defined_in = defined_in
|
29
|
-
@implemented_in = implemented_in
|
56
|
+
@defs = defs
|
30
57
|
@accessibility = accessibility
|
31
|
-
|
32
|
-
|
33
|
-
|
58
|
+
end
|
59
|
+
|
60
|
+
def defined_in
|
61
|
+
@defined_in ||= defs.last.defined_in
|
62
|
+
end
|
63
|
+
|
64
|
+
def implemented_in
|
65
|
+
@implemented_in ||= defs.last.implemented_in
|
66
|
+
end
|
67
|
+
|
68
|
+
def method_types
|
69
|
+
@method_types ||= defs.map(&:type)
|
70
|
+
end
|
71
|
+
|
72
|
+
def comments
|
73
|
+
@comments ||= defs.map(&:comment).compact
|
74
|
+
end
|
75
|
+
|
76
|
+
def annotations
|
77
|
+
@annotations ||= defs.flat_map(&:annotations)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @deprecated
|
81
|
+
def attributes
|
82
|
+
[]
|
34
83
|
end
|
35
84
|
|
36
85
|
def public?
|
@@ -44,28 +93,24 @@ module RBS
|
|
44
93
|
def sub(s)
|
45
94
|
self.class.new(
|
46
95
|
super_method: super_method&.sub(s),
|
47
|
-
|
48
|
-
|
49
|
-
implemented_in: implemented_in,
|
50
|
-
accessibility: @accessibility,
|
51
|
-
attributes: attributes,
|
52
|
-
annotations: annotations,
|
53
|
-
comment: comment
|
96
|
+
defs: defs.map {|defn| defn.update(type: defn.type.sub(s)) },
|
97
|
+
accessibility: @accessibility
|
54
98
|
)
|
55
99
|
end
|
56
100
|
|
57
101
|
def map_type(&block)
|
58
102
|
self.class.new(
|
59
103
|
super_method: super_method&.map_type(&block),
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
104
|
+
defs: defs.map {|defn| defn.update(type: defn.type.map_type(&block)) },
|
105
|
+
accessibility: @accessibility
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
def map_method_type(&block)
|
110
|
+
self.class.new(
|
111
|
+
super_method: super_method,
|
112
|
+
defs: defs.map {|defn| defn.update(type: yield(defn.type)) },
|
113
|
+
accessibility: @accessibility
|
69
114
|
)
|
70
115
|
end
|
71
116
|
end
|
@@ -73,78 +118,149 @@ module RBS
|
|
73
118
|
module Ancestor
|
74
119
|
Instance = Struct.new(:name, :args, keyword_init: true)
|
75
120
|
Singleton = Struct.new(:name, keyword_init: true)
|
76
|
-
ExtensionInstance = Struct.new(:name, :extension_name, :args, keyword_init: true)
|
77
|
-
ExtensionSingleton = Struct.new(:name, :extension_name, keyword_init: true)
|
78
121
|
end
|
79
122
|
|
80
|
-
|
123
|
+
class InstanceAncestors
|
124
|
+
attr_reader :type_name
|
125
|
+
attr_reader :params
|
126
|
+
attr_reader :ancestors
|
127
|
+
|
128
|
+
def initialize(type_name:, params:, ancestors:)
|
129
|
+
@type_name = type_name
|
130
|
+
@params = params
|
131
|
+
@ancestors = ancestors
|
132
|
+
end
|
133
|
+
|
134
|
+
def apply(args, location:)
|
135
|
+
InvalidTypeApplicationError.check!(
|
136
|
+
type_name: type_name,
|
137
|
+
args: args,
|
138
|
+
params: params,
|
139
|
+
location: location
|
140
|
+
)
|
141
|
+
|
142
|
+
subst = Substitution.build(params, args)
|
143
|
+
|
144
|
+
ancestors.map do |ancestor|
|
145
|
+
case ancestor
|
146
|
+
when Ancestor::Instance
|
147
|
+
if ancestor.args.empty?
|
148
|
+
ancestor
|
149
|
+
else
|
150
|
+
Ancestor::Instance.new(
|
151
|
+
name: ancestor.name,
|
152
|
+
args: ancestor.args.map {|type| type.sub(subst) }
|
153
|
+
)
|
154
|
+
end
|
155
|
+
when Ancestor::Singleton
|
156
|
+
ancestor
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class SingletonAncestors
|
163
|
+
attr_reader :type_name
|
164
|
+
attr_reader :ancestors
|
165
|
+
|
166
|
+
def initialize(type_name:, ancestors:)
|
167
|
+
@type_name = type_name
|
168
|
+
@ancestors = ancestors
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
attr_reader :type_name
|
173
|
+
attr_reader :entry
|
174
|
+
attr_reader :ancestors
|
81
175
|
attr_reader :self_type
|
82
176
|
attr_reader :methods
|
83
177
|
attr_reader :instance_variables
|
84
178
|
attr_reader :class_variables
|
85
|
-
attr_reader :ancestors
|
86
179
|
|
87
|
-
def initialize(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
180
|
+
def initialize(type_name:, entry:, self_type:, ancestors:)
|
181
|
+
case entry
|
182
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
183
|
+
# ok
|
184
|
+
else
|
185
|
+
unless entry.decl.is_a?(AST::Declarations::Interface)
|
186
|
+
raise "Declaration should be a class, module, or interface: #{type_name}"
|
187
|
+
end
|
93
188
|
end
|
94
189
|
|
95
|
-
unless
|
190
|
+
unless self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)
|
96
191
|
raise "self_type should be the type of declaration: #{self_type}"
|
97
192
|
end
|
98
193
|
|
194
|
+
@type_name = type_name
|
99
195
|
@self_type = self_type
|
100
|
-
@
|
196
|
+
@entry = entry
|
101
197
|
@methods = {}
|
102
198
|
@instance_variables = {}
|
103
199
|
@class_variables = {}
|
104
200
|
@ancestors = ancestors
|
105
201
|
end
|
106
202
|
|
107
|
-
def name
|
108
|
-
declaration.name
|
109
|
-
end
|
110
|
-
|
111
203
|
def class?
|
112
|
-
|
204
|
+
entry.is_a?(Environment::ClassEntry)
|
113
205
|
end
|
114
206
|
|
115
207
|
def module?
|
116
|
-
|
208
|
+
entry.is_a?(Environment::ModuleEntry)
|
209
|
+
end
|
210
|
+
|
211
|
+
def interface?
|
212
|
+
entry.is_a?(Environment::SingleEntry) && entry.decl.is_a?(AST::Declarations::Interface)
|
117
213
|
end
|
118
214
|
|
119
215
|
def class_type?
|
120
|
-
|
216
|
+
self_type.is_a?(Types::ClassSingleton)
|
121
217
|
end
|
122
218
|
|
123
219
|
def instance_type?
|
124
|
-
|
220
|
+
self_type.is_a?(Types::ClassInstance)
|
125
221
|
end
|
126
222
|
|
127
223
|
def interface_type?
|
128
|
-
|
224
|
+
self_type.is_a?(Types::Interface)
|
129
225
|
end
|
130
226
|
|
131
227
|
def type_params
|
132
|
-
|
228
|
+
type_params_decl.each.map(&:name)
|
133
229
|
end
|
134
230
|
|
135
231
|
def type_params_decl
|
136
|
-
case
|
137
|
-
when
|
138
|
-
|
139
|
-
|
140
|
-
|
232
|
+
case entry
|
233
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
234
|
+
entry.type_params
|
235
|
+
when Environment::SingleEntry
|
236
|
+
entry.decl.type_params
|
141
237
|
end
|
142
238
|
end
|
143
239
|
|
240
|
+
def sub(s)
|
241
|
+
definition = self.class.new(type_name: type_name, self_type: self_type.sub(s), ancestors: ancestors, entry: entry)
|
242
|
+
|
243
|
+
definition.methods.merge!(methods.transform_values {|method| method.sub(s) })
|
244
|
+
definition.instance_variables.merge!(instance_variables.transform_values {|v| v.sub(s) })
|
245
|
+
definition.class_variables.merge!(class_variables.transform_values {|v| v.sub(s) })
|
246
|
+
|
247
|
+
definition
|
248
|
+
end
|
249
|
+
|
250
|
+
def map_method_type(&block)
|
251
|
+
definition = self.class.new(type_name: type_name, self_type: self_type, ancestors: ancestors, entry: entry)
|
252
|
+
|
253
|
+
definition.methods.merge!(methods.transform_values {|method| method.map_method_type(&block) })
|
254
|
+
definition.instance_variables.merge!(instance_variables)
|
255
|
+
definition.class_variables.merge!(class_variables)
|
256
|
+
|
257
|
+
definition
|
258
|
+
end
|
259
|
+
|
144
260
|
def each_type(&block)
|
145
261
|
if block_given?
|
146
262
|
methods.each_value do |method|
|
147
|
-
if method.defined_in ==
|
263
|
+
if method.defined_in == type_name
|
148
264
|
method.method_types.each do |method_type|
|
149
265
|
method_type.each_type(&block)
|
150
266
|
end
|
@@ -152,13 +268,13 @@ module RBS
|
|
152
268
|
end
|
153
269
|
|
154
270
|
instance_variables.each_value do |var|
|
155
|
-
if var.declared_in ==
|
271
|
+
if var.declared_in == type_name
|
156
272
|
yield var.type
|
157
273
|
end
|
158
274
|
end
|
159
275
|
|
160
276
|
class_variables.each_value do |var|
|
161
|
-
if var.declared_in ==
|
277
|
+
if var.declared_in == type_name
|
162
278
|
yield var.type
|
163
279
|
end
|
164
280
|
end
|