rubocop 1.45.1 → 1.47.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 (160) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +10 -9
  4. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  5. data/lib/rubocop/comment_config.rb +19 -0
  6. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  7. data/lib/rubocop/cop/base.rb +1 -1
  8. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  9. data/lib/rubocop/cop/corrector.rb +1 -1
  10. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
  11. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  12. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  13. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  14. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  15. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -1
  16. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs/cop_description.rb +4 -4
  18. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +1 -1
  19. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  20. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  21. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  22. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  23. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  24. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  25. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +39 -0
  26. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  27. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -4
  28. data/lib/rubocop/cop/layout/class_structure.rb +5 -3
  29. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
  30. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  31. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  32. data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
  33. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
  34. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -2
  35. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  36. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  37. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
  38. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -7
  39. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  40. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  41. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  42. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  43. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  44. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  45. data/lib/rubocop/cop/lint/debugger.rb +3 -0
  46. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  47. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  48. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  49. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
  50. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  51. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  52. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  53. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  54. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  55. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
  56. data/lib/rubocop/cop/lint/missing_super.rb +31 -2
  57. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -9
  58. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +6 -10
  59. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  60. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  61. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +10 -4
  62. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  63. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
  64. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  65. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  66. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  67. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  68. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  69. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  70. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  71. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  72. data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -2
  73. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -9
  74. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -1
  75. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  76. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  77. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  78. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  79. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  80. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  81. data/lib/rubocop/cop/mixin/comments_help.rb +2 -2
  82. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  83. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  84. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +10 -7
  85. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  86. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  87. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  88. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  89. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  90. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  91. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  92. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  93. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  94. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  95. data/lib/rubocop/cop/style/accessor_grouping.rb +22 -12
  96. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
  97. data/lib/rubocop/cop/style/array_intersect.rb +1 -1
  98. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  99. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  100. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  101. data/lib/rubocop/cop/style/block_delimiters.rb +2 -2
  102. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  103. data/lib/rubocop/cop/style/collection_compact.rb +1 -1
  104. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  105. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  106. data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
  107. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -6
  108. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  109. data/lib/rubocop/cop/style/documentation.rb +1 -1
  110. data/lib/rubocop/cop/style/documentation_method.rb +4 -4
  111. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  112. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  113. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  114. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  115. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  116. data/lib/rubocop/cop/style/file_read.rb +1 -1
  117. data/lib/rubocop/cop/style/file_write.rb +1 -1
  118. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  119. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  120. data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
  121. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  122. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  123. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
  124. data/lib/rubocop/cop/style/min_max.rb +3 -3
  125. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  126. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  127. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  128. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  129. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  130. data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
  131. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
  132. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  133. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  134. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +5 -6
  135. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +10 -3
  136. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  137. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  138. data/lib/rubocop/cop/style/require_order.rb +1 -3
  139. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  140. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  141. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  142. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
  143. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  144. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  145. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  146. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  147. data/lib/rubocop/cop/style/word_array.rb +17 -5
  148. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  149. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  150. data/lib/rubocop/cop/team.rb +11 -8
  151. data/lib/rubocop/cop/util.rb +13 -4
  152. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  153. data/lib/rubocop/directive_comment.rb +3 -3
  154. data/lib/rubocop/ext/comment.rb +18 -0
  155. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  156. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  157. data/lib/rubocop/target_ruby.rb +1 -1
  158. data/lib/rubocop/version.rb +1 -1
  159. data/lib/rubocop.rb +2 -0
  160. metadata +10 -5
@@ -104,7 +104,7 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def inline_comment?(comment)
107
- !comment_line?(comment.loc.expression.source_line)
107
+ !comment_line?(comment.source_range.source_line)
108
108
  end
109
109
 
110
110
  def annotation_range(annotation)
@@ -66,7 +66,7 @@ module RuboCop
66
66
 
67
67
  def register_offense(comment, matched_keyword)
68
68
  add_offense(comment, message: format(MSG, keyword: matched_keyword)) do |corrector|
69
- range = range_with_surrounding_space(comment.loc.expression, newlines: false)
69
+ range = range_with_surrounding_space(comment.source_range, newlines: false)
70
70
  corrector.remove(range)
71
71
 
