rubocop 1.75.4 → 1.75.6

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +2 -0
  3. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  4. data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
  5. data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
  6. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -1
  7. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  8. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  9. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  10. data/lib/rubocop/cop/lint/duplicate_methods.rb +44 -2
  11. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  12. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -0
  13. data/lib/rubocop/cop/lint/void.rb +2 -2
  14. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  15. data/lib/rubocop/cop/mixin/trailing_comma.rb +6 -2
  16. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
  17. data/lib/rubocop/cop/style/comparable_between.rb +3 -0
  18. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  19. data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
  20. data/lib/rubocop/cop/style/if_unless_modifier.rb +20 -0
  21. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -0
  22. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  23. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  24. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  25. data/lib/rubocop/cop/style/string_concatenation.rb +1 -2
  26. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  27. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -0
  28. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  29. data/lib/rubocop/version.rb +1 -1
  30. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fc4cebf1565ee3ced4efc79eb1012c0750f797f0ba74f94620ff50ff1d7be8e
4
- data.tar.gz: b1e53688b07611ebec3ebc028022f71314960573cc421cfdd1b6c6b831008abf
3
+ metadata.gz: 4692afe0e994fae9d158ac440d48f460623d28bbad07fc7ccf141aa3737e82a1
4
+ data.tar.gz: 3dba40c9526a877cdc7269d54b3c89e3d64f8147cb5e2b885146c1d02d94bc19
5
5
  SHA512:
6
- metadata.gz: b124c47ddee3e947bbcda187086ae1a8bf45317702d6ab0bc43f7888b90c8d560c12f61ae6fc4890bf5fec29016d88678cbc08db84e9dad5ee3ec242c8e03884
7
- data.tar.gz: fcc14e85af8aac9186971fa21371743f29221c8e694c7cf17b44762d628c7246d720b3e241f006286a43f3523e6ab9e587e0c2f0aecb5d34fe849375ca7ad183
6
+ metadata.gz: acd7a48eac01d73747fb22cef86c75c4b2da8a910f341ddda19572eabd9126e8a42edac565df8ce0e6946e69f44d892e08c358dd9c6d72455974c05277731e3e
7
+ data.tar.gz: 2afef8e39089e476050a24aa63e4f637a4765759b31c74672740fb86067dada674140574c61a0d426950ea57e36c7b5bdc00db5cbab14e0000fa7aa065e83c6c
data/config/default.yml CHANGED
@@ -3702,7 +3702,9 @@ Style/CommentedKeyword:
3702
3702
  Style/ComparableBetween:
3703
3703
  Description: 'Enforces the use of `Comparable#between?` instead of logical comparison.'
3704
3704
  Enabled: pending
3705
+ Safe: false
3705
3706
  VersionAdded: '1.74'
3707
+ VersionChanged: '1.75'
3706
3708
  StyleGuide: '#ranges-or-between'
3707
3709
 
3708
3710
  Style/ComparableClamp:
@@ -250,7 +250,7 @@ module RuboCop
250
250
  reset!
251
251
 
252
252
  alignment_for(first_pair).each do |alignment|
253
- delta = alignment.deltas_for_first_pair(first_pair, node)
253
+ delta = alignment.deltas_for_first_pair(first_pair)
254
254
  check_delta delta, node: first_pair, alignment: alignment
255
255
  end
256
256
 
@@ -58,6 +58,12 @@ module RuboCop
58
58
  # attr_reader :name #: String
59
59
  # attr_reader :age #: Integer?
60
60
  #
61
+ # #: (
62
+ # #| Integer,
63
+ # #| String
64
+ # #| ) -> void
65
+ # def foo; end
66
+ #
61
67
  # @example AllowRBSInlineAnnotation: true
62
68
  #
63
69
  # # good
@@ -67,6 +73,12 @@ module RuboCop
67
73
  # attr_reader :name #: String
68
74
  # attr_reader :age #: Integer?
69
75
  #
76
+ # #: (
77
+ # #| Integer,
78
+ # #| String
79
+ # #| ) -> void
80
+ # def foo; end
81
+ #
70
82
  # @example AllowSteepAnnotation: false (default)
