rubocop 0.49.1 → 0.50.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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/bin/rubocop +1 -1
  4. data/config/default.yml +160 -99
  5. data/config/disabled.yml +4 -5
  6. data/config/enabled.yml +149 -47
  7. data/lib/rubocop.rb +41 -14
  8. data/lib/rubocop/ast/builder.rb +4 -1
  9. data/lib/rubocop/ast/node.rb +36 -42
  10. data/lib/rubocop/ast/node/args_node.rb +1 -13
  11. data/lib/rubocop/ast/node/array_node.rb +9 -0
  12. data/lib/rubocop/ast/node/block_node.rb +9 -0
  13. data/lib/rubocop/ast/node/def_node.rb +71 -0
  14. data/lib/rubocop/ast/node/for_node.rb +8 -0
  15. data/lib/rubocop/ast/node/if_node.rb +10 -2
  16. data/lib/rubocop/ast/node/mixin/collection_node.rb +15 -0
  17. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +174 -0
  18. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +89 -0
  19. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +18 -31
  20. data/lib/rubocop/ast/node/regexp_node.rb +35 -0
  21. data/lib/rubocop/ast/node/send_node.rb +1 -154
  22. data/lib/rubocop/ast/node/super_node.rb +3 -24
  23. data/lib/rubocop/ast/node/yield_node.rb +21 -0
  24. data/lib/rubocop/ast/traversal.rb +6 -6
  25. data/lib/rubocop/cli.rb +7 -3
  26. data/lib/rubocop/config.rb +45 -8
  27. data/lib/rubocop/config_loader.rb +7 -5
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -3
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +64 -0
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +12 -12
  31. data/lib/rubocop/cop/commissioner.rb +8 -2
  32. data/lib/rubocop/cop/cop.rb +3 -1
  33. data/lib/rubocop/cop/generator.rb +94 -21
  34. data/lib/rubocop/cop/internal_affairs.rb +3 -0
  35. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +14 -3
  36. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +43 -0
  37. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +46 -0
  38. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +49 -0
  39. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +1 -1
  40. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +2 -3
  41. data/lib/rubocop/cop/layout/align_array.rb +2 -2
  42. data/lib/rubocop/cop/layout/align_hash.rb +2 -2
  43. data/lib/rubocop/cop/layout/align_parameters.rb +5 -11
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  46. data/lib/rubocop/cop/layout/dot_position.rb +9 -0
  47. data/lib/rubocop/cop/layout/else_alignment.rb +30 -13
  48. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +4 -0
  49. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +20 -4
  50. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -3
  51. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -3
  52. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +3 -3
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +5 -2
  54. data/lib/rubocop/cop/layout/indent_heredoc.rb +19 -24
  55. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -2
  56. data/lib/rubocop/cop/layout/indentation_width.rb +12 -8
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -18
  58. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +20 -17
  59. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +3 -3
  60. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -0
  61. data/lib/rubocop/cop/layout/space_after_colon.rb +7 -0
  62. data/lib/rubocop/cop/layout/space_after_comma.rb +10 -0
  63. data/lib/rubocop/cop/layout/space_after_method_name.rb +5 -3
  64. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  65. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +13 -4
  66. data/lib/rubocop/cop/layout/space_around_keyword.rb +9 -5
  67. data/lib/rubocop/cop/layout/space_before_block_braces.rb +54 -5
  68. data/lib/rubocop/cop/layout/space_before_comment.rb +7 -0
  69. data/lib/rubocop/cop/layout/space_before_semicolon.rb +7 -0
  70. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +1 -1
  71. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  73. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +8 -4
  74. data/lib/rubocop/cop/layout/tab.rb +1 -1
  75. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +4 -2
  76. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  77. data/lib/rubocop/cop/lint/block_alignment.rb +15 -6
  78. data/lib/rubocop/cop/lint/boolean_symbol.rb +38 -0
  79. data/lib/rubocop/cop/lint/condition_position.rb +5 -1
  80. data/lib/rubocop/cop/lint/debugger.rb +16 -9
  81. data/lib/rubocop/cop/lint/def_end_alignment.rb +4 -4
  82. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +3 -3
  83. data/lib/rubocop/cop/lint/duplicate_methods.rb +73 -5
  84. data/lib/rubocop/cop/lint/duplicated_key.rb +1 -1
  85. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  86. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  87. data/lib/rubocop/cop/lint/empty_expression.rb +1 -1
  88. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  89. data/lib/rubocop/cop/lint/empty_when.rb +1 -1
  90. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  91. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -5
  92. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +35 -40
  93. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  94. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +18 -13
  95. data/lib/rubocop/cop/lint/inherit_exception.rb +8 -7
  96. data/lib/rubocop/cop/lint/interpolation_check.rb +36 -0
  97. data/lib/rubocop/cop/lint/literal_in_condition.rb +3 -3
  98. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  99. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  100. data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -7
  101. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  102. data/lib/rubocop/cop/lint/percent_string_array.rb +3 -12
  103. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  104. data/lib/rubocop/cop/lint/rand_one.rb +7 -1
  105. data/lib/rubocop/cop/lint/redundant_with_index.rb +77 -0
  106. data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
  107. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  108. data/lib/rubocop/cop/lint/rescue_type.rb +13 -6
  109. data/lib/rubocop/cop/lint/rescue_without_error_class.rb +38 -0
  110. data/lib/rubocop/cop/lint/return_in_void_context.rb +63 -0
  111. data/lib/rubocop/cop/lint/script_permission.rb +6 -0
  112. data/lib/rubocop/cop/lint/syntax.rb +17 -20
  113. data/lib/rubocop/cop/lint/unified_integer.rb +3 -2
  114. data/lib/rubocop/cop/lint/unneeded_disable.rb +1 -1
  115. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  116. data/lib/rubocop/cop/lint/unreachable_code.rb +53 -8
  117. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +74 -0
  118. data/lib/rubocop/cop/lint/uri_regexp.rb +73 -0
  119. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -8
  120. data/lib/rubocop/cop/lint/useless_setter_call.rb +10 -11
  121. data/lib/rubocop/cop/lint/void.rb +29 -23
  122. data/lib/rubocop/cop/metrics/line_length.rb +2 -2
  123. data/lib/rubocop/cop/metrics/method_length.rb +8 -3
  124. data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
  125. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +1 -1
  126. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -2
  127. data/lib/rubocop/cop/mixin/first_element_line_break.rb +12 -3
  128. data/lib/rubocop/cop/mixin/heredoc.rb +28 -0
  129. data/lib/rubocop/cop/mixin/method_complexity.rb +9 -6
  130. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +68 -31
  131. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +18 -0
  132. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  133. data/lib/rubocop/cop/mixin/percent_array.rb +52 -0
  134. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  135. data/lib/rubocop/cop/{style → naming}/accessor_method_name.rb +11 -12
  136. data/lib/rubocop/cop/{style → naming}/ascii_identifiers.rb +1 -1
  137. data/lib/rubocop/cop/{style/op_method.rb → naming/binary_operator_parameter_name.rb} +2 -2
  138. data/lib/rubocop/cop/{style → naming}/class_and_module_camel_case.rb +1 -1
  139. data/lib/rubocop/cop/{style → naming}/constant_name.rb +1 -1
  140. data/lib/rubocop/cop/{style → naming}/file_name.rb +8 -4
  141. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +68 -0
  142. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +58 -0
  143. data/lib/rubocop/cop/{style → naming}/method_name.rb +1 -1
  144. data/lib/rubocop/cop/{style → naming}/predicate_name.rb +6 -7
  145. data/lib/rubocop/cop/{style → naming}/variable_name.rb +11 -15
  146. data/lib/rubocop/cop/{style → naming}/variable_number.rb +1 -1
  147. data/lib/rubocop/cop/performance/caller.rb +39 -11
  148. data/lib/rubocop/cop/performance/casecmp.rb +4 -4
  149. data/lib/rubocop/cop/performance/compare_with_block.rb +4 -4
  150. data/lib/rubocop/cop/performance/double_start_end_with.rb +4 -4
  151. data/lib/rubocop/cop/performance/end_with.rb +3 -3
  152. data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
  153. data/lib/rubocop/cop/performance/hash_each_methods.rb +66 -25
  154. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
  155. data/lib/rubocop/cop/performance/range_include.rb +2 -2
  156. data/lib/rubocop/cop/performance/redundant_block_call.rb +6 -6
  157. data/lib/rubocop/cop/performance/redundant_match.rb +5 -5
  158. data/lib/rubocop/cop/performance/redundant_merge.rb +39 -23
  159. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -2
  160. data/lib/rubocop/cop/performance/regexp_match.rb +13 -5
  161. data/lib/rubocop/cop/performance/size.rb +1 -1
  162. data/lib/rubocop/cop/performance/start_with.rb +3 -3
  163. data/lib/rubocop/cop/performance/times_map.rb +23 -12
  164. data/lib/rubocop/cop/performance/unfreeze_string.rb +50 -0
  165. data/lib/rubocop/cop/performance/uri_default_parser.rb +47 -0
  166. data/lib/rubocop/cop/rails/active_support_aliases.rb +1 -1
  167. data/lib/rubocop/cop/rails/delegate.rb +36 -7
  168. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +1 -1
  169. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -2
  170. data/lib/rubocop/cop/rails/file_path.rb +3 -4
  171. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  172. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +48 -0
  173. data/lib/rubocop/cop/rails/http_positional_arguments.rb +5 -5
  174. data/lib/rubocop/cop/rails/not_null_column.rb +1 -1
  175. data/lib/rubocop/cop/rails/pluralization_grammar.rb +2 -2
  176. data/lib/rubocop/cop/rails/relative_date_constant.rb +1 -1
  177. data/lib/rubocop/cop/rails/request_referer.rb +2 -2
  178. data/lib/rubocop/cop/rails/reversible_migration.rb +12 -12
  179. data/lib/rubocop/cop/rails/save_bang.rb +8 -6
  180. data/lib/rubocop/cop/rails/scope_args.rb +1 -1
  181. data/lib/rubocop/cop/security/eval.rb +2 -2
  182. data/lib/rubocop/cop/security/json_load.rb +2 -2
  183. data/lib/rubocop/cop/security/marshal_load.rb +2 -2
  184. data/lib/rubocop/cop/security/yaml_load.rb +2 -2
  185. data/lib/rubocop/cop/style/alias.rb +44 -20
  186. data/lib/rubocop/cop/style/and_or.rb +48 -34
  187. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +1 -1
  188. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  189. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  190. data/lib/rubocop/cop/style/command_literal.rb +20 -9
  191. data/lib/rubocop/cop/style/conditional_assignment.rb +30 -28
  192. data/lib/rubocop/cop/style/copyright.rb +10 -10
  193. data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -5
  194. data/lib/rubocop/cop/style/dir.rb +52 -0
  195. data/lib/rubocop/cop/style/documentation_method.rb +2 -6
  196. data/lib/rubocop/cop/style/empty_case_condition.rb +1 -1
  197. data/lib/rubocop/cop/style/empty_else.rb +3 -2
  198. data/lib/rubocop/cop/style/empty_literal.rb +1 -2
  199. data/lib/rubocop/cop/style/empty_method.rb +27 -17
  200. data/lib/rubocop/cop/style/flip_flop.rb +2 -2
  201. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  202. data/lib/rubocop/cop/style/guard_clause.rb +4 -2
  203. data/lib/rubocop/cop/style/hash_syntax.rb +10 -10
  204. data/lib/rubocop/cop/style/identical_conditional_branches.rb +5 -1
  205. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
  206. data/lib/rubocop/cop/style/implicit_runtime_error.rb +4 -3
  207. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  208. data/lib/rubocop/cop/style/inverse_methods.rb +20 -8
  209. data/lib/rubocop/cop/style/lambda.rb +19 -9
  210. data/lib/rubocop/cop/style/lambda_call.rb +22 -1
  211. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -20
  212. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -4
  213. data/lib/rubocop/cop/style/method_def_parentheses.rb +18 -26
  214. data/lib/rubocop/cop/style/method_missing.rb +5 -18
  215. data/lib/rubocop/cop/style/min_max.rb +67 -0
  216. data/lib/rubocop/cop/style/missing_else.rb +16 -3
  217. data/lib/rubocop/cop/style/mixin_grouping.rb +2 -2
  218. data/lib/rubocop/cop/style/module_function.rb +8 -4
  219. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -1
  220. data/lib/rubocop/cop/style/multiline_memoization.rb +25 -3
  221. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  222. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  223. data/lib/rubocop/cop/style/mutable_constant.rb +2 -6
  224. data/lib/rubocop/cop/style/negated_if.rb +8 -4
  225. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +8 -8
  226. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  227. data/lib/rubocop/cop/style/non_nil_check.rb +14 -14
  228. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +6 -2
  229. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  230. data/lib/rubocop/cop/style/numeric_predicate.rb +8 -4
  231. data/lib/rubocop/cop/style/one_line_conditional.rb +8 -3
  232. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  233. data/lib/rubocop/cop/style/optional_arguments.rb +1 -2
  234. data/lib/rubocop/cop/style/or_assignment.rb +88 -0
  235. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  236. data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -11
  237. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  238. data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
  239. data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
  240. data/lib/rubocop/cop/style/proc.rb +1 -1
  241. data/lib/rubocop/cop/style/raise_args.rb +16 -17
  242. data/lib/rubocop/cop/style/redundant_begin.rb +6 -5
  243. data/lib/rubocop/cop/style/redundant_conditional.rb +95 -0
  244. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  245. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -11
  246. data/lib/rubocop/cop/style/redundant_return.rb +23 -11
  247. data/lib/rubocop/cop/style/redundant_self.rb +18 -9
  248. data/lib/rubocop/cop/style/regexp_literal.rb +12 -4
  249. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  250. data/lib/rubocop/cop/style/return_nil.rb +98 -0
  251. data/lib/rubocop/cop/style/safe_navigation.rb +80 -43
  252. data/lib/rubocop/cop/style/single_line_block_params.rb +14 -13
  253. data/lib/rubocop/cop/style/single_line_methods.rb +9 -13
  254. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  255. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +17 -39
  256. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +22 -1
  257. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  258. data/lib/rubocop/cop/style/symbol_array.rb +5 -25
  259. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  260. data/lib/rubocop/cop/style/symbol_proc.rb +3 -18
  261. data/lib/rubocop/cop/style/ternary_parentheses.rb +14 -10
  262. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +28 -9
  263. data/lib/rubocop/cop/style/trivial_accessors.rb +39 -56
  264. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  265. data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -1
  266. data/lib/rubocop/cop/style/unneeded_interpolation.rb +1 -1
  267. data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
  268. data/lib/rubocop/cop/style/variable_interpolation.rb +8 -3
  269. data/lib/rubocop/cop/style/word_array.rb +7 -24
  270. data/lib/rubocop/cop/style/yoda_condition.rb +49 -14
  271. data/lib/rubocop/cop/style/zero_length_predicate.rb +25 -18
  272. data/lib/rubocop/cop/team.rb +16 -8
  273. data/lib/rubocop/cop/util.rb +11 -0
  274. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  275. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  276. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -0
  277. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  278. data/lib/rubocop/formatter/tap_formatter.rb +71 -0
  279. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -0
  280. data/lib/rubocop/node_pattern.rb +44 -26
  281. data/lib/rubocop/options.rb +1 -0
  282. data/lib/rubocop/processed_source.rb +3 -1
  283. data/lib/rubocop/remote_config.rb +5 -1
  284. data/lib/rubocop/result_cache.rb +1 -0
  285. data/lib/rubocop/rspec/cop_helper.rb +10 -10
  286. data/lib/rubocop/rspec/expect_offense.rb +6 -8
  287. data/lib/rubocop/rspec/shared_examples.rb +8 -8
  288. data/lib/rubocop/string_util.rb +2 -0
  289. data/lib/rubocop/version.rb +1 -1
  290. metadata +51 -18
  291. data/lib/rubocop/cop/mixin/access_modifier_node.rb +0 -41
  292. data/lib/rubocop/cop/mixin/on_method_def.rb +0 -44
