rubocop 0.52.1 → 0.53.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/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +118 -46
  5. data/config/disabled.yml +8 -8
  6. data/config/enabled.yml +84 -28
  7. data/lib/rubocop.rb +28 -8
  8. data/lib/rubocop/ast/builder.rb +35 -37
  9. data/lib/rubocop/ast/node.rb +16 -1
  10. data/lib/rubocop/ast/node/and_node.rb +0 -8
  11. data/lib/rubocop/ast/node/block_node.rb +1 -9
  12. data/lib/rubocop/ast/node/case_node.rb +0 -8
  13. data/lib/rubocop/ast/node/ensure_node.rb +0 -8
  14. data/lib/rubocop/ast/node/for_node.rb +0 -8
  15. data/lib/rubocop/ast/node/or_node.rb +0 -8
  16. data/lib/rubocop/ast/node/pair_node.rb +0 -8
  17. data/lib/rubocop/ast/node/resbody_node.rb +0 -8
  18. data/lib/rubocop/ast/node/send_node.rb +0 -8
  19. data/lib/rubocop/ast/node/symbol_node.rb +0 -8
  20. data/lib/rubocop/ast/node/until_node.rb +0 -8
  21. data/lib/rubocop/ast/node/when_node.rb +0 -8
  22. data/lib/rubocop/ast/node/while_node.rb +0 -8
  23. data/lib/rubocop/cli.rb +17 -7
  24. data/lib/rubocop/comment_config.rb +24 -3
  25. data/lib/rubocop/config.rb +75 -6
  26. data/lib/rubocop/config_loader.rb +18 -28
  27. data/lib/rubocop/config_loader_resolver.rb +61 -9
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/commissioner.rb +2 -2
  32. data/lib/rubocop/cop/cop.rb +4 -0
  33. data/lib/rubocop/cop/corrector.rb +11 -1
  34. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
  37. data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
  38. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
  40. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
  42. data/lib/rubocop/cop/generator.rb +29 -8
  43. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
  45. data/lib/rubocop/cop/layout/align_hash.rb +106 -37
  46. data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
  47. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
  48. data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
  49. data/lib/rubocop/cop/layout/class_structure.rb +6 -7
  50. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  51. data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
  52. data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
  55. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
  56. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  57. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  58. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
  59. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
  60. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
  61. data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
  62. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  63. data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
  64. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
  65. data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
  66. data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
  67. data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
  68. data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
  69. data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
  70. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
  71. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  72. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
  73. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
  75. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
  76. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  77. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
  78. data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
  80. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
  83. data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  86. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
  87. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
  88. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
  89. data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
  90. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
  91. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
  92. data/lib/rubocop/cop/layout/tab.rb +42 -16
  93. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
  94. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
  95. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
  96. data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
  97. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  98. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
  99. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  100. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
  101. data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
  102. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
  103. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
  104. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
  105. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  106. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  107. data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
  108. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
  109. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
  110. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  111. data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
  112. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
  115. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  116. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
  117. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
  118. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
  119. data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
  120. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
  122. data/lib/rubocop/cop/lint/script_permission.rb +30 -10
  123. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  124. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
  125. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  126. data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
  127. data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
  128. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
  129. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
  131. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
  132. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  135. data/lib/rubocop/cop/lint/void.rb +49 -10
  136. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  137. data/lib/rubocop/cop/metrics/line_length.rb +5 -2
  138. data/lib/rubocop/cop/mixin/alignment.rb +4 -0
  139. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  140. data/lib/rubocop/cop/mixin/def_node.rb +4 -0
  141. data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
  142. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
  143. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
  144. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  145. data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
  146. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  147. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
  148. data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
  149. data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
  150. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
  151. data/lib/rubocop/cop/mixin/range_help.rb +102 -0
  152. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
  153. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
  154. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
  155. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
  156. data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
  157. data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
  158. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  159. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
  160. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
  161. data/lib/rubocop/cop/naming/file_name.rb +5 -10
  162. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
  163. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
  164. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
  165. data/lib/rubocop/cop/offense.rb +3 -2
  166. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
  167. data/lib/rubocop/cop/performance/casecmp.rb +17 -8
  168. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
  169. data/lib/rubocop/cop/performance/count.rb +1 -0
  170. data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
  171. data/lib/rubocop/cop/performance/flat_map.rb +2 -0
  172. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
  173. data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
  174. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
  175. data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
  176. data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
  177. data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
  178. data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
  179. data/lib/rubocop/cop/rails/blank.rb +3 -3
  180. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
  181. data/lib/rubocop/cop/rails/delegate.rb +6 -6
  182. data/lib/rubocop/cop/rails/file_path.rb +7 -1
  183. data/lib/rubocop/cop/rails/find_by.rb +2 -0
  184. data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
  185. data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
  186. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
  187. data/lib/rubocop/cop/rails/presence.rb +8 -2
  188. data/lib/rubocop/cop/rails/present.rb +5 -5
  189. data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
  190. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  191. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
  192. data/lib/rubocop/cop/rails/request_referer.rb +3 -2
  193. data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
  194. data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
  195. data/lib/rubocop/cop/rails/save_bang.rb +11 -12
  196. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  197. data/lib/rubocop/cop/rails/time_zone.rb +38 -16
  198. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
  199. data/lib/rubocop/cop/rails/validation.rb +30 -2
  200. data/lib/rubocop/cop/security/open.rb +48 -0
  201. data/lib/rubocop/cop/style/and_or.rb +1 -0
  202. data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
  203. data/lib/rubocop/cop/style/attr.rb +2 -0
  204. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  205. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
  206. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  207. data/lib/rubocop/cop/style/class_vars.rb +23 -0
  208. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  209. data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
  210. data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  212. data/lib/rubocop/cop/style/copyright.rb +3 -1
  213. data/lib/rubocop/cop/style/each_with_object.rb +15 -1
  214. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
  215. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
  216. data/lib/rubocop/cop/style/empty_else.rb +9 -5
  217. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  218. data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
  219. data/lib/rubocop/cop/style/empty_literal.rb +1 -0
  220. data/lib/rubocop/cop/style/encoding.rb +2 -0
  221. data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
  222. data/lib/rubocop/cop/style/for.rb +33 -0
  223. data/lib/rubocop/cop/style/format_string.rb +1 -1
  224. data/lib/rubocop/cop/style/format_string_token.rb +4 -5
  225. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  226. data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  228. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  229. data/lib/rubocop/cop/style/lambda.rb +1 -1
  230. data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
  231. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
  232. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
  233. data/lib/rubocop/cop/style/missing_else.rb +72 -7
  234. data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
  235. data/lib/rubocop/cop/style/module_function.rb +10 -0
  236. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
  237. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  238. data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
  239. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
  240. data/lib/rubocop/cop/style/next.rb +1 -0
  241. data/lib/rubocop/cop/style/not.rb +2 -0
  242. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  243. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
  245. data/lib/rubocop/cop/style/redundant_return.rb +37 -3
  246. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  247. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  248. data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
  249. data/lib/rubocop/cop/style/semicolon.rb +3 -1
  250. data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
  251. data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
  252. data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
  253. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  254. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
  255. data/lib/rubocop/cop/style/symbol_array.rb +29 -0
  256. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  257. data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
  258. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
  259. data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
  260. data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
  261. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
  262. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
  263. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  264. data/lib/rubocop/cop/style/unless_else.rb +2 -0
  265. data/lib/rubocop/cop/style/word_array.rb +0 -1
  266. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  267. data/lib/rubocop/cop/team.rb +5 -5
  268. data/lib/rubocop/cop/util.rb +23 -188
  269. data/lib/rubocop/cop/variable_force.rb +1 -1
  270. data/lib/rubocop/file_finder.rb +45 -0
  271. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
  272. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  273. data/lib/rubocop/formatter/html_formatter.rb +12 -5
  274. data/lib/rubocop/formatter/json_formatter.rb +1 -1
  275. data/lib/rubocop/node_pattern.rb +8 -5
  276. data/lib/rubocop/options.rb +40 -33
  277. data/lib/rubocop/path_util.rb +5 -8
  278. data/lib/rubocop/processed_source.rb +53 -0
  279. data/lib/rubocop/remote_config.rb +1 -1
  280. data/lib/rubocop/result_cache.rb +1 -1
  281. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  282. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
  283. data/lib/rubocop/rspec/shared_contexts.rb +3 -1
  284. data/lib/rubocop/rspec/shared_examples.rb +23 -25
  285. data/lib/rubocop/rspec/support.rb +5 -0
  286. data/lib/rubocop/runner.rb +3 -2
  287. data/lib/rubocop/string_util.rb +10 -9
  288. data/lib/rubocop/target_finder.rb +4 -1
  289. data/lib/rubocop/token.rb +26 -16
  290. data/lib/rubocop/version.rb +6 -4
  291. metadata +31 -17
  292. data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # Checks that ActiveRecord aliases are not used. The direct method names