71
83
  #
72
84
  # # bad
@@ -175,7 +187,7 @@ module RuboCop
175
187
  end
176
188
 
177
189
  def rbs_inline_annotation?(comment)
178
- allow_rbs_inline_annotation? && comment.text.start_with?(/#:|#\[.+\]/)
190
+ allow_rbs_inline_annotation? && comment.text.start_with?(/#:|#\[.+\]|#\|/)
179
191
  end
180
192
 
181
193
  def allow_steep_annotation?
@@ -23,6 +23,16 @@ module RuboCop
23
23
  def kind(token)
24
24
  'semicolon' if token.semicolon?
25
25
  end
26
+
27
+ def space_missing?(token1, token2)
28
+ super && !semicolon_sequence?(token1, token2)
29
+ end
30
+
31
+ private
32
+
33
+ def semicolon_sequence?(token, next_token)
34
+ token.semicolon? && next_token.semicolon?
35
+ end
26
36
  end
27
37
  end
28
38
  end
@@ -6,6 +6,8 @@ module RuboCop
6
6
  # Checks that brackets used for array literals have or don't have
7
7
  # surrounding space depending on configuration.
8
8
  #
9
+ # Array pattern matching is handled in the same way.
10
+ #
9
11
  # @example EnforcedStyle: no_space (default)
10
12
  # # The `no_space` style enforces that array literals have
11
13
  # # no surrounding space.
@@ -82,9 +84,10 @@ module RuboCop
82
84
  EMPTY_MSG = '%<command>s space inside empty array brackets.'
83
85
 
84
86
  def on_array(node)
85
- return unless node.square_brackets?
87
+ return if node.array_type? && !node.square_brackets?
86
88
 
87
89
  tokens, left, right = array_brackets(node)
90
+ return unless left && right
88
91
 
89
92
  if empty_brackets?(left, right, tokens: tokens)
90
93
  return empty_offenses(node, left, right, EMPTY_MSG)
@@ -95,6 +98,7 @@ module RuboCop
95
98
 
96
99
  issue_offenses(node, left, right, start_ok, end_ok)
97
100
  end
101
+ alias on_array_pattern on_array
98
102
 
99
103
  private
100
104
 
@@ -6,6 +6,8 @@ module RuboCop
6
6
  # Checks that braces used for hash literals have or don't have
7
7
  # surrounding space depending on configuration.
8
8
  #
9
+ # Hash pattern matching is handled in the same way.
10
+ #
9
11
  # @example EnforcedStyle: space (default)
10
12
  # # The `space` style enforces that hash literals have
11
13
  # # surrounding space.
@@ -87,6 +89,7 @@ module RuboCop
87
89
  check(tokens[-2], tokens[-1]) if tokens.size > 2
88
90
  check_whitespace_only_hash(node) if enforce_no_space_style_for_empty_braces?
89
91
  end
92
+ alias on_hash_pattern on_hash
90
93
 
91
94
  private
92
95
 
@@ -51,10 +51,9 @@ module RuboCop
51
51
  'in a regexp.'
52
52
 
53
53
  def on_interpolation(begin_node)
54
- final_node = begin_node.children.last
55
-
56
- return unless begin_node.parent.regexp_type?
54
+ return unless (final_node = begin_node.children.last)
57
55
  return unless final_node.array_type?
56
+ return unless begin_node.parent.regexp_type?
58
57
 
59
58
  if array_of_literal_values?(final_node)
60
59
  register_array_of_literal_values(begin_node, final_node)
@@ -43,7 +43,7 @@ module RuboCop
43
43
  dup: 'to_h',
44
44
  exists?: 'exist?',
45
45
  gethostbyaddr: 'Addrinfo#getnameinfo',
46
- gethostbyname: 'Addrinfo#getaddrinfo',
46
+ gethostbyname: 'Addrinfo.getaddrinfo',
47
47
  iterator?: 'block_given?'
48
48
  }.freeze
49
49
 
@@ -39,9 +39,35 @@ module RuboCop
39
39
  # end
40
40
  #
41
41
  # alias bar foo
42
+ #
43
+ # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
44
+ #
45
+ # # good
46
+ # def foo
47
+ # 1
48
+ # end
49
+ #
50
+ # delegate :foo, to: :bar
51
+ #
52
+ # @example AllCops:ActiveSupportExtensionsEnabled: true
53
+ #
54
+ # # bad
55
+ # def foo
56
+ # 1
57
+ # end
58
+ #
59
+ # delegate :foo, to: :bar
60
+ #
61
+ # # good
62
+ # def foo
63
+ # 1
64
+ # end
65
+ #
66
+ # delegate :baz, to: :bar
42
67
  class DuplicateMethods < Base
43
68
  MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
44
- RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr].freeze
69
+ RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr
70
+ delegate].freeze
45
71
 
