rubocop-on-rbs 2.0.0.dev → 2.1.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/README.md +1 -4
  4. data/config/default.yml +6 -4
  5. data/lib/rubocop/cop/rbs/layout/annotation_indentation.rb +90 -0
  6. data/lib/rubocop/cop/rbs/layout/comment_indentation.rb +34 -32
  7. data/lib/rubocop/cop/rbs/layout/empty_lines_around_access_modifier.rb +4 -3
  8. data/lib/rubocop/cop/rbs/layout/empty_lines_around_body.rb +8 -0
  9. data/lib/rubocop/cop/rbs/layout/empty_lines_around_overloads.rb +22 -6
  10. data/lib/rubocop/cop/rbs/layout/end_alignment.rb +2 -1
  11. data/lib/rubocop/cop/rbs/layout/extra_spacing.rb +1 -0
  12. data/lib/rubocop/cop/rbs/layout/indentation_width.rb +17 -2
  13. data/lib/rubocop/cop/rbs/layout/overload_indentation.rb +16 -6
  14. data/lib/rubocop/cop/rbs/layout/space_after_comma.rb +1 -0
  15. data/lib/rubocop/cop/rbs/layout/space_around_arrow.rb +4 -2
  16. data/lib/rubocop/cop/rbs/layout/space_around_braces.rb +6 -3
  17. data/lib/rubocop/cop/rbs/layout/space_around_operators.rb +19 -1
  18. data/lib/rubocop/cop/rbs/layout/space_before_colon.rb +1 -1
  19. data/lib/rubocop/cop/rbs/layout/space_before_overload.rb +27 -13
  20. data/lib/rubocop/cop/rbs/lint/ambiguous_keyword_argument_key.rb +3 -2
  21. data/lib/rubocop/cop/rbs/lint/ambiguous_operator_precedence.rb +2 -0
  22. data/lib/rubocop/cop/rbs/lint/duplicate_annotation.rb +2 -0
  23. data/lib/rubocop/cop/rbs/lint/duplicate_overload.rb +3 -2
  24. data/lib/rubocop/cop/rbs/lint/new_returns_void.rb +0 -2
  25. data/lib/rubocop/cop/rbs/lint/top_level_interface.rb +6 -4
  26. data/lib/rubocop/cop/rbs/lint/top_level_type_alias.rb +6 -4
  27. data/lib/rubocop/cop/rbs/lint/useless_access_modifier.rb +3 -3
  28. data/lib/rubocop/cop/rbs/style/block_return_boolish.rb +1 -0
  29. data/lib/rubocop/cop/rbs/style/class_with_singleton.rb +1 -1
  30. data/lib/rubocop/cop/rbs/style/classic_type.rb +6 -5
  31. data/lib/rubocop/cop/rbs/style/initialize_return_type.rb +1 -0
  32. data/lib/rubocop/cop/rbs/style/instance_with_instance.rb +1 -1
  33. data/lib/rubocop/cop/rbs/style/optional_nil.rb +1 -1
  34. data/lib/rubocop/cop/rbs/style/redundant_parentheses.rb +19 -5
  35. data/lib/rubocop/cop/rbs/style/true_false.rb +1 -1
  36. data/lib/rubocop/cop/rbs_cops.rb +1 -1
  37. data/lib/rubocop/rbs/cop_base.rb +29 -1
  38. data/lib/rubocop/rbs/on_type_helper.rb +2 -0
  39. data/lib/rubocop/rbs/processed_rbs_source.rb +10 -5
  40. data/lib/rubocop/rbs/version.rb +1 -1
  41. metadata +8 -8
  42. data/lib/rubocop/cop/rbs/lint/will_syntax_error.rb +0 -228
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb12bf04d27c5b1e90a4537e696d0f43e3440653244e71ab14bd189ef876ad1d
4
- data.tar.gz: 265c57dc1917d19594e7175696147db9668a48b57c1b463472488e8bae4eade6
3
+ metadata.gz: 43791277046bd585b3979b68148eb004aa7212cbcdd5301f7d5001915cf20b8a
4
+ data.tar.gz: b261814ee8ff54554e351e018c688821df1fff4b1bc78c9b6440df53e8db2029
5
5
  SHA512:
6
- metadata.gz: 808e37b431fcbad539a5fc99910816f15d00ccde4f35c9e3139e76c22b458680ab9a3e5130436d7fe4d83d9967cea0c777f07b542b72cc669b6011a9a20e29a6
7
- data.tar.gz: 9951c42a0f33cdca49d1c580ceecbb0d774b3534794e55ed08e69e274a657f8262f218ed759de4ef93c99ffd1aba79da238225f32f96edc2a4e990e5caaa5a46
6
+ metadata.gz: 0a2e89869da1c6353ba2cf7baec53629244a69538f94e0ae6523cae22165fd4775f78d5bbfd7a0925ce2b992567b256e73a956306d8c0022b599db89f67e092b
7
+ data.tar.gz: 53fea77b783bd0a3f53a2c59129e2cae7161c78c923cda78ce0ea7875e1a8ed53a2923df8aa438bb1143f3d0bfbfda410f6ab3c3ef0be1ca378664f7679b511c
data/CHANGELOG.md CHANGED
@@ -1,6 +1,59 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.1.0] - 2026-09-27
4
+
5
+ * Drop support for Ruby v3.2 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/153
6
+ * [RBS/Layout/IndentationWidth] Support `Width` option by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/157
7
+
8
+ ## [2.0.0] - 2026-03-27
9
+
10
+ * Support rbs v4 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/145
11
+ * Drop `RBS/Lint/WillSyntaxError` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/145
12
+
13
+ ## [1.9.1] - 2026-02-10
14
+
15
+ * [RBS/Layout/OverloadIndentation] Fix false positive by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/141
16
+ * [RBS/Layout/EmptyLinesAroundOverloads] Fix false positive by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/142
17
+ * [RBS/Layout/SpaceBeforeOverload] Support `...` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/143
18
+
19
+ ## [1.9.0] - 2026-01-14
20
+
21
+ * Add cop `RBS/Layout/AnnotationIndentation` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/124
22
+ * Fix bug when multi annotation by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/125
23
+ * [RBS/Layout/SpaceAroundOperators] Support type params by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/126
24
+ * Support new Cops by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/129
25
+ * [RBS/Layout/CommentIndentation] Fix false positive by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/136
26
+ * Use ruby v4 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/137
27
+
28
+ ## [1.8.0] - 2025-06-26
29
+
30
+ * Add task for update dependencies by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/110
31
+ * Should melt down Gemfile.lock by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/111
32
+ * Dynamically generate document URLs by version by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/114
33
+ * Add new cop `RBS/Lint/ImplicitlyReturnsNil` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/115
34
+ * [RBS/Lint/DuplicateOverload] Ignore the difference of return type. by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/116
35
+ * Add `RBS/Lint/DuplicateAnnotation` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/117
36
+ * Fix message by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/118
37
+
38
+ ## [1.7.0] - 2025-05-18
39
+
40
+ * Add `RBS/Lint/RestKeywordHash` by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/102
41
+ * Support documentation URL for department by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/103
42
+ * Refine documentation by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/104
43
+ * Add RBS/Layout/EmptyLineBetweenDeclarations by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/105
44
+ * [RBS/Layout/EmptyLineBetweenDeclarations] Short fix by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/106
45
+
46
+ ## [1.6.0] - 2025-04-25
47
+
48
+ * [RBS::Style::TrueFalse] More support decls by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/97
49
+ * [RBS/Style/OptionalNil] More support decls by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/98
50
+ * [RBS/Style/DuplicatedType] More support decls by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/100
51
+
52
+ ## [1.5.0] - 2025-03-23
53
+
3
54
  * Pluginfy RuboCop on RBS by @ydah in https://github.com/ksss/rubocop-on-rbs/pull/88
55
+ * Drop support for ruby v3.1 by @ksss in https://github.com/ksss/rubocop-on-rbs/pull/90
56
+ * Fix RuboCop RakeTask plugin assignment in README by @ydah in https://github.com/ksss/rubocop-on-rbs/pull/92
4
57
 
5
58
  ## [1.4.2] - 2025-02-23
6
59
 
data/README.md CHANGED
@@ -24,11 +24,8 @@ def foo: ( void) -> untyped
24
24
  sig/foo.rbs:2:11: C: [Correctable] RBS/Layout/ExtraSpacing: Unnecessary spacing detected.
25
25
  def foo: ( void) -> untyped
26
26
  ^^
27
- sig/foo.rbs:2:14: W: RBS/Lint/WillSyntaxError: void type is only allowed in return type or generics parameter
28
- def foo: ( void) -> untyped
29
- ^^^^
30
27
 
