rubocop 1.35.0 → 1.36.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +11 -0
  4. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +0 -0
  5. data/lib/rubocop/config.rb +1 -1
  6. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  7. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  8. data/lib/rubocop/cop/layout/block_alignment.rb +14 -12
  9. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  10. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
  11. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
  12. data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
  13. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  14. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
  15. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  16. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  17. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
  18. data/lib/rubocop/cop/lint/empty_conditional_body.rb +31 -1
  19. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
  20. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
  21. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
  22. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  23. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -2
  24. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  25. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  26. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
  27. data/lib/rubocop/cop/mixin/allowed_methods.rb +10 -5
  28. data/lib/rubocop/cop/mixin/allowed_pattern.rb +13 -5
  29. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  30. data/lib/rubocop/cop/mixin/hash_transform_method.rb +9 -5
  31. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  32. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  33. data/lib/rubocop/cop/style/access_modifier_declarations.rb +77 -1
  34. data/lib/rubocop/cop/style/case_equality.rb +40 -10
  35. data/lib/rubocop/cop/style/each_for_simple_loop.rb +40 -5
  36. data/lib/rubocop/cop/style/guard_clause.rb +27 -16
  37. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  38. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  39. data/lib/rubocop/cop/style/next.rb +1 -5
  40. data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
  41. data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
  42. data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
  43. data/lib/rubocop/cop/style/sole_nested_conditional.rb +0 -2
  44. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  45. data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
  46. data/lib/rubocop/cop/style/word_array.rb +1 -1
  47. data/lib/rubocop/cop/util.rb +1 -1
  48. data/lib/rubocop/feature_loader.rb +3 -1
  49. data/lib/rubocop/formatter/html_formatter.rb +2 -2
  50. data/lib/rubocop/runner.rb +4 -0
  51. data/lib/rubocop/server/cache.rb +9 -8
  52. data/lib/rubocop/version.rb +3 -2
  53. data/lib/rubocop.rb +1 -1
  54. metadata +5 -5
@@ -68,6 +68,8 @@ module RuboCop
68
68
  # `transform_values` if value transformation uses key.
69
69
  return if captures.transformation_uses_both_args?
70
70
 
71
+ return unless captures.use_transformed_argname?
72
+
71
73
  message = "Prefer `#{new_method_name}` over `#{match_desc}`."
72
74
  add_offense(node, message: message) do |corrector|
73
75
  correction = prepare_correction(node)
@@ -113,11 +115,7 @@ module RuboCop
113
115
  end
114
116
 
115
117
  # Internal helper class to hold match data
116
- Captures = Struct.new(
117
- :transformed_argname,
118
- :transforming_body_expr,
119
- :unchanged_body_expr
120
- ) do
118
+ Captures = Struct.new(:transformed_argname, :transforming_body_expr, :unchanged_body_expr) do
121
119
  def noop_transformation?
122
120
  transforming_body_expr.lvar_type? &&
123
121
  transforming_body_expr.children == [transformed_argname]
@@ -126,6 +124,12 @@ module RuboCop
126
124
  def transformation_uses_both_args?
127
125
  transforming_body_expr.descendants.include?(unchanged_body_expr)
128
126
  end
127
+
128
+ def use_transformed_argname?
129
+ transforming_body_expr.each_descendant(:lvar).any? do |node|
130
+ node.source == transformed_argname.to_s
131
+ end
132
+ end
129
133
  end
130
134
 
131
135
  # Internal helper class to hold autocorrect data
@@ -57,7 +57,7 @@ module RuboCop
57
57
  end
58
58
 
59
59
  if left_parenthesis && style == :special_inside_parentheses
60
- return [left_parenthesis.column + 1, :first_colmn_after_left_parenthesis]
60
+ return [left_parenthesis.column + 1, :first_column_after_left_parenthesis]
61
61
  end
62
62
 
63
63
  [left_brace.source_line =~ /\S/, :start_of_line]
@@ -72,10 +72,10 @@ module RuboCop
72
72
  PATTERN
73
73
 
74
74
  def allowed_conditional_expression_on_rhs?(node)
75
- node&.if_type? && contains_contant?(node)
75
+ node&.if_type? && contains_constant?(node)
76
76
  end
77
77
 
78
- def contains_contant?(node)
78
+ def contains_constant?(node)
79
79
  node.branches.any?(&:const_type?)
80
80
  end
81
81
  end
