rubocop 1.46.0 → 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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +7 -0
  4. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  5. data/lib/rubocop/comment_config.rb +2 -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 +1 -1
  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 +2 -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/first_argument_indentation.rb +1 -1
  33. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  34. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  35. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
  36. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  37. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  38. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  39. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  40. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  41. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  43. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  44. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  45. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
  46. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  47. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  48. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  49. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  50. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  51. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
  52. data/lib/rubocop/cop/lint/missing_super.rb +31 -2
  53. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  54. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  55. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
  56. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  57. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
  58. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  59. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  60. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  61. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  62. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  63. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  64. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  65. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  66. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  67. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  68. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  69. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  70. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  71. data/lib/rubocop/cop/mixin/comments_help.rb +2 -2
  72. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  73. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  74. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  75. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  76. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  77. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  78. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  79. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  80. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  81. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  82. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
  83. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -1
  84. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
  85. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  86. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  87. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  88. data/lib/rubocop/cop/style/block_delimiters.rb +2 -2
  89. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  90. data/lib/rubocop/cop/style/collection_compact.rb +1 -1
  91. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  92. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  93. data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
  94. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -6
  95. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  96. data/lib/rubocop/cop/style/documentation.rb +1 -1
  97. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  98. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  99. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  100. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  101. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  102. data/lib/rubocop/cop/style/file_read.rb +1 -1
  103. data/lib/rubocop/cop/style/file_write.rb +1 -1
  104. data/lib/rubocop/cop/style/guard_clause.rb +1 -1
  105. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  106. data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
  107. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  108. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  109. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
  110. data/lib/rubocop/cop/style/min_max.rb +3 -3
  111. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  112. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  113. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  114. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  115. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  116. data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
  117. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
  118. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  119. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +10 -3
  120. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  121. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  122. data/lib/rubocop/cop/style/require_order.rb +1 -3
  123. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  124. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  125. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
  126. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  127. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  128. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  129. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  130. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  131. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  132. data/lib/rubocop/cop/util.rb +1 -1
  133. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  134. data/lib/rubocop/directive_comment.rb +3 -3
  135. data/lib/rubocop/ext/comment.rb +18 -0
  136. data/lib/rubocop/version.rb +1 -1
  137. data/lib/rubocop.rb +2 -0
  138. metadata +7 -3
@@ -65,14 +65,14 @@ module RuboCop
65
65
  end
66
66
 
67
67
  def method_source(if_body)
68
- range_between(if_body.loc.expression.begin_pos, if_body.loc.selector.end_pos).source
68
+ range_between(if_body.source_range.begin_pos, if_body.loc.selector.end_pos).source
69
69
  end
70
70
 
71
71
  def first_line_comment(node)
72
72
  comment = processed_source.find_comment { |c| same_line?(c, node) }
73
73
  return unless comment
74
74
 
75
- comment_source = comment.loc.expression.source
75
+ comment_source = comment.source
76
76
  comment_source unless comment_disables_cop?(comment_source)
77
77
  end
78
78
 
@@ -75,7 +75,7 @@ module RuboCop
75
75
 
76
76
  def inside_comment?(range, comma_offset)
77
77
  comment = processed_source.comment_at_line(range.line)
78
- comment && comment.loc.expression.begin_pos < range.begin_pos + comma_offset
78
+ comment && comment.source_range.begin_pos < range.begin_pos + comma_offset
79
79
  end
80
80
 
81
81
  # Returns true if the node has round/square/curly brackets.
@@ -38,7 +38,7 @@ module RuboCop
38
38
  return if correct_case_delimiters?(node)
39
39
 
40
40
  add_offense(node.loc.heredoc_end) do |corrector|
41
- expr = node.loc.expression
41
+ expr = node.source_range
42
42
 
43
43
  corrector.replace(expr, correct_delimiters(expr.source))
44
44
  corrector.replace(node.loc.heredoc_end, correct_delimiters(delimiter_string(expr)))
@@ -67,7 +67,7 @@ module RuboCop
67
67
 
68
68
  def range_position(node)
69
69
  selector_end_pos = node.loc.selector.end_pos + 1
70
- expr_end_pos = node.loc.expression.end_pos
70
+ expr_end_pos = node.source_range.end_pos
71
71
 
72
72
  range_between(selector_end_pos, expr_end_pos)
73
73
  end
@@ -72,7 +72,7 @@ module RuboCop
72
72
  next if allowed_method_name?(method_name.to_s, prefix)
73
73
 
74
74
  add_offense(
75
- node.first_argument.loc.expression,
75
+ node.first_argument.source_range,
76
76
  message: message(method_name, expected_name(method_name.to_s, prefix))
77
77
  )
78
78
  end