72
72
  unless matched_keyword == 'end'
@@ -84,7 +84,7 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def source_line(comment)
87
- comment.location.expression.source_line
87
+ comment.source_range.source_line
88
88
  end
89
89
  end
90
90
  end
@@ -38,7 +38,7 @@ module RuboCop
38
38
  offense = offense_range(node)
39
39
  current = offense.source
40
40
 
41
- if node.arguments.any?(&:percent_literal?)
41
+ if (use_percent_literal = node.arguments.any?(&:percent_literal?))
42
42
  if percent_literals_includes_only_basic_literals?(node)
43
43
  prefer = preferred_method(node)
44
44
  message = format(MSG, prefer: prefer, current: current)
@@ -51,7 +51,15 @@ module RuboCop
51
51
  end
52
52
 
53
53
  add_offense(offense, message: message) do |corrector|
54
- corrector.replace(offense, prefer)
54
+ if use_percent_literal
55
+ corrector.replace(offense, prefer)
56
+ else
57
+ corrector.replace(node.loc.selector, 'push')
58
+ node.arguments.each do |argument|
59
+ corrector.remove(argument.loc.begin)
60
+ corrector.remove(argument.loc.end)
61
+ end
62
+ end
55
63
  end
56
64
  end
57
65
  # rubocop:enable Metrics
@@ -450,7 +450,7 @@ module RuboCop
450
450
  end
451
451
 
452
452
  def white_space_range(node, column)
453
- expression = node.loc.expression
453
+ expression = node.source_range
454
454
  begin_pos = expression.begin_pos - (expression.column - column - 2)
455
455
 
456
456
  Parser::Source::Range.new(expression.source_buffer, begin_pos, expression.begin_pos)
@@ -458,9 +458,9 @@ module RuboCop
458
458
 
459
459
  def assignment(node)
460
460
  *_, condition = *node
461
- Parser::Source::Range.new(node.loc.expression.source_buffer,
462
- node.loc.expression.begin_pos,
463
- condition.loc.expression.begin_pos)
461
+ Parser::Source::Range.new(node.source_range.source_buffer,
462
+ node.source_range.begin_pos,
463
+ condition.source_range.begin_pos)
464
464
  end
465
465
 
466
466
  def correct_if_branches(corrector, cop, node)
@@ -565,7 +565,7 @@ module RuboCop
565
565
  end
566
566
 
567
567
  def move_assignment_inside_condition(corrector, node)
568
- column = node.loc.expression.column
568
+ column = node.source_range.column
569
569
  *_var, condition = *node
570
570
  assignment = assignment(node)
571
571
 
@@ -616,7 +616,7 @@ module RuboCop
616
616
  end
617
617
 
618
618
  def move_assignment_inside_condition(corrector, node)
619
- column = node.loc.expression.column
619
+ column = node.source_range.column
620
620
  *_var, condition = *node
621
621
  assignment = assignment(node)
622
622
 
@@ -116,7 +116,7 @@ module RuboCop
116
116
 
117
117
  def preceding_comment_blocks(node)
118
118
  # Collect comments in the method call, but outside the heredoc
119
- comments = processed_source.each_comment_in_lines(node.loc.expression.line_span)
119
+ comments = processed_source.each_comment_in_lines(node.source_range.line_span)
120
120
 
121
121
  comments.each_with_object({}) do |comment, hash|
122
122
  merge_adjacent_comments(comment.text, comment.loc.line, hash)
@@ -110,7 +110,7 @@ module RuboCop
110
110
  return if nodoc_self_or_outer_module?(node)
111
111
  return if include_statement_only?(body)
112
112
 
113
- range = range_between(node.loc.expression.begin_pos, node.loc.name.end_pos)
113
+ range = range_between(node.source_range.begin_pos, node.loc.name.end_pos)
114
114
  message = format(MSG, type: node.type, identifier: identifier(node))
115
115
  add_offense(range, message: message)
116
116
  end
@@ -101,16 +101,16 @@ module RuboCop
101
101
 
102
102
  MSG = 'Missing method documentation comment.'
103
103
 
