rubocop-on-rbs 2.0.0 → 2.2.0

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +46 -0
  4. data/config/default.yml +111 -0
  5. data/lib/rubocop/cop/rbs/layout/annotation_indentation.rb +2 -1
  6. data/lib/rubocop/cop/rbs/layout/comment_indentation.rb +1 -1
  7. data/lib/rubocop/cop/rbs/layout/empty_lines_around_access_modifier.rb +3 -2
  8. data/lib/rubocop/cop/rbs/layout/empty_lines_around_body.rb +8 -0
  9. data/lib/rubocop/cop/rbs/layout/end_alignment.rb +2 -1
  10. data/lib/rubocop/cop/rbs/layout/extra_spacing.rb +1 -0
  11. data/lib/rubocop/cop/rbs/layout/indentation_width.rb +17 -2
  12. data/lib/rubocop/cop/rbs/layout/overload_indentation.rb +7 -5
  13. data/lib/rubocop/cop/rbs/layout/space_after_comma.rb +1 -0
  14. data/lib/rubocop/cop/rbs/layout/space_around_arrow.rb +4 -2
  15. data/lib/rubocop/cop/rbs/layout/space_around_braces.rb +6 -3
  16. data/lib/rubocop/cop/rbs/layout/space_before_colon.rb +1 -1
  17. data/lib/rubocop/cop/rbs/lint/ambiguous_keyword_argument_key.rb +2 -42
  18. data/lib/rubocop/cop/rbs/lint/ambiguous_operator_precedence.rb +2 -0
  19. data/lib/rubocop/cop/rbs/lint/duplicate_annotation.rb +2 -0
  20. data/lib/rubocop/cop/rbs/lint/duplicate_overload.rb +2 -24
  21. data/lib/rubocop/cop/rbs/lint/literal_intersection.rb +7 -38
  22. data/lib/rubocop/cop/rbs/lint/new_returns_void.rb +2 -19
  23. data/lib/rubocop/cop/rbs/lint/rest_keyword_hash.rb +2 -22
  24. data/lib/rubocop/cop/rbs/lint/top_level_interface.rb +6 -4
  25. data/lib/rubocop/cop/rbs/lint/top_level_type_alias.rb +6 -4
  26. data/lib/rubocop/cop/rbs/lint/unused_overload_type_params.rb +2 -41
  27. data/lib/rubocop/cop/rbs/lint/useless_access_modifier.rb +3 -3
  28. data/lib/rubocop/cop/rbs/mixin/ambiguous_keyword_argument_key.rb +59 -0
  29. data/lib/rubocop/cop/rbs/mixin/block_return_boolish.rb +32 -0
  30. data/lib/rubocop/cop/rbs/mixin/class_with_singleton.rb +44 -0
  31. data/lib/rubocop/cop/rbs/mixin/classic_type.rb +72 -0
  32. data/lib/rubocop/cop/rbs/mixin/duplicate_overload.rb +43 -0
  33. data/lib/rubocop/cop/rbs/mixin/duplicated_type.rb +59 -0
  34. data/lib/rubocop/cop/rbs/mixin/empty_argument.rb +167 -0
  35. data/lib/rubocop/cop/rbs/mixin/initialize_return_type.rb +35 -0
  36. data/lib/rubocop/cop/rbs/mixin/instance_with_instance.rb +54 -0
  37. data/lib/rubocop/cop/rbs/mixin/literal_intersection.rb +56 -0
  38. data/lib/rubocop/cop/rbs/mixin/new_returns_void.rb +33 -0
  39. data/lib/rubocop/cop/rbs/mixin/optional_nil.rb +58 -0
  40. data/lib/rubocop/cop/rbs/mixin/redundant_parentheses.rb +161 -0
  41. data/lib/rubocop/cop/rbs/mixin/rest_keyword_hash.rb +40 -0
  42. data/lib/rubocop/cop/rbs/mixin/true_false.rb +89 -0
  43. data/lib/rubocop/cop/rbs/mixin/unused_overload_type_params.rb +58 -0
  44. data/lib/rubocop/cop/rbs/style/block_return_boolish.rb +2 -16
  45. data/lib/rubocop/cop/rbs/style/class_with_singleton.rb +2 -30
  46. data/lib/rubocop/cop/rbs/style/classic_type.rb +7 -55
  47. data/lib/rubocop/cop/rbs/style/duplicated_type.rb +7 -44
  48. data/lib/rubocop/cop/rbs/style/empty_argument.rb +7 -145
  49. data/lib/rubocop/cop/rbs/style/initialize_return_type.rb +2 -18
  50. data/lib/rubocop/cop/rbs/style/instance_with_instance.rb +2 -39
  51. data/lib/rubocop/cop/rbs/style/optional_nil.rb +7 -40
  52. data/lib/rubocop/cop/rbs/style/redundant_parentheses.rb +5 -130
  53. data/lib/rubocop/cop/rbs/style/true_false.rb +7 -71
  54. data/lib/rubocop/cop/rbs_cops.rb +17 -0
  55. data/lib/rubocop/cop/rbs_inline/lint/ambiguous_keyword_argument_key.rb +28 -0
  56. data/lib/rubocop/cop/rbs_inline/lint/duplicate_overload.rb +31 -0
  57. data/lib/rubocop/cop/rbs_inline/lint/literal_intersection.rb +31 -0
  58. data/lib/rubocop/cop/rbs_inline/lint/new_returns_void.rb +28 -0
  59. data/lib/rubocop/cop/rbs_inline/lint/rest_keyword_hash.rb +31 -0
  60. data/lib/rubocop/cop/rbs_inline/lint/syntax.rb +40 -0
  61. data/lib/rubocop/cop/rbs_inline/lint/unused_annotation.rb +41 -0
  62. data/lib/rubocop/cop/rbs_inline/lint/unused_overload_type_params.rb +28 -0
  63. data/lib/rubocop/cop/rbs_inline/style/block_return_boolish.rb +27 -0
  64. data/lib/rubocop/cop/rbs_inline/style/class_with_singleton.rb +29 -0
  65. data/lib/rubocop/cop/rbs_inline/style/classic_type.rb +38 -0
  66. data/lib/rubocop/cop/rbs_inline/style/duplicated_type.rb +37 -0
  67. data/lib/rubocop/cop/rbs_inline/style/empty_argument.rb +42 -0
  68. data/lib/rubocop/cop/rbs_inline/style/initialize_return_type.rb +37 -0
  69. data/lib/rubocop/cop/rbs_inline/style/instance_with_instance.rb +29 -0
  70. data/lib/rubocop/cop/rbs_inline/style/optional_nil.rb +32 -0
  71. data/lib/rubocop/cop/rbs_inline/style/redundant_parentheses.rb +96 -0
  72. data/lib/rubocop/cop/rbs_inline/style/true_false.rb +37 -0
  73. data/lib/rubocop/cop/rbs_inline_cops.rb +21 -0
  74. data/lib/rubocop/rbs/cop_base.rb +33 -34
  75. data/lib/rubocop/rbs/cop_helper.rb +22 -0
  76. data/lib/rubocop/rbs/on_type_helper.rb +2 -0
  77. data/lib/rubocop/rbs/processed_rbs_source.rb +10 -5
  78. data/lib/rubocop/rbs/version.rb +1 -1
  79. data/lib/rubocop/rbs_inline/cop_base.rb +110 -0
  80. data/lib/rubocop/rbs_inline/processed_inline_source.rb +33 -0
  81. data/lib/rubocop-on-rbs.rb +4 -0
  82. metadata +41 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52b6d2d8d5f69d9af653de61ac795ed71d7ce63663c65450dd842e4c1816c69f
