rubocop 0.85.1 → 0.89.1

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 (409) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -4
  3. data/bin/rubocop-profile +32 -0
  4. data/config/default.yml +227 -26
  5. data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
  6. data/lib/rubocop/cli/command/base.rb +1 -0
  7. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  8. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +3 -3
  10. data/lib/rubocop/cli/command/version.rb +2 -2
  11. data/lib/rubocop/cli.rb +2 -4
  12. data/lib/rubocop/comment_config.rb +5 -7
  13. data/lib/rubocop/config.rb +21 -4
  14. data/lib/rubocop/config_loader.rb +41 -69
  15. data/lib/rubocop/config_loader_resolver.rb +4 -4
  16. data/lib/rubocop/config_obsoletion.rb +6 -2
  17. data/lib/rubocop/config_store.rb +4 -0
  18. data/lib/rubocop/config_validator.rb +2 -4
  19. data/lib/rubocop/cop/autocorrect_logic.rb +14 -24
  20. data/lib/rubocop/cop/badge.rb +1 -1
  21. data/lib/rubocop/cop/base.rb +407 -0
  22. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
  23. data/lib/rubocop/cop/commissioner.rb +47 -50
  24. data/lib/rubocop/cop/cop.rb +85 -236
  25. data/lib/rubocop/cop/corrector.rb +38 -115
  26. data/lib/rubocop/cop/correctors/line_break_corrector.rb +4 -4
  27. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
  28. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  29. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +15 -18
  31. data/lib/rubocop/cop/force.rb +1 -0
  32. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +39 -13
  33. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  34. data/lib/rubocop/cop/generator/configuration_injector.rb +3 -3
  35. data/lib/rubocop/cop/generator.rb +1 -1
  36. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +4 -12
  37. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
  39. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +8 -8
  40. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +10 -7
  41. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +7 -8
  42. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  43. data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
  44. data/lib/rubocop/cop/layout/case_indentation.rb +18 -19
  45. data/lib/rubocop/cop/layout/class_structure.rb +5 -44
  46. data/lib/rubocop/cop/layout/comment_indentation.rb +4 -4
  47. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  48. data/lib/rubocop/cop/layout/empty_lines.rb +0 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
  50. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -8
  51. data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
  52. data/lib/rubocop/cop/layout/end_of_line.rb +1 -1
  53. data/lib/rubocop/cop/layout/extra_spacing.rb +22 -36
  54. data/lib/rubocop/cop/layout/first_argument_indentation.rb +5 -1
  55. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  56. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -1
  57. data/lib/rubocop/cop/layout/hash_alignment.rb +2 -3
  58. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  59. data/lib/rubocop/cop/layout/indentation_style.rb +0 -2
  60. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  61. data/lib/rubocop/cop/layout/multiline_block_layout.rb +17 -7
  62. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  63. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +0 -2
  64. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +22 -27
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  67. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +33 -66
  68. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  70. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +4 -3
  71. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  73. data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
  74. data/lib/rubocop/cop/legacy/corrector.rb +29 -0
  75. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -4
  76. data/lib/rubocop/cop/lint/ambiguous_operator.rb +15 -10
  77. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +11 -13
  78. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  79. data/lib/rubocop/cop/lint/big_decimal_new.rb +10 -10
  80. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +50 -0
  81. data/lib/rubocop/cop/lint/boolean_symbol.rb +16 -11
  82. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -1
  83. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  84. data/lib/rubocop/cop/lint/debugger.rb +7 -1
  85. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -10
  86. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +21 -17
  87. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
  88. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  89. data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
  90. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +1 -1
  91. data/lib/rubocop/cop/lint/duplicate_methods.rb +9 -6
  92. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +60 -0
  93. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  94. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  95. data/lib/rubocop/cop/lint/empty_conditional_body.rb +67 -0
  96. data/lib/rubocop/cop/lint/empty_ensure.rb +5 -5
  97. data/lib/rubocop/cop/lint/empty_expression.rb +2 -2
  98. data/lib/rubocop/cop/lint/empty_interpolation.rb +5 -6
  99. data/lib/rubocop/cop/lint/empty_when.rb +2 -2
  100. data/lib/rubocop/cop/lint/ensure_return.rb +27 -29
  101. data/lib/rubocop/cop/lint/erb_new_arguments.rb +11 -10
  102. data/lib/rubocop/cop/lint/flip_flop.rb +1 -1
  103. data/lib/rubocop/cop/lint/float_comparison.rb +93 -0
  104. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -2
  105. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -5
  106. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +13 -14
  107. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +5 -4
  108. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
  109. data/lib/rubocop/cop/lint/inherit_exception.rb +12 -7
  110. data/lib/rubocop/cop/lint/interpolation_check.rb +21 -5
  111. data/lib/rubocop/cop/lint/literal_as_condition.rb +14 -2
  112. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -7
  113. data/lib/rubocop/cop/lint/loop.rb +23 -2
  114. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +6 -5
  115. data/lib/rubocop/cop/lint/missing_super.rb +99 -0
  116. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  117. data/lib/rubocop/cop/lint/multiple_comparison.rb +6 -9
  118. data/lib/rubocop/cop/lint/nested_method_definition.rb +15 -21
  119. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  120. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  121. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +84 -13
  122. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
  123. data/lib/rubocop/cop/lint/number_conversion.rb +6 -9
  124. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +11 -13
  125. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +90 -0
  126. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +12 -13
  127. data/lib/rubocop/cop/lint/percent_string_array.rb +14 -13
  128. data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -13
  129. data/lib/rubocop/cop/lint/raise_exception.rb +15 -5
  130. data/lib/rubocop/cop/lint/rand_one.rb +3 -3
  131. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +43 -40
  132. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +7 -11
  133. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -7
  134. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +15 -11
  135. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +6 -13
  136. data/lib/rubocop/cop/lint/redundant_with_index.rb +11 -14
  137. data/lib/rubocop/cop/lint/redundant_with_object.rb +11 -14
  138. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -2
  139. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -2
  140. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  141. data/lib/rubocop/cop/lint/rescue_type.rb +8 -8
  142. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -4
  143. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -6
  144. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +14 -10
  145. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +10 -2
  146. data/lib/rubocop/cop/lint/script_permission.rb +10 -7
  147. data/lib/rubocop/cop/lint/self_assignment.rb +78 -0
  148. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -11
  149. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  150. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
  151. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +3 -3
  152. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -1
  153. data/lib/rubocop/cop/lint/suppressed_exception.rb +4 -7
  154. data/lib/rubocop/cop/lint/syntax.rb +11 -26
  155. data/lib/rubocop/cop/lint/to_json.rb +4 -6
  156. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +34 -0
  157. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +4 -4
  158. data/lib/rubocop/cop/lint/unified_integer.rb +4 -6
  159. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  160. data/lib/rubocop/cop/lint/unreachable_loop.rb +174 -0
  161. data/lib/rubocop/cop/lint/unused_block_argument.rb +8 -3
  162. data/lib/rubocop/cop/lint/unused_method_argument.rb +9 -4
  163. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  164. data/lib/rubocop/cop/lint/uri_regexp.rb +11 -47
  165. data/lib/rubocop/cop/lint/useless_access_modifier.rb +26 -16
  166. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -4
  167. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -15
  168. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -6
  169. data/lib/rubocop/cop/lint/void.rb +3 -7
  170. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  171. data/lib/rubocop/cop/metrics/block_length.rb +24 -2
  172. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  173. data/lib/rubocop/cop/metrics/class_length.rb +26 -3
  174. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +37 -4
  175. data/lib/rubocop/cop/metrics/method_length.rb +25 -2
  176. data/lib/rubocop/cop/metrics/module_length.rb +26 -3
  177. data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -6
  178. data/lib/rubocop/cop/metrics/perceived_complexity.rb +7 -8
  179. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +47 -4
  180. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +157 -0
  181. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  182. data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +37 -0
  183. data/lib/rubocop/cop/migration/department_name.rb +14 -16
  184. data/lib/rubocop/cop/mixin/alignment.rb +2 -1
  185. data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
  186. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -1
  187. data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
  188. data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
  189. data/lib/rubocop/cop/mixin/code_length.rb +26 -5
  190. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
  191. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  192. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  193. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  194. data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
  195. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  196. data/lib/rubocop/cop/mixin/hash_transform_method.rb +5 -11
  197. data/lib/rubocop/cop/mixin/line_length_help.rb +1 -3
  198. data/lib/rubocop/cop/mixin/method_complexity.rb +10 -2
  199. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  200. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -2
  201. data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
  202. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
  203. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  204. data/lib/rubocop/cop/mixin/percent_array.rb +2 -6
  205. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  206. data/lib/rubocop/cop/mixin/range_help.rb +19 -5
  207. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +27 -0
  208. data/lib/rubocop/cop/mixin/statement_modifier.rb +39 -10
  209. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  210. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -27
  211. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -5
  212. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +12 -17
  213. data/lib/rubocop/cop/mixin/unused_argument.rb +4 -6
  214. data/lib/rubocop/cop/mixin/visibility_help.rb +50 -0
  215. data/lib/rubocop/cop/naming/accessor_method_name.rb +4 -2
  216. data/lib/rubocop/cop/naming/ascii_identifiers.rb +29 -6
  217. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +4 -4
  218. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  219. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -2
  220. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  221. data/lib/rubocop/cop/naming/file_name.rb +4 -6
  222. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +2 -2
  223. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -3
  224. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -2
  225. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  226. data/lib/rubocop/cop/naming/method_parameter_name.rb +2 -2
  227. data/lib/rubocop/cop/naming/predicate_name.rb +6 -10
  228. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -11
  229. data/lib/rubocop/cop/naming/variable_name.rb +1 -1
  230. data/lib/rubocop/cop/naming/variable_number.rb +1 -1
  231. data/lib/rubocop/cop/offense.rb +16 -2
  232. data/lib/rubocop/cop/registry.rb +3 -3
  233. data/lib/rubocop/cop/security/eval.rb +2 -2
  234. data/lib/rubocop/cop/security/json_load.rb +6 -8
  235. data/lib/rubocop/cop/security/marshal_load.rb +2 -4
  236. data/lib/rubocop/cop/security/open.rb +2 -2
  237. data/lib/rubocop/cop/security/yaml_load.rb +6 -6
  238. data/lib/rubocop/cop/style/access_modifier_declarations.rb +16 -9
  239. data/lib/rubocop/cop/style/accessor_grouping.rb +149 -0
  240. data/lib/rubocop/cop/style/alias.rb +41 -36
  241. data/lib/rubocop/cop/style/and_or.rb +9 -11
  242. data/lib/rubocop/cop/style/array_coercion.rb +63 -0
  243. data/lib/rubocop/cop/style/array_join.rb +6 -8
  244. data/lib/rubocop/cop/style/ascii_comments.rb +4 -4
  245. data/lib/rubocop/cop/style/attr.rb +11 -9
  246. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +5 -7
  247. data/lib/rubocop/cop/style/bare_percent_literals.rb +11 -13
  248. data/lib/rubocop/cop/style/begin_block.rb +2 -2
  249. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +141 -0
  250. data/lib/rubocop/cop/style/block_comments.rb +14 -18
  251. data/lib/rubocop/cop/style/block_delimiters.rb +25 -27
  252. data/lib/rubocop/cop/style/case_equality.rb +22 -3
  253. data/lib/rubocop/cop/style/case_like_if.rb +220 -0
  254. data/lib/rubocop/cop/style/class_and_module_children.rb +15 -12
  255. data/lib/rubocop/cop/style/class_check.rb +7 -9
  256. data/lib/rubocop/cop/style/class_methods.rb +7 -11
  257. data/lib/rubocop/cop/style/class_vars.rb +24 -7
  258. data/lib/rubocop/cop/style/collection_methods.rb +11 -17
  259. data/lib/rubocop/cop/style/colon_method_call.rb +8 -9
  260. data/lib/rubocop/cop/style/colon_method_definition.rb +6 -6
  261. data/lib/rubocop/cop/style/command_literal.rb +24 -25
  262. data/lib/rubocop/cop/style/comment_annotation.rb +15 -15
  263. data/lib/rubocop/cop/style/commented_keyword.rb +6 -3
  264. data/lib/rubocop/cop/style/conditional_assignment.rb +12 -3
  265. data/lib/rubocop/cop/style/constant_visibility.rb +3 -2
  266. data/lib/rubocop/cop/style/copyright.rb +15 -15
  267. data/lib/rubocop/cop/style/date_time.rb +2 -2
  268. data/lib/rubocop/cop/style/def_with_parentheses.rb +8 -10
  269. data/lib/rubocop/cop/style/dir.rb +9 -12
  270. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +8 -10
  271. data/lib/rubocop/cop/style/documentation.rb +8 -10
  272. data/lib/rubocop/cop/style/documentation_method.rb +1 -1
  273. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +12 -15
  274. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  275. data/lib/rubocop/cop/style/each_for_simple_loop.rb +5 -8
  276. data/lib/rubocop/cop/style/each_with_object.rb +16 -19
  277. data/lib/rubocop/cop/style/empty_case_condition.rb +27 -26
  278. data/lib/rubocop/cop/style/empty_else.rb +17 -19
  279. data/lib/rubocop/cop/style/empty_literal.rb +20 -21
  280. data/lib/rubocop/cop/style/empty_method.rb +10 -13
  281. data/lib/rubocop/cop/style/encoding.rb +6 -10
  282. data/lib/rubocop/cop/style/end_block.rb +4 -6
  283. data/lib/rubocop/cop/style/eval_with_location.rb +9 -7
  284. data/lib/rubocop/cop/style/even_odd.rb +7 -11
  285. data/lib/rubocop/cop/style/expand_path_arguments.rb +23 -22
  286. data/lib/rubocop/cop/style/explicit_block_argument.rb +102 -0
  287. data/lib/rubocop/cop/style/exponential_notation.rb +9 -11
  288. data/lib/rubocop/cop/style/float_division.rb +8 -11
  289. data/lib/rubocop/cop/style/for.rb +11 -15
  290. data/lib/rubocop/cop/style/format_string.rb +21 -19
  291. data/lib/rubocop/cop/style/format_string_token.rb +10 -12
  292. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +20 -42
  293. data/lib/rubocop/cop/style/global_std_stream.rb +65 -0
  294. data/lib/rubocop/cop/style/global_vars.rb +2 -2
  295. data/lib/rubocop/cop/style/guard_clause.rb +5 -6
  296. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +69 -0
  297. data/lib/rubocop/cop/style/hash_each_methods.rb +5 -8
  298. data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
  299. data/lib/rubocop/cop/style/hash_syntax.rb +4 -3
  300. data/lib/rubocop/cop/style/hash_transform_keys.rb +3 -2
  301. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -1
  302. data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
  303. data/lib/rubocop/cop/style/if_inside_else.rb +2 -2
  304. data/lib/rubocop/cop/style/if_unless_modifier.rb +18 -40
  305. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +11 -3
  306. data/lib/rubocop/cop/style/if_with_semicolon.rb +3 -6
  307. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -1
  308. data/lib/rubocop/cop/style/infinite_loop.rb +24 -24
  309. data/lib/rubocop/cop/style/inline_comment.rb +3 -3
  310. data/lib/rubocop/cop/style/inverse_methods.rb +23 -33
  311. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  312. data/lib/rubocop/cop/style/lambda.rb +7 -12
  313. data/lib/rubocop/cop/style/lambda_call.rb +14 -13
  314. data/lib/rubocop/cop/style/line_end_concatenation.rb +19 -16
  315. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -11
  316. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +4 -8
  317. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -1
  318. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -7
  319. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -2
  320. data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -16
  321. data/lib/rubocop/cop/style/min_max.rb +8 -12
  322. data/lib/rubocop/cop/style/missing_else.rb +11 -21
  323. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +10 -3
  324. data/lib/rubocop/cop/style/mixin_grouping.rb +24 -27
  325. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  326. data/lib/rubocop/cop/style/module_function.rb +10 -13
  327. data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
  328. data/lib/rubocop/cop/style/multiline_if_modifier.rb +3 -10
  329. data/lib/rubocop/cop/style/multiline_if_then.rb +5 -11
  330. data/lib/rubocop/cop/style/multiline_memoization.rb +14 -12
  331. data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -2
  332. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -8
  333. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -9
  334. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  335. data/lib/rubocop/cop/style/mutable_constant.rb +27 -24
  336. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -6
  337. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  338. data/lib/rubocop/cop/style/next.rb +2 -2
  339. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  340. data/lib/rubocop/cop/style/numeric_predicate.rb +7 -4
  341. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +42 -0
  342. data/lib/rubocop/cop/style/parallel_assignment.rb +5 -5
  343. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
  344. data/lib/rubocop/cop/style/proc.rb +1 -1
  345. data/lib/rubocop/cop/style/random_with_offset.rb +5 -10
  346. data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
  347. data/lib/rubocop/cop/style/redundant_condition.rb +15 -3
  348. data/lib/rubocop/cop/style/redundant_exception.rb +18 -10
  349. data/lib/rubocop/cop/style/redundant_fetch_block.rb +122 -0
  350. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
  351. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  352. data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -2
  353. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
  354. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +4 -3
  355. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +23 -32
  356. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  357. data/lib/rubocop/cop/style/redundant_sort.rb +26 -12
  358. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
  359. data/lib/rubocop/cop/style/safe_navigation.rb +4 -4
  360. data/lib/rubocop/cop/style/sample.rb +1 -1
  361. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  362. data/lib/rubocop/cop/style/signal_exception.rb +3 -1
  363. data/lib/rubocop/cop/style/single_argument_dig.rb +54 -0
  364. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  365. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
  366. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  367. data/lib/rubocop/cop/style/string_concatenation.rb +92 -0
  368. data/lib/rubocop/cop/style/struct_inheritance.rb +23 -2
  369. data/lib/rubocop/cop/style/symbol_array.rb +6 -6
  370. data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
  371. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  372. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
  373. data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
  374. data/lib/rubocop/cop/style/word_array.rb +1 -1
  375. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  376. data/lib/rubocop/cop/style/zero_length_predicate.rb +12 -8
  377. data/lib/rubocop/cop/team.rb +98 -82
  378. data/lib/rubocop/cop/tokens_util.rb +84 -0
  379. data/lib/rubocop/cop/util.rb +5 -15
  380. data/lib/rubocop/cop/utils/format_string.rb +2 -3
  381. data/lib/rubocop/cop/variable_force/branch.rb +1 -0
  382. data/lib/rubocop/cop/variable_force/variable.rb +7 -5
  383. data/lib/rubocop/cop/variable_force.rb +0 -2
  384. data/lib/rubocop/cops_documentation_generator.rb +282 -0
  385. data/lib/rubocop/error.rb +1 -0
  386. data/lib/rubocop/file_finder.rb +12 -12
  387. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -3
  388. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  389. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  390. data/lib/rubocop/name_similarity.rb +7 -3
  391. data/lib/rubocop/options.rb +18 -11
  392. data/lib/rubocop/path_util.rb +19 -19
  393. data/lib/rubocop/platform.rb +1 -1
  394. data/lib/rubocop/rake_task.rb +7 -9
  395. data/lib/rubocop/result_cache.rb +12 -8
  396. data/lib/rubocop/rspec/cop_helper.rb +4 -4
  397. data/lib/rubocop/rspec/expect_offense.rb +63 -22
  398. data/lib/rubocop/rspec/shared_contexts.rb +16 -17
  399. data/lib/rubocop/runner.rb +35 -34
  400. data/lib/rubocop/target_finder.rb +14 -11
  401. data/lib/rubocop/target_ruby.rb +2 -2
  402. data/lib/rubocop/version.rb +2 -2
  403. data/lib/rubocop.rb +33 -5
  404. metadata +49 -11
  405. data/lib/rubocop/cop/lint/useless_comparison.rb +0 -28
  406. data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
  407. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +0 -37
  408. data/lib/rubocop/cop/mixin/too_many_lines.rb +0 -35
  409. data/lib/rubocop/cop/style/method_missing_super.rb +0 -34