@@ -16,10 +16,10 @@ module RuboCop
16
16
  class LstripRstrip < Cop
17
17
  MSG = 'Use `strip` instead of `%s.%s`.'.freeze
18
18
 
19
- def_node_matcher :lstrip_rstrip, <<-END
19
+ def_node_matcher :lstrip_rstrip, <<-PATTERN
20
20
  {(send $(send _ $:rstrip) $:lstrip)
21
21
  (send $(send _ $:lstrip) $:rstrip)}
22
- END
22
+ PATTERN
23
23
 
24
24
  def on_send(node)
25
25
  lstrip_rstrip(node) do |first_send, method_one, method_two|
@@ -22,9 +22,9 @@ module RuboCop
22
22
  # Right now, we only detect direct calls on a Range literal
23
23
  # (We don't even catch it if the Range is in double parens)
24
24
 
25
- def_node_matcher :range_include, <<-END
25
+ def_node_matcher :range_include, <<-PATTERN
26
26
  (send {irange erange (begin {irange erange})} :include? ...)
27
- END
27
+ PATTERN
28
28
 
29
29
  def on_send(node)
30
30
  return unless range_include(node)
@@ -29,18 +29,18 @@ module RuboCop
29
29
  CLOSE_PAREN = ')'.freeze
30
30
  SPACE = ' '.freeze
