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
@@ -71,7 +71,7 @@ module RuboCop
71
71
  end
72
72
 
73
73
  def with_object_range(send)
74
- range_between(send.loc.selector.begin_pos, send.loc.expression.end_pos)
74
+ range_between(send.loc.selector.begin_pos, send.source_range.end_pos)
75
75
  end
76
76
  end
77
77
  end
@@ -41,7 +41,8 @@ module RuboCop
41
41
 
42
42
  def on_send(node)
43
43
  return if node.receiver
44
- return unless node.parent.block_type? && node.parent.method?(:refine)
44
+ return unless (parent = node.parent)
45
+ return unless parent.block_type? && parent.method?(:refine)
45
46
 
46
47
  add_offense(node.loc.selector, message: format(MSG, current: node.method_name))
47
48
  end
@@ -50,7 +50,7 @@ module RuboCop
50
50
  return if invalid_exceptions.empty?
51
51
 
52
52
  add_offense(
53
- node.loc.keyword.join(rescued.loc.expression),
53
+ node.loc.keyword.join(rescued.source_range),
54
54
  message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
55
55
  ) do |corrector|
56
56
  autocorrect(corrector, node)
@@ -59,9 +59,9 @@ module RuboCop
59
59
 
60
60
  def autocorrect(corrector, node)
61
61
  rescued, _, _body = *node
62
- range = Parser::Source::Range.new(node.loc.expression.source_buffer,
62
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
63
63
  node.loc.keyword.end_pos,
64
- rescued.loc.expression.end_pos)
64
+ rescued.source_range.end_pos)
65
65
 
66
66
  corrector.replace(range, correction(*rescued))
67
67
  end
@@ -65,7 +65,7 @@ module RuboCop
65
65
  end
66
66
 
67
67
  def location(node, unsafe_method_call)
68
- node.loc.expression.join(unsafe_method_call.loc.expression)
68
+ node.source_range.join(unsafe_method_call.source_range)
69
69
  end
70
70
 
71
71
  def top_conditional_ancestor(node)
@@ -53,7 +53,7 @@ module RuboCop
53
53
  private
54
54
 
55
55
  def autocorrect(comment)
56
- FileUtils.chmod('+x', comment.loc.expression.source_buffer.name)
56
+ FileUtils.chmod('+x', comment.source_range.source_buffer.name)
57
57
  end
58
58
 
59
59
  def executable?(processed_source)
@@ -83,7 +83,7 @@ module RuboCop
83
83
 
84
84
  def offense_range(rescues)
85
85
  shadowing_rescue = find_shadowing_rescue(rescues)
86
- expression = shadowing_rescue.loc.expression
86
+ expression = shadowing_rescue.source_range
87
87
  range_between(expression.begin_pos, expression.end_pos)
88
88
  end
89
89
 
@@ -43,8 +43,12 @@ module RuboCop
43
43
  return unless def_node
44
44
 
45
45
  enum_conversion_call?(node) do |method_node, arguments|
46
- add_offense(node) unless method_name?(method_node, def_node.method_name) &&
47
- arguments_match?(arguments, def_node)
46
+ next if method_node.call_type? &&
47
+ !method_node.method?(:__method__) && !method_node.method?(:__callee__)
48
+ next if method_name?(method_node, def_node.method_name) &&
49
+ arguments_match?(arguments, def_node)
50
+
51
+ add_offense(node)
48
52
  end
49
53
  end
50
54
 
@@ -167,14 +167,6 @@ module RuboCop
167
167
  ({block numblock} (send _ {:class_eval :instance_eval}) ...)
168
168
  PATTERN
169
169
 