@@ -40,8 +40,9 @@ module RuboCop
40
40
  # # good
41
41
  # Pathname.new(__dir__).expand_path
42
42
  #
43
- class ExpandPathArguments < Cop
43
+ class ExpandPathArguments < Base
44
44
  include RangeHelp
45
+ extend AutoCorrector
45
46
 
46
47
  MSG = 'Use `expand_path(%<new_path>s%<new_default_dir>s)` instead of ' \
47
48
  '`expand_path(%<current_path>s, __FILE__)`.'
@@ -53,7 +54,7 @@ module RuboCop
53
54
 
54
55
  def_node_matcher :file_expand_path, <<~PATTERN
55
56
  (send
56
- (const nil? :File) :expand_path
57
+ (const {nil? cbase} :File) :expand_path
57
58
  $_
58
59
  $_)
59
60
  PATTERN
@@ -69,49 +70,47 @@ module RuboCop
69
70
  (send
70
71
  (send
71
72
  (send
72
- (const nil? :Pathname) :new
73
+ (const {nil? cbase} :Pathname) :new
73
74
  $_) :parent) :expand_path)
74
75
  PATTERN
75
76
 
76
77
  def on_send(node)
77
- if (captured_values = file_expand_path(node))
78
- current_path, default_dir = captured_values
78
+ return unless node.method?(:expand_path)
79
79
 