4
- data.tar.gz: e81e32efe74897317c3eb4183cfb11e6e65b0bcaa04345261787dfc29eb92741
3
+ metadata.gz: '08ba6bad1ed2be5adfb8b5afeaf6917521e98618a7279354231e637727774177'
4
+ data.tar.gz: 9e1ac97d25171ec66ad0815bab269e652ce10b159cb372aad2bd9b0baeeb4913
5
5
  SHA512:
6
- metadata.gz: 6f7a1fdceb0841f976a3cfe4147e9f17e43e13447702314e03747bbd0565f945615f23e952d7ffd08ba7dd00c46f34b2d5bfcd7d8692d94eaf901d528c776cd1
7
- data.tar.gz: f0949c448ec168f168b4d4c2b723670bac8e2dade272e8b569533314c366e26b89b805860f455f49f5a3d1f06294a7ad0334baa8c878ab043459b2cbf22c115f
6
+ metadata.gz: f8a8c23cfaffc12e440c3b0b8ab6e122e6d68352c481b0b548183329c36967b275627131b25b6a7123da202c84c93e2b2442735f3080fac20b148da12f7c4561
7
+ data.tar.gz: 800caf959a981ead103d76f611a69ec61ce4828d7e620c48bab82a621b21eea1ca8bccf90bb4c6a7fe6080c155bc29cf2bd6c0886e3707a67e8ae3da3d718581
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.2.0] - 2026-09-28
4
+
5
+ * Mark all `RBSInline/*` cops as `Enabled: pending` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/164
6
+ * They will be enabled by default in v3.0.0. Use `NewCops: enable` to enable them now.
7
+ * Add `RBSInline` department for RBS inline annotations in Ruby files by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/159
8
+ * `RBSInline/Lint/Syntax`
9
+ * `RBSInline/Lint/UnusedAnnotation`
10
+ * Replace crc32 cache with `ObjectSpace::WeakKeyMap` and drop `zlib` dependency by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/160
11
+ * Add `RBSInline/Style` department by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/161
12
+ * `RBSInline/Style/BlockReturnBoolish`
13
+ * `RBSInline/Style/ClassWithSingleton`
14
+ * `RBSInline/Style/ClassicType`
15
+ * `RBSInline/Style/DuplicatedType`
16
+ * `RBSInline/Style/EmptyArgument`
17
+ * `RBSInline/Style/InitializeReturnType`
18
+ * `RBSInline/Style/InstanceWithInstance`
19
+ * `RBSInline/Style/OptionalNil`
20
+ * `RBSInline/Style/RedundantParentheses`
21
+ * `RBSInline/Style/TrueFalse`
22
+ * Drop steep by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/162
23
+ * Add `RBSInline/Lint` cops sharing implementation with `RBS/Lint` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/163
24
+ * `RBSInline/Lint/AmbiguousKeywordArgumentKey`
25
+ * `RBSInline/Lint/DuplicateOverload`
26
+ * `RBSInline/Lint/LiteralIntersection`
27
+ * `RBSInline/Lint/NewReturnsVoid`
28
+ * `RBSInline/Lint/RestKeywordHash`
29
+ * `RBSInline/Lint/UnusedOverloadTypeParams`
30
+
31
+ ## [2.1.0] - 2026-09-27
32
+
33
+ * Drop support for Ruby v3.2 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/153
34
+ * [RBS/Layout/IndentationWidth] Support `Width` option by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/157
35
+
3
36
  ## [2.0.0] - 2026-03-27
