rbs 0.18.0 → 1.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/Rakefile +4 -0
  4. data/core/builtin.rbs +4 -0
  5. data/core/file.rbs +0 -4
  6. data/core/hash.rbs +1 -3
  7. data/core/io.rbs +159 -6
  8. data/core/kernel.rbs +1 -1
  9. data/core/time.rbs +0 -12
  10. data/goodcheck.yml +20 -0
  11. data/lib/rbs.rb +2 -0
  12. data/lib/rbs/ast/declarations.rb +7 -2
  13. data/lib/rbs/ast/members.rb +10 -4
  14. data/lib/rbs/cli.rb +10 -10
  15. data/lib/rbs/definition.rb +70 -3
  16. data/lib/rbs/definition_builder.rb +544 -989
  17. data/lib/rbs/definition_builder/ancestor_builder.rb +476 -0
  18. data/lib/rbs/definition_builder/method_builder.rb +217 -0
  19. data/lib/rbs/environment.rb +5 -1
  20. data/lib/rbs/environment_loader.rb +1 -1
  21. data/lib/rbs/environment_walker.rb +16 -10
  22. data/lib/rbs/errors.rb +71 -66
  23. data/lib/rbs/method_type.rb +1 -31
  24. data/lib/rbs/parser.rb +1000 -894
  25. data/lib/rbs/parser.y +108 -57
  26. data/lib/rbs/prototype/rb.rb +14 -3
  27. data/lib/rbs/prototype/rbi.rb +6 -6
  28. data/lib/rbs/prototype/runtime.rb +53 -33
  29. data/lib/rbs/substitution.rb +4 -0
  30. data/lib/rbs/test.rb +3 -1
  31. data/lib/rbs/test/hook.rb +24 -7
  32. data/lib/rbs/types.rb +63 -6
  33. data/lib/rbs/validator.rb +4 -2
  34. data/lib/rbs/variance_calculator.rb +5 -1
  35. data/lib/rbs/version.rb +1 -1
  36. data/lib/rbs/writer.rb +9 -1
  37. data/schema/members.json +5 -1
  38. data/sig/definition.rbs +6 -1
  39. data/sig/definition_builder.rbs +3 -0
  40. data/sig/errors.rbs +20 -0
  41. data/sig/members.rbs +4 -1
  42. data/sig/method_types.rbs +3 -16
  43. data/sig/type_name_resolver.rbs +4 -2
  44. data/sig/types.rbs +17 -1
  45. data/sig/validator.rbs +12 -0
  46. data/stdlib/dbm/0/dbm.rbs +0 -2
  47. data/stdlib/logger/0/log_device.rbs +1 -2
  48. data/stdlib/monitor/0/monitor.rbs +119 -0
  49. data/stdlib/time/0/time.rbs +327 -0
  50. data/stdlib/tsort/0/tsort.rbs +8 -0
  51. data/stdlib/uri/0/common.rbs +401 -0
  52. data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
  53. data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
  54. data/steep/Gemfile.lock +13 -14
  55. 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
@@ -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,
@@ -102,7 +102,7 @@ module RBS
102
102
  end
103
103
  end
104
104
 
105
- path.each_child do |child|
105
+ path.children.sort.each do |child|
106
106
  each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
107
107
  end
108
108
  end
@@ -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
- each_type_name type, &block
56
+ each_type_node type, &block
57
57
  end
58
58
  end
59
59
  when name.alias?
60
- each_type_name builder.expand_alias(name), &block
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
- each_type_name type, &block
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
- each_type_name type, &block
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
- each_type_name(ty, &block)
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
- each_type_name(ty, &block)
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
- each_type_name ty, &block
131
+ each_type_node ty, &block
126
132
  end
127
133
  when RBS::Types::Optional
128
- each_type_name type.type, &block
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
- each_type_name ty, &block
139
+ each_type_node ty, &block
134
140
  end
135
141
  when RBS::Types::Proc
136
142
  type.each_type do |ty|
137
- each_type_name ty, &block
143
+ each_type_node ty, &block
138
144
  end
139
145
  else
140
146
  raise "Unexpected type given: #{type}"
@@ -68,18 +68,20 @@ module RBS
68
68
  attr_reader :location
69
69
 
70
70
  def initialize(ancestors:, location:)
71
- last = case last = ancestors.last
72
- when Definition::Ancestor::Singleton
73
- "singleton(#{last.name})"
74
- when Definition::Ancestor::Instance
75
- if last.args.empty?
76
- last.name.to_s
77
- else
78
- "#{last.name}[#{last.args.join(", ")}]"
79
- end
80
- end
81
-
82
- super "#{Location.to_string location}: Detected recursive ancestors: #{last}"
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 :decl
198
- attr_reader :location
199
+ attr_reader :type
200
+ attr_reader :method_name
201
+ attr_reader :members
199
202
 
200
- def initialize(decl:, name:, location:)
201
- decl_str = case decl
202
- when AST::Declarations::Interface, AST::Declarations::Class, AST::Declarations::Module
203
- decl.name.to_s
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}: #{decl_str} has duplicated method definition: #{name}"
208
+ super "#{Location.to_string location}: #{qualified_method_name} has duplicated definitions"
209
209
  end
210
210
 
211
- def self.check!(decl:, methods:, name:, location:)
212
- if methods.key?(name)
213
- raise new(decl: decl, name: name, location: location)
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 MethodDefinitionConflictWithInterfaceMixinError < StandardError
225
+ class DuplicatedInterfaceMethodDefinitionError < StandardError
219
226
  include MethodNameHelper
220
227
 
221
- attr_reader :type_name
228
+ attr_reader :type
222
229
  attr_reader :method_name
223
- attr_reader :kind
224
- attr_reader :mixin_member
225
- attr_reader :entries
230
+ attr_reader :member
226
231
 
227
- def initialize(type_name:, method_name:, kind:, mixin_member:, entries:)
228
- @type_name = type_name
232
+ def initialize(type:, method_name:, member:)
233
+ @type = type
229
234
  @method_name = method_name
230
- @kind = kind
231
- @mixin_member = mixin_member
232
- @entries = entries
235
+ @member = member
233
236
 
234
- super "#{entries[0].decl.location}: Duplicated method with interface mixin: #{method_name_string}"
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
- MethodTypeError = Struct.new(:method_name, :method_type, :param, keyword_init: true)
340
- InheritanceError = Struct.new(:super_class, :param, keyword_init: true)
341
- MixinError = Struct.new(:include_member, :param, keyword_init: true)
345
+ attr_reader :type_name
346
+ attr_reader :param
347
+ attr_reader :location
342
348
 
343
- attr_reader :decl
344
- attr_reader :errors
349
+ def initialize(type_name:, param:, location:)
350
+ @type_name = type_name
351
+ @param = param
352
+ @location = location
345
353
 
346
- def initialize(decl:, errors:)
347
- @decl = decl
348
- @errors = errors
349
-
350
- message = [
351
- "#{Location.to_string decl.location}: Invalid variance annotation: #{decl.name}"
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
- super message.join("\n")
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