@@ -92,7 +92,7 @@ module RuboCop
92
92
 
93
93
  def offense_range(resbody)
94
94
  variable = resbody.exception_variable
95
- variable.loc.expression
95
+ variable.source_range
96
96
  end
97
97
 
98
98
  def variable_name_matches?(node, name)
@@ -22,6 +22,15 @@ module RuboCop
22
22
  # attr_reader :bar, :baz
23
23
  # end
24
24
  #
25
+ # # good
26
+ # class Foo
27
+ # # may be intended comment for bar.
28
+ # attr_reader :bar
29
+ #
30
+ # may_be_intended_annotation :baz
31
+ # attr_reader :baz
32
+ # end
33
+ #
25
34
  # @example EnforcedStyle: separated
26
35
  # # bad
27
36
  # class Foo
@@ -70,7 +79,7 @@ module RuboCop
70
79
  if (preferred_accessors = preferred_accessors(node))
71
80
  corrector.replace(node, preferred_accessors)
72
81
  else
73
- range = range_with_surrounding_space(node.loc.expression, side: :left)
82
+ range = range_with_surrounding_space(node.source_range, side: :left)
74
83
  corrector.remove(range)
75
84
  end
76
85
  end
@@ -124,9 +124,9 @@ module RuboCop
124
124
 
125
125
  def register_offense_to_forwarding_method_arguments(forwarding_method)
126
126
  add_offense(arguments_range(forwarding_method)) do |corrector|
127
- range = range_between(
128
- forwarding_method.loc.selector.end_pos, forwarding_method.source_range.end_pos
129
- )
127
+ begin_pos = forwarding_method.loc.selector&.end_pos || forwarding_method.loc.dot.end_pos
128
+ range = range_between(begin_pos, forwarding_method.source_range.end_pos)
129
+
130
130
  corrector.replace(range, '(...)')
131
131
  end
132
132
  end
@@ -30,7 +30,7 @@ module RuboCop
30
30
  private
31
31
 
32
32
  def first_offense_range(comment)
33
- expression = comment.loc.expression
33
+ expression = comment.source_range
34
34
  first_offense = first_non_ascii_chars(comment.text)
35
35
 
36
36
  start_position = expression.begin_pos + comment.text.index(first_offense)
@@ -55,7 +55,7 @@ module RuboCop
55
55
  def after_class(class_node)
56
56
  @macros_to_rewrite[class_node].each do |macro|
57
57
  node = macro.node
58
- range = range_by_whole_lines(node.loc.expression, include_final_newline: true)
58
+ range = range_by_whole_lines(node.source_range, include_final_newline: true)
59
59
 
60
60
  correct(range) do |corrector|
61
61
  if macro.writer?
@@ -46,7 +46,7 @@ module RuboCop
46
46
  private
47
47
 
48
48
  def parts(comment)
49
- expr = comment.loc.expression
49
+ expr = comment.source_range
50
50
  eq_begin = expr.resize(BEGIN_LENGTH)
51
51
  eq_end = eq_end_part(comment, expr)
52
52
  contents = range_between(eq_begin.end_pos, eq_end.begin_pos)
@@ -299,7 +299,7 @@ module RuboCop
299
299
 
300
300
  def move_comment_before_block(corrector, comment, block_node, closing_brace)
301
301
  range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
302
- corrector.remove(range_with_surrounding_space(comment.loc.expression, side: :right))
302
+ corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
303
303
  remove_trailing_whitespace(corrector, range, comment)
304
304
  corrector.insert_after(range, "\n")
305
305
 
@@ -314,7 +314,7 @@ module RuboCop
314
314
  end
315
315
 
316
316
  def remove_trailing_whitespace(corrector, range, comment)
317
- range_of_trailing = range.end.join(comment.loc.expression.begin)
317
+ range_of_trailing = range.end.join(comment.source_range.begin)
318
318
 
319
319
  corrector.remove(range_of_trailing) if range_of_trailing.source.match?(/\A\s+\z/)
320
320
  end
@@ -239,7 +239,7 @@ module RuboCop
239
239
  end
240
240
 
241
241
  def correction_range(node)
242
- range_between(node.parent.loc.keyword.begin_pos, node.loc.expression.end_pos)
242
+ range_between(node.parent.loc.keyword.begin_pos, node.source_range.end_pos)
243
243
  end
244
244
 
245
245
  # Named captures work with `=~` (if regexp is on lhs) and with `match` (both sides)
@@ -112,7 +112,7 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def range(begin_pos_node, end_pos_node)
115
- range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.loc.expression.end_pos)
115
+ range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.source_range.end_pos)
116
116
  end
117
117
  end
118
118
  end
@@ -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
@@ -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