rbs 0.4.0 → 0.9.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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile +14 -0
  6. data/README.md +86 -47
  7. data/Rakefile +53 -21
  8. data/bin/rbs-prof +9 -0
  9. data/bin/run_in_md.rb +49 -0
  10. data/docs/stdlib.md +0 -2
  11. data/docs/syntax.md +6 -3
  12. data/goodcheck.yml +65 -0
  13. data/lib/rbs.rb +3 -0
  14. data/lib/rbs/ast/comment.rb +6 -0
  15. data/lib/rbs/ast/declarations.rb +106 -13
  16. data/lib/rbs/ast/members.rb +41 -17
  17. data/lib/rbs/cli.rb +317 -121
  18. data/lib/rbs/constant.rb +4 -4
  19. data/lib/rbs/constant_table.rb +51 -45
  20. data/lib/rbs/definition.rb +175 -59
  21. data/lib/rbs/definition_builder.rb +814 -604
  22. data/lib/rbs/environment.rb +352 -210
  23. data/lib/rbs/environment_walker.rb +14 -23
  24. data/lib/rbs/errors.rb +184 -3
  25. data/lib/rbs/factory.rb +14 -0
  26. data/lib/rbs/location.rb +15 -0
  27. data/lib/rbs/parser.y +100 -34
  28. data/lib/rbs/prototype/rb.rb +101 -113
  29. data/lib/rbs/prototype/rbi.rb +5 -3
  30. data/lib/rbs/prototype/runtime.rb +11 -7
  31. data/lib/rbs/substitution.rb +12 -1
  32. data/lib/rbs/test.rb +82 -3
  33. data/lib/rbs/test/errors.rb +5 -1
  34. data/lib/rbs/test/hook.rb +133 -259
  35. data/lib/rbs/test/observer.rb +17 -0
  36. data/lib/rbs/test/setup.rb +35 -19
  37. data/lib/rbs/test/setup_helper.rb +29 -0
  38. data/lib/rbs/test/spy.rb +0 -321
  39. data/lib/rbs/test/tester.rb +116 -0
  40. data/lib/rbs/test/type_check.rb +43 -7
  41. data/lib/rbs/type_name_resolver.rb +58 -0
  42. data/lib/rbs/types.rb +94 -2
  43. data/lib/rbs/validator.rb +55 -0
  44. data/lib/rbs/variance_calculator.rb +12 -2
  45. data/lib/rbs/version.rb +1 -1
  46. data/lib/rbs/writer.rb +127 -91
  47. data/rbs.gemspec +0 -10
  48. data/schema/decls.json +36 -10
  49. data/schema/members.json +3 -0
  50. data/stdlib/benchmark/benchmark.rbs +151 -151
  51. data/stdlib/builtin/enumerable.rbs +3 -3
  52. data/stdlib/builtin/file.rbs +0 -3
  53. data/stdlib/builtin/io.rbs +4 -4
  54. data/stdlib/builtin/proc.rbs +1 -2
  55. data/stdlib/builtin/thread.rbs +2 -2
  56. data/stdlib/csv/csv.rbs +4 -6
  57. data/stdlib/fiber/fiber.rbs +1 -1
  58. data/stdlib/json/json.rbs +7 -1
  59. data/stdlib/logger/formatter.rbs +23 -0
  60. data/stdlib/logger/log_device.rbs +39 -0
  61. data/stdlib/logger/logger.rbs +507 -0
  62. data/stdlib/logger/period.rbs +7 -0
  63. data/stdlib/logger/severity.rbs +8 -0
  64. data/stdlib/mutex_m/mutex_m.rbs +77 -0
  65. data/stdlib/pathname/pathname.rbs +6 -6
  66. data/stdlib/prime/integer-extension.rbs +1 -1
  67. data/stdlib/prime/prime.rbs +44 -44
  68. data/stdlib/pty/pty.rbs +159 -0
  69. data/stdlib/tmpdir/tmpdir.rbs +1 -1
  70. metadata +19 -130
  71. data/lib/rbs/test/test_helper.rb +0 -183
@@ -6,19 +6,20 @@ module RBS
6
6
 
7
7
  def initialize
8
8
  @source_decls = []
9
- @toplevel_members = []
10
9
  end
11
10
 
12
11
  def decls
13
12
  decls = []
14
13
 