80
+ if (current_path, default_dir = file_expand_path(node))
80
81
  inspect_offense_for_expand_path(node, current_path, default_dir)
81
82
  elsif (default_dir = pathname_parent_expand_path(node))
82
83
  return unless unrecommended_argument?(default_dir)
83
84
 
84
- add_offense(node, message: PATHNAME_MSG)
85
+ add_offense(node, message: PATHNAME_MSG) do |corrector|
86
+ autocorrect(corrector, node)
87
+ end
85
88
  elsif (default_dir = pathname_new_parent_expand_path(node))
86
89
  return unless unrecommended_argument?(default_dir)
87
90
 
88
- add_offense(node, message: PATHNAME_NEW_MSG)
91
+ add_offense(node, message: PATHNAME_NEW_MSG) do |corrector|
92
+ autocorrect(corrector, node)
93
+ end
89
94
  end
90
95
  end
91
96
 
92
- def autocorrect(node)
93
- lambda do |corrector|
94
- if (captured_values = file_expand_path(node))
95
- current_path, default_dir = captured_values
97
+ private
96
98
 
97
- autocorrect_expand_path(corrector, current_path, default_dir)
98
- elsif (default_dir = pathname_parent_expand_path(node)) ||
99
- (default_dir = pathname_new_parent_expand_path(node))
100
- corrector.replace(default_dir, '__dir__')
101
- remove_parent_method(corrector, default_dir)
102
- end
99
+ def autocorrect(corrector, node)
100
+ if (current_path, default_dir = file_expand_path(node))
101
+ autocorrect_expand_path(corrector, current_path, default_dir)
102
+ elsif (dir = pathname_parent_expand_path(node) || pathname_new_parent_expand_path(node))
103
+ corrector.replace(dir, '__dir__')
104
+ remove_parent_method(corrector, dir)
103
105
  end
