rbs 0.12.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.gitignore +0 -1
  4. data/CHANGELOG.md +31 -0
  5. data/Gemfile +3 -0
  6. data/README.md +8 -2
  7. data/Rakefile +2 -2
  8. data/Steepfile +1 -0
  9. data/bin/annotate-with-rdoc +1 -1
  10. data/bin/setup +0 -2
  11. data/docs/CONTRIBUTING.md +1 -0
  12. data/docs/syntax.md +50 -6
  13. data/goodcheck.yml +22 -5
  14. data/lib/rbs/ast/comment.rb +1 -1
  15. data/lib/rbs/cli.rb +12 -4
  16. data/lib/rbs/constant.rb +1 -1
  17. data/lib/rbs/constant_table.rb +9 -8
  18. data/lib/rbs/definition_builder.rb +6 -7
  19. data/lib/rbs/environment.rb +5 -1
  20. data/lib/rbs/environment_loader.rb +12 -12
  21. data/lib/rbs/namespace.rb +1 -1
  22. data/lib/rbs/parser.rb +3148 -0
  23. data/lib/rbs/parser.y +10 -3
  24. data/lib/rbs/prototype/rb.rb +38 -6
  25. data/lib/rbs/prototype/runtime.rb +17 -7
  26. data/lib/rbs/test/hook.rb +2 -0
  27. data/lib/rbs/test/setup_helper.rb +4 -4
  28. data/lib/rbs/test/tester.rb +4 -1
  29. data/lib/rbs/test/type_check.rb +12 -6
  30. data/lib/rbs/type_name.rb +1 -1
  31. data/lib/rbs/variance_calculator.rb +2 -2
  32. data/lib/rbs/version.rb +1 -1
  33. data/lib/rbs/writer.rb +25 -15
  34. data/sig/constant.rbs +21 -0
  35. data/sig/constant_table.rbs +30 -0
  36. data/sig/declarations.rbs +2 -2
  37. data/sig/definition.rbs +2 -2
  38. data/sig/definition_builder.rbs +4 -5
  39. data/sig/environment_loader.rbs +54 -0
  40. data/sig/members.rbs +2 -2
  41. data/sig/method_types.rbs +1 -1
  42. data/sig/namespace.rbs +4 -4
  43. data/sig/parser.rbs +25 -0
  44. data/sig/substitution.rbs +3 -3
  45. data/sig/typename.rbs +1 -1
  46. data/sig/types.rbs +1 -1
  47. data/sig/version.rbs +3 -0
  48. data/sig/writer.rbs +40 -0
  49. data/stdlib/base64/base64.rbs +1 -1
  50. data/stdlib/benchmark/benchmark.rbs +2 -2
  51. data/stdlib/builtin/array.rbs +124 -120
  52. data/stdlib/builtin/basic_object.rbs +54 -54
  53. data/stdlib/builtin/binding.rbs +42 -42
  54. data/stdlib/builtin/builtin.rbs +28 -0
  55. data/stdlib/builtin/class.rbs +33 -33
  56. data/stdlib/builtin/complex.rbs +90 -90
  57. data/stdlib/builtin/encoding.rbs +33 -33
  58. data/stdlib/builtin/enumerable.rbs +58 -52
  59. data/stdlib/builtin/enumerator.rbs +35 -35
  60. data/stdlib/builtin/errors.rbs +2 -2
  61. data/stdlib/builtin/exception.rbs +50 -50
  62. data/stdlib/builtin/false_class.rbs +6 -6
  63. data/stdlib/builtin/fiber.rbs +14 -14
  64. data/stdlib/builtin/fiber_error.rbs +1 -1
  65. data/stdlib/builtin/float.rbs +161 -161
  66. data/stdlib/builtin/gc.rbs +3 -3
  67. data/stdlib/builtin/hash.rbs +7 -7
  68. data/stdlib/builtin/io.rbs +88 -88
  69. data/stdlib/builtin/kernel.rbs +71 -153
  70. data/stdlib/builtin/match_data.rbs +1 -1
  71. data/stdlib/builtin/method.rbs +19 -19
  72. data/stdlib/builtin/module.rbs +13 -13
  73. data/stdlib/builtin/nil_class.rbs +20 -20
  74. data/stdlib/builtin/numeric.rbs +101 -101
  75. data/stdlib/builtin/object.rbs +173 -173
  76. data/stdlib/builtin/proc.rbs +91 -91
  77. data/stdlib/builtin/random.rbs +1 -1
  78. data/stdlib/builtin/range.rbs +3 -5
  79. data/stdlib/builtin/rational.rbs +83 -83
  80. data/stdlib/builtin/signal.rbs +7 -7
  81. data/stdlib/builtin/string.rbs +10 -10
  82. data/stdlib/builtin/string_io.rbs +8 -8
  83. data/stdlib/builtin/struct.rbs +1 -1
  84. data/stdlib/builtin/symbol.rbs +1 -1
  85. data/stdlib/builtin/thread.rbs +189 -189
  86. data/stdlib/builtin/thread_group.rbs +2 -2
  87. data/stdlib/builtin/true_class.rbs +10 -10
  88. data/stdlib/builtin/warning.rbs +1 -1
  89. data/stdlib/coverage/coverage.rbs +2 -2
  90. data/stdlib/csv/csv.rbs +1 -1
  91. data/stdlib/date/date.rbs +4 -4
  92. data/stdlib/date/date_time.rbs +1 -1
  93. data/stdlib/find/find.rbs +12 -12
  94. data/stdlib/logger/log_device.rbs +1 -1
  95. data/stdlib/logger/logger.rbs +1 -1
  96. data/stdlib/pathname/pathname.rbs +41 -39
  97. data/stdlib/pstore/pstore.rbs +287 -0
  98. data/stdlib/pty/pty.rbs +5 -29
  99. data/stdlib/tmpdir/tmpdir.rbs +12 -12
  100. data/stdlib/uri/generic.rbs +2 -2
  101. data/stdlib/uri/http.rbs +158 -0
  102. data/stdlib/uri/https.rbs +108 -0
  103. data/stdlib/uri/ldap.rbs +224 -0
  104. data/stdlib/uri/ldaps.rbs +108 -0
  105. data/steep/Gemfile.lock +13 -17
  106. metadata +13 -3