104
- # @!method module_function_node?(node)
105
- def_node_matcher :module_function_node?, <<~PATTERN
106
- (send nil? :module_function ...)
104
+ # @!method modifier_node?(node)
105
+ def_node_matcher :modifier_node?, <<~PATTERN
106
+ (send nil? {:module_function :ruby2_keywords} ...)
107
107
  PATTERN
108
108
 
109
109
  def on_def(node)
110
110
  return if node.method?(:initialize)
111
111
 
112
112
  parent = node.parent
113
- module_function_node?(parent) ? check(parent) : check(node)
113
+ modifier_node?(parent) ? check(parent) : check(node)
114
114
  end
115
115
  alias on_defs on_def
116
116
 
@@ -131,7 +131,7 @@ module RuboCop
131
131
  end
132
132
 
133
133
  def whole_line_expression(node)
134
- range_by_whole_lines(node.loc.expression, include_final_newline: true)
134
+ range_by_whole_lines(node.source_range, include_final_newline: true)
135
135
  end
136
136
  end
137
137
  end
@@ -37,7 +37,7 @@ module RuboCop
37
37
 
38
38
  def autocorrect(corrector, node)
39
39
  block = node.parent
40
- range = range_between(block.loc.begin.end_pos, node.loc.expression.end_pos)
40
+ range = range_between(block.loc.begin.end_pos, node.source_range.end_pos)
41
41
 
42
42
  corrector.remove(range)
43
43
  end
@@ -34,7 +34,7 @@ module RuboCop
34
34
 
35
35
  def autocorrect(corrector, node)
36
36
  send_node = node.parent.send_node
37
- range = range_between(send_node.loc.expression.end_pos, node.loc.expression.end_pos)
37
+ range = range_between(send_node.source_range.end_pos, node.source_range.end_pos)
38
38
 
39
39
  corrector.remove(range)
40
40
  end
@@ -146,7 +146,7 @@ module RuboCop
146
146
  actual: line_node.source,
147
147
  expected: expected)
148
148
 
149
- add_offense(line_node.loc.expression, message: message) do |corrector|
149
+ add_offense(line_node.source_range, message: message) do |corrector|
150
150
  corrector.replace(line_node, expected)
151
151
  end
152
152
  end
@@ -175,14 +175,14 @@ module RuboCop
175
175
  end
176
176
 
177
177
  def line_difference(line_node, code)
178
- string_first_line(code) - line_node.loc.expression.first_line
178
+ string_first_line(code) - line_node.source_range.first_line
179
179
  end
180
180
 
181
181
  def string_first_line(str_node)
182
182
  if str_node.heredoc?
183
183
  str_node.loc.heredoc_body.first_line
184
184
  else
185
- str_node.loc.expression.first_line
185
+ str_node.source_range.first_line
186
186
  end
187
187
  end
188
188
 
@@ -210,7 +210,7 @@ module RuboCop
210
210
  def add_offense_for_missing_line(node, code)
211
211
  register_offense(node) do |corrector|
212
212
  line_str = missing_line(node, code)
213
- corrector.insert_after(node.loc.expression.end, ", #{line_str}")
213
+ corrector.insert_after(node.source_range.end, ", #{line_str}")
214
214
  end
215
215
  end
216
216
 
@@ -145,7 +145,7 @@ module RuboCop
145
145
  end
146
146
 
147
147
  def block_body_range(block_node, send_node)
148
- range_between(send_node.loc.expression.end_pos, block_node.loc.end.end_pos)
148
+ range_between(send_node.source_range.end_pos, block_node.loc.end.end_pos)
149
149
  end
150
150
  end
151
151
  end
@@ -71,7 +71,7 @@ module RuboCop
71
71
  message = format(MSG, read_method: read_method(mode))
72
72
 
73
73
  add_offense(read_node, message: message) do |corrector|
74
- range = range_between(node.loc.selector.begin_pos, read_node.loc.expression.end_pos)
74
+ range = range_between(node.loc.selector.begin_pos, read_node.source_range.end_pos)
75
75
  replacement = "#{read_method(mode)}(#{filename.source})"
76
76
 
77
77
  corrector.replace(range, replacement)
@@ -74,7 +74,7 @@ module RuboCop
74
74
  message = format(MSG, write_method: write_method(mode))
75
75
 