4
37
 
5
38
  * Support rbs v4 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/145
data/README.md CHANGED
@@ -104,6 +104,52 @@ RBS/Style:
104
104
  $ bundle exec rubocop --only RBS/Style
105
105
  ```
106
106
 
107
+ ### RBSInline
108
+
109
+ Cops for RBS inline annotations (`#: String`, `# @rbs x: Integer`) written in Ruby files.
110
+ They are separated from `RBS/*` cops and run only on Ruby files that contain annotations.
111
+
112
+ All `RBSInline/*` cops are `pending` in v2.x and will be enabled by default in v3.0.0.
113
+ To enable them now, set `NewCops: enable` in your `.rubocop.yml`:
114
+
115
+ ```yaml
116
+ AllCops:
117
+ NewCops: enable
118
+ ```
119
+
120
+ Or enable only the `RBSInline` department (requires RuboCop 1.89+):
121
+
122
+ ```yaml
123
+ RBSInline:
124
+ NewCops: enable
125
+ ```
126
+
127
+ ### RBSInline/Lint
128
+
129
+ Same as `RBS/Lint`, but for inline annotations.
130
+
131
+ ```yaml
132
+ RBSInline/Lint:
133
+ Enabled: true
134
+ ```
135
+
136
+ ```console
137
+ $ bundle exec rubocop --only RBSInline/Lint
138
+ ```
139
+
140
+ ### RBSInline/Style
141
+
142
+ Same as `RBS/Style`, but for inline annotations.
143
+
144
+ ```yaml
145
+ RBSInline/Style:
146
+ Enabled: true
147
+ ```
148
+
149
+ ```console
150
+ $ bundle exec rubocop --only RBSInline/Style
151
+ ```
152
+
107
153
  ## Installation
108
154
 
109
155
  Install the gem and add to the application's Gemfile by executing:
data/config/default.yml CHANGED
@@ -77,6 +77,8 @@ RBS/Layout/ExtraSpacing:
77
77
  RBS/Layout/IndentationWidth:
78
78
  Description: 'Use 2 spaces for indentation'
79
79
  Enabled: true
80
+ # Number of spaces for each indentation level.
81
+ Width: 2
80
82
 
81
83
  RBS/Layout/OverloadIndentation:
82
84
  Description: 'Indent overload method'
@@ -220,3 +222,112 @@ RBS/Style/RedundantParentheses:
220
222
  RBS/Style/TrueFalse:
221
223
  Description: 'Use bool instead of true | false'
222
224
  Enabled: true
225
+
226
+ # RBSInline
227
+
228
+ RBSInline:
229
+ Enabled: true
230
+
231
+ ## RBSInline/Lint
232
+
233
+ RBSInline/Lint:
234
+ Enabled: true
235
+
236
+ RBSInline/Lint/AmbiguousKeywordArgumentKey:
237
+ Description: 'Check ambiguous keyword argument key'
238
+ Enabled: pending
239
+ VersionAdded: '2.2.0'
240
+
241
+ RBSInline/Lint/DuplicateOverload:
242
+ Description: 'Checks that there are no repeated overload bodies'
243
+ Enabled: pending
244
+ VersionAdded: '2.2.0'
245
+
246
+ RBSInline/Lint/LiteralIntersection:
247
+ Description: 'Check literal intersection'
248
+ Enabled: pending
249
+ VersionAdded: '2.2.0'
250
+
251
+ RBSInline/Lint/NewReturnsVoid:
252
+ Description: 'sigleton `new` method should not returns `void` type'
253
+ Enabled: pending
254
+ VersionAdded: '2.2.0'
255
+
256
+ RBSInline/Lint/RestKeywordHash:
257
+ Description: 'Check rest keyword with `Hash` type'
258
+ Enabled: pending
259
+ VersionAdded: '2.2.0'
260
+
261
+ RBSInline/Lint/Syntax:
262
+ Severity: error
263
+ Description: 'Check RBS inline annotation syntax'
264
+ Enabled: pending
265
+ VersionAdded: '2.2.0'
266
+ AllowedPatterns:
267
+ # Embedded RBS by rbs-inline gem. Not supported by RBS::InlineParser.
268
+ - '\A# @rbs!'
269
+
270
+ RBSInline/Lint/UnusedAnnotation:
271
+ Description: 'Check unused RBS inline annotation'
272
+ Enabled: pending
273
+ VersionAdded: '2.2.0'
274
+
275
+ RBSInline/Lint/UnusedOverloadTypeParams:
276
+ Description: 'Check redundant overload type params'
277
+ Enabled: pending
278
+ VersionAdded: '2.2.0'
279
+
280
+ ## RBSInline/Style
281
+
282
+ RBSInline/Style:
283
+ Enabled: true
284
+
285
+ RBSInline/Style/BlockReturnBoolish:
286
+ Description: 'Use `bool` for block return type'
287
+ Enabled: pending
288
+ VersionAdded: '2.2.0'
289
+
290
+ RBSInline/Style/ClassWithSingleton:
291
+ Description: 'Check `class` with singleton context'
292
+ Enabled: pending
293
+ VersionAdded: '2.2.0'
294
+
295
+ RBSInline/Style/ClassicType:
296
+ Description: 'Use simple type'
297
+ Enabled: pending
298
+ VersionAdded: '2.2.0'
299
+
300
+ RBSInline/Style/DuplicatedType:
301
+ Description: 'Check duplicated type'
302
+ Enabled: pending
303
+ VersionAdded: '2.2.0'
304
+
305
+ RBSInline/Style/EmptyArgument:
306
+ Description: 'Use `()` for empty argument'
307
+ Enabled: pending
308
+ VersionAdded: '2.2.0'
309
+
310
+ RBSInline/Style/InitializeReturnType:
311
+ Description: 'Use `void` for initialize method'
312
+ Enabled: pending
313
+ VersionAdded: '2.2.0'
314
+
315
+ RBSInline/Style/InstanceWithInstance:
316
+ Description: 'Check `instance` with instance context'
317
+ Enabled: pending
318
+ VersionAdded: '2.2.0'
319
+
320
+ RBSInline/Style/OptionalNil:
321
+ Description: 'Use nil instead of nil?'
322
+ Enabled: pending
323
+ VersionAdded: '2.2.0'
324
+
325
+ RBSInline/Style/RedundantParentheses:
326
+ Description: 'Remove redundant parentheses'
327
+ Enabled: pending
328
+ VersionAdded: '2.2.0'
329
+
330
+ RBSInline/Style/TrueFalse:
331
+ Description: 'Use bool instead of true | false'
332
+ Enabled: pending
333
+ VersionAdded: '2.2.0'
@@ -35,7 +35,8 @@ module RuboCop
35
35
  when ::RBS::AST::Members::MethodDefinition