@@ -1,5 +1,6 @@
1
1
  class RBS::Parser
2
- token tUIDENT tLIDENT tNAMESPACE tINTERFACEIDENT tLKEYWORD tUKEYWORD tGLOBALIDENT
2
+ token tUIDENT tLIDENT tNAMESPACE tINTERFACEIDENT tGLOBALIDENT
3
+ tLKEYWORD tUKEYWORD tLKEYWORD_Q_E tUKEYWORD_Q_E
3
4
  tIVAR tCLASSVAR
4
5
  tANNOTATION
5
6
  tSTRING tSYMBOL tINTEGER tWRITE_ATTR
@@ -474,6 +475,8 @@ rule
474
475
 
475
476
  method_type:
476
477
  start_merged_scope type_params params_opt block_opt kARROW simple_type {
478
+ reset_variable_scope
479
+
477
480
  location = (val[1] || val[2] || val[3] || val[4]).location + val[5].location
478
481
  type_params = val[1]&.value || []
479
482
 
@@ -846,7 +849,7 @@ rule
846
849
  result = val[0]
847
850
  }
848
851
 
849
- keyword: tLKEYWORD | tUKEYWORD
852
+ keyword: tLKEYWORD | tUKEYWORD | tLKEYWORD_Q_E | tUKEYWORD_Q_E
850
853
 
851
854
  function_type:
852
855
  kLPAREN params kRPAREN kARROW simple_type {
@@ -874,7 +877,7 @@ rule
874
877
  required_keywords: {},
875
878
  optional_keywords: {},
876
879
  rest_keywords: nil,
877
- return_type: val[2]
880
+ return_type: val[1]
878
881
  )
879
882
 
880
883
  result = LocatedValue.new(value: type, location: location)
@@ -1344,8 +1347,12 @@ def next_token
1344
1347
  new_token(:tNAMESPACE)
1345
1348
  when input.scan(/[a-z_]\w*:/)
1346
1349
  new_token(:tLKEYWORD, input.matched.chop.to_sym)