@@ -9,6 +9,11 @@ module RuboCop
9
9
  # Applications of visibility methods to symbols can be controlled
10
10
  # using AllowModifiersOnSymbols config.
11
11
  #
12
+ # @safety
13
+ # Autocorrection is not safe, because the visibility of dynamically
14
+ # defined methods can vary depending on the state determined by
15
+ # the group access modifier.
16
+ #
12
17
  # @example EnforcedStyle: group (default)
13
18
  # # bad
14
19
  # class Foo
@@ -63,7 +68,10 @@ module RuboCop
63
68
  #
64
69
  # end
65
70
  class AccessModifierDeclarations < Base
71
+ extend AutoCorrector
72
+
66
73
  include ConfigurableEnforcedStyle
74
+ include RangeHelp
67
75
 
68
76
  GROUP_STYLE_MESSAGE = [
69
77
  '`%<access_modifier>s` should not be',
@@ -88,7 +96,10 @@ module RuboCop
88
96
  return if allow_modifiers_on_symbols?(node)
89
97
 
90
98
  if offense?(node)
91
- add_offense(node.loc.selector) { opposite_style_detected }
99
+ add_offense(node.loc.selector) do |corrector|
100
+ autocorrect(corrector, node)
101
+ end
102
+ opposite_style_detected
92
103
  else
93
104
  correct_style_detected
94
105
  end
@@ -96,6 +107,23 @@ module RuboCop
96
107
 
97
108
  private
98
109
 
110
+ def autocorrect(corrector, node)
111
+ case style
112
+ when :group
113
+ def_node = find_corresponding_def_node(node)
114
+ return unless def_node
115
+
116
+ remove_node(corrector, def_node)
117
+ remove_node(corrector, node)
118
+ insert_def(corrector, node, def_node.source)
119
+ when :inline
120
+ remove_node(corrector, node)
121
+ select_grouped_def_nodes(node).each do |grouped_def_node|
122
+ insert_inline_modifier(corrector, grouped_def_node, node.method_name)
123
+ end
124
+ end
125
+ end
126
+
99
127
  def allow_modifiers_on_symbols?(node)
100
128
  cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node)
101
129
  end
@@ -130,6 +158,54 @@ module RuboCop
130
158
  format(INLINE_STYLE_MESSAGE, access_modifier: access_modifier)
131
159
  end
132
160
  end
161
+
162
+ def find_corresponding_def_node(node)
163
+ if access_modifier_with_symbol?(node)
164
+ method_name = node.arguments.first.value
165
+ node.parent.each_child_node(:def).find do |child|
166
+ child.method?(method_name)
167
+ end
168
+ else
169
+ node.arguments.first
170
+ end
171
+ end
172
+
173
+ def find_argument_less_modifier_node(node)
174
+ node.parent.each_child_node(:send).find do |child|
175
+ child.method?(node.method_name) && child.arguments.empty?
176
+ end
177
+ end
178
+
179
+ def select_grouped_def_nodes(node)
180
+ node.right_siblings.take_while do |sibling|
181
+ !(sibling.send_type? && sibling.bare_access_modifier_declaration?)
182
+ end.select(&:def_type?)
183
+ end
184
+
185
+ def insert_def(corrector, node, source)
186
+ argument_less_modifier_node = find_argument_less_modifier_node(node)
187
+ if argument_less_modifier_node
188
+ corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
189
+ else
190
+ corrector.insert_before(
191
+ node.each_ancestor(:block, :class, :module).first.location.end,
192
+ "#{node.method_name}\n\n#{source}\n"
193
+ )
194
+ end
195
+ end
196
+
197
+ def insert_inline_modifier(corrector, node, modifier_name)
198
+ corrector.insert_before(node, "#{modifier_name} ")
199
+ end
200
+
201
+ def remove_node(corrector, node)
202
+ corrector.remove(
203
+ range_by_whole_lines(
204
+ node.location.expression,
205
+ include_final_newline: true
206
+ )
207
+ )
208
+ end
133
209
  end
134
210
  end
135
211
  end
@@ -7,6 +7,9 @@ module RuboCop
7
7
  #
8
8
  # If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
9
9
  # the case equality operator is a constant.
10
+
11
+ # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
12
+ # the case equality operator is `self.class`. Note intermediate variables are not accepted.
10
13
  #
11
14
  # @example
12
15
  # # bad
@@ -26,6 +29,14 @@ module RuboCop
26
29
  # # good
27
30
  # Array === something
