rubocop 1.11.0 → 1.15.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 (425) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/config/default.yml +58 -6
  4. data/exe/rubocop +1 -3
  5. data/lib/rubocop.rb +6 -1
  6. data/lib/rubocop/cached_data.rb +1 -3
  7. data/lib/rubocop/cli.rb +4 -6
  8. data/lib/rubocop/cli/command/auto_genenerate_config.rb +9 -19
  9. data/lib/rubocop/cli/command/init_dotfile.rb +1 -3
  10. data/lib/rubocop/cli/command/show_cops.rb +1 -4
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +3 -2
  12. data/lib/rubocop/comment_config.rb +45 -101
  13. data/lib/rubocop/config.rb +11 -26
  14. data/lib/rubocop/config_loader.rb +5 -11
  15. data/lib/rubocop/config_loader_resolver.rb +22 -14
  16. data/lib/rubocop/config_obsoletion/cop_rule.rb +1 -2
  17. data/lib/rubocop/config_store.rb +1 -2
  18. data/lib/rubocop/config_validator.rb +5 -10
  19. data/lib/rubocop/cop/autocorrect_logic.rb +3 -8
  20. data/lib/rubocop/cop/badge.rb +1 -2
  21. data/lib/rubocop/cop/base.rb +8 -6
  22. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -2
  23. data/lib/rubocop/cop/bundler/gem_comment.rb +43 -11
  24. data/lib/rubocop/cop/bundler/gem_version.rb +99 -0
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -4
  26. data/lib/rubocop/cop/commissioner.rb +2 -8
  27. data/lib/rubocop/cop/cop.rb +4 -18
  28. data/lib/rubocop/cop/corrector.rb +1 -4
  29. data/lib/rubocop/cop/correctors/alignment_corrector.rb +6 -12
  30. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +2 -4
  31. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -2
  32. data/lib/rubocop/cop/correctors/line_break_corrector.rb +3 -6
  33. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -3
  34. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -3
  35. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -8
  36. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -4
  38. data/lib/rubocop/cop/generator.rb +1 -4
  39. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -2
  40. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -5
  41. data/lib/rubocop/cop/internal_affairs/example_description.rb +7 -5
  42. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +2 -5
  43. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -3
  44. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -3
  45. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -2
  46. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -2
  47. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -3
  48. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +12 -10
  49. data/lib/rubocop/cop/layout/argument_alignment.rb +34 -18
  50. data/lib/rubocop/cop/layout/array_alignment.rb +7 -6
  51. data/lib/rubocop/cop/layout/assignment_indentation.rb +8 -7
  52. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -4
  53. data/lib/rubocop/cop/layout/block_alignment.rb +7 -19
  54. data/lib/rubocop/cop/layout/block_end_newline.rb +4 -8
  55. data/lib/rubocop/cop/layout/case_indentation.rb +1 -3
  56. data/lib/rubocop/cop/layout/class_structure.rb +4 -10
  57. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +18 -30
  58. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -21
  59. data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -6
  60. data/lib/rubocop/cop/layout/dot_position.rb +1 -3
  61. data/lib/rubocop/cop/layout/else_alignment.rb +10 -9
  62. data/lib/rubocop/cop/layout/empty_comment.rb +5 -12
  63. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -8
  64. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -6
  65. data/lib/rubocop/cop/layout/empty_lines.rb +1 -3
  66. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +8 -18
  67. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -8
  68. data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
  69. data/lib/rubocop/cop/layout/end_of_line.rb +1 -1
  70. data/lib/rubocop/cop/layout/extra_spacing.rb +3 -7
  71. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -5
  72. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +10 -8
  73. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -2
  74. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -20
  75. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -2
  76. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -2
  77. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +1 -2
  78. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +6 -5
  79. data/lib/rubocop/cop/layout/hash_alignment.rb +18 -13
  80. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -9
  81. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -6
  82. data/lib/rubocop/cop/layout/indentation_consistency.rb +9 -6
  83. data/lib/rubocop/cop/layout/indentation_style.rb +25 -30
  84. data/lib/rubocop/cop/layout/indentation_width.rb +24 -12
  85. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -4
  86. data/lib/rubocop/cop/layout/line_length.rb +4 -15
  87. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +1 -2
  88. data/lib/rubocop/cop/layout/multiline_block_layout.rb +7 -15
  89. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -2
  90. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -2
  91. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +22 -15
  92. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +10 -5
  93. data/lib/rubocop/cop/layout/parameter_alignment.rb +6 -5
  94. data/lib/rubocop/cop/layout/redundant_line_break.rb +137 -0
  95. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -6
  96. data/lib/rubocop/cop/layout/single_line_block_chain.rb +53 -0
  97. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -3
  98. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -4
  99. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +6 -14
  100. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -2
  101. data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -6
  102. data/lib/rubocop/cop/layout/space_around_operators.rb +4 -9
  103. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -2
  104. data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -3
  105. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  106. data/lib/rubocop/cop/layout/space_before_first_arg.rb +5 -11
  107. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -4
  108. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -10
  109. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +2 -7
  110. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -10
  111. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -2
  112. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
  113. data/lib/rubocop/cop/legacy/corrections_proxy.rb +2 -8
  114. data/lib/rubocop/cop/legacy/corrector.rb +1 -3
  115. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -6
  116. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +14 -7
  117. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -2
  118. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -2
  119. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +83 -41
  120. data/lib/rubocop/cop/lint/deprecated_constants.rb +3 -3
  121. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -5
  122. data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -2
  123. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +1 -3
  124. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -7
  125. data/lib/rubocop/cop/lint/else_layout.rb +1 -3
  126. data/lib/rubocop/cop/lint/empty_block.rb +18 -2
  127. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -3
  128. data/lib/rubocop/cop/lint/empty_file.rb +1 -3
  129. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -3
  130. data/lib/rubocop/cop/lint/ensure_return.rb +1 -3
  131. data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -7
  132. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -2
  133. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +3 -6
  134. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -2
  135. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  136. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +3 -7
  137. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -2
  138. data/lib/rubocop/cop/lint/interpolation_check.rb +3 -11
  139. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -6
  140. data/lib/rubocop/cop/lint/loop.rb +1 -2
  141. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +3 -7
  142. data/lib/rubocop/cop/lint/missing_super.rb +1 -2
  143. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -2
  144. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -2
  145. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -3
  146. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -3
  147. data/lib/rubocop/cop/lint/number_conversion.rb +11 -5
  148. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +1 -2
  149. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -3
  150. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -3
  151. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -3
  152. data/lib/rubocop/cop/lint/raise_exception.rb +1 -2
  153. data/lib/rubocop/cop/lint/rand_one.rb +1 -2
  154. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +9 -22
  155. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -3
  156. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +3 -7
  157. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -2
  158. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -4
  159. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -4
  160. data/lib/rubocop/cop/lint/regexp_as_condition.rb +1 -3
  161. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -4
  162. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -2
  163. data/lib/rubocop/cop/lint/rescue_type.rb +2 -7
  164. data/lib/rubocop/cop/lint/return_in_void_context.rb +1 -2
  165. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -2
  166. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +4 -10
  167. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -2
  168. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +2 -7
  169. data/lib/rubocop/cop/lint/shadowed_argument.rb +4 -11
  170. data/lib/rubocop/cop/lint/shadowed_exception.rb +7 -8
  171. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -2
  172. data/lib/rubocop/cop/lint/suppressed_exception.rb +44 -1
  173. data/lib/rubocop/cop/lint/symbol_conversion.rb +91 -6
  174. data/lib/rubocop/cop/lint/syntax.rb +1 -3
  175. data/lib/rubocop/cop/lint/to_json.rb +1 -2
  176. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -3
  177. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -3
  178. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -5
  179. data/lib/rubocop/cop/lint/unreachable_loop.rb +14 -7
  180. data/lib/rubocop/cop/lint/unused_block_argument.rb +9 -7
  181. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -2
  182. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -4
  183. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -9
  184. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -3
  185. data/lib/rubocop/cop/lint/void.rb +5 -12
  186. data/lib/rubocop/cop/message_annotator.rb +1 -3
  187. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -7
  188. data/lib/rubocop/cop/metrics/class_length.rb +1 -3
  189. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -2
  190. data/lib/rubocop/cop/metrics/module_length.rb +2 -6
  191. data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -5
  192. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
  193. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -7
  194. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -7
  195. data/lib/rubocop/cop/migration/department_name.rb +3 -7
  196. data/lib/rubocop/cop/mixin/alignment.rb +12 -7
  197. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -4
  198. data/lib/rubocop/cop/mixin/code_length.rb +1 -3
  199. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  200. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +2 -2
  201. data/lib/rubocop/cop/mixin/configurable_formatting.rb +3 -8
  202. data/lib/rubocop/cop/mixin/def_node.rb +2 -5
  203. data/lib/rubocop/cop/mixin/documentation_comment.rb +3 -6
  204. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -7
  205. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -3
  206. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -3
  207. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -6
  208. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -3
  209. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  210. data/lib/rubocop/cop/mixin/gem_declaration.rb +13 -0
  211. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +3 -6
  212. data/lib/rubocop/cop/mixin/hash_transform_method.rb +7 -22
  213. data/lib/rubocop/cop/mixin/interpolation.rb +1 -3
  214. data/lib/rubocop/cop/mixin/line_length_help.rb +13 -10
  215. data/lib/rubocop/cop/mixin/match_range.rb +2 -5
  216. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -3
  217. data/lib/rubocop/cop/mixin/method_preference.rb +1 -2
  218. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +4 -3
  219. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +1 -3
  220. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +11 -40
  221. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -2
  222. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -2
  223. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -4
  224. data/lib/rubocop/cop/mixin/percent_array.rb +1 -3
  225. data/lib/rubocop/cop/mixin/percent_literal.rb +0 -6
  226. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +5 -11
  227. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +4 -7
  228. data/lib/rubocop/cop/mixin/range_help.rb +10 -13
  229. data/lib/rubocop/cop/mixin/rescue_node.rb +2 -6
  230. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -2
  231. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -4
  232. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -2
  233. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -3
  234. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  235. data/lib/rubocop/cop/mixin/trailing_body.rb +1 -2
  236. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -2
  237. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +7 -13
  238. data/lib/rubocop/cop/mixin/unused_argument.rb +1 -3
  239. data/lib/rubocop/cop/naming/ascii_identifiers.rb +2 -4
  240. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -2
  241. data/lib/rubocop/cop/naming/file_name.rb +7 -16
  242. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +6 -3
  243. data/lib/rubocop/cop/naming/method_name.rb +1 -2
  244. data/lib/rubocop/cop/naming/predicate_name.rb +1 -2
  245. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -0
  246. data/lib/rubocop/cop/offense.rb +3 -8
  247. data/lib/rubocop/cop/registry.rb +12 -11
  248. data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -5
  249. data/lib/rubocop/cop/style/accessor_grouping.rb +1 -3
  250. data/lib/rubocop/cop/style/alias.rb +5 -12
  251. data/lib/rubocop/cop/style/and_or.rb +3 -1
  252. data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -3
  253. data/lib/rubocop/cop/style/ascii_comments.rb +1 -2
  254. data/lib/rubocop/cop/style/attr.rb +1 -3
  255. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -5
  256. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +59 -71
  257. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +60 -0
  258. data/lib/rubocop/cop/style/case_like_if.rb +16 -6
  259. data/lib/rubocop/cop/style/character_literal.rb +2 -4
  260. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -10
  261. data/lib/rubocop/cop/style/class_equality_comparison.rb +2 -0
  262. data/lib/rubocop/cop/style/class_methods.rb +1 -3
  263. data/lib/rubocop/cop/style/collection_compact.rb +1 -3
  264. data/lib/rubocop/cop/style/colon_method_call.rb +1 -3
  265. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  266. data/lib/rubocop/cop/style/command_literal.rb +4 -9
  267. data/lib/rubocop/cop/style/comment_annotation.rb +3 -6
  268. data/lib/rubocop/cop/style/commented_keyword.rb +7 -13
  269. data/lib/rubocop/cop/style/conditional_assignment.rb +10 -24
  270. data/lib/rubocop/cop/style/copyright.rb +3 -6
  271. data/lib/rubocop/cop/style/date_time.rb +2 -5
  272. data/lib/rubocop/cop/style/def_with_parentheses.rb +1 -2
  273. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  274. data/lib/rubocop/cop/style/documentation.rb +25 -3
  275. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -2
  276. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -7
  277. data/lib/rubocop/cop/style/empty_else.rb +3 -9
  278. data/lib/rubocop/cop/style/empty_literal.rb +12 -9
  279. data/lib/rubocop/cop/style/empty_method.rb +3 -7
  280. data/lib/rubocop/cop/style/end_block.rb +1 -2
  281. data/lib/rubocop/cop/style/endless_method.rb +1 -3
  282. data/lib/rubocop/cop/style/eval_with_location.rb +3 -5
  283. data/lib/rubocop/cop/style/expand_path_arguments.rb +1 -3
  284. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -4
  285. data/lib/rubocop/cop/style/format_string_token.rb +1 -4
  286. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -11
  287. data/lib/rubocop/cop/style/guard_clause.rb +3 -7
  288. data/lib/rubocop/cop/style/hash_conversion.rb +31 -3
  289. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
  290. data/lib/rubocop/cop/style/hash_like_case.rb +1 -2
  291. data/lib/rubocop/cop/style/hash_syntax.rb +20 -24
  292. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -3
  293. data/lib/rubocop/cop/style/if_unless_modifier.rb +40 -13
  294. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  295. data/lib/rubocop/cop/style/inverse_methods.rb +3 -7
  296. data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
  297. data/lib/rubocop/cop/style/lambda.rb +2 -4
  298. data/lib/rubocop/cop/style/lambda_call.rb +1 -2
  299. data/lib/rubocop/cop/style/line_end_concatenation.rb +5 -12
  300. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +47 -3
  301. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +26 -16
  302. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -2
  303. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  304. data/lib/rubocop/cop/style/method_def_parentheses.rb +4 -8
  305. data/lib/rubocop/cop/style/min_max.rb +1 -2
  306. data/lib/rubocop/cop/style/missing_else.rb +2 -4
  307. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +1 -2
  308. data/lib/rubocop/cop/style/mixin_grouping.rb +4 -10
  309. data/lib/rubocop/cop/style/mixin_usage.rb +1 -2
  310. data/lib/rubocop/cop/style/module_function.rb +3 -6
  311. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -2
  312. data/lib/rubocop/cop/style/multiline_method_signature.rb +11 -6
  313. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -2
  314. data/lib/rubocop/cop/style/multiple_comparison.rb +2 -4
  315. data/lib/rubocop/cop/style/mutable_constant.rb +4 -10
  316. data/lib/rubocop/cop/style/negated_if.rb +1 -2
  317. data/lib/rubocop/cop/style/negated_if_else_condition.rb +23 -2
  318. data/lib/rubocop/cop/style/negated_unless.rb +1 -2
  319. data/lib/rubocop/cop/style/nested_modifier.rb +3 -7
  320. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -3
  321. data/lib/rubocop/cop/style/next.rb +4 -9
  322. data/lib/rubocop/cop/style/nil_lambda.rb +29 -12
  323. data/lib/rubocop/cop/style/non_nil_check.rb +2 -5
  324. data/lib/rubocop/cop/style/numeric_literals.rb +3 -11
  325. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -7
  326. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -2
  327. data/lib/rubocop/cop/style/option_hash.rb +1 -3
  328. data/lib/rubocop/cop/style/optional_arguments.rb +2 -5
  329. data/lib/rubocop/cop/style/or_assignment.rb +2 -6
  330. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -9
  331. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -3
  332. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -2
  333. data/lib/rubocop/cop/style/perl_backrefs.rb +2 -9
  334. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -4
  335. data/lib/rubocop/cop/style/proc.rb +1 -2
  336. data/lib/rubocop/cop/style/raise_args.rb +4 -8
  337. data/lib/rubocop/cop/style/random_with_offset.rb +3 -8
  338. data/lib/rubocop/cop/style/redundant_argument.rb +2 -11
  339. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -3
  340. data/lib/rubocop/cop/style/redundant_begin.rb +40 -6
  341. data/lib/rubocop/cop/style/redundant_capital_w.rb +1 -2
  342. data/lib/rubocop/cop/style/redundant_condition.rb +2 -5
  343. data/lib/rubocop/cop/style/redundant_conditional.rb +3 -6
  344. data/lib/rubocop/cop/style/redundant_exception.rb +3 -6
  345. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  346. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -2
  347. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -2
  348. data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -20
  349. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  350. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -4
  351. data/lib/rubocop/cop/style/redundant_return.rb +6 -4
  352. data/lib/rubocop/cop/style/redundant_self.rb +9 -9
  353. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
  354. data/lib/rubocop/cop/style/redundant_sort.rb +2 -5
  355. data/lib/rubocop/cop/style/regexp_literal.rb +4 -8
  356. data/lib/rubocop/cop/style/rescue_modifier.rb +21 -14
  357. data/lib/rubocop/cop/style/rescue_standard_error.rb +3 -7
  358. data/lib/rubocop/cop/style/return_nil.rb +1 -2
  359. data/lib/rubocop/cop/style/safe_navigation.rb +10 -21
  360. data/lib/rubocop/cop/style/send.rb +1 -2
  361. data/lib/rubocop/cop/style/signal_exception.rb +3 -7
  362. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -2
  363. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -5
  364. data/lib/rubocop/cop/style/single_line_methods.rb +21 -4
  365. data/lib/rubocop/cop/style/sole_nested_conditional.rb +31 -7
  366. data/lib/rubocop/cop/style/special_global_vars.rb +6 -18
  367. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -2
  368. data/lib/rubocop/cop/style/stderr_puts.rb +2 -6
  369. data/lib/rubocop/cop/style/string_chars.rb +39 -0
  370. data/lib/rubocop/cop/style/string_concatenation.rb +8 -10
  371. data/lib/rubocop/cop/style/string_literals.rb +2 -5
  372. data/lib/rubocop/cop/style/struct_inheritance.rb +10 -0
  373. data/lib/rubocop/cop/style/symbol_literal.rb +1 -3
  374. data/lib/rubocop/cop/style/symbol_proc.rb +4 -9
  375. data/lib/rubocop/cop/style/ternary_parentheses.rb +3 -6
  376. data/lib/rubocop/cop/style/top_level_method_definition.rb +75 -0
  377. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +6 -3
  378. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -6
  379. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +2 -5
  380. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -10
  381. data/lib/rubocop/cop/style/trivial_accessors.rb +67 -4
  382. data/lib/rubocop/cop/style/unless_else.rb +1 -2
  383. data/lib/rubocop/cop/style/unless_logical_operators.rb +8 -2
  384. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -1
  385. data/lib/rubocop/cop/style/when_then.rb +1 -3
  386. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -2
  387. data/lib/rubocop/cop/style/word_array.rb +1 -2
  388. data/lib/rubocop/cop/style/yoda_condition.rb +3 -11
  389. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -2
  390. data/lib/rubocop/cop/team.rb +2 -5
  391. data/lib/rubocop/cop/util.rb +8 -11
  392. data/lib/rubocop/cop/utils/format_string.rb +1 -3
  393. data/lib/rubocop/cop/variable_force.rb +6 -15
  394. data/lib/rubocop/cop/variable_force/assignment.rb +1 -2
  395. data/lib/rubocop/cop/variable_force/branch.rb +16 -2
  396. data/lib/rubocop/cop/variable_force/reference.rb +1 -3
  397. data/lib/rubocop/cop/variable_force/scope.rb +4 -8
  398. data/lib/rubocop/cop/variable_force/variable.rb +2 -4
  399. data/lib/rubocop/cops_documentation_generator.rb +7 -21
  400. data/lib/rubocop/directive_comment.rb +69 -9
  401. data/lib/rubocop/ext/regexp_parser.rb +3 -6
  402. data/lib/rubocop/file_finder.rb +1 -3
  403. data/lib/rubocop/formatter/clang_style_formatter.rb +4 -2
  404. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -8
  405. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -5
  406. data/lib/rubocop/formatter/html_formatter.rb +4 -10
  407. data/lib/rubocop/formatter/json_formatter.rb +1 -5
  408. data/lib/rubocop/formatter/junit_formatter.rb +23 -14
  409. data/lib/rubocop/formatter/progress_formatter.rb +1 -3
  410. data/lib/rubocop/formatter/tap_formatter.rb +4 -2
  411. data/lib/rubocop/magic_comment.rb +1 -1
  412. data/lib/rubocop/options.rb +30 -50
  413. data/lib/rubocop/path_util.rb +1 -3
  414. data/lib/rubocop/rake_task.rb +3 -0
  415. data/lib/rubocop/remote_config.rb +4 -7
  416. data/lib/rubocop/result_cache.rb +5 -12
  417. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  418. data/lib/rubocop/rspec/expect_offense.rb +4 -9
  419. data/lib/rubocop/rspec/shared_contexts.rb +8 -15
  420. data/lib/rubocop/runner.rb +7 -14
  421. data/lib/rubocop/target_finder.rb +19 -16
  422. data/lib/rubocop/target_ruby.rb +4 -8
  423. data/lib/rubocop/version.rb +1 -1
  424. metadata +13 -7
  425. data/lib/rubocop/core_ext/hash.rb +0 -20