1350
+ when input.scan(/[a-z_]\w*[?!]:/)
1351
+ new_token(:tLKEYWORD_Q_E, input.matched.chop.to_sym)
1347
1352
  when input.scan(/[A-Z]\w*:/)
1348
1353
  new_token(:tUKEYWORD, input.matched.chop.to_sym)
1354
+ when input.scan(/[A-Z]\w*[?!]:/)
1355
+ new_token(:tUKEYWORD_Q_E, input.matched.chop.to_sym)
1349
1356
  when input.scan(/\$[A-Za-z_]\w*/)
1350
1357
  new_token(:tGLOBALIDENT)
1351
1358
  when input.scan(/@[a-zA-Z_]\w*/)
@@ -135,6 +135,18 @@ module RBS
135
135
 
136
136
  decls.push member unless decls.include?(member)
137
137
 
138
+ when :ALIAS
139
+ new_name, old_name = node.children.map { |c| literal_to_symbol(c) }
140
+ member = AST::Members::Alias.new(
141
+ new_name: new_name,
142
+ old_name: old_name,
143
+ kind: singleton ? :singleton : :instance,
144
+ annotations: [],
145
+ location: nil,
146
+ comment: comments[node.first_lineno - 1],
147
+ )
148
+ decls.push member unless decls.include?(member)
149
+
138
150
  when :FCALL
139
151
  # Inside method definition cannot reach here.
140
152
  args = node.children[1]&.children || []
@@ -166,9 +178,9 @@ module RBS
166
178
  end
167
179
  when :attr_reader
168
180
  args.each do |arg|
