rubocop 1.46.0 → 1.52.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/config/default.yml +83 -11
  4. data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
  5. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  6. data/lib/rubocop/cli.rb +6 -6
  7. data/lib/rubocop/comment_config.rb +2 -0
  8. data/lib/rubocop/config.rb +7 -3
  9. data/lib/rubocop/config_loader.rb +8 -8
  10. data/lib/rubocop/config_obsoletion.rb +2 -2
  11. data/lib/rubocop/cop/autocorrect_logic.rb +29 -13
  12. data/lib/rubocop/cop/base.rb +6 -2
  13. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  14. data/lib/rubocop/cop/cop.rb +2 -2
  15. data/lib/rubocop/cop/corrector.rb +1 -1
  16. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  17. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
  18. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
  19. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  20. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  21. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  23. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  24. data/lib/rubocop/cop/gemspec/dependency_version.rb +1 -1
  25. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
  26. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  27. data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
  28. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  29. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  30. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  31. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
  32. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  33. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +1 -1
  34. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  36. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  37. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  38. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -21
  39. data/lib/rubocop/cop/layout/class_structure.rb +6 -3
  40. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  41. data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
  42. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  43. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  44. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  45. data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
  46. data/lib/rubocop/cop/layout/extra_spacing.rb +6 -1
  47. data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -2
  48. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  49. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  50. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  51. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  52. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
  53. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  54. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  55. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  56. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
  57. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  58. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  59. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  60. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  61. data/lib/rubocop/cop/layout/redundant_line_break.rb +6 -7
  62. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
  63. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  64. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  65. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
  66. data/lib/rubocop/cop/layout/space_inside_parens.rb +2 -2
  67. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  68. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  69. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  70. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  71. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  72. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  73. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  74. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  75. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
  76. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  77. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  78. data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
  79. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  80. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
  81. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  82. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  83. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  84. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  85. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  86. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
  87. data/lib/rubocop/cop/lint/missing_super.rb +34 -2
  88. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  89. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  90. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  91. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  92. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  93. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  94. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  95. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +4 -4
  96. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  97. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
  98. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  99. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  100. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  101. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  102. data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
  103. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  104. data/lib/rubocop/cop/lint/script_permission.rb +1 -1
  105. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  106. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
  107. data/lib/rubocop/cop/lint/syntax.rb +4 -0
  108. data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -1
  109. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  110. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
  111. data/lib/rubocop/cop/lint/useless_access_modifier.rb +9 -1
  112. data/lib/rubocop/cop/lint/useless_assignment.rb +59 -1
  113. data/lib/rubocop/cop/lint/useless_method_definition.rb +10 -2
  114. data/lib/rubocop/cop/lint/useless_rescue.rb +4 -1
  115. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  116. data/lib/rubocop/cop/lint/void.rb +69 -9
  117. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  118. data/lib/rubocop/cop/metrics/class_length.rb +1 -0
  119. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  120. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  121. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -3
  122. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  123. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  124. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  125. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  126. data/lib/rubocop/cop/mixin/comments_help.rb +9 -5
  127. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  128. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  129. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -2
  130. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  131. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  132. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  133. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  134. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  135. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
  136. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  137. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  138. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  139. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  140. data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
  141. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +22 -7
  142. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  143. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  144. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  145. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  146. data/lib/rubocop/cop/registry.rb +3 -1
  147. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -7
  148. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
  149. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  150. data/lib/rubocop/cop/style/attr.rb +11 -1
  151. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  152. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
  153. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  154. data/lib/rubocop/cop/style/block_delimiters.rb +11 -2
  155. data/lib/rubocop/cop/style/case_like_if.rb +20 -3
  156. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
  157. data/lib/rubocop/cop/style/class_equality_comparison.rb +51 -40
  158. data/lib/rubocop/cop/style/collection_compact.rb +20 -7
  159. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  160. data/lib/rubocop/cop/style/combinable_loops.rb +26 -6
  161. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  162. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  163. data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
  164. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -8
  165. data/lib/rubocop/cop/style/copyright.rb +6 -3
  166. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  167. data/lib/rubocop/cop/style/dir.rb +1 -1
  168. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  169. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  170. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
  171. data/lib/rubocop/cop/style/documentation.rb +11 -5
  172. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  173. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  174. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  175. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  176. data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
  177. data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
  178. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  179. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  180. data/lib/rubocop/cop/style/file_read.rb +3 -3
  181. data/lib/rubocop/cop/style/file_write.rb +1 -1
  182. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  183. data/lib/rubocop/cop/style/guard_clause.rb +3 -1
  184. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
  185. data/lib/rubocop/cop/style/hash_except.rb +23 -12
  186. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  187. data/lib/rubocop/cop/style/hash_syntax.rb +5 -2
  188. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  189. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  190. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  191. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  192. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  193. data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
  194. data/lib/rubocop/cop/style/invertible_unless_condition.rb +9 -5
  195. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
  196. data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
  197. data/lib/rubocop/cop/style/map_to_set.rb +4 -1
  198. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -9
  199. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
  200. data/lib/rubocop/cop/style/min_max.rb +3 -3
  201. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
  202. data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
  203. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  204. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  205. data/lib/rubocop/cop/style/negated_if_else_condition.rb +12 -7
  206. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  207. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  208. data/lib/rubocop/cop/style/parallel_assignment.rb +26 -18
  209. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  210. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  211. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  212. data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
  213. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
  214. data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
  215. data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
  216. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  217. data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
  218. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  219. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  220. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +2 -2
  221. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  222. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +11 -4
  223. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  224. data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -4
  225. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  226. data/lib/rubocop/cop/style/require_order.rb +12 -8
  227. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  228. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  229. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  230. data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
  231. data/lib/rubocop/cop/style/semicolon.rb +12 -1
  232. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  233. data/lib/rubocop/cop/style/sole_nested_conditional.rb +6 -4
  234. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  235. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  236. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  237. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  238. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  239. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  240. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  241. data/lib/rubocop/cop/style/unpack_first.rb +3 -3
  242. data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
  243. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  244. data/lib/rubocop/cop/team.rb +2 -2
  245. data/lib/rubocop/cop/util.rb +1 -1
  246. data/lib/rubocop/cop/variable_force/assignment.rb +33 -1
  247. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  248. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  249. data/lib/rubocop/cop/variable_force.rb +1 -0
  250. data/lib/rubocop/cops_documentation_generator.rb +10 -3
  251. data/lib/rubocop/directive_comment.rb +3 -3
  252. data/lib/rubocop/ext/comment.rb +18 -0
  253. data/lib/rubocop/ext/regexp_node.rb +1 -1
  254. data/lib/rubocop/ext/regexp_parser.rb +1 -1
  255. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  256. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  257. data/lib/rubocop/options.rb +4 -1
  258. data/lib/rubocop/result_cache.rb +2 -2
  259. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  260. data/lib/rubocop/rspec/support.rb +1 -0
  261. data/lib/rubocop/server/cache.rb +1 -1
  262. data/lib/rubocop/server/client_command/exec.rb +2 -1
  263. data/lib/rubocop/server/core.rb +1 -1
  264. data/lib/rubocop/server/helper.rb +1 -1
  265. data/lib/rubocop/server/server_command/exec.rb +1 -1
  266. data/lib/rubocop/target_ruby.rb +3 -2
  267. data/lib/rubocop/version.rb +10 -6
  268. data/lib/rubocop.rb +13 -0
  269. metadata +23 -8