31
31
 
32
- def_node_matcher :blockarg_def, <<-END
32
+ def_node_matcher :blockarg_def, <<-PATTERN
33
33
  {(def _ (args ... (blockarg $_)) $_)
34
34
  (defs _ _ (args ... (blockarg $_)) $_)}
35
- END
35
+ PATTERN
36
36
 
37
- def_node_search :blockarg_calls, <<-END
37
+ def_node_search :blockarg_calls, <<-PATTERN
38
38
  (send (lvar %1) :call ...)
39
- END
39
+ PATTERN
40
40
 
41
- def_node_search :blockarg_assigned?, <<-END
41
+ def_node_search :blockarg_assigned?, <<-PATTERN
42
42
  (lvasgn %1 ...)
43
- END
43
+ PATTERN
44
44
 
45
45
  def on_def(node)
46
46
  blockarg_def(node) do |argname, body|
@@ -22,21 +22,21 @@ module RuboCop
22
22
 
23
23
  # 'match' is a fairly generic name, so we don't flag it unless we see
24
24
  # a string or regexp literal on one side or the other
25
- def_node_matcher :match_call?, <<-END
25
+ def_node_matcher :match_call?, <<-PATTERN
26
26
  {(send {str regexp} :match _)
27
27
  (send !nil :match {str regexp})}