28
31
  #
32
+ # @example AllowOnSelfClass: false (default)
33
+ # # bad
34
+ # self.class === something
35
+ #
36
+ # @example AllowOnSelfClass: true
37
+ # # good
38
+ # self.class === something
39
+ #
29
40
  class CaseEquality < Base
30
41
  extend AutoCorrector
31
42
 
@@ -33,7 +44,10 @@ module RuboCop
33
44
  RESTRICT_ON_SEND = %i[===].freeze
34
45
 
35
46
  # @!method case_equality?(node)
36
- def_node_matcher :case_equality?, '(send $#const? :=== $_)'
47
+ def_node_matcher :case_equality?, '(send $#offending_receiver? :=== $_)'
48
+
49
+ # @!method self_class?(node)
50
+ def_node_matcher :self_class?, '(send (self) :class)'
37
51
 
38
52
  def on_send(node)
39
53
  case_equality?(node) do |lhs, rhs|
@@ -48,12 +62,11 @@ module RuboCop
48
62
 
49
63
  private
50
64
 
51
- def const?(node)
52
- if cop_config.fetch('AllowOnConstant', false)
53
- !node&.const_type?
54
- else
55
- true
56
- end
65
+ def offending_receiver?(node)
66
+ return false if node&.const_type? && cop_config.fetch('AllowOnConstant', false)
67
+ return false if self_class?(node) && cop_config.fetch('AllowOnSelfClass', false)
68
+
69
+ true
57
70
  end
58
71
 
59
72
  def replacement(lhs, rhs)
@@ -66,12 +79,29 @@ module RuboCop
66
79
  #
67
80
  # So here is noop.
68
81
  when :begin
69
- child = lhs.children.first
70
- "#{lhs.source}.include?(#{rhs.source})" if child&.range_type?
82
+ begin_replacement(lhs, rhs)
71
83
  when :const
72
- "#{rhs.source}.is_a?(#{lhs.source})"
84
+ const_replacement(lhs, rhs)
85
+ when :send
86
+ send_replacement(lhs, rhs)
73
87
  end
74
88
  end
89
+
90
+ def begin_replacement(lhs, rhs)
91
+ return unless lhs.children.first&.range_type?
92
+
93
+ "#{lhs.source}.include?(#{rhs.source})"
94
+ end
95
+
96
+ def const_replacement(lhs, rhs)
97
+ "#{rhs.source}.is_a?(#{lhs.source})"
98
+ end
99
+
100
+ def send_replacement(lhs, rhs)
101
+ return unless self_class?(lhs)
102
+
103
+ "#{rhs.source}.is_a?(#{lhs.source})"
104
+ end
75
105
  end
76
106
  end
77
107
  end
@@ -28,14 +28,14 @@ module RuboCop
28
28
  MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.'
29
29
 
30
30
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
31
- return unless offending_each_range(node)
31
+ return unless offending?(node)
32
32
 
33
33
  send_node = node.send_node
34
34
 
35
35
  range = send_node.receiver.source_range.join(send_node.loc.selector)
36
36
 
37
37
  add_offense(range) do |corrector|
38
- range_type, min, max = offending_each_range(node)
38
+ range_type, min, max = each_range(node)
39
39
 
40
40
  max += 1 if range_type == :irange
41
41
 
@@ -45,9 +45,44 @@ module RuboCop
45
45
 
46
46
  private
47
47
 
48
- # @!method offending_each_range(node)
49
- def_node_matcher :offending_each_range, <<~PATTERN
50
- (block (send (begin (${irange erange} (int $_) (int $_))) :each) (args) ...)
48
+ def offending?(node)
49
+ each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
50
+ end
51
+
52
+ # @!method each_range(node)
53
+ def_node_matcher :each_range, <<~PATTERN
54
+ (block
55
+ (send
56
+ (begin
57
+ (${irange erange}
58
+ (int $_) (int $_)))
59
+ :each)
60
+ (args ...)
61
+ ...)
62
+ PATTERN
63
+
64
+ # @!method each_range_with_zero_origin?(node)
65
+ def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
66
+ (block
67
+ (send
68
+ (begin
69
+ ({irange erange}
70
+ (int 0) (int _)))
71
+ :each)
72
+ (args ...)
73
+ ...)
74
+ PATTERN
75
+
76
+ # @!method each_range_without_block_argument?(node)
77
+ def_node_matcher :each_range_without_block_argument?, <<~PATTERN
78
+ (block
79
+ (send
80
+ (begin
81
+ ({irange erange}
82
+ (int _) (int _)))
83
+ :each)
84
+ (args)
85
+ ...)
51
86
  PATTERN
