rubocop 1.81.7 → 1.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +21 -5
  4. data/config/obsoletion.yml +4 -0
  5. data/lib/rubocop/cli.rb +2 -1
  6. data/lib/rubocop/comment_config.rb +62 -17
  7. data/lib/rubocop/config_loader.rb +2 -1
  8. data/lib/rubocop/config_loader_resolver.rb +2 -2
  9. data/lib/rubocop/cop/autocorrect_logic.rb +2 -0
  10. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -3
  11. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
  12. data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
  13. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  14. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -0
  15. data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
  16. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  17. data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -4
  18. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  19. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  20. data/lib/rubocop/cop/layout/line_length.rb +7 -4
  21. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +5 -3
  22. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  23. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
  24. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +1 -1
  25. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  26. data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -0
  27. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  28. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
  29. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  30. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
  31. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -1
  32. data/lib/rubocop/cop/lint/self_assignment.rb +9 -1
  33. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
  34. data/lib/rubocop/cop/lint/useless_or.rb +15 -2
  35. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +1 -1
  36. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  37. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +0 -4
  38. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  39. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
  40. data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
  41. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  42. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  43. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  44. data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
  45. data/lib/rubocop/cop/mixin/trailing_comma.rb +4 -5
  46. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  47. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
  48. data/lib/rubocop/cop/style/case_equality.rb +11 -13
  49. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  50. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -11
  51. data/lib/rubocop/cop/style/constant_visibility.rb +3 -3
  52. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  53. data/lib/rubocop/cop/style/endless_method.rb +2 -2
  54. data/lib/rubocop/cop/style/guard_clause.rb +0 -11
  55. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  56. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
  57. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
  58. data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
  59. data/lib/rubocop/cop/style/multiline_method_signature.rb +0 -4
  60. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  61. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  62. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  63. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +5 -0
  64. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  65. data/lib/rubocop/cop/style/super_arguments.rb +2 -2
  66. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
  67. data/lib/rubocop/cop/util.rb +2 -3
  68. data/lib/rubocop/directive_comment.rb +46 -3
  69. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -0
  70. data/lib/rubocop/lsp/diagnostic.rb +12 -17
  71. data/lib/rubocop/lsp/routes.rb +9 -36
  72. data/lib/rubocop/lsp/runtime.rb +2 -2
  73. data/lib/rubocop/lsp/server.rb +2 -2
  74. data/lib/rubocop/magic_comment.rb +20 -0
  75. data/lib/rubocop/rake_task.rb +1 -1
  76. data/lib/rubocop/remote_config.rb +7 -8
  77. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  78. data/lib/rubocop/rspec/support.rb +1 -1
  79. data/lib/rubocop/target_ruby.rb +1 -1
  80. data/lib/rubocop/version.rb +1 -1
  81. data/lib/rubocop.rb +1 -0
  82. metadata +7 -6
@@ -38,6 +38,24 @@ module RuboCop
38
38
  # elsif do_this
39
39
  # do_that
40
40
  # end
41
+ #
42
+ # # bad
43
+ #
44
+ # # For single-line conditionals using `then` the layout is disallowed
45
+ # # when the `else` body is multiline because it is treated as a lint offense.
46
+ # if something then on_the_same_line_as_then
47
+ # else first_line
48
+ # second_line
49
+ # end
50
+ #
51
+ # # good
52
+ #
53
+ # # For single-line conditional using `then` the layout is allowed
54
+ # # when `else` body is a single-line because it is treated as intentional.
55
+ #
56
+ # if something then on_the_same_line_as_then
57
+ # else single_line
58
+ # end
41
59
  class ElseLayout < Base
42
60
  include Alignment
43
61
  include RangeHelp
@@ -47,6 +65,7 @@ module RuboCop
47
65
 
48
66
  def on_if(node)
49
67
  return if node.ternary?
68
+ return if node.then? && !node.else_branch&.begin_type?
50
69
 
51
70
  # If the if is on a single line, it'll be handled by `Style/OneLineConditional`
52
71
  return if node.single_line?
