rbs 0.9.0 → 0.12.1

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +9 -9
  3. data/CHANGELOG.md +31 -0
  4. data/Gemfile +1 -0
  5. data/README.md +1 -1
  6. data/Rakefile +16 -6
  7. data/Steepfile +28 -0
  8. data/bin/steep +4 -0
  9. data/bin/test_runner.rb +7 -5
  10. data/docs/syntax.md +14 -1
  11. data/lib/rbs/ast/comment.rb +7 -1
  12. data/lib/rbs/ast/declarations.rb +15 -9
  13. data/lib/rbs/ast/members.rb +3 -8
  14. data/lib/rbs/buffer.rb +1 -1
  15. data/lib/rbs/cli.rb +62 -1
  16. data/lib/rbs/definition.rb +35 -16
  17. data/lib/rbs/definition_builder.rb +99 -68
  18. data/lib/rbs/environment.rb +24 -11
  19. data/lib/rbs/environment_loader.rb +55 -35
  20. data/lib/rbs/location.rb +1 -5
  21. data/lib/rbs/method_type.rb +5 -5
  22. data/lib/rbs/namespace.rb +14 -3
  23. data/lib/rbs/parser.y +2 -12
  24. data/lib/rbs/prototype/rb.rb +3 -5
  25. data/lib/rbs/prototype/rbi.rb +1 -4
  26. data/lib/rbs/prototype/runtime.rb +0 -4
  27. data/lib/rbs/substitution.rb +4 -3
  28. data/lib/rbs/test/hook.rb +1 -0
  29. data/lib/rbs/test/setup.rb +17 -12
  30. data/lib/rbs/test/setup_helper.rb +15 -0
  31. data/lib/rbs/test/tester.rb +59 -13
  32. data/lib/rbs/test/type_check.rb +43 -14
  33. data/lib/rbs/type_name.rb +18 -1
  34. data/lib/rbs/type_name_resolver.rb +10 -3
  35. data/lib/rbs/types.rb +27 -21
  36. data/lib/rbs/variance_calculator.rb +8 -5
  37. data/lib/rbs/version.rb +1 -1
  38. data/lib/rbs/writer.rb +7 -3
  39. data/sig/annotation.rbs +26 -0
  40. data/sig/buffer.rbs +28 -0
  41. data/sig/builtin_names.rbs +41 -0
  42. data/sig/comment.rbs +26 -0
  43. data/sig/declarations.rbs +202 -0
  44. data/sig/definition.rbs +129 -0
  45. data/sig/definition_builder.rbs +95 -0
  46. data/sig/environment.rbs +94 -0
  47. data/sig/environment_loader.rbs +4 -0
  48. data/sig/location.rbs +52 -0
  49. data/sig/members.rbs +160 -0
  50. data/sig/method_types.rbs +40 -0
  51. data/sig/namespace.rbs +124 -0
  52. data/sig/polyfill.rbs +3 -0
  53. data/sig/rbs.rbs +3 -0
  54. data/sig/substitution.rbs +39 -0
  55. data/sig/type_name_resolver.rbs +24 -0
  56. data/sig/typename.rbs +70 -0
  57. data/sig/types.rbs +361 -0
  58. data/sig/util.rbs +13 -0
  59. data/sig/variance_calculator.rbs +35 -0
  60. data/stdlib/bigdecimal/big_decimal.rbs +887 -0
  61. data/stdlib/bigdecimal/math/big_math.rbs +142 -0
  62. data/stdlib/builtin/array.rbs +2 -1
  63. data/stdlib/builtin/builtin.rbs +0 -3
  64. data/stdlib/builtin/hash.rbs +1 -1
  65. data/stdlib/builtin/math.rbs +26 -26
  66. data/stdlib/builtin/struct.rbs +9 -10
  67. data/stdlib/date/date.rbs +1056 -0
  68. data/stdlib/date/date_time.rbs +582 -0
  69. data/stdlib/forwardable/forwardable.rbs +204 -0
  70. data/stdlib/set/set.rbs +1 -1
  71. data/stdlib/uri/file.rbs +167 -0
  72. data/stdlib/uri/generic.rbs +875 -0
  73. data/stdlib/zlib/zlib.rbs +392 -0
  74. data/steep/Gemfile +3 -0
  75. data/steep/Gemfile.lock +55 -0
  76. metadata +39 -6
@@ -31,10 +31,11 @@ module RBS
31
31
  def apply(ty)
32
32
  case ty
33
33
  when Types::Variable
34
+ # @type var ty: Types::Variable
34
35
  mapping[ty.name] || ty
35
36
  when Types::Bases::Instance
36
- if instance_type
37
- instance_type
37
+ if t = instance_type
38
+ t
38
39
  else
39
40
  ty
40
41
  end
@@ -44,7 +45,7 @@ module RBS
44
45
  end
45
46
 
46
47
  def without(*vars)
47
- self.class.new.tap do |subst|
48
+ Substitution.new.tap do |subst|
48
49
  subst.mapping.merge!(mapping)
49
50
  vars.each do |var|
50
51
  subst.mapping.delete(var)
@@ -7,6 +7,7 @@ module RBS
7
7
  OPERATORS = {
8
8
  :== => "eqeq",
9
9
  :=== => "eqeqeq",
10
+ :!= => "noteq",
10
11
  :+ => "plus",
11
12
  :- => "minus",
12
13
  :* => "star",
@@ -9,21 +9,26 @@ logger = Logger.new(STDERR)
9
9
 
10
10
  begin
11
11
  opts = Shellwords.shellsplit(ENV["RBS_TEST_OPT"] || "-I sig")
12
- filter = ENV.fetch('RBS_TEST_TARGET').split(',').map! { |e| e.strip }
12
+ filter = ENV.fetch('RBS_TEST_TARGET', "").split(',').map! { |e| e.strip }
13
13
  skips = (ENV['RBS_TEST_SKIP'] || '').split(',').map! { |e| e.strip }
14
14
  RBS.logger_level = (ENV["RBS_TEST_LOGLEVEL"] || "info")
15
15
  sample_size = get_sample_size(ENV['RBS_TEST_SAMPLE_SIZE'] || '')
16
+ double_class = to_double_class(ENV['RBS_TEST_DOUBLE_SUITE'])
17
+ unchecked_classes = (ENV['RBS_TEST_UNCHECKED_CLASSES'] || '').split(',').map! { |unchecked_class| unchecked_class.strip }.push(*double_class)
16
18
  rescue InvalidSampleSizeError => exception
17
19
  RBS.logger.error exception.message
18
20
  exit 1
19
- rescue Exception => e
20
- raise e.message
21
+ end
22
+
23
+ if filter.empty?
21
24
  STDERR.puts "rbs/test/setup handles the following environment variables:"
22
25
  STDERR.puts " [REQUIRED] RBS_TEST_TARGET: test target class name, `Foo::Bar,Foo::Baz` for each class or `Foo::*` for all classes under `Foo`"
23
26
  STDERR.puts " [OPTIONAL] RBS_TEST_SKIP: skip testing classes"
24
27
  STDERR.puts " [OPTIONAL] RBS_TEST_OPT: options for signatures (`-r` for libraries or `-I` for signatures)"
25
28
  STDERR.puts " [OPTIONAL] RBS_TEST_LOGLEVEL: one of debug|info|warn|error|fatal (defaults to info)"
26
29
  STDERR.puts " [OPTIONAL] RBS_TEST_SAMPLE_SIZE: sets the amount of values in a collection to be type-checked (Set to `ALL` to type check all the values)"
30
+ STDERR.puts " [OPTIONAL] RBS_TEST_DOUBLE_SUITE: sets the double suite in use (currently supported: minitest | rspec)"
31
+ STDERR.puts " [OPTIONAL] RBS_TEST_UNCHECKED_CLASSES: sets the classes that would not be checked"
27
32
  exit 1
28
33
  end
29
34
 
@@ -50,16 +55,16 @@ end
50
55
 
51
56
  tester = RBS::Test::Tester.new(env: env)
52
57
 
58
+ module_name = Module.instance_method(:name)
59
+
53
60
  TracePoint.trace :end do |tp|
54
- class_name = tp.self.name&.yield_self {|name| to_absolute_typename name }
61
+ class_name = module_name.bind(tp.self).call&.yield_self {|name| to_absolute_typename name }
55
62
 
56
63
  if class_name
57
64
  if filter.any? {|f| match(to_absolute_typename(f).to_s, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
58
- if tester.checkers.none? {|hook| hook.klass == tp.self }
59
- if env.class_decls.key?(class_name)
60
- logger.info "Setting up hooks for #{class_name}"
61
- tester.install!(tp.self, sample_size: sample_size)
62
- end
65
+ if env.class_decls.key?(class_name)
66
+ logger.info "Setting up hooks for #{class_name}"
67
+ tester.install!(tp.self, sample_size: sample_size, unchecked_classes: unchecked_classes)
63
68
  end
64
69
  end
65
70
  end
@@ -67,8 +72,8 @@ end
67
72
 
68
73
  at_exit do
69
74
  if $!.nil? || $!.is_a?(SystemExit) && $!.success?
70
- logger.warn "No type checker was installed! " if tester.checkers.empty?
75
+ if tester.targets.empty?
76
+ logger.debug { "No type checker was installed!" }
77
+ end
71
78
  end
72
79
  end
73
-
74
-
@@ -24,6 +24,21 @@ module RBS
24
24
  int_size
25
25
  end
26
26
  end
27
+
28
+ def to_double_class(double_suite)
29
+ return nil unless double_suite
30
+
31
+ case double_suite.downcase.strip
32
+ when 'rspec'
33
+ ['::RSpec::Mocks::Double']
34
+ when 'minitest'
35
+ ['::Minitest::Mock']
36
+ else
37
+ RBS.logger.warn "Unknown test suite - defaults to nil"
38
+ nil
39
+ end
40
+ end
41
+
27
42
  end
28
43
  end
29
44
  end
@@ -2,11 +2,15 @@ module RBS
2
2
  module Test
3
3
  class Tester
4
4
  attr_reader :env
5
- attr_reader :checkers
5
+ attr_reader :targets
6
+ attr_reader :instance_testers
7
+ attr_reader :singleton_testers
6
8
 
7
9
  def initialize(env:)
8
10
  @env = env
9
- @checkers = []
11
+ @targets = []
12
+ @instance_testers = {}
13
+ @singleton_testers = {}
10
14
  end
11
15
 
12
16
  def factory
@@ -17,34 +21,74 @@ module RBS
17
21
  @builder ||= DefinitionBuilder.new(env: env)
18
22
  end
19
23
 
20
- def install!(klass, sample_size:)
24
+ def skip_method?(type_name, method)
25
+ if method.implemented_in == type_name
26
+ if method.annotations.any? {|a| a.string == "rbs:test:skip" }
27
+ :skip
28
+ else
29
+ false
30
+ end
31
+ else
32
+ if method.annotations.any? {|a| a.string == "rbs:test:target" }
33
+ false
34
+ else
35
+ :implemented_in
36
+ end
37
+ end
38
+ end
39
+
40
+ def install!(klass, sample_size:, unchecked_classes:)
21
41
  RBS.logger.info { "Installing runtime type checker in #{klass}..." }
22
42
 
23
43
  type_name = factory.type_name(klass.name).absolute!
24
44
 
25
45
  builder.build_instance(type_name).tap do |definition|
26
46
  instance_key = new_key(type_name, "InstanceChecker")
27
- Observer.register(instance_key, MethodCallTester.new(klass, builder, definition, kind: :instance, sample_size: sample_size))
47
+ tester, set = instance_testers[klass] ||= [
48
+ MethodCallTester.new(klass, builder, definition, kind: :instance, sample_size: sample_size, unchecked_classes: unchecked_classes),
49
+ Set[]
50
+ ]
51
+ Observer.register(instance_key, tester)
28
52
 
29
53
  definition.methods.each do |name, method|
30
- if method.implemented_in == type_name
31
- RBS.logger.info { "Setting up method hook in ##{name}..." }
32
- Hook.hook_instance_method klass, name, key: instance_key
54
+ if reason = skip_method?(type_name, method)
55
+ unless reason == :implemented_in
56
+ RBS.logger.info { "Skipping ##{name} because of `#{reason}`..." }
57
+ end
58
+ else
59
+ if klass.instance_methods(false).include?(name) && !set.include?(name)
60
+ RBS.logger.info { "Setting up method hook in ##{name}..." }
61
+ Hook.hook_instance_method klass, name, key: instance_key
62
+ set << name
63
+ end
33
64
  end
34
65
  end
35
66
  end
36
67
 
37
68
  builder.build_singleton(type_name).tap do |definition|
38
69
  singleton_key = new_key(type_name, "SingletonChecker")
39
- Observer.register(singleton_key, MethodCallTester.new(klass.singleton_class, builder, definition, kind: :singleton, sample_size: sample_size))
70
+ tester, set = singleton_testers[klass] ||= [
71
+ MethodCallTester.new(klass.singleton_class, builder, definition, kind: :singleton, sample_size: sample_size, unchecked_classes: unchecked_classes),
72
+ Set[]
73
+ ]
74
+ Observer.register(singleton_key, tester)
40
75
 
41
76
  definition.methods.each do |name, method|
42
- if method.implemented_in == type_name || name == :new
43
- RBS.logger.info { "Setting up method hook in .#{name}..." }
44
- Hook.hook_singleton_method klass, name, key: singleton_key
77
+ if reason = skip_method?(type_name, method)
78
+ unless reason == :implemented_in
79
+ RBS.logger.info { "Skipping .#{name} because of `#{reason}`..." }
80
+ end
81
+ else
82
+ if klass.methods(false).include?(name) && !set.include?(name)
83
+ RBS.logger.info { "Setting up method hook in .#{name}..." }
84
+ Hook.hook_singleton_method klass, name, key: singleton_key
85
+ set << name
86
+ end
45
87
  end
46
88
  end
47
89
  end
90
+
91
+ targets << klass
48
92
  end
49
93
 
50
94
  def new_key(type_name, prefix)
@@ -67,13 +111,15 @@ module RBS
67
111
  attr_reader :builder
68
112
  attr_reader :kind
69
113
  attr_reader :sample_size
114
+ attr_reader :unchecked_classes
70
115
 
71
- def initialize(self_class, builder, definition, kind:, sample_size:)
116
+ def initialize(self_class, builder, definition, kind:, sample_size:, unchecked_classes:)
72
117
  @self_class = self_class
73
118
  @definition = definition
74
119
  @builder = builder
75
120
  @kind = kind
76
121
  @sample_size = sample_size
122
+ @unchecked_classes = unchecked_classes
77
123
  end
78
124
 
79
125
  def env
@@ -81,7 +127,7 @@ module RBS
81
127
  end
82
128
 
83
129
  def check
84
- @check ||= TypeCheck.new(self_class: self_class, builder: builder, sample_size: sample_size)
130
+ @check ||= TypeCheck.new(self_class: self_class, builder: builder, sample_size: sample_size, unchecked_classes: unchecked_classes)
85
131
  end
86
132
 
87
133
  def format_method_name(name)
@@ -4,13 +4,18 @@ module RBS
4
4
  attr_reader :self_class
5
5
  attr_reader :builder
6
6
  attr_reader :sample_size
7
+ attr_reader :unchecked_classes
8
+
9
+ attr_reader :const_cache
7
10
 
8
11
  DEFAULT_SAMPLE_SIZE = 100
9
12
 
10
- def initialize(self_class:, builder:, sample_size:)
13
+ def initialize(self_class:, builder:, sample_size:, unchecked_classes:)
11
14
  @self_class = self_class
12
15
  @builder = builder
13
16
  @sample_size = sample_size
17
+ @unchecked_classes = unchecked_classes.uniq
18
+ @const_cache = {}
14
19
  end
15
20
 
16
21
  def overloaded_call(method, method_name, call, errors:)
@@ -179,11 +184,37 @@ module RBS
179
184
  end
180
185
  end
181
186
 
182
- def sample(array)
183
- sample_size && (array.size > sample_size) ? array.sample(sample_size) : array
187
+ def each_sample(array, &block)
188
+ if block
189
+ if sample_size && array.size > sample_size
190
+ if sample_size > 0
191
+ size = array.size
192
+ sample_size.times do
193
+ yield array[rand(size)]
194
+ end
195
+ end
196
+ else
197
+ array.each(&block)
198
+ end
199
+ else
200
+ enum_for :each_sample, array
201
+ end
202
+ end
203
+
204
+ def get_class(type_name)
205
+ const_cache[type_name] ||= Object.const_get(type_name.to_s)
206
+ end
207
+
208
+ def is_double?(value)
209
+ unchecked_classes.any? { |unchecked_class| Test.call(value, IS_AP, Object.const_get(unchecked_class))}
184
210
  end
185
211
 
186
212
  def value(val, type)
213
+ if is_double?(val)
214
+ RBS.logger.info("A double (#{val.inspect}) is detected!")
215
+ return true
216
+ end
217
+
187
218
  case type
188
219
  when Types::Bases::Any
189
220
  true
@@ -204,17 +235,14 @@ module RBS
204
235
  when Types::Bases::Instance
205
236
  Test.call(val, IS_AP, self_class)
206
237
  when Types::ClassInstance
207
- klass = Object.const_get(type.name.to_s)
238
+ klass = get_class(type.name)
208
239
  case
209
240
  when klass == ::Array
210
- Test.call(val, IS_AP, klass) && sample(val).yield_self do |val|
211
- val.all? {|v| value(v, type.args[0]) }
212
- end
241
+ Test.call(val, IS_AP, klass) && each_sample(val).all? {|v| value(v, type.args[0]) }
213
242
  when klass == ::Hash
214
- Test.call(val, IS_AP, klass) && sample(val.keys).yield_self do |keys|
215
- values = val.values_at(*keys)
216
- keys.all? {|key| value(key, type.args[0]) } && values.all? {|v| value(v, type.args[1]) }
217
- end
243
+ Test.call(val, IS_AP, klass) && each_sample(val.keys).all? do |key|
244
+ value(key, type.args[0]) && value(val[key], type.args[1])
245
+ end
218
246
  when klass == ::Range
219
247
  Test.call(val, IS_AP, klass) && value(val.begin, type.args[0]) && value(val.end, type.args[0])
220
248
  when klass == ::Enumerator
@@ -235,7 +263,7 @@ module RBS
235
263
  end
236
264
  end
237
265
 
238
- sample(values).all? do |v|
266
+ each_sample(values).all? do |v|
239
267
  if v.size == 1
240
268
  # Only one block argument.
241
269
  value(v[0], type.args[0]) || value(v, type.args[0])
@@ -253,7 +281,7 @@ module RBS
253
281
  Test.call(val, IS_AP, klass)
254
282
  end
255
283
  when Types::ClassSingleton
256
- klass = Object.const_get(type.name.to_s)
284
+ klass = get_class(type.name)
257
285
  val == klass
258
286
  when Types::Interface
259
287
  methods = Set.new(Test.call(val, METHODS))
@@ -278,7 +306,8 @@ module RBS
278
306
  Test.call(val, IS_AP, ::Array) &&
279
307
  type.types.map.with_index {|ty, index| value(val[index], ty) }.all?
280
308
  when Types::Record
281
- Test::call(val, IS_AP, ::Hash)
309
+ Test::call(val, IS_AP, ::Hash) &&
310
+ type.fields.map {|key, type| value(val[key], type) }.all?
282
311
  when Types::Proc
283
312
  Test::call(val, IS_AP, ::Proc)
284
313
  else
@@ -1,3 +1,4 @@
1
+
1
2
  module RBS
2
3
  class TypeName
3
4
  attr_reader :namespace
@@ -14,13 +15,15 @@ module RBS
14
15
  :alias
15
16
  when "_"
16
17
  :interface
18
+ else
19
+ raise
17
20
  end
18
21
  end
19
22
 
20
23
  def ==(other)
21
24
  other.is_a?(self.class) && other.namespace == namespace && other.name == name
22
25
  end
23
-
26
+
24
27
  alias eql? ==
25
28
 
26
29
  def hash
@@ -68,3 +71,17 @@ module RBS
68
71
  end
69
72
  end
70
73
  end
74
+
75
+ module Kernel
76
+ def TypeName(string)
77
+ absolute = string.start_with?("::")
78
+
79
+ *path, name = string.delete_prefix("::").split("::").map(&:to_sym)
80
+ raise unless name
81
+
82
+ RBS::TypeName.new(
83
+ name: name,
84
+ namespace: RBS::Namespace.new(path: path, absolute: absolute)
85
+ )
86
+ end
87
+ end
@@ -1,6 +1,6 @@
1
1
  module RBS
2
2
  class TypeNameResolver
3
- Query = Struct.new(:type_name, :context, keyword_init: true)
3
+ Query = _ = Struct.new(:type_name, :context, keyword_init: true)
4
4
 
5
5
  attr_reader :all_names
6
6
  attr_reader :cache
@@ -36,15 +36,22 @@ module RBS
36
36
  query = Query.new(type_name: type_name, context: context)
37
37
  try_cache(query) do
38
38
  path_head, *path_tail = type_name.to_namespace.path
39
+ raise unless path_head
40
+
39
41
  name_head = TypeName.new(name: path_head, namespace: Namespace.empty)
40
42
 
41
- absolute_head = context.each.find do |namespace|
43
+ absolute_head = context.find do |namespace|
44
+ # @type break: TypeName
42
45
  full_name = name_head.with_prefix(namespace)
43
46
  has_name?(full_name) and break full_name
44
47
  end
45
48
 
46
- if absolute_head
49
+ case absolute_head
50
+ when TypeName
47
51
  has_name?(Namespace.new(path: absolute_head.to_namespace.path.push(*path_tail), absolute: true).to_type_name)
52
+ when Namespace
53
+ # This cannot happen because the `context.find` doesn't return a Namespace.
54
+ raise
48
55
  end
49
56
  end
50
57
  end
@@ -1,3 +1,4 @@
1
+
1
2
  module RBS
2
3
  module Types
3
4
  module NoFreeVariables
@@ -77,7 +78,7 @@ module RBS
77
78
  when Types::Bases::Class
78
79
  'class'
79
80
  else
80
- raise "Unexpected base type: #{type.inspect}"
81
+ raise "Unexpected base type: #{inspect}"
81
82
  end
82
83
  end
83
84
  end
@@ -138,8 +139,6 @@ module RBS
138
139
  new(name: v, location: nil)
139
140
  when Array
140
141
  v.map {|x| new(name: x, location: nil) }
141
- else
142
- raise
143
142
  end
144
143
  end
145
144
 
@@ -227,7 +226,7 @@ module RBS
227
226
  end
228
227
 
229
228
  def each_type(&block)
230
- if block_given?
229
+ if block
231
230
  args.each(&block)
232
231
  else
233
232
  enum_for :each_type
@@ -380,7 +379,7 @@ module RBS
380
379
  end
381
380
 
382
381
  def each_type(&block)
383
- if block_given?
382
+ if block
384
383
  types.each(&block)
385
384
  else
386
385
  enum_for :each_type
@@ -445,7 +444,7 @@ module RBS
445
444
  end
446
445
 
447
446
  def each_type(&block)
448
- if block_given?
447
+ if block
449
448
  fields.each_value(&block)
450
449
  else
451
450
  enum_for :each_type
@@ -492,11 +491,15 @@ module RBS
492
491
  end
493
492
 
494
493
  def to_s(level = 0)
495
- if type.is_a?(RBS::Types::Literal) && type.literal.is_a?(Symbol)
496
- "#{type.to_s(1)} ?"
497
- else
498
- "#{type.to_s(1)}?"
494
+ case t = type
495
+ when RBS::Types::Literal
496
+ case t.literal
497
+ when Symbol
498
+ return "#{type.to_s(1)} ?"
499
+ end
499
500
  end
501
+
502
+ "#{type.to_s(1)}?"
500
503
  end
501
504
 
502
505
  def each_type
@@ -560,7 +563,7 @@ module RBS
560
563
  end
561
564
 
562
565
  def each_type(&block)
563
- if block_given?
566
+ if block
564
567
  types.each(&block)
565
568
  else
566
569
  enum_for :each_type
@@ -568,7 +571,7 @@ module RBS
568
571
  end
569
572
 
570
573
  def map_type(&block)
571
- if block_given?
574
+ if block
572
575
  Union.new(types: types.map(&block), location: location)
573
576
  else
574
577
  enum_for :map_type
@@ -629,7 +632,7 @@ module RBS
629
632
  end
630
633
 
631
634
  def each_type(&block)
632
- if block_given?
635
+ if block
633
636
  types.each(&block)
634
637
  else
635
638
  enum_for :each_type
@@ -637,7 +640,7 @@ module RBS
637
640
  end
638
641
 
639
642
  def map_type(&block)
640
- if block_given?
643
+ if block
641
644
  Intersection.new(types: types.map(&block), location: location)
642
645
  else
643
646
  enum_for :map_type
@@ -672,8 +675,8 @@ module RBS
672
675
  self.class.hash ^ type.hash ^ name.hash
673
676
  end
674
677
 
675
- def map_type
676
- if block_given?
678
+ def map_type(&block)
679
+ if block
677
680
  Param.new(name: name, type: yield(type))
678
681
  else
679
682
  enum_for :map_type
@@ -772,7 +775,7 @@ module RBS
772
775
  end
773
776
 
774
777
  def map_type(&block)
775
- if block_given?
778
+ if block
776
779
  Function.new(
777
780
  required_positionals: required_positionals.map {|param| param.map_type(&block) },
778
781
  optional_positionals: optional_positionals.map {|param| param.map_type(&block) },
@@ -810,7 +813,7 @@ module RBS
810
813
  end
811
814
 
812
815
  def each_param(&block)
813
- if block_given?
816
+ if block
814
817
  required_positionals.each(&block)
815
818
  optional_positionals.each(&block)
816
819
  rest_positionals&.yield_self(&block)
@@ -891,7 +894,9 @@ module RBS
891
894
  end
892
895
 
893
896
  def param_to_s
897
+ # @type var params: Array[String]
894
898
  params = []
899
+
895
900
  params.push(*required_positionals.map(&:to_s))
896
901
  params.push(*optional_positionals.map {|p| "?#{p}"})
897
902
  params.push("*#{rest_positionals}") if rest_positionals
@@ -927,8 +932,9 @@ module RBS
927
932
  def drop_tail
928
933
  case
929
934
  when !trailing_positionals.empty?
935
+ last = trailing_positionals.last or raise
930
936
  [
931
- trailing_positionals.last,
937
+ last,
932
938
  update(trailing_positionals: trailing_positionals.take(trailing_positionals.size - 1))
933
939
  ]
934
940
  else
@@ -960,7 +966,7 @@ module RBS
960
966
  self.class.hash ^ type.hash
961
967
  end
962
968
 
963
- def free_variables(set)
969
+ def free_variables(set = Set[])
964
970
  type.free_variables(set)
965
971
  end
966
972
 
@@ -977,7 +983,7 @@ module RBS
977
983
  end
978
984
 
979
985
  def each_type(&block)
980
- if block_given?
986
+ if block
981
987
  type.each_type(&block)
982
988
  else
983
989
  enum_for :each_type