7
+ # are more clear and easier to read.
8
+ #
9
+ # @example
10
+ # #bad
11
+ # Book.update_attributes!(author: 'Alice')
12
+ #
13
+ # #good
14
+ # Book.update!(author: 'Alice')
15
+ class ActiveRecordAliases < Cop
16
+ MSG = 'Use `%<prefer>s` instead of `%<current>s`.'.freeze
17
+
18
+ ALIASES = {
19
+ update_attributes: :update,
20
+ update_attributes!: :update!
21
+ }.freeze
22
+
23
+ def on_send(node)
24
+ ALIASES.each do |bad, good|
25
+ next unless node.method?(bad)
26
+
27
+ add_offense(node,
28
+ message: format(MSG, prefer: good, current: bad),
29
+ location: :selector,
30
+ severity: :warning)
31
+ break
32
+ end
33
+ end
34
+
35
+ def autocorrect(node)
36
+ lambda do |corrector|
37
+ corrector.replace(
38
+ node.loc.selector,
39
+ ALIASES[node.method_name].to_s
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -82,12 +82,12 @@ module RuboCop
82
82
  def on_or(node)
83
83
  return unless cop_config['NilOrEmpty']
84
84
 
85
- nil_or_empty?(node) do |variable1, variable2|
86
- return unless variable1 == variable2
85
+ nil_or_empty?(node) do |var1, var2|
86
+ return unless var1 == var2
87
87
 
88
88
  add_offense(node,
89
89
  message: format(MSG_NIL_OR_EMPTY,
90
- prefer: replacement(variable1),
90
+ prefer: replacement(var1),
91
91
  current: node.source))
92
92
  end
93
93
  end
@@ -50,6 +50,10 @@ module RuboCop
50
50
  _)
