rbs 0.18.0 → 1.0.0.pre
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/CHANGELOG.md +31 -0
- data/Rakefile +4 -0
- data/core/builtin.rbs +4 -0
- data/core/file.rbs +0 -4
- data/core/hash.rbs +1 -3
- data/core/io.rbs +159 -6
- data/core/kernel.rbs +1 -1
- data/core/time.rbs +0 -12
- data/goodcheck.yml +20 -0
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -2
- data/lib/rbs/ast/members.rb +10 -4
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +544 -989
- data/lib/rbs/definition_builder/ancestor_builder.rb +476 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +5 -1
- data/lib/rbs/environment_loader.rb +1 -1
- data/lib/rbs/environment_walker.rb +16 -10
- data/lib/rbs/errors.rb +71 -66
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +1000 -894
- data/lib/rbs/parser.y +108 -57
- data/lib/rbs/prototype/rb.rb +14 -3
- data/lib/rbs/prototype/rbi.rb +6 -6
- data/lib/rbs/prototype/runtime.rb +53 -33
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +24 -7
- data/lib/rbs/types.rb +63 -6
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +9 -1
- data/schema/members.json +5 -1
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +3 -0
- data/sig/errors.rbs +20 -0
- data/sig/members.rbs +4 -1
- data/sig/method_types.rbs +3 -16
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +17 -1
- data/sig/validator.rbs +12 -0
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/tsort/0/tsort.rbs +8 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +13 -14
- metadata +14 -5
@@ -0,0 +1,217 @@
|
|
1
|
+
module RBS
|
2
|
+
class DefinitionBuilder
|
3
|
+
class MethodBuilder
|
4
|
+
class Methods
|
5
|
+
Definition = Struct.new(:name, :type, :originals, :overloads, :accessibilities, keyword_init: true) do
|
6
|
+
def original
|
7
|
+
originals[0]
|
8
|
+
end
|
9
|
+
|
10
|
+
def accessibility
|
11
|
+
accessibilities[0]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.empty(name:, type:)
|
15
|
+
new(type: type, name: name, originals: [], overloads: [], accessibilities: [])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :type
|
20
|
+
attr_reader :methods
|
21
|
+
|
22
|
+
def initialize(type:)
|
23
|
+
@type = type
|
24
|
+
@methods = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate!
|
28
|
+
methods.each_value do |defn|
|
29
|
+
if defn.originals.size > 1
|
30
|
+
raise DuplicatedMethodDefinitionError.new(
|
31
|
+
type: type,
|
32
|
+
method_name: defn.name,
|
33
|
+
members: defn.originals
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def each
|
42
|
+
if block_given?
|
43
|
+
Sorter.new(methods).each_strongly_connected_component do |scc|
|
44
|
+
if scc.size > 1
|
45
|
+
raise RecursiveAliasDefinitionError.new(type: type, defs: scc)
|
46
|
+
end
|
47
|
+
|
48
|
+
yield scc[0]
|
49
|
+
end
|
50
|
+
else
|
51
|
+
enum_for :each
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Sorter
|
56
|
+
include TSort
|
57
|
+
|
58
|
+
attr_reader :methods
|
59
|
+
|
60
|
+
def initialize(methods)
|
61
|
+
@methods = methods
|
62
|
+
end
|
63
|
+
|
64
|
+
def tsort_each_node(&block)
|
65
|
+
methods.each_value(&block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def tsort_each_child(defn)
|
69
|
+
if (member = defn.original).is_a?(AST::Members::Alias)
|
70
|
+
if old = methods[member.old_name]
|
71
|
+
yield old
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :env
|
79
|
+
attr_reader :instance_methods
|
80
|
+
attr_reader :singleton_methods
|
81
|
+
attr_reader :interface_methods
|
82
|
+
|
83
|
+
def initialize(env:)
|
84
|
+
@env = env
|
85
|
+
|
86
|
+
@instance_methods = {}
|
87
|
+
@singleton_methods = {}
|
88
|
+
@interface_methods = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def build_instance(type_name)
|
92
|
+
instance_methods[type_name] ||=
|
93
|
+
begin
|
94
|
+
entry = env.class_decls[type_name]
|
95
|
+
args = Types::Variable.build(entry.type_params.each.map(&:name))
|
96
|
+
type = Types::ClassInstance.new(name: type_name, args: args, location: nil)
|
97
|
+
Methods.new(type: type).tap do |methods|
|
98
|
+
entry.decls.each do |d|
|
99
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
100
|
+
case member
|
101
|
+
when AST::Members::MethodDefinition
|
102
|
+
if member.instance?
|
103
|
+
build_method(methods, type, member: member, accessibility: accessibility)
|
104
|
+
end
|
105
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
106
|
+
if member.kind == :instance
|
107
|
+
build_attribute(methods, type, member: member, accessibility: accessibility)
|
108
|
+
end
|
109
|
+
when AST::Members::Alias
|
110
|
+
if member.kind == :instance
|
111
|
+
build_alias(methods, type, member: member, accessibility: accessibility)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end.validate!
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def build_singleton(type_name)
|
121
|
+
singleton_methods[type_name] ||=
|
122
|
+
begin
|
123
|
+
entry = env.class_decls[type_name]
|
124
|
+
type = Types::ClassSingleton.new(name: type_name, location: nil)
|
125
|
+
|
126
|
+
Methods.new(type: type).tap do |methods|
|
127
|
+
entry.decls.each do |d|
|
128
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
129
|
+
case member
|
130
|
+
when AST::Members::MethodDefinition
|
131
|
+
if member.singleton?
|
132
|
+
build_method(methods, type, member: member, accessibility: accessibility)
|
133
|
+
end
|
134
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
135
|
+
if member.kind == :singleton
|
136
|
+
build_attribute(methods, type, member: member, accessibility: accessibility)
|
137
|
+
end
|
138
|
+
when AST::Members::Alias
|
139
|
+
if member.kind == :singleton
|
140
|
+
build_alias(methods, type, member: member, accessibility: accessibility)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end.validate!
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def build_interface(type_name)
|
150
|
+
interface_methods[type_name] ||=
|
151
|
+
begin
|
152
|
+
entry = env.interface_decls[type_name]
|
153
|
+
args = Types::Variable.build(entry.decl.type_params.each.map(&:name))
|
154
|
+
type = Types::Interface.new(name: type_name, args: args, location: nil)
|
155
|
+
|
156
|
+
Methods.new(type: type).tap do |methods|
|
157
|
+
entry.decl.members.each do |member|
|
158
|
+
case member
|
159
|
+
when AST::Members::MethodDefinition
|
160
|
+
build_method(methods, type, member: member, accessibility: :public)
|
161
|
+
when AST::Members::Alias
|
162
|
+
build_alias(methods, type, member: member, accessibility: :public)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end.validate!
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def build_alias(methods, type, member:, accessibility:)
|
170
|
+
defn = methods.methods[member.new_name] ||= Methods::Definition.empty(type: type, name: member.new_name)
|
171
|
+
|
172
|
+
defn.originals << member
|
173
|
+
defn.accessibilities << accessibility
|
174
|
+
end
|
175
|
+
|
176
|
+
def build_attribute(methods, type, member:, accessibility:)
|
177
|
+
if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
|
178
|
+
defn = methods.methods[member.name] ||= Methods::Definition.empty(type: type, name: member.name)
|
179
|
+
|
180
|
+
defn.accessibilities << accessibility
|
181
|
+
defn.originals << member
|
182
|
+
end
|
183
|
+
|
184
|
+
if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
|
185
|
+
defn = methods.methods[:"#{member.name}="] ||= Methods::Definition.empty(type: type, name: :"#{member.name}=")
|
186
|
+
|
187
|
+
defn.accessibilities << accessibility
|
188
|
+
defn.originals << member
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def build_method(methods, type, member:, accessibility:)
|
193
|
+
defn = methods.methods[member.name] ||= Methods::Definition.empty(type: type, name: member.name)
|
194
|
+
|
195
|
+
if member.overload?
|
196
|
+
defn.overloads << member
|
197
|
+
else
|
198
|
+
defn.accessibilities << accessibility
|
199
|
+
defn.originals << member
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def each_member_with_accessibility(members, accessibility: :public)
|
204
|
+
members.each do |member|
|
205
|
+
case member
|
206
|
+
when AST::Members::Public
|
207
|
+
accessibility = :public
|
208
|
+
when AST::Members::Private
|
209
|
+
accessibility = :private
|
210
|
+
else
|
211
|
+
yield member, accessibility
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/lib/rbs/environment.rb
CHANGED
@@ -244,7 +244,8 @@ module RBS
|
|
244
244
|
super_class: decl.super_class&.yield_self do |super_class|
|
245
245
|
AST::Declarations::Class::Super.new(
|
246
246
|
name: absolute_type_name(resolver, super_class.name, context: context),
|
247
|
-
args: super_class.args.map {|type| absolute_type(resolver, type, context: context) }
|
247
|
+
args: super_class.args.map {|type| absolute_type(resolver, type, context: context) },
|
248
|
+
location: super_class.location
|
248
249
|
)
|
249
250
|
end,
|
250
251
|
members: decl.members.map do |member|
|
@@ -349,6 +350,7 @@ module RBS
|
|
349
350
|
AST::Members::AttrAccessor.new(
|
350
351
|
name: member.name,
|
351
352
|
type: absolute_type(resolver, member.type, context: context),
|
353
|
+
kind: member.kind,
|
352
354
|
annotations: member.annotations,
|
353
355
|
comment: member.comment,
|
354
356
|
location: member.location,
|
@@ -358,6 +360,7 @@ module RBS
|
|
358
360
|
AST::Members::AttrReader.new(
|
359
361
|
name: member.name,
|
360
362
|
type: absolute_type(resolver, member.type, context: context),
|
363
|
+
kind: member.kind,
|
361
364
|
annotations: member.annotations,
|
362
365
|
comment: member.comment,
|
363
366
|
location: member.location,
|
@@ -367,6 +370,7 @@ module RBS
|
|
367
370
|
AST::Members::AttrWriter.new(
|
368
371
|
name: member.name,
|
369
372
|
type: absolute_type(resolver, member.type, context: context),
|
373
|
+
kind: member.kind,
|
370
374
|
annotations: member.annotations,
|
371
375
|
comment: member.comment,
|
372
376
|
location: member.location,
|
@@ -53,11 +53,11 @@ module RBS
|
|
53
53
|
definition = builder.build_interface(name)
|
54
54
|
unless only_ancestors?
|
55
55
|
definition.each_type do |type|
|
56
|
-
|
56
|
+
each_type_node type, &block
|
57
57
|
end
|
58
58
|
end
|
59
59
|
when name.alias?
|
60
|
-
|
60
|
+
each_type_node builder.expand_alias(name), &block
|
61
61
|
else
|
62
62
|
raise "Unexpected TypeNameNode with type_name=#{name}"
|
63
63
|
end
|
@@ -77,7 +77,7 @@ module RBS
|
|
77
77
|
|
78
78
|
unless only_ancestors?
|
79
79
|
ancestor.args.each do |type|
|
80
|
-
|
80
|
+
each_type_node type, &block
|
81
81
|
end
|
82
82
|
end
|
83
83
|
when Definition::Ancestor::Singleton
|
@@ -88,13 +88,19 @@ module RBS
|
|
88
88
|
|
89
89
|
unless only_ancestors?
|
90
90
|
definition.each_type do |type|
|
91
|
-
|
91
|
+
each_type_node type, &block
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
97
|
def each_type_name(type, &block)
|
98
|
+
each_type_node(type) do |node|
|
99
|
+
yield node.type_name
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def each_type_node(type, &block)
|
98
104
|
case type
|
99
105
|
when RBS::Types::Bases::Any
|
100
106
|
when RBS::Types::Bases::Class
|
@@ -111,30 +117,30 @@ module RBS
|
|
111
117
|
when RBS::Types::ClassInstance
|
112
118
|
yield InstanceNode.new(type_name: type.name)
|
113
119
|
type.args.each do |ty|
|
114
|
-
|
120
|
+
each_type_node(ty, &block)
|
115
121
|
end
|
116
122
|
when RBS::Types::Interface
|
117
123
|
yield TypeNameNode.new(type_name: type.name)
|
118
124
|
type.args.each do |ty|
|
119
|
-
|
125
|
+
each_type_node(ty, &block)
|
120
126
|
end
|
121
127
|
when RBS::Types::Alias
|
122
128
|
yield TypeNameNode.new(type_name: type.name)
|
123
129
|
when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Tuple
|
124
130
|
type.types.each do |ty|
|
125
|
-
|
131
|
+
each_type_node ty, &block
|
126
132
|
end
|
127
133
|
when RBS::Types::Optional
|
128
|
-
|
134
|
+
each_type_node type.type, &block
|
129
135
|
when RBS::Types::Literal
|
130
136
|
# nop
|
131
137
|
when RBS::Types::Record
|
132
138
|
type.fields.each_value do |ty|
|
133
|
-
|
139
|
+
each_type_node ty, &block
|
134
140
|
end
|
135
141
|
when RBS::Types::Proc
|
136
142
|
type.each_type do |ty|
|
137
|
-
|
143
|
+
each_type_node ty, &block
|
138
144
|
end
|
139
145
|
else
|
140
146
|
raise "Unexpected type given: #{type}"
|
data/lib/rbs/errors.rb
CHANGED
@@ -68,18 +68,20 @@ module RBS
|
|
68
68
|
attr_reader :location
|
69
69
|
|
70
70
|
def initialize(ancestors:, location:)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
71
|
+
names = ancestors.map do |ancestor|
|
72
|
+
case ancestor
|
73
|
+
when Definition::Ancestor::Singleton
|
74
|
+
"singleton(#{ancestor.name})"
|
75
|
+
when Definition::Ancestor::Instance
|
76
|
+
if ancestor.args.empty?
|
77
|
+
ancestor.name.to_s
|
78
|
+
else
|
79
|
+
"#{ancestor.name}[#{ancestor.args.join(", ")}]"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
super "#{Location.to_string location}: Detected recursive ancestors: #{names.join(" < ")}"
|
83
85
|
end
|
84
86
|
|
85
87
|
def self.check!(self_ancestor, ancestors:, location:)
|
@@ -194,44 +196,54 @@ module RBS
|
|
194
196
|
end
|
195
197
|
|
196
198
|
class DuplicatedMethodDefinitionError < StandardError
|
197
|
-
attr_reader :
|
198
|
-
attr_reader :
|
199
|
+
attr_reader :type
|
200
|
+
attr_reader :method_name
|
201
|
+
attr_reader :members
|
199
202
|
|
200
|
-
def initialize(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
when AST::Declarations::Extension
|
205
|
-
"#{decl.name} (#{decl.extension_name})"
|
206
|
-
end
|
203
|
+
def initialize(type:, method_name:, members:)
|
204
|
+
@type = type
|
205
|
+
@method_name = method_name
|
206
|
+
@members = members
|
207
207
|
|
208
|
-
super "#{Location.to_string location}: #{
|
208
|
+
super "#{Location.to_string location}: #{qualified_method_name} has duplicated definitions"
|
209
209
|
end
|
210
210
|
|
211
|
-
def
|
212
|
-
|
213
|
-
|
211
|
+
def qualified_method_name
|
212
|
+
case type
|
213
|
+
when Types::ClassSingleton
|
214
|
+
"#{type.name}.#{method_name}"
|
215
|
+
else
|
216
|
+
"#{type.name}##{method_name}"
|
214
217
|
end
|
215
218
|
end
|
219
|
+
|
220
|
+
def location
|
221
|
+
members[0].location
|
222
|
+
end
|
216
223
|
end
|
217
224
|
|
218
|
-
class
|
225
|
+
class DuplicatedInterfaceMethodDefinitionError < StandardError
|
219
226
|
include MethodNameHelper
|
220
227
|
|
221
|
-
attr_reader :
|
228
|
+
attr_reader :type
|
222
229
|
attr_reader :method_name
|
223
|
-
attr_reader :
|
224
|
-
attr_reader :mixin_member
|
225
|
-
attr_reader :entries
|
230
|
+
attr_reader :member
|
226
231
|
|
227
|
-
def initialize(
|
228
|
-
@
|
232
|
+
def initialize(type:, method_name:, member:)
|
233
|
+
@type = type
|
229
234
|
@method_name = method_name
|
230
|
-
@
|
231
|
-
@mixin_member = mixin_member
|
232
|
-
@entries = entries
|
235
|
+
@member = member
|
233
236
|
|
234
|
-
super "#{
|
237
|
+
super "#{member.location}: Duplicated method definition: #{qualified_method_name}"
|
238
|
+
end
|
239
|
+
|
240
|
+
def qualified_method_name
|
241
|
+
case type
|
242
|
+
when Types::ClassSingleton
|
243
|
+
"#{type.name}.#{method_name}"
|
244
|
+
else
|
245
|
+
"#{type.name}##{method_name}"
|
246
|
+
end
|
235
247
|
end
|
236
248
|
end
|
237
249
|
|
@@ -247,12 +259,6 @@ module RBS
|
|
247
259
|
|
248
260
|
super "#{Location.to_string location}: Unknown method alias name: #{original_name} => #{aliased_name}"
|
249
261
|
end
|
250
|
-
|
251
|
-
def self.check!(methods:, original_name:, aliased_name:, location:)
|
252
|
-
unless methods.key?(original_name)
|
253
|
-
raise new(original_name: original_name, aliased_name: aliased_name, location: location)
|
254
|
-
end
|
255
|
-
end
|
256
262
|
end
|
257
263
|
|
258
264
|
class SuperclassMismatchError < StandardError
|
@@ -336,33 +342,32 @@ module RBS
|
|
336
342
|
end
|
337
343
|
|
338
344
|
class InvalidVarianceAnnotationError < StandardError
|
339
|
-
|
340
|
-
|
341
|
-
|
345
|
+
attr_reader :type_name
|
346
|
+
attr_reader :param
|
347
|
+
attr_reader :location
|
342
348
|
|
343
|
-
|
344
|
-
|
349
|
+
def initialize(type_name:, param:, location:)
|
350
|
+
@type_name = type_name
|
351
|
+
@param = param
|
352
|
+
@location = location
|
345
353
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
errors.each do |error|
|
355
|
-
case error
|
356
|
-
when MethodTypeError
|
357
|
-
message << " MethodTypeError (#{error.param.name}): on `#{error.method_name}` #{error.method_type.to_s} (#{error.method_type.location&.start_line})"
|
358
|
-
when InheritanceError
|
359
|
-
message << " InheritanceError: #{error.super_class}"
|
360
|
-
when MixinError
|
361
|
-
message << " MixinError: #{error.include_member.name} (#{error.include_member.location&.start_line})"
|
362
|
-
end
|
363
|
-
end
|
354
|
+
super "#{Location.to_string location}: Type parameter variance error: #{param.name} is #{param.variance} but used as incompatible variance"
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class RecursiveAliasDefinitionError < StandardError
|
359
|
+
attr_reader :type
|
360
|
+
attr_reader :defs
|
364
361
|
|
365
|
-
|
362
|
+
def initialize(type:, defs:)
|
363
|
+
@type = type
|
364
|
+
@defs = defs
|
365
|
+
|
366
|
+
super "#{Location.to_string location}: Recursive aliases in #{type}: #{defs.map(&:name).join(", ")}"
|
367
|
+
end
|
368
|
+
|
369
|
+
def location
|
370
|
+
defs[0].original.location
|
366
371
|
end
|
367
372
|
end
|
368
373
|
end
|