15
- decls.push(*source_decls)
14
+ top_decls, top_members = source_decls.partition {|decl| decl.is_a?(AST::Declarations::Base) }
16
15
 
17
- unless toplevel_members.empty?
18
- top = AST::Declarations::Extension.new(
16
+ decls.push(*top_decls)
17
+
18
+ unless top_members.empty?
19
+ top = AST::Declarations::Class.new(
19
20
  name: TypeName.new(name: :Object, namespace: Namespace.empty),
20
- extension_name: :Toplevel,
21
- members: toplevel_members,
21
+ super_class: nil,
22
+ members: top_members,
22
23
  annotations: [],
23
24
  comment: nil,
24
25
  location: nil,
@@ -27,7 +28,7 @@ module RBS
27
28
  decls << top
28
29
  end
29
30
 
30
- decls.uniq
31
+ decls
31
32
  end
32
33
 
33
34
  def parse(string)
@@ -51,19 +52,15 @@ module RBS
51
52
  end
52
53
  end
53
54
 
54
- process RubyVM::AbstractSyntaxTree.parse(string), namespace: Namespace.empty, current_module: nil, comments: comments, singleton: false
55
- end
56
-
57
- def nested_name(name)
58
- (current_namespace + const_to_name(name).to_namespace).to_type_name.relative!
55
+ process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, singleton: false
59
56
  end
60
57
 
61
- def process(node, namespace:, current_module:, comments:, singleton:)
58
+ def process(node, decls:, comments:, singleton:)
62
59
  case node.type
63
60
  when :CLASS
64
61
  class_name, super_class, *class_body = node.children
65
62
  kls = AST::Declarations::Class.new(
66
- name: const_to_name(class_name).with_prefix(namespace).relative!,
63
+ name: const_to_name(class_name),
67
64
  super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: []),
68
65
  type_params: AST::Declarations::ModuleTypeParams.empty,
69
66
  members: [],
@@ -72,39 +69,42 @@ module RBS
72
69
  comment: comments[node.first_lineno - 1]
73
70
  )
74
71
 
75
- source_decls.push kls
72
+ decls.push kls
76
73
 
77
74
  each_node class_body do |child|
78
- process child, namespace: kls.name.to_namespace, current_module: kls, comments: comments, singleton: false
75
+ process child, decls: kls.members, comments: comments, singleton: false
79
76
  end
77
+
80
78
  when :MODULE
81
79
  module_name, *module_body = node.children
82
80
 
83
81
  mod = AST::Declarations::Module.new(
84
- name: const_to_name(module_name).with_prefix(namespace).relative!,
82
+ name: const_to_name(module_name),
85
83
  type_params: AST::Declarations::ModuleTypeParams.empty,
86
- self_type: nil,
84
+ self_types: [],
87
85
  members: [],
88
86
  annotations: [],
89
87
  location: nil,
90
88
  comment: comments[node.first_lineno - 1]
91
89
  )
92
90
 
93
- source_decls.push mod
91
+ decls.push mod
94
92
 
95
93
  each_node module_body do |child|
96
- process child, namespace: mod.name.to_namespace, current_module: mod, comments: comments, singleton: false
94
+ process child, decls: mod.members, comments: comments, singleton: false
97
95
  end
96
+
98
97
  when :SCLASS
99
- this = node.children[0]
98
+ this, body = node.children
99
+
100
100
  if this.type != :SELF
101
101
  RBS.logger.warn "`class <<` syntax with not-self may be compiled to incorrect code: #{this}"
102
102
  end
103
103
 
104
- body = node.children[1]
105
104
  each_child(body) do |child|
106
- process child, namespace: namespace, current_module: current_module, comments: comments, singleton: true
105
+ process child, decls: decls, comments: comments, singleton: true
107
106
  end
107
+
108
108
  when :DEFN, :DEFS
109
109
  if node.type == :DEFN
110
110
  def_name, def_body = node.children
@@ -130,116 +130,104 @@ module RBS
130
130
  types: types,
131
131
  kind: kind,
132
132
  comment: comments[node.first_lineno - 1],
133
- attributes: []
133
+ attributes: [],
134
+ overload: false
134
135
  )
135
136
 
136
- if current_module
137
- current_module.members.push member
138
- else
139
- toplevel_members.push member
140
- end
137
+ decls.push member unless decls.include?(member)
138
+
141
139
  when :FCALL
