rbs 1.0.0.pre → 1.0.3

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +10 -4
  3. data/CHANGELOG.md +41 -6
  4. data/Gemfile +7 -2
  5. data/README.md +1 -1
  6. data/Rakefile +11 -4
  7. data/Steepfile +2 -1
  8. data/bin/annotate-with-rdoc +0 -4
  9. data/bin/test_runner.rb +4 -5
  10. data/core/encoding.rbs +1 -1
  11. data/core/file.rbs +4 -0
  12. data/core/io.rbs +81 -5
  13. data/core/kernel.rbs +56 -56
  14. data/core/module.rbs +43 -2
  15. data/core/unbound_method.rbs +16 -0
  16. data/docs/CONTRIBUTING.md +2 -2
  17. data/docs/stdlib.md +50 -12
  18. data/docs/syntax.md +0 -17
  19. data/goodcheck.yml +3 -3
  20. data/lib/rbs/ast/declarations.rb +0 -47
  21. data/lib/rbs/definition_builder.rb +102 -64
  22. data/lib/rbs/definition_builder/ancestor_builder.rb +52 -3
  23. data/lib/rbs/environment.rb +1 -7
  24. data/lib/rbs/environment_loader.rb +7 -3
  25. data/lib/rbs/errors.rb +22 -57
  26. data/lib/rbs/parser.rb +1003 -1027
  27. data/lib/rbs/parser.y +12 -21
  28. data/lib/rbs/prototype/rb.rb +18 -4
  29. data/lib/rbs/prototype/runtime.rb +30 -14
  30. data/lib/rbs/test/hook.rb +7 -6
  31. data/lib/rbs/test/setup_helper.rb +0 -1
  32. data/lib/rbs/types.rb +6 -2
  33. data/lib/rbs/version.rb +1 -1
  34. data/lib/rbs/writer.rb +4 -3
  35. data/rbs.gemspec +1 -0
  36. data/sig/ancestor_builder.rbs +98 -0
  37. data/sig/declarations.rbs +4 -16
  38. data/sig/definition_builder.rbs +17 -71
  39. data/sig/errors.rbs +141 -2
  40. data/sig/method_builder.rbs +71 -0
  41. data/sig/substitution.rbs +3 -0
  42. data/sig/types.rbs +1 -15
  43. data/stdlib/csv/0/csv.rbs +3 -0
  44. data/stdlib/fileutils/0/fileutils.rbs +585 -0
  45. data/stdlib/pathname/0/pathname.rbs +2 -2
  46. data/stdlib/prettyprint/0/prettyprint.rbs +366 -0
  47. data/stdlib/prime/0/prime.rbs +6 -0
  48. data/stdlib/securerandom/0/securerandom.rbs +2 -0
  49. data/stdlib/uri/0/common.rbs +1 -1
  50. metadata +10 -7
  51. data/core/data.rbs +0 -5
@@ -259,7 +259,7 @@ class Module < Object
259
259
  # or method `code' for Thing:Class
260
260
  #
261
261
  def class_eval: (String arg0, ?String filename, ?Integer lineno) -> untyped
262
- | [U] (untyped arg0) { (untyped m) -> U } -> U
262
+ | [U] { (self m) -> U } -> U
263
263
 
264
264
  # Evaluates the given block in the context of the class/module. The method
265
265
  # defined in the block will belong to the receiver. Any arguments passed to the
@@ -443,6 +443,47 @@ class Module < Object
443
443
  #
444
444
  def const_set: (Symbol | String arg0, untyped arg1) -> untyped
445
445
 