51
51
  PATTERN
52
52
 
53
+ def_node_matcher :create_table_with_timestamps_proc?, <<-PATTERN
54
+ (send nil? :create_table (sym _) (block-pass (sym :timestamps)))
55
+ PATTERN
56
+
53
57
  def_node_search :timestamps_included?, <<-PATTERN
54
58
  (send _var :timestamps ...)
55
59
  PATTERN
@@ -66,6 +70,8 @@ module RuboCop
66
70
  if parent.body.nil? || !time_columns_included?(parent.body)
67
71
  add_offense(parent)
68
72
  end
73
+ elsif create_table_with_timestamps_proc?(node)
74
+ # nothing to do
69
75
  else
70
76
  add_offense(node)
71
77
  end
@@ -55,6 +55,11 @@ module RuboCop
55
55
  class Delegate < Cop
56
56
  MSG = 'Use `delegate` to define delegations.'.freeze
57
57
 
58
+ def_node_matcher :delegate?, <<-PATTERN
59
+ (def _method_name _args
60
+ (send (send nil? _) _ ...))
61
+ PATTERN
62
+
58
63
  def on_def(node)
59
64
  return unless trivial_delegate?(node)
60
65
  return if private_or_protected_delegation(node)
@@ -81,16 +86,11 @@ module RuboCop
81
86
  def trivial_delegate?(def_node)
82
87
  method_name, args, body = *def_node
83
88
 
84
- delegate?(body) &&
89
+ delegate?(def_node) &&
85
90
  method_name_matches?(method_name, body) &&
86
91
  arguments_match?(args, body)
87
92
  end
88
93
 
89
- def delegate?(body)
90
- body && body.send_type? && body.receiver &&
91
- body.receiver.send_type? && !body.receiver.receiver
92
- end
93
-
94
94
  def arguments_match?(arg_array, body)
95
95
  argument_array = body.arguments
96
96
 
@@ -4,7 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Rails
6
6
  # This cop is used to identify usages of file path joining process
7
- # to use `Rails.root.join` clause.
7
+ # to use `Rails.root.join` clause. This is to avoid bugs on operating
8
+ # system that don't use '/' as the path separator.
8
9
  #
9
10
  # @example
10
11
  # # bad
@@ -15,6 +16,8 @@ module RuboCop
15
16
  # # good