104
106
  end
105
107
 
106
- private
107
-
108
108
  def unrecommended_argument?(default_dir)
109
109
  default_dir.source == '__FILE__'
110
110
  end
111
111
 
112
112
  def inspect_offense_for_expand_path(node, current_path, default_dir)
113
- return unless unrecommended_argument?(default_dir) &&
114
- current_path.str_type?
113
+ return unless unrecommended_argument?(default_dir) && current_path.str_type?
115
114
 
116
115
  current_path = strip_surrounded_quotes!(current_path.source)
117
116
 
@@ -127,7 +126,9 @@ module RuboCop
127
126
  current_path: "'#{current_path}'"
128
127
  )
129
128
 
130
- add_offense(node, location: :selector, message: message)
129
+ add_offense(node.loc.selector, message: message) do |corrector|
130
+ autocorrect(corrector, node)
131
+ end
131
132
  end
132
133
 
133
134
  def autocorrect_expand_path(corrector, current_path, default_dir)
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces the use of explicit block argument to avoid writing
7
+ # block literal that just passes its arguments to another block.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # def with_tmp_dir
12
+ # Dir.mktmpdir do |tmp_dir|
13
+ # Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
14
+ # end
15
+ # end
16
+ #
17
+ # # bad
18
+ # def nine_times
19
+ # 9.times { yield }
20
+ # end
21
+ #
22
+ # # good
23
+ # def with_tmp_dir(&block)
24
+ # Dir.mktmpdir do |tmp_dir|
25
+ # Dir.chdir(tmp_dir, &block)
26
+ # end
27
+ # end
28
+ #
29
+ # with_tmp_dir do |dir|
30
+ # puts "dir is accessible as a parameter and pwd is set: #{dir}"
31
+ # end
32
+ #
33
+ # # good
34
+ # def nine_times(&block)
35
+ # 9.times(&block)
36
+ # end
37
+ #
38
+ class ExplicitBlockArgument < Base
39
+ include RangeHelp
40
+ extend AutoCorrector
41
+
42
+ MSG = 'Consider using explicit block argument in the '\
43
+ "surrounding method's signature over `yield`."
44
+
45
+ def_node_matcher :yielding_block?, <<~PATTERN
46
+ (block $_ (args $...) (yield $...))
47
+ PATTERN
48
+
49
+ def initialize(config = nil, options = nil)
50
+ super
51
+ @def_nodes = Set.new
52
+ end
53
+
54
+ def on_yield(node)
55
+ block_node = node.parent
56
+
57
+ yielding_block?(block_node) do |send_node, block_args, yield_args|
58
+ return unless yielding_arguments?(block_args, yield_args)
59
+
60
+ add_offense(block_node) do |corrector|
61
+ corrector.remove(block_body_range(block_node, send_node))
62
+
63
+ add_block_argument(send_node, corrector)
64
+
65
+ def_node = block_node.each_ancestor(:def, :defs).first
66
+ add_block_argument(def_node, corrector) if @def_nodes.add?(def_node)
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def yielding_arguments?(block_args, yield_args)
74
+ yield_args.zip(block_args).all? do |yield_arg, block_arg|
75
+ block_arg && yield_arg.children.first == block_arg.children.first
76
+ end
77
+ end
78
+
79
+ def add_block_argument(node, corrector)
80
+ if node.arguments?
81
+ last_arg = node.arguments.last
82
+ arg_range = range_with_surrounding_comma(last_arg.source_range, :right)
83
+ replacement = ' &block'
84
+ replacement = ",#{replacement}" unless arg_range.source.end_with?(',')
85
+ corrector.insert_after(arg_range, replacement) unless last_arg.blockarg_type?
86
+ elsif node.send_type?
87
+ corrector.insert_after(node, '(&block)')
88
+ else
89
+ corrector.insert_after(node.loc.name, '(&block)')
90
+ end
91
+ end
92
+
93
+ def block_body_range(block_node, send_node)
94
+ range_between(
95
+ send_node.loc.expression.end_pos,
96
+ block_node.loc.end.end_pos
97
+ )
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -58,8 +58,13 @@ module RuboCop
58
58
  # 1e4