@@ -11,6 +11,9 @@ module RuboCop
11
11
  # missing method. In other cases, the theoretical ideal handling could be
12
12
  # challenging or verbose for no actual gain.
13
13
  #
14
+ # Autocorrection is not supported because the position of `super` cannot be
15
+ # determined automatically.
16
+ #
14
17
  # @example
15
18
  # # bad
16
19
  # class Employee < Person
@@ -28,6 +31,21 @@ module RuboCop
28
31
  # end
29
32
  #
30
33
  # # bad
34
+ # Employee = Class.new(Person) do
35
+ # def initialize(name, salary)
36
+ # @salary = salary
37
+ # end
38
+ # end
39
+ #
40
+ # # good
41
+ # Employee = Class.new(Person) do
42
+ # def initialize(name, salary)
43
+ # super(name)
44
+ # @salary = salary
45
+ # end
46
+ # end
47
+ #
48
+ # # bad
31
49
  # class Parent
32
50
  # def self.inherited(base)
33
51
  # do_something
@@ -55,6 +73,13 @@ module RuboCop
55
73
 
56
74
  CALLBACKS = (CLASS_LIFECYCLE_CALLBACKS + METHOD_LIFECYCLE_CALLBACKS).to_set.freeze
57
75
 
76
+ # @!method class_new_block(node)
77
+ def_node_matcher :class_new_block, <<~RUBY
78
+ ({block numblock}
79
+ (send
80
+ (const {nil? cbase} :Class) :new $_) ...)
81
+ RUBY
82
+
58
83
  def on_def(node)