28
- END
28
+ PATTERN
29
29
 
30
- def_node_matcher :only_truthiness_matters?, <<-END
30
+ def_node_matcher :only_truthiness_matters?, <<-PATTERN
31
31
  ^({if while until case while_post until_post} equal?(%0) ...)
32
- END
32
+ PATTERN
33
33
 
34
34
  def on_send(node)
35
35
  return unless match_call?(node) &&
36
36
  (!node.value_used? || only_truthiness_matters?(node)) &&
37
37
  !(node.parent && node.parent.block_type?)
38
38
 
39
- add_offense(node, :expression)
39
+ add_offense(node)
40
40
  end
41
41
 
42
42
  def autocorrect(node)
@@ -14,28 +14,26 @@ module RuboCop
14
14
  AREF_ASGN = '%s[%s] = %s'.freeze
15
15
  MSG = 'Use `%s` instead of `%s`.'.freeze
16
16
 
17
- def_node_matcher :redundant_merge, '(send $_ :merge! (hash $...))'
18
- def_node_matcher :modifier_flow_control?, <<-END
17
+ def_node_matcher :redundant_merge_candidate, <<-PATTERN
18
+ (send $!nil :merge! [(hash $...) !kwsplat_type?])
19
+ PATTERN
20
+
21
+ def_node_matcher :modifier_flow_control?, <<-PATTERN
19
22
  [{if while until} modifier_form?]