142
- if current_module
143
- # Inside method definition cannot reach here.
144
- args = node.children[1]&.children || []
145
-
146
- case node.children[0]
147
- when :include
148
- args.each do |arg|
149
- if (name = const_to_name(arg))
150
- current_module.members << AST::Members::Include.new(
151
- name: name,
152
- args: [],
153
- annotations: [],
154
- location: nil,
155
- comment: comments[node.first_lineno - 1]
156
- )
157
- end
140
+ # Inside method definition cannot reach here.
141
+ args = node.children[1]&.children || []
142
+
143
+ case node.children[0]
144
+ when :include
145
+ args.each do |arg|
146
+ if (name = const_to_name(arg))
147
+ decls << AST::Members::Include.new(
148
+ name: name,
149
+ args: [],
150
+ annotations: [],
151
+ location: nil,
152
+ comment: comments[node.first_lineno - 1]
153
+ )
158
154
  end
159
- when :extend
160
- args.each do |arg|
161
- if (name = const_to_name(arg))
162
- current_module.members << AST::Members::Extend.new(
163
- name: name,
164
- args: [],
165
- annotations: [],
166
- location: nil,
167
- comment: comments[node.first_lineno - 1]
168
- )
169
- end
155
+ end
156
+ when :extend
157
+ args.each do |arg|
158
+ if (name = const_to_name(arg))
159
+ decls << AST::Members::Extend.new(
160
+ name: name,
161
+ args: [],
162
+ annotations: [],
163
+ location: nil,
164
+ comment: comments[node.first_lineno - 1]
165
+ )
170
166
  end
171
- when :attr_reader
172
- args.each do |arg|
173
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
174
- current_module.members << AST::Members::AttrReader.new(
175
- name: arg.children[0],
176
- ivar_name: nil,
177
- type: Types::Bases::Any.new(location: nil),
178
- location: nil,
179
- comment: comments[node.first_lineno - 1],
180
- annotations: []
181
- )
182
- end
167
+ end
168
+ when :attr_reader
169
+ args.each do |arg|
170
+ if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
171
+ decls << AST::Members::AttrReader.new(
172
+ name: arg.children[0],
173
+ ivar_name: nil,
174
+ type: Types::Bases::Any.new(location: nil),
175
+ location: nil,
176
+ comment: comments[node.first_lineno - 1],
177
+ annotations: []
178
+ )
183
179
  end
184
- when :attr_accessor
185
- args.each do |arg|
186
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
187
- current_module.members << AST::Members::AttrAccessor.new(
188
- name: arg.children[0],
189
- ivar_name: nil,
190
- type: Types::Bases::Any.new(location: nil),
191
- location: nil,
192
- comment: comments[node.first_lineno - 1],
193
- annotations: []
194
- )
195
- end
180
+ end
181
+ when :attr_accessor
182
+ args.each do |arg|
183
+ if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
184
+ decls << AST::Members::AttrAccessor.new(
185
+ name: arg.children[0],
186
+ ivar_name: nil,
187
+ type: Types::Bases::Any.new(location: nil),
188
+ location: nil,
189
+ comment: comments[node.first_lineno - 1],
190
+ annotations: []
191
+ )
196
192
  end
197
- when :attr_writer
198
- args.each do |arg|
199
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
200
- current_module.members << AST::Members::AttrWriter.new(
201
- name: arg.children[0],
202
- ivar_name: nil,
203
- type: Types::Bases::Any.new(location: nil),
204
- location: nil,
205
- comment: comments[node.first_lineno - 1],
206
- annotations: []
207
- )
208
- end
193
+ end
194
+ when :attr_writer
195
+ args.each do |arg|
196
+ if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
197
+ decls << AST::Members::AttrWriter.new(
198
+ name: arg.children[0],
199
+ ivar_name: nil,
200
+ type: Types::Bases::Any.new(location: nil),
201
+ location: nil,
202
+ comment: comments[node.first_lineno - 1],
203
+ annotations: []
204
+ )
209
205
  end
210
206
  end
211
207
  end
208
+
212
209
  each_child node do |child|
213
- process child, namespace: namespace, current_module: current_module, comments: comments, singleton: singleton
210
+ process child, decls: decls, comments: comments, singleton: singleton
214
211
  end
215
212
 
216
213
  when :CDECL