76
76
  add_offense(write_node, message: message) do |corrector|
77
- range = range_between(node.loc.selector.begin_pos, write_node.loc.expression.end_pos)
77
+ range = range_between(node.loc.selector.begin_pos, write_node.source_range.end_pos)
78
78
  replacement = replacement(mode, filename, content, write_node)
79
79
 
80
80
  corrector.replace(range, replacement)
@@ -182,7 +182,7 @@ module RuboCop
182
182
 
183
183
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
184
184
  def autocorrect(corrector, node, condition, replacement, guard)
185
- corrector.replace(node.loc.keyword.join(condition.loc.expression), replacement)
185
+ corrector.replace(node.loc.keyword.join(condition.source_range), replacement)
186
186
 
187
187
  if_branch = node.if_branch
188
188
  else_branch = node.else_branch
@@ -247,7 +247,7 @@ module RuboCop
247
247
  end
248
248
 
249
249
  def argument_without_space?(node)
250
- node.argument? && node.loc.expression.begin_pos == node.parent.loc.selector.end_pos
250
+ node.argument? && node.source_range.begin_pos == node.parent.loc.selector.end_pos
251
251
  end
252
252
 
253
253
  def autocorrect_hash_rockets(corrector, pair_node)
@@ -11,6 +11,20 @@ module RuboCop
11
11
  # cop. The tab size is configured in the `IndentationWidth` of the
12
12
  # `Layout/IndentationStyle` cop.
13
13
  #
14
+ # NOTE: It is allowed when `defined?` argument has an undefined value,
15
+ # because using the modifier form causes the following incompatibility:
16
+ #
17
+ # [source,ruby]
18
+ # ----
19
+ # unless defined?(undefined_foo)
20
+ # undefined_foo = 'default_value'
21
+ # end
22
+ # undefined_foo # => 'default_value'
23
+ #
24
+ # undefined_bar = 'default_value' unless defined?(undefined_bar)
25
+ # undefined_bar # => nil
26
+ # ----
27
+ #
14
28
  # @example
15
29
  # # bad
16
30
  # if condition
@@ -51,6 +65,8 @@ module RuboCop
51
65
  end
52
66
 
53
67
  def on_if(node)
68
+ return if defined_nodes(node).any? { |n| defined_argument_is_undefined?(node, n) }
69
+
54
70
  msg = if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
55
71
  MSG_USE_MODIFIER
56
72
  elsif too_long_due_to_modifier?(node)
@@ -65,6 +81,24 @@ module RuboCop
65
81
 
66
82
  private
67
83
 
84
+ def defined_nodes(node)
85
+ if node.condition.defined_type?
86
+ [node.condition]
87
+ else
88
+ node.condition.each_descendant.select(&:defined_type?)
89
+ end
90
+ end
91
+
92
+ def defined_argument_is_undefined?(if_node, defined_node)
93
+ defined_argument = defined_node.first_argument
94
+ return false unless defined_argument.lvar_type? || defined_argument.send_type?
95
+
96
+ if_node.left_siblings.none? do |sibling|
97
+ sibling.respond_to?(:lvasgn_type?) && sibling.lvasgn_type? &&
98
+ sibling.name == defined_argument.node_parts[0]
99
+ end
100
+ end
101
+
68
102
  def autocorrect(corrector, node)
69
103
  replacement = if node.modifier_form?
70
104
  last_argument = node.if_branch.last_argument if node.if_branch.send_type?
@@ -155,15 +155,15 @@ module RuboCop
155
155
  end
156
156
 
157
157
  def not_to_receiver(node, method_call)
158
- Parser::Source::Range.new(node.loc.expression.source_buffer,
158
+ Parser::Source::Range.new(node.source_range.source_buffer,
159
159
  node.loc.selector.begin_pos,
160
- method_call.loc.expression.begin_pos)
160
+ method_call.source_range.begin_pos)
161
161
  end
162
162
 
163
163
  def end_parentheses(node, method_call)
164
- Parser::Source::Range.new(node.loc.expression.source_buffer,
165
- method_call.loc.expression.end_pos,
166
- node.loc.expression.end_pos)
164
+ Parser::Source::Range.new(node.source_range.source_buffer,
165
+ method_call.source_range.end_pos,
166
+ node.source_range.end_pos)
167
167
  end
