rubocop 1.35.0 → 1.36.0

Sign up to get free protection for your applications and to get access to all the features.
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'