59
84
  return unless offender?(node)
60
85
 
@@ -88,8 +113,15 @@ module RuboCop
88
113
  end
89
114
 
90
115
  def inside_class_with_stateful_parent?(node)
91
- class_node = node.each_ancestor(:class).first
92
- class_node&.parent_class && !stateless_class?(class_node.parent_class)
116
+ if (block_node = node.each_ancestor(:block, :numblock).first)
117
+ return false unless (super_class = class_new_block(block_node))
118
+
119
+ !stateless_class?(super_class)
120
+ elsif (class_node = node.each_ancestor(:class).first)
121
+ class_node.parent_class && !stateless_class?(class_node.parent_class)
122
+ else
123
+ false
124
+ end
93
125
  end
94
126
 
95
127
  def stateless_class?(node)
@@ -131,12 +131,12 @@ module RuboCop
131
131
 
132
132
  # @!method eval_call?(node)
133
133
  def_node_matcher :eval_call?, <<~PATTERN
134
- (block (send _ {:instance_eval :class_eval :module_eval} ...) ...)
134
+ ({block numblock} (send _ {:instance_eval :class_eval :module_eval} ...) ...)
135
135
  PATTERN
136
136
 
137
137
  # @!method exec_call?(node)
138
138
  def_node_matcher :exec_call?, <<~PATTERN
139
- (block (send _ {:instance_exec :class_exec :module_exec} ...) ...)
139
+ ({block numblock} (send _ {:instance_exec :class_exec :module_exec} ...) ...)
140
140
  PATTERN
141
141
  end
142
142
  end
@@ -6,13 +6,13 @@ module RuboCop
6
6
  # Checks for uses of numbered parameter assignment.
7
7
  # It emulates the following warning in Ruby 2.7:
8
8
  #
9
- # % ruby -ve '_1 = :value'
9
+ # $ ruby -ve '_1 = :value'
10
10
  # ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
11
11
  # -e:1: warning: `_1' is reserved for numbered parameter; consider another name
12
12
  #
13
13
  # Assigning to a numbered parameter (from `_1` to `_9`) causes an error in Ruby 3.0.
14
14
  #
15
- # % ruby -ve '_1 = :value'
15
+ # $ ruby -ve '_1 = :value'
16
16
  # ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
17
17
  # -e:1: _1 is reserved for numbered parameter
18
18
  #
@@ -31,6 +31,8 @@ module RuboCop
31
31
  return unless lhs&.casgn_type?
32
32
 
33
33
  add_offense(node.loc.operator) do |corrector|
34
+ next if node.each_ancestor(:def, :defs).any?
35
+
34
36
  corrector.replace(node.loc.operator, '=')
35
37
  end
36
38
  end
@@ -3,7 +3,6 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- #
7
6
  # Checks the proper ordering of magic comments and whether
8
7
  # a magic comment is not placed before a shebang.
9
8
  #
@@ -65,13 +65,13 @@ module RuboCop
65
65
  def on_when(node)
66
66
  regexp_conditions = node.conditions.select(&:regexp_type?)
67
67
 
68
- @valid_ref = regexp_conditions.map { |condition| check_regexp(condition) }.compact.max
68
+ @valid_ref = regexp_conditions.filter_map { |condition| check_regexp(condition) }.max
69
69
  end
70
70
 
71
71
  def on_in_pattern(node)
72
72
  regexp_patterns = regexp_patterns(node)
73
73
 
74
- @valid_ref = regexp_patterns.map { |pattern| check_regexp(pattern) }.compact.max
74
+ @valid_ref = regexp_patterns.filter_map { |pattern| check_regexp(pattern) }.max
75
75
  end
76
76
 
77
77
  def on_nth_ref(node)
@@ -50,7 +50,7 @@ module RuboCop
50
50
 
51
51
  add_offense(node) do |corrector|
52
52
  node.each_value do |value|
53
- range = value.loc.expression
53
+ range = value.source_range
54
54
 
55
55
  match = range.source.match(TRAILING_QUOTE)