168
168
 
169
169
  # When comparing classes, `!(Integer < Numeric)` is not the same as
@@ -123,10 +123,10 @@ module RuboCop
123
123
  end
124
124
 
125
125
  def range(node)
126
- buffer = node.loc.expression.source_buffer
126
+ buffer = node.source_range.source_buffer
127
127
  map_node = node.receiver.send_node
128
128
  begin_pos = map_node.loc.selector.begin_pos
129
- end_pos = node.loc.expression.end_pos
129
+ end_pos = node.source_range.end_pos
130
130
 
131
131
  Parser::Source::Range.new(buffer, begin_pos, end_pos)
132
132
  end
@@ -226,7 +226,7 @@ module RuboCop
226
226
  end
227
227
 
228
228
  def args_end(node)
229
- node.loc.expression.end
229
+ node.source_range.end
230
230
  end
231
231
 
232
232
  def args_parenthesized?(node)
@@ -48,13 +48,13 @@ module RuboCop
48
48
  when :return
49
49
  argument_range(node)
50
50
  else
51
- node.loc.expression
51
+ node.source_range
52
52
  end
53
53
  end
54
54
 
55
55
  def argument_range(node)
56
- first_argument_range = node.children.first.loc.expression
57
- last_argument_range = node.children.last.loc.expression
56
+ first_argument_range = node.children.first.source_range
57
+ last_argument_range = node.children.last.source_range
58
58
 
59
59
  first_argument_range.join(last_argument_range)
60
60
  end
@@ -51,9 +51,9 @@ module RuboCop
51
51
  private
52
52
 
53
53
  def range_to_remove_for_subsequent_mixin(mixins, node)
54
- range = node.loc.expression
54
+ range = node.source_range
55
55
  prev_mixin = mixins.each_cons(2) { |m, n| break m if n == node }
56
- between = prev_mixin.loc.expression.end.join(range.begin)
56
+ between = prev_mixin.source_range.end.join(range.begin)
57
57
  # if separated from previous mixin with only whitespace?
58
58
  unless /\S/.match?(between.source)
59
59
  range = range.join(between) # then remove that too
@@ -75,7 +75,7 @@ module RuboCop
75
75
  message = format(MSG, mixin: send_node.method_name, suffix: 'a single statement')
76
76
 
77
77
  add_offense(send_node, message: message) do |corrector|
78
- range = send_node.loc.expression
78
+ range = send_node.source_range
79
79
  mixins = sibling_mixins(send_node)
80
80
  if send_node == mixins.first
81
81
  correction = group_mixins(send_node, mixins)
@@ -94,7 +94,7 @@ module RuboCop
94
94
  message = format(MSG, mixin: send_node.method_name, suffix: 'separate statements')
95
95
 
96
96
  add_offense(send_node, message: message) do |corrector|
97
- range = send_node.loc.expression
97
+ range = send_node.source_range
98
98
  correction = separate_mixins(send_node)
99
99
 
100
100
  corrector.replace(range, correction)
@@ -75,7 +75,7 @@ module RuboCop
75
75
  end
76
76
 
77
77
  def indentation_width(node)
78
- processed_source.line_indentation(node.loc.expression.line)
78
+ processed_source.line_indentation(node.source_range.line)
79
79
  end
80
80
 
81
81
  def definition_width(node)
@@ -83,7 +83,7 @@ module RuboCop
83
83
 
84
84
  def comments_in_condition(node)
85
85
  comments_in_range(node).map do |comment|
86
- "#{comment.loc.expression.source}\n"
86
+ "#{comment.source}\n"
87
87
  end.join
88
88
  end
89
89
 
@@ -112,7 +112,7 @@ module RuboCop
112
112
  if node.ternary?
113
113
  node.if_branch
114
114
  else
115
- range_between(node.condition.loc.expression.end_pos, node.loc.else.begin_pos)
115
+ range_between(node.condition.source_range.end_pos, node.loc.else.begin_pos)
116
116
  end
117
117
  end
118
118
 
@@ -57,9 +57,9 @@ module RuboCop
57
57
 
58
58
  def autocorrect(corrector, node)