46
72
  def initialize(config = nil, options = nil)
47
73
  super
@@ -85,15 +111,25 @@ module RuboCop
85
111
  (send nil? :alias_method (sym $_name) _)
86
112
  PATTERN
87
113
 
114
+ # @!method delegate_method?(node)
115
+ def_node_matcher :delegate_method?, <<~PATTERN
116
+ (send nil? :delegate (sym $_)+ (hash _))
117
+ PATTERN
118
+
88
119
  # @!method sym_name(node)
89
120
  def_node_matcher :sym_name, '(sym $_name)'
90
- def on_send(node)
121
+
122
+ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
91
123
  if (name = alias_method?(node))
92
124
  return if node.ancestors.any?(&:if_type?)
93
125
 
94
126
  found_instance_method(node, name)
95
127
  elsif (attr = node.attribute_accessor?)
96
128
  on_attr(node, *attr)
129
+ elsif active_support_extensions_enabled? && (names = delegate_method?(node))
130
+ return if node.ancestors.any?(&:if_type?)
131
+
132
+ on_delegate(node, names)
97
133
  end
98
134
  end
99
135
 
@@ -118,6 +154,12 @@ module RuboCop
118
154
  current: source_location(node))
119
155
  end
120
156
 
157
+ def on_delegate(node, method_names)
158
+ method_names.each do |name|
159
+ found_instance_method(node, name)
160
+ end
161
+ end
162
+
121
163
  def found_instance_method(node, name)
122
164
  return found_sclass_method(node, name) unless (scope = node.parent_module_name)
123
165
 
@@ -248,7 +248,7 @@ module RuboCop
248
248
  add_offense(cond) do |corrector|
249
249
  corrector.replace(node, "else\n #{node.else_branch.source}")
250
250
  end
251
- elsif result
251
+ elsif node.if_branch && result
252
252
  add_offense(cond) do |corrector|
253
253
  corrector.replace(node, node.if_branch.source)
254
254
  end
@@ -104,6 +104,8 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def chained_assignment?(node)
107
+ return true if node.lvasgn_type? && node.expression&.send_type?
108
+
107
109
  node.respond_to?(:expression) && node.expression&.lvasgn_type?
108
110
  end
109
111
 
@@ -128,8 +128,8 @@ module RuboCop
128
128
 
129
129
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
130
130
  def check_void_op(node, &block)
131
- node = node.children.first while node.begin_type?
132
- return unless node.call_type? && OPERATORS.include?(node.method_name)
131
+ node = node.children.first while node&.begin_type?
132
+ return unless node&.call_type? && OPERATORS.include?(node.method_name)
133
133
  if !UNARY_OPERATORS.include?(node.method_name) && node.loc.dot && node.arguments.none?
134
134
  return
135
135
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  true
11
11
  end
12
12
 