52
87
  end
53
88
  end
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # Use a guard clause instead of wrapping the code inside a conditional
7
7
  # expression
8
8
  #
9
+ # A condition with an `elsif` or `else` branch is allowed unless
10
+ # one of `return`, `break`, `next`, `raise`, or `fail` is used
11
+ # in the body of the conditional expression.
12
+ #
9
13
  # @example
10
14
  # # bad
11
15
  # def test
@@ -50,34 +54,41 @@ module RuboCop
50
54
  #
51
55
  # @example AllowConsecutiveConditionals: false (default)
52
56
  # # bad
53
- # if foo?
54
- # work
55
- # end
57
+ # def test
58
+ # if foo?
59
+ # work
60
+ # end
56
61
  #
57
- # if bar? # <- reports an offense
58
- # work
62
+ # if bar? # <- reports an offense
63
+ # work
64
+ # end
59
65
  # end
60
66
  #
61
67
  # @example AllowConsecutiveConditionals: true
62
68
  # # good
63
- # if foo?
64
- # work
65
- # end
69
+ # def test
70
+ # if foo?
71
+ # work
72
+ # end
66
73
  #
67
- # if bar?
68
- # work
74
+ # if bar?
75
+ # work
76
+ # end
69
77
  # end
70
78
  #
71
79
  # # bad
72
- # if foo?
73
- # work
74
- # end
80
+ # def test
81
+ # if foo?
82
+ # work
83
+ # end
75
84
  #
76
- # do_something
85
+ # do_something
77
86
  #
78
- # if bar? # <- reports an offense
79
- # work
87
+ # if bar? # <- reports an offense
88
+ # work
89
+ # end
80
90
  # end
91
+ #
81
92
  class GuardClause < Base
82
93
  include MinBodyLength
83
94
  include StatementModifier
@@ -130,7 +130,7 @@ module RuboCop
130
130
  call_as_argument_or_chain?(node) ||
131
131
  hash_literal_in_arguments?(node) ||
132
132
  node.descendants.any? do |n|
133
- n.forwarded_args_type? || ambigious_literal?(n) || logical_operator?(n) ||
133
+ n.forwarded_args_type? || ambiguous_literal?(n) || logical_operator?(n) ||
134
134
  call_with_braced_block?(n)
135
135
  end
136
136
  end
@@ -166,7 +166,7 @@ module RuboCop
166
166
  previous.parenthesized? || allowed_chained_call_with_parentheses?(previous)
167
167
  end
168
168
 
169
- def ambigious_literal?(node)
169
+ def ambiguous_literal?(node)
170
170
  splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) || unary_literal?(node)
171
171
  end
172
172
 
@@ -49,7 +49,7 @@ module RuboCop
49
49
 
50
50
  # Requires `then` for write `in` and its body on the same line.
51
51
  def require_then?(in_pattern_node)
52
- return true if in_pattern_node.pattern.first_line != in_pattern_node.pattern.last_line
52
+ return true unless in_pattern_node.pattern.single_line?
53
53
  return false unless in_pattern_node.body
54
54
 
55
55
  same_line?(in_pattern_node, in_pattern_node.body)
@@ -225,11 +225,7 @@ module RuboCop
225
225
  adjustment = delta + @reindented_lines[lineno]
226
226
  @reindented_lines[lineno] = adjustment
227
227
 
228
- if adjustment.positive?
229
- corrector.remove_leading(buffer.line_range(lineno), adjustment)
230
- elsif adjustment.negative?
231
- corrector.insert_before(buffer.line_range(lineno), ' ' * -adjustment)
232
- end
228
+ corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
233
229
  end
234
230
  end
235
231
  end
@@ -83,10 +83,31 @@ module RuboCop
83
83
  end
84
84
  end
85
85
 
86
+ # @private
87
+ # @param [RuboCop::AST::Node] node
88
+ # @return [String, nil]
89
+ def preferred_expression_to_node_with_constant_prefix(node)
90
+ expression = preferred_expression_to(node)
91
+ return unless expression
92
+
93
+ "#{constant_prefix(node)}#{expression}"
94
+ end
95
+
96
+ # @private
97
+ # @param [RuboCop::AST::Node] node
98
+ # @return [String]
99
+ def constant_prefix(node)
100
+ if node.each_ancestor(:class, :module).any?
101
+ '::'
102
+ else
103
+ ''
104
+ end
105
+ end
106
+
86
107
  # @private