20
- END
23
+ PATTERN
21
24
 
22
25
  def on_send(node)
23
- each_redundant_merge(node) do |receiver, pairs|
24
- return if pairs.any?(&:kwsplat_type?)
25
-
26
- assignments = to_assignments(receiver, pairs).join('; ')
27
- message = format(MSG, assignments, node.source)
28
- add_offense(node, :expression, message)
26
+ each_redundant_merge(node) do |redundant_merge_node|
27
+ add_offense(redundant_merge_node)
29
28
  end
30
29
  end
31
30
 
32
31
  def autocorrect(node)
33
- redundant_merge(node) do |receiver, pairs|
32
+ redundant_merge_candidate(node) do |receiver, pairs|
34
33
  new_source = to_assignments(receiver, pairs).join("\n")
35
34
 
36
- parent = node.parent
37
- if parent && pairs.size > 1
38
- correct_multiple_elements(node, parent, new_source)
35
+ if node.parent && pairs.size > 1
36
+ correct_multiple_elements(node, node.parent, new_source)
39
37
  else
40
38
  correct_single_element(node, new_source)
41
39
  end
@@ -44,18 +42,36 @@ module RuboCop
44
42
 
45
43
  private
46
44
 
45
+ def message(node)
46
+ redundant_merge_candidate(node) do |receiver, pairs|
47
+ assignments = to_assignments(receiver, pairs).join('; ')
48
+
49
+ format(MSG, assignments, node.source)
50
+ end
51
+ end
52
+
47
53
  def each_redundant_merge(node)
48
- redundant_merge(node) do |receiver, pairs|
49
- next unless receiver
50
- next if node.value_used? &&
51
- !EachWithObjectInspector.new(node, receiver).value_used?
52
- next if pairs.size > 1 && !receiver.pure?
53
- next if pairs.size > max_key_value_pairs
54
-
55
- yield receiver, pairs
54
+ redundant_merge_candidate(node) do |receiver, pairs|
55
+ next if non_redundant_merge?(node, receiver, pairs)
56
+
57
+ yield node
56
58
  end
