rubocop 1.81.6 → 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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +22 -6
  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 +7 -6
  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/hash_alignment.rb +2 -0
  17. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  18. data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -4
  19. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  20. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  21. data/lib/rubocop/cop/layout/line_length.rb +7 -4
  22. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +5 -3
  23. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  24. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
  25. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +1 -1
  26. data/lib/rubocop/cop/lint/debugger.rb +0 -2
  27. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  28. data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -0
  29. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  30. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +16 -6
  31. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
  32. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  33. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
  34. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -1
  35. data/lib/rubocop/cop/lint/self_assignment.rb +9 -1
  36. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
  37. data/lib/rubocop/cop/lint/useless_or.rb +15 -2
  38. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +1 -1
  39. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  40. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +0 -4
  41. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  42. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
  43. data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
  44. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  45. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  46. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  47. data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
  48. data/lib/rubocop/cop/mixin/trailing_comma.rb +4 -5
  49. data/lib/rubocop/cop/naming/method_name.rb +4 -2
  50. data/lib/rubocop/cop/naming/predicate_method.rb +4 -4
  51. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
  52. data/lib/rubocop/cop/style/case_equality.rb +11 -13
  53. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  54. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -11
  55. data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
  56. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  57. data/lib/rubocop/cop/style/endless_method.rb +2 -2
  58. data/lib/rubocop/cop/style/float_division.rb +15 -1
  59. data/lib/rubocop/cop/style/guard_clause.rb +0 -11
  60. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  61. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
  62. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
  63. data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
  64. data/lib/rubocop/cop/style/multiline_method_signature.rb +0 -4
  65. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  66. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  67. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  68. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +5 -0
  69. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  70. data/lib/rubocop/cop/style/semicolon.rb +3 -2
  71. data/lib/rubocop/cop/style/sole_nested_conditional.rb +8 -1
  72. data/lib/rubocop/cop/style/super_arguments.rb +2 -2
  73. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
  74. data/lib/rubocop/cop/util.rb +2 -3
  75. data/lib/rubocop/directive_comment.rb +46 -3
  76. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -0
  77. data/lib/rubocop/lsp/diagnostic.rb +12 -17
  78. data/lib/rubocop/lsp/routes.rb +9 -36
  79. data/lib/rubocop/lsp/runtime.rb +2 -2
  80. data/lib/rubocop/lsp/server.rb +2 -2
  81. data/lib/rubocop/magic_comment.rb +20 -0
  82. data/lib/rubocop/rake_task.rb +1 -1
  83. data/lib/rubocop/remote_config.rb +7 -8
  84. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  85. data/lib/rubocop/rspec/support.rb +1 -1
  86. data/lib/rubocop/target_ruby.rb +1 -1
  87. data/lib/rubocop/version.rb +1 -1
  88. data/lib/rubocop.rb +1 -0
  89. metadata +7 -6
@@ -35,6 +35,26 @@ module RuboCop
35
35
  # def cook(dry_ingredients = self.dry_ingredients)
36
36
  # dry_ingredients.combine
37
37
  # end
38
+ #
39
+ # # bad
40
+ # def foo(pie = pie = pie)
41
+ # pie.heat_up
42
+ # end
43
+ #
44
+ # # good
45
+ # def foo(pie)
46
+ # pie.heat_up
47
+ # end
48
+ #
49
+ # # bad
50
+ # def foo(pie = cake = pie)
51
+ # [pie, cake].each(&:heat_up)
52
+ # end
53
+ #
54
+ # # good
55
+ # def foo(cake = pie)
56
+ # [pie, cake].each(&:heat_up)
57
+ # end
38
58
  class CircularArgumentReference < Base
39
59
  extend TargetRubyVersion
40
60
 
@@ -51,11 +71,35 @@ module RuboCop
51
71
  private
52
72
 
53
73
  def check_for_circular_argument_references(arg_name, arg_value)
54
- return unless arg_value.lvar_type?
55
- return unless arg_value.to_a == [arg_name]
74
+ if arg_value.lvar_type? && arg_value.to_a == [arg_name]
75
+ add_offense(arg_value, message: format(MSG, arg_name: arg_name))
76
+
77
+ return
78
+ end
79
+
80
+ check_assignment_chain(arg_name, arg_value)
81
+ end
82
+
83
+ # rubocop:disable Metrics/AbcSize
84
+ def check_assignment_chain(arg_name, node)
85
+ return unless node.lvasgn_type?
86
+
87
+ seen_variables = Set[]
88
+ current_node = node
89
+
90
+ while current_node.lvasgn_type?
91
+ seen_variables << current_node.children.first if current_node.lvasgn_type?
92
+ current_node = current_node.children.last
93
+ end
94
+
95
+ return unless current_node.lvar_type?
96
+
97
+ variable_node = current_node.children.first
98
+ return unless seen_variables.include?(variable_node) || variable_node == arg_name
56
99
 
