rubocop-on-rbs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/CODE_OF_CONDUCT.md +84 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +186 -0
  6. data/config/default.yml +165 -0
  7. data/lib/rubocop/cop/rbs/layout/comment_indentation.rb +69 -0
  8. data/lib/rubocop/cop/rbs/layout/empty_lines_around_overloads.rb +49 -0
  9. data/lib/rubocop/cop/rbs/layout/end_alignment.rb +55 -0
  10. data/lib/rubocop/cop/rbs/layout/extra_spacing.rb +55 -0
  11. data/lib/rubocop/cop/rbs/layout/indentation_width.rb +64 -0
  12. data/lib/rubocop/cop/rbs/layout/overload_indentation.rb +69 -0
  13. data/lib/rubocop/cop/rbs/layout/space_around_arrow.rb +56 -0
  14. data/lib/rubocop/cop/rbs/layout/space_around_braces.rb +77 -0
  15. data/lib/rubocop/cop/rbs/layout/space_before_colon.rb +43 -0
  16. data/lib/rubocop/cop/rbs/layout/space_before_overload.rb +46 -0
  17. data/lib/rubocop/cop/rbs/layout/trailing_whitespace.rb +42 -0
  18. data/lib/rubocop/cop/rbs/lint/syntax.rb +18 -0
  19. data/lib/rubocop/cop/rbs/lint/type_params_arity.rb +170 -0
  20. data/lib/rubocop/cop/rbs/lint/useless_overload_type_params.rb +57 -0
  21. data/lib/rubocop/cop/rbs/lint/will_syntax_error.rb +205 -0
  22. data/lib/rubocop/cop/rbs/style/block_return_boolish.rb +35 -0
  23. data/lib/rubocop/cop/rbs/style/classic_type.rb +73 -0
  24. data/lib/rubocop/cop/rbs/style/duplicated_type.rb +61 -0
  25. data/lib/rubocop/cop/rbs/style/initialize_return_type.rb +40 -0
  26. data/lib/rubocop/cop/rbs/style/merge_untyped.rb +91 -0
  27. data/lib/rubocop/cop/rbs/style/optional_nil.rb +50 -0
  28. data/lib/rubocop/cop/rbs/style/true_false.rb +84 -0
  29. data/lib/rubocop/cop/rbs_cops.rb +28 -0
  30. data/lib/rubocop/rbs/cop_base.rb +91 -0
  31. data/lib/rubocop/rbs/inject.rb +20 -0
  32. data/lib/rubocop/rbs/processed_rbs_source.rb +29 -0
  33. data/lib/rubocop/rbs/version.rb +7 -0
  34. data/lib/rubocop/rbs.rb +15 -0
  35. data/lib/rubocop-on-rbs.rb +13 -0
  36. metadata +106 -0
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Lint
7
+ # Notice useless overload type parameters.
8
+ #
9
+ # @example default
10
+ # # bad
11
+ # def foo: [T] () -> void
12
+ #
13
+ # # bad
14
+ # def bar: [T, U] (T) -> void
15
+ #
16
+ # # good
17
+ # def foo: [T] (Array[T]) -> T
18
+ class UselessOverloadTypeParams < RuboCop::RBS::CopBase
19
+ MSG = 'Useless overload type variable - `%<variable>s`.'
20
+
21
+ def on_rbs_def(decl)
22
+ decl.overloads.each do |overload|
23
+ next if overload.method_type.type_params.empty?
24
+
25
+ type_params = overload.method_type.type_params
26
+
27
+ overload.method_type.each_type do |type|
28
+ used_variable_in_type(type) do |var|
29
+ type_params.delete_if { |type_param| type_param.name == var.name }
30
+ end
31
+ end
32
+ next if type_params.empty?
33
+
34
+ type_params.each do |type_param|
35
+ next unless type_param.location
36
+
37
+ t = location_to_range(type_param.location[:name])
38
+ add_offense(t, message: format(MSG, variable: type_param.name), severity: :warning)
39
+ end
40
+ end
41
+ end
42
+
43
+ def used_variable_in_type(type, &block)
44
+ case type
45
+ when ::RBS::Types::Variable
46
+ yield type
47
+ else
48
+ type.each_type do |t|
49
+ used_variable_in_type(t, &block)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,205 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Lint
7
+ # This cop checks the WillSyntaxError in RBS.
8
+ # RBS with this diagnostics will fail in `rbs validate` command.
9
+ #
10
+ # @example default
11
+ # # bad
12
+ # def foo: (void) -> void
13
+ #
14
+ # # bad
15
+ # CONST: self
16
+ class WillSyntaxError < RuboCop::RBS::CopBase
17
+ # @rbs!
18
+ # module Types = ::RBS::Types
19
+ # module AST = ::RBS::AST
20
+
21
+ # @rbs skip
22
+ AST = ::RBS::AST
23
+ # @rbs skip
24
+ Types = ::RBS::Types
25
+
26
+ def on_rbs_class(decl)
27
+ if super_class = decl.super_class
28
+ super_class.args.each do |arg|
29
+ void_type_context_validator(arg, true)
30
+ no_self_type_validator(arg)
31
+ no_classish_type_validator(arg)
32
+ end
33
+ end
34
+ check_module_or_class(decl)
35
+ end
36
+
37
+ def on_rbs_module(decl)
38
+ decl.self_types.each do |self_type|
39
+ self_type.args.each do |arg|
40
+ void_type_context_validator(arg, true)
41
+ no_self_type_validator(arg)
42
+ no_classish_type_validator(arg)
43
+ end
44
+ end
45
+ check_module_or_class(decl)
46
+ end
47
+
48
+ def check_module_or_class(decl)
49
+ decl.type_params.each do |param|
50
+ if ub = param.upper_bound
51
+ void_type_context_validator(ub)
52
+ no_self_type_validator(ub)
53
+ no_classish_type_validator(ub)
54
+ end
55
+ end
56
+
57
+ decl.each_member do |member|
58
+ case member
59
+ when AST::Members::MethodDefinition
60
+ member.overloads.each do |ov|
61
+ void_type_context_validator(ov.method_type)
62
+ end
63
+ when AST::Members::Attribute
64
+ void_type_context_validator(member.type)
65
+ when AST::Members::Mixin
66
+ member.args.each do |arg|
67
+ no_self_type_validator(arg)
68
+ unless arg.is_a?(Types::Bases::Void)
69
+ void_type_context_validator(arg, true)
70
+ end
71
+ end
72
+ when AST::Members::Var
73
+ void_type_context_validator(member.type)
74
+ if member.is_a?(AST::Members::ClassVariable)
75
+ no_self_type_validator(member.type)
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def on_rbs_interface(decl)
82
+ decl.members.each do |member|
83
+ case member
84
+ when AST::Members::MethodDefinition
85
+ member.overloads.each do |ov|
86
+ void_type_context_validator(ov.method_type)
87
+ no_classish_type_validator(ov.method_type)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def on_rbs_constant(decl)
94
+ no_self_type_validator(decl.type)
95
+ no_classish_type_validator(decl.type)
96
+ void_type_context_validator(decl.type)
97
+ end
98
+ alias on_rbs_global on_rbs_constant
99
+ alias on_rbs_type_alias on_rbs_constant
100
+
101
+ private
102
+
103
+ # @rbs type: ::RBS::Types::t
104
+ def no_self_type_validator(type)
105
+ case type
106
+ when ::RBS::MethodType,
107
+ Types::Record,
108
+ Types::Tuple,
109
+ Types::Union,
110
+ Types::Intersection,
111
+ Types::Optional,
112
+ Types::ClassInstance,
113
+ Types::Proc
114
+ type.each_type do |t|
115
+ no_self_type_validator(t)
116
+ end
117
+ else
118
+ if type.has_self_type?
119
+ offence(type, "`self` type is not allowed in this context")
120
+ end
121
+ end
122
+ end
123
+
124
+ # @rbs type: ::RBS::MethodType | ::RBS::Types::t
125
+ def no_classish_type_validator(type)
126
+ case type
127
+ when ::RBS::MethodType,
128
+ Types::Record,
129
+ Types::Tuple,
130
+ Types::Union,
131
+ Types::Intersection,
132
+ Types::Optional,
133
+ Types::ClassInstance,
134
+ Types::Proc
135
+ type.each_type do |t|
136
+ no_classish_type_validator(t)
137
+ end
138
+ when Types::Bases::Instance
139
+ offence(type, "`instance` type is not allowed in this context")
140
+ when Types::Bases::Class
141
+ offence(type, "`class` type is not allowed in this context")
142
+ else
143
+ if type.has_classish_type?
144
+ offence(type, "`instance` or `class` type is not allowed in this context")
145
+ end
146
+ end
147
+ end
148
+
149
+ # @rbs type: ::RBS::MethodType | ::RBS::Types::Function | ::RBS::Types::t
150
+ # @rbs allowed_here: bool
151
+ def void_type_context_validator(type, allowed_here = false)
152
+ return if type.is_a?(Types::UntypedFunction)
153
+
154
+ case type
155
+ when ::RBS::MethodType
156
+ void_type_context_validator(type.type)
157
+ when Types::Function
158
+ type.each_param do |param|
159
+ void_type_context_validator(param.type)
160
+ end
161
+ case type.return_type
162
+ when Types::Bases::Void
163
+ # `() -> void` is allowed
164
+ else
165
+ void_type_context_validator(type.return_type, true)
166
+ end
167
+ when Types::Proc
168
+ void_type_context_validator(type.type)
169
+ if type.block
170
+ void_type_context_validator(type.block.type)
171
+ void_type_context_validator(type.block.self_type) if type.block.self_type
172
+ end
173
+ when Types::ClassInstance
174
+ type.args.each do |arg|
175
+ next if arg.is_a?(Types::Bases::Void)
176
+
177
+ void_type_context_validator(arg)
178
+ end
179
+ when Types::Record,
180
+ Types::Tuple,
181
+ Types::Union,
182
+ Types::Intersection,
183
+ Types::Optional
184
+ type.each_type do |t|
185
+ void_type_context_validator(t)
186
+ end
187
+ else
188
+ if allowed_here
189
+ return if type.is_a?(Types::Bases::Void)
190
+ end
191
+ if type.with_nonreturn_void?
192
+ offence(type, "`void` type is only allowed in return type or generics parameter")
193
+ end
194
+ end
195
+ end
196
+
197
+ def offence(decl, message)
198
+ range = location_to_range(decl.location)
199
+ add_offense(range, message: message)
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: () { () -> bool } -> void
10
+ #
11
+ # # good
12
+ # def foo: () { () -> boolish } -> void
13
+ class BlockReturnBoolish < RuboCop::RBS::CopBase
14
+ extend AutoCorrector
15
+ MSG = 'Use `boolish` instead of `bool` in block return type.'
16
+
17
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
18
+ def on_rbs_def(decl)
19
+ decl.overloads.each do |overload|
20
+ next unless overload.method_type.block
21
+
22
+ return_type = overload.method_type.block.type.return_type
23
+ next unless return_type.is_a?(::RBS::Types::Bases::Bool)
24
+
25
+ range = location_to_range(return_type.location)
26
+ add_offense(range) do |corrector|
27
+ corrector.replace(range, 'boolish')
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: () -> TrueClass
10
+ #
11
+ # # bad
12
+ # def bar: () -> NilClass
13
+ #
14
+ # # good
15
+ # def foo: () -> true
16
+ #
17
+ # # good
18
+ # def bar: () -> nil
19
+ class ClassicType < RuboCop::RBS::CopBase
20
+ extend AutoCorrector
21
+
22
+ Types = ::RBS::Types
23
+
24
+ def on_rbs_def(decl)
25
+ decl.overloads.each do |overload|
26
+ overload.method_type.each_type do |type|
27
+ check_type(type)
28
+ end
29
+ end
30
+ end
31
+
32
+ # @rbs type: ::RBS::Types::t
33
+ def check_type(type)
34
+ find_replacement(type) do |t, replaced|
35
+ range = location_to_range(t.location)
36
+ add_offense(range, message: "Use `#{replaced}` instead of `#{t}`") do |corrector|
37
+ corrector.replace(range, replaced)
38
+ end
39
+ end
40
+ end
41
+
42
+ def find_replacement(type, &block)
43
+ case type
44
+ when Types::Record,
45
+ Types::Tuple,
46
+ Types::Union,
47
+ Types::Intersection,
48
+ Types::Optional,
49
+ Types::Proc,
50
+ Types::Alias,
51
+ Types::Interface
52
+ type.each_type do |t|
53
+ find_replacement(t, &block)
54
+ end
55
+ when Types::ClassInstance
56
+ case type.name.to_s
57
+ when 'TrueClass', '::TrueClass'
58
+ block.call([type, 'true'])
59
+ when 'FalseClass', '::FalseClass'
60
+ block.call([type, 'false'])
61
+ when 'NilClass', '::NilClass'
62
+ block.call([type, 'nil'])
63
+ end
64
+ type.each_type do |arg|
65
+ find_replacement(arg, &block)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: (Integer | Integer) -> void
10
+ #
11
+ # # bad
12
+ # def foo: (Integer & Integer) -> void
13
+ #
14
+ # # good
15
+ # def foo: (Integer) -> void
16
+ class DuplicatedType < RuboCop::RBS::CopBase
17
+ extend AutoCorrector
18
+
19
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
20
+ def on_rbs_def(decl)
21
+ decl.overloads.each do |overload|
22
+ overload.method_type.each_type do |type|
23
+ check_type(type)
24
+ end
25
+ end
26
+ end
27
+
28
+ # @rbs type: ::RBS::Types::t
29
+ def check_type(type)
30
+ case type
31
+ when ::RBS::Types::Record,
32
+ ::RBS::Types::Tuple,
33
+ ::RBS::Types::Optional,
34
+ ::RBS::Types::ClassInstance,
35
+ ::RBS::Types::Proc
36
+ type.each_type do |t|
37
+ check_type(t)
38
+ end
39
+ when ::RBS::Types::Union,
40
+ ::RBS::Types::Intersection
41
+ set = Set.new
42
+ type.types.each do |t|
43
+ if set.include?(t)
44
+ if t.location
45
+ range = location_to_range(t.location)
46
+ add_offense(range, message: "Duplicated type `#{t}`.")
47
+ end
48
+ else
49
+ set.add(t)
50
+ end
51
+ end
52
+ type.each_type do |t|
53
+ check_type(t)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def initialize: () -> untyped
10
+ #
11
+ # # bad
12
+ # def initialize: () -> nil
13
+ #
14
+ # # good
15
+ # def initialize: () -> void
16
+ class InitializeReturnType < RuboCop::RBS::CopBase
17
+ extend AutoCorrector
18
+ MSG = '`#initialize` method should return `void`'
19
+
20
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
21
+ def on_rbs_def(decl)
22
+ return unless decl.name == :initialize
23
+ return unless decl.kind == :instance
24
+ return unless decl.overloading == false
25
+
26
+ decl.overloads.each do |overload|
27
+ return_type = overload.method_type.type.return_type
28
+ next if return_type.is_a?(::RBS::Types::Bases::Void)
29
+
30
+ range = location_to_range(return_type.location)
31
+ add_offense(range) do |corrector|
32
+ corrector.replace(range, 'void')
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: (untyped?) -> untyped?
10
+ #
11
+ # # bad
12
+ # def foo: (Integer | untyped) -> (Integer | untyped)
13
+ #
14
+ # # bad
15
+ # def foo: (Integer & untyped) -> (Integer & untyped)
16
+ #
17
+ # # good
18
+ # def foo: (untyped) -> untyped
19
+ class MergeUntyped < RuboCop::RBS::CopBase
20
+ extend AutoCorrector
21
+
22
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
23
+ def on_rbs_def(decl)
24
+ decl.overloads.each do |overload|
25
+ overload.method_type.type.tap do |fun|
26
+ fun.each_param do |param|
27
+ check_type(param.type)
28
+ end
29
+ check_type(fun.return_type)
30
+ end
31
+ end
32
+ end
33
+
34
+ def check_type(type)
35
+ find_replacement(type) do |method, t, replaced|
36
+ case method
37
+ when :replace
38
+ range = location_to_range(t.location)
39
+ add_offense(range, message: "Use `#{replaced}` instead of `#{t}`") do |corrector|
40
+ corrector.replace(range, replaced.to_s)
41
+ end
42
+ when :remove
43
+ range = t
44
+ add_offense(range, message: "Remove `?` in Optional") do |corrector|
45
+ corrector.remove(range)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def find_replacement(type, &block)
52
+ case type
53
+ when ::RBS::Types::Optional
54
+ case type.type
55
+ when ::RBS::Types::Bases::Any,
56
+ ::RBS::Types::Bases::Nil,
57
+ ::RBS::Types::Bases::Void,
58
+ ::RBS::Types::Bases::Top,
59
+ ::RBS::Types::Bases::Bottom
60
+ # untyped? => untyped
61
+ block.call([:replace, type, type.type])
62
+ when ::RBS::Types::Optional
63
+ # (Integer?)? => Integer?
64
+ range = Parser::Source::Range.new(processed_source.buffer, type.type.location.end_pos - 1,
65
+ type.type.location.end_pos)
66
+ block.call([:remove, range])
67
+ find_replacement(type.type, &block)
68
+ when ::RBS::Types::Union, ::RBS::Types::Intersection
69
+ find_replacement(type.type, &block)
70
+ end
71
+ when ::RBS::Types::Union, ::RBS::Types::Intersection
72
+ # (untyped | Integer) => untyped
73
+ # (untyped & Integer) => untyped
74
+ if type.types.any? { |t| t.is_a?(::RBS::Types::Bases::Any) }
75
+ block.call([:replace, type, 'untyped'])
76
+ end
77
+
78
+ uniqed = type.types.uniq
79
+ if uniqed.size < type.types.size
80
+ block.call([:replace, type, type.class.new(types: uniqed, location: nil)])
81
+ end
82
+ type.types.each do |t|
83
+ find_replacement(t, &block)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: (nil?) -> void
10
+ #
11
+ # # good
12
+ # def foo: (nil) -> void
13
+ class OptionalNil < RuboCop::RBS::CopBase
14
+ extend AutoCorrector
15
+
16
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
17
+ def on_rbs_def(decl)
18
+ decl.overloads.each do |overload|
19
+ overload.method_type.each_type do |type|
20
+ find_replacement(type) do |t, replaced|
21
+ range = location_to_range(t.location)
22
+ add_offense(range, message: "Use `#{replaced}` instead of `#{t}`") do |corrector|
23
+ corrector.replace(range, replaced.to_s)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ # @rbs type: ::RBS::Types::t
31
+ def find_replacement(type, &block)
32
+ case type
33
+ when ::RBS::Types::Optional
34
+ case type.type
35
+ when ::RBS::Types::Bases::Nil
36
+ block.call([type, ::RBS::Types::Bases::Nil.new(location: nil)])
37
+ else
38
+ find_replacement(type.type, &block)
39
+ end
40
+ else
41
+ type.each_type do |type|
42
+ find_replacement(type, &block)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Style
7
+ # @example default
8
+ # # bad
9
+ # def foo: (true | false) -> (true | false)
10
+ #
11
+ # # bad
12
+ # def foo: (TrueClass | FalseClass) -> (TrueClass | FalseClass)
13
+ #
14
+ # # good
15
+ # def foo: (bool) -> bool
16
+ class TrueFalse < RuboCop::RBS::CopBase
17
+ extend AutoCorrector
18
+
19
+ # @sig decl: ::RBS::AST::Members::MethodDefinition
20
+ def on_rbs_def(decl)
21
+ decl.overloads.each do |overload|
22
+ overload.method_type.each_type do |type|
23
+ find_replacement(type) do |t, replaced|
24
+ range = location_to_range(t.location)
25
+ add_offense(range, message: "Use `#{replaced}` instead of `#{t}`") do |corrector|
26
+ corrector.replace(range, replaced.to_s)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # @rbs type: ::RBS::Types::t
34
+ def find_replacement(type, &block)
35
+ case type
36
+ when ::RBS::Types::Union
37
+ has_true = has_false = false
38
+ type.types.each do |t|
39
+ case t
40
+ when ::RBS::Types::Literal
41
+ has_true = true if t.literal == true
42
+ has_false = true if t.literal == false
43
+ when ::RBS::Types::ClassInstance
44
+ case t.name.to_s
45
+ when 'TrueClass', '::TrueClass'
46
+ has_true = true
47
+ when 'FalseClass', '::FalseClass'
48
+ has_false = true
49
+ end
50
+ end
51
+ end
52
+ if has_true && has_false
53
+ replaced = type.types.dup
54
+ first_index = nil
55
+ i = -1
56
+ replaced.delete_if do |t|
57
+ i += 1
58
+ case t
59
+ when ::RBS::Types::Literal
60
+ (t.literal == true || t.literal == false).tap do |r|
61
+ first_index ||= i if r
62
+ end
63
+ when ::RBS::Types::ClassInstance
64
+ t.name.to_s.then do |s|
65
+ s == 'TrueClass' || s == '::TrueClass' || s == 'FalseClass' || s == '::FalseClass'
66
+ end.tap do |r|
67
+ first_index ||= i if r
68
+ end
69
+ end
70
+ end
71
+ replaced.insert(first_index || 0, ::RBS::Types::Bases::Bool.new(location: nil))
72
+ block.call([type, ::RBS::Types::Union.new(types: replaced, location: nil)])
73
+ end
74
+ else
75
+ type.each_type do |type|
76
+ find_replacement(type, &block)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end