56
56
  corrector.remove_trailing(range, match[0].length) if match
@@ -41,7 +41,7 @@ module RuboCop
41
41
 
42
42
  def autocorrect(corrector, node)
43
43
  node.children.each do |child|
44
- range = child.loc.expression
44
+ range = child.source_range
45
45
 
46
46
  corrector.remove_trailing(range, 1) if range.source.end_with?(',')
47
47
  corrector.remove_leading(range, 1) if
@@ -231,7 +231,7 @@ module RuboCop
231
231
  cop_names = cops.sort.map { |c| describe(c) }.join(', ')
232
232
 
233
233
  add_offense(location, message: message(cop_names)) do |corrector|
234
- range = comment_range_with_surrounding_space(location, comment.loc.expression)
234
+ range = comment_range_with_surrounding_space(location, comment.source_range)
235
235
 
236
236
  if leave_free_comment?(comment, range)
237
237
  corrector.replace(range, ' # ')
@@ -263,8 +263,8 @@ module RuboCop
263
263
 
264
264
  def cop_range(comment, cop)
265
265
  cop = remove_department_marker(cop)
266
- matching_range(comment.loc.expression, cop) ||
267
- matching_range(comment.loc.expression, Badge.parse(cop).cop_name) ||
266
+ matching_range(comment.source_range, cop) ||
267
+ matching_range(comment.source_range, Badge.parse(cop).cop_name) ||
268
268
  raise("Couldn't find #{cop} in comment: #{comment.text}")
269
269
  end
270
270
 
@@ -281,7 +281,7 @@ module RuboCop
281
281
  .drop_while { |r| !r.equal?(range) }
282
282
  .each_cons(2)
283
283
  .map { |range1, range2| range1.end.join(range2.begin).source }
284
- .all? { |intervening| /\A\s*,\s*\Z/.match?(intervening) }
284
+ .all?(/\A\s*,\s*\z/)
285
285
  end
286
286
 
287
287
  SIMILAR_COP_NAMES_CACHE = Hash.new do |hash, cop_name|
@@ -74,7 +74,7 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def comment_start(comment)
77
- comment.loc.expression.begin_pos
77
+ comment.source_range.begin_pos
78
78
  end
79
79
 
80
80
  def cop_name_indention(comment, name)
@@ -82,7 +82,7 @@ module RuboCop
82
82
  end
83
83
 
84
84
  def range_with_comma(comment, name)
85
- source = comment.loc.expression.source
85
+ source = comment.source
86
86
 
87
87
  begin_pos = cop_name_indention(comment, name)
88
88
  end_pos = begin_pos + name.size
@@ -94,14 +94,14 @@ module RuboCop
94
94
 
95
95
  def range_to_remove(begin_pos, end_pos, comment)
96
96
  start = comment_start(comment)
97
- source = comment.loc.expression.source
97
+ source = comment.source
98
98
 
99
99
  if source[begin_pos - 1] == ','
100
100
  range_with_comma_before(start, begin_pos, end_pos)
101
101
  elsif source[end_pos] == ','
102
102
  range_with_comma_after(comment, start, begin_pos, end_pos)
103
103
  else
104
- range_between(start, comment.loc.expression.end_pos)
104
+ range_between(start, comment.source_range.end_pos)
105
105
  end
106
106
  end
107
107
 
@@ -112,7 +112,7 @@ module RuboCop
112
112
  # If the list of cops is comma-separated, but without a empty space after the comma,
113
113
  # we should **not** remove the prepending empty space, thus begin_pos += 1
114
114
  def range_with_comma_after(comment, start, begin_pos, end_pos)
115
- begin_pos += 1 if comment.loc.expression.source[end_pos + 1] != ' '
115
+ begin_pos += 1 if comment.source[end_pos + 1] != ' '
116
116
 
117
117
  range_between(start + begin_pos, start + end_pos + 1)
118
118
  end
@@ -56,7 +56,7 @@ module RuboCop
56
56
  if node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
57
57
  corrector.insert_after(node.parent, "\nend")
58
58
 
59
- range = range_with_surrounding_space(node.loc.expression, side: :right)
59
+ range = range_with_surrounding_space(node.source_range, side: :right)
60
60
  else
61
61
  range = range_by_whole_lines(node.source_range, include_final_newline: true)
62
62
  end