170
- # @!method class_constructor?(node)
171
- def_node_matcher :class_constructor?, <<~PATTERN
172
- ({block numblock} {
173
- (send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
174
- (send (const {nil? cbase} :Data) :define ...)
175
- } ...)
176
- PATTERN
177
-
178
170
  def check_node(node)
179
171
  return if node.nil?
180
172
 
@@ -273,7 +265,7 @@ module RuboCop
273
265
 
274
266
  def eval_call?(child)
275
267
  class_or_instance_eval?(child) ||
276
- class_constructor?(child) ||
268
+ child.class_constructor? ||
277
269
  any_context_creating_methods?(child)
278
270
  end
279
271
 
@@ -72,8 +72,9 @@ module RuboCop
72
72
  def use_exception_variable_in_ensure?(resbody_node)
73
73
  return false unless (exception_variable = resbody_node.exception_variable)
74
74
  return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
75
+ return false unless (ensure_body = ensure_node.body)
75
76
 
76
- ensure_node.body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
77
+ ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
77
78
  end
78
79
 
79
80
  def exception_objects(resbody_node)
@@ -74,7 +74,7 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def remove_node(corrector, node)
77
- corrector.remove(range_by_whole_lines(node.loc.expression, include_final_newline: true))
77
+ corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
78
78
  end
79
79
 
80
80
  def autocorrect_block_pass(corrector, node, proc_name)
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Metrics
6
+ # Checks for literals with extremely many entries. This is indicative of
7
+ # configuration or data that may be better extracted somewhere else, like
8
+ # a database, fetched from an API, or read from a non-code file (CSV,
9
+ # JSON, YAML, etc.).
10
+ #
11
+ # @example
12
+ # # bad
13
+ # # Huge Array literal
14
+ # [1, 2, '...', 999_999_999]
15
+ #
16
+ # # bad
17
+ # # Huge Hash literal
18
+ # { 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}
19
+ #
20
+ # # bad
21
+ # # Huge Set "literal"
22
+ # Set[1, 2, '...', 999_999_999]
23
+ #
24
+ # # good
25
+ # # Reasonably sized Array literal
26
+ # [1, 2, '...', 10]
27
+ #
28
+ # # good
29
+ # # Reading huge Array from external data source
30
+ # # File.readlines('numbers.txt', chomp: true).map!(&:to_i)
31
+ #
32
+ # # good
33
+ # # Reasonably sized Hash literal
34
+ # { 1 => 1, 2 => 2, '...' => '...', 10 => 10}
35
+ #
36
+ # # good
37
+ # # Reading huge Hash from external data source
38
+ # CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
39
+ # hash[row["key"].to_i] = row["value"].to_i
40
+ # end
41
+ #
42
+ # # good
43
+ # # Reasonably sized Set "literal"
44
+ # Set[1, 2, '...', 10]
45
+ #
46
+ # # good
47
+ # # Reading huge Set from external data source
48
+ # SomeFramework.config_for(:something)[:numbers].to_set
49
+ #
50
+ class CollectionLiteralLength < Base
51
+ MSG = 'Avoid hard coding large quantities of data in code. ' \
52
+ 'Prefer reading the data from an external source.'
53
+ RESTRICT_ON_SEND = [:[]].freeze
54
+
55
+ def on_array(node)
56
+ add_offense(node) if node.children.length >= collection_threshold
57
+ end
58
+ alias on_hash on_array
59
+
60
+ def on_index(node)
61
+ add_offense(node) if node.arguments.length >= collection_threshold
62
+ end
63
+
64
+ def on_send(node)
65
+ on_index(node) if node.method?(:[])
66
+ end
67
+
68
+ private
69
+
70
+ def collection_threshold
71
+ cop_config.fetch('LengthThreshold', Float::INFINITY)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -163,8 +163,8 @@ module RuboCop
163
163
  return 0 unless parenthesized?(parent)
164
164
 
165
165
  [
166
- parent.loc.begin.end_pos != descendant.loc.expression.begin_pos,
167
- parent.loc.end.begin_pos != descendant.loc.expression.end_pos
166
+ parent.loc.begin.end_pos != descendant.source_range.begin_pos,
167
+ parent.loc.end.begin_pos != descendant.source_range.end_pos
168
168
  ].count(true)
169
169
  end
170
170
 
@@ -45,7 +45,7 @@ module RuboCop
45
45
  end
46
46
 
47
47
  def check_cop_name(name, comment, offset)
48
- start = comment.location.expression.begin_pos + offset
48
+ start = comment.source_range.begin_pos + offset
49
49
  range = range_between(start, start + name.length)
50
50
 
51
51
  add_offense(range) do |corrector|
@@ -29,7 +29,7 @@ module RuboCop
29
29
 
30
30
  # Returns the range bounds for just the annotation
31
31
  def bounds
32
- start = comment.loc.expression.begin_pos + margin.length
32
+ start = comment.source_range.begin_pos + margin.length
33
33
  length = [keyword, colon, space].reduce(0) { |len, elem| len + elem.to_s.length }
34
34
  [start, start + length]
35
35
  end
@@ -36,7 +36,7 @@ module RuboCop
36
36
  length = calculator.calculate
37
37
  return if length <= max_length
38
38
 
39
- location = node.casgn_type? ? node.loc.name : node.loc.expression
39
+ location = node.casgn_type? ? node.loc.name : node.source_range
40
40
 
41
41
  add_offense(location, message: message(length, max_length)) { self.max = length }
42
42
  end
@@ -37,7 +37,7 @@ module RuboCop
37
37
  private
38
38
 
39
39
  def end_position_for(node)
40
- end_line = buffer.line_for_position(node.loc.expression.end_pos)
40
+ end_line = buffer.line_for_position(node.source_range.end_pos)
41
41
  buffer.line_range(end_line).end_pos
42
42
  end
43
43
 
@@ -68,7 +68,7 @@ module RuboCop
68
68
  node.loc.else.line
69
69
  elsif node.if_type? && node.ternary?
70
70
  node.else_branch.loc.line
71
- elsif (next_sibling = node.right_sibling)
71
+ elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
72
72
  next_sibling.loc.line
73
73
  elsif (parent = node.parent)
74
74
  parent.loc.end ? parent.loc.end.line : parent.loc.line
@@ -23,7 +23,7 @@ module RuboCop
23
23
  # The args node1 & node2 may represent a RuboCop::AST::Node
24
24
  # or a Parser::Source::Comment. Both respond to #loc.
25
25
  def preceding_comment?(node1, node2)
26
- node1 && node2 && precede?(node2, node1) && comment_line?(node2.loc.expression.source)
26
+ node1 && node2 && precede?(node2, node1) && comment_line?(node2.source)
27
27
  end
28
28
 
29
29
  # The args node1 & node2 may represent a RuboCop::AST::Node
@@ -33,7 +33,7 @@ module RuboCop
33
33
 
34
34
  def separator_delta(pair)
35
35
  if pair.hash_rocket?
36
- correct_separator_column = pair.key.loc.expression.end.column + 1
36
+ correct_separator_column = pair.key.source_range.end.column + 1
37
37
  actual_separator_column = pair.loc.operator.column
38
38
 
39
39
  correct_separator_column - actual_separator_column
@@ -95,19 +95,19 @@ module RuboCop
95
95
  use_modifier_form_without_parenthesized_method_call?(method_dispatch_node)
96
96
  end
97
97
 
98
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
98
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
99
99
  def def_node_that_require_parentheses(node)
100
100
  last_pair = node.parent.pairs.last
101
101
  return unless last_pair.key.source == last_pair.value.source
102
102
  return unless (dispatch_node = find_ancestor_method_dispatch_node(node))
103
- return if node.respond_to?(:parenthesized?) && !node.parenthesized?
104
- return unless last_expression?(dispatch_node) || method_dispatch_as_argument?(dispatch_node)
103
+ return if dispatch_node.parenthesized?
104
+ return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
105
105
 
106
106
  def_node = node.each_ancestor(:send, :csend, :super, :yield).first
107
107
 
108
108
  DefNode.new(def_node) unless def_node && def_node.arguments.empty?
109
109
  end
110
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
110
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
111
111
 
112
112
  def find_ancestor_method_dispatch_node(node)
113
113
  return unless (ancestor = node.parent.parent)
@@ -132,9 +132,12 @@ module RuboCop
132
132
  ancestor.ancestors.any? { |node| node.respond_to?(:modifier_form?) && node.modifier_form? }
133
133
  end
134
134
 
135
- def last_expression?(ancestor)
136
- ancestor.right_sibling ||
137
- ancestor.each_ancestor.find { |node| node.assignment? || node.send_type? }&.right_sibling
135
+ def last_expression?(node)
136
+ return false if node.right_sibling
137
+ return true unless (assignment_node = node.each_ancestor.find(&:assignment?))
138
+ return last_expression?(assignment_node.parent) if assignment_node.parent&.assignment?
139
+
140
+ !assignment_node.right_sibling
138
141
  end
139
142
 
140
143
  def method_dispatch_as_argument?(method_dispatch_node)
@@ -159,7 +159,7 @@ module RuboCop
159
159
  end
160
160
 
161
161
  def strip_prefix_and_suffix(node, corrector)
162
- expression = node.loc.expression
162
+ expression = node.source_range
163
163
  corrector.remove_leading(expression, leading)
164
164
  corrector.remove_trailing(expression, trailing)
165
165
  end
@@ -175,11 +175,11 @@ module RuboCop
175
175
  end
176
176
 
177
177
  def set_new_arg_name(transformed_argname, corrector)
178
- corrector.replace(block_node.arguments.loc.expression, "|#{transformed_argname}|")
178
+ corrector.replace(block_node.arguments.source_range, "|#{transformed_argname}|")
179
179
  end
180
180
 
181
181
  def set_new_body_expression(transforming_body_expr, corrector)
182
- body_source = transforming_body_expr.loc.expression.source
182
+ body_source = transforming_body_expr.source
183
183
  if transforming_body_expr.hash_type? && !transforming_body_expr.braces?
184
184
  body_source = "{ #{body_source} }"
185
185
  end
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # TEAM: backend_infra
4
- # WATCHERS: maxh
5
-
6
3
  module RuboCop
7
4
  module Cop
8
5
  # Common functionality for checking for a line break before each
@@ -10,7 +10,7 @@ module RuboCop
10
10
  def get_source_range(node, comments_as_separators)
11
11
  unless comments_as_separators
12
12
  first_comment = processed_source.ast_with_comments[node].first
13
- return first_comment.loc.expression unless first_comment.nil?
13
+ return first_comment.source_range unless first_comment.nil?
14
14
  end
15
15
  node.source_range
16
16
  end
@@ -132,12 +132,7 @@ module RuboCop
132
132
  end
133
133
 
134
134
  def range_with_comments(node)
135
- ranges = [
136
- node,
137
- *@processed_source.ast_with_comments[node]
138
- ].map do |element|
139
- element.location.expression
140
- end
135
+ ranges = [node, *@processed_source.ast_with_comments[node]].map(&:source_range)
141
136
  ranges.reduce do |result, range|
142
137
  add_range(result, range)
143
138
  end
@@ -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)
@@ -7,8 +7,8 @@ module RuboCop
7
7
  # By default it enforces accessors to be placed in grouped declarations,