87
108
  # @param [RuboCop::AST::Node] node
88
109
  def on_back_ref_or_gvar_or_nth_ref(node)
89
- preferred_expression = preferred_expression_to(node)
110
+ preferred_expression = preferred_expression_to_node_with_constant_prefix(node)
90
111
  return unless preferred_expression
91
112
 
92
113
  add_offense(
@@ -29,6 +29,9 @@ module RuboCop
29
29
  # @!method rescue?(node)
30
30
  def_node_matcher :rescue?, '{^resbody ^^resbody}'
31
31
 
32
+ # @!method allowed_pin_operator?(node)
33
+ def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
34
+
32
35
  # @!method arg_in_call_with_block?(node)
33
36
  def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)'
34
37
 
@@ -44,6 +47,7 @@ module RuboCop
44
47
  empty_parentheses?(node) ||
45
48
  first_arg_begins_with_hash_literal?(node) ||
46
49
  rescue?(node) ||
50
+ allowed_pin_operator?(node) ||
47
51
  allowed_expression?(node)
48
52
  end
49
53
 
@@ -141,7 +141,7 @@ module RuboCop
141
141
 
142
142
  corrector.remove(begin_range(node, body))
143
143
  corrector.remove(end_range(node, body))
144
- corrector.insert_before(method_call.loc.dot, '&')
144
+ corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
145
145
  handle_comments(corrector, node, method_call)
146
146
 
147
147
  add_safe_nav_to_all_methods_in_chain(corrector, method_call, body)
@@ -250,7 +250,9 @@ module RuboCop
250
250
  end
251
251
 
252
252
  def unsafe_method?(send_node)
253
- negated?(send_node) || send_node.assignment? || !send_node.dot?
253
+ negated?(send_node) ||
254
+ send_node.assignment? ||
255
+ (!send_node.dot? && !send_node.safe_navigation?)
254
256
  end
255
257
 
256
258
  def negated?(send_node)
@@ -173,8 +173,6 @@ module RuboCop
173
173
  end
174
174
 
175
175
  def correct_for_comment(corrector, node, if_branch)
176
- return if config.for_cop('Style/IfUnlessModifier')['Enabled']
177
-
178
176
  comments = processed_source.ast_with_comments[if_branch]
179
177
  comment_text = comments.map(&:text).join("\n") << "\n"
180
178
 
@@ -69,7 +69,7 @@ module RuboCop
69
69
  if c.dsym_type?
70
70
  string_literal = to_string_literal(c.source)
71
71
 
72
- ":#{trim_string_interporation_escape_character(string_literal)}"
72
+ ":#{trim_string_interpolation_escape_character(string_literal)}"
73
73
  else
74
74
  to_symbol_literal(c.value.to_s)
75
75
  end
@@ -11,10 +11,11 @@ module RuboCop
11
11
  # These are customizable with `AllowedMethods` option.
12
12
  #
13
13
  # @safety
14
- # This cop is unsafe because `proc`s and blocks work differently
15
- # when additional arguments are passed in. A block will silently
16
- # allow additional arguments, but a `proc` will raise
17
- # an `ArgumentError`.
14
+ # This cop is unsafe because there is a difference that a `Proc`
15
+ # generated from `Symbol#to_proc` behaves as a lambda, while
16
+ # a `Proc` generated from a block does not.
17
+ # For example, a lambda will raise an `ArgumentError` if the
18
+ # number of arguments is wrong, but a non-lambda `Proc` will not.
18
19
  #
19
20
  # For example:
20
21
  #
@@ -87,7 +87,7 @@ module RuboCop
87
87
  if word.dstr_type?
88
88
  string_literal = to_string_literal(word.source)
89
89
 
90
- trim_string_interporation_escape_character(string_literal)
90
+ trim_string_interpolation_escape_character(string_literal)
91
91
  else
92
92
  to_string_literal(word.children[0])
93
93
  end
@@ -126,7 +126,7 @@ module RuboCop
126
126
  end
127
127
  end
128
128
 