@@ -269,7 +269,11 @@ module RuboCop
269
269
  end
270
270
 
271
271
  add_offense(cond) do |corrector|
272
+ next if part_of_ignored_node?(node)
273
+
272
274
  corrector.replace(node, new_node)
275
+
276
+ ignore_node(node)
273
277
  end
274
278
  end
275
279
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -66,7 +66,7 @@ module RuboCop
66
66
 
67
67
  def special_keyword?(node)
68
68
  # handle strings like __FILE__
69
- (node.str_type? && !node.loc.respond_to?(:begin)) || node.source_range.is?('__LINE__')
69
+ (node.str_type? && !node.loc?(:begin)) || node.source_range.is?('__LINE__')
70
70
  end
71
71
 
72
72
  def array_in_regexp?(node)
@@ -45,6 +45,10 @@ module RuboCop
45
45
  end
46
46
  end
47
47
  end
48
+ alias on_ivasgn on_lvasgn
49
+ alias on_cvasgn on_lvasgn
50
+ alias on_gvasgn on_lvasgn
51
+ alias on_casgn on_lvasgn
48
52
  alias on_or_asgn on_lvasgn
49
53
  alias on_op_asgn on_lvasgn
50
54
  end
@@ -112,22 +112,36 @@ module RuboCop
112
112
 
113
113
  def each_line_range(cop, line_ranges)
114
114
  line_ranges.each_with_index do |line_range, line_range_index|
115
- next if ignore_offense?(line_range)
116
- next if expected_final_disable?(cop, line_range)
115
+ next if should_skip_line_range?(cop, line_range)
117
116
 
118
117
  comment = processed_source.comment_at_line(line_range.begin)
119
- redundant = if all_disabled?(comment)
120
- find_redundant_all(line_range, line_ranges[line_range_index + 1])
121
- elsif department_disabled?(cop, comment)
122
- find_redundant_department(cop, line_range)
123
- else
124
- find_redundant_cop(cop, line_range)
125
- end
118
+ next if skip_directive?(comment)
126
119
 
120
+ next_range = line_ranges[line_range_index + 1]
121
+ redundant = find_redundant_directive(cop, comment, line_range, next_range)
127
122
  yield comment, redundant if redundant
128
123
  end
129
124
  end
130
125
 
126
+ def should_skip_line_range?(cop, line_range)
127
+ ignore_offense?(line_range) || expected_final_disable?(cop, line_range)
128
+ end
129
+
130
+ def skip_directive?(comment)
131
+ directive = DirectiveComment.new(comment)
132
+ directive.push? || directive.pop?
133
+ end
134
+
135
+ def find_redundant_directive(cop, comment, line_range, next_range)
136
+ if all_disabled?(comment)
137
+ find_redundant_all(line_range, next_range)
138
+ elsif department_disabled?(cop, comment)
139
+ find_redundant_department(cop, line_range)
140
+ else
141
+ find_redundant_cop(cop, line_range)
142
+ end
143
+ end
144
+
131
145
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
132
146
  def each_already_disabled(cop, line_ranges)
133
147
  line_ranges.each_cons(2) do |previous_range, range|
@@ -19,7 +19,8 @@ module RuboCop
19
19
  # * 2.2+ ... Add `rational` and `complex` above
20
20
  # * 2.7+ ... Add `ruby2_keywords` above
21
21
  # * 3.1+ ... Add `fiber` above
22
- # * 3.2+ ... `set`
22
+ # * 3.2+ ... Add `set` above
23
+ # * 4.0+ ... Add `pathname` above
23
24
  #
24
25
  # This cop target those features.
25
26
  #