59
59
  # 12e5
60
60
  #
61
- class ExponentialNotation < Cop
61
+ class ExponentialNotation < Base
62
62
  include ConfigurableEnforcedStyle
63
+ MESSAGES = {
64
+ scientific: 'Use a mantissa in [1, 10[.',
65
+ engineering: 'Use an exponent divisible by 3 and a mantissa in [0.1, 1000[.',
66
+ integral: 'Use an integer as mantissa, without trailing zero.'
67
+ }.freeze
63
68
 
64
69
  def on_float(node)
65
70
  add_offense(node) if offense?(node)
@@ -69,7 +74,7 @@ module RuboCop
69
74
 
70
75
  def scientific?(node)
71
76
  mantissa, = node.source.split('e')
72
- mantissa =~ /^-?[1-9](\.\d*[0-9])?$/
77
+ /^-?[1-9](\.\d*[0-9])?$/.match?(mantissa)
73
78
  end
74
79
 
75
80
  def engineering?(node)
@@ -85,7 +90,7 @@ module RuboCop
85
90
 
86
91
  def integral(node)
87
92
  mantissa, = node.source.split('e')
88
- mantissa =~ /^-?[1-9](\d*[1-9])?$/
93
+ /^-?[1-9](\d*[1-9])?$/.match?(mantissa)
89
94
  end