8
8
  # but it can be configured to enforce separating them in multiple declarations.
9
9
  #
10
- # NOTE: `Sorbet` is not compatible with "grouped" style. Consider "separated" style
11
- # or disabling this cop.
10
+ # NOTE: If there is a method call before the accessor method it is always allowed
11
+ # as it might be intended like Sorbet.
12
12
  #
13
13
  # @example EnforcedStyle: grouped (default)
14
14
  # # bad
@@ -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
@@ -43,11 +52,9 @@ module RuboCop
43
52
  GROUPED_MSG = 'Group together all `%<accessor>s` attributes.'
44
53
  SEPARATED_MSG = 'Use one attribute per `%<accessor>s`.'
45
54
 
46
- ACCESSOR_METHODS = %i[attr_reader attr_writer attr_accessor attr].freeze
47
-
48
55
  def on_class(node)
49
56
  class_send_elements(node).each do |macro|
50
- next unless accessor?(macro)
57
+ next unless macro.attribute_accessor?
51
58
 
52
59
  check(macro)
53
60
  end
@@ -58,7 +65,7 @@ module RuboCop
58
65
  private
59
66
 
60
67
  def check(send_node)
61
- return if previous_line_comment?(send_node)
68
+ return if previous_line_comment?(send_node) || !groupable_accessor?(send_node)
62
69
  return unless (grouped_style? && sibling_accessors(send_node).size > 1) ||