16
17
  # Rails.root.join('app', 'models', 'goober')
17
18
  class FilePath < Cop
19
+ include RangeHelp
20
+
18
21
  MSG = 'Please use `Rails.root.join(\'path\', \'to\')` instead.'.freeze
19
22
 
20
23
  def_node_matcher :file_join_nodes?, <<-PATTERN
@@ -31,6 +34,9 @@ module RuboCop
31
34
 
32
35
  def on_dstr(node)
33
36
  return unless rails_root_nodes?(node)
37
+ return unless node.children.last.source.start_with?('.') ||
38
+ node.children.last.source.include?(File::SEPARATOR)
39
+
34
40
  register_offense(node)
35
41
  end
36
42
 
@@ -14,6 +14,8 @@ module RuboCop
14
14
  # # good
15
15
  # User.find_by(name: 'Bruce')
16
16
  class FindBy < Cop
17
+ include RangeHelp
18
+
17
19
  MSG = 'Use `find_by` instead of `where.%<method>s`.'.freeze
18
20
  TARGET_SELECTORS = %i[first take].freeze
19
21
 
@@ -60,12 +60,15 @@ module RuboCop
60
60
  # the range of the text to replace, which is the whole line
61
61
  code_to_replace = node.loc.expression
62
62
  # what to replace with
63
- format = parentheses?(node) ? '%s(%s%s%s)' : '%s %s%s%s'
64
- new_code = format(format, node.method_name, controller_action,
65
- params, headers)
63
+ format = parentheses_format(node)
64
+ new_code = format(format, name: node.method_name,
65
+ action: controller_action,
66
+ params: params, headers: headers)
66
67
  ->(corrector) { corrector.replace(code_to_replace, new_code) }
67
68
  end
68
69
 
70
+ private
71
+
69
72
  def needs_conversion?(data)
70
73
  return true unless data.hash_type?
71
74
 
@@ -87,14 +90,23 @@ module RuboCop
87
90
  return '' if data.hash_type? && data.empty?
88
91
 
89
92
  hash_data = if data.hash_type?
90
- format('{ %s }', data.pairs.map(&:source).join(', '))
93
+ format('{ %<data>s }',
94
+ data: data.pairs.map(&:source).join(', '))
91
95
  else
92
96
  # user supplies an object,
93
97
  # no need to surround with braces
94
98
  data.source
95
99
  end
96
100
 
97
- format(', %s: %s', type, hash_data)
101
+ format(', %<type>s: %<hash_data>s', type: type, hash_data: hash_data)
102
+ end
103
+
104
+ def parentheses_format(node)
105
+ if parentheses?(node)
106
+ '%<name>s(%<action>s%<params>s%<headers>s)'
107
+ else
108
+ '%<name>s %<action>s%<params>s%<headers>s'
109
+ end
98
110
  end
99
111
  end
100
112
  end
@@ -7,7 +7,8 @@ module RuboCop
7
7
  # ActiveRecord can't automatically determine the inverse association
8
8
  # because of a scope or the options used. This can result in unnecessary
9
9
  # queries in some circumstances. `:inverse_of` must be manually specified
10
- # for associations to work in both ways, or set to `false` to opt-out.
10
+ # for associations to work in both ways, or set to `false` or `nil`
11
+ # to opt-out.
11
12
  #
12
13
  # @example
13
14
  # # good
@@ -52,6 +53,24 @@ module RuboCop
52
53
  # belongs_to :blog
53
54
  # end
54
55
  #
56
+ # # good
57
+ # # When you don't want to use the inverse association.
58
+ # class Blog < ApplicationRecord
59
+ # has_many(:posts,
60
+ # -> { order(published_at: :desc) },
61
+ # inverse_of: false
62
+ # )
63
+ # end
64
+ #
65
+ # # good
66
+ # # You can also opt-out with specifying `inverse_of: nil`.
67
+ # class Blog < ApplicationRecord
68
+ # has_many(:posts,
69
+ # -> { order(published_at: :desc) },
70
+ # inverse_of: nil
71
+ # )
72
+ # end
73
+ #
55
74
  # @example
56
75
  # # bad
57
76
  # class Picture < ApplicationRecord
@@ -155,7 +174,7 @@ module RuboCop
155
174
  PATTERN
156
175
 
157
176
  def_node_matcher :inverse_of_option?, <<-PATTERN