446
+ # Returns the Ruby source filename and line number containing first definition
447
+ # of constant specified. If the named constant is not found, `nil` is returned.
448
+ # If the constant is found, but its source location can not be extracted
449
+ # (constant is defined in C code), empty array is returned.
450
+ #
451
+ # *inherit* specifies whether to lookup in `mod.ancestors` (`true` by default).
452
+ #
453
+ # # test.rb:
454
+ # class A
455
+ # C1 = 1
456
+ # end
457
+ #
458
+ # module M
459
+ # C2 = 2
460
+ # end
461
+ #
462
+ # class B < A
463
+ # include M
464
+ # C3 = 3
465
+ # end
466
+ #
467
+ # class A # continuation of A definition
468
+ # end
469
+ #
470
+ # p B.const_source_location('C3') # => ["test.rb", 11]
471
+ # p B.const_source_location('C2') # => ["test.rb", 6]
472
+ # p B.const_source_location('C1') # => ["test.rb", 2]
473
+ #
474
+ # p B.const_source_location('C2', false) # => nil -- don't lookup in ancestors
475
+ #
476
+ # p Object.const_source_location('B') # => ["test.rb", 9]
477
+ # p Object.const_source_location('A') # => ["test.rb", 1] -- note it is first entry, not "continuation"
478
+ #
479
+ # p B.const_source_location('A') # => ["test.rb", 1] -- because Object is in ancestors
480
+ # p M.const_source_location('A') # => ["test.rb", 1] -- Object is not ancestor, but additionally checked for modules
481
+ #
482
+ # p Object.const_source_location('A::C1') # => ["test.rb", 2] -- nesting is supported
483
+ # p Object.const_source_location('String') # => [] -- constant is defined in C code
484
+ #
485
+ def const_source_location: (Symbol | String name, ?boolish inherit) -> ([String, Integer] | [ ] | nil)
486
+
446
487
  # Returns an array of the names of the constants accessible in *mod*. This
447
488
  # includes the names of constants in any included modules (example at start of
448
489
  # section), unless the *inherit* parameter is set to `false`.
@@ -752,7 +793,7 @@ class Module < Object
752
793
  # or method `code' for Thing:Class
753
794
  #
754
795
  def module_eval: (String arg0, ?String filename, ?Integer lineno) -> untyped
755
- | [U] (untyped arg0) { (untyped m) -> U } -> U
796
+ | [U] { (self m) -> U } -> U
756
797
 
757
798
  # Evaluates the given block in the context of the class/module. The method
758
799
  # defined in the block will belong to the receiver. Any arguments passed to the
@@ -150,4 +150,20 @@ class UnboundMethod
150
150
  # if there is no method on superclass.
151
151
  #
152
152
  def super_method: () -> UnboundMethod?
153
+
154
+ # Returns the original name of the method.
155
+ #
156
+ # class C
157
+ # def foo; end
158
+ # alias bar foo
159
+ # end
160
+ # C.instance_method(:bar).original_name # => :foo
161
+ #
162
+ def original_name: () -> Symbol
163
+
164
+ # Bind *umeth* to *recv* and then invokes the method with the specified
165
+ # arguments. This is semantically equivalent to `umeth.bind(recv).call(args,
166
+ # ...)`.
167
+ #
168
+ def bind_call: (untyped recv, *untyped args) ?{ (*untyped) -> untyped } -> untyped
153
169
  end
@@ -49,12 +49,12 @@ You may find the *Good for first contributor* column where you can find some cla
49
49
  * `--merge` tells to use the method types in RBS if exists.
50
50
  * `rbs prototype runtime --merge --method-owner=Numeric Integer`
51
51
  * You can use --method-owner if you want to print method of other classes too, for documentation purpose.
52
- * `bin/annotate-with-rdoc stdlib/builtin/string.rbs`
52
+ * `bin/annotate-with-rdoc core/string.rbs`
53
53
  * Write comments using RDoc.
54
54
  * It contains arglists section, but I don't think we should have it in RBS files.
55
55
  * `bin/query-rdoc String#initialize`
56
56
  * Print RDoc documents in the format you can copy-and-paste to RBS.
57
- * `bin/sort stdlib/builtin/string.rbs`
57
+ * `bin/sort core/string.rbs`
58
58
  * Sort declarations members in RBS files.