57
59
  end
58
60
 
61
+ def non_redundant_merge?(node, receiver, pairs)
62
+ non_redundant_pairs?(receiver, pairs) ||
63
+ non_redundant_value_used?(receiver, node)
64
+ end
65
+
66
+ def non_redundant_pairs?(receiver, pairs)
67
+ pairs.size > 1 && !receiver.pure? || pairs.size > max_key_value_pairs
68
+ end
69
+
70
+ def non_redundant_value_used?(receiver, node)
71
+ node.value_used? &&
72
+ !EachWithObjectInspector.new(node, receiver).value_used?
73
+ end
74
+
59
75
  def correct_multiple_elements(node, parent, new_source)
60
76
  if modifier_flow_control?(parent)
61
77
  new_source = rewrite_with_modifier(node, parent, new_source)
@@ -141,9 +157,9 @@ module RuboCop
141
157
  receiver
142
158
  end
143
159
 
144
- def_node_matcher :each_with_object_node, <<-END
160
+ def_node_matcher :each_with_object_node, <<-PATTERN
145
161
  (block (send _ :each_with_object _) (args _ $_) ...)
146
- END
162
+ PATTERN
147
163
  end
148
164
  end
149
165
  end
@@ -18,9 +18,9 @@ module RuboCop
18
18
  class RedundantSortBy < Cop
19
19
  MSG = 'Use `sort` instead of `sort_by { |%s| %s }`.'.freeze
20
20
 
21
- def_node_matcher :redundant_sort_by, <<-END
21
+ def_node_matcher :redundant_sort_by, <<-PATTERN
22
22
  (block $(send _ :sort_by) (args (arg $_x)) (lvar _x))
23
- END
23
+ PATTERN
24
24
 
25
25
  def on_block(node)
26
26
  redundant_sort_by(node) do |send, var_name|
@@ -81,9 +81,11 @@ module RuboCop
81
81
  (send (regexp (str _) {(regopt) (regopt _)}) :=== !nil)
82
82
  PATTERN
83
83
 
84
- def_node_matcher :match_with_lvasgn?, <<-PATTERN
85
- (match_with_lvasgn !nil !nil)
86
- PATTERN
84
+ def match_with_lvasgn?(node)
85
+ return false unless node.match_with_lvasgn_type?
86
+ regexp, _rhs = *node
87
+ regexp.to_regexp.named_captures.empty?
88
+ end
87
89
 
88
90
  MATCH_NODE_PATTERN = <<-PATTERN.freeze