217
- type_name = case
218
- when node.children[0].is_a?(Symbol)
219
- ns = if current_module
220
- current_module.name.to_namespace
221
- else
222
- Namespace.empty
223
- end
224
- TypeName.new(name: node.children[0], namespace: ns)
225
- else
226
- name = const_to_name(node.children[0])
227
- if current_module
228
- name.with_prefix current_module.name.to_namespace
229
- else
230
- name
231
- end.relative!
232
- end
233
-
234
- source_decls << AST::Declarations::Constant.new(
235
- name: type_name,
214
+ const_name = case
215
+ when node.children[0].is_a?(Symbol)
216
+ TypeName.new(name: node.children[0], namespace: Namespace.empty)
217
+ else
218
+ const_to_name(node.children[0])
219
+ end
220
+
221
+ decls << AST::Declarations::Constant.new(
222
+ name: const_name,
236
223
  type: node_type(node.children.last),
237
224
  location: nil,
238
225
  comment: comments[node.first_lineno - 1]
239
226
  )
227
+
240
228
  else
241
229
  each_child node do |child|
242
- process child, namespace: namespace, current_module: current_module, comments: comments, singleton: singleton
230
+ process child, decls: decls, comments: comments, singleton: singleton
243
231
  end
244
232
  end
245
233
  end
@@ -69,7 +69,7 @@ module RBS
69
69
  members: [],
70
70
  annotations: [],
71
71
  location: nil,
72
- self_type: nil,
72
+ self_types: [],
73
73
  comment: comment
74
74
  )
75
75
 
@@ -173,7 +173,8 @@ module RBS
173
173
  types: types,
174
174
  kind: :singleton,
175
175
  comment: comment,
176
- attributes: []
176
+ attributes: [],
177
+ overload: false
177
178
  )
178
179
  end
179
180
 
@@ -193,7 +194,8 @@ module RBS
193
194
  types: types,
194
195
  kind: :instance,
195
196
  comment: comment,
196
- attributes: []
197
+ attributes: [],
198
+ overload: false
197
199
  )
198
200
  end
199
201
 
@@ -128,7 +128,7 @@ module RBS
128
128
 
129
129
  def merge_rbs(module_name, members, instance: nil, singleton: nil)
130
130
  if merge
131
- if env.class?(module_name.absolute!)
131
+ if env.class_decls[module_name.absolute!]
132
132
  case
133
133
  when instance
134
134
  method = builder.build_instance(module_name.absolute!).methods[instance]
@@ -152,9 +152,10 @@ module RBS
152
152
  },
153
153
  kind: kind,
154
154
  location: nil,
155
- comment: method.comment,
155
+ comment: method.comments[0],
156
156
  annotations: method.annotations,
157
- attributes: method.attributes
157
+ attributes: method.attributes,
158
+ overload: false
158
159
  )
159
160
  return
160
161
  end
@@ -192,7 +193,8 @@ module RBS
192
193
  location: nil,
193
194
  comment: nil,
194
195
  annotations: [],
195
- attributes: []
196
+ attributes: [],
197
+ overload: false
196
198
  )
197
199
  end
198
200
  else
@@ -225,7 +227,8 @@ module RBS
225
227
  location: nil,
226
228
  comment: nil,
227
229
  annotations: [],
228
- attributes: []
230
+ attributes: [],
231
+ overload: false
229
232
  )
230
233
  end
231
234
  else
@@ -259,7 +262,8 @@ module RBS
259
262
  location: nil,
260
263
  comment: nil,
261
264
  annotations: [],
262
- attributes: []
265
+ attributes: [],
266
+ overload: false
263
267
  )
264
268
  end
265
269
  else