129
- def trim_string_interporation_escape_character(str)
129
+ def trim_string_interpolation_escape_character(str)
130
130
  str.gsub(/\\\#\{(.*?)\}/) { "\#{#{Regexp.last_match(1)}}" }
131
131
  end
132
132
 
@@ -41,7 +41,9 @@ module RuboCop
41
41
  # https://github.com/rubocop/rubocop/issues/10893
42
42
  require(namespaced_target)
43
43
  rescue ::LoadError => error_for_namespaced_target
44
- raise e if error_for_namespaced_target.path == namespaced_target
44
+ # NOTE: This wrap is necessary due to JRuby 9.3.4.0 incompatibility:
45
+ # https://github.com/jruby/jruby/issues/7316
46
+ raise LoadError, e if error_for_namespaced_target.path == namespaced_target
45
47
 
46
48
  raise error_for_namespaced_target
47
49
  end
@@ -93,12 +93,12 @@ module RuboCop
93
93
 
94
94
  def highlighted_source_line(offense)
95
95
  source_before_highlight(offense) +
96
- hightlight_source_tag(offense) +
96
+ highlight_source_tag(offense) +
97
97
  source_after_highlight(offense) +
98
98
  possible_ellipses(offense.location)
99
99
  end
100
100
 
101
- def hightlight_source_tag(offense)
101
+ def highlight_source_tag(offense)
102
102
  "<span class=\"highlight #{offense.severity}\">" \
103
103
  "#{escape(offense.highlighted_area.source)}" \
104
104
  '</span>'
@@ -64,6 +64,10 @@ module RuboCop
64
64
  # instances that each inspects its allotted group of files.
65
65
  def warm_cache(target_files)
66
66
  saved_options = @options.dup
67
+ if target_files.length <= 1
68
+ puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug]
69
+ return
70
+ end
67
71
  puts 'Running parallel inspection' if @options[:debug]
68
72
  %i[autocorrect safe_autocorrect].each { |opt| @options[opt] = false }
69
73
  Parallel.each(target_files) { |target_file| file_offenses(target_file) }
@@ -62,17 +62,18 @@ module RuboCop
62
62
  # `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
63
63
  # so that only the necessary `CacheRootDirectory` can be obtained.
64
64
  require 'yaml'
65
-
66
65
  config_path = ConfigFinder.find_config_path(Dir.pwd)
67
66
 
68
- # Ruby 3.1+
69
- config_yaml = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('4.0.0')
70
- YAML.safe_load_file(config_path, permitted_classes: [Regexp, Symbol])
71
- else
72
- config = YAML.load_file(config_path)
67
+ require 'erb'
68
+ file_contents = File.read(config_path)
69
+ yaml_code = ERB.new(file_contents).result
70
+
71
+ config_yaml = YAML.safe_load(yaml_code, permitted_classes: [Regexp, Symbol])
73
72
 
74
- config == false ? nil : config
75
- end
73
+ # For compatibility with Ruby 3.0 or lower.
74
+ if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
75
+ config_yaml == false ? nil : config_yaml
76
+ end
76
77
 
77
78
  config_yaml&.dig('AllCops', 'CacheRootDirectory')
78
79
  end
@@ -3,11 +3,11 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.35.0'
6
+ STRING = '1.36.0'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
10
- 'running on %<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'
10
+ 'running on %<ruby_engine>s %<ruby_version>s)%<server>s [%<ruby_platform>s]'
11
11
 
12
12
  CANONICAL_FEATURE_NAMES = { 'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown',
13
13
  'Thread_safety' => 'ThreadSafety' }.freeze
@@ -19,6 +19,7 @@ module RuboCop
19
19
  verbose_version = format(MSG, version: STRING, parser_version: Parser::VERSION,
20
20
  rubocop_ast_version: RuboCop::AST::Version::STRING,
21
21
  ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
22
+ server: Server.running? ? ' +server' : '',
22
23
  ruby_platform: RUBY_PLATFORM)
23
24
  return verbose_version unless env
24
25
 
data/lib/rubocop.rb CHANGED
@@ -703,7 +703,7 @@ require_relative 'rubocop/cli'
703
703
  require_relative 'rubocop/cli/command'
704
704
  require_relative 'rubocop/cli/environment'
705
705
  require_relative 'rubocop/cli/command/base'
706
- require_relative 'rubocop/cli/command/auto_genenerate_config'
706
+ require_relative 'rubocop/cli/command/auto_generate_config'
707
707
  require_relative 'rubocop/cli/command/execute_runner'
708
708
  require_relative 'rubocop/cli/command/init_dotfile'
709
709
  require_relative 'rubocop/cli/command/show_cops'