90
95
 
91
96
  def offense?(node)
@@ -104,14 +109,7 @@ module RuboCop
104
109
  end
105
110
 
106
111
  def message(_node)
107
- case style
108
- when :scientific
109
- 'Use a mantissa in [1, 10[.'
110
- when :engineering
111
- 'Use an exponent divisible by 3 and a mantissa in [0.1, 1000[.'
112
- when :integral
113
- 'Use an integer as mantissa, without trailing zero.'
114
- end
112
+ MESSAGES[style]
115
113
  end
116
114
  end
117
115
  end
@@ -39,8 +39,14 @@ module RuboCop
39
39
  #
40
40
  # # good
41
41
  # a.fdiv(b)
42
- class FloatDivision < Cop
42
+ class FloatDivision < Base
43
43
  include ConfigurableEnforcedStyle
44
+ MESSAGES = {
45
+ left_coerce: 'Prefer using `.to_f` on the left side.',
46
+ right_coerce: 'Prefer using `.to_f` on the right side.',
47
+ single_coerce: 'Prefer using `.to_f` on one side only.',
48
+ fdiv: 'Prefer using `fdiv` for float divisions.'
49
+ }.freeze
44
50
 
45
51
  def_node_matcher :right_coerce?, <<~PATTERN
46
52
  (send _ :/ (send _ :to_f))
@@ -77,16 +83,7 @@ module RuboCop
77
83
  end
78
84
 
79
85
  def message(_node)
80
- case style
81
- when :left_coerce
82
- 'Prefer using `.to_f` on the left side.'
83
- when :right_coerce
84
- 'Prefer using `.to_f` on the right side.'
85
- when :single_coerce
86
- 'Prefer using `.to_f` on one side only.'
87
- when :fdiv
88
- 'Prefer using `fdiv` for float divisions.'
89
- end
86
+ MESSAGES[style]
90
87
  end
91
88
  end
92
89
  end
@@ -38,9 +38,10 @@ module RuboCop
38
38
  # end
39
39
  # end
40
40
  #
41
- class For < Cop
41
+ class For < Base
42
42
  include ConfigurableEnforcedStyle
43
43
  include RangeHelp
44
+ extend AutoCorrector
44
45
 
45
46
  EACH_LENGTH = 'each'.length
46
47
  PREFER_EACH = 'Prefer `each` over `for`.'
@@ -48,8 +49,10 @@ module RuboCop
48
49
 
49
50
  def on_for(node)
50
51
  if style == :each
51
- add_offense(node, message: PREFER_EACH) do
52
- opposite_style_detected
52
+ return unless opposite_style_detected
53
+
54
+ add_offense(node, message: PREFER_EACH) do |corrector|
55
+ ForToEachCorrector.new(node).call(corrector)
53
56
  end
54
57
  else
55
58
  correct_style_detected
@@ -60,27 +63,20 @@ module RuboCop
60
63
  return unless suspect_enumerable?(node)
61
64
 
62
65
  if style == :for
63
- add_offense(node, message: PREFER_FOR) do
64
- opposite_style_detected
66
+ return unless opposite_style_detected
67
+
68
+ add_offense(node, message: PREFER_FOR) do |corrector|
69
+ EachToForCorrector.new(node).call(corrector)
65
70
  end
66
71
  else
67
72
  correct_style_detected
68
73
  end
69
74
  end
70
75
 
71
- def autocorrect(node)
72
- if style == :each
73
- ForToEachCorrector.new(node)
74
- else
75
- EachToForCorrector.new(node)
76
- end
77
- end
78
-
79
76
  private
80
77
 
81
78
  def suspect_enumerable?(node)
82
- node.multiline? &&
83
- node.send_node.method?(:each) && !node.send_node.arguments?
79
+ node.multiline? && node.send_node.method?(:each) && !node.send_node.arguments?
84
80
  end
85
81
  end
86
82
  end
@@ -35,11 +35,14 @@ module RuboCop
35
35
  # # good
36
36
  # puts '%10s' % 'hoge'
37
37
  #
38
- class FormatString < Cop
38
+ class FormatString < Base
39
39
  include ConfigurableEnforcedStyle
40
+ extend AutoCorrector
40
41
 
41
42
  MSG = 'Favor `%<prefer>s` over `%<current>s`.'
42
43
 
44
+ FORMAT_METHODS = %i[format sprintf %].freeze
45
+
43
46
  def_node_matcher :formatter, <<~PATTERN