59
59
  range = if node.single_line?
60
- range_with_surrounding_space(node.body.loc.expression)
60
+ range_with_surrounding_space(node.body.source_range)
61
61
  else
62
- range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
62
+ range_by_whole_lines(node.body.source_range, include_final_newline: true)
63
63
  end
64
64
 
65
65
  corrector.remove(range)
@@ -70,8 +70,8 @@ module RuboCop
70
70
  end
71
71
 
72
72
  def range_of_offense(node)
73
- return node.loc.expression unless node.ternary?
74
- return node.loc.expression if node.ternary? && branches_have_method?(node)
73
+ return node.source_range unless node.ternary?
74
+ return node.source_range if node.ternary? && branches_have_method?(node)
75
75
 
76
76
  range_between(node.loc.question.begin_pos, node.loc.colon.end_pos)
77
77
  end
@@ -33,11 +33,11 @@ module RuboCop
33
33
  private
34
34
 
35
35
  def opening_brace(node)
36
- node.loc.begin.join(node.children.first.loc.expression.begin)
36
+ node.loc.begin.join(node.children.first.source_range.begin)
37
37
  end
38
38
 
39
39
  def closing_brace(node)
40
- node.children.last.loc.expression.end.join(node.loc.end)
40
+ node.children.last.source_range.end.join(node.loc.end)
41
41
  end
42
42
  end
43
43
  end
@@ -97,7 +97,7 @@ module RuboCop
97
97
  end
98
98
 
99
99
  def autocorrect_variable_interpolation(corrector, embedded_node, node)
100
- replacement = "#{embedded_node.loc.expression.source}.to_s"
100
+ replacement = "#{embedded_node.source}.to_s"
101
101
 
102
102
  corrector.replace(node, replacement)
103
103
  end
@@ -107,7 +107,7 @@ module RuboCop
107
107
 
108
108
  source = if require_parentheses?(embedded_var)
109
109
  receiver = range_between(
110
- embedded_var.loc.expression.begin_pos, embedded_var.loc.selector.end_pos
110
+ embedded_var.source_range.begin_pos, embedded_var.loc.selector.end_pos
111
111
  )
112
112
  arguments = embedded_var.arguments.map(&:source).join(', ')
113
113
 
@@ -153,7 +153,7 @@ module RuboCop
153
153
 
154
154
  return if node.send_type? && !method_call_with_redundant_parentheses?(node)
155
155
 
156
- offense(begin_node, 'an unary operation')
156
+ offense(begin_node, 'a unary operation')
157
157
  end
158
158
 
159
159
  def offense(node, msg)
@@ -74,7 +74,7 @@ module RuboCop
74
74
 
75
75
  non_redundant =
76
76
  whitespace_in_free_space_mode?(node, class_elem) ||
77
- backslash_b?(class_elem) || backslash_zero?(class_elem) ||
77
+ backslash_b?(class_elem) || octal_requiring_char_class?(class_elem) ||
78
78
  requires_escape_outside_char_class?(class_elem)
79
79
 
80
80
  !non_redundant
@@ -104,11 +104,10 @@ module RuboCop
104
104
  elem == '\b'
105
105
  end
106
106
 
107
- def backslash_zero?(elem)
108
- # See https://github.com/rubocop/rubocop/issues/11067 for details - in short "\0" != "0" -
109
- # the former means an Unicode code point `"\u0000"`, the latter a number character `"0"`.
110
- # Similarly "\032" means "\u001A". Other numbers starting with "\0" can also be mentioned.
111
- elem == '\0'
107
+ def octal_requiring_char_class?(elem)
108
+ # The octal escapes \1 to \7 only work inside a character class
109
+ # because they would be a backreference outside it.
110
+ elem.match?(/\A\\[1-7]\z/)
112
111
  end
113
112
 
114
113
  def requires_escape_outside_char_class?(elem)
@@ -74,11 +74,18 @@ module RuboCop
74
74
 
75
75
  def char_class_begins_or_ends_with_escaped_hyphen?(node, index)
76
76
  # The hyphen character is allowed to be escaped within a character class
77
- # but it's not necessry to escape hyphen if it's the first or last character
77
+ # but it's not necessary to escape hyphen if it's the first or last character
78
78
  # within the character class. This method checks if that's the case.