36
36
  member.overloads.each do |overload|
37
37
  overload.annotations.each do |annotation|
38
- ignore_poses << annotation.location.start_pos
38
+ location = annotation.location or next
39
+ ignore_poses << location.start_pos
39
40
  end
40
41
  end
41
42
  end
@@ -46,7 +46,7 @@ module RuboCop
46
46
 
47
47
  def line_after_comment(comment)
48
48
  lines = processed_source.lines
49
- lines[comment.location.start_line..].find { |line| !line.blank? }
49
+ lines[comment.location.start_line..]&.find { |line| !line.blank? }
50
50
  end
51
51
 
52
52
  def correct_indentation(next_line)
@@ -29,8 +29,9 @@ module RuboCop
29
29
  MSG = 'Keep a blank line before and after `<%<kind>s>`.'
30
30
 
31
31
  def on_rbs_class(decl)
32
- @class_or_module_def_first_line = decl.location.start_line
33
- @class_or_module_def_last_line = decl.location.end_line
32
+ location = decl.location or return
33
+ @class_or_module_def_first_line = location.start_line
34
+ @class_or_module_def_last_line = location.end_line
34
35
  end
35
36
  alias on_rbs_module on_rbs_class
36
37
 
@@ -4,11 +4,14 @@ module RuboCop
4
4
  module Cop
5
5
  module RBS
6
6
  module Layout
7
+ # @rbs module-self: RuboCop::RBS::CopBase
7
8
  module EmptyLinesAroundBody
8
9
  MSG_EXTRA = 'Extra empty line detected at %<kind>s body %<location>s.'
9
10
 
10
11
  private
11
12
 
13
+ # Main endpoint
14
+ #: (untyped decl) -> void
12
15
  def check(decl)
13
16
  first_line = decl.location.start_line
14
17
  last_line = decl.location.end_line
@@ -18,14 +21,19 @@ module RuboCop
18
21
  check_ending(last_line)
19
22
  end
20
23
 
24
+ # Check line after `class/module/interface`
25
+ #: (Integer first_line) -> void
21
26
  def check_beginning(first_line)
22
27
  check_source(first_line, 'beginning')
23
28
  end
24
29
 
30
+ # Check line before `end`
31
+ #: (Integer last_line) -> void
25
32
  def check_ending(last_line)
26
33
  check_source(last_line - 2, 'end')
27
34
  end
28
35
 
36
+ #: (Integer line_no, untyped desc) -> void
29
37
  def check_source(line_no, desc)
30
38
  return unless line_no.positive?
31
39
  return unless processed_source.lines[line_no]
@@ -42,7 +42,8 @@ module RuboCop
42
42
  end_loc = decl.location[:end]
43
43
  actual = end_loc.start_column
44
44
  if actual != expect
45
- line_start_pos = processed_source.raw_source.rindex(/\R/, end_loc.start_pos) + 1
45
+ newline_pos = processed_source.raw_source.rindex(/\R/, end_loc.start_pos) or return
46
+ line_start_pos = newline_pos + 1
46
47
  range = range_between(end_loc.start_pos, end_loc.end_pos)
47
48
  source = decl.location.source.each_line.first.strip
48
49
  message = "`end` at #{end_loc.start_line}, #{end_loc.start_column} is not aligned with " \
@@ -38,6 +38,7 @@ module RuboCop
38
38
  end
39
39
  end
40
40
 
41
+ #: () -> ::Set[Integer]
41
42
  def aligned_locations
42
43
  comments = processed_rbs_source.tokens.select(&:comment?)
43
44
  Set.new.tap do |aligned|
@@ -6,7 +6,7 @@ module RuboCop
6
6
  module Layout
7
7
  # Checks if the indentation width.
8
8
  #
9
- # @example
9
+ # @example Width: 2 (default)
10
10
  # # bad