@@ -69,7 +70,8 @@ module RuboCop
69
70
  (target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
70
71
  (target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
71
72
  (target_ruby_version >= 3.1 && feature_name == 'fiber') ||
72
- (target_ruby_version >= 3.2 && feature_name == 'set')
73
+ (target_ruby_version >= 3.2 && feature_name == 'set') ||
74
+ (target_ruby_version >= 4.0 && feature_name == 'pathname')
73
75
  end
74
76
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
75
77
  end
@@ -144,7 +144,9 @@ module RuboCop
144
144
  expression = node.parent.source_range if node.parent.array_type?
145
145
  [expression, variable.source]
146
146
  elsif !variable.array_type?
147
- [expression, "[#{variable.source}]"]
147
+ replacement = variable.source
148
+ replacement = "[#{replacement}]" if wrap_in_brackets?(node)
149
+ [expression, replacement]
148
150
  elsif redundant_brackets?(node)
149
151
  [expression, remove_brackets(variable)]
150
152
  else
@@ -176,6 +178,10 @@ module RuboCop
176
178
  grandparent&.resbody_type?
177
179
  end
178
180
 
181
+ def wrap_in_brackets?(node)
182
+ node.parent.array_type? && !node.parent.bracketed?
183
+ end
184
+
179
185
  def remove_brackets(array)
180
186
  array_start = array.loc.begin.source
181
187
  elements = *array
@@ -23,7 +23,15 @@ module RuboCop
23
23
  # # good (method calls possibly can return different results)
24
24
  # hash[foo] = hash[foo]
25
25
  #
26
- # @example AllowRBSInlineAnnotation:true
26
+ # @example AllowRBSInlineAnnotation: false (default)
27
+ # # bad
28
+ # foo = foo #: Integer
29
+ # foo, bar = foo, bar #: Integer
30
+ # Foo = Foo #: Integer
31
+ # hash['foo'] = hash['foo'] #: Integer
32
+ # obj.attr = obj.attr #: Integer
33
+ #
34
+ # @example AllowRBSInlineAnnotation: true
27
35
  # # good
28
36
  # foo = foo #: Integer
29
37
  # foo, bar = foo, bar #: Integer
@@ -78,6 +78,7 @@ module RuboCop
78
78
  }
79
79
  PATTERN
80
80
 
81
+ # rubocop:disable Metrics/MethodLength
81
82
  def flow_expression?(node)
82
83
  return report_on_flow_command?(node) if flow_command?(node)
83
84
 
@@ -89,12 +90,14 @@ module RuboCop
89
90
  check_if(node)
90
91
  when :case, :case_match
91
92
  check_case(node)
92
- when :def
93
+ when :def, :defs
93
94
  register_redefinition(node)
95
+ false
94
96
  else
95
97
  false
96
98
  end
97
99
  end
100
+ # rubocop:enable Metrics/MethodLength
98
101
 
99
102
  def check_if(node)
100
103
  if_branch = node.if_branch
@@ -113,8 +116,7 @@ module RuboCop
113
116
  end
114
117
 
115
118
  def register_redefinition(node)
116
- @redefined << node.method_name if redefinable_flow_method? node.method_name
117
- false
119
+ @redefined << node.method_name if redefinable_flow_method?(node.method_name)
118
120
  end
119
121
 
120
122
  def instance_eval_block?(node)
@@ -9,6 +9,13 @@ module RuboCop
9
9
  # on `nil` (e.g. `nil.to_i` evaluates to `0`). Therefore, OR expressions
10
10
  # appended after these methods will never evaluate.
11
11
  #
12
+ # @safety
13
+ # As shown in the examples below, there are generally two possible ways to correct the
14
+ # offense, but this cop’s autocorrection always chooses the option that preserves the
15
+ # current behavior. While this does not change how the code behaves, that option is not
16
+ # necessarily the appropriate fix in every situation. For this reason, the autocorrection
17
+ # provided by this cop is considered unsafe.
18
+ #
12
19
  # @example
13
20
  #
14
21
  # # bad
@@ -64,6 +71,8 @@ module RuboCop
64
71
  # x&.to_s or fallback
65
72
  #
66
73
  class UselessOr < Base
74
+ extend AutoCorrector
75
+
67
76
  MSG = '`%<rhs>s` will never evaluate because `%<lhs>s` always returns a truthy value.'
68
77
 
69
78
  TRUTHY_RETURN_VALUE_METHODS = Set[:to_a, :to_c, :to_d, :to_i, :to_f, :to_h, :to_r,
@@ -89,8 +98,12 @@ module RuboCop
89
98
  private
90
99
 
91
100
  def report_offense(or_node, truthy_node)
92
- add_offense(or_node.loc.operator.join(or_node.rhs.source_range),
93
- message: format(MSG, lhs: truthy_node.source, rhs: or_node.rhs.source))
101
+ add_offense(
102
+ or_node.loc.operator.join(or_node.rhs.source_range),
103
+ message: format(MSG, lhs: truthy_node.source, rhs: or_node.rhs.source)
104
+ ) do |corrector|
105
+ corrector.replace(or_node, or_node.lhs.source)
106
+ end
94
107
  end
95
108
  end
96
109
  end
@@ -31,7 +31,7 @@ module RuboCop
31
31
  @checked_nodes[node] = true
32
32
 
33
33
  case node.type
34
- when :def, :class, :module, :sclass
34
+ when :def, :defs, :class, :module, :sclass
35
35
  return false
36
36
  when :send
37
37
  return non_nil_method?(node.method_name) if node.receiver == receiver
@@ -84,7 +84,10 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def assignment?(node)
87
- return compound_assignment(node) if node.masgn_type? || node.shorthand_asgn?
87
+ if node.masgn_type? || node.shorthand_asgn?
88
+ compound_assignment(node)
89
+ return false
90
+ end
88
91
 
89
92
  node.for_type? ||
90
93
  (node.respond_to?(:setter_method?) && node.setter_method?) ||
@@ -101,8 +104,6 @@ module RuboCop
101
104
  child.respond_to?(:setter_method?) && !child.setter_method?
102
105
  end
103
106
  @assignment += will_be_miscounted
104
-
105
- false
106
107
  end
107
108
 
108
109
  def simple_assignment?(node)
@@ -27,10 +27,6 @@ module RuboCop
27
27
  .gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
28
28
  end
29
29
 
30
- def max_line_length
31
- config.for_cop('Layout/LineLength')['Max']
32
- end
33
-
34
30
  def comment_within?(node)
35
31
  comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
36
32
 
@@ -59,7 +59,7 @@ module RuboCop
59
59
  return node.loc.name if node.casgn_type?
60
60
 
61
61
  if LSP.enabled?
62
- end_range = node.loc.respond_to?(:name) ? node.loc.name : node.loc.begin
62
+ end_range = node.loc?(:name) ? node.loc.name : node.loc.begin
63
63
  node.source_range.begin.join(end_range)
64
64
  else
65
65
  node.source_range
@@ -13,7 +13,7 @@ module RuboCop
13
13
 
14
14
  DefNode = Struct.new(:node) do
15
15
  def selector
16
- if node.loc.respond_to?(:selector)
16
+ if node.loc?(:selector)
17
17
  node.loc.selector
18
18
  else
19
19
  node.loc.keyword
@@ -8,8 +8,27 @@ module RuboCop
8
8
 
9
9
  private
10
10
 
11
- def ignore_cop_directives?
12
- config.for_cop('Layout/LineLength')['IgnoreCopDirectives']
11
+ def allow_rbs_inline_annotation?
12
+ config.for_cop('Layout/LineLength')['AllowRBSInlineAnnotation']
13
+ end
14
+
15
+ def rbs_inline_annotation_on_source_line?(line_index)
16
+ source_line_number = line_index + processed_source.buffer.first_line
17
+ comment = processed_source.comment_at_line(source_line_number)
18
+
19
+ return false unless comment
20
+
21
+ comment.text.start_with?(/#:|#\[.+\]|#\|/)
22
+ end
23
+
24
+ def allow_cop_directives?
25
+ # TODO: This logic for backward compatibility with deprecated `IgnoreCopDirectives` option.
26
+ # The following three lines will be removed in RuboCop 2.0.
27
+ ignore_cop_directives = config.for_cop('Layout/LineLength')['IgnoreCopDirectives']
28
+ return true if ignore_cop_directives
29
+ return false if ignore_cop_directives == false
30
+
31
+ config.for_cop('Layout/LineLength')['AllowCopDirectives']
13
32
  end
14
33
 
15
34
  def directive_on_source_line?(line_index)
@@ -73,7 +73,7 @@ module RuboCop
73
73
 
74
74
  def location(node)
75
75
  if LSP.enabled?
76
- end_range = node.loc.respond_to?(:name) ? node.loc.name : node.loc.begin
76
+ end_range = node.loc?(:name) ? node.loc.name : node.loc.begin
77
77
  node.source_range.begin.join(end_range)
78
78
  else
79
79
  node.source_range
@@ -200,7 +200,7 @@ module RuboCop
200
200
  end
201
201
 
202
202
  def grouped_expression?(node)
203
- node.begin_type? && node.loc.respond_to?(:begin) && node.loc.begin
203
+ node.begin_type? && node.loc?(:begin) && node.loc.begin
204
204
  end
205
205
 
206
206
  def inside_arg_list_parentheses?(node, ancestor)
@@ -127,7 +127,7 @@ module RuboCop
127
127
  parent ||= node
128
128
 
129
129
  if node.respond_to?(:loc) &&
130
- node.loc.respond_to?(:heredoc_end) &&
130
+ node.loc?(:heredoc_end) &&
131
131
  node.loc.heredoc_end.last_line >= parent.last_line
132
132
  return true
133
133
  end
@@ -100,12 +100,6 @@ module RuboCop
100
100
  node.parent.send_type?
101
101
  end
102
102
 
103
- def max_line_length
104
- return unless config.cop_enabled?('Layout/LineLength')
105
-
106
- config.for_cop('Layout/LineLength')['Max']
107
- end
108
-
109
103
  def comment_disables_cop?(comment)
110
104
  regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
111
105
  Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
@@ -96,11 +96,10 @@ module RuboCop
96
96
  end
97
97
 
98
98
  def method_name_and_arguments_on_same_line?(node)
99
- return false unless node.call_type?
99
+ return false if !node.call_type? || node.last_line != node.last_argument.last_line
100
+ return true if node.last_argument.hash_type? && node.last_argument.braces?
100
101
 
101
- line = node.loc.selector.nil? ? node.loc.line : node.loc.selector.line
102
-
103
- line == node.last_argument.last_line && node.last_line == node.last_argument.last_line
102
+ node.loc.selector.line == node.last_argument.last_line
104
103
  end
105
104
 
106
105
  # A single argument with the closing bracket on the same line as the end
@@ -185,7 +184,7 @@ module RuboCop
185
184
 
186
185
  def heredoc?(node)
187
186
  return false unless node.is_a?(RuboCop::AST::Node)
188
- return true if node.loc.respond_to?(:heredoc_body)
187
+ return true if node.loc?(:heredoc_body)
189
188
 
190
189
  return heredoc_send?(node) if node.send_type?
191
190
 
@@ -234,7 +234,7 @@ module RuboCop
234
234
  end
235
235
 
236
236
  def range_position(node)
237
- if node.loc.respond_to?(:selector)
237
+ if node.loc?(:selector)
238
238
  selector_end_pos = node.loc.selector.end_pos + 1
239
239
  expr_end_pos = node.source_range.end_pos
240
240
 
@@ -41,8 +41,7 @@ module RuboCop
41
41
 
42
42
  def check(node)
43
43
  return if node.heredoc?
44
- return unless node.loc.respond_to?(:begin)
45
- return unless node.loc.begin
44
+ return unless node.loc?(:begin)
46
45
 
47
46
  source = node.loc.begin.source
48
47
  if requires_percent_q?(source)
@@ -3,31 +3,36 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for uses of the case equality operator(===).
6
+ # Checks for uses of the case equality operator (`===`).
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
-
10
+ #
11
11
  # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
12
12
  # the case equality operator is `self.class`. Note intermediate variables are not accepted.
13
13
  #
14
+ # NOTE: Regexp case equality (`/regexp/ === var`) is allowed because changing it to
15
+ # `/regexp/.match?(var)` needs to take into account `Regexp.last_match?`, `$~`, `$1`, etc.
16
+ # This potentially incompatible transformation is handled by `Performance/RegexpMatch` cop.
17
+ #
14
18
  # @example
15
19
  # # bad
16
20
  # (1..100) === 7
17
- # /something/ === some_string
18
21
  #
19
22
  # # good
20
- # something.is_a?(Array)
21
23
  # (1..100).include?(7)
22
- # /something/.match?(some_string)
23
24
  #
24
25
  # @example AllowOnConstant: false (default)
25
26
  # # bad
26
27
  # Array === something
27
28
  #
29
+ # # good
30
+ # something.is_a?(Array)
31
+ #
28
32
  # @example AllowOnConstant: true
29
33
  # # good
30
34
  # Array === something
35
+ # something.is_a?(Array)
31
36
  #
32
37
  # @example AllowOnSelfClass: false (default)
33
38
  # # bad
@@ -51,7 +56,7 @@ module RuboCop
51
56
 
52
57
  def on_send(node)
53
58
  case_equality?(node) do |lhs, rhs|
54
- return if lhs.const_type? && !lhs.module_name?
59
+ return if lhs.regexp_type? || (lhs.const_type? && !lhs.module_name?)
55
60
 
56
61
  add_offense(node.loc.selector) do |corrector|
57
62
  replacement = replacement(lhs, rhs)
@@ -71,13 +76,6 @@ module RuboCop
71
76
 
72
77
  def replacement(lhs, rhs)
73
78
  case lhs.type
74
- when :regexp
75
- # The automatic correction from `a === b` to `a.match?(b)` needs to
76
- # consider `Regexp.last_match?`, `$~`, `$1`, and etc.
77
- # This correction is expected to be supported by `Performance/Regexp` cop.
78
- # See: https://github.com/rubocop/rubocop-performance/issues/152
79
- #
80
- # So here is noop.
81
79
  when :begin
82
80
  begin_replacement(lhs, rhs)
83
81
  when :const
@@ -183,6 +183,7 @@ module RuboCop
183
183
 
184
184
  def check_nested_style(node)
185
185
  return unless compact_node_name?(node)
186
+ return if node.parent&.type?(:class, :module)
186
187
 
187
188
  add_offense(node.loc.name, message: NESTED_MSG) do |corrector|
188
189
  autocorrect(corrector, node)
@@ -213,9 +213,7 @@ module RuboCop
213
213
  ASSIGN_TO_CONDITION_MSG = 'Assign variables inside of conditionals.'
214
214
  VARIABLE_ASSIGNMENT_TYPES = %i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
215
215
  ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES + %i[and_asgn or_asgn op_asgn masgn].freeze
216
- LINE_LENGTH = 'Layout/LineLength'
217
216
  ENABLED = 'Enabled'
218
- MAX = 'Max'
219
217
  SINGLE_LINE_CONDITIONS_ONLY = 'SingleLineConditionsOnly'
220
218
 
221
219
  # The shovel operator `<<` does not have its own type. It is a `send`
@@ -399,7 +397,7 @@ module RuboCop
399
397
  # of the longest line + the length of the corrected assignment is
400
398
  # greater than the max configured line length
401
399
  def correction_exceeds_line_limit?(node, branches)
402
- return false unless line_length_cop_enabled?
400
+ return false unless config.cop_enabled?('Layout/LineLength')
403
401
 
404
402
  assignment = lhs(tail(branches[0]))
405
403
 
@@ -417,14 +415,6 @@ module RuboCop
417
415
  assignment + longest_line
418
416
  end
419
417
 
420
- def line_length_cop_enabled?
421
- config.for_cop(LINE_LENGTH)[ENABLED]
422
- end
423
-
424
- def max_line_length
425
- config.for_cop(LINE_LENGTH)[MAX]
426
- end
427
-
428
418
  def single_line_conditions_only?
429
419
  cop_config[SINGLE_LINE_CONDITIONS_ONLY]
430
420
  end
@@ -29,19 +29,19 @@ module RuboCop
29
29
  # @example IgnoreModules: false (default)
30
30
  # # bad
31
31
  # class Foo
32
- # MyClass = Struct.new()
32
+ # MyClass = Struct.new
33
33
  # end
34
34
  #
35
35
  # # good
36
36
  # class Foo
37
- # MyClass = Struct.new()
37
+ # MyClass = Struct.new
38
38
  # public_constant :MyClass
39
39
  # end
40
40
  #
41
41
  # @example IgnoreModules: true
42
42
  # # good
43
43
  # class Foo
44
- # MyClass = Struct.new()
44
+ # MyClass = Struct.new
45
45
  # end
46
46
  #
47
47
  class ConstantVisibility < Base
@@ -107,12 +107,6 @@ module RuboCop
107
107
  def expanded_style?
108
108
  style == :expanded
109
109
  end
110
-
111
- def max_line_length
112
- return unless config.cop_enabled?('Layout/LineLength')
113
-
114
- config.for_cop('Layout/LineLength')['Max']
115
- end
116
110
  end
117
111
  end
118
112
  end
@@ -200,7 +200,7 @@ module RuboCop
200
200
 
201
201
  def use_heredoc?(node)
202
202
  return false unless (body = node.body)
203
- return true if body.str_type? && body.heredoc?
203
+ return true if body.any_str_type? && body.heredoc?
204
204
 
205
205
  body.each_descendant(:str).any?(&:heredoc?)
206
206
  end
@@ -234,7 +234,7 @@ module RuboCop
234
234
 
235
235
  offset = modifier_offset(node)
236
236
 
237
- endless_replacement(node).length + offset > config.for_cop('Layout/LineLength')['Max']
237
+ endless_replacement(node).length + offset > max_line_length
238
238
  end
239
239
 
240
240
  def modifier_offset(node)
@@ -45,17 +45,6 @@ module RuboCop
45
45
  # ok
46
46
  #
47
47
  # # bad
48
- # if something
49
- # foo || raise('exception')
50
- # else
51
- # ok
52
- # end
53
- #
54
- # # good
55
- # foo || raise('exception') if something
56
- # ok
57
- #
58
- # # bad
59
48
  # define_method(:test) do
60
49
  # if something
61
50
  # work
@@ -207,14 +207,14 @@ module RuboCop
207
207
  def too_long_line_based_on_config?(range, line)
208
208
  return false if matches_allowed_pattern?(line)
209
209
 
210
- too_long = too_long_line_based_on_ignore_cop_directives?(range, line)
210
+ too_long = too_long_line_based_on_allow_cop_directives?(range, line)
211
211
  return too_long unless too_long == :undetermined
212
212
 
213
213
  too_long_line_based_on_allow_uri?(line)
214
214
  end
215
215
 
216
- def too_long_line_based_on_ignore_cop_directives?(range, line)
217
- if ignore_cop_directives? && directive_on_source_line?(range.line - 1)
216
+ def too_long_line_based_on_allow_cop_directives?(range, line)
217
+ if allow_cop_directives? && directive_on_source_line?(range.line - 1)
218
218
  return line_length_without_directive(line) > max_line_length
219
219
  end
220
220
 
@@ -36,10 +36,21 @@ module RuboCop
36
36
  cop_config.fetch('IncludedMacros', []).map(&:to_sym)
37
37
  end
38
38
 
39
+ def included_macro_patterns
40
+ cop_config.fetch('IncludedMacroPatterns', [])
41
+ end
42
+
43
+ def matches_included_macro_pattern?(method_name)
44
+ included_macro_patterns.any? do |pattern|
45
+ Regexp.new(pattern).match?(method_name.to_s)
46
+ end
47
+ end
48
+
39
49
  def ignored_macro?(node)
40
50
  cop_config['IgnoreMacros'] &&
41
51
  node.macro? &&
42
- !included_macros_list.include?(node.method_name)
52
+ !included_macros_list.include?(node.method_name) &&
53
+ !matches_included_macro_pattern?(node.method_name)
43
54
  end
44
55
  end
45
56
  end