79
79
  # e.g. "[0-9\\-]" or "[\\-0-9]" would return true
80
- contents_range(node).source[index - 1] == '[' ||
81
- contents_range(node).source[index + 2] == ']'
80
+ content = contents_range(node).source
81
+
82
+ if content[index + 2] == ']'
83
+ true
84
+ elsif content[index - 1] == '['
85
+ index < 2 || content[index - 2] != '\\'
86
+ else
87
+ false
88
+ end
82
89
  end
83
90
 
84
91
  def delimiter?(node, char)
@@ -129,13 +129,13 @@ module RuboCop
129
129
  end
130
130
 
131
131
  def offense_range(sort_node, node)
132
- range_between(sort_node.loc.selector.begin_pos, node.loc.expression.end_pos)
132
+ range_between(sort_node.loc.selector.begin_pos, node.source_range.end_pos)
133
133
  end
134
134
 
135
135
  def message(node, sorter, accessor)
136
136
  accessor_source = range_between(
137
137
  node.loc.selector.begin_pos,
138
- node.loc.expression.end_pos
138
+ node.source_range.end_pos
139
139
  ).source
140
140
 
141
141
  format(MSG,
@@ -146,7 +146,7 @@ module RuboCop
146
146
 
147
147
  def autocorrect(corrector, node, sort_node, sorter, accessor)
148
148
  # Remove accessor, e.g. `first` or `[-1]`.
149
- corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
149
+ corrector.remove(range_between(accessor_start(node), node.source_range.end_pos))
150
150
  # Replace "sort" or "sort_by" with the appropriate min/max method.
151
151
  corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
152
152
  # Replace to avoid syntax errors when followed by a logical operator.
@@ -67,7 +67,7 @@ module RuboCop
67
67
  elsif begin_loc_present?(node)
68
68
  contents_range(node)
69
69
  else
70
- node.loc.expression
70
+ node.source_range
71
71
  end
72
72
  end
73
73
 
@@ -139,7 +139,7 @@ module RuboCop
139
139
 
140
140
  def heredoc_with_disabled_interpolation?(node)
141
141
  if heredoc?(node)
142
- node.loc.expression.source.end_with?("'")
142
+ node.source.end_with?("'")
143
143
  elsif node.parent&.dstr_type?
144
144
  heredoc_with_disabled_interpolation?(node.parent)
145
145
  else
@@ -125,9 +125,7 @@ module RuboCop
125
125
  end
126
126
 
127
127
  def in_same_section?(node1, node2)
128
- !node1.location.expression.with(
129
- end_pos: node2.location.expression.end_pos
130
- ).source.include?("\n\n")
128
+ !node1.source_range.with(end_pos: node2.source_range.end_pos).source.include?("\n\n")
131
129
  end
132
130
  end
133
131
  end
@@ -105,11 +105,11 @@ module RuboCop
105
105
  private
106
106
 
107
107
  def offense_for_implicit_enforced_style(node, error)
108
- range = node.loc.keyword.join(error.loc.expression)
108
+ range = node.loc.keyword.join(error.source_range)
109
109
 
110
110
  add_offense(range, message: MSG_IMPLICIT) do |corrector|
111
111
  error = rescue_standard_error?(node)
112
- range = range_between(node.loc.keyword.end_pos, error.loc.expression.end_pos)
112
+ range = range_between(node.loc.keyword.end_pos, error.source_range.end_pos)
113
113
 
114
114
  corrector.remove(range)
115
115
  end
@@ -297,11 +297,11 @@ module RuboCop
297
297
  end
298
298
 
299
299
  def begin_range(node, method_call)
300
- range_between(node.loc.expression.begin_pos, method_call.loc.expression.begin_pos)
300
+ range_between(node.source_range.begin_pos, method_call.source_range.begin_pos)
301
301
  end
302
302
 
303
303
  def end_range(node, method_call)
304
- range_between(method_call.loc.expression.end_pos, node.loc.expression.end_pos)
304
+ range_between(method_call.source_range.end_pos, node.source_range.end_pos)
305
305
  end
306
306
 
307
307
  def add_safe_nav_to_all_methods_in_chain(corrector,