@@ -141,7 +141,7 @@ module RuboCop
141
141
  expression = loc.expression
142
142
 
143
143
  if array_new?(variable)
144
- expression = node.parent.loc.expression if node.parent.array_type?
144
+ expression = node.parent.source_range if node.parent.array_type?
145
145
  [expression, variable.source]
146
146
  elsif !variable.array_type?
147
147
  [expression, "[#{variable.source}]"]
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for string conversion in string interpolation,
6
+ # Checks for string conversion in string interpolation, `print`, `puts`, and `warn` arguments,
7
7
  # which is redundant.
8
8
  #
9
9
  # @example
@@ -11,18 +11,26 @@ module RuboCop
11
11
  # # bad
12
12
  #
13
13
  # "result is #{something.to_s}"
14
+ # print something.to_s
15
+ # puts something.to_s
16
+ # warn something.to_s
14
17
  #
15
18
  # @example
16
19
  #
17
20
  # # good
18
21
  #
19
22
  # "result is #{something}"
23
+ # print something
24
+ # puts something
25
+ # warn something
26
+ #
20
27
  class RedundantStringCoercion < Base
21
28
  include Interpolation
22
29
  extend AutoCorrector
23
30
 
24
- MSG_DEFAULT = 'Redundant use of `Object#to_s` in interpolation.'
25
- MSG_SELF = 'Use `self` instead of `Object#to_s` in interpolation.'
31
+ MSG_DEFAULT = 'Redundant use of `Object#to_s` in %<context>s.'
32
+ MSG_SELF = 'Use `self` instead of `Object#to_s` in %<context>s.'
33
+ RESTRICT_ON_SEND = %i[print puts warn].freeze
26
34
 
27
35
  # @!method to_s_without_args?(node)
28
36
  def_node_matcher :to_s_without_args?, '(send _ :to_s)'
@@ -32,18 +40,30 @@ module RuboCop
32
40
 
33
41
  return unless to_s_without_args?(final_node)
34
42
 
35
- message = final_node.receiver ? MSG_DEFAULT : MSG_SELF
36
-
37
- add_offense(final_node.loc.selector, message: message) do |corrector|
38
- receiver = final_node.receiver
39
- corrector.replace(
40
- final_node,
41
- if receiver
42
- receiver.source
43
- else
44
- 'self'
45
- end
46
- )
43
+ register_offense(final_node, 'interpolation')
44
+ end
45
+
46
+ def on_send(node)
47
+ return if node.receiver
48
+
49
+ node.each_child_node(:send) do |child|
50
+ next if !child.method?(:to_s) || child.arguments.any?
51
+
52
+ register_offense(child, "`#{node.method_name}`")
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def register_offense(node, context)
59
+ receiver = node.receiver
60
+ template = receiver ? MSG_DEFAULT : MSG_SELF
61
+ message = format(template, context: context)
62
+
63
+ add_offense(node.loc.selector, message: message) do |corrector|
64
+ replacement = receiver ? receiver.source : 'self'
65
+
66
+ corrector.replace(node, replacement)
47
67
  end
48
68
  end
49
69
  end
@@ -72,7 +72,7 @@ module RuboCop
72
72
  end
73
73
 
74
74
  def with_index_range(send)
75
- range_between(send.loc.selector.begin_pos, send.loc.expression.end_pos)
75
+ range_between(send.loc.selector.begin_pos, send.source_range.end_pos)
76
76
  end
77
77
  end
78
78
  end
@@ -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
@@ -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)
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- #
7
- # This cop checks for `send`, `public_send`, and `__send__` methods
6
+ # Checks for `send`, `public_send`, and `__send__` methods
8
7
  # when using mix-in.
9
8
  #
10
9
  # `include` and `prepend` methods were private methods until Ruby 2.0,
@@ -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
 
@@ -121,18 +121,12 @@ module RuboCop
121
121
 
122
122
  if rescued_exceptions.any?
123
123
  rescued_exceptions.each_with_object([]) do |exception, converted|
124
- # FIXME: Workaround `rubocop:disable` comment for JRuby.
125
- # https://github.com/jruby/jruby/issues/6642
126
- # rubocop:disable Style/RedundantBegin
127
- begin
128
- RuboCop::Util.silence_warnings do
129
- # Avoid printing deprecation warnings about constants
130
- converted << Kernel.const_get(exception.source)
131
- end
132
- rescue NameError
133
- converted << nil
124
+ RuboCop::Util.silence_warnings do
125
+ # Avoid printing deprecation warnings about constants
126
+ converted << Kernel.const_get(exception.source)
134
127
  end