@@ -8,9 +8,7 @@ module RuboCop
8
8
  extend NodePattern::Macros
9
9
 
10
10
  def after_leaving_scope(scope, _variable_table)
11
- scope.variables.each_value do |variable|
12
- check_argument(variable)
13
- end
11
+ scope.variables.each_value { |variable| check_argument(variable) }
14
12
  end
15
13
 
16
14
  private
@@ -70,16 +70,14 @@ module RuboCop
70
70
  private
71
71
 
72
72
  def should_check?(token)
73
- token.type == :tIDENTIFIER ||
74
- (token.type == :tCONSTANT && cop_config['AsciiConstants'])
73
+ token.type == :tIDENTIFIER || (token.type == :tCONSTANT && cop_config['AsciiConstants'])
75
74
  end
76
75
 
77
76
  def first_offense_range(identifier)
78
77
  expression = identifier.pos
79
78
  first_offense = first_non_ascii_chars(identifier.text)
80
79
 
81
- start_position = expression.begin_pos +
82
- identifier.text.index(first_offense)
80
+ start_position = expression.begin_pos + identifier.text.index(first_offense)
83
81
  end_position = start_position + first_offense.length
84
82
 
85
83
  range_between(start_position, end_position)
@@ -16,8 +16,7 @@ module RuboCop
16
16
  class BinaryOperatorParameterName < Base