63
70
  (separated_style? && send_node.arguments.size > 1)
64
71
 
@@ -72,7 +79,7 @@ module RuboCop
72
79
  if (preferred_accessors = preferred_accessors(node))
73
80
  corrector.replace(node, preferred_accessors)
74
81
  else
75
- range = range_with_surrounding_space(node.loc.expression, side: :left)
82
+ range = range_with_surrounding_space(node.source_range, side: :left)
76
83
  corrector.remove(range)
77
84
  end
78
85
  end
@@ -81,6 +88,13 @@ module RuboCop
81
88
  comment_line?(processed_source[node.first_line - 2])
82
89
  end
83
90
 
91
+ def groupable_accessor?(node)
92
+ return true unless (previous_expression = node.left_siblings.last)
93
+ return true unless previous_expression.send_type?
94
+
95
+ previous_expression.attribute_accessor? || previous_expression.access_modifier?
96
+ end
97
+
84
98
  def class_send_elements(class_node)
85
99
  class_def = class_node.body
86
100
 
@@ -93,10 +107,6 @@ module RuboCop
93
107
  end
94
108
  end
95
109
 
96
- def accessor?(send_node)
97
- send_node.macro? && ACCESSOR_METHODS.include?(send_node.method_name)
98
- end
99
-
100
110
  def grouped_style?
101
111
  style == :grouped
102
112
  end
@@ -107,7 +117,7 @@ module RuboCop
107
117
 
108
118
  def sibling_accessors(send_node)
109
119
  send_node.parent.each_child_node(:send).select do |sibling|
110
- accessor?(sibling) &&
120
+ sibling.attribute_accessor? &&
111
121
  sibling.method?(send_node.method_name) &&
112
122
  node_visibility(sibling) == node_visibility(send_node) &&
113
123
  !previous_line_comment?(sibling)
@@ -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
@@ -12,7 +12,7 @@ module RuboCop
12
12
  # `(array1 & array2).any?` and is more readable.
13
13
  #
14
14
  # @safety
15
- # This cop cannot guarantee that array1 and array2 are
15
+ # This cop cannot guarantee that `array1` and `array2` are
16
16
  # actually arrays while method `intersect?` is for arrays only.
17
17
  #
18
18
  # @example
@@ -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