57
- add_offense(arg_value, message: format(MSG, arg_name: arg_name))
100
+ add_offense(current_node, message: format(MSG, arg_name: arg_name))
58
101
  end
102
+ # rubocop:enable Metrics/AbcSize
59
103
  end
60
104
  end
61
105
  end
@@ -46,7 +46,7 @@ module RuboCop
46
46
  COMMON_MSG = 'Malformed directive comment detected.'
47
47
 
48
48
  MISSING_MODE_NAME_MSG = 'The mode name is missing.'
49
- INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, or `todo`.'
49
+ INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, `todo`, `push`, or `pop`.' # rubocop:disable Layout/LineLength
50
50
  MISSING_COP_NAME_MSG = 'The cop name is missing.'
51
51
  MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
52
52
  'Comment in the directive must start with `--`.'
@@ -102,8 +102,6 @@ module RuboCop
102
102
  end
103
103
 
104
104
  def debugger_method?(send_node)
105
- return false if send_node.parent&.send_type? && send_node.parent.receiver == send_node
106
-
107
105
  debugger_methods.include?(chained_method_name(send_node))
108
106
  end
109
107
 
@@ -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)
@@ -9,9 +9,21 @@ module RuboCop
9
9
  # cop disables on wide ranges of code, that latter contributors to
10
10
  # a file wouldn't be aware of.
11
11
  #
12
- # @example
13
- # # Lint/MissingCopEnableDirective:
14
- # # MaximumRangeSize: .inf
12
+ # You can set `MaximumRangeSize` to define the maximum number of
13
+ # consecutive lines a cop can be disabled for.
14
+ #
15
+ # - `.inf` any size (default)
16
+ # - `0` allows only single-line disables
17
+ # - `1` means the maximum allowed is as follows:
18
+ #
19
+ # [source,ruby]
20
+ # ----
21
+ # # rubocop:disable SomeCop
22
+ # a = 1
23
+ # # rubocop:enable SomeCop
24
+ # ----
25
+ #
26
+ # @example MaximumRangeSize: .inf (default)
15
27
  #
16
28
  # # good
17
29
  # # rubocop:disable Layout/SpaceAroundOperators
@@ -25,9 +37,7 @@ module RuboCop
25
37
  # x= 0
26
38
  # # EOF
27
39
  #
28
- # @example
29
- # # Lint/MissingCopEnableDirective:
30
- # # MaximumRangeSize: 2
40
+ # @example MaximumRangeSize: 2
31
41
  #
32
42
  # # good
33
43
  # # rubocop:disable Layout/SpaceAroundOperators
@@ -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
 
@@ -147,7 +147,9 @@ module RuboCop
147
147
  alias on_defs on_def
148
148
 
149
149
  def on_alias(node)
150
- handle_method_name(node.new_identifier, node.new_identifier.value)
150
+ return unless (new_identifier = node.new_identifier).sym_type?
151
+
152
+ handle_method_name(new_identifier, new_identifier.value)
151
153
  end
152
154
 
153
155
  private
@@ -232,7 +234,7 @@ module RuboCop
232
234
  end
233
235
 
234
236
  def range_position(node)
235
- if node.loc.respond_to?(:selector)
237
+ if node.loc?(:selector)
236
238
  selector_end_pos = node.loc.selector.end_pos + 1
237
239
  expr_end_pos = node.source_range.end_pos
238
240
 
@@ -193,8 +193,7 @@ module RuboCop
193
193
  return_values << extract_return_value(return_node)
194
194
  end
195
195
 
196
- last_value = last_value(node)
197
- return_values << last_value if last_value
196
+ return_values << last_value(node)
198
197
 
199
198
  process_return_values(return_values)
200
199
  end
@@ -247,8 +246,9 @@ module RuboCop
247
246
  end
248
247
 
249
248
  def last_value(node)
250
- value = node.begin_type? ? node.children.last : node
251
- value&.return_type? ? extract_return_value(value) : value
249
+ value = node.begin_type? ? node.children.last || s(:nil) : node
250
+
251
+ value.return_type? ? extract_return_value(value) : value
252
252
  end
253
253
 
254
254
  def process_return_values(return_values)
@@ -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)