169
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
181
+ if arg && (name = literal_to_symbol(arg))
170
182
  decls << AST::Members::AttrReader.new(
171
- name: arg.children[0],
183
+ name: name,
172
184
  ivar_name: nil,
173
185
  type: Types::Bases::Any.new(location: nil),
174
186
  location: nil,
@@ -179,9 +191,9 @@ module RBS
179
191
  end
180
192
  when :attr_accessor
181
193
  args.each do |arg|
182
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
194
+ if arg && (name = literal_to_symbol(arg))
183
195
  decls << AST::Members::AttrAccessor.new(
184
- name: arg.children[0],
196
+ name: name,
185
197
  ivar_name: nil,
186
198
  type: Types::Bases::Any.new(location: nil),
187
199
  location: nil,
@@ -192,9 +204,9 @@ module RBS
192
204
  end
193
205
  when :attr_writer
194
206
  args.each do |arg|
195
- if arg&.type == :LIT && arg.children[0].is_a?(Symbol)
207
+ if arg && (name = literal_to_symbol(arg))
196
208
  decls << AST::Members::AttrWriter.new(
197
- name: arg.children[0],
209
+ name: name,
198
210
  ivar_name: nil,
199
211
  type: Types::Bases::Any.new(location: nil),
200
212
  location: nil,
@@ -203,6 +215,17 @@ module RBS
203
215
  )
204
216
  end
205
217
  end
218
+ when :alias_method
219
+ if args[0] && args[1] && (new_name = literal_to_symbol(args[0])) && (old_name = literal_to_symbol(args[1]))
220
+ decls << AST::Members::Alias.new(
221
+ new_name: new_name,
222
+ old_name: old_name,
223
+ kind: singleton ? :singleton : :instance,
224
+ annotations: [],
225
+ location: nil,
226
+ comment: comments[node.first_lineno - 1],
227
+ )
228
+ end
206
229
  end
207
230
 
208
231
  each_child node do |child|
@@ -248,6 +271,15 @@ module RBS
248
271
  end
249
272
  end
250
273
 
274
+ def literal_to_symbol(node)
275
+ case node.type
276
+ when :LIT
277
+ node.children[0] if node.children[0].is_a?(Symbol)
278
+ when :STR
279
+ node.children[0].to_sym
280
+ end
281
+ end
282
+
251
283
  def each_node(nodes)
252
284
  nodes.each do |child|
253
285
  if child.is_a?(RubyVM::AbstractSyntaxTree::Node)
@@ -17,11 +17,13 @@ module RBS
17
17
  end
18
18
 
19
19
  def target?(const)
20
+ name = const_name(const)
21
+
20
22
  patterns.any? do |pattern|
21
23
  if pattern.end_with?("*")
22
- (const.name || "").start_with?(pattern.chop)
24
+ (name || "").start_with?(pattern.chop)
23
25
  else
24
- const.name == pattern
26
+ name == pattern
25
27
  end
26
28
  end
27
29
  end
@@ -37,7 +39,7 @@ module RBS
37
39
  def decls
38
40
  unless @decls
39
41
  @decls = []
40
- ObjectSpace.each_object(Module).select {|mod| target?(mod) }.sort_by(&:name).each do |mod|
42
+ ObjectSpace.each_object(Module).select {|mod| target?(mod) }.sort_by{|mod| const_name(mod) }.each do |mod|
41
43
  case mod
42
44
  when Class
43
45
  generate_class mod
@@ -356,12 +358,14 @@ module RBS
356
358
  end
357
359
 
358
360
  def generate_module(mod)
359
- unless mod.name
361
+ name = const_name(mod)
362
+
363
+ unless name
360
364
  RBS.logger.warn("Skipping anonymous module #{mod}")
361
365
  return
362
366
  end
363
367
 
364
- type_name = to_type_name(mod.name)
368
+ type_name = to_type_name(name)
365
369
 
366
370
  decl = AST::Declarations::Module.new(
367
371
  name: type_name,
@@ -374,12 +378,13 @@ module RBS
374
378
  )
375
379
 
376
380
  each_mixin(mod.included_modules, *mod.included_modules.flat_map(&:included_modules), namespace: type_name.namespace) do |included_module|
377
- unless included_module.name
381
+ included_module_name = const_name(included_module)
382
+ unless included_module_name
378
383
  RBS.logger.warn("Skipping anonymous module #{included_module} included in #{mod}")
379
384
  next
380
385
  end
381
386
 
382
- module_name = to_type_name(included_module.name)
387
+ module_name = to_type_name(included_module_name)
383
388
  if module_name.namespace == type_name.namespace
384
389
  module_name = TypeName.new(name: module_name.name, namespace: Namespace.empty)
385
390
  end
@@ -399,6 +404,11 @@ module RBS
399
404
 
400
405
  generate_constants mod
401
406
  end
407
+
408
+ def const_name(const)
409
+ @module_name_method ||= Module.instance_method(:name)
410
+ @module_name_method.bind(const).call
411
+ end
402
412
  end
403
413
  end
404
414
  end
@@ -5,6 +5,8 @@ module RBS
5
5
  module Test
6
6
  module Hook
7
7
  OPERATORS = {
8
+ :[] => "indexlookup",
9
+ :[]= => "indexset",
8
10
  :== => "eqeq",
9
11
  :=== => "eqeqeq",
10
12
  :!= => "noteq",
@@ -3,15 +3,15 @@ module RBS
3
3
  module SetupHelper
4
4
  class InvalidSampleSizeError < StandardError
5
5
  attr_reader :string
6
-
6
+
7
7
  def initialize(string)
8
8
  @string = string
9
9
  super("Sample size should be a positive integer: `#{string}`")
10
10
  end
11
11
  end
12
-
12
+
13
13
  DEFAULT_SAMPLE_SIZE = 100
14
-
14
+
15
15
  def get_sample_size(string)
16
16
  case string
17
17
  when ""
@@ -32,7 +32,7 @@ module RBS
32
32
  when 'rspec'
33
33
  ['::RSpec::Mocks::Double']
34
34
  when 'minitest'
35
- ['::Minitest::Mock']
35
+ ['::Minitest::Mock']
36
36
  else
37
37
  RBS.logger.warn "Unknown test suite - defaults to nil"
38
38
  nil
@@ -56,7 +56,10 @@ module RBS
56
56
  RBS.logger.info { "Skipping ##{name} because of `#{reason}`..." }
57
57
  end
58
58
  else
59
- if klass.instance_methods(false).include?(name) && !set.include?(name)
59
+ if !set.include?(name) && (
60
+ name == :initialize ||
61
+ klass.instance_methods(false).include?(name) ||
62
+ klass.private_instance_methods(false).include?(name))
60
63
  RBS.logger.info { "Setting up method hook in ##{name}..." }
61
64
  Hook.hook_instance_method klass, name, key: instance_key
62
65
  set << name
@@ -202,24 +202,30 @@ module RBS
202
202
  end
203
203
 
204
204
  def get_class(type_name)
205
- const_cache[type_name] ||= Object.const_get(type_name.to_s)
205
+ const_cache[type_name] ||= begin
206
+ Object.const_get(type_name.to_s)
207
+ rescue NameError
208
+ nil
209
+ end
206
210
  end
207
211
 
208
212
  def is_double?(value)
209
213
  unchecked_classes.any? { |unchecked_class| Test.call(value, IS_AP, Object.const_get(unchecked_class))}
214
+ rescue NameError
215
+ false
210
216
  end
211
217
 
212
218
  def value(val, type)
213
219
  if is_double?(val)
214
220
  RBS.logger.info("A double (#{val.inspect}) is detected!")
215
- return true
221
+ return true
216
222
  end
217
223
 
218
224
  case type
219
225
  when Types::Bases::Any
220
226
  true
221
227
  when Types::Bases::Bool
222
- true
228
+ val.is_a?(TrueClass) || val.is_a?(FalseClass)
223
229
  when Types::Bases::Top
224
230
  true
225
231
  when Types::Bases::Bottom
@@ -235,7 +241,7 @@ module RBS
235
241
  when Types::Bases::Instance
236
242
  Test.call(val, IS_AP, self_class)
237
243
  when Types::ClassInstance
238
- klass = get_class(type.name)
244
+ klass = get_class(type.name) or return false
239
245
  case
240
246
  when klass == ::Array
241
247
  Test.call(val, IS_AP, klass) && each_sample(val).all? {|v| value(v, type.args[0]) }
@@ -281,7 +287,7 @@ module RBS
281
287
  Test.call(val, IS_AP, klass)
282
288
  end
283
289
  when Types::ClassSingleton
284
- klass = get_class(type.name)
290
+ klass = get_class(type.name) or return false
285
291
  val == klass
286
292
  when Types::Interface
287
293
  methods = Set.new(Test.call(val, METHODS))
@@ -306,7 +312,7 @@ module RBS
306
312
  Test.call(val, IS_AP, ::Array) &&
307
313
  type.types.map.with_index {|ty, index| value(val[index], ty) }.all?
308
314
  when Types::Record
309
- Test::call(val, IS_AP, ::Hash) &&
315
+ Test::call(val, IS_AP, ::Hash) &&
310
316
  type.fields.map {|key, type| value(val[key], type) }.all?
311
317
  when Types::Proc
312
318
  Test::call(val, IS_AP, ::Proc)
@@ -23,7 +23,7 @@ module RBS
23
23
  def ==(other)
24
24
  other.is_a?(self.class) && other.namespace == namespace && other.name == name
25
25
  end
26
-
26
+
27
27
  alias eql? ==
28
28
 
29
29
  def hash
@@ -120,7 +120,7 @@ module RBS
120
120
 
121
121
  type.args.each.with_index do |ty, i|
122
122
  var = type_params.params[i]
123
- case var.variance
123
+ case var&.variance
124
124
  when :invariant
125
125
  type(ty, result: result, context: :invariant)
126
126
  when :covariant
@@ -135,7 +135,7 @@ module RBS
135
135
  when :contravariant
136
136
  :covariant
137
137
  else
138
- raise
138
+ raise
139
139
  end
140
140
  type(ty, result: result, context: con)
141
141
  end
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.12.1"
2
+ VERSION = "0.15.0"
3
3
  end
@@ -60,6 +60,8 @@ module RBS
60
60
 
61
61
  def write(decls)
62
62
  [nil, *decls].each_cons(2) do |prev, decl|
63
+ raise unless decl
64
+
63
65
  preserve_empty_line(prev, decl)
64
66
  write_decl decl
65
67
  end
@@ -68,8 +70,8 @@ module RBS
68
70
  def write_decl(decl)
69
71
  case decl
70
72
  when AST::Declarations::Class
71
- super_class = if decl.super_class
72
- " < #{name_and_args(decl.super_class.name, decl.super_class.args)}"
73
+ super_class = if super_class = decl.super_class
74
+ " < #{name_and_args(super_class.name, super_class.args)}"
73
75
  end
74
76
  write_comment decl.comment
75
77
  write_annotation decl.annotations
@@ -77,6 +79,8 @@ module RBS
77
79
 
78
80
  indent do
79
81
  [nil, *decl.members].each_cons(2) do |prev, member|
82
+ raise unless member
83
+
80
84
  preserve_empty_line prev, member
81
85
  write_member member
82
86
  end
@@ -134,9 +138,6 @@ module RBS
134
138
 
135
139
  puts "end"
136
140
 
137
- when AST::Declarations::Extension
138
- RBS.logger.warn "Extension is ignored: #{decl.name}"
139
-
140
141
  end
141
142
  end
142
143
 
@@ -288,20 +289,29 @@ module RBS
288
289
  end
289
290
 
290
291
  def preserve_empty_line(prev, decl)
291
- return unless prev
292
+ # @type var decl: _Located
292
293
 
293
- decl = decl.comment if decl.respond_to?(:comment) && decl.comment
294
+ return unless prev
294
295
 
295
- # When the signature is not constructed by the parser,
296
- # it always inserts an empty line.
297
- if !prev.location || !decl.location
298
- puts
299
- return
296
+ if (_ = decl).respond_to?(:comment)
297
+ if comment = (_ = decl).comment
298
+ decl = comment
299
+ end
300
300
  end
301
301
 
302
- prev_end_line = prev.location.end_line
303
- start_line = decl.location.start_line
304
- if start_line - prev_end_line > 1
302
+ prev_loc = prev.location
303
+ decl_loc = decl.location
304
+
305
+ if prev_loc && decl_loc
306
+ prev_end_line = prev_loc.end_line
307
+ start_line = decl_loc.start_line
308
+
309
+ if start_line - prev_end_line > 1
310
+ puts
311
+ end
312
+ else
313
+ # When the signature is not constructed by the parser,
314
+ # it always inserts an empty line.
305
315
  puts
306
316
  end
307
317
  end
@@ -0,0 +1,21 @@
1
+ module RBS
2
+ class Constant
3
+ type constant_entry = Environment::ClassEntry
4
+ | Environment::ModuleEntry
5
+ | Environment::SingleEntry[TypeName, AST::Declarations::Constant]
6
+
7
+ attr_reader name: TypeName
8
+
9
+ attr_reader type: Types::t
10
+
11
+ attr_reader entry: constant_entry
12
+
13
+ def initialize: (name: TypeName, type: Types::t, entry: constant_entry) -> void
14
+
15
+ def ==: (untyped other) -> bool
16
+
17
+ alias eql? ==
18
+
19
+ def hash: () -> Integer
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ module RBS
2
+ class ConstantTable
3
+ attr_reader definition_builder: DefinitionBuilder
4
+ attr_reader constant_scopes_cache: Hash[TypeName, Array[Namespace]]
5
+ attr_reader resolver: TypeNameResolver
6
+ attr_reader env(): Environment
7
+
8
+ def initialize: (builder: DefinitionBuilder) -> void
9
+
10
+ def absolute_type: (Types::t, context: Array[Namespace]) -> Types::t
11
+
12
+ def absolute_type_name: (TypeName, context: Array[Namespace], location: Location?) -> TypeName
13
+
14
+ def name_to_constant: (TypeName) -> Constant?
15
+
16
+ def split_name: (TypeName) -> Array[Symbol]
17
+
18
+ def resolve_constant_reference: (TypeName name, context: Array[Namespace]) -> Constant?
19
+
20
+ def resolve_constant_reference_context: (Symbol, context: Array[Namespace]) -> Constant?
21
+
22
+ def resolve_constant_reference_inherit: (Symbol, scopes: Array[Namespace], ?no_object: boolish) -> Constant?
23
+
24
+ def constant_scopes: (TypeName) -> Array[Namespace]
25
+
26
+ def constant_scopes_module: (TypeName, scopes: Array[Namespace]) -> Array[Namespace]
27
+
28
+ def constant_scopes0: (TypeName, ?scopes: Array[Namespace]) -> Array[Namespace]
29
+ end
30
+ end