89
91
  {
@@ -139,11 +141,15 @@ module RuboCop
139
141
  def check_condition(cond)
140
142
  match_node?(cond) do
141
143
  return if last_match_used?(cond)
142
- add_offense(cond, :expression,
143
- format(MSG, cond.loc.selector.source))
144
+
145
+ add_offense(cond)
144
146
  end
145
147
  end
146
148
 
149
+ def message(node)
150
+ format(MSG, node.loc.selector.source)
151
+ end
152
+
147
153
  def last_match_used?(match_node)
148
154
  scope_root = scope_root(match_node)
149
155
  body = scope_root ? scope_body(scope_root) : match_node.ancestors.last
@@ -176,6 +182,8 @@ module RuboCop
176
182
  case node.type
177
183
  when :module
178
184
  children[1]
185
+ when :defs
186
+ children[3]
179
187
  else
180
188
  children[2]
181
189
  end
@@ -29,7 +29,7 @@ module RuboCop
29
29
  def on_send(node)
30
30
  return unless eligible_node?(node)
31
31
 
32
- add_offense(node, node.loc.selector)
32
+ add_offense(node, :selector)
33
33
  end
34
34
 
35
35
  private
@@ -18,10 +18,10 @@ module RuboCop
18
18
  'the beginning of the string.'.freeze
19
19
  SINGLE_QUOTE = "'".freeze
20
20
 
21
- def_node_matcher :redundant_regex?, <<-END
21
+ def_node_matcher :redundant_regex?, <<-PATTERN
22
22
  {(send $!nil {:match :=~} (regexp (str $#literal_at_start?) (regopt)))
23
23
  (send (regexp (str $#literal_at_start?) (regopt)) {:match :=~} $_)}
24
- END
24
+ PATTERN
25
25
 
26
26
  def literal_at_start?(regex_str)
27
27
  # is this regexp 'literal' in the sense of only matching literal
@@ -36,7 +36,7 @@ module RuboCop
36
36
  def on_send(node)
37
37
  return unless redundant_regex?(node)
38
38
 
39
- add_offense(node, :expression)
39
+ add_offense(node)
40
40
  end
41
41
 
42
42
  def autocorrect(node)
@@ -19,7 +19,9 @@ module RuboCop
19
19
  # i.to_s
20
20
  # end
21
21
  class TimesMap < Cop
22
- MSG = 'Use `Array.new` with a block instead of `.times.%s`.'.freeze
22
+ MESSAGE = 'Use `Array.new(%<count>s)` with a block ' \
23
+ 'instead of `.times.%<map_or_collect>s`'.freeze
24
+ MESSAGE_ONLY_IF = 'only if `%<count>s` is always 0 or more'.freeze
23
25
 
24
26
  def on_send(node)
25
27
  check(node)
@@ -32,27 +34,36 @@ module RuboCop
32
34
  private
33
35
 
34
36
  def check(node)
35
- times_map_call(node) do |map_or_collect|
36
- add_offense(node, :expression, format(MSG, map_or_collect))
37
+ times_map_call(node) do |map_or_collect, count|
38
+ add_offense(node, :expression, message(map_or_collect, count))
37
39
  end
38
40
  end
39
41
 
40
- def_node_matcher :times_map_call, <<-END
41
- {(block (send (send !nil :times) ${:map :collect}) ...)
42
- (send (send !nil :times) ${:map :collect} (block_pass ...))}
43
- END
42
+ def message(map_or_collect, count)
43
+ template = if count.literal?
44
+ MESSAGE + '.'
45
+ else
46
+ "#{MESSAGE} #{MESSAGE_ONLY_IF}."
47
+ end
48
+ format(template,
49
+ count: count.source,
50
+ map_or_collect: map_or_collect.method_name)
51
+ end
44
52
 
45
- def autocorrect(node)
46
- send_node = node.send_type? ? node : node.each_descendant(:send).first
53
+ def_node_matcher :times_map_call, <<-PATTERN
54
+ {(block $(send (send $!nil :times) {:map :collect}) ...)
55
+ $(send (send $!nil :times) {:map :collect} (block_pass ...))}
56
+ PATTERN
47
57
 
48
- count, = *send_node.receiver
58
+ def autocorrect(node)
59
+ map_or_collect, count = times_map_call(node)
49
60
 
50
61
  replacement =
51
62
  "Array.new(#{count.source}" \
52
- "#{send_node.arguments.map { |arg| ", #{arg.source}" }.join})"
63
+ "#{map_or_collect.arguments.map { |arg| ", #{arg.source}" }.join})"
53
64
 
54
65
  lambda do |corrector|
55
- corrector.replace(send_node.loc.expression, replacement)
66
+ corrector.replace(map_or_collect.loc.expression, replacement)
56
67
  end
57
68
  end
58
69
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # In Ruby 2.3 or later, use unary plus operator to unfreeze a string
7
+ # literal instead of `String#dup` and `String.new`.
8
+ # Unary plus operator is faster than `String#dup`.
9
+ #
10
+ # Note: `String.new` (without operator) is not exactly the same as `+''`.
11
+ # These differ in encoding. `String.new.encoding` is always `ASCII-8BIT`.
12
+ # However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`).
13
+ # So, if you expect `ASCII-8BIT` encoding, disable this cop.
14
+ #
15
+ # @example
16
+ # # bad
17
+ # ''.dup
18
+ # "something".dup
19
+ # String.new
20
+ # String.new('')
21
+ # String.new('something')
22
+ #
23
+ # # good
24
+ # +'something'
25
+ # +''
26
+ class UnfreezeString < Cop
27
+ extend TargetRubyVersion
28
+
29
+ minimum_target_ruby_version 2.3
30
+
31
+ MSG = 'Use unary plus to get an unfrozen string literal.'.freeze
32
+
33
+ def_node_matcher :dup_string?, <<-PATTERN
34
+ (send {str dstr} :dup)
35
+ PATTERN
36
+
37
+ def_node_matcher :string_new?, <<-PATTERN
38
+ {
39
+ (send (const nil :String) :new {str dstr})
40
+ (send (const nil :String) :new)
41
+ }
42
+ PATTERN
43
+
44
+ def on_send(node)
45
+ add_offense(node) if dup_string?(node) || string_new?(node)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Performance
6
+ # This cop identifies places where `URI::Parser.new`
7
+ # can be replaced by `URI::DEFAULT_PARSER`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # URI::Parser.new
12
+ #
13
+ # # good
14
+ # URI::DEFAULT_PARSER
15
+ #
16
+ class UriDefaultParser < Cop
17
+ MSG = 'Use `%sURI::DEFAULT_PARSER` instead of ' \
18
+ '`%sURI::Parser.new`.'.freeze
19
+
20
+ def_node_matcher :uri_parser_new?, <<-PATTERN
21
+ (send
22
+ (const
23
+ (const ${nil cbase} :URI) :Parser) :new)
24
+ PATTERN
25
+
26
+ def on_send(node)
27
+ return unless uri_parser_new?(node) do |captured_value|
28
+ double_colon = captured_value ? '::' : ''
29
+ message = format(MSG, double_colon, double_colon)
30
+
31
+ add_offense(node, :expression, message)
32
+ end
33
+ end
34
+
35
+ def autocorrect(node)
36
+ lambda do |corrector|
37
+ double_colon = uri_parser_new?(node) ? '::' : ''
38
+
39
+ corrector.replace(
40
+ node.loc.expression, "#{double_colon}URI::DEFAULT_PARSER"
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -38,7 +38,7 @@ module RuboCop
38
38
  end
39
39
 
40
40
  def on_send(node)
41
- ALIASES.keys.each do |aliased_method|
41
+ ALIASES.each_key do |aliased_method|
42
42
  register_offense(node, aliased_method) if
43
43
  public_send(aliased_method, node)
44
44
  end
@@ -3,8 +3,17 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Rails
6
- # This cop looks for delegations, that could have been created
7
- # automatically with delegate method.
6
+ # This cop looks for delegations that could have been created
7
+ # automatically with the `delegate` method.
8
+ #
9
+ # Safe navigation `&.` is ignored because Rails' `allow_nil`
10
+ # option checks not just for nil but also delegates if nil
11
+ # responds to the delegated method.
12
+ #
13
+ # The `EnforceForPrefixed` option (defaulted to `true`) means that
14
+ # using the target object as a prefix of the method name
15
+ # without using the `delegate` method will be a violation.
16
+ # When set to `false`, this case is legal.
8
17
  #
9
18
  # @example
10
19
  # # bad
@@ -15,6 +24,18 @@ module RuboCop
15
24
  # # good
16
25
  # delegate :bar, to: :foo
17
26
  #
27
+ # # good
28
+ # def bar
29
+ # foo&.bar
30
+ # end
31
+ #
32
+ # # good
33
+ # private
34
+ # def bar
35
+ # foo.bar
36
+ # end
37
+ #
38
+ # # EnforceForPrefixed: true
18
39
  # # bad
19
40
  # def foo_bar
20
41
  # foo.bar
@@ -23,11 +44,14 @@ module RuboCop
23
44
  # # good
24
45
  # delegate :bar, to: :foo, prefix: true
25
46
  #
47
+ # # EnforceForPrefixed: false
26
48
  # # good
27
- # private
28
- # def bar
49
+ # def foo_bar
29
50
  # foo.bar
30
51
  # end
52
+ #
53
+ # # good
54
+ # delegate :bar, to: :foo, prefix: true
31
55
  class Delegate < Cop
32
56
  MSG = 'Use `delegate` to define delegations.'.freeze
33
57
 
@@ -35,7 +59,7 @@ module RuboCop
35
59
  method_name, args, body = *node
36
60
  return unless trivial_delegate?(method_name, args, body)
37
61
  return if private_or_protected_delegation(node)
38
- add_offense(node, :keyword, MSG)
62
+ add_offense(node, :keyword)
39
63
  end
40
64
 
41
65
  private
@@ -54,7 +78,7 @@ module RuboCop
54
78
  end
55
79
 
56
80
  def trivial_delegate?(method_name, args, body)
57
- body && delegate?(body) &&
81
+ body && delegate?(body) && !body.csend_type? &&
58
82
  method_name_matches?(method_name, body) &&
59
83
  arguments_match?(args, body)
60
84
  end
@@ -78,7 +102,12 @@ module RuboCop
78
102
  def method_name_matches?(method_name, body)
79
103
  _receiver, property_name, *_args = *body
80
104
  method_name == property_name ||
81
- method_name == prefixed_method_name(body)
105
+ (include_prefix_case? &&
106
+ method_name == prefixed_method_name(body))
107
+ end
108
+
109
+ def include_prefix_case?
110
+ cop_config['EnforceForPrefixed']
82
111
  end
83
112
 
84
113
  def prefixed_method_name(body)