158
- (pair (sym :inverse_of) !nil)
177
+ (pair (sym :inverse_of) _)
159
178
  PATTERN
160
179
 
161
180
  def on_send(node)
@@ -4,12 +4,12 @@ module RuboCop
4
4
  module Cop
5
5
  module Rails
6
6
  # This cop checks that methods specified in the filter's `only`
7
- # or `except` options are explicitly defined in the controller.
7
+ # or `except` options are explicitly defined in the class or module.
8
8
  #
9
9
  # You can specify methods of superclass or methods added by mixins
10
10
  # on the filter, but these confuse developers. If you specify methods
11
- # where are defined on another controller, you should define the filter
12
- # in that controller.
11
+ # where are defined on another classes or modules, you should define
12
+ # the filter in that class or module.
13
13
  #
14
14
  # @example
15
15
  # # bad
@@ -33,8 +33,31 @@ module RuboCop
33
33
  # def logout
34
34
  # end
35
35
  # end
36
+ #
37
+ # @example
38
+ # # bad
39
+ # module FooMixin
40
+ # extend ActiveSupport::Concern
41
+ #
42
+ # included do
43
+ # before_action proc { authenticate }, only: :foo
44
+ # end
45
+ # end
46
+ #
47
+ # # good
48
+ # module FooMixin
49
+ # extend ActiveSupport::Concern
50
+ #
51
+ # included do
52
+ # before_action proc { authenticate }, only: :foo
53
+ # end
54
+ #
55
+ # def foo
56
+ # # something
57
+ # end
58
+ # end
36
59
  class LexicallyScopedActionFilter < Cop
37
- MSG = '%<action>s not explicitly defined on the controller.'.freeze
60
+ MSG = '%<action>s not explicitly defined on the %<type>s.'.freeze
38
61
 