13
- def deltas_for_first_pair(first_pair, _node)
13
+ def deltas_for_first_pair(first_pair)
14
14
  {
15
15
  separator: separator_delta(first_pair),
16
16
  value: value_delta(first_pair)
@@ -81,13 +81,7 @@ module RuboCop
81
81
  class TableAlignment
82
82
  include ValueAlignment
83
83
 
84
- def initialize
85
- self.max_key_width = 0
86
- end
87
-
88
- def deltas_for_first_pair(first_pair, node)
89
- self.max_key_width = node.keys.map { |key| key.source.length }.max
90
-
84
+ def deltas_for_first_pair(first_pair)
91
85
  separator_delta = separator_delta(first_pair, first_pair, 0)
92
86
  {
93
87
  separator: separator_delta,
@@ -97,30 +91,37 @@ module RuboCop
97
91
 
98
92
  private
99
93
 
100
- attr_accessor :max_key_width
101
-
102
94
  def key_delta(first_pair, current_pair)
103
95
  first_pair.key_delta(current_pair)
104
96
  end
105
97
 
106
98
  def hash_rocket_delta(first_pair, current_pair)
107
- first_pair.loc.column + max_key_width + 1 - current_pair.loc.operator.column
99
+ first_pair.loc.column + max_key_width(first_pair.parent) + 1 -
100
+ current_pair.loc.operator.column
108
101
  end
109
102
 
110
103
  def value_delta(first_pair, current_pair)
111
104
  correct_value_column = first_pair.key.loc.column +
112
- current_pair.delimiter(true).length +
113
- max_key_width
105
+ max_key_width(first_pair.parent) +
106
+ max_delimiter_width(first_pair.parent)
114
107
 
115
108
  current_pair.value_omission? ? 0 : correct_value_column - current_pair.value.loc.column
116
109
  end
110
+
111
+ def max_key_width(hash_node)
112
+ hash_node.keys.map { |key| key.source.length }.max
113
+ end
114
+
115
+ def max_delimiter_width(hash_node)
116
+ hash_node.pairs.map { |pair| pair.delimiter(true).length }.max
117
+ end
117
118
  end
118
119
 
119
120
  # Handles calculation of deltas when the enforced style is 'separator'.
120
121
  class SeparatorAlignment
121
122
  include ValueAlignment
122
123
 
123
- def deltas_for_first_pair(*_nodes)
124
+ def deltas_for_first_pair(_first_pair)
124
125
  {}
125
126
  end
126
127
 
@@ -107,7 +107,7 @@ module RuboCop
107
107
  # of the argument is not considered multiline, even if the argument
108
108
  # itself might span multiple lines.
109
109
  def allowed_multiline_argument?(node)
110
- elements(node).one? && (!node.loc.end || !Util.begins_its_line?(node.loc.end))
110
+ elements(node).one? && !Util.begins_its_line?(node_end_location(node))
111
111
  end
112
112
 
113
113
  def elements(node)
@@ -127,10 +127,14 @@ module RuboCop
127
127
 
128
128
  def no_elements_on_same_line?(node)
129
129
  items = elements(node).map(&:source_range)
130
- items << node.loc.end
130
+ items << node_end_location(node)
131
131
  items.each_cons(2).none? { |a, b| on_same_line?(a, b) }
132
132
  end
133
133
 
134
+ def node_end_location(node)
135
+ node.loc.end || node.source_range.end.adjust(begin_pos: -1)
136
+ end
137
+
134
138
  def on_same_line?(range1, range2)
135
139
  range1.last_line == range2.line
136
140
  end
@@ -479,6 +479,9 @@ module RuboCop
479
479
  end
480
480
 
481
481
  def ruby_32_only_anonymous_forwarding?
482
+ # A block argument and an anonymous block argument are never passed together.
483
+ return false if @send_node.each_ancestor(:any_block).any?
484
+
482
485
  def_all_anonymous_args?(@def_node) && send_all_anonymous_args?(@send_node)
483
486
  end
484
487
 
@@ -9,6 +9,9 @@ module RuboCop
9
9
  # although the difference generally isn't observable. If you require maximum
10
10
  # performance, consider using logical comparison.
11
11
  #
12
+ # @safety
13
+ # This cop is unsafe because the receiver may not respond to `between?`.
14
+ #
12
15
  # @example
13
16
  #
14
17
  # # bad
@@ -4,6 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for inheritance from `Data.define` to avoid creating the anonymous parent class.
7
+ # Inheriting from `Data.define` adds a superfluous level in inheritance tree.
7
8
  #
8
9
  # @safety
9
10
  # Autocorrection is unsafe because it will change the inheritance
@@ -17,12 +18,18 @@ module RuboCop
17
18
  # end
18
19
  # end
19
20
  #
21
+ # Person.ancestors
22
+ # # => [Person, #<Class:0x000000010b4e14a0>, Data, (...)]
23
+ #
20
24
  # # good
21
25
  # Person = Data.define(:first_name, :last_name) do
22
26
  # def age
23
27
  # 42
24
28
  # end
25
29
  # end
30
+ #
31
+ # Person.ancestors
32
+ # # => [Person, Data, (...)]
26
33
  class DataInheritance < Base
27
34
  include RangeHelp
28
35
  extend AutoCorrector
@@ -189,7 +189,7 @@ module RuboCop
189
189
  end
190
190
  end
191
191
 
192
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
192
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
193
193
  def check_expressions(node, expressions, insert_position)
194
194
  return if expressions.any?(&:nil?)
195
195
 
@@ -197,7 +197,7 @@ module RuboCop
197
197
 
198
198
  expressions.each do |expression|
199
199
  add_offense(expression) do |corrector|
200
- next if node.if_type? && node.ternary?
200
+ next if node.if_type? && (node.ternary? || node.then?)
201
201
 
202
202
  range = range_by_whole_lines(expression.source_range, include_final_newline: true)
203
203
  corrector.remove(range)
@@ -213,7 +213,7 @@ module RuboCop
213
213
  end
214
214
  end
215
215
  end
216
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
216
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
217
217
 
218
218
  def correct_assignment(corrector, node, expression, insert_position)
219
219
  if insert_position == :after_condition
@@ -23,6 +23,17 @@ module RuboCop
23
23
  # end
24
24
  # ----
25
25
  #
26
+ # The code `def method_name = body if condition` is considered a bad case by
27
+ # `Style/AmbiguousEndlessMethodDefinition` cop. So, to respect the user's intention to use
28
+ # an endless method definition in the `if` body, the following code is allowed:
29
+ #
30
+ # [source,ruby]
31
+ # ----
32
+ # if condition
33
+ # def method_name = body
34
+ # end
35
+ # ----
36
+ #
26
37
  # NOTE: It is allowed when `defined?` argument has an undefined value,
27
38
  # because using the modifier form causes the following incompatibility:
28
39
  #
@@ -77,10 +88,14 @@ module RuboCop
77
88
  [Style::SoleNestedConditional]
78
89
  end
79
90
 
91
+ # rubocop:disable Metrics/AbcSize
80
92
  def on_if(node)
93
+ return if endless_method?(node.body)
94
+
81
95
  condition = node.condition
82
96
  return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
83
97
  pattern_matching_nodes(condition).any?
98
+
84
99
  return unless (msg = message(node))
85
100
 
86
101
  add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
@@ -90,9 +105,14 @@ module RuboCop
90
105
  ignore_node(node)
91
106
  end
92
107
  end
108
+ # rubocop:enable Metrics/AbcSize
93
109
 
94
110
  private
95
111
 
112
+ def endless_method?(body)
113
+ body&.any_def_type? && body.endless?
114
+ end
115
+
96
116
  def defined_nodes(condition)
97
117
  if condition.defined_type?
98
118
  [condition]
@@ -222,6 +222,9 @@ module RuboCop
222
222
  end
223
223
 
224
224
  def unary_literal?(node)
225
+ # NOTE: should be removed after releasing https://github.com/rubocop/rubocop-ast/pull/379
226
+ return node.source.match?(/\A[+-]/) if node.complex_type?
227
+
225
228
  (node.numeric_type? && node.sign?) ||
226
229
  (node.parent&.send_type? && node.parent.unary_operation?)
227
230
  end
@@ -23,11 +23,13 @@ module RuboCop
23
23
  'clause in a multiline statement.'
24
24
 
25
25
  def on_if(node)
26
+ return if part_of_ignored_node?(node)
26
27
  return unless node.modifier_form? && node.body.multiline?
27
28
 
28
29
  add_offense(node, message: format(MSG, keyword: node.keyword)) do |corrector|
29
30
  corrector.replace(node, to_normal_if(node))
30
31
  end
32
+ ignore_node(node)
31
33
  end
32
34
 
33
35
  private
@@ -45,7 +45,7 @@ module RuboCop
45
45
  # Report offense only if changing case doesn't change semantics,
46
46
  # i.e., if the string would become dynamic or has special characters.
47
47
  ast = parse(corrected(node.source)).ast
48
- return if node.children != ast.children
48
+ return if node.children != ast&.children
49
49
 
50
50
  add_offense(node.loc.begin) do |corrector|
51
51
  corrector.replace(node, corrected(node.source))
@@ -185,8 +185,10 @@ module RuboCop
185
185
  end
186
186
 
187
187
  def add_parentheses?(node)
188
- node.assignment? || (node.operator_keyword? && !node.and_type?) ||
189
- (node.call_type? && node.arguments.any? && !node.parenthesized?)
188
+ return true if node.assignment? || (node.operator_keyword? && !node.and_type?)
189
+ return false unless node.call_type?
190
+
191
+ (node.arguments.any? && !node.parenthesized?) || node.prefix_not?
190
192
  end
191
193
 
192
194
  def parenthesized_method_arguments(node)
@@ -51,7 +51,6 @@ module RuboCop
51
51
  # Pathname.new('/') + 'test'
52
52
  #
53
53
  class StringConcatenation < Base
54
- include RangeHelp
55
54
  extend AutoCorrector
56
55
 
57
56
  MSG = 'Prefer string interpolation to string concatenation.'
@@ -147,7 +146,7 @@ module RuboCop
147
146
  when :str
148
147
  adjust_str(part)
149
148
  when :dstr
150
- part.children.all?(&:str_type?) ? adjust_str(part) : contents_range(part).source
149
+ part.children.all?(&:str_type?) ? adjust_str(part) : part.value
151
150
  else
152
151
  "\#{#{part.source}}"
153
152
  end
@@ -3,7 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for inheritance from Struct.new.
6
+ # Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
7
+ # adds a superfluous level in inheritance tree.
7
8
  #
8
9
  # @safety
9
10
  # Autocorrection is unsafe because it will change the inheritance
@@ -17,12 +18,18 @@ module RuboCop
17
18
  # end
18
19
  # end
19
20
  #
21
+ # Person.ancestors
22
+ # # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
23
+ #
20
24
  # # good
21
25
  # Person = Struct.new(:first_name, :last_name) do
22
26
  # def age
23
27
  # 42
24
28
  # end
25
29
  # end
30
+ #
31
+ # Person.ancestors
32
+ # # => [Person, Struct, (...)]
26
33
  class StructInheritance < Base
27
34
  include RangeHelp
28
35
  extend AutoCorrector
@@ -178,6 +178,7 @@ module RuboCop
178
178
  next unless value.is_a?(Array)
179
179
  next if value.empty?
180
180
 
181
+ value.map! { |v| v.nil? ? '~' : v } # Change nil back to ~ as in the YAML file.
181
182
  output_buffer.puts "# #{param}: #{value.uniq.join(', ')}"
182
183
  end
183
184
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require 'cgi/escape'
4
4
  require 'erb'
5
5
 
6
6
  module RuboCop
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.75.4'
6
+ STRING = '1.75.6'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.75.4
4
+ version: 1.75.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -9,7 +9,7 @@ authors:
9
9
  - Yuji Nakayama
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-04-28 00:00:00.000000000 Z
12
+ date: 2025-05-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -1080,7 +1080,7 @@ licenses:
1080
1080
  - MIT
1081
1081
  metadata:
1082
1082
  homepage_uri: https://rubocop.org/
1083
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.75.4
1083
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.75.6
1084
1084
  source_code_uri: https://github.com/rubocop/rubocop/
1085
1085
  documentation_uri: https://docs.rubocop.org/rubocop/1.75/
1086
1086
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues