rbs 0.9.0 → 0.12.1

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