31
- 1 file inspected, 3 offenses detected, 2 offenses autocorrectable
28
+ 1 file inspected, 2 offenses detected, 2 offenses autocorrectable
32
29
  ```
33
30
 
34
31
  ## Support VSCode
data/config/default.yml CHANGED
@@ -27,6 +27,10 @@ RBS:
27
27
  RBS/Layout:
28
28
  Enabled: true
29
29
 
30
+ RBS/Layout/AnnotationIndentation:
31
+ Description: 'Use 2 spaces for annotation indentation'
32
+ Enabled: true
33
+
30
34
  RBS/Layout/CommentIndentation:
31
35
  Description: 'Use 2 spaces for comment indentation'
32
36
  Enabled: true
@@ -73,6 +77,8 @@ RBS/Layout/ExtraSpacing:
73
77
  RBS/Layout/IndentationWidth:
74
78
  Description: 'Use 2 spaces for indentation'
75
79
  Enabled: true
80
+ # Number of spaces for each indentation level.
81
+ Width: 2
76
82
 
77
83
  RBS/Layout/OverloadIndentation:
78
84
  Description: 'Indent overload method'
@@ -172,10 +178,6 @@ RBS/Lint/UnusedTypeAliasTypeParams:
172
178
  Description: 'Check redundant type alias type params'
173
179
  Enabled: true
174
180
 
175
- RBS/Lint/WillSyntaxError:
176
- Description: 'Check RBS will syntax error'
177
- Enabled: true
178
-
179
181
  ## RBS/Style
180
182
 
181
183
  RBS/Style:
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RBS
6
+ module Layout
7
+ # Checks the indentation of annotations in RBS.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # # comment
12
+ # %a{pure}
13
+ # def foo: () -> void
14
+ #
15
+ # # good
16
+ # # comment
17
+ # %a{pure}
18
+ # def foo: () -> void
19
+ #
20
+ class AnnotationIndentation < RuboCop::RBS::CopBase
21
+ extend AutoCorrector
22
+
23
+ MSG = "Incorrect indentation detected (column %<expect>s instead of %<actual>s)."
24
+
25
+ def on_rbs_new_investigation
26
+ indent_start_lines = Set.new
27
+ indent_end_lines = Set.new
28
+ ignore_poses = Set.new
29
+ processed_rbs_source.decls.each do |decl|
30
+ walk_decl(decl) do |d|
31
+ indent_start_lines << d.location.start_line
32
+ indent_end_lines << d.location.end_line
33
+ d.members.each do |member|
34
+ case member
35
+ when ::RBS::AST::Members::MethodDefinition
36
+ member.overloads.each do |overload|
37
+ overload.annotations.each do |annotation|
38
+ location = annotation.location or next
39
+ ignore_poses << location.start_pos
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ expected_width = 0
48
+ last_annotation_line = -1
49
+ processed_rbs_source.tokens.each do |token|
50
+ case token.type
51
+ when :kMODULE, :kCLASS, :kINTERFACE
52
+ next unless indent_start_lines.include?(token.location.start_line)
53
+
54
+ expected_width += 2
55
+ when :kEND
56
+ next unless indent_end_lines.include?(token.location.start_line)
57
+
58
+ expected_width -= 2
59
+ when :tANNOTATION
60
+ next if ignore_poses.include?(token.location.start_pos)
61
+
62
+ if token.location.start_column == expected_width
63
+ last_annotation_line = token.location.start_line
64
+ next
65
+ end
66
+ next if last_annotation_line == token.location.start_line
67
+
68
+ token_range = location_to_range(token.location)
69
+ message = format(MSG, expect: expected_width, actual: token.location.start_column)
70
+ last_annotation_line = token.location.start_line
71
+ add_offense(token_range, message: message) do |corrector|
72
+ line_start_pos = processed_source.buffer.line_range(token.location.start_line).begin_pos
73
+ indent = range_between(line_start_pos, token.location.start_pos)
74
+ corrector.replace(indent, ' ' * expected_width)
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def walk_decl(decl, &block)
81
+ if decl.respond_to?(:members)
82
+ yield decl
83
+ decl.members.each { |member| walk_decl(member, &block) }
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -21,45 +21,47 @@ module RuboCop
21
21
  MSG = "Incorrect indentation detected (column %<expect>s instead of %<actual>s)."
22
22
 
23
23
  def on_rbs_new_investigation
24
- indent_start_lines = Set.new
25
- indent_end_lines = Set.new
26
- processed_rbs_source.decls.each do |decl|
27
- walk_decl(decl) do |d|
28
- indent_start_lines << d.location.start_line
29
- indent_end_lines << d.location.end_line
30
- end
24
+ comments = processed_rbs_source.tokens.select { |token| token.type == :tLINECOMMENT }
25
+ comments.each_with_index do |token, comment_index|
26
+ check(token, comment_index)
31
27
  end
28
+ end
32
29
 
33
- expected_width = 0
34
- processed_rbs_source.tokens.each do |token|
35
- case token.type
36
- when :kMODULE, :kCLASS, :kINTERFACE
37
- next unless indent_start_lines.include?(token.location.start_line)
30
+ def check(comment_token, _comment_index)
31
+ next_line = line_after_comment(comment_token)
32
+ correct_comment_indentation = correct_indentation(next_line)
33
+ column = comment_token.location.start_column
38
34
 
39
- expected_width += 2
40
- when :kEND
41
- next unless indent_end_lines.include?(token.location.start_line)
35
+ column_delta = correct_comment_indentation - column
36
+ return if column_delta.zero?
42
37
 
43
- expected_width -= 2
44
- when :tLINECOMMENT
45
- if token.location.start_column != expected_width
46
- token_range = location_to_range(token.location)
47
- message = format(MSG, expect: expected_width, actual: token.location.start_column)
48
- add_offense(token_range, message: message) do |corrector|
49
- line_start_pos = processed_source.buffer.line_range(token.location.start_line).begin_pos
50
- indent = range_between(line_start_pos, token.location.start_pos)
51
- corrector.replace(indent, ' ' * expected_width)
52
- end
53
- end
54
- end
38
+ token_range = location_to_range(comment_token.location)
39
+ message = format(MSG, expect: correct_comment_indentation, actual: column)
40
+ add_offense(token_range, message: message) do |corrector|
41
+ line_start_pos = processed_source.buffer.line_range(comment_token.location.start_line).begin_pos
42
+ indent = range_between(line_start_pos, comment_token.location.start_pos)
43
+ corrector.replace(indent, ' ' * correct_comment_indentation)
55
44
  end
56
45
  end
57
46
 
58
- def walk_decl(decl, &block)
59
- if decl.respond_to?(:members)
60
- yield decl
61
- decl.members.each { |member| walk_decl(member, &block) }
62
- end
47
+ def line_after_comment(comment)
48
+ lines = processed_source.lines
49
+ lines[comment.location.start_line..]&.find { |line| !line.blank? }
50
+ end
51
+
52
+ def correct_indentation(next_line)
53
+ return 0 unless next_line
54
+
55
+ indentation_of_next_line = next_line =~ /\S/
56
+ indentation_of_next_line + if less_indented?(next_line)
57
+ 2
58
+ else
59
+ 0
60
+ end
61
+ end
62
+
63
+ def less_indented?(line)
64
+ /\A\s*end\b/.match?(line)
63
65
  end
64
66
  end
65
67
  end
@@ -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
 
@@ -68,7 +69,7 @@ module RuboCop
68
69
  end
69
70
 
70
71
  def previous_line_ignoring_comments(processed_source, send_line)
71
- processed_source[0..send_line - 2].reverse.find { |line| !comment_line?(line) }
72
+ processed_source[0..(send_line - 2)].reverse.find { |line| !comment_line?(line) }
72
73
  end
73
74
 
74
75
  def previous_line_empty?(send_line)
@@ -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]
@@ -21,19 +21,35 @@ module RuboCop
21
21
 
22
22
  MSG = 'Empty line detected around overloads.'
23
23
 
24
+ # @rbs decl: ::RBS::AST::Members::MethodDefinition
25
+ # @rbs return: void
24
26
  def on_rbs_def(decl)
25
- return unless 1 < decl.overloads.length
26
-
27
27
  decl.overloads.each_cons(2) do |overload, next_overload|
28
- check_empty_lines(overload, next_overload)
28
+ end_line = overload&.method_type&.location&.end_line || 0
29
+ next_start_line = next_overload&.method_type&.location&.start_line || 0
30
+ check_empty_lines(end_line, next_start_line)
31
+ end
32
+
33
+ if decl.overloading? && decl.overloads.length.positive?
34
+ # : () -> void
35
+ #
36
+ # | ...
37
+ end_location = decl.overloads.last.method_type.location or return
38
+ slice = processed_source.raw_source[end_location.end_pos..] or return
39
+ bar_index = slice.index('|') or return
40
+ bar_line = slice[0..bar_index]&.count("\n") or return
41
+ check_empty_lines(end_location.end_line, end_location.end_line + bar_line)
29
42
  end
30
43
  end
31
44
 
32
- def check_empty_lines(overload, next_overload)
33
- return if overload.method_type.location.end_line + 1 == next_overload.method_type.location.start_line
45
+ # @rbs end_line: Integer
46
+ # @rbs next_start_line: Integer
47
+ # @rbs return: void
48
+ def check_empty_lines(end_line, next_start_line)
49
+ return if end_line + 1 == next_start_line
34
50
 
35
51
  total = 0
36
- range = overload.method_type.location.end_line...(next_overload.method_type.location.start_line - 1)
52
+ range = end_line...(next_start_line - 1)
37
53
  processed_source.raw_source.each_line.each_with_index do |line, lineno|
38
54
  if range.cover?(lineno) && line == "\n"
39
55
  empty_line = range_between(total, total + 1)
@@ -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
@@ -39,8 +41,11 @@ module RuboCop
39
41
 
40
42
  loc = bar&.location
41
43
  next unless loc
42
- next unless overload_starts.include?(base_pos + after.location.start_pos)
43
44
 
45
+ # pDOT3 is not included in decl.overloads
46
+ next unless overload_starts.include?(base_pos + after.location.start_pos) || after.type == :pDOT3
47
+
48
+ # () -> void | (Integer) -> void
44
49
  if before.location.end_line == bar.location.start_line
45
50
  range = range_between(base_pos + bar.location.start_pos, base_pos + bar.location.end_pos)
46
51
  add_offense(range, message: "Insert newline before `|`") do |corrector|
@@ -49,12 +54,17 @@ module RuboCop
49
54
  end
50
55
  end
51
56
 
57
+ # () -> void
58
+ # |
59
+ # (Integer) -> void
52
60
  if bar.location.end_line != after.location.start_line
53
61
  range = range_between(base_pos + bar.location.start_pos, base_pos + bar.location.end_pos)
54
62
  add_offense(range, message: "Remove newline after `|`") do |corrector|
55
63
  space = range_between(base_pos + bar.location.end_pos, base_pos + after.location.start_pos)
56
64
  corrector.replace(space, ' ')
57
65
  end
66
+ # : () -> void
67
+ # | (Integer) -> void
58
68
  elsif bar.location.start_column != first_colon_column
59
69
  range = range_between(base_pos + bar.location.start_pos, base_pos + bar.location.end_pos)
60
70
  add_offense(range, message: 'Indent the `|` to the first `:`') do |corrector|
@@ -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
@@ -14,8 +14,15 @@ module RuboCop
14
14
  class SpaceAroundOperators < RuboCop::RBS::CopBase
15
15
  extend AutoCorrector
16
16
 
17
+ def on_rbs_class(decl)
18
+ check_type_params(decl)
19
+ end
20
+ alias on_rbs_module on_rbs_class
21
+ alias on_rbs_interface on_rbs_class
22
+
17
23
  def on_rbs_def(decl)
18
24
  decl.overloads.each do |overload|
25
+ check_type_params(overload.method_type)
19
26
  overload.method_type.each_type do |type|
20
27
  check_type(type)
21
28
  end
@@ -26,10 +33,14 @@ module RuboCop
26
33
  check_type(decl.type)
27
34
  end
28
35
  alias on_rbs_global on_rbs_constant
29
- alias on_rbs_type_alias on_rbs_constant
30
36
  alias on_rbs_attribute on_rbs_constant
31
37
  alias on_rbs_var on_rbs_constant
32
38
 
39
+ def on_rbs_type_alias(decl)
40
+ check_type_params(decl)
41
+ check_type(decl.type)
42
+ end
43
+
33
44
  def check_type(type)
34
45
  case type
35
46
  when ::RBS::Types::Union
@@ -42,6 +53,13 @@ module RuboCop
42
53
  end
43
54
  end
44
55
 
56
+ def check_type_params(decl)
57
+ decl.type_params.each do |type_param|
58
+ check_type(type_param.default_type) if type_param.default_type
59
+ check_type(type_param.upper_bound_type) if type_param.upper_bound_type
60
+ end
61
+ end
62
+
45
63
  def check_operator(type, operator)
46
64
  type.types.each_cons(2) do |before, after|
47
65
  next unless before.location.end_line == after.location.start_line
@@ -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