39
62
  FILTERS = %w[
40
63
  :after_action
@@ -67,12 +90,18 @@ module RuboCop
67
90
  methods_node = only_or_except_filter_methods(node)
68
91
  return unless methods_node
69
92
 
70
- defined_methods = node.parent.each_child_node(:def).map(&:method_name)
93
+ parent = node.each_ancestor(:class, :module).first
94
+ return unless parent
95
+ block = parent.each_child_node(:begin).first
96
+ return unless block
97
+
98
+ defined_methods = block.each_child_node(:def).map(&:method_name)
71
99
  methods = array_values(methods_node).reject do |method|
72
100
  defined_methods.include?(method)
73
101
  end
74
102
 
75
- add_offense(node, message: message(methods)) unless methods.empty?
103
+ message = message(methods, parent)
104
+ add_offense(node, message: message) unless methods.empty?
76
105
  end
77
106
 
78
107
  private
@@ -99,11 +128,18 @@ module RuboCop
99
128
  end
100
129
  end
101
130
 
102
- def message(methods)
131
+ # @param methods [Array<String>]
132
+ # @param parent [RuboCop::AST::Node]
133
+ # @return [String]
134
+ def message(methods, parent)
103
135
  if methods.size == 1
104
- format(MSG, action: "`#{methods[0]}` is")
136
+ format(MSG,
137
+ action: "`#{methods[0]}` is",
138
+ type: parent.type)
105
139
  else
106
- format(MSG, action: "`#{methods.join('`, `')}` are")
140
+ format(MSG,
141
+ action: "`#{methods.join('`, `')}` are",
142
+ type: parent.type)
107
143
  end
108
144
  end
109
145
  end
@@ -71,14 +71,16 @@ module RuboCop
71
71
  PATTERN
72
72
 
73
73
  def on_if(node)
74
+ return if ignore_if_node?(node)
75
+
74
76
  redundant_receiver_and_other(node) do |receiver, other|
75
- unless ignore_other_node?(other)
77
+ unless ignore_other_node?(other) || receiver.nil?
76
78
  add_offense(node, message: message(node, receiver, other))
77
79
  end
78
80
  end
79
81
 
80
82
  redundant_negative_receiver_and_other(node) do |receiver, other|
81
- unless ignore_other_node?(other)
83
+ unless ignore_other_node?(other) || receiver.nil?
82
84
  add_offense(node, message: message(node, receiver, other))
83
85
  end
84
86
  end
@@ -98,6 +100,10 @@ module RuboCop
98
100
 
99
101
  private
100
102
 
103
+ def ignore_if_node?(node)
104
+ node.elsif?
105
+ end
106
+
101
107
  def ignore_other_node?(node)
102
108
  node && (node.if_type? || node.rescue_type? || node.while_type?)
103
109
  end
@@ -75,12 +75,12 @@ module RuboCop
75
75
  def on_and(node)
76
76
  return unless cop_config['NotNilAndNotEmpty']
77
77
 
78
- exists_and_not_empty?(node) do |variable1, variable2|
79
- return unless variable1 == variable2
78
+ exists_and_not_empty?(node) do |var1, var2|
79
+ return unless var1 == var2
80
80
 
81
81
  add_offense(node,
82
82
  message: format(MSG_EXISTS_AND_NOT_EMPTY,
83
- prefer: replacement(variable1),
83
+ prefer: replacement(var1),
84
84
  current: node.source))
85
85
  end
86
86
  end
@@ -88,8 +88,8 @@ module RuboCop
88
88
  def on_or(node)
89
89
  return unless cop_config['NilOrEmpty']
90
90
 
91
- exists_and_not_empty?(node) do |variable1, variable2|
92
- return unless variable1 == variable2
91
+ exists_and_not_empty?(node) do |var1, var2|
92
+ return unless var1 == var2
93
93
 
94
94
  add_offense(node, message: MSG_EXISTS_AND_NOT_EMPTY)
95
95
  end
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # x = self[:attr]
17
17
  # self[:attr] = val
18
18
  class ReadWriteAttribute < Cop
19
- MSG = 'Prefer `%s` over `%s`.'.freeze
19
+ MSG = 'Prefer `%<prefer>s` over `%<current>s`.'.freeze
20
20
 
21
21
  def_node_matcher :read_write_attribute?, <<-PATTERN
22
22
  {
@@ -46,9 +46,10 @@ module RuboCop
46
46
 
47
47
  def message(node)
48
48
  if node.method?(:read_attribute)
49
- format(MSG, 'self[:attr]', 'read_attribute(:attr)')
49
+ format(MSG, prefer: 'self[:attr]', current: 'read_attribute(:attr)')
50
50
  else
51
- format(MSG, 'self[:attr] = val', 'write_attribute(:attr, val)')
51
+ format(MSG, prefer: 'self[:attr] = val',
52
+ current: 'write_attribute(:attr, val)')
52
53
  end
53
54
  end
54
55
 
@@ -56,6 +56,7 @@ module RuboCop
56
56
  # end
57
57
  class RedundantReceiverInWithOptions < Cop
58
58
  extend TargetRailsVersion
59
+ include RangeHelp
59
60
 
60
61
  minimum_target_rails_version 4.2
61
62
 
@@ -19,8 +19,8 @@ module RuboCop
19
19
  # end
20
20
  # end
21
21
  class RelativeDateConstant < Cop
22
- MSG = 'Do not assign %s to constants as it will be evaluated only ' \
23
- 'once.'.freeze
22
+ MSG = 'Do not assign %<method_name>s to constants as it ' \
23
+ 'will be evaluated only once.'.freeze
24
24
 
25
25
  RELATIVE_DATE_METHODS = %i[ago from_now since until].freeze
26
26
 
@@ -72,7 +72,8 @@ module RuboCop
72
72
 
73
73
  nodes.each do |n|
74
74
  if relative_date_method?(n)
75
- add_offense(node.parent, message: format(MSG, n.method_name))
75
+ add_offense(node.parent,
76
+ message: format(MSG, method_name: n.method_name))
76
77
  end
77
78
  end
78
79
  end
@@ -22,7 +22,8 @@ module RuboCop
22
22
  class RequestReferer < Cop
23
23
  include ConfigurableEnforcedStyle
24
24
 
25
- MSG = 'Use `request.%s` instead of `request.%s`.'.freeze
25
+ MSG = 'Use `request.%<prefer>s` instead of ' \
26
+ '`request.%<current>s`.'.freeze
26
27
 
27
28
  def_node_matcher :referer?, <<-PATTERN
28
29
  (send (send nil? :request) {:referer :referrer})
@@ -43,7 +44,7 @@ module RuboCop
43
44
  private
44
45
 
45
46
  def message(_node)
46
- format(MSG, style, wrong_method_name)
47
+ format(MSG, prefer: style, current: wrong_method_name)
47
48
  end
48
49
 
49
50
  def wrong_method_name