135
- # rubocop:enable Style/RedundantBegin
128
+ rescue NameError
129
+ converted << nil
136
130
  end
137
131
  else
138
132
  # treat an empty `rescue` as `rescue StandardError`
@@ -33,6 +33,10 @@ module RuboCop
33
33
  message << '.' unless message.end_with?('.')
34
34
  message
35
35
  end
36
+
37
+ def find_severity(_range, _severity)
38
+ :fatal
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -14,8 +14,14 @@ module RuboCop
14
14
  #
15
15
  # # good
16
16
  # def foo(x, y = 1)
17
+ # # Alternatives to `__callee__` are `__method__` and `:foo`.
17
18
  # return to_enum(__callee__, x, y)
18
- # # alternatives to `__callee__` are `__method__` and `:foo`
19
+ # end
20
+ #
21
+ # # good
22
+ # def foo(x, y = 1)
23
+ # # It is also allowed if it is wrapped in some method like Sorbet.
24
+ # return to_enum(T.must(__callee__), x, y)
19
25
  # end
20
26
  #
21
27
  class ToEnumArguments < Base
@@ -8,25 +8,39 @@ module RuboCop
8
8
  # always ignored. This is detected automatically since Ruby 2.7.
9
9
  #
10
10
  # @example
11
+ # # bad
12
+ # return 1
11
13
  #
12
- # # Detected since Ruby 2.7
13
- # return 1 # 1 is always ignored.
14
+ # # good
15
+ # return
14
16
  class TopLevelReturnWithArgument < Base
15
- # This cop works by validating the ancestors of the return node. A
16
- # top-level return node's ancestors should not be of block, def, or
17
- # defs type.
17
+ extend AutoCorrector
18
18
 
19
19
  MSG = 'Top level return with argument detected.'
20
20
 
21
21
  def on_return(return_node)
22
- add_offense(return_node) if return_node.arguments? && ancestors_valid?(return_node)
22
+ return unless top_level_return_with_any_argument?(return_node)
23
+
24
+ add_offense(return_node) do |corrector|
25
+ remove_arguments(corrector, return_node)
26
+ end
23
27
  end
24
28
 
25
29
  private
26
30
 
27
- def ancestors_valid?(return_node)
28
- prohibited_ancestors = return_node.each_ancestor(:block, :def, :defs)
29
- prohibited_ancestors.none?
31
+ def top_level_return_with_any_argument?(return_node)
32
+ top_level_return?(return_node) && return_node.arguments?
33
+ end
34
+
35
+ def remove_arguments(corrector, return_node)
36
+ corrector.replace(return_node, 'return')
37
+ end
38
+
39
+ # This cop works by validating the ancestors of the return node. A
40
+ # top-level return node's ancestors should not be of block, def, or
41
+ # defs type.
42
+ def top_level_return?(return_node)
43
+ return_node.each_ancestor(:block, :def, :defs).none?
30
44
  end
31
45
  end
32
46
  end
@@ -111,9 +111,9 @@ module RuboCop
111
111
  return false unless node.block_type? || node.numblock_type?
112
112
 
113
113
  send_node = node.send_node
114
- return false if matches_allowed_pattern?(send_node.source)
115
-
116
- send_node.enumerable_method? || send_node.enumerator_method? || send_node.method?(:loop)
114
+ loopable = send_node.enumerable_method? || send_node.enumerator_method? ||
115
+ send_node.method?(:loop)
116
+ loopable && !matches_allowed_pattern?(send_node.source)
117
117
  end
118
118
 
119
119
  def check(node)
@@ -137,7 +137,7 @@ module RuboCop
137
137
  alias on_sclass on_class
138
138
 
139
139
  def on_block(node)
140
- return unless eval_call?(node)
140
+ return unless eval_call?(node) || included_block?(node)
141
141
 
142
142
  check_node(node.body)
143
143
  end
@@ -192,10 +192,13 @@ module RuboCop
192
192
  end
193
193
  end
194
194
 
195
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
195
196
  def check_child_nodes(node, unused, cur_vis)
196
197
  node.child_nodes.each do |child|
197
198
  if child.send_type? && access_modifier?(child)