59
59
  * `rbs validate -r LIB`
60
60
  Validate the syntax and some of the semantics.
@@ -11,7 +11,7 @@ The typical steps of writing signatures will be like the following:
11
11
 
12
12
  ## Signatures
13
13
 
14
- Signatures for standard libraries are located in `stdlib` directory. `stdlib/builtin` is for builtin libraries. Other libraries have directories like `stdlib/set` or `stdlib/pathname`.
14
+ Signatures for builtin libraries are located in `core` directory. Also, signatures for standard libraries are located in `stdlib` directory.
15
15
 
16
16
  To write signatures see [syntax guide](syntax.md).
17
17
 
@@ -118,23 +118,61 @@ It generates `test/stdlib/[class_name]_test.rb`.
118
118
  The test scripts would look like the following:
119
119
 
120
120
  ```rb
121
- class StringTest < StdlibTest
122
- target String
121
+ class StringSingletonTest < Test::Unit::TestCase
122
+ include TypeAssertions
123
+
124
+ testing "singleton(::String)"
125
+
126
+ def test_initialize
127
+ assert_send_type "() -> String",
128
+ String, :new
129
+ assert_send_type "(String) -> String",
130
+ String, :new, ""
131
+ assert_send_type "(String, encoding: Encoding) -> String",
132
+ String, :new, "", encoding: Encoding::ASCII_8BIT
133
+ assert_send_type "(String, encoding: Encoding, capacity: Integer) -> String",
134
+ String, :new, "", encoding: Encoding::ASCII_8BIT, capacity: 123
135
+ assert_send_type "(encoding: Encoding, capacity: Integer) -> String",
136
+ String, :new, encoding: Encoding::ASCII_8BIT, capacity: 123
137
+ assert_send_type "(ToStr) -> String",
138
+ String, :new, ToStr.new("")
139
+ assert_send_type "(encoding: ToStr) -> String",
140
+ String, :new, encoding: ToStr.new('Shift_JIS')
141
+ assert_send_type "(capacity: ToInt) -> String",
142
+ String, :new, capacity: ToInt.new(123)
143
+ end
144
+ end
145
+
146
+ class StringTest < Test::Unit::TestCase
147
+ include TypeAssertions
148
+
149
+ # library "pathname", "set", "securerandom" # Declare library signatures to load
150
+ testing "::String"
123
151
 
124
152
  def test_gsub
125
- s = "string"
126
- s.gsub(/./, "")
127
- s.gsub("a", "b")
128
- s.gsub(/./) {|x| "" }
129
- s.gsub(/./, {"foo" => "bar"})
130
- s.gsub(/./)
131
- s.gsub("")
153
+ assert_send_type "(Regexp, String) -> String",
154
+ "string", :gsub, /./, ""
155
+ assert_send_type "(String, String) -> String",
156
+ "string", :gsub, "a", "b"
157
+ assert_send_type "(Regexp) { (String) -> String } -> String",
158
+ "string", :gsub, /./ do |x| "" end
159
+ assert_send_type "(Regexp) { (String) -> ToS } -> String",
160
+ "string", :gsub, /./ do |x| ToS.new("") end
161
+ assert_send_type "(Regexp, Hash[String, String]) -> String",
162
+ "string", :gsub, /./, {"foo" => "bar"}
163
+ assert_send_type "(Regexp) -> Enumerator[String, self]",
164
+ "string", :gsub, /./
165
+ assert_send_type "(String) -> Enumerator[String, self]",
166
+ "string", :gsub, ""
167
+ assert_send_type "(ToStr, ToStr) -> String",
168
+ "string", :gsub, ToStr.new("a"), ToStr.new("b")
132
169
  end
133
170
  end
134
171
  ```
135
172
 
136
- You need two method calls, `target` and `using`.
137
- `target` method call tells which class is the subject of the class.
173
+ You need include `TypeAssertions` which provide useful methods for you.
174
+ `testing` method call tells which class is the subject of the class.
175
+ `assert_send_type` method call asserts to be valid types and confirms to be able to execute without exceptions.
138
176
  And you write the sample programs which calls all of the patterns of overloads.