11
11
  # class Foo
12
12
  # def foo: () -> void
@@ -17,6 +17,17 @@ module RuboCop
17
17
  # def foo: () -> void
18
18
  # end
19
19
  #
20
+ # @example Width: 4
21
+ # # bad
22
+ # class Foo
23
+ # def foo: () -> void
24
+ # end
25
+ #
26
+ # # good
27
+ # class Foo
28
+ # def foo: () -> void
29
+ # end
30
+ #
20
31
  class IndentationWidth < RuboCop::RBS::CopBase
21
32
  extend AutoCorrector
22
33
 
@@ -33,7 +44,7 @@ module RuboCop
33
44
  if decl.respond_to?(:members)
34
45
  check(decl, expect: expect)
35
46
  decl.members.each do |member|
36
- check_indentation(member, expect: expect + 2)
47
+ check_indentation(member, expect: expect + configured_indentation_width)
37
48
  end
38
49
  else
39
50
  check(decl, expect: expect)
@@ -52,6 +63,10 @@ module RuboCop
52
63
  end
53
64
  end
54
65
 
66
+ def configured_indentation_width
67
+ cop_config['Width'] || 2
68
+ end
69
+
55
70
  def line_start_pos(decl)
56
71
  rindex = processed_source.raw_source.rindex(/\R/, decl.location.start_pos)
57
72
  if rindex
@@ -26,11 +26,13 @@ module RuboCop
26
26
  extend AutoCorrector
27
27
 
28
28
  def on_rbs_def(decl)
29
- base_pos = decl.location.start_pos
30
- base_col = decl.location.start_column
31
- overload_starts = decl.overloads.map { |overload| overload.method_type.location.start_pos }
32
- tokens = ::RBS::Parser.lex(decl.location.source).value.reject { |t| t.type == :tTRIVIA }
33
- first_colon_column = base_col + tokens.find { |t| t.type == :pCOLON }&.location&.start_column
29
+ location = decl.location or return
30
+ base_pos = location.start_pos
31
+ base_col = location.start_column
32
+ overload_starts = decl.overloads.filter_map { |overload| overload.method_type.location&.start_pos }
33
+ tokens = ::RBS::Parser.lex(location.source).value.reject { |t| t.type == :tTRIVIA }
34
+ colon_column = tokens.find { |t| t.type == :pCOLON }&.location&.start_column or return
35
+ first_colon_column = base_col + colon_column
34
36
  ([nil] + tokens).each_cons(3) do |before, bar, after|
35
37
  next unless before
36
38
  next unless bar
@@ -20,6 +20,7 @@ module RuboCop
20
20
 
21
21
  def on_rbs_new_investigation
22
22
  processed_rbs_source.tokens.each_cons(2) do |comma, after|
23
+ next unless comma && after
23
24
  next unless comma.type == :pCOMMA
24
25
  next unless comma.location
25
26
  next unless comma.location.end_line == after.location.start_line
@@ -27,13 +27,15 @@ module RuboCop
27
27
 
28
28
  # @sig decl: ::RBS::AST::Members::MethodDefinition
29
29
  def on_rbs_def(decl)
30
- base = decl.location.start_pos
31
- tokens = ::RBS::Parser.lex(decl.location.source).value.reject { |t| t.type == :tTRIVIA }
30
+ location = decl.location or return
31
+ base = location.start_pos
32
+ tokens = ::RBS::Parser.lex(location.source).value.reject { |t| t.type == :tTRIVIA }
32
33
  ([nil] + tokens).each_cons(3) do |before, token, after|
33
34
  next unless token&.type == :pARROW
34
35
 
35
36
  loc = token&.location
36
37
  next unless loc
38
+ next unless after
37
39
 
38
40
  if before && (before.location.end_pos + 1 != loc.start_pos)
39
41
  next unless before.location.end_line == loc.start_line
@@ -18,9 +18,12 @@ module RuboCop
18
18
 
19
19
  # @sig decl: ::RBS::AST::Members::MethodDefinition
20
20
  def on_rbs_def(decl)
21
+ location = decl.location or return
21
22
  paren_level = 0
22
- tokens = ::RBS::Parser.lex(decl.location.source).value.reject { |t| t.type == :tTRIVIA }
23
+ tokens = ::RBS::Parser.lex(location.source).value.reject { |t| t.type == :tTRIVIA }
23
24
  ([nil] + tokens).each_cons(3) do |before, token, after|