17
17
  extend AutoCorrector
18
18
 
19
- MSG = 'When defining the `%<opr>s` operator, ' \
20
- 'name its argument `other`.'
19
+ MSG = 'When defining the `%<opr>s` operator, name its argument `other`.'
21
20
 
22
21
  OP_LIKE_METHODS = %i[eql? equal?].freeze
23
22
  EXCLUDED = %i[+@ -@ [] []= << === ` =~].freeze
@@ -27,22 +27,17 @@ module RuboCop
27
27
  class FileName < Base
28
28
  include RangeHelp
29
29
 
30
- MSG_SNAKE_CASE = 'The name of this source file (`%<basename>s`) ' \
31
- 'should use snake_case.'
32
- MSG_NO_DEFINITION = '%<basename>s should define a class or module ' \
33
- 'called `%<namespace>s`.'
30
+ MSG_SNAKE_CASE = 'The name of this source file (`%<basename>s`) should use snake_case.'
31
+ MSG_NO_DEFINITION = '%<basename>s should define a class or module called `%<namespace>s`.'
34
32
  MSG_REGEX = '`%<basename>s` should match `%<regex>s`.'
35
33
 
36
34
  SNAKE_CASE = /^[\d[[:lower:]]_.?!]+$/.freeze
37
35
 
38
36
  def on_new_investigation
39
37
  file_path = processed_source.file_path
40
- return if config.file_to_exclude?(file_path) ||
41
- config.allowed_camel_case_file?(file_path)
38
+ return if config.file_to_exclude?(file_path) || config.allowed_camel_case_file?(file_path)
42
39
 
43
- for_bad_filename(file_path) do |range, msg|
44
- add_offense(range, message: msg)
45
- end
40
+ for_bad_filename(file_path) { |range, msg| add_offense(range, message: msg) }
46
41
  end
47
42
 
48
43
  private
@@ -62,8 +57,7 @@ module RuboCop
62
57
  def perform_class_and_module_naming_checks(file_path, basename)
63
58
  return unless expect_matching_definition?
64
59
 
65
- if check_definition_path_hierarchy? &&
66
- !matching_definition?(file_path)
60
+ if check_definition_path_hierarchy? && !matching_definition?(file_path)
67
61
  msg = no_definition_message(basename, file_path)
68
62
  elsif !matching_class?(basename)
69
63
  msg = no_definition_message(basename, basename)
@@ -136,8 +130,7 @@ module RuboCop
136
130
 
137
131
  const_namespace, const_name = *const
138
132
  next if name != const_name && !match_acronym?(name, const_name)
139
- next unless namespace.empty? ||
140
- match_namespace(child, const_namespace, namespace)
133
+ next unless namespace.empty? || match_namespace(child, const_namespace, namespace)
141
134
 
142
135
  return node
143
136
  end
@@ -181,9 +174,7 @@ module RuboCop
181
174
  expected = expected.to_s
182
175
  name = name.to_s
183
176
 
184
- allowed_acronyms.any? do |acronym|
185
- expected.gsub(acronym.capitalize, acronym) == name
186
- end
177
+ allowed_acronyms.any? { |acronym| expected.gsub(acronym.capitalize, acronym) == name }
187
178
  end
188
179
 
189
180
  def to_namespace(path)
@@ -139,6 +139,10 @@ module RuboCop
139
139
  # define_method(:foo) do
140
140
  # @_foo ||= calculate_expensive_thing
141
141
  # end
142
+ #
143
+ # This cop relies on the pattern `@instance_var ||= ...`,
144
+ # but this is sometimes used for other purposes than memoization
145
+ # so this cop is considered unsafe.
142
146
  class MemoizedInstanceVariableName < Base
143
147
  include ConfigurableEnforcedStyle
144
148
 
@@ -243,8 +247,7 @@ module RuboCop
243
247
  def message(variable)
244
248
  variable_name = variable.to_s.sub('@', '')
245
249
 
246
- return UNDERSCORE_REQUIRED if style == :required &&
247
- !variable_name.start_with?('_')
250
+ return UNDERSCORE_REQUIRED if style == :required && !variable_name.start_with?('_')
248
251
 
249
252
  MSG
250
253
  end
@@ -256,7 +259,7 @@ module RuboCop
256
259
  end
257
260
 
258
261
  def variable_name_candidates(method_name)
259
- no_underscore = method_name.sub(/\A_/, '')
262
+ no_underscore = method_name.delete_prefix('_')
260
263
  with_underscore = "_#{method_name}"
261
264
  case style
262
265
  when :required
@@ -53,8 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  def on_def(node)
56
- return if node.operator_method? ||
57
- matches_ignored_pattern?(node.method_name)
56
+ return if node.operator_method? || matches_ignored_pattern?(node.method_name)
58
57
 
59
58
  check_name(node, node.method_name, node.loc.name)
60
59
  end
@@ -44,8 +44,7 @@ module RuboCop
44
44
 
45
45
  add_offense(
46
46
  node.first_argument.loc.expression,
47
- message: message(method_name,
48
- expected_name(method_name.to_s, prefix))
47
+ message: message(method_name, expected_name(method_name.to_s, prefix))
49
48
  )
50
49
  end
51
50
  end
@@ -9,6 +9,11 @@ module RuboCop
9
9
  # The `PreferredName` config option takes a `String`. It represents
10
10
  # the required name of the variable. Its default is `e`.
11
11
  #
12
+ # NOTE: This cop does not consider nested rescues because it cannot
13
+ # guarantee that the variable from the outer rescue is not used within
14
+ # the inner rescue (in which case, changing the inner variable would
15
+ # shadow the outer variable).
16
+ #
12
17
  # @example PreferredName: e (default)
13
18
  # # bad
14
19
  # begin
@@ -62,6 +67,11 @@ module RuboCop
62
67
  offending_name = variable_name(node)
63
68
  return unless offending_name
64
69
 
70
+ # Handle nested rescues by only requiring the outer one to use the
71
+ # configured variable name, so that nested rescues don't use the same
72
+ # variable.
73
+ return if node.each_ancestor(:resbody).any?
74
+
65
75
  preferred_name = preferred_name(offending_name)
66
76
  return if preferred_name.to_sym == offending_name
67
77
 
@@ -7,8 +7,7 @@ module RuboCop
7
7
  include Comparable
8
8
 
9
9
  # @api private
10
- COMPARISON_ATTRIBUTES = %i[line column cop_name
11
- message severity].freeze
10
+ COMPARISON_ATTRIBUTES = %i[line column cop_name message severity].freeze
12
11
 
13
12
  # @api public
14
13
  #
@@ -141,9 +140,7 @@ module RuboCop
141
140
  # @return [Parser::Source::Range]
142
141
  # the range of the code that is highlighted
143
142
  def highlighted_area
144
- Parser::Source::Range.new(source_line,
145
- column,
146
- column + column_length)
143
+ Parser::Source::Range.new(source_line, column, column + column_length)
147
144
  end
148
145
 
149
146
  # @api private
@@ -220,9 +217,7 @@ module RuboCop
220
217
  alias eql? ==
221
218
 
222
219
  def hash
223
- COMPARISON_ATTRIBUTES.reduce(0) do |hash, attribute|
224
- hash ^ public_send(attribute).hash
225
- end
220
+ COMPARISON_ATTRIBUTES.reduce(0) { |hash, attribute| hash ^ public_send(attribute).hash }
226
221
  end
227
222
 
228
223
  # @api public
@@ -10,12 +10,7 @@ module RuboCop
10
10
 
11
11
  def initialize(name, origin, badges)
12
12
  super(
13
- format(
14
- MSG,
15
- name: name,
16
- origin: origin,
17
- options: badges.to_a.join(' or ')
18
- )
13
+ format(MSG, name: name, origin: origin, options: badges.to_a.join(' or '))
19
14
  )
20
15
  end
21
16
  end
@@ -64,6 +59,11 @@ module RuboCop
64
59
  with(without_department.values.flatten)
65
60
  end
66
61
 
62
+ # @return [Boolean] Checks if given name is department
63
+ def department?(name)
64
+ departments.include? name.to_sym
65
+ end
66
+
67
67
  def contains_cop_matching?(names)
68
68
  cops.any? { |cop| cop.match?(names) }
69
69
  end
@@ -150,16 +150,13 @@ module RuboCop
150
150
  end
151
151
 
152
152
  def enabled(config, only = [], only_safe: false)
153
- select do |cop|
154
- only.include?(cop.cop_name) || enabled?(cop, config, only_safe)
155
- end
153
+ select { |cop| only.include?(cop.cop_name) || enabled?(cop, config, only_safe) }
156
154
  end
157
155
 
158
156
  def enabled?(cop, config, only_safe)
159
157
  cfg = config.for_cop(cop)
160
158
 
161
- cop_enabled = cfg.fetch('Enabled') == true ||
162
- enabled_pending_cop?(cfg, config)
159
+ cop_enabled = cfg.fetch('Enabled') == true || enabled_pending_cop?(cfg, config)
163
160
 
164
161
  if only_safe
165
162
  cop_enabled && cfg.fetch('Safe', true)
@@ -179,6 +176,10 @@ module RuboCop
179
176
  cops.map(&:cop_name)
180
177
  end
181
178
 
179
+ def names_for_department(department)
180
+ cops.select { |cop| cop.department == department.to_sym }.map(&:cop_name)
181
+ end
182
+
182
183
  def ==(other)
183
184
  cops == other.cops
184
185
  end
@@ -47,7 +47,7 @@ module RuboCop
47
47
  #
48
48
  # end
49
49
  #
50
- # @example AllowModifiersOnSymbols: true
50
+ # @example AllowModifiersOnSymbols: true (default)
51
51
  # # good
52
52
  # class Foo
53
53
  #
@@ -79,7 +79,7 @@ module RuboCop
79
79
 
80
80
  # @!method access_modifier_with_symbol?(node)
81
81
  def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
82
- (send nil? {:private :protected :public} (sym _))
82
+ (send nil? {:private :protected :public :module_function} (sym _))
83
83
  PATTERN
84
84
 
85
85
  def on_send(node)
@@ -88,9 +88,7 @@ module RuboCop
88
88
  return if allow_modifiers_on_symbols?(node)
89
89
 
90
90
  if offense?(node)
91
- add_offense(node.loc.selector) do
92
- opposite_style_detected
93
- end
91
+ add_offense(node.loc.selector) { opposite_style_detected }
94
92
  else
95
93
  correct_style_detected
96
94
  end
@@ -129,9 +129,7 @@ module RuboCop
129
129
  end
130
130
 
131
131
  def group_accessors(node, accessors)
132
- accessor_names = accessors.flat_map do |accessor|
133
- accessor.arguments.map(&:source)
134
- end
132
+ accessor_names = accessors.flat_map { |accessor| accessor.arguments.map(&:source) }
135
133
 
136
134
  "#{node.method_name} #{accessor_names.join(', ')}"
137
135
  end
@@ -27,10 +27,8 @@ module RuboCop
27
27
  extend AutoCorrector
28
28
 
29
29
  MSG_ALIAS = 'Use `alias_method` instead of `alias`.'
30
- MSG_ALIAS_METHOD = 'Use `alias` instead of `alias_method` ' \
31
- '%<current>s.'
32
- MSG_SYMBOL_ARGS = 'Use `alias %<prefer>s` instead of ' \
33
- '`alias %<current>s`.'
30
+ MSG_ALIAS_METHOD = 'Use `alias` instead of `alias_method` %<current>s.'
31
+ MSG_SYMBOL_ARGS = 'Use `alias %<prefer>s` instead of `alias %<current>s`.'
34
32
 
35
33
  RESTRICT_ON_SEND = %i[alias_method].freeze
36
34
 
@@ -52,9 +50,7 @@ module RuboCop
52
50
  autocorrect(corrector, node)
53
51
  end
54
52
  elsif node.children.none? { |arg| bareword?(arg) }
55
- add_offense_for_args(node) do |corrector|
56
- autocorrect(corrector, node)
57
- end
53
+ add_offense_for_args(node) { |corrector| autocorrect(corrector, node) }
58
54
  end
59
55
  end
60
56
 
@@ -75,17 +71,14 @@ module RuboCop
75
71
  end
76
72
 
77
73
  def alias_method_possible?(node)
78
- scope_type(node) != :instance_eval &&
79
- node.children.none?(&:gvar_type?)
74
+ scope_type(node) != :instance_eval && node.children.none?(&:gvar_type?)
80
75
  end
81
76
 
82
77
  def add_offense_for_args(node, &block)
83
78
  existing_args = node.children.map(&:source).join(' ')
84
79
  preferred_args = node.children.map { |a| a.source[1..-1] }.join(' ')
85
80
  arg_ranges = node.children.map(&:source_range)
86
- msg = format(MSG_SYMBOL_ARGS,
87
- prefer: preferred_args,
88
- current: existing_args)
81
+ msg = format(MSG_SYMBOL_ARGS, prefer: preferred_args, current: existing_args)
89
82
  add_offense(arg_ranges.reduce(&:join), message: msg, &block)
90
83
  end
91
84
 
@@ -94,7 +94,9 @@ module RuboCop
94
94
 
95
95
  return unless correctable_send?(node)
96
96
 
97
- corrector.replace(whitespace_before_arg(node), '(')
97
+ whitespace_before_arg_range = whitespace_before_arg(node)
98
+ corrector.remove(whitespace_before_arg_range)
99
+ corrector.insert_before(whitespace_before_arg_range, '(')
98
100
  corrector.insert_after(node.last_argument, ')')
99
101
  end
100
102
 
@@ -107,9 +107,7 @@ module RuboCop
107
107
  begin_pos = forwarding_method.source_range.begin_pos
108
108
  end_pos = forwarding_method.source_range.end_pos
109
109
 
110
- lvars.all? do |lvar|
111
- lvar.source_range.begin_pos.between?(begin_pos, end_pos)
112
- end
110
+ lvars.all? { |lvar| lvar.source_range.begin_pos.between?(begin_pos, end_pos) }
113
111
  end
114
112
 
115
113
  def register_offense_to_forwarding_method_arguments(forwarding_method)
@@ -35,8 +35,7 @@ module RuboCop
35
35
  expression = comment.loc.expression
36
36
  first_offense = first_non_ascii_chars(comment.text)
37
37
 
38
- start_position = expression.begin_pos +
39
- comment.text.index(first_offense)
38
+ start_position = expression.begin_pos + comment.text.index(first_offense)
40
39
  end_position = start_position + first_offense.length
41
40
 
42
41
  range_between(start_position, end_position)
@@ -24,9 +24,7 @@ module RuboCop
24
24
  def on_send(node)
25
25
  return unless node.command?(:attr) && node.arguments?
26
26
  # check only for method definitions in class/module body
27
- return if node.parent &&
28
- !node.parent.class_type? &&
29
- !class_eval?(node.parent)
27
+ return if node.parent && !node.parent.class_type? && !class_eval?(node.parent)
30
28
 
31
29
  message = message(node)
32
30
  add_offense(node.loc.selector, message: message) do |corrector|
@@ -19,9 +19,7 @@ module RuboCop
19
19
  class AutoResourceCleanup < Base
20
20
  MSG = 'Use the block version of `%<class>s.%<method>s`.'
21
21
 
22
- TARGET_METHODS = {
23
- File: :open
24
- }.freeze
22
+ TARGET_METHODS = { File: :open }.freeze
25
23
 
26
24
  RESTRICT_ON_SEND = TARGET_METHODS.values.freeze
27
25
 
@@ -42,8 +40,7 @@ module RuboCop
42
40
 
43
41
  def cleanup?(node)
44
42
  parent = node.parent
45
- node.block_argument? ||
46
- (parent && (parent.block_type? || !parent.lvasgn_type?))
43
+ node.block_argument? || (parent && (parent.block_type? || !parent.lvasgn_type?))
47
44
  end
48
45
  end
49
46
  end
@@ -19,47 +19,61 @@ module RuboCop
19
19
  # end
20
20
  #
21
21
  class BisectedAttrAccessor < Base
22
- include VisibilityHelp
22
+ require_relative 'bisected_attr_accessor/macro'
23
+
24
+ include RangeHelp
23
25
  extend AutoCorrector
24
26
 
25
27
  MSG = 'Combine both accessors into `attr_accessor %<name>s`.'
26
28
 
29
+ def on_new_investigation
30
+ @macros_to_rewrite = {}
31
+ end
32
+
27
33
  def on_class(class_node)
28
- VISIBILITY_SCOPES.each do |visibility|
29
- reader_names, writer_names = accessor_names(class_node, visibility)
30
- next unless reader_names && writer_names
34
+ @macros_to_rewrite[class_node] = Set.new
35
+
36
+ find_macros(class_node.body).each do |_visibility, macros|
37
+ bisected = find_bisection(macros)
38
+ next unless bisected.any?
31
39
 
32
- accessor_macroses(class_node, visibility).each do |macro|
33
- check(macro, reader_names, writer_names)
40
+ macros.each do |macro|
41
+ attrs = macro.bisect(*bisected)
42
+ next if attrs.none?
43
+
44
+ @macros_to_rewrite[class_node] << macro
45
+ attrs.each { |attr| register_offense(attr) }
34
46
  end
35
47
  end
36
48
  end
37
49
  alias on_sclass on_class
38
50
  alias on_module on_class
39
51
 
40
- private
41
-
42
- def accessor_names(class_node, visibility)
43
- reader_names = nil
44
- writer_names = nil
45
-
46
- accessor_macroses(class_node, visibility).each do |macro|
47
- names = macro.arguments.map(&:source)
48
-
49
- names.each do |name|
50
- if attr_reader?(macro)
51
- (reader_names ||= Set.new).add(name)
52
+ # Each offending macro is captured and registered in `on_class` but correction
53
+ # happens in `after_class` because a macro might have multiple attributes
54
+ # rewritten from it
55
+ def after_class(class_node)
56
+ @macros_to_rewrite[class_node].each do |macro|
57
+ node = macro.node
58
+ range = range_by_whole_lines(node.loc.expression, include_final_newline: true)
59
+
60
+ correct(range) do |corrector|
61
+ if macro.writer?
62
+ correct_writer(corrector, macro, node, range)
52
63
  else
53
- (writer_names ||= Set.new).add(name)
64
+ correct_reader(corrector, macro, node, range)
54
65
  end
55
66
  end
56
67
  end
57
-
58
- [reader_names, writer_names]
59
68
  end
69
+ alias after_sclass after_class
70
+ alias after_module after_class
60
71
 
61
- def accessor_macroses(class_node, visibility)
62
- class_def = class_node.body
72
+ private
73
+
74
+ def find_macros(class_def)
75
+ # Find all the macros (`attr_reader`, `attr_writer`, etc.) in the class body
76
+ # and turn them into `Macro` objects so that they can be processed.
63
77
  return [] if !class_def || class_def.def_type?
64
78
 
65
79
  send_nodes =
@@ -69,66 +83,40 @@ module RuboCop
69
83
  class_def.each_child_node(:send)
70
84
  end
71
85
 
72
- send_nodes.select { |node| attr_within_visibility_scope?(node, visibility) }
86
+ send_nodes.each_with_object([]) do |node, macros|
87
+ macros << Macro.new(node) if Macro.macro?(node)
88
+ end.group_by(&:visibility)
73
89
  end
74
90
 
75
- def attr_within_visibility_scope?(node, visibility)
76
- node.macro? &&
77
- (attr_reader?(node) || attr_writer?(node)) &&
78
- node_visibility(node) == visibility
91
+ def find_bisection(macros)
92
+ # Find which attributes are defined in both readers and writers so that they
93
+ # can be replaced with accessors.
94
+ readers, writers = macros.partition(&:reader?)
95
+ readers.flat_map(&:attr_names) & writers.flat_map(&:attr_names)
79
96
  end
80
97
 
81
- def attr_reader?(send_node)
82
- send_node.method?(:attr_reader) || send_node.method?(:attr)
98
+ def register_offense(attr)
99
+ add_offense(attr, message: format(MSG, name: attr.source))
83
100
  end
84
101
 
85
- def attr_writer?(send_node)
86
- send_node.method?(:attr_writer)
87
- end
102
+ def correct_reader(corrector, macro, node, range)
103
+ attr_accessor = "attr_accessor #{macro.bisected_names.join(', ')}\n"
88
104
 
89
- def check(macro, reader_names, writer_names)
90
- macro.arguments.each do |arg_node|
91
- name = arg_node.source
92
-
93
- next unless (attr_reader?(macro) && writer_names.include?(name)) ||
94
- (attr_writer?(macro) && reader_names.include?(name))
95
-
96
- add_offense(arg_node, message: format(MSG, name: name)) do |corrector|
97
- macro = arg_node.parent
98
-
99
- corrector.replace(macro, replacement(macro, arg_node))
100
- end
101
- end
102
- end
103
-
104
- def replacement(macro, node)
105
- class_node = macro.each_ancestor(:class, :sclass, :module).first
106
- reader_names, writer_names = accessor_names(class_node, node_visibility(macro))
107
-
108
- rest_args = rest_args(macro.arguments, reader_names, writer_names)
109
-
110
- if attr_reader?(macro)
111
- attr_reader_replacement(macro, node, rest_args)
112
- elsif rest_args.empty?
113
- ''
105
+ if macro.all_bisected?
106
+ corrector.replace(range, "#{indent(node)}#{attr_accessor}")
114
107
  else
115
- "#{macro.method_name} #{rest_args.map(&:source).join(', ')}"
116
- end
117
- end
118
-
119
- def rest_args(args, reader_names, writer_names)
120
- args.reject do |arg|
121
- name = arg.source
122
- reader_names.include?(name) && writer_names.include?(name)
108
+ correction = "#{indent(node)}attr_reader #{macro.rest.join(', ')}"
109
+ corrector.insert_before(node, attr_accessor)
110
+ corrector.replace(node, correction)
123
111
  end
124
112
  end
125
113
 
126
- def attr_reader_replacement(macro, node, rest_args)
127
- if rest_args.empty?
128
- "attr_accessor #{node.source}"
114
+ def correct_writer(corrector, macro, node, range)
115
+ if macro.all_bisected?
116
+ corrector.remove(range)
129
117
  else
130
- "attr_accessor #{node.source}\n"\
131
- "#{indent(macro)}#{macro.method_name} #{rest_args.map(&:source).join(', ')}"
118
+ correction = "attr_writer #{macro.rest.join(', ')}"
119
+ corrector.replace(node, correction)
132
120
  end
133
121
  end
134
122
  end