@@ -366,7 +370,7 @@ module RBS
366
370
  decl = AST::Declarations::Module.new(
367
371
  name: type_name,
368
372
  type_params: AST::Declarations::ModuleTypeParams.empty,
369
- self_type: nil,
373
+ self_types: [],
370
374
  members: [],
371
375
  annotations: [],
372
376
  location: nil,
@@ -1,6 +1,7 @@
1
1
  module RBS
2
2
  class Substitution
3
3
  attr_reader :mapping
4
+ attr_accessor :instance_type
4
5
 
5
6
  def initialize()
6
7
  @mapping = {}
@@ -10,7 +11,7 @@ module RBS
10
11
  mapping[from] = to
11
12
  end
12
13
 
13
- def self.build(variables, types, &block)
14
+ def self.build(variables, types, instance_type: nil, &block)
14
15
  unless variables.size == types.size
15
16
  raise "Broken substitution: variables=#{variables}, types=#{types}"
16
17
  end
@@ -22,6 +23,8 @@ module RBS
22
23
  type = block_given? ? yield(t) : t
23
24
  subst.add(from: v, to: type)
24
25
  end
26
+
27
+ subst.instance_type = instance_type
25
28
  end
26
29
  end
27
30
 
@@ -29,6 +32,12 @@ module RBS
29
32
  case ty
30
33
  when Types::Variable
31
34
  mapping[ty.name] || ty
35
+ when Types::Bases::Instance
36
+ if instance_type
37
+ instance_type
38
+ else
39
+ ty
40
+ end
32
41
  else
33
42
  ty
34
43
  end
@@ -40,6 +49,8 @@ module RBS
40
49
  vars.each do |var|
41
50
  subst.mapping.delete(var)
42
51
  end
52
+
53
+ subst.instance_type = self.instance_type
43
54
  end
44
55
  end
45
56
  end
@@ -1,7 +1,11 @@
1
+ require "securerandom"
2
+ require "rbs/test/observer"
1
3
  require "rbs/test/spy"
2
4
  require "rbs/test/errors"
3
5
  require "rbs/test/type_check"
6
+ require "rbs/test/tester"
4
7
  require "rbs/test/hook"
8
+ require "rbs/test/setup_helper"
5
9
 
6
10
  module RBS
7
11
  module Test
@@ -16,11 +20,86 @@ module RBS
16
20
  INSPECT = Kernel.instance_method(:inspect)
17
21
  METHODS = Kernel.instance_method(:methods)
18
22
 
19
- ArgumentsReturn = Struct.new(:arguments, :return_value, :exception, keyword_init: true)
23
+ class ArgumentsReturn
24
+ attr_reader :arguments
25
+ attr_reader :exit_value
26
+ attr_reader :exit_type
27
+
28
+ def initialize(arguments:, exit_value:, exit_type:)
29
+ @arguments = arguments
30
+ @exit_value = exit_value
31
+ @exit_type = exit_type
32
+ end
33
+
34
+ def self.return(arguments:, value:)
35
+ new(arguments: arguments, exit_value: value, exit_type: :return)
36
+ end
37
+
38
+ def self.exception(arguments:, exception:)
39
+ new(arguments: arguments, exit_value: exception, exit_type: :exception)
40
+ end
41
+
42
+ def self.break(arguments:)
43
+ new(arguments: arguments, exit_value: nil, exit_type: :break)
44
+ end
45
+
46
+ def return_value
47
+ raise unless exit_type == :return
48
+ exit_value
49
+ end
50
+
51
+ def exception
52
+ raise unless exit_type == :exception
53
+ exit_value
54
+ end
55
+
56
+ def return?
57
+ exit_type == :return
58
+ end
59
+
60
+ def exception?
61
+ exit_type == :exception
62
+ end
63
+
64
+ def break?
65
+ exit_type == :break
66
+ end
67
+ end
68
+
20
69
  CallTrace = Struct.new(:method_name, :method_call, :block_calls, :block_given, keyword_init: true)
21
70
 
22
- def self.call(receiver, method, *args, **kwargs, &block)
23
- method.bind_call(receiver, *args, **kwargs, &block)
71
+ class <<self
72
+ attr_accessor :suffix
73
+
74
+ def reset_suffix
75
+ self.suffix = "RBS_TEST_#{SecureRandom.hex(3)}"
76
+ end
77
+ end
78
+
79
+ reset_suffix
80
+
81
+ if ::UnboundMethod.instance_methods.include?(:bind_call)
82
+ def self.call(receiver, method, *args, &block)
83
+ method.bind_call(receiver, *args, &block)
84
+ end
85
+ else
86
+ def self.call(receiver, method, *args, &block)
87
+ method.bind(receiver).call(*args, &block)
88
+ end
24
89
  end
25
90
  end
26
91
  end
92
+
93
+ unless ::Module.private_instance_methods.include?(:ruby2_keywords)
94
+ class Module
95
+ private
96
+ def ruby2_keywords(*)
97
+ end
98
+ end
99
+ end
100
+
101
+ unless ::Proc.instance_methods.include?(:ruby2_keywords)
102
+ class Proc
103
+ def ruby2_keywords; end
104
+ end
105
+ end