44
47
  {
45
48
  (send nil? ${:sprintf :format} _ _ ...)
@@ -53,46 +56,45 @@ module RuboCop
53
56
  PATTERN
54
57
 
55
58
  def on_send(node)
59
+ return unless FORMAT_METHODS.include?(node.method_name)
60
+
56
61
  formatter(node) do |selector|
57
62
  detected_style = selector == :% ? :percent : selector
58
63
 
59
64
  return if detected_style == style
60
65
 
61
- add_offense(node, location: :selector,
62
- message: message(detected_style))
66
+ add_offense(node.loc.selector, message: message(detected_style)) do |corrector|
67
+ autocorrect(corrector, node)
68
+ end
63
69
  end
64
70
  end
65
71
 
72
+ private
73
+
66
74
  def message(detected_style)
67
- format(MSG,
68
- prefer: method_name(style),
69
- current: method_name(detected_style))
75
+ format(MSG, prefer: method_name(style), current: method_name(detected_style))
70
76
  end
71
77
 
72
78
  def method_name(style_name)
73
79
  style_name == :percent ? 'String#%' : style_name
74
80
  end
75
81
 
76
- def autocorrect(node)
82
+ def autocorrect(corrector, node)
77
83
  return if variable_argument?(node)
78
84
 
79
- lambda do |corrector|
80
- case node.method_name
81
- when :%
82
- autocorrect_from_percent(corrector, node)
85
+ case node.method_name
86
+ when :%
87
+ autocorrect_from_percent(corrector, node)
88
+ when :format, :sprintf
89
+ case style
90
+ when :percent
91
+ autocorrect_to_percent(corrector, node)
83
92
  when :format, :sprintf
84
- case style
85
- when :percent
86
- autocorrect_to_percent(corrector, node)
87
- when :format, :sprintf
88
- corrector.replace(node.loc.selector, style.to_s)
89
- end
93
+ corrector.replace(node.loc.selector, style.to_s)
90
94
  end
91
95
  end
92
96
  end
93
97
 
94
- private
95
-
96
98
  def autocorrect_from_percent(corrector, node)
97
99
  percent_rhs = node.first_argument
98
100
  args = case percent_rhs.type
@@ -37,20 +37,19 @@ module RuboCop
37
37
  #
38
38
  # # good
39
39
  # format('%s', 'Hello')
40
- class FormatStringToken < Cop
40
+ class FormatStringToken < Base
41
41
  include ConfigurableEnforcedStyle
42
42
 
43
43
  def on_str(node)
44
+ return unless node.value.include?('%')
44
45
  return if node.each_ancestor(:xstr, :regexp).any?
45
46
 
46
47
  tokens(node) do |detected_style, token_range|
47
- if detected_style == style ||
48
- unannotated_format?(node, detected_style)
48
+ if detected_style == style || unannotated_format?(node, detected_style)
49
49
  correct_style_detected
50
50
  else
51
51
  style_detected(detected_style)
52
- add_offense(node, location: token_range,
53
- message: message(detected_style))
52
+ add_offense(token_range, message: message(detected_style))
54
53
  end
55
54
  end
56
55
  end
@@ -65,8 +64,7 @@ module RuboCop
65
64
  PATTERN
66
65
 
67
66
  def unannotated_format?(node, detected_style)
68
- detected_style == :unannotated &&
69
- !format_string_in_typical_context?(node)
67
+ detected_style == :unannotated && !format_string_in_typical_context?(node)
70
68
  end
71
69
 
72
70
  def message(detected_style)
@@ -75,11 +73,11 @@ module RuboCop
75
73
 
76
74
  # rubocop:disable Style/FormatStringToken
77
75
  def message_text(style)
78
- case style
79
- when :annotated then 'annotated tokens (like `%<foo>s`)'
80
- when :template then 'template tokens (like `%{foo}`)'
81
- when :unannotated then 'unannotated tokens (like `%s`)'
82
- end
76
+ {
77
+ annotated: 'annotated tokens (like `%<foo>s`)',
78
+ template: 'template tokens (like `%{foo}`)',
79
+ unannotated: 'unannotated tokens (like `%s`)'
80
+ }[style]
83
81
  end
84
82
  # rubocop:enable Style/FormatStringToken
85
83
 
@@ -73,10 +73,11 @@ module RuboCop
73
73
  # module Bar
74
74
  # # ...
75
75
  # end
76
- class FrozenStringLiteralComment < Cop
76
+ class FrozenStringLiteralComment < Base
77
77
  include ConfigurableEnforcedStyle
78
78
  include FrozenStringLiteral
79
79
  include RangeHelp
80
+ extend AutoCorrector
80
81
 
81
82
  MSG_MISSING_TRUE = 'Missing magic comment `# frozen_string_literal: '\
82
83
  'true`.'
@@ -85,7 +86,7 @@ module RuboCop
85
86
  MSG_DISABLED = 'Frozen string literal comment must be set to `true`.'
86
87
  SHEBANG = '#!'
87
88
 
88
- def investigate(processed_source)
89
+ def on_new_investigation
89
90
  return if processed_source.tokens.empty?
90
91
 
91
92
  case style
@@ -98,23 +99,6 @@ module RuboCop
98
99
  end
99
100
  end
100
101
 
101
- def autocorrect(node)
102
- lambda do |corrector|
103
- case style
104
- when :never
105
- remove_comment(corrector, node)
106
- when :always_true
107
- if frozen_string_literal_specified?
108
- enable_comment(corrector)
109
- else
110
- insert_comment(corrector)
111
- end
112
- else
113
- insert_comment(corrector)
114
- end
115
- end
116
- end
117
-
118
102
  private
119
103
 
120
104
  def ensure_no_comment(processed_source)
@@ -148,7 +132,7 @@ module RuboCop
148
132
  end
149
133
 
150
134
  next_token = processed_source.tokens[token_number]
151
- token = next_token if next_token && next_token.text =~ Encoding::ENCODING_PATTERN
135
+ token = next_token if Encoding::ENCODING_PATTERN.match?(next_token&.text)
152
136
 
153
137
  token
154
138
  end
@@ -160,51 +144,45 @@ module RuboCop
160
144
  end
161
145
 
162
146
  def missing_offense(processed_source)
163
- last_special_comment = last_special_comment(processed_source)
164
147
  range = source_range(processed_source.buffer, 0, 0)
165
148
 
166
- add_offense(last_special_comment,
167
- location: range,
168
- message: MSG_MISSING)
149
+ add_offense(range, message: MSG_MISSING) do |corrector|
150
+ insert_comment(corrector)
151
+ end
169
152
  end
170
153
 
171
154
  def missing_true_offense(processed_source)
172
- last_special_comment = last_special_comment(processed_source)
173
155
  range = source_range(processed_source.buffer, 0, 0)
174
156
 
175
- add_offense(last_special_comment,
176
- location: range,
177
- message: MSG_MISSING_TRUE)
157
+ add_offense(range, message: MSG_MISSING_TRUE) do |corrector|
158
+ insert_comment(corrector)
159
+ end
178
160
  end
179
161
 
180
162
  def unnecessary_comment_offense(processed_source)
181
- frozen_string_literal_comment =
182
- frozen_string_literal_comment(processed_source)
163
+ frozen_string_literal_comment = frozen_string_literal_comment(processed_source)
183
164
 
184
- add_offense(frozen_string_literal_comment,
185
- location: frozen_string_literal_comment.pos,
186
- message: MSG_UNNECESSARY)
165
+ add_offense(frozen_string_literal_comment.pos, message: MSG_UNNECESSARY) do |corrector|
166
+ remove_comment(corrector, frozen_string_literal_comment)
167
+ end
187
168
  end
188
169
 
189
170
  def disabled_offense(processed_source)
190
- frozen_string_literal_comment =
191
- frozen_string_literal_comment(processed_source)
171
+ frozen_string_literal_comment = frozen_string_literal_comment(processed_source)
192
172
 
193
- add_offense(frozen_string_literal_comment,
194
- location: frozen_string_literal_comment.pos,
195
- message: MSG_DISABLED)
173
+ add_offense(frozen_string_literal_comment.pos, message: MSG_DISABLED) do |corrector|
174
+ enable_comment(corrector)
175
+ end
196
176
  end
197
177
 
198
178
  def remove_comment(corrector, node)
199
- corrector.remove(range_with_surrounding_space(range: node.pos,
200
- side: :right))
179
+ corrector.remove(range_with_surrounding_space(range: node.pos, side: :right))
201
180
  end
202
181
 
203
182
  def enable_comment(corrector)
204
183
  comment = frozen_string_literal_comment(processed_source)
205
184
 
206
- corrector.replace(line_range(comment.line),
207
- FROZEN_STRING_LITERAL_ENABLED)
185
+ corrector.replace(line_range(comment.line), FROZEN_STRING_LITERAL_ENABLED)
208
186
  end
209
187
 
210
188
  def insert_comment(corrector)
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces the use of `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.
7
+ # `STDOUT/STDERR/STDIN` are constants, and while you can actually
8
+ # reassign (possibly to redirect some stream) constants in Ruby, you'll get
9
+ # an interpreter warning if you do so.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # STDOUT.puts('hello')
14
+ #
15
+ # hash = { out: STDOUT, key: value }
16
+ #
17
+ # def m(out = STDOUT)
18
+ # out.puts('hello')
19
+ # end
20
+ #
21
+ # # good
22
+ # $stdout.puts('hello')
23
+ #
24
+ # hash = { out: $stdout, key: value }
25
+ #
26
+ # def m(out = $stdout)
27
+ # out.puts('hello')
28
+ # end
29
+ #
30
+ class GlobalStdStream < Base
31
+ extend AutoCorrector
32
+
33
+ MSG = 'Use `%<gvar_name>s` instead of `%<const_name>s`.'
34
+
35
+ STD_STREAMS = %i[STDIN STDOUT STDERR].to_set.freeze
36
+
37
+ def_node_matcher :const_to_gvar_assignment?, <<~PATTERN
38
+ (gvasgn %1 (const nil? _))
39
+ PATTERN
40
+
41
+ def on_const(node)
42
+ const_name = node.children[1]
43
+ return unless STD_STREAMS.include?(const_name)
44
+
45
+ gvar_name = gvar_name(const_name).to_sym
46
+ return if const_to_gvar_assignment?(node.parent, gvar_name)
47
+
48
+ add_offense(node, message: message(const_name)) do |corrector|
49
+ corrector.replace(node, gvar_name)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def message(const_name)
56
+ format(MSG, gvar_name: gvar_name(const_name), const_name: const_name)
57
+ end
58
+
59
+ def gvar_name(const_name)
60
+ "$#{const_name.to_s.downcase}"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # FOO = 2
20
20
  # foo = 2
21
21
  # $stdin.read
22
- class GlobalVars < Cop
22
+ class GlobalVars < Base
23
23
  MSG = 'Do not introduce global variables.'
24
24
 
25
25
  # built-in global variables and their English aliases
@@ -72,7 +72,7 @@ module RuboCop
72
72
  def check(node)
73
73
  global_var, = *node
74
74
 
75
- add_offense(node, location: :name) unless allowed_var?(global_var)
75
+ add_offense(node.loc.name) unless allowed_var?(global_var)
76
76
  end
77
77
  end
78
78
  end