25
+ next unless token && after
26
+
24
27
  case token.type
25
28
  when :pLPAREN # '('
26
29
  paren_level += 1
@@ -31,12 +34,12 @@ module RuboCop
31
34
  next unless (after.type == :pLPAREN || after.type == :pARROW)
32
35
  next unless paren_level == 0
33
36
 
34
- check_around_space(decl.location, before, token, after)
37
+ check_around_space(location, before, token, after)
35
38
  when :pRBRACE # '}'
36
39
  next unless after.type == :pARROW
37
40
  next unless paren_level == 0
38
41
 
39
- check_around_space(decl.location, before, token, after)
42
+ check_around_space(location, before, token, after)
40
43
  end
41
44
  end
42
45
  end
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # @sig decl: ::RBS::AST::Members::MethodDefinition
19
19
  def on_rbs_def(decl)
20
20
  source = processed_source.raw_source
21
- loc = decl.location
21
+ loc = decl.location or return
22
22
  colon_start_pos = source.index(':', loc.start_pos)
23
23
  return unless colon_start_pos
24
24
 
@@ -11,50 +11,10 @@ module RuboCop
11
11
  # def foo: (option?: bool, option!: bool, Option: bool) -> void
12
12
  #
13
13
  class AmbiguousKeywordArgumentKey < RuboCop::RBS::CopBase
14
+ include RuboCop::Cop::RBS::Mixin::AmbiguousKeywordArgumentKey
14
15
  extend AutoCorrector
15
16
 
16
- # @rbs decl: ::RBS::AST::Members::MethodDefinition
17
- def on_rbs_def(decl)
18
- decl.overloads.each do |overload|
19
- func = overload.method_type.type
20
- next unless func.kind_of?(::RBS::Types::Function)
21
- next unless !func.required_keywords.empty? || !func.optional_keywords.empty?
22
-
23
- base_pos = overload.method_type.location.start_pos
24
- lex_result = ::RBS::Parser.lex(overload.method_type.location.source)
25
- buf = []
26
- lex_result.value.each do |token|
27
- case token.type
28
- when :pLPAREN, :pRPAREN, :tTRIVIA
29
- # skip
30
- when :pCOLON
31
- next if buf.empty?
32
-
33
- case buf.last.type
34
- when :pQUESTION
35
- buf.shift if buf.first.type == :pQUESTION
36
- actual = buf.map { |t| t.location.source }.join
37
- did_you_mean = buf.reject { |t| t.location.source == '?' }.map { |t| t.location.source }.join
38
- message = +"`#{actual}` is not local variable name."
39
- if did_you_mean.length > 0
40
- message << " Did you mean `?#{did_you_mean}` for optional keyword argument?"
41
- end
42
- range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
43
- add_offense(range, message: message)
44
- when :tBANGIDENT, :tUIDENT
45
- buf.shift if buf.first.type == :pQUESTION
46
- actual = buf.map { |t| t.location.source }.join
47
- range = range_between(buf.first.location.start_pos + base_pos, buf.last.location.end_pos + base_pos)
48
- add_offense(range, message: "`#{actual}` is not local variable name.")
49
- end
50
- when :pCOMMA
51
- buf.clear
52
- else
53
- buf << token
54
- end
55
- end
56
- end
57
- end
17
+ alias on_rbs_def check_def
58
18
  end
59
19
  end
60
20
  end
@@ -36,6 +36,8 @@ module RuboCop
36
36
 
37
37
  def check_type(type)
38
38
  on_type([::RBS::Types::Union], type) do |union|
39
+ next unless union.is_a?(::RBS::Types::Union)
40
+
39
41
  union.types.each do |t|
40
42
  case t
41
43
  when ::RBS::Types::Intersection
@@ -23,6 +23,7 @@ module RuboCop
23
23
  class DuplicateAnnotation < RuboCop::RBS::CopBase
24
24
  MSG = 'Duplicate annotation detected.'
25
25
 
26
+ #: (::RBS::AST::Members::MethodDefinition) -> void
26
27
  def on_rbs_def(decl)
27
28
  decl.annotations.each_with_index do |annotation, idx|
28
29
  next_annotations = decl.annotations[(idx + 1)..] or next
@@ -41,6 +42,7 @@ module RuboCop
41
42
  end
42
43
  end
43
44
 