198
199
  cur_vis, unused = check_send_node(child, cur_vis, unused)
200
+ elsif child.block_type? && included_block?(child)
201
+ next
199
202
  elsif method_definition?(child)
200
203
  unused = nil
201
204
  elsif start_of_new_scope?(child)
@@ -207,6 +210,7 @@ module RuboCop
207
210
 
208
211
  [cur_vis, unused]
209
212
  end
213
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
210
214
 
211
215
  def check_send_node(node, cur_vis, unused)
212
216
  if node.bare_access_modifier?
@@ -240,6 +244,10 @@ module RuboCop
240
244
  [new_vis, unused]
241
245
  end
242
246
 
247
+ def included_block?(block_node)
248
+ active_support_extensions_enabled? && block_node.method?(:included)
249
+ end
250
+
243
251
  def method_definition?(child)
244
252
  static_method_definition?(child) ||
245
253
  dynamic_method_definition?(child) ||
@@ -13,6 +13,12 @@ module RuboCop
13
13
  # reassignments and properly handles varied cases such as branch, loop,
14
14
  # rescue, ensure, etc.
15
15
  #
16
+ # @safety
17
+ # This cop's autocorrection is unsafe because removing assignment from
18
+ # operator assignment can cause NameError if this assignment has been used to declare
19
+ # local variable. For example, replacing `a ||= 1` to `a || 1` may cause
20
+ # "undefined local variable or method `a' for main:Object (NameError)".
21
+ #
16
22
  # @example
17
23
  #
18
24
  # # bad
@@ -31,6 +37,10 @@ module RuboCop
31
37
  # do_something(some_var)
32
38
  # end
33
39
  class UselessAssignment < Base
40
+ extend AutoCorrector
41
+
42
+ include RangeHelp
43
+
34
44
  MSG = 'Useless assignment to variable - `%<variable>s`.'
35
45
 
36
46
  def self.joining_forces
@@ -55,7 +65,9 @@ module RuboCop
55
65
  assignment.node.loc.name
56
66
  end
57
67
 
58
- add_offense(location, message: message)
68
+ add_offense(location, message: message) do |corrector|
69
+ autocorrect(corrector, assignment)
70
+ end
59
71
  end
60
72
  end
61
73
 
@@ -119,6 +131,52 @@ module RuboCop
119
131
 
120
132
  node.receiver.nil? && !node.arguments?
121
133
  end
134
+
135
+ # rubocop:disable Metrics/AbcSize
136
+ def autocorrect(corrector, assignment)
137
+ if assignment.exception_assignment?
138
+ remove_exception_assignment_part(corrector, assignment.node)
139
+ elsif assignment.multiple_assignment? || assignment.rest_assignment? ||
140
+ assignment.for_assignment?
141
+ rename_variable_with_underscore(corrector, assignment.node)
142
+ elsif assignment.operator_assignment?
143
+ remove_trailing_character_from_operator(corrector, assignment.node)
144
+ elsif assignment.regexp_named_capture?
145
+ replace_named_capture_group_with_non_capturing_group(corrector, assignment.node,
146
+ assignment.variable.name)
147
+ else
148
+ remove_local_variable_assignment_part(corrector, assignment.node)
149
+ end
150
+ end
151
+ # rubocop:enable Metrics/AbcSize
152
+
153
+ def remove_exception_assignment_part(corrector, node)
154
+ corrector.remove(
155
+ range_between(
156
+ (node.parent.children.first&.source_range || node.parent.location.keyword).end_pos,
157
+ node.source_range.end_pos
158
+ )
159
+ )
160
+ end
161
+
162
+ def rename_variable_with_underscore(corrector, node)
163
+ corrector.replace(node, '_')
164
+ end
165
+
166
+ def remove_trailing_character_from_operator(corrector, node)
167
+ corrector.remove(node.parent.location.operator.end.adjust(begin_pos: -1))
168
+ end
169
+
170
+ def replace_named_capture_group_with_non_capturing_group(corrector, node, variable_name)
171
+ corrector.replace(
172
+ node.children.first,
173
+ node.children.first.source.sub(/\(\?<#{variable_name}>/, '(?:')
174
+ )
175
+ end
176
+
177
+ def remove_local_variable_assignment_part(corrector, node)
178
+ corrector.replace(node, node.expression.source)
179
+ end
122
180
  end
123
181
  end
124
182
  end