rbs 0.4.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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