139
177
 
140
178
  Note that the instrumentation is based on refinements and you need to write all method calls in the unit class definitions.
@@ -531,23 +531,6 @@ interface _Foo
531
531
  end
532
532
  ```
533
533
 
534
- ### Extension declaration
535
-
536
- Extension is to model _open class_.
537
-
538
- ```
539
- extension Kernel (Pathname)
540
- def Pathname: (String) -> Pathname
541
- end
542
-
543
- extension Array[A] (ActiveSupport)
544
- def to: (Integer) -> Array[A]
545
- def from: (Integer) -> Array[A]
546
- def second: () -> A?
547
- def third: () -> A?
548
- end
549
- ```
550
-
551
534
  ### Type alias declaration
552
535
 
553
536
  You can declare an alias of types.
@@ -3,7 +3,7 @@ rules:
3
3
  pattern: 💪👽🚨
4
4
  message: Do you forget to delete `arglists` section?
5
5
  glob:
6
- - "stdlib/**/*.rbs"
6
+ - "{core,stdlib}/**/*.rbs"
7
7
  fail:
8
8
  - |
9
9
  # arglists 💪👽🚨 << Delete this section
@@ -22,7 +22,7 @@ rules:
22
22
  justification:
23
23
  - Documents (comments) may contain that pattern.
24
24
  glob:
25
- - "stdlib/**/*.rbs"
25
+ - "{core,stdlib}/**/*.rbs"
26
26
  fail:
27
27
  - "def `send`: (String | Symbol arg0, *untyped arg1) -> untyped"
28
28
  pass:
@@ -71,7 +71,7 @@ rules:
71
71
  end
72
72
  pass:
73
73
  - |
74
- class IntegerTest < Minitest::Test
74
+ class IntegerTest < Test::Unit::TestCase
75
75
  include TypeAssertions
76
76
 
77
77
  testing "Integer"
@@ -300,53 +300,6 @@ module RBS
300
300
  end
301
301
  end
302
302
 
303
- class Extension < Base
304
- attr_reader :name
305
- attr_reader :type_params
306
- attr_reader :extension_name
307
- attr_reader :members
308
- attr_reader :annotations
309
- attr_reader :location
310
- attr_reader :comment
311
-
312
- def initialize(name:, type_params:, extension_name:, members:, annotations:, location:, comment:)
313
- @name = name
314
- @type_params = type_params
315
- @extension_name = extension_name
316
- @members = members
317
- @annotations = annotations
318
- @location = location
319
- @comment = comment
320
- end
321
-
322
- def ==(other)
323
- other.is_a?(Extension) &&
324
- other.name == name &&
325
- other.type_params == type_params &&
326
- other.extension_name == extension_name &&
327
- other.members == members
328
- end
329
-
330
- alias eql? ==
331
-
332
- def hash
333
- self.class.hash ^ name.hash ^ type_params.hash ^ extension_name.hash ^ members.hash
334
- end
335
-
336
- def to_json(*a)
337
- {
338
- declaration: :extension,
339
- name: name,
340
- type_params: type_params,
341
- extension_name: extension_name,
342
- members: members,
343
- annotations: annotations,
344
- location: location,
345
- comment: comment
346
- }.to_json(*a)
347
- end
348
- end
349
-
350
303
  class Interface < Base
351
304
  attr_reader :name
352
305
  attr_reader :type_params
@@ -44,7 +44,8 @@ module RBS
44
44
 
45
45
  ancestors = ancestor_builder.interface_ancestors(type_name)
46
46
  Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
47
- ancestor_builder.one_interface_ancestors(type_name).included_interfaces.each do |mod|
47
+ included_interfaces = ancestor_builder.one_interface_ancestors(type_name).included_interfaces or raise
48
+ included_interfaces.each do |mod|
48
49
  defn = build_interface(mod.name)
49
50
  subst = Substitution.build(defn.type_params, mod.args)
50
51
 
@@ -54,13 +55,17 @@ module RBS
54
55
  end
55
56
 
56
57
  methods = method_builder.build_interface(type_name)
58
+ one_ancestors = ancestor_builder.one_interface_ancestors(type_name)
59
+
60
+ validate_type_params(definition, methods: methods, ancestors: one_ancestors)
61
+
57
62
  methods.each do |defn|
58
- method = case defn.original
63
+ method = case original = defn.original
59
64
  when AST::Members::MethodDefinition
60
- defs = defn.original.types.map do |method_type|
65
+ defs = original.types.map do |method_type|
61
66
  Definition::Method::TypeDef.new(
62
67
  type: method_type,
63
- member: defn.original,
68
+ member: original,
64
69
  defined_in: type_name,
65
70
  implemented_in: nil
66
71
  )
@@ -73,15 +78,15 @@ module RBS
73
78
  alias_of: nil
74
79
  )
75
80
  when AST::Members::Alias
76
- unless definition.methods.key?(defn.original.old_name)
81
+ unless definition.methods.key?(original.old_name)
77
82
  raise UnknownMethodAliasError.new(
78
- original_name: defn.original.old_name,
79
- aliased_name: defn.original.new_name,
80
- location: defn.original.location
83
+ original_name: original.old_name,
84
+ aliased_name: original.new_name,
85
+ location: original.location
81
86
  )
82
87
  end
83
88
 
84
- original_method = definition.methods[defn.original.old_name]
89
+ original_method = definition.methods[original.old_name]
85
90
  Definition::Method.new(
86
91
  super_method: nil,
87
92
  defs: original_method.defs.map do |defn|
@@ -101,10 +106,14 @@ module RBS
101
106
  end
102
107
 
103
108
  definition.methods[defn.name]
109
+
110
+ when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
111
+ raise
112
+
104
113
  end
105
114
 
106
115
  defn.overloads.each do |overload|
107
- defs = overload.types.map do |method_type|
116
+ overload_defs = overload.types.map do |method_type|
108
117
  Definition::Method::TypeDef.new(
109
118
  type: method_type,
110
119
  member: overload,
@@ -113,7 +122,7 @@ module RBS
113
122
  )
114
123
  end
115
124
 
116
- method.defs.unshift(*defs)
125
+ method.defs.unshift(*overload_defs)
117
126
  end
118
127
 
119
128
  definition.methods[defn.name] = method
@@ -122,8 +131,8 @@ module RBS
122
131
  end
123
132
  end
124
133
 
125
- def build_instance(type_name)
126
- try_cache(type_name, cache: instance_cache) do
134
+ def build_instance(type_name, no_self_types: false)
135
+ try_cache(type_name, cache: instance_cache, key: [type_name, no_self_types]) do
127
136
  entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
128
137
  ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
129
138
 
@@ -141,31 +150,39 @@ module RBS
141
150
  validate_type_params definition, methods: methods, ancestors: one_ancestors
142
151
 
143
152
  if super_class = one_ancestors.super_class
144
- defn = build_instance(super_class.name)
145
- merge_definition(src: defn,
146
- dest: definition,
147
- subst: Substitution.build(defn.type_params, super_class.args),
148
- keep_super: true)
153
+ case super_class
154
+ when Definition::Ancestor::Instance
155
+ build_instance(super_class.name).yield_self do |defn|
156
+ merge_definition(src: defn,
157
+ dest: definition,
158
+ subst: Substitution.build(defn.type_params, super_class.args),
159
+ keep_super: true)
160
+ end
161
+ else
162
+ raise
163
+ end
149
164
  end
150
165
 
151
- if one_ancestors.self_types
152
- one_ancestors.self_types.each do |ans|
153
- defn = if ans.name.interface?
154
- build_interface(ans.name)
155
- else
156
- build_instance(ans.name)
157
- end
166
+ if self_types = one_ancestors.self_types
167
+ unless no_self_types
168
+ self_types.each do |ans|
169
+ defn = if ans.name.interface?
170
+ build_interface(ans.name)
171
+ else
172
+ build_instance(ans.name)
173
+ end
158
174
 
159
- # Successor interface method overwrites.
160
- merge_definition(src: defn,
161
- dest: definition,
162
- subst: Substitution.build(defn.type_params, ans.args),
163
- keep_super: true)
175
+ # Successor interface method overwrites.
176
+ merge_definition(src: defn,
177
+ dest: definition,
178
+ subst: Substitution.build(defn.type_params, ans.args),
179
+ keep_super: true)
180
+ end
164
181
  end
165
182
  end
166
183
 
167
- one_ancestors.included_modules.each do |mod|
168
- defn = build_instance(mod.name)
184
+ one_ancestors.each_included_module do |mod|
185
+ defn = build_instance(mod.name, no_self_types: true)
169
186
  merge_definition(src: defn,
170
187
  dest: definition,
171
188
  subst: Substitution.build(defn.type_params, mod.args))
@@ -173,16 +190,20 @@ module RBS
173
190
 
174
191
  interface_methods = {}
175
192
 
176
- one_ancestors.included_interfaces.each do |mod|
193
+ one_ancestors.each_included_interface do |mod|
177
194
  defn = build_interface(mod.name)
178
195
  subst = Substitution.build(defn.type_params, mod.args)
179
196
 
180
197
  defn.methods.each do |name, method|
181
198
  if interface_methods.key?(name)
199
+ include_member = mod.source
200
+
201
+ raise unless include_member.is_a?(AST::Members::Include)
202
+
182
203
  raise DuplicatedInterfaceMethodDefinitionError.new(
183
204
  type: self_type,
184
205
  method_name: name,
185
- member: mod.source
206
+ member: include_member
186
207
  )
187
208
  end
188
209
 
@@ -221,7 +242,7 @@ module RBS
221
242
  end
222
243
  end
223
244
 
224
- one_ancestors.prepended_modules.each do |mod|
245
+ one_ancestors.each_prepended_module do |mod|
225
246
  defn = build_instance(mod.name)
226
247
  merge_definition(src: defn,
227
248
  dest: definition,
@@ -261,24 +282,28 @@ module RBS
261
282
  end
262
283
  end
263
284
 
264
- one_ancestors.extended_modules.each do |mod|
265
- defn = build_instance(mod.name)
266
- merge_definition(src: defn,
285
+ one_ancestors.each_extended_module do |mod|
286
+ mod_defn = build_instance(mod.name, no_self_types: true)
287
+ merge_definition(src: mod_defn,
267
288
  dest: definition,
268
- subst: Substitution.build(defn.type_params, mod.args))
289
+ subst: Substitution.build(mod_defn.type_params, mod.args))
269
290
  end
270
291
 
271
292
  interface_methods = {}
272
- one_ancestors.extended_interfaces.each do |mod|
273
- defn = build_interface(mod.name)
274
- subst = Substitution.build(defn.type_params, mod.args)
293
+ one_ancestors.each_extended_interface do |mod|
294
+ mod_defn = build_interface(mod.name)
295
+ subst = Substitution.build(mod_defn.type_params, mod.args)
275
296
 
276
- defn.methods.each do |name, method|
297
+ mod_defn.methods.each do |name, method|
277
298
  if interface_methods.key?(name)
299
+ src_member = mod.source
300
+
301
+ raise unless src_member.is_a?(AST::Members::Extend)
302
+
278
303
  raise DuplicatedInterfaceMethodDefinitionError.new(
279
304
  type: self_type,
280
305
  method_name: name,
281
- member: mod.source
306
+ member: src_member
282
307
  )
283
308
  end
284
309
 
@@ -418,6 +443,20 @@ module RBS
418
443
  end
419
444
  end
420
445
 
446
+ def source_location(source, decl)
447
+ case source
448
+ when nil
449
+ decl.location
450
+ when :super
451
+ case decl
452
+ when AST::Declarations::Class
453
+ decl.super_class&.location
454
+ end
455
+ else
456
+ source.location
457
+ end
458
+ end
459
+
421
460
  def validate_type_params(definition, ancestors:, methods:)
422
461
  type_params = definition.type_params_decl
423
462
 
@@ -429,19 +468,17 @@ module RBS
429
468
  when Definition::Ancestor::Instance
430
469
  result = calculator.in_inherit(name: ancestor.name, args: ancestor.args, variables: param_names)
431
470
  validate_params_with(type_params, result: result) do |param|
432
- location = case source = ancestor.source
433
- when nil
434
- definition.entry.primary.decl.location
435
- when :super
436
- definition.entry.primary.decl.super_class.location
437
- else
438
- source.location
439
- end
471
+ decl = case entry = definition.entry
472
+ when Environment::ModuleEntry, Environment::ClassEntry
473
+ entry.primary.decl
474
+ when Environment::SingleEntry
475
+ entry.decl
476
+ end
440
477
 
441
478
  raise InvalidVarianceAnnotationError.new(
442
479
  type_name: definition.type_name,
443
480
  param: param,
444
- location: location
481
+ location: source_location(ancestor.source, decl)
445
482
  )
446
483
  end
447
484
  end
@@ -481,8 +518,6 @@ module RBS
481
518
  nil
482
519
  when nil
483
520
  nil
484
- else
485
- raise
486
521
  end
487
522
 
488
523
  if method_types
@@ -537,11 +572,11 @@ module RBS
537
572
  if interface_methods.key?(method_name)
538
573
  interface_method = interface_methods[method_name]
539
574
 
540
- if method_def.original
575
+ if original = method_def.original
541
576
  raise DuplicatedMethodDefinitionError.new(
542
577
  type: definition.self_type,
543
578
  method_name: method_name,
544
- members: [method_def.original]
579
+ members: [original]
545
580
  )
546
581
  end
547
582
 
@@ -561,6 +596,7 @@ module RBS
561
596
  )
562
597
  end
563
598
 
599
+ # @type var accessibility: RBS::Definition::accessibility
564
600
  accessibility = if method_name == :initialize
565
601
  :private
566
602
  else
@@ -640,7 +676,7 @@ module RBS
640
676
  end
641
677
 
642
678
  method_def.overloads.each do |overload|
643
- defs = overload.types.map do |method_type|
679
+ type_defs = overload.types.map do |method_type|
644
680
  Definition::Method::TypeDef.new(
645
681
  type: method_type,
646
682
  member: overload,
@@ -649,7 +685,7 @@ module RBS
649
685
  )
650
686
  end
651
687
 
652
- method.defs.unshift(*defs)
688
+ method.defs.unshift(*type_defs)
653
689
  end
654
690
 
655
691
  definition.methods[method_name] = method
@@ -717,8 +753,10 @@ module RBS
717
753
  )
718
754
  end
719
755
 
720
- def try_cache(type_name, cache:)
721
- cached = _ = cache[type_name]
756
+ def try_cache(type_name, cache:, key: type_name)
757
+ # @type var cc: Hash[untyped, Definition | false | nil]
758
+ cc = _ = cache
759
+ cached = cc[key]
722
760
 
723
761
  case cached
724
762
  when Definition
@@ -726,11 +764,11 @@ module RBS
726
764
  when false
727
765
  raise
728
766
  when nil
729
- cache[type_name] = false
767
+ cc[key] = false
730
768
  begin
731
- cache[type_name] = yield
769
+ cc[key] = yield
732
770
  rescue => ex
733
- cache.delete(type_name)
771
+ cc.delete(key)
734
772
  raise ex
735
773
  end
736
774
  else