45
+ #: (::RBS::AST::Annotation, Array[::RBS::AST::Annotation]) -> void
44
46
  def check_annotations(left_annotation, right_annotations)
45
47
  right_annotations.each do |right_annotation|
46
48
  next unless left_annotation == right_annotation
@@ -13,31 +13,9 @@ module RuboCop
13
13
  # | () -> top
14
14
  #
15
15
  class DuplicateOverload < RuboCop::RBS::CopBase
16
- MSG = 'Duplicate overload arguments detected.'
16
+ include RuboCop::Cop::RBS::Mixin::DuplicateOverload
17
17
 
18
- def on_rbs_def(decl)
19
- overloads = decl.overloads
20
- overloads.each_with_index do |overload, idx|
21
- next if idx == overloads.size - 1
22
-
23
- next_overloads = overloads[(idx + 1)..-1]
24
- next_overloads.each do |next_overload|
25
- a = method_type_with_untyped_return_type(overload.method_type)
26
- b = method_type_with_untyped_return_type(next_overload.method_type)
27
- next unless a == b
28
-
29
- range = location_to_range(next_overload.method_type.location)
30
- add_offense(range)
31
- end
32
- end
33
- end
34
-
35
- private
36
-
37
- def method_type_with_untyped_return_type(method_type)
38
- type = method_type.type.with_return_type(::RBS::Types::Bases::Any.new(location: nil))
39
- method_type.update(type:)
40
- end
18
+ alias on_rbs_def check_def
41
19
  end
42
20
  end
43
21
  end
@@ -14,45 +14,14 @@ module RuboCop
14
14
  # 1 & _Foo
15
15
  #
16
16
  class LiteralIntersection < RuboCop::RBS::CopBase
17
- MSG = "Don't use literals with `&`."
17
+ include RuboCop::Cop::RBS::Mixin::LiteralIntersection
18
18
 
19
- def on_rbs_def(decl)
20
- decl.overloads.each do |overload|
21
- overload.method_type.each_type do |type|
22
- check_type(type)
23
- end
24
- end
25
- end
26
-
27
- def check_type(type)
28
- on_type([::RBS::Types::Intersection], type) do |intersection|
29
- check_intersection(intersection)
30
- end
31
- end
32
-
33
- def on_rbs_constant(type)
34
- check_type(type.type)
35
- end
36
- alias on_rbs_global on_rbs_constant
37
- alias on_rbs_type_alias on_rbs_constant
38
- alias on_rbs_attribute on_rbs_constant
39
- alias on_rbs_var on_rbs_constant
40
-
41
- def check_intersection(intersection)
42
- intersection.types.each do |type|
43
- check_intersection_child(type)
44
- end
45
- end
46
-
47
- def check_intersection_child(type)
48
- case type
49
- when ::RBS::Types::Literal
50
- range = location_to_range(type.location)
51
- add_offense(range)
52
- when ::RBS::Types::Intersection
53
- check_intersection(type)
54
- end
55
- end
19
+ alias on_rbs_def check_def
20
+ alias on_rbs_constant check_member
21
+ alias on_rbs_global check_member
22
+ alias on_rbs_type_alias check_member
23
+ alias on_rbs_attribute check_member
24
+ alias on_rbs_var check_member
56
25
  end
57
26
  end
58
27
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rbs_inline: enabled
4
-
5
3
  module RuboCop
6
4
  module Cop
7
5
  module RBS
@@ -18,24 +16,9 @@ module RuboCop
18
16
  # def self.new: () -> instance
19
17
  #
20
18
  class NewReturnsVoid < RuboCop::RBS::CopBase
21
- MSG = "Don't use `void` in self.new method. Did you mean `instance`?"
22
-
23
- # @rbs decl: RBS::AST::Members::MethodDefinition
24
- def on_rbs_def(decl)
25
- return unless decl.kind == :singleton
26
- return unless decl.name == :new
27
-
28
- decl.overloads.each do |overload|
29
- return_type = overload.method_type.type.return_type
30
- case return_type
31
- when ::RBS::Types::Bases::Void
32
- next unless return_type.location
19
+ include RuboCop::Cop::RBS::Mixin::NewReturnsVoid
33
20
 
34
- range = location_to_range(return_type.location)
35
- add_offense(range)
36
- end
37
- end
38
- end
21
+ alias on_rbs_def check_def
